#ifndef __FCAMERA_H
#define __FCAMERA_H


enum forCameraMode
	{
	FCM_ABSOLUTE=1,
	FCM_RELATIVELOOK,
	FCM_RELATIVECAMERA,
	FCM_FOLLOW,
	FCM_FOLLOW2D
	};
typedef enum forCameraMode forCameraMode;


struct forCameraCommon
	{
	float
			toUp[3],toUpRate,
			toFov,toFovRate,
			toSlide[2],toSlideRate[2];
	};
typedef struct forCameraCommon forCameraCommon;


struct forCameraAbsolute
	{
	float
			toLook[3],toLookRate,
			toCamera[3],toCameraRate;
	};
typedef struct forCameraAbsolute forCameraAbsolute;

struct forCameraCommonAbsolute
	{
	struct forCameraCommon common;
	struct forCameraAbsolute absolute;
	};
typedef struct forCameraCommonAbsolute forCameraCommonAbsolute;


struct forCameraRelative
	{
	float
			basePoint[3],baseDirection,baseAngle,
			distance,toDistance,toDistanceRate,
			direction,toDirection,toDirectionRate,
			angle,toAngle,toAngleRate;
	};
typedef struct forCameraRelative forCameraRelative;

struct forCameraCommonRelative
	{
	struct forCameraCommon common;
	struct forCameraRelative relative;
	};
typedef struct forCameraCommonRelative forCameraCommonRelative;


struct forCameraFollow
	{
	float
			basePoint[3],
			followPoint[3],followDistance,
			forward[3],forwardRate,
			cameraDistance,toCameraDistance,toCameraDistanceRate;
	};
typedef struct forCameraFollow forCameraFollow;

struct forCameraCommonFollow
	{
	struct forCameraCommon common;
	struct forCameraFollow follow;
	};
typedef struct forCameraCommonFollow forCameraCommonFollow;


struct forCameraFollow2D
	{
	float
			basePoint[3],standardHeight,baseMinHeight,baseMaxHeight,
			followPoint[2],followDistance,
			forward[2],forwardSlideRate,forwardMaxSlide,
			lookMinRate,lookMaxRate,
			cameraDistance,toCameraDistance,toCameraDistanceRate,
			cameraAngle,toCameraAngle,toCameraAngleRate,cameraHeightRate;
	int axis[3];  /* axis[0,1] : 2D field axis , axis[2] : vertical axis */
	};
typedef struct forCameraFollow2D forCameraFollow2D;

struct forCameraCommonFollow2D
	{
	struct forCameraCommon common;
	struct forCameraFollow2D follow2D;
	};
typedef struct forCameraCommonFollow2D forCameraCommonFollow2D;


struct forCamera
	{
	float *look[3],*camera[3],*up[3],*fov,*slide[2];
	forCameraMode mode;  /* the value in FCM_* */
	struct forCameraCommon common;
			/* set always, importantly */
	union 
		{
		struct forCameraAbsolute absolute;
		struct forCameraRelative relative;
		struct forCameraFollow follow;
		struct forCameraFollow2D follow2D;
		}
		data;
	};
typedef struct forCamera forCamera;


void setForCamera(forCamera *pCamera,
		float *lookX,float *lookY,float *lookZ,
		float *cameraX,float *cameraY,float *cameraZ,
		float *upX,float *upY,float *upZ,
		float *fov,float *slideSide,float *slideUp);

void setForCameraAbsolute(forCamera *pCamera,
		const forCameraCommon *pCommon,const forCameraAbsolute *pAbsolute);
void setForCameraCommonAbsolute(forCamera *pCamera,
		const forCameraCommonAbsolute *pCommonAbsolute);

void setForCameraRelative(forCamera *pCamera,forCameraMode mode,
		const forCameraCommon *pCommon,const forCameraRelative *pRelative);
void setForCameraCommonRelative(forCamera *pCamera,forCameraMode mode,
		const forCameraCommonRelative *pCommonRelative);

void setForCameraFollow(forCamera *pCamera,
		const forCameraCommon *pCommon,const forCameraFollow *pFollow);
void setForCameraCommonFollow(forCamera *pCamera,
		const forCameraCommonFollow *pCommonFollow);

void setForCameraFollow2D(forCamera *pCamera,
		const forCameraCommon *pCommon,const forCameraFollow2D *pFollow2D);
void setForCameraCommonFollow2D(forCamera *pCamera,
		const forCameraCommonFollow2D *pCommonFollow2D);

void cameraCommon(forCamera *pCamera);
void cameraAbsolute(forCamera *pCamera);
void cameraRelative(forCamera *pCamera);
void cameraFollow(forCamera *pCamera);
void cameraFollow2D(forCamera *pCamera);


#endif  /* __FCAMERA_H */
