/*
	Ninja Library

	COPYRIGHT (C) SEGA ENTERPRISES,LTD.

*/
#ifndef	_NJ_MOTION_H_
#define	_NJ_MOTION_H_

/*--------------------------------------*/
/*      Motion define                   */
/*--------------------------------------*/
/* motion type bits */

#define NJD_MTYPE_POS_0			BIT_0
#define NJD_MTYPE_ANG_1			BIT_1
#define NJD_MTYPE_SCL_2			BIT_2
#define NJD_MTYPE_VEC_3			BIT_3
#define NJD_MTYPE_VEC_0			BIT_4
#define NJD_MTYPE_SANG_1		BIT_5
#define	NJD_MTYPE_TARGET_3		BIT_6
#define	NJD_MTYPE_ROLL_6		BIT_7
#define	NJD_MTYPE_ANGLE_7		BIT_8
#define	NJD_MTYPE_RGB_8			BIT_9
#define	NJD_MTYPE_INTENSITY_9	BIT_10
#define	NJD_MTYPE_POINT_9		BIT_12
#define NJD_MTYPE_QUAT_1        BIT_13
#define NJD_MTYPE_SHAPEID		BIT_14    /* compact shape            */
#define NJD_MTYPE_EVENT_4		BIT_15

#define NJD_MTYPE_LINER         0x0000    /* use liner                */
#define NJD_MTYPE_SPLINE        0x0040    /* use spline               */
#define NJD_MTYPE_USER          0x0080    /* use user function        */
#define NJD_MTYPE_MASK          0x00c0    /* motion function mask     */



/*	Rotate Type of the return code of njGetMotionNodeData function */
#define	NJD_MROT_ANGLEXYZ		0
#define	NJD_MROT_ANGLEZXY		1
#define	NJD_MROT_QUATERNION		2

/* Motion event flag */
#define	NJD_EVENT_HIDE			BIT_0

/*
 * NJS_MOTION
*/
/* key frame animation */
typedef struct {
	Uint32          keyframe;
	Float           key[3];
} NJS_MKEY_F;

typedef struct {
	Uint32          keyframe;
	Angle           key[3];     /* angle                        */
} NJS_MKEY_A;

typedef struct {
	Uint16          keyframe;
	Sangle          key[3];     /* angle                        */
} NJS_MKEY_SA;

typedef struct {
	Uint32          keyframe;
	Angle           angle;      /* angle                        */
	Float           axe[3];     /* axe vector                   */
} NJS_MKEY_AX;

typedef struct
{
	Uint32          keyframe;
	void            *key;        /* pointer                     */
} NJS_MKEY_P;

typedef struct {
	Uint32          keyframe;
	Float           key;
} NJS_MKEY_F1;

typedef struct {
	Uint32          keyframe;
	Float           key[2];
} NJS_MKEY_F2;

typedef struct {
	Uint32          keyframe;
	Float           nrang;
	Float           frang;
	Angle           iang;
	Angle           oang;
} NJS_MKEY_SPOT;

typedef struct {
	Uint32          keyframe;
	Uint32          key;
} NJS_MKEY_UI32;

typedef struct {
	Uint32          keyframe;
	Sint32          key;
} NJS_MKEY_SI32, NJS_MKEY_A1;

typedef struct {
    Uint32          keyframe;
    Float           key[4];
} NJS_MKEY_QUAT;

typedef struct {
	Uint32          keyframe;
	Uint32          shapeId;
} NJS_MKEY_SHAPEID;

typedef struct {
	Uint16          keyframe;
	Sangle          key;
} NJS_MKEY_SA1;

typedef struct {
	Uint16          keyframe;
	Uint16          key;
} NJS_MKEY_UI16;

typedef struct {
	NJS_MKEY_SHAPEID    *keys;
	Uint16              nbKey;
	Uint16              entryId;
} NJS_CSHAPEDATA;

/*
 * NJS_MDATA
 */
/* 1 factor : pos or ang or scl or shape or vec */
typedef struct {
	void            *p[1];      /* factor pointer               */
	Uint32          nb[1];      /* factor count                 */
} NJS_MDATA1;

/* 2 factors : pos and ang, pos and vec(light motion), etc      */
typedef struct {
	void            *p[2];      /* factor pointer               */
	Uint32          nb[2];      /* factor count                 */
} NJS_MDATA2;

/* 3 factors : pos and ang and scl, pos and ang and shape, etc  */
typedef struct {
	void            *p[3];      /* factor pointer               */
	Uint32          nb[3];      /* factor count                 */
} NJS_MDATA3;

/* 4 factors : pos and ang and scl and shape, etc               */
typedef struct {
	void            *p[4];      /* factor pointer               */
	Uint32          nb[4];      /* factor count                 */
} NJS_MDATA4;

/* 5 factors : etc               */
typedef struct {
	void            *p[5];      /* factor pointer               */
	Uint32          nb[5];      /* factor count                 */
} NJS_MDATA5;

typedef struct {
	void            *mdata;     /* NJS_MDATA array              */
	Uint32          nbFrame;    /* frame count                  */
	Uint16          type;       /* motion type  NJD_MTYPE_...   */
	Uint16          inp_fn;     /* interpolation & factor count */
} NJS_MOTION;

typedef struct
{
	NJS_MOTION		*motion[2];		/* motion's pointers */
	Float			frame[2];		/* current frames */
} NJS_MOTION_LINK;


typedef struct {
	NJS_CNK_OBJECT  *object;    /* Object Tree top pointer      */
	NJS_MOTION      *motion;    /* motion                       */
#if 0
	NJS_TEXLIST     *texlist;   /* current texture list         */
#endif
} NJS_ACTION;

typedef struct
{
	NJS_CNK_OBJECT  *object;		/* object's pointer */
	NJS_MOTION_LINK	*motionlink;	/* motion-link's pointer */
} NJS_ACTION_LINK;


/*--------------------------------------*/
/*   Compact shape define               */
/*--------------------------------------*/

/*
 * NJS_CSHAPE
 */
/* compact shape animation */
typedef struct {
	Sint32          *cv;        /* chunk vertex pointer         */
} NJS_CSHAPECV;

typedef struct {
	NJS_CSHAPECV    *cvlist;    /* key frame group chunk vertex data */
	Uint16          groupId;    /* key frame group Id           */
	Uint16          reserved;   /* reserved zone                */
} NJS_CSHAPE_KEYGROUP;

typedef struct {
	NJS_CSHAPE_KEYGROUP *shapes;    /* key frame groups         */
	Uint32              nbShape;    /* key frame group count    */
} NJS_CSHAPELIST;


/*--------------------------------------*/
/*   Light & Camera Motion Structure    */
/*--------------------------------------*/

typedef struct {
	NJS_LIGHT	*light;
	NJS_MOTION	*motion;
} NJS_LACTION;

typedef struct {
	NJS_CAMERA	*camera;
	NJS_MOTION	*motion;
} NJS_CACTION;

typedef struct {
	Float	*pos;
	Angle	*ang;
	Float	*scl;
} NJS_MOTION_DATA;

typedef struct {
	Float	*pos;
	Float	*vect;
	Sangle	*roll;
	Sangle	*ang;
} NJS_CMOTION_DATA;

typedef struct {
	Float	*pos;
	Float	*rgb;
	Float	*rang;
} NJS_LMOTION_DATA;

typedef struct{
	Int 		n;
	NJS_LIGHT	**lights;
	NJS_MOTION	**motions;
}NJS_MLIGHT_MOTION;
/*		prototype declarations			*/

/*
	High level motion functions
*/

/*	set shape buffer	*/
void	njInitShape( void *buf, Sint32 size );
void	njSetShapeList( const NJS_CSHAPELIST *shape_list );
void	njSetMotionCallback( void (*func)(NJS_CNK_OBJECT *obj) );
void	njInitShapeLink( void *buf, Sint32 size );
void	njSetShapeLinkList( const NJS_CSHAPELIST *shape_list );

/*	draw motion */
void	njCnkEasyDrawMotion( const NJS_CNK_OBJECT *object, const NJS_MOTION *motion, Float frame );
void	njCnkSimpleDrawMotion( const NJS_CNK_OBJECT *object, const NJS_MOTION *motion, Float frame );
void	njCnkEasyMultiDrawMotion( const NJS_CNK_OBJECT *object, const NJS_MOTION *motion, Float frame );
void	njCnkSimpleMultiDrawMotion( const NJS_CNK_OBJECT *object, const NJS_MOTION *motion, Float frame );

/*	draw shape motion */
void	njCnkEasyDrawShapeMotion( const NJS_CNK_OBJECT *object, const NJS_MOTION *motion, const NJS_MOTION *shape, Float frame );
void	njCnkSimpleDrawShapeMotion( const NJS_CNK_OBJECT *object, const NJS_MOTION *motion, const NJS_MOTION *shape, Float frame );
void	njCnkEasyMultiDrawShapeMotion( const NJS_CNK_OBJECT *object, const NJS_MOTION *motion, const NJS_MOTION *shape, Float frame );
void	njCnkSimpleMultiDrawShapeMotion( const NJS_CNK_OBJECT *object, const NJS_MOTION *motion, const NJS_MOTION *shape, Float frame );

/*	draw motion link	*/
void	njCnkEasyDrawMotionLink( const NJS_CNK_OBJECT *object, const NJS_MOTION_LINK *motionlink, Float rate );
void	njCnkSimpleDrawMotionLink( const NJS_CNK_OBJECT *object, const NJS_MOTION_LINK *motionlink, Float rete );
void	njCnkEasyMultiDrawMotionLink( const NJS_CNK_OBJECT *object, const NJS_MOTION_LINK *motionlink, Float rate );
void	njCnkSimpleMultiDrawMotionLink( const NJS_CNK_OBJECT *object, const NJS_MOTION_LINK *motionlink, Float rate );

/*	draw shape motion link		*/
void	njCnkEasyDrawShapeMotionLink( const NJS_CNK_OBJECT *object, const NJS_MOTION_LINK *motionlink, const NJS_MOTION_LINK *shapelink, Float rate );
void	njCnkSimpleDrawShapeMotionLink( const NJS_CNK_OBJECT *object, const NJS_MOTION_LINK *motionlink, const NJS_MOTION_LINK *shapelink, Float rate );
void	njCnkEasyMultiDrawShapeMotionLink( const NJS_CNK_OBJECT *object, const NJS_MOTION_LINK *motionlink, const NJS_MOTION_LINK *shapelink, Float rate );
void	njCnkSimpleMultiDrawShapeMotionLink( const NJS_CNK_OBJECT *object, const NJS_MOTION_LINK *motionlink, const NJS_MOTION_LINK *shapelink, Float rate );

/*	get draw motion	*/
void	njGetDrawMotion( const NJS_CNK_OBJECT *object, const NJS_MOTION *motion, NJS_MOTION_DATA *data, Float frame );

/*	camera motion	*/
void	njCameraAction( const NJS_CACTION *caction, Float frame );
void	njCameraMotion( const NJS_CAMERA *camera, const NJS_MOTION *motion, Float frame );

/*	get camera motion	*/
void	njGetCameraAction( const NJS_CACTION *caction, NJS_CMOTION_DATA *data, Float frame );
void	njGetCameraMotion( const NJS_CAMERA *camera, const NJS_MOTION *motion, NJS_CMOTION_DATA *data, Float frame );

/*	light motion	*/
void	njLightAction( Int light_num, const NJS_LACTION *laction, Float frame );
void	njLightMotion( Int light_num, const NJS_LIGHT *light, const NJS_MOTION *motion, Float frame );

/*	get light motion	*/
void	njGetLightAction( const NJS_LACTION *laction, NJS_LMOTION_DATA *data, Float frame );
void	njGetLightMotion( const NJS_LIGHT *light, const NJS_MOTION *motion, NJS_LMOTION_DATA *data, Float frame );

/* multilight motion */
void	njMultiLightMotion(const NJS_MLIGHT_MOTION *mlight,Float frame);

/*
	Low level motion functions
*/

//	motion core
void	njStartMotionEx( const NJS_MOTION *motion, Float frame );
void	njSetNextMotionNodeEx( void );
void	njSetCurMotionInfoSlot( int Slot );

//	object motion
void	njStartMotionObj( const NJS_MOTION *motion, Float frame );
void	njStartMotionObjEx( const NJS_MOTION *motion, Float frame );
int		njGetMotionNodeData( const NJS_CNK_OBJECT *cnkobj, Float pos[3], Angle ang[3], Float scl[3], NJS_QUATERNION *qua );
void	njMotionTransformEx( const NJS_CNK_OBJECT *cnkobj );
void	njChangeMotionObject( NJS_CNK_OBJECT *cnkobj);
Sint32	njGetMotionEventFlag( void );

//	motion link
void	njStartMotionLink( const NJS_MOTION_LINK *motion_link, Float rate );
int		njGetMotionLinkNodeData( const NJS_CNK_OBJECT *cnkobj, Float pos[3], Angle ang[3], Float scl[3], NJS_QUATERNION *qua );
void	njMotionLinkTransformEx( const NJS_CNK_OBJECT *cnkobj );
void	njSetNextMotionLinkNode( void );

//	shape motion
void	njSetCurShapeInfoSlot( int Slot );
void	njStartShapeEx( const NJS_MOTION *shape, Float frame );
void	njSetNextShapeNodeEx( void );
void	njCalcShapeVlist( const NJS_CNK_MODEL *cnkmodel );
void	njGetShapeGroupID( void );
void	njSetShapeVlist( Uint32 *vlist, Uint32 vtype );

//	shape link
void	njStartShapeLink( const NJS_MOTION_LINK *shape_link, Float rate );
void	njSetNextShapeLinkNode( void );
void	njCalcShapeLinkVlist( const NJS_CNK_MODEL *cnkmodel );




//	Motion, Shape, MotionLink, ShapeLink with a specified function.
void	njDrawMotion( const NJS_CNK_OBJECT *object, const NJS_MOTION *motion, Float frame,
					   Sint32 ( *pDrawFunc )( NJS_CNK_MODEL *cnkmodel ) );

void	njDrawMotionLink( const NJS_CNK_OBJECT *object, const NJS_MOTION_LINK *motion_link,
						   Float rate, Sint32 ( *pDrawFunc )( NJS_CNK_MODEL *cnkmodel ) );

void	njCnkDrawShapeMotion( const NJS_CNK_OBJECT *object, const NJS_MOTION *motion, const NJS_MOTION *shape, Float frame, Float sframe,
							   Sint32 ( *pDrawFunc )( NJS_CNK_MODEL *cnkmodel ) );

void	njCnkDrawShapeLink( const NJS_CNK_OBJECT *object, const NJS_MOTION_LINK *motion_link, const NJS_MOTION_LINK *shape_link,
							 Float rate, Sint32 ( *pDrawFunc )( NJS_CNK_MODEL *cnkmodel ) );


#endif	/*_NJ_MOTION_H_*/
