#ifndef __AUTOCAMERA_H
#define __AUTOCAMERA_H

#ifndef __CAMERA_H
#include "camera.h"
#endif  /* __CAMERA_H */

#ifndef __BSPLINE_H
#include "bspline.h"
#endif  /* __BSPLINE_H */


/* for the time of autoCameraDataT */
#define AUTOCAMERA_END (-1)  /* end of automatic camera, time=0 */
#define AUTOCAMERA_ENDLESS (-2)  /* endless automatic camera */

struct autoCameraT
	{
	cameraT *camera;  /* camera */
	struct autoCameraDataT *autoCameraData;  /* automatic camera data */
	int time;  /* a frame number of a camera, incremented serialy */
	void *data;  /* for various use */
	float *target[3];  /* target coordinates for target-relative mode */
	float *forward[3];  /* forward vector for target-follow mode */
	float *velocity[3];  /* velocity vector for target-follow mode */
	float *standardHeight;  /* standard height for target-follow-2d mode */
	};
typedef struct autoCameraT autoCameraT;

struct autoCameraDataT
	{
	int time;  /* time of an automatic camera */
	void (*program)(autoCameraT *pAuto,void *pData);  /* a program */
	void *data;  /* an argument for forAutoForCamera->program */
	};
typedef struct autoCameraDataT autoCameraDataT;


void setAutoCamera(autoCameraT *pAuto);

void setAutoCameraCamera(autoCameraT *pAuto,void *pData);
void setAutoCameraAutoCameraData(autoCameraT *pAuto,void *pData);
void setAutoCameraData(autoCameraT *pAuto,void *pData);
void setAutoCameraTargetForwardVelocity(autoCameraT *pAuto,
		float *fTargetX,float *fTargetY,float *fTargetZ,
		float *fForwardX,float *fForwardY,float *fForwardZ,
		float *fVelocityX,float *fVelocityY,float *fVelocityZ,
		float *fStandardHeight);

void initializeAutoCameraBsplineTime(autoCameraT *pAuto,void *pData);

void initializeAutoCameraCommonAbsolute(autoCameraT *pAuto,void *pData);
void autoCameraBsplineAbsolute(autoCameraT *pAuto,void *pData);
void autoCameraBsplineAbsoluteUp(autoCameraT *pAuto,void *pData);
void autoCameraBsplineAbsoluteFov(autoCameraT *pAuto,void *pData);
void autoCameraBsplineAbsoluteUpFov(autoCameraT *pAuto,void *pData);

void initializeAutoCameraCommonLookRelative(autoCameraT *pAuto,void *pData);
void autoCameraBsplineLookRelative(autoCameraT *pAuto,void *pData);
void autoCameraBsplineLookRelativeUp(autoCameraT *pAuto,void *pData);
void autoCameraBsplineLookRelativeFov(autoCameraT *pAuto,void *pData);
void autoCameraBsplineLookRelativeUpFov(autoCameraT *pAuto,void *pData);

void initializeAutoCameraCommonCameraRelative(autoCameraT *pAuto,void *pData);
void autoCameraBsplineCameraRelative(autoCameraT *pAuto,void *pData);
void autoCameraBsplineCameraRelativeUp(autoCameraT *pAuto,void *pData);
void autoCameraBsplineCameraRelativeFov(autoCameraT *pAuto,void *pData);
void autoCameraBsplineCameraRelativeUpFov(autoCameraT *pAuto,void *pData);

/* for initializer of target-relative, use that of look-relative */
void autoCameraBsplineTargetRelative(autoCameraT *pAuto,void *pData);
void autoCameraBsplineTargetRelativeUp(autoCameraT *pAuto,void *pData);
void autoCameraBsplineTargetRelativeFov(autoCameraT *pAuto,void *pData);
void autoCameraBsplineTargetRelativeUpFov(autoCameraT *pAuto,void *pData);

#ifdef CAMERAFOLLOW
void initializeAutoCameraCommonFollow(autoCameraT *pAuto,void *pData);
#endif  /* CAMERAFOLLOW */

void initializeAutoCameraCommonFollow2d(autoCameraT *pAuto,void *pData);
void autoCameraBsplineFollow2d(autoCameraT *pAuto,void *pData);
void autoCameraBsplineFollow2dUp(autoCameraT *pAuto,void *pData);
void autoCameraBsplineFollow2dFov(autoCameraT *pAuto,void *pData);
void autoCameraBsplineFollow2dUpFov(autoCameraT *pAuto,void *pData);


#endif  /* __AUTOCAMERA_H */
