/** \file Shader.h
 * \brief The header file for the 'Shader' class.
 */

#pragma once
// OSkA Includes
#include "OSkA.h"
#include "ShaderInterface.h"

// Other Includes
#include <string>

namespace OSkA
{
	/** \brief A Shader implements the methods of the ShaderInterface
	 *
	 * The Shader class implements the methods of the ShaderInterface and
	 * offers methods to initiate a new shader object. The Shader
	 * will be used by an AnimationShader and allows to enable/disable
	 * and to pass parameters to the shader.
	 *
	 * With this class we can use the default shader, but also a self
	 * written shader(basen on the default shader).
	 */
	class Shader : public ShaderInterface
	{
	public:
		/** \brief Default Constructor
		 */
		Shader();
		/** \brief Destructor
		 */
		~Shader();

		/** \brief Init the default shader.
		 *
		 * The Shader is initiated with the default shader source code
		 * that uses the animation data stored in a texture.
		 * \return A string containing error messages for debugging.
		 */
		std::string initDefaultShaderTexture();
		/** \brief Init the default shader.
		 *
		 * The Shader is initiated with the default shader source code
		 * that uses the animation data passed as a uniform.
		 * \return A string containing error messages for debugging.
		 */
		std::string initDefaultShaderUniform();
		/** \brief Init the shader with a give source code.
		 *
		 * The Shader is initiated with a given source code.
		 * \param vertexSource Source code for the GLSL vertex shader.
		 * \param fragmentSource Source code for the GLSL fragment shader.
		 * \return A string containing error messages for debugging.
		 */
		std::string initNewShader(std::string vertexSource, std::string fragmentSource);
		/** \brief Init the shader with source code loaded from a file
		 *
		 * The Shader is initiated with source code that is loaded from a file.
		 * \param vertexSource File for the GLSL vertex shader source code.
		 * \param fragmentSource File for the GLSL fragment shader source code.
		 * \return A string containing error messages for debugging.
		 */
		std::string initNewShaderFromFile(char* vertexSourceFile, char* fragmentSourceFile);

		/** \brief Interface method, for details see ShaderInterface
		 */
		void enable();
		/** \brief Interface method, for details see ShaderInterface
		 */
		void disable();

		/** \brief Interface method, for details see ShaderInterface
		 */
		unsigned int getAttributeLocation(char* name);
		/** \brief Interface method, for details see ShaderInterface
		 */
		unsigned int getUniformLocation(char* name);

		/** \brief Interface method, for details see ShaderInterface
		 */
		void setVertexAttribPointer(unsigned int location, int size, int type, bool normalized, int stride, void* data);
		/** \brief Interface method, for details see ShaderInterface
		 */
		void setUniformMatrix4fv(unsigned int location, int count, bool transpose, float* data);

		/** \brief Interface method, for details see ShaderInterface
		 */
		void setUniform1f(unsigned int location, float value);
		/** \brief Interface method, for details see ShaderInterface
		 */
		void setUniform1i(unsigned int location, int value);
	private:
		/** \brief Loads the content of a text file
		 *
		 * The complete content of the given text file is loaded and stored
		 * into the string variable
		 * \param filename	filename of the text file
		 * \param storage	pointer to the string variable the content will be stored in
		 * \return true - loading successfull, false - loading failed
		 */
		bool loadTextFile(char* filename, std::string* storage);

		/** \brief The OpenGL shader program object.
		 */
		unsigned int shaderProgram;
		/** \brief The OpenGL vertex shader object.
		 */
		unsigned int vertexShaderObject;
		/** \brief The OpenGL fragment shader object.
		 */
		unsigned int fragmentShaderObject;
	};
}
