/*
QtWagon: a project about 3D objects.
Science and technology promotion license applied. Third party license automatically cascaded.
Zhikai Wang/ www.heteroclinic.net 2013
You can do anything with this file or any file(s) published as part QtWagon project, given this header is kept.
*/
#ifndef __CAMERA
#define __CAMERA
#include <GL/glut.h> 

#include "glMovingObject.h"

typedef struct _StructPserpective {
	float fovy;
	float near_z;
	float far_z;
	float fovy_min;
	float fovy_max;

} StructPserpective, * p_StructPserpective;
typedef struct _StructOrthorgonal {
	float o_size1;
	float o_size2;
	float o_size3;
	float o_size4;
	float near_z;
	float far_z;
	float o_size_limit;
} StructOrthorgonal, * p_StructOrthorgonal;


class camera: public glMovingObjectf
{
protected:
	glOrientation<float> lastorientation;
	mathVector<float> swirludvector;
public:
	void camera::setSwirlVectors(mathVector<float> r);
	void initSwirlVectors();
	const mathVector<float> getSwirludvector();
	const glOrientation<float> getLastorientation();
	void setLookedAt (mathPoint<float> nmpt) ;
	bool showFocus;

	const mathPoint<float> getLookedAt();
	glMovingObjectf * followed_obj; // NULL => a free camera, else an attached camera

	StructPserpective spStructPserpective;
	StructOrthorgonal soStructOrthorgonal;

	float focusSize;
	float lookat_radius;
	float safe_lookat_radius;
	mathPoint<float>  LookedAt;
	bool orthorgonal_disp;
	bool free_camera;

	float default_deta_fb;
	float default_deta_fovy;
	float default_deta_osize;
	float default_deta_swirl;
	float default_deta_pan;


	camera( const mathPoint<float> & nglobalPosition  = mathPoint<float>((float)0.0,(float)0.0,(float)0.0));
	virtual ~camera();

	void drawFocus ();
	void initSp();
	void initSo();
	void zoomIn() ;
	void zoomOut() ;
	void increase_lookat_radius();
	void decrease_lookat_radius();
	void fb_lookat_radius(float deta_fb);
	void forward(float deta_fb);
	void updateLookat();


	void swirl(float angles,mathVector<float> tmpY );
	void backward(float deta_fb);
	void rotateAboutMatrix( const mathVector<float> & v, float theta) ;
	void RollYawPitch(unsigned char lastElement,float ROTATION_ANGLE);
	void roll(float degree = (float)1.0);
	void yaw(float degree = (float)1.0);
	void pitch(float degree = (float)1.0) ;
	void setPosition(const mathPoint<float> &npos ) ;

	void panLeftRight(float delta = (float)0.2);
	void panUpDown(float delta = (float)0.2);
	void panLevelForwardBackward(float delta = (float)0.2);
};

#endif