#include <psemek/gfx/query.hpp>

#include <optional>

namespace psemek::gfx
{

	query_pool::scope::~scope()
	{
		gl::EndQuery(target);
	}

	query_pool::scope query_pool::begin(GLenum target, util::function<void(GLint)> callback)
	{
		std::optional<std::size_t> index;
		for (std::size_t i = 0; i < ids_.size(); ++i)
		{
			if (callbacks_[i]) continue;
			index = i;
			break;
		}

		if (!index)
		{
			index = ids_.size();
			gl::GenQueries(1, &ids_.emplace_back());
			callbacks_.emplace_back();
		}

		callbacks_[*index] = std::move(callback);
		gl::BeginQuery(target, ids_[*index]);

		return {target};
	}

	void query_pool::poll()
	{
		for (std::size_t i = 0; i < ids_.size(); ++i)
		{
			if (!callbacks_[i]) continue;

			GLuint result;
			gl::GetQueryObjectuiv(ids_[i], gl::QUERY_RESULT_AVAILABLE, &result);
			if (result == gl::TRUE)
			{
				gl::GetQueryObjectuiv(ids_[i], gl::QUERY_RESULT, &result);
				callbacks_[i](result);
				callbacks_[i].reset();
			}
		}
	}

	query_pool::~query_pool()
	{
		gl::DeleteQueries(ids_.size(), ids_.data());
	}

}
