/* camera.h: virtual camera management */

#ifndef _CAMERA_H_
#define _CAMERA_H_

#include "vector.h"
#include "color.h"

#ifdef __cplusplus
extern "C" {
#endif

typedef struct CAMERA {
	VECTOR eyep, 		/* virtual camera position in 3D space */
	       lookp,		/* focus point of camera */
	       updir;		/* direction pointing upward */
	float viewdist;		/* distance from eyepoint to focus point */
	float fov, hfov, vfov;	/* field of view, horizontal and vertical,
				 * in degrees. */
	float near, far;	/* near and far clipping plane distance */
	int hres, vres;		/* horizontal and vertical resolution */
	VECTOR X, Y, Z;		/* eye coordinate system: X=right, Y=down, Z=viewing direction */
	RGB background;		/* window background color */
	int changed;		/* True when camera position has been updated */
} CAMERA;

extern CAMERA Camera;		/* The one and only virtual camera */

extern CAMERA *CameraCreate(void);
extern void CameraDestroy(CAMERA *camera);

/* sets virtual camera position, focus point, up-direction, field of view
 * (in degrees), horizontal and vertical window resolution and window
 * background. Returns (CAMERA *)NULL if eyepoint and focus point coincide or
 * viewing direction is equal to the up-direction. */
extern CAMERA *CameraSet(CAMERA *cam, 
			 VECTOR *eyep, VECTOR *lookp, VECTOR *updir, 
			 float fov, int hres, int vres, RGB *background);

/* sets only field-of-view, up-direction, focus point, camera position */
extern CAMERA *CameraSetFov(CAMERA *cam, float fov);
extern CAMERA *CameraSetUpdir(CAMERA *cam, float x, float y, float z);
extern CAMERA *CameraSetLookp(CAMERA *cam, float x, float y, float z);
extern CAMERA *CameraSetEyep(CAMERA *cam, float x, float y, float z);

/* moves and rotates the camera, e.g. as reaction to mouse movements on
 * the canvas window */
extern CAMERA *CameraMoveForward(CAMERA *cam, float step);
extern CAMERA *CameraMoveRight(CAMERA *cam, float step);
extern CAMERA *CameraMoveUp(CAMERA *cam, float step);
extern CAMERA *CameraTurnRight(CAMERA *cam, float angle);
extern CAMERA *CameraTurnUp(CAMERA *cam, float angle);
extern CAMERA *CameraTilt(CAMERA *cam, float angle);
extern CAMERA *CameraZoom(CAMERA *cam, float amount);

/* camera postition etc.. can be saved on a stack of size MAXCAMSTACK. */
#define MAXCAMSTACK 20

/* saves/restores the virtual camera on/from the stack */
extern void CameraPush(CAMERA *cam);
extern CAMERA *CameraPop(CAMERA *cam);

/* returns pointer to the next saved camera. If previous==NULL, the first saved
 * camera is returned. In subsequent calls, the previous camera returned
 * by this function should be passed as the parameter. If all saved cameras
 * have been iterated over, NULL is returned. */
extern CAMERA *NextSavedCamera(CAMERA *previous);

/* creates a dialog offering the predefined views in the file. ui_camera.c */
extern void CreatePredefViewButtons(int nr, CAMERA *views, char **descriptions);

/* in ui_camera.c */
extern void GoToNextView(void), GoToPreviousView(void), GoToViewNr(int viewnr);

#ifdef __cplusplus
}
#endif

#endif /*CAMERA_H_*/
