#pragma once

#include "GlobalParamsBuffer.h"
#include "OpenGLRenderer.h"
#include "RuntimeSnapshotProvider.h"
#include "ShaderBuildQueue.h"
#include "ShaderTypes.h"
#include "ShaderProgramCompiler.h"
#include "ShaderTextureBindings.h"

#include <string>

class OpenGLShaderPrograms
{
public:
	using LayerProgram = OpenGLRenderer::LayerProgram;

	OpenGLShaderPrograms(OpenGLRenderer& renderer, RuntimeSnapshotProvider& runtimeSnapshotProvider);

	bool CompileLayerPrograms(unsigned inputFrameWidth, unsigned inputFrameHeight, int errorMessageSize, char* errorMessage);
	bool CommitPreparedLayerPrograms(const PreparedShaderBuild& preparedBuild, unsigned inputFrameWidth, unsigned inputFrameHeight, int errorMessageSize, char* errorMessage);
	bool CompileDecodeShader(int errorMessageSize, char* errorMessage);
	bool CompileOutputPackShader(int errorMessageSize, char* errorMessage);
	void DestroyLayerPrograms();
	void DestroySingleLayerProgram(LayerProgram& layerProgram);
	void DestroyDecodeShaderProgram();
	void ResetTemporalHistoryState();
	void ResetShaderFeedbackState();
	const std::vector<RuntimeRenderState>& CommittedLayerStates() const { return mCommittedLayerStates; }
	bool UpdateTextBindingTexture(const RuntimeRenderState& state, LayerProgram::TextBinding& textBinding, std::string& error);
	bool UpdateGlobalParamsBuffer(const RuntimeRenderState& state, unsigned availableSourceHistoryLength, unsigned availableTemporalHistoryLength, bool feedbackAvailable);

private:
	OpenGLRenderer& mRenderer;
	RuntimeSnapshotProvider& mRuntimeSnapshotProvider;
	ShaderTextureBindings mTextureBindings;
	GlobalParamsBuffer mGlobalParamsBuffer;
	ShaderProgramCompiler mCompiler;
	std::vector<RuntimeRenderState> mCommittedLayerStates;
};
