#pragma once

#include "GLExtensions.h"

#include <array>
#include <string>
#include <vector>

enum class RenderTargetId
{
	Decoded,
	LayerTemp,
	Composite,
	Output,
	OutputPack,
	Count
};

struct RenderTarget
{
	GLuint texture = 0;
	GLuint framebuffer = 0;
	unsigned width = 0;
	unsigned height = 0;
	GLenum internalFormat = GL_RGBA8;
	GLenum pixelFormat = GL_RGBA;
	GLenum pixelType = GL_UNSIGNED_BYTE;
};

class RenderTargetPool
{
public:
	bool Create(
		RenderTargetId id,
		unsigned width,
		unsigned height,
		GLenum internalFormat,
		GLenum pixelFormat,
		GLenum pixelType,
		const char* errorPrefix,
		std::string& error);
	bool ReserveTemporaryTargets(
		std::size_t count,
		unsigned width,
		unsigned height,
		GLenum internalFormat,
		GLenum pixelFormat,
		GLenum pixelType,
		std::string& error);
	void DestroyTemporaryTargets();
	void Destroy();

	GLuint Texture(RenderTargetId id) const { return Target(id).texture; }
	GLuint Framebuffer(RenderTargetId id) const { return Target(id).framebuffer; }
	const RenderTarget& Target(RenderTargetId id) const;
	const RenderTarget& TemporaryTarget(std::size_t index) const { return mTemporaryTargets[index]; }
	std::size_t TemporaryTargetCount() const { return mTemporaryTargets.size(); }

private:
	static std::size_t TargetIndex(RenderTargetId id) { return static_cast<std::size_t>(id); }

	std::array<RenderTarget, static_cast<std::size_t>(RenderTargetId::Count)> mTargets;
	std::vector<RenderTarget> mTemporaryTargets;
};
