#include "Wireframe_Box.h"
#include "Hub.h"
#include "Utils.h"

namespace Geo
{

	GLshort indices[] = 
	{
		0, 1,
		1, 2,
		2, 3,
		3, 0,
		4, 5,
		5, 6,
		6, 7,
		7, 4,
		0, 4,
		1, 5,
		2, 6,
		3, 7
	};

	GLfloat uvs[]=
	{
		0.0f,1.0f,0.0f,
		0.0f,1.0f,0.0f,
		0.0f,1.0f,0.0f,
		0.0f,1.0f,0.0f,
		0.0f,1.0f,0.0f,
		0.0f,1.0f,0.0f,
		0.0f,1.0f,0.0f,
		0.0f,1.0f,0.0f
	};
	GLuint uvbuffer;

	WireframeBox::WireframeBox() : mHit(false)
	{}

	void WireframeBox::Init(glm::vec3 aMin, glm::vec3 aMax)
	{
		// Init variables
		mGreenTexture = GLUtils::LoadTGA("media/textures/green.tga");
		mRedTexture = GLUtils::LoadTGA("media/textures/red.tga");

		// Set up buffers
		glGenVertexArrays(1, &mVOAID);
		glBindVertexArray(mVOAID);

		mVerts.push_back(glm::vec3(aMax.x, aMax.y, aMax.z));
		mVerts.push_back(glm::vec3(aMin.x, aMax.y, aMax.z));
		mVerts.push_back(glm::vec3(aMin.x, aMin.y, aMax.z));
		mVerts.push_back(glm::vec3(aMax.x, aMin.y, aMax.z));

		mVerts.push_back(glm::vec3(aMax.x, aMax.y, aMin.z));
		mVerts.push_back(glm::vec3(aMin.x, aMax.y, aMin.z));
		mVerts.push_back(glm::vec3(aMin.x, aMin.y, aMin.z));
		mVerts.push_back(glm::vec3(aMax.x, aMin.y, aMin.z));

		glGenBuffers(1, &mVertexBuffer);
		glBindBuffer(GL_ARRAY_BUFFER, mVertexBuffer);
		glBufferData(GL_ARRAY_BUFFER, mVerts.size() * sizeof(glm::vec3), &mVerts[0], GL_STATIC_DRAW);

		glGenBuffers(1, &uvbuffer);
		glBindBuffer(GL_ARRAY_BUFFER, uvbuffer);
		glBufferData(GL_ARRAY_BUFFER, 24 * sizeof(GLfloat), &uvs[0], GL_STATIC_DRAW);

		// Generate a buffer for the indices as well
		glGenBuffers(1, &mIndiceBuffer);
		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndiceBuffer);
		glBufferData(GL_ELEMENT_ARRAY_BUFFER, 24 * sizeof(GLshort), &indices[0], GL_STATIC_DRAW);
	}

	void WireframeBox::Draw()
	{
		// Update
		Hub::I().UpdateCamMatrices(mMatrices);
		Hub::I().GetShader().UpdateMatrices(mMatrices);

		// Bind
		//glBindVertexArray(mVOAID);
		//glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndiceBuffer);

		// Texture 
		glActiveTexture(0);
		if (mHit)
			glBindTexture(GL_TEXTURE_2D, mRedTexture);
		else
			glBindTexture(GL_TEXTURE_2D, mGreenTexture);
		glUniform1i(Hub::I().GetShader().GetTextureId(), 0 - GL_TEXTURE0);

		// Vertex Buffer
		glEnableVertexAttribArray(0);
		glBindBuffer(GL_ARRAY_BUFFER, mVertexBuffer);
		glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);

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

		// Indice Buffer
		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndiceBuffer);
		glDrawElements(GL_LINES, 24, GL_UNSIGNED_SHORT, 0);

		glDisableVertexAttribArray(0);
		glDisableVertexAttribArray(1);
	}

}