#include "AABoundingBox.h"
#include "BoundingSphere.h"
#include "Material.h"


AABoundBox::AABoundBox(Vec3f max, Vec3f min)
{
	this->max = max;
	this->min = min;
	recalculateCenter();
}
//-------------------------------------------------------------------------
AABoundBox::~AABoundBox()
{

}
//-------------------------------------------------------------------------
void AABoundBox::setMax(Vec3f newMax)
{
	this->max = newMax;
	recalculateCenter();
}
//-------------------------------------------------------------------------
void AABoundBox::setMin(Vec3f newMin)
{
	this->min = newMin;
	recalculateCenter();
}
//-------------------------------------------------------------------------
void AABoundBox::setCenter(Vec3f newCenter)
{
	Vec3f translation = Vec3f(&center, &newCenter);
	this->center = newCenter;
	max.add(translation);
	min.add(translation);
}
//-------------------------------------------------------------------------
void AABoundBox::growByPoint(Vec3f newOne)
{
	if(newOne.x > max.x)
		max.x = newOne.x;
	if(newOne.x < min.x)
		min.x = newOne.x;

	if(newOne.y > max.y)
		max.y = newOne.y;
	if(newOne.y < min.y)
		min.y = newOne.y;

	if(newOne.z > max.z)
		max.z = newOne.z;
	if(newOne.z < min.z)
		min.z = newOne.z;
	recalculateCenter();
}
//-------------------------------------------------------------------------
Vec3f AABoundBox::getMax()
{
	return max;
}
//-------------------------------------------------------------------------
Vec3f AABoundBox::getMin()
{
	return min;
}
//-------------------------------------------------------------------------
Vec3f AABoundBox::getCenter()
{
	return center;
}
//-------------------------------------------------------------------------
void AABoundBox::recalculateCenter()
{
	center.x = (max.x + min.x) * 0.5;
	center.y = (max.y + min.y) * 0.5;
	center.z = (max.z + min.z) * 0.5;
}
//-------------------------------------------------------------------------
void AABoundBox::scale(float x, float y, float z)
{
	min.x *= x;
	min.y *= y;
	min.z *= z;

	max.x *= x;
	max.y *= y;
	max.z *= z;
}
//-------------------------------------------------------------------------
bool AABoundBox::collisionTest(AABoundBox* other)
{
	Vec3f otherMax = other->getMax();
	Vec3f otherMin = other->getMin();

	// no overlap in z-coords
	if( max.z < otherMin.z || min.z > otherMax.z)
		return false;

	// no overlap in x-coords
	if( max.x < otherMin.x || min.x > otherMax.x)
		return false;

	// no overlap in y-coords
	if( max.y < otherMin.y || min.y > otherMax.y)
		return false;

	return true;
}
//-------------------------------------------------------------------------
bool AABoundBox::collisionTest(BoundingSphere* other)
{
	Vec3f otherCenter = other->getCenter();
	float otherRadius = other->getRadius();


	// den Punkt der Kugel finden die der Box am nächsten ist
	Vec3f centerCenterVec = Vec3f(&otherCenter, &center);
	float distance = centerCenterVec.length();

	if(distance <= otherRadius)
		return true;

	centerCenterVec.normalize();
	centerCenterVec.scale(otherRadius);
	centerCenterVec.add(otherCenter);
		
	// centerCenterVec ist der gesuchte punkt

	// no overlap in z-coords
	if( max.z < centerCenterVec.z || min.z > centerCenterVec.z)
		return false;

	// no overlap in x-coords
	if( max.x < centerCenterVec.x || min.x > centerCenterVec.x)
		return false;

	// no overlap in y-coords
	if( max.y < centerCenterVec.y || min.y > centerCenterVec.y)
		return false;
	return false;
}
//-------------------------------------------------------------------------
void AABoundBox::render(Material* mat)
{
	Vec3f dimensions = Vec3f(&min, &max);

	if(mat)
		mat->activate();

	glPushMatrix();
		glTranslatef(center.x, center.y, center.z);
		glScalef(dimensions.x, dimensions.y, dimensions.z);
			glutWireCube(1);
	glPopMatrix();
}