#include  "ModelObject.h"

Model::Model(  const vector<MeshObject>& meshes):meshes(meshes)
{
	this->modelMatrix.loadIdentity();
}



void Model::getModelMatrix(Matrix4X4<float>& matrix) const
{
	matrix = this->modelMatrix;
}

Matrix4X4<float>& Model::getModelMatrixRef(void)
{
	return this->modelMatrix;
}
vector<MeshObject>& Model::getMeshes(void)
{
	return this->meshes;
}

void Model::setModelMatrix( const Matrix4X4<float>& matrix)
{
	this->modelMatrix = matrix;
}



void Model::identity(void)
{
	this->modelMatrix.loadIdentity();
}

void Model::translate( float translateX, float translateY, float translateZ)
{
	this->modelMatrix.translate( translateX ,translateY, translateZ );
}
void Model::rotate( float angleX, float angleY, float angleZ)
{
	this->modelMatrix.rotate(angleX, angleY, angleZ);
}

void Model::scale( float scaleX, float scaleY, float scaleZ)
{
	this->modelMatrix.scale(scaleX, scaleY, scaleZ);
}

void Model::setPosition( float posX, float posY, float posZ )
{
	this->modelMatrix[12] = posX;
	this->modelMatrix[13] = posY;
	this->modelMatrix[14] = posZ;
}

float& Model::positionX(void)
{
	return this->modelMatrix[12];
}

float& Model::positionY(void)
{
	return this->modelMatrix[13];
}

float& Model::positionZ(void)
{
	return this->modelMatrix[14];
}

void Model::scale( float scaleXYZ )
{
	this->modelMatrix.scale( scaleXYZ, scaleXYZ, scaleXYZ );
}
void Model::transformGlobal( const Matrix4X4<float> &transformMatrix )
{
	this->modelMatrix = transformMatrix * this->modelMatrix;
}
void Model::transformLocal( const Matrix4X4<float> &transformMatrix )
{
	this->modelMatrix = this->modelMatrix * transformMatrix;
}

namespace RENDER
{
	void renderModel( Model& model, bool useMaterialColor)
	{
		glMatrixMode(GL_MODELVIEW);
		glPushMatrix();

		glMultMatrixf( model.getModelMatrixRef().getPtr()  );

		for (int i=0; i<model.getMeshes().size(); ++i)
		{
			if ( useMaterialColor )
			{
				applyMeshColor( model.getMeshes()[i] );
			}
			else
			{
				glColor3f( 1.0, 1.0, 1.0 );
			}

			VBOmanager::renderVBO(model.getMeshes()[i].vbo_data, model.getMeshes()[i].textures);
		}

		glPopMatrix();
	}

	void renderModelNoModelTransform( Model& model)
	{
		for (int i=0; i<model.getMeshes().size(); ++i)
		{
			applyMeshColor( model.getMeshes()[i] );
			VBOmanager::renderVBO(model.getMeshes()[i].vbo_data, model.getMeshes()[i].textures);
		}
	}

	void applyMeshColor( const MeshObject& mesh)
	{
		if ( mesh.material!=NULL )
		{
			assert(mesh.material->getMaterialType()== PHONG);
			PhongMaterial *material = (PhongMaterial*) mesh.material;
			glColor3fv( material->diffuse );
		}
		else
		{
			glColor3f( 0,0,0 );
		}
	}
}