#include "CollisionModel.hpp"

#include "gl.hpp"

CollisionModel::CollisionModel(Vector3f Min, Vector3f Max):
min(Min),
max(Max)
{
}

bool CollisionModel::CheckCollision(	const CollisionModel& CM1, Vector3f Pos1,
								const CollisionModel& CM2, Vector3f Pos2)
{
	//use the seperate axis theorem, as soon as we have a seperate axis, we have no collision
	Vector3f Min1=CM1.min+Pos1, Min2=CM2.min+Pos2, Max1=CM1.max+Pos1, Max2=CM2.max+Pos2;

	//x
	if(Max1.x < Min2.x || Max2.x < Min1.x)
		return false;
	//y
	if(Max1.y < Min2.y || Max2.y < Min1.y)
		return false;
	//z
	if(Max1.z < Min2.z || Max2.z < Min1.z)
		return false;

	return true;
}
	
Vector3f CollisionModel::CollisionNormal(	const CollisionModel& CM1, Vector3f Pos1, Vector3f Vel1,
											const CollisionModel& CM2, Vector3f Pos2)
{
	Vector3f Min1=CM1.min+Pos1, Min2=CM2.min+Pos2, Max1=CM1.max+Pos1, Max2=CM2.max+Pos2;

	//time until collision, if we would just move along one axis
	float I=133700.001337f; //we just need a big initialisation number as we need the minimum of the following:
	float timeX=I, timeY=I, timeZ=I;

	if(Vel1.x>0)
		timeX=(Min2.x-Max1.x)/Vel1.x;
	if(Vel1.x<0)
		timeX=(Min1.x-Max2.x)/-Vel1.x;//we need the abs velocity for distance calculation!

	if(Vel1.y>0)
		timeY=(Min2.y-Max1.y)/Vel1.y;
	if(Vel1.y<0)
		timeY=(Min1.y-Max2.y)/-Vel1.y;
	
	if(Vel1.z>0)
		timeZ=(Min2.z-Max1.z)/Vel1.z;
	if(Vel1.z<0)
		timeZ=(Min1.z-Max2.z)/-Vel1.z;

	//negative time means that the object has already passed the distance in the past, so it can't reflect here
	if(timeX<0) timeX=I;
	if(timeY<0) timeY=I;
	if(timeZ<0) timeZ=I;

	if(timeX < timeY && timeX < timeZ)
		return Vector3f(1, 0, 0);
	if(timeY < timeX && timeY < timeZ)
		return Vector3f(0, 1, 0);
	if(timeZ < timeY && timeZ < timeX)
		return Vector3f(0, 0, 1);

	return Vector3f();
}

void CollisionModel::Render(Vector3f Position)
{
	glDisable(GL_DEPTH_TEST);
	glMatrixMode(GL_MODELVIEW);
	glPushMatrix();
	glTranslatef(Position.x, Position.y, Position.z);

	glColor3f(1, 1, 0);

	/*GLUquadric* Q=gluNewQuadric();
	gluQuadricDrawStyle(Q, GLU_LINE);
	
	gluSphere(Q, Object->GetCollisionModel().GetRadius(), 12,12);
	gluDeleteQuadric(Q);*/

	//draw the bounding box
	glColor3f(0, 0, 1);

	Vector3f A=max;
	Vector3f B=min;

	glBegin(GL_LINES);
	//lower quad
	glVertex3f(A.x, A.y, A.z);
	glVertex3f(B.x, A.y, A.z);

	glVertex3f(B.x, A.y, A.z);
	glVertex3f(B.x, B.y, A.z);

	glVertex3f(B.x, B.y, A.z);
	glVertex3f(A.x, B.y, A.z);

	glVertex3f(A.x, B.y, A.z);
	glVertex3f(A.x, A.y, A.z);

	//upper quad
	glVertex3f(A.x, A.y, B.z);
	glVertex3f(B.x, A.y, B.z);

	glVertex3f(B.x, A.y, B.z);
	glVertex3f(B.x, B.y, B.z);

	glVertex3f(B.x, B.y, B.z);
	glVertex3f(A.x, B.y, B.z);

	glVertex3f(A.x, B.y, B.z);
	glVertex3f(A.x, A.y, B.z);

	//sides
	glVertex3f(A.x, A.y, A.z);
	glVertex3f(A.x, A.y, B.z);

	glVertex3f(A.x, B.y, A.z);
	glVertex3f(A.x, B.y, B.z);

	glVertex3f(B.x, B.y, A.z);
	glVertex3f(B.x, B.y, B.z);

	glVertex3f(B.x, A.y, A.z);
	glVertex3f(B.x, A.y, B.z);

	glEnd();
	glColor3f(1, 1, 1);

	glPopMatrix();
	glEnable(GL_DEPTH_TEST);
}