/******************************************************************************
*	File		-	glShader.h
*	Author		-	Joey Pollack
*	Date		-	2018/06/26 (y/m/d)
*	Mod Date	-	2021/09/02 (y/m/d)
*	Description	-	Manages a single OpenGL shader program. Uses GLEW.
*
******************************************************************************/

#ifndef GL_SHADER_H_
#define	GL_SHADER_H_


#include <string>
#include <iostream>
#include <vector>


namespace lunarium
{
	class Logger;

	class glShader
	{
	private:

		struct ShaderInfo
		{
			unsigned int ID;
			std::string Source;
			bool IsCompiled;
			int GLType;
		};

	public:

		// To support more shader types:
		//			1) Add a TYPE_* enum value here before TYPE_COUNT
		//			2) in the constructor add a new GLType to the array in the correct place
		enum { TYPE_VERTEX, TYPE_GEOMETRY, TYPE_FRAGMENT, TYPE_COUNT, TYPE_INVALID = TYPE_COUNT };
		const char* TypeNames[3] = { "Vertex", "Geometry", "Fragment" };

		glShader();

		bool IsBuilt() const;

		bool SetSource(int sourceType, const char* source, bool loadFromFile = true);
		bool CompileShader(int sourceType);
		bool BuildProgram(bool autoFreeShaders = true);
		void FreeShaders();

		void MakeActive();

		bool SetUniformi(const char* uniformName, std::vector<int> values, bool asVector = false);
		bool SetUniformf(const char* uniformName, std::vector<float> values, bool asVector = false);
		bool SetUniformMatrix(const char* uniformName, int numMats, float* pData);

		void LogAllUniforms() const;


	private:

		unsigned int mProgram;
		bool mbProgramBuilt;

		ShaderInfo mShaders[TYPE_COUNT];

		Logger* mpLogger;

	private:	// Helper Methods

		std::string LoadShaderFromFile(const char* filename);
	};
}

#endif	// GL_SHADER_H_

