#include "Shader.h"
#include <string>
#include "Utils.h"
#include "Hub.h"
#include "Global_Properties.h"

namespace Shaders
{
	void Shader::Activate()
	{
		glUseProgram(mProgId);
	}

	void Shader::UpdateCamData()
	{
		PerspectiveCamera cam = Hub::I().GetCamera();
		glUniform3f(mCameraPosId, cam.GetPosition().x, cam.GetPosition().y, cam.GetPosition().z);
	}

	void Shader::UpdateMatrices(Geo::Data::MatSpaces& aMat)
	{
		glUniformMatrix4fv(mId, 1, GL_FALSE, &(aMat.mModel[0][0]));
		glUniformMatrix4fv(mvId, 1, GL_FALSE, &(aMat.mMV[0][0]));
		glUniformMatrix4fv(mvpId, 1, GL_FALSE, &(aMat.mMVP[0][0]));
	}

	void Shader::CleanUp()
	{
		glDeleteProgram(mProgId);
	}


	void AmbDifSpecShader::Init()
	{
		std::string vertPath = "media/shaders/Ambient_Diffuse_Spec.vert";
		std::string fragPath = "media/shaders/Ambient_Diffuse_Spec.frag";

		mProgId = GLUtils::LoadShaders(vertPath.c_str(), fragPath.c_str());

		mId = glGetUniformLocation(mProgId, "M");
		mvId = glGetUniformLocation(mProgId, "MV");
		mvpId = glGetUniformLocation(mProgId, "MVP");
		mTextureId = glGetUniformLocation(mProgId, "myTextureSampler");

		mLightColorId = glGetUniformLocation(mProgId, "sharedLightColor");
		mAmbientIntensityId = glGetUniformLocation(mProgId, "ambientIntensity");
		mDiffuseDirId = glGetUniformLocation(mProgId, "diffuseDir");
		mDiffuseIntensity = glGetUniformLocation(mProgId, "diffuseIntensity");
		mSpecMatIntId = glGetUniformLocation(mProgId, "specularMatInt");
		mSpecMatPowerId = glGetUniformLocation(mProgId, "specularMatPower");
		mCameraPosId = glGetUniformLocation(mProgId, "cameraPosition");

		
		mEnableAmbient = GlobalProperties::ENABLE_AMBIENT;
		mEnableDiffuse = GlobalProperties::ENABLE_DIFFUSE;
		mEnableSpecular = GlobalProperties::ENABLE_SPECULAR;

		mLightColor = glm::vec3(GlobalProperties::LIGHT_COLOR[0], GlobalProperties::LIGHT_COLOR[1], GlobalProperties::LIGHT_COLOR[2]);

		mAmbientIntensity = GlobalProperties::AMBIENT_INTENSITY;
		mDiffuseDir = glm::vec3(GlobalProperties::DIFFUSE_DIR[0], GlobalProperties::DIFFUSE_DIR[1], GlobalProperties::DIFFUSE_DIR[2]);
		mDiffuseIntensity = GlobalProperties::DIFFUSE_INTENSITY;
		mSpecMatInt = GlobalProperties::SPEC_INTENSITY;
		mSpecMatPower = GlobalProperties::SPEC_POWER;
	}

	void AmbDifSpecShader::UpdateLights()
	{
		if (mEnableAmbient)
		{
			glUniform3f(mLightColorId, mLightColor.x, mLightColor.y, mLightColor.z);
			glUniform1f(mAmbientIntensityId, mAmbientIntensity);
		}
		if (mEnableDiffuse)
		{
			glUniform3f(mDiffuseDirId, mDiffuseDir.x, mDiffuseDir.y, mDiffuseDir.z);
			glUniform1f(mDiffuseIntensityId, mDiffuseIntensity);
		}
		if (mEnableSpecular)
		{
			glUniform1f(mSpecMatIntId, mSpecMatInt);
			glUniform1f(mSpecMatPowerId, mSpecMatPower);
		}
	}


	void ColorShader::Init()
	{
		std::string vertPath = "media/shaders/Basic.vert";
		std::string fragPath = "media/shaders/Basic.frag";

		mProgId = GLUtils::LoadShaders(vertPath.c_str(), fragPath.c_str());

		mId = glGetUniformLocation(mProgId, "M");
		mvId = glGetUniformLocation(mProgId, "MV");
		mvpId = glGetUniformLocation(mProgId, "MVP");
	}

}