#ifndef KINECTSKELETON_H__
#define KINECTSKELETON_H__

#define NUMBEROFSKELETONS 2

#include "KinectImageExport.h"
#include <QHash>
#include <vector>
#include <vnl/vnl_vector_fixed.h>
#include <itkDataObject.h>
#include <itkObjectFactory.h>

/*	@class		Skeleton
 *	@author		Sebastian Bauer
 *	@brief		User skeleton
 *
 *	@details
 */
typedef vnl_vector_fixed<float,3> VF3;
//

class  KINECTIMAGE_EXPORT KinectSkeleton : public itk::DataObject
{
public:
	/** @name Standard typedefs */
	//@{
	typedef KinectSkeleton							Self;
	typedef itk::DataObject						Superclass;
	typedef itk::SmartPointer<Self>				Pointer;
	typedef itk::SmartPointer<const Self>		ConstPointer;
	//@}

	/// Object creation
	itkNewMacro(Self);

	/// RTTI
	itkTypeMacro(KinectSkeleton, itk::DataObject);
	
	/// Body joints
	enum JointTypes
	{
		SKEL_HIP_Center			= 0,
		SKEL_TORSO				= 1, // Spine
		SKEL_NECK				= 2,
		SKEL_HEAD				= 3,
		
		SKEL_LEFT_SHOULDER		= 4,
		SKEL_LEFT_ELBOW			= 5,
		SKEL_LEFT_WRIST			= 6,
		SKEL_LEFT_HAND			= 7,
		
		SKEL_RIGHT_SHOULDER		= 8,
		SKEL_RIGHT_ELBOW		= 9,
		SKEL_RIGHT_WRIST		=10,
		SKEL_RIGHT_HAND			=11,

		SKEL_LEFT_HIP			=12,
		SKEL_LEFT_KNEE			=13,
		SKEL_LEFT_ANKLE			=14,
		SKEL_LEFT_FOOT			=15,

		SKEL_RIGHT_HIP			=16,
		SKEL_RIGHT_KNEE			=17,
		SKEL_RIGHT_ANKLE		=18,
		SKEL_RIGHT_FOOT			=19,
		SKEL_COM				=20, // Center of Mass
		SKEL_COUNT				=21
	};

	/// Body joints quality flags
	enum JointTrackingState
	{
		NOT_TRACKED	= 0,
		INFERRED	= 1,
		TRACKED		= 2
	};

	/// Skeleton quality flags

	enum SkeletonTrackingState
	{
		SKELETON_FULL				= 0,
		SKELETON_CLIPPED_RIGHT		= 1,
		SKELETON_CLIPPED_LEFT		= 2,
		SKELETON_CLIPPED_TOP		= 4,
		SKELETON_CLIPPED_BOTTOM		= 8
	};

	void SetJoint(JointTypes Joint, VF3 Pos, int idx);
	void SetJoint(int Joint, VF3 Pos, int idx);
	void SetJoint(JointTypes Joint, float PosX, float PosY, float PosZ, int idx);
	VF3  GetJoint(JointTypes Joint, int idx) const;

	void SetTrackingState(JointTypes Joint, short value, int idx);
	short GetTrackingState(JointTypes Joint, int idx) const;

protected:
	/// Constructor
	KinectSkeleton();
	/// Destructor
	virtual ~KinectSkeleton();

protected:
	/// The body joint positions of skeleton 1
	std::vector<VF3> m_JointPositions1;	
	/// The body joint positions of skeleton 2
	std::vector<VF3> m_JointPositions2;	

	/// The joint quality flags for each skeleton joints
	short m_TrackingState[KinectSkeleton::SKEL_COUNT * NUMBEROFSKELETONS];

private:
	/// purposely not implemented
	KinectSkeleton(Self&); 
	/// purposely not implemented
	void operator=(const Self&); 
};

#endif //KINECTSKELETON_H__
