#pragma once


#include  "tools++.h"
#include  "NiTool.h"

#include  "Vector.h"
#include  "Rotation.h"
#include  "NiToolWin.h"





#define   NI_JTXT_FILE_ID		"NI_JOINTS_TEXT_FILE"


#define	  NI_JOINT_NUM			34	//
#define	  NI_JOINT_NAME_NUM	    34	// 
#define	  NI_MAX_JOINT_NUM		NI_JOINT_NUM	//

#define	  NI_OPENNI_JOINT_NUM	25	// OPENNI_MAX_JOINT_NUM
#define   NI_KINECT_JOINT_NUM	20	// KINECT_MAX_JOINT_NUM, NUI_SKELETON_POSITION_COUNT





//////////////////////////////////////////////////////////////////////////
//
// 共通ジョイント番号
//
#define	  NI_PELVIS		 0
#define	  NI_TORSO		 1
#define	  NI_WAIST		 2
#define	  NI_CHEST		 3
#define	  NI_NECK		 4
#define	  NI_HEAD		 5
#define	  NI_SKULL		 6

#define	  NI_L_EYE		 7
#define	  NI_R_EYE		 8
#define	  NI_L_BUST		 9
#define	  NI_R_BUST		10

#define   NI_L_COLLAR	11
#define   NI_L_SHLDR	12
#define   NI_L_ELBOW	13
#define	  NI_L_WRIST	14
#define	  NI_L_HAND		15

#define   NI_R_COLLAR	16
#define	  NI_R_SHLDR	17
#define	  NI_R_ELBOW	18
#define	  NI_R_WRIST	19
#define	  NI_R_HAND		20

#define	  NI_L_HIP		21
#define   NI_L_KNEE		22
#define	  NI_L_ANKLE	23
#define	  NI_L_FOOT		24
#define	  NI_L_TOE		25
	
#define	  NI_R_HIP		26
#define	  NI_R_KNEE		27
#define	  NI_R_ANKLE	28
#define	  NI_R_FOOT		29
#define	  NI_R_TOE		30

#define	  NI_L_FINGER	31		// Parameter of Finger (Dummy Joint)
#define	  NI_R_FINGER	32		// Parameter of Finger (Dummy Joint)
#define   NI_FACE		33		// Parameter of Expression (Dummy Joint)



//////////////////////////////////////////////////////////////////////////
//
// SDK(OpenNI, Kinect SDK)用 作業ジョイント番号．
// 二つのSDKのジョイント名はこの名前に集約される．
//

extern int  NI_JNT_PELVIS;
extern int  NI_JNT_TORSO;
extern int  NI_JNT_NECK;
extern int  NI_JNT_HEAD;

extern int	NI_JNT_L_EYE;
extern int	NI_JNT_R_EYE;
extern int	NI_JNT_L_BUST;
extern int	NI_JNT_R_BUST;
	
extern int  NI_JNT_L_SHLDR;
extern int  NI_JNT_L_ELBOW;
extern int  NI_JNT_L_WRIST;
extern int  NI_JNT_L_HAND;
	
extern int  NI_JNT_R_SHLDR;
extern int  NI_JNT_R_ELBOW;
extern int  NI_JNT_R_WRIST;
extern int  NI_JNT_R_HAND;

extern int  NI_JNT_L_HIP;
extern int  NI_JNT_L_KNEE;
extern int  NI_JNT_L_ANKLE;
extern int  NI_JNT_L_FOOT;
	
extern int  NI_JNT_R_HIP;
extern int  NI_JNT_R_KNEE;
extern int  NI_JNT_R_ANKLE;
extern int  NI_JNT_R_FOOT;

extern int  NI_JNT_L_FINGER;
extern int  NI_JNT_R_FINGER;
extern int  NI_JNT_FACE;




namespace jbxwl {

using namespace jbxl;



///////////////////////////////////////////////////////////////////////////////////////

typedef struct __NiJointData
{
	int				joint;
	int				index;

	Vector<double>	vect;
	Quaternion		quat;
	//
} NiJointData;




typedef struct __NiFrameData
{
	int			 frmn;		// フレーム番号
	int			 msec;		// フレーム時間
	int			 jnum;		// Joint の数
	NiJointData* jdat;
	//
} NiFrameData;





///////////////////////////////////////////////////////////////////////////////////////

// 共通のジョイントの名前と番号
std::string	NiJointName(int n);
int			NiJointNum(char* name);


// SDK 固有のジョイント番号から共通のジョイント名を得る
std::string	NiSDK2JointName(int joint, NiSDK_Lib lib);

// SDK 固有のジョイント番号からミラージョイントの番号を得る
int			NiSDKMirrorJointNum(int joint, NiSDK_Lib lib);

#define		NiMirrorJointNum(j)  NiSDKMirrorJointNum((j), NiSDK_None)


// 共通のジョイント名から Library 固有のジョイント番号を得る
int			JointName2NiSDK(char* jname, NiSDK_Lib lib);

// 共通ジョイント番号から，SDK 固有の座標用または回転用ジョイント番号を得る
int			Ni2SDKPosJointNum(int joint, NiSDK_Lib lib);
int			Ni2SDKRotJointNum(int joint, NiSDK_Lib lib);

#define     Ni2SDKJointNum(j, l)  Ni2SDKPosJointNum((j), (l))


// SDK 固有のジョイント番号を設定する
void		NiSetKinectJointNums(void);
void		NiSetOpenNIJointNums(void);


// Frame
NiFrameData* makeFixFrameData(int frame, int  jnum);
NiFrameData* makeVarFrameData(int frame, int* jnum, int* frtm=NULL);
void		 freeFrameData(NiFrameData* frmdata, int frm_num);





////////////////////////////////////////////////////////////////////////////////////////
//
//  CBaseFrameTool Class
//

class CBaseFrameTool
{
public:
	CBaseFrameTool(void)  { frameData = NULL;}
	~CBaseFrameTool(void) {}

	NiJointData*	frameData;

public:
	virtual NiJointData* getFrameData(int frmnum) { return frameData;}

};






////////////////////////////////////////////////////////////////////////////////////////
//
//  CJTextTool Class
//

class CJTextTool : public CBaseFrameTool
{
public:
	CJTextTool(void)  { init();}
	~CJTextTool(void) { clearData();}


public:
	void			init(void);
	void			clearData(void);

	BOOL			readFile(FILE* fp);

	void			writeHeader(FILE* fp) { if (fp!=NULL) fprintf(fp, "%s\n", NI_JTXT_FILE_ID);}
	void			writeData(FILE* fp, unsigned short msec);

	void			setPosVect(Vector<double>* pos, NiSDK_Lib lib, BOOL mirror);
	void			setRotQuat(Quaternion* rot,     NiSDK_Lib lib, BOOL mirror);

	NiFrameData*	getJointsFrame(void)  { return jtxt_joints;}
	unsigned int	getFrameNumber(void)  { return jtxt_frmnum;}


public:
	//
	NiFrameData*	jtxt_joints;
	unsigned int	jtxt_frmnum;

	//
	virtual NiJointData* getFrameData(int frmnum);
	//
	NiJointData		frame_data[NI_JOINT_NUM];


public:
	// Joints
	void			clearJointsData(double val=-1.0);

	Vector<double>	posVect[NI_JOINT_NUM];
	Quaternion		rotQuat[NI_JOINT_NUM];
};




}	// name space









/*
//
// OpenNI
//
	PELVIS					( 0)
	XN_SKEL_HEAD			( 1)
	XN_SKEL_NECK			( 2)
	XN_SKEL_TORSO			( 3)
	XN_SKEL_WAIST			( 4)

	XN_SKEL_LEFT_COLLAR		( 5)
	XN_SKEL_LEFT_SHOULDER	( 6)
	XN_SKEL_LEFT_ELBOW		( 7)
	XN_SKEL_LEFT_WRIST		( 8)
	XN_SKEL_LEFT_HAND		( 9)
	XN_SKEL_LEFT_FINGERTIP	(10)

	XN_SKEL_RIGHT_COLLAR	(11)
	XN_SKEL_RIGHT_SHOULDER	(12)
	XN_SKEL_RIGHT_ELBOW		(13)
	XN_SKEL_RIGHT_WRIST		(14)
	XN_SKEL_RIGHT_HAND		(15)
	XN_SKEL_RIGHT_FINGERTIP	(16)

	XN_SKEL_LEFT_HIP		(17)
	XN_SKEL_LEFT_KNEE		(18)
	XN_SKEL_LEFT_ANKLE		(19)
	XN_SKEL_LEFT_FOOT		(20)

	XN_SKEL_RIGHT_HIP		(21)
	XN_SKEL_RIGHT_KNEE		(22)
	XN_SKEL_RIGHT_ANKLE		(23)
	XN_SKEL_RIGHT_FOOT		(24)
*/


/*
//
// Kinect SDK
//
	NUI_SKELETON_POSITION_HIP_CENTER	  ( 0)
	NUI_SKELETON_POSITION_SPINE			  ( 1)
	NUI_SKELETON_POSITION_SHOULDER_CENTER ( 2)
	NUI_SKELETON_POSITION_HEAD			  ( 3)

	NUI_SKELETON_POSITION_SHOULDER_LEFT   ( 4)
	NUI_SKELETON_POSITION_ELBOW_LEFT	  ( 5)
	NUI_SKELETON_POSITION_WRIST_LEFT	  ( 6)
	NUI_SKELETON_POSITION_HAND_LEFT		  ( 7)

	NUI_SKELETON_POSITION_SHOULDER_RIGHT  ( 8)
	NUI_SKELETON_POSITION_ELBOW_RIGHT	  ( 9)
	NUI_SKELETON_POSITION_WRIST_RIGHT	  (10)
	NUI_SKELETON_POSITION_HAND_RIGHT	  (11)

	NUI_SKELETON_POSITION_HIP_LEFT		  (12)
	NUI_SKELETON_POSITION_KNEE_LEFT		  (13)
	NUI_SKELETON_POSITION_ANKLE_LEFT	  (14)
	NUI_SKELETON_POSITION_FOOT_LEFT		  (15)

	NUI_SKELETON_POSITION_HIP_RIGHT		  (16)
	NUI_SKELETON_POSITION_KNEE_RIGHT	  (17)
	NUI_SKELETON_POSITION_ANKLE_RIGHT	  (18)
	NUI_SKELETON_POSITION_FOOT_RIGHT	  (19)
*/