#include "Geo_Obj_Textured.h"
#include <glm/glm.hpp>
#include "Hub.h"

namespace Geo
{
	GeoObjTextured::GeoObjTextured(Data::GeoData& aModelData, Textures::Data::TextureData& aTextureData) :
		mVOAID(0), mRendererEnabled(true), mModelData(aModelData), mTextureData(aTextureData)
	{
		glGenVertexArrays(1, &mVOAID);
		glBindVertexArray(mVOAID);
	}

	void GeoObjTextured::Bind()
	{
		// Vertex Buffer
		glEnableVertexAttribArray(0);
		glBindBuffer(GL_ARRAY_BUFFER, mModelData.mVertexBuffer);
		glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);

		// UV Buffer
		glEnableVertexAttribArray(1);
		glBindBuffer(GL_ARRAY_BUFFER, mModelData.mUVBuffer);
		glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, 0);

		// Normal Buffer
		glEnableVertexAttribArray(2);
		glBindBuffer(GL_ARRAY_BUFFER, mModelData.mNormalBuffer);
		glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 0, 0);

		// Indice Buffer
		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mModelData.mIndiceBuffer);
	}

	void GeoObjTextured::Render()
	{
		glDrawElements(GL_TRIANGLES, mModelData.mIndices.size(), GL_UNSIGNED_SHORT, 0);

		glDisableVertexAttribArray(0);
		glDisableVertexAttribArray(1);
		glDisableVertexAttribArray(2);
	}

	void GeoObjTextured::SetTextureData(GLuint aTextureSlot, GLuint aUniformTextureId)
	{
		glActiveTexture(aTextureSlot);
		glBindTexture(GL_TEXTURE_2D, mTextureData.mTexture);
		glUniform1i(aUniformTextureId, aTextureSlot - GL_TEXTURE0);
	}

	void GeoObjTextured::UpdateBindRender()
	{
		if (!mRendererEnabled)
			return;

		UpdateCamData();

		Hub::I().GetShader().UpdateMatrices(GetMatrices());
		SetTextureData(GL_TEXTURE0, Hub::I().GetShader().GetTextureId());

		Bind();
		Render();
	}

	void GeoObjTextured::UpdateCamData()
	{
		Hub::I().UpdateCamMatrices(mMatrices);
	}

	void GeoObjTextured::CleanUp()
	{
		glDeleteVertexArrays(1, &mVOAID);
	}
}