#ifndef _GESTURE_H_
#define _GESTURE_H_

#include <string>
#include <vector>

namespace GestureDef{
	// Mingyu: 
	// The structs defined here should contain ONLY standard datatype to
	// make it independent to Ogre (Thus, no constructor involving Ogre variables)

	struct XYZ{
		float x;
		float y;
		float z;
	};

	struct ORI{
		float w;
		float x;
		float y;
		float z;
	};

	struct YPR{
		float yaw;
		float pitch;
		float roll;
	};

	struct Sample{			// follow the same order in memory array!  sizeof(Sample)= 14*sizeof(float)=56
		float timestamp;	// in ms
		XYZ   pos;			// position from PPT (real world position in meter)		
		ORI   ori;			// orientation from wiimote in quaternion
		XYZ   acc;			// acceleration in local x, y, z (g)
		YPR	  w;			// angular speed in yaw, pitch, roll (rad/s), RHS y-up
	};

	struct Gesture{
		std::string		name;		// name of this gesture
		std::string		tester;		// the tester who performs this gesture
		size_t			trial;		// the ith trial peformed by this tester
		size_t			length;		// the number of samples in this recorded gesture
		size_t			rightHand;	// 0: leftHand,  1: rightHand
		std::vector<Sample>	data;	// the streams of samples 

		// extra information for the gyro calibration
		// We DO NOT do HARD calibration while recording one gesture
		YPR noise;
		YPR bias;	
	};
	
	// utility functions for quaternion
	ORI quatMul(ORI q1, ORI q2);	
	ORI quatConj(ORI q);
	ORI quatNorm(ORI q);

	// Mingyu:
	// The enum and utility function to get the corresponding "gesture name"
	enum GestureName{
		// swipe eight directions
		SWIPE_RIGHT,
		SWIPE_LEFT,
		SWIPE_UP,
		SWIPE_DOWN,
		SWIPE_UPRIGHT,
		SWIPE_UPLEFT,
		SWIPE_DOWNRIGHT,
		SWIPE_DOWNLEFT,

		// back & forth
		POKE_RIGHT,
		POKE_LEFT,
		POKE_UP,
		POKE_DOWN,

		// others
		V_SHAPE,
		X_SHAPE,
		CIR_HOR_CLK,
		CIR_HOR_CCLK,
		CIR_VER_CLK,
		CIR_VER_CCLK,
		TWIST_CLK,
		TWITS_CCLK,

		TOTAL_GESTURES
	};
	
	// Global function to get the gesture name
	// Mingyu: a stupid implementation
	std::string getGestureName(int gestureIdx);

	// Global function to load the tester name/rightHand from a text file
	struct TesterInfo{
		std::string name;
		int rightHand;
	};
	//std::vector<TesterInfo> loadTestersInfo(std::string path);
}
#endif