#pragma once

#include "volumeshop.h"

#include "Environment.h"
#include "Interactor.h"
#include "Vector.h"
#include "Timer.h"
#include "Matrix.h"
#include <float.h>
#include <math.h>

class InteractorPerspectiveCamera : public Interactor
{
public:

	InteractorPerspectiveCamera(Environment & envEnvironment) : m_envEnvironment(envEnvironment)
	{
	};

	virtual ~InteractorPerspectiveCamera()
	{
	};

	Environment & GetEnvironment()
	{
		return m_envEnvironment;
	};

	virtual void idle()
	{
	};

	virtual void underlay()
	{
	};

	virtual void display()
	{
	};

	virtual void overlay()
	{
	};

	virtual void reshape(const unsigned int uWidth, const unsigned int uHeight)
	{
		const Vector vecEye(0.0f,0.0f,sqrtf(3.0f));
		const Vector vecCenter(0.0f,0.0f,0.0f);
		const Vector vecUp(0.0f,1.0f,0.0f);

		const Vector vecF = (vecCenter - vecEye).GetNormalized();
		const Vector vecS = vecF.GetCross(vecUp.GetNormalized());
		const Vector vecU = vecS.GetCross(vecF);

		Matrix matViewingPreTransformation(vecS.GetX(),vecS.GetY(),vecS.GetZ(),0.0f, vecU.GetX(),vecU.GetY(),vecU.GetZ(),0.0f, -vecF.GetX(),-vecF.GetY(),-vecF.GetZ(),0.0f, 0.0f,0.0f,0.0f,1.0f);
		matViewingPreTransformation.translate(-vecEye);	
		GetEnvironment().SetViewingPreTransformation(matViewingPreTransformation);
/*
		Matrix matViewingPostTransformation;
		matViewingPostTransformation.translate(-vecEye);

		GetEnvironment().SetViewingPostTransformation(matViewingPostTransformation);
*/
		const float fFieldOfView = 45.0f;
		const float fAspectRatio = float(uWidth) / float(uHeight);
		const float fNear = 0.5*sqrtf(3.0f);//0.5f*sqrtf(3.0f);//1.0f / (2.0f*sqrtf(3.0f));
		const float fFar = 3.0f*sqrtf(3.0f);
		const float fF = 1.0f / tanf(0.5f * fFieldOfView);
		Matrix matProjectionPreTransformation(fF / fAspectRatio,0.0f,0.0f,0.0f, 0.0f,fF,0.0f,0.0f, 0.0f,0.0f,(fFar+fNear)/(fNear-fFar),(2.0f*fFar*fNear)/(fNear-fFar),  0.0f,0.0f,-1.0f,0.0f);	
		//matProjectionPreTransformation *= matViewingPreTransformation;
		GetEnvironment().SetProjectionPreTransformation(matProjectionPreTransformation);




		GetEnvironment().update();
	};

	virtual void mousePress(const MouseEvent & mouEvent)
	{
	};

	virtual void mouseRelease(const MouseEvent & mouEvent)
	{
	};


	virtual void mouseMove(const MouseEvent & mouEvent)
	{
	};

	virtual void keyboardPress(const KeyboardEvent & keyEvent) 
	{
	};

	virtual void keyboardRelease(const KeyboardEvent & keyEvent)
	{
	};

private:

	Environment & m_envEnvironment;
};