// (c) Ubi Studios 1996
// See Vincent Greco for any comment or question

#ifndef __CAMERA_HPP__
#define __CAMERA_HPP__

//**************************************
#ifndef CPA_EXPORT
#if defined(CPA_WANTS_IMPORT)
#define CPA_EXPORT __declspec(dllimport)
#elif defined(CPA_WANTS_EXPORT)
#define CPA_EXPORT __declspec(dllexport)
#else
#define CPA_EXPORT
#endif
#endif
//**************************************
#include "incITF.h"
#include "dialogba.hpp"

typedef enum {InertCamera, ActorCamera} tdeCameraType;

class Camera : public CPA_BaseObject,
	public CPA_EdMot<GLI_tdxHandleToCamera>
{


public:
	Camera(tdeCameraType eType, CPA_ObjectDLLBase *p_oDLL,CPA_MainWorld* p_oMainWorld,GLI_tdxHandleToCamera hObj,
			   CString csName = "",CString csFileName = "",CString csSectionName = "");

	Camera(tdeCameraType eType, CPA_ObjectDLLBase *p_oDLL,CPA_MainWorld* p_oMainWorld,CString csName = "",
			CString csFileName = "",CString csSectionName = "");

//copy constructor
	Camera(Camera& src);
	
	~Camera();
    void *GetEngineStruct() { return GetStruct(); };
	void SetEngineStruct (GLI_tdxHandleToCamera hObj) { SetStruct(hObj); }
//	void ReInit(GLI_tdxHandleToCamera hCamera);


	// members
private:
	tdeCameraType			m_eCameraType;
	
	tdeAxisSystem			m_eRotationAxisSystem;
	tdeAxisSystem			m_eTranslationAxisSystem;

	tdeRotationCenterType	m_eRotationCenterType;
	tdeTargetType			m_eTargetType;
	
	MTH3D_tdstVector		m_stRotationCenterPoint;
	tdeCoordsType			m_eRotationCenterPointCoordsType;
	CPA_SuperObject			*m_p_oRotationCenterSuperObject;

	MTH3D_tdstVector		m_stTargetPoint; // world coordinates always
	CPA_SuperObject			*m_p_oTargetSuperObject;

	POS_tdstCompletePosition m_stCameraMatrix; 
	BOOL	m_bActive;							// tells wether the m_hDevice and m_hViewport are valid or not

	DEV_ViewPort3D			*m_p_oViewPort;

	CPA_Object				*m_p_oActor;	//if it's an actor camera, this is the actor
	CPA_SuperObject			*m_p_oActorSO;	// and this is the actor SuperObject

	DialogBar				m_oDialogBar;

	double					m_dTwistAngle;
	long					m_lTwistRemoveCount;
	BOOL					m_bPrivilegeMode;

	// methods
public:

	static void StaticInit();

    long   GetDataType ()  { return 0;   }
    void * GetData     ()  { return GetStruct(); }

	DEV_ViewPort3D *GetViewport() {return m_p_oViewPort;};	

	POS_tdstCompletePosition *GetCameraMatrix() {return &m_stCameraMatrix;};
	DialogBar		*GetDialogBar() {return &m_oDialogBar;};	

	void OnToolBarCommand(UINT nID);
	void Preferences();
	void CompletePreferences();
	void FrontView();
	void BackView();
	void LeftView();
	void RightView();
	void TopView();
	void BottomView();

	BOOL IsActive() {return m_bActive;};
	BOOL IsInPrivilegeMode() {return m_bPrivilegeMode;};
	void SetPrivilegeMode(BOOL bMode);


	tdeCameraType GetCameraType() { return m_eCameraType; };

	void Activate( DEV_ViewPort3D *p_oViewPort, CPA_DialogBar *p_oPopUpParent, CPoint oPos);
	void Disactivate();

	void SetRotationAxisSystem(tdeAxisSystem eSystem);
	void SetTranslationAxisSystem(tdeAxisSystem eSystem);

	tdeAxisSystem GetRotationAxisSystem();
	tdeAxisSystem GetTranslationAxisSystem();

	BOOL SetRotationCenterType(tdeRotationCenterType eRotCenterType);
	tdeRotationCenterType GetRotationCenterType();
	tdeRotationCenterType GetEffectiveRotationCenterType();
	
	BOOL SetTargetType(tdeTargetType eTargetType);
	tdeTargetType GetTargetType();

	void SetRotationCenterPoint(CPA_CameraCoords *p_oRotationCenter, tdeCoordsType eType = Absolute);
	BOOL SetRotationCenterSuperObject(CPA_SuperObject *p_oSuperObject);
	CPA_SuperObject *GetRotationCenterSuperObject() {return m_p_oRotationCenterSuperObject;};
	BOOL GetRotationCenter(MTH3D_tdstVector &r_stCenter);
	void GetRotationCenterPoint(MTH3D_tdstVector &r_stPoint, tdeCoordsType &r_eType);

	void GetTargetPoint(MTH3D_tdstVector &r_stPoint);
	void SetTargetPoint(CPA_CameraCoords *p_oRotationCenter);
	BOOL SetTargetSuperObject(CPA_SuperObject *p_oSuperObject);
	CPA_SuperObject *GetTargetSuperObject() {return m_p_oTargetSuperObject;};
	BOOL GetTarget(MTH3D_tdstVector &r_stTarget);

	void Translate(CPA_CameraCoords *p_oOffset, BOOL bUserDefinedAxis = FALSE);
	void SetPosition(CPA_CameraCoords *p_oPos = NULL);

	void Rotate(tdeAxis eAxis, double dAngle);
	void SetRotation(double dAngleX = 0, double dAngleY = 0, double dAngleZ = 0);

	void GetMatrix(POS_tdstCompletePosition *p_oMatrix);
	void SetMatrix(POS_tdstCompletePosition *p_oMatrix);
	
	void ZoomOnTarget(CPA_SuperObject *p_oSuperObject = NULL);

	void Update();
	void UpdateFromEngine();

	void ShowDialogBar() {m_oDialogBar.Show();};
	void HideDialogBar() {m_oDialogBar.Hide();};

	void CameraToWorldCoordinates_Point(MTH3D_tdstVector &r_stVector);
	void CameraToWorldCoordinates_Vector(MTH3D_tdstVector &r_stVector);
	void WorldToCameraCoordinates_Point(MTH3D_tdstVector &r_stVector);
	void WorldToCameraCoordinates_Vector(MTH3D_tdstVector &r_stVector);

private:
	
	void ResetCameraRotationMatrix();
	void ResetCamera();

	void InternalUpdate();
	void InternalBackUpdate();

	void CameraOriginalToWorldCoordinates(MTH3D_tdstVector &r_stVector);

	void WorldToCameraOriginalCoordinates(MTH3D_tdstVector &r_stVector);

	void BuildRotationMatrix_X(POS_tdstCompletePosition &r_stMatrix, double xXAngle);
	void BuildRotationMatrix_Y(POS_tdstCompletePosition &r_stMatrix, double xXAngle);
	void BuildRotationMatrix_Z(POS_tdstCompletePosition &r_stMatrix, double xXAngle);

	void RotateCameraToSeePoint(MTH3D_tdstVector *p_stTarget);

	void RemoveTwist();
	void SetTwist();
	void ResetTwist();
	double GetRealTwistAngle();
	// toolbar
	void InitInertCameraToolBar();

};

#endif //__CAMERA_HPP__