#pragma once

#include "dllinterface.h"
//#include "..\Utilities\util.h"
#include <d3d9.h>
#include <D3DX9Math.h>
#include "DXVector3.h"
#include "DXMatrix.h"

class DXFUNCTIONS_API Camera
{
	DXVector3		m_vPosition;
	D3DXQUATERNION	m_qtRotation;
	DXMatrix		m_matView;
	DXMatrix		m_matProj;
	float			m_Near,m_Far;
	
public:
	Camera(void);
	Camera(const DXMatrix& matview, const DXMatrix& matproj);
	~Camera(void);

	void Reset(void);

	DXVector3 GetPosition(void) const {return m_vPosition;}
	void SetPosition(const DXVector3& pos);

	void SetRotation(const D3DXQUATERNION& rot);
	D3DXQUATERNION GetRotation(void) const {return m_qtRotation;}

	void SetLookAt(const DXVector3& lookat, const DXVector3& up);
	
	void SetPerspectiveProj(const float viewwidth, const float viewheight, const float znear, const float zfar){float m = znear/(viewwidth>viewheight?viewwidth:viewheight); D3DXMatrixPerspectiveLH((D3DXMATRIX*)&m_matProj,viewwidth*m,viewheight*m,znear,zfar);m_Near=znear;m_Far=zfar;}
	void SetPerspectiveProjEx(const float width, const float height, const float znear, const float zfar){D3DXMatrixPerspectiveLH((D3DXMATRIX*)&m_matProj,width,height,znear,zfar);m_Near=znear;m_Far=zfar;}
	void SetPerspectiveProjFov(const float fovy, const float aspect, const float znear, const float zfar){D3DXMatrixPerspectiveFovLH((D3DXMATRIX*)&m_matProj,fovy,aspect,znear,zfar);m_Near=znear;m_Far=zfar;}
	void SetOrthoProj(const float width, const float height, const float znear, const float zfar){D3DXMatrixOrthoLH((D3DXMATRIX*)&m_matProj,width,height,znear,zfar);m_Near=znear;m_Far=zfar;}

	DXVector3 GetYawPitchRoll(void) const;

	void SetProjMatrix(const DXMatrix& matProj);
	void SetViewMatrix(const DXMatrix& matView);
	
	DXVector3 GetViewUpVector(void) const {return DXVector3(m_matView._12,m_matView._22,m_matView._32);}
	DXVector3 GetViewRightVector(void)const {return DXVector3(m_matView._11,m_matView._21,m_matView._31);}
	DXVector3 GetViewDirVector(void) const {return DXVector3(m_matView._13,m_matView._23,m_matView._33);}

	//Rotates around the local XYZ Axis
	void Rotate(const DXVector3& angle);
	//Rotates around the camera XYZ Axis
	void RotateOriented(const DXVector3& angle);
	//Moves the camera in the local coordinate system
	void Move(const DXVector3& dp);
	//Moves the camera in its oriented coordinate system
	void MoveOriented(const DXVector3& dp);

	void FlipSide(void);

	float GetAspectRatio(void) const { return m_matProj._22 / m_matProj._11;}
	
	DXMatrix GetViewMatrix(void) const {return m_matView;}
	DXMatrix GetProjMatrix(void) const {return m_matProj;}

	float GetFarPlane(void) const {return m_Far;}
	float GetNearPlane(void) const {return m_Near;}

	void BuildView(const DXVector3 &Position, const DXVector3 &ViewDir, const DXVector3 &ViewRight, const DXVector3 &ViewUp);

	DXMatrix GetViewProjMatrix(void) const {return m_matView * m_matProj;}

	void GetMousePickRay(DXVector3& outOrig, DXVector3& outDir, const int MouseX, const int MouseY, const D3DVIEWPORT9* const ViewPort) const;
};
