#pragma once
#include "Surface.h"
#include "3D/Shader.h"

#ifdef GUI_GTK

namespace gui {

	/**
	 * Vertex shader.
	 */
	class GLVertexShader {
	public:
		// Create.
		GLVertexShader(GLSurface &surface, VertexShader *shader);

		// Destroy.
		~GLVertexShader();

		// The shader itself.
		GLuint shader;

		// Surface.
		GLSurface &surface;

		// Destroy.
		static void destroy(void *me) {
			delete (GLVertexShader *)me;
		}
	};


	/**
	 * Pixel shader.
	 */
	class GLPixelShader {
	public:
		// Create.
		GLPixelShader(GLSurface &surface, PixelShader *shader);

		// Destroy.
		~GLPixelShader();

		// The shader itself.
		GLuint shader;

		// Surface.
		GLSurface &surface;

		// Destroy.
		static void destroy(void *me) {
			delete (GLPixelShader *)me;
		}
	};


	/**
	 * Program. Corresponds to a vertex shader and a pixel shader linked together as a unit.
	 *
	 * A program is initially empty. It must be explicitly initialized.
	 */
	class GLProgram {
	public:
		// Create.
		GLProgram(GLVertexShader *vertex, GLPixelShader *pixel, VertexDesc *inputDesc, Pipeline *pipeline);

		// Destroy.
		~GLProgram();

		// Input format. From OpenGL 4.6 or later (from 2012):
		// https://www.khronos.org/opengl/wiki/Vertex_Specification#Separate_attribute_format
		// It is a Vertex Array Object.
		GLuint inputFormat;

		// The program.
		GLuint program;

		// Uniform buffers to bind.
		vector<GLuint> constantBuffers;

		// Surface.
		GLSurface &surface;

		// Update the constant buffers.
		void update(Pipeline *pipeline, DirtyRange dirty);

		// Destroy.
		static void destroy(void *me) {
			delete (GLProgram *)me;
		}
	};
}

#endif
