#include "Viewer.h"

extern int LIGHT_QUALITY;
extern float LIGHT_SIZE;


void Observer::zoomCamera( float zoom, Camera<float>& camera )
{
	float diffY = min( nearCameraLimit-1, zoom );
	camera.move_camera( diffY );
	float distance = camera.pos.get_distance( this->cameraPivot );

	if ( distance < nearCameraLimit )
	{
		camera.look =  this->cameraPivot - camera.pos;
		camera.look.normalize();
		camera.pos = this->cameraPivot - camera.look * nearCameraLimit; //move camera to NEAR_LIMIT distance
	}
	else if ( distance > farCameraLimit )
	{
		camera.look = this->cameraPivot - camera.pos;
		camera.look .normalize();
		camera.pos = this->cameraPivot - camera.look * farCameraLimit; //move camera to FAR_LIMIT distance
	}
}
void Observer::rotateCamera( float axisX, float axisY, Camera<float>& camera )
{
	camera.recalculate_up();
	float angle = camera.get_up().get_angle_Ang( MAKE_VECTOR<float>(0,1,0));

	if ( camera.look.get_dot_product( MAKE_VECTOR<float>(0,1,0)) > 0 )
	{
		angle = -angle;
	}

	angle += axisY;

	float rotY =axisY;

	if ( angle > this->maxVerticalAngle - EPSILON )
	{

		float overflow = angle - this->maxVerticalAngle;
		rotY = axisY- overflow;
		angle = this->maxVerticalAngle;
	}
	else if ( angle < this->minVerticalAngle - EPSILON )
	{
		float overflow = angle - this->minVerticalAngle;
		rotY = axisY - overflow;
		angle = this->minVerticalAngle;
	}

	camera.rotate_camera_axis( this->cameraPivot, MAKE_VECTOR<float>(0,1,0), -axisX );
	camera.rotate_camera_axis( this->cameraPivot, camera.right, -rotY );
}
void Observer::calibrateCamera( Camera<float>& camera )
{
	this->zoomCamera( 0, camera );
	this->rotateCamera( 0,0, camera );
}
Observer::Observer( void )
{
	this->nearCameraLimit = 10;
	this->farCameraLimit = 200;

	this->maxVerticalAngle = 80;
	this->minVerticalAngle = -80;
}
BasicViewer::BasicViewer(void)
{
	this->observerData.nearCameraLimit = 5;
	this->observerData.farCameraLimit = 50;

	this->observerData.maxVerticalAngle = 80;
	this->observerData.minVerticalAngle = -80;

	this->camera.look = MAKE_VECTOR<float>(0,0,-1);
	this->camera.look.normalize();
	this->camera.pos = this->observerData.cameraPivot - this->camera.look * this->observerData.nearCameraLimit ;
	this->camera.right = MAKE_VECTOR<float>(1,0,0);
	this->camera.recalculate_up();

}
void BasicViewer::handleKeyboard( Keyboard &keyboard )
{
	if ( keyboard.isPressed( Qt::Key_Left ) )
	{
		this->observerData.rotateCamera( 1, 0, this->camera );
	}
	if ( keyboard.isPressed( Qt::Key_Right ) )
	{
		this->observerData.rotateCamera( -1, 0, this->camera );
	}
	if ( keyboard.isPressed( Qt::Key_Up ) )
	{
		this->observerData.rotateCamera( 0, 1, this->camera );
	}
	if ( keyboard.isPressed( Qt::Key_Down ) )
	{
		this->observerData.rotateCamera( 0, -1, this->camera );
	}
	if ( keyboard.isPressed( Qt::Key_Plus ) )
	{
		this->observerData.zoomCamera( 0.5, this->camera );
	}
	if ( keyboard.isPressed( Qt::Key_Minus ) )
	{
		this->observerData.zoomCamera( -0.5, this->camera );
	}
}

void BasicViewer::handleMouse( Mouse &mouse )
{
	if ( mouse.pressedButtons[  Mouse::LEFT ] )
	{
		this->observerData.rotateCamera( mouse.getDiffX(), mouse.getDiffY(), this->camera );
	}

	this->observerData.zoomCamera(  mouse.wheel * 0.1, this->camera ); 
}


