// Base3DObject.cpp

#include "Base3DObject.h"

Base3DObject::Base3DObject(bool ODEObject, bool model, std::string dir, std::string file, 
		dReal posx, dReal posy, dReal posz)
{
	position.x = posx;
	position.y = posy;
	position.z = posz;
	//orientation.x  = 0;
	//orientation.y  = 0;
	//orientation.z  = 0;

	has3DModel = model;
	filename = file;
	dirname = dir;

	isODEObject = ODEObject;
	thisIsTransparent = false;

#ifdef USING_VRJUGGLER //using Juggler's special context-specific data types
	*displayListNumber = -1;
#else //using normal data types
	displayListNumber = -1;
#endif


	if (has3DModel && !ODEObject) //ODE objects load their own models for now
	{
		//create OBJ object
		thisModel = new COBJModel();
		thisModel->LoadCOBJModel2(dirname, filename);
		//thisModel->ReadMTL();

		////setup bounding extremes
		//bboxMin.x = thisModel->Box[0];
		//bboxMax.x = thisModel->Box[1];
		//bboxMin.y = thisModel->Box[2];
		//bboxMax.y = thisModel->Box[3];
		//bboxMin.z = thisModel->Box[4];
		//bboxMax.z = thisModel->Box[5];

		////setup bbox center
		//bboxCenter.x = (bboxMin.x + bboxMax.x)/2;
		//bboxCenter.y = (bboxMin.y + bboxMax.y)/2;
		//bboxCenter.z = (bboxMin.z + bboxMax.z)/2;

		//Do this in a separate function so it can be done in VRJuggler's contextInit function.
		//thisModel->BuildList();
	}
}

Base3DObject::~Base3DObject()
{
}

void Base3DObject::SetPosition(point3d newposition)
{
	//re-implement this in derived classes
	position = newposition;
}

point3d Base3DObject::GetPosition()
{
	//re-implement this in derived classes
	return position;
}

void Base3DObject::SetOrientation(int axis, dReal angle)
{
	//re-implement this in derived classes
}

//point3d Base3DObject::GetOrientation()
//{
//	//re-implement this in derived classes
//	return orientation;
//}

bool Base3DObject::Update(dReal deltaTime)
{
	//give each object a chance to update things every frame
	//re-implement this in derived classes

	return true;
}

void Base3DObject::Draw()
{
	//re-implement this in derived classes

	if (has3DModel)
	{
		if (thisIsTransparent)
		{
			float matAmbientAndDiffuse[4] = {0.9, 0.9, 0.9, 0.7};
			glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, matAmbientAndDiffuse);
			glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
			glEnable(GL_BLEND);	
			glDepthMask(GL_FALSE);
		}

		glPushMatrix();
		glTranslatef(position.x, position.y, position.z);
		thisModel->DrawModel();
		glPopMatrix();

		if (thisIsTransparent)
		{
			glDisable(GL_BLEND);	
			glDepthMask(GL_TRUE);
		}
	}
	else
	{
		//do nothing -> no visual representation
	}
}

void Base3DObject::MakeDisplayList()
{
	//re-implement this in derived classes
	if (has3DModel)
	{
		thisModel->BuildList();
	}
}

bool Base3DObject::IsODEObject()
{
	return isODEObject;
}

bool Base3DObject::Has3DModel()
{
	return has3DModel;
}

void Base3DObject::SetTransparency(bool transparent)
{
	thisIsTransparent = transparent;
}