/***************************************************************************
*                                                                          *
*  Copyright (C) Golaem S.A.  All Rights Reserved.                         *
*                                                                          *
***************************************************************************/

#pragma once

#include "glmSDKAPI.h"
#include "glmMotionDefinitions.h"
#include <glmGenericSkeleton.h>
#include <glmGroundSupportSequence.h>

#include <glmGolaemMotionDeclarations.h> // GolaemMotion declarations

namespace glm
{
	/**
	 * \brief Represent a channel in an animation
	 *
	 * \author dev@golaem.com
	 *
	 */
	class GLM_SDK_API LimbConfigurationV0
	{
		GLM_RTTI( "44e578cc-b507-4c64-a4aa-7c3c5cc96e9a", glm::LimbConfigurationV0, addAttributes )

	public:

		GLM_CLASS_STAT_ID( glm::MemoryStatIds::GolaemShared)

		//************************************************************
		//! @name Constructors and destructor
		//************************************************************
		//@{
		/**
		 * \brief Default constructor
		 */
		LimbConfigurationV0();
		//@}

		//************************************************************
		//! @name Initialization & construction
		//************************************************************
		//@{
		/**
		 * \brief Create the bones of the LimbConfigurationV0 according to the hierarchical skeleton and its generalization class
		 * \param skeleton 
		 */
		//void setMorphology(const GenericSpecificConverter* skeleton);

		/**
		 * \brief Finish the LimbConfigurationV0 (remove all bones)
		 */
		//void finish();			
		//@}

		//************************************************************
		//! @name Configuration
		//************************************************************
		//@{
		inline void setCoronalLocation(CoronalPlaneLocation::Value coronalLocation);
		inline CoronalPlaneLocation::Value getCoronalLocation() const;

		inline void setTransverseLocation(TransversePlaneLocation::Value transverseLocation);
		inline TransversePlaneLocation::Value getTransverseLocation() const;

		inline void setSagittalLocation(SagittalPlaneLocation::Value sagittalLocation);
		inline SagittalPlaneLocation::Value getSagittalLocation() const;

		inline void setSkeletonPartType(SkeletonPartType::Value partType);
		inline SkeletonPartType::Value getSkeletonPartType() const;

		inline void setDefaultReplayMode(AnimationReplayMode::Value defaultReplayMode);
		inline AnimationReplayMode::Value getDefaultReplayMode() const;

		inline int getGenericBoneIndex() const;
		inline void setGenericBoneIndex(int genericBoneIndex);
		inline int getSpineRange() const;
		inline void setSpineRange(int spineRange);
		inline bool isUsingLimb() const;
		inline void setUsingLimb(bool useLimb);
		inline bool isUsingEffector() const;
		inline void setUsingEffector(bool useEffector);
		//@}
		

		//************************************************************
		//! @name Accessors
		//************************************************************
		//@{
		inline GroundSupportSequence& touchConstraintSequence();

		inline const GroundSupportSequence& getConstraintSequence() const;
		//@}

	protected:
		/**
		 * \brief register the inspectable attributes to the class RTTI
		 */
		static void addAttributes() ;

	private:
		//************************************************************
		// Data
		//************************************************************
		//@{
		int _coronalLocation;
		int _transverseLocation;
		int _sagittalLocation;

		int _partType;

		int _defaultReplayMode;

		int	_genericBoneIndex;
		int _spineRange;
		bool _useLimb;
		bool _useEffectors;

		GroundSupportSequence _constraintSequence;
		//@}
	};



	//************************************************************
	// Definition of inline methods
	//************************************************************

	//------------------------------------------------------------
	// setCoronalLocation
	//------------------------------------------------------------
	inline void
		LimbConfigurationV0::setCoronalLocation(CoronalPlaneLocation::Value coronalLocation)
	{
		_coronalLocation=coronalLocation;
	}

	//------------------------------------------------------------
	// getCoronalLocation
	//------------------------------------------------------------
	inline CoronalPlaneLocation::Value
		LimbConfigurationV0::getCoronalLocation() const
	{
		return (CoronalPlaneLocation::Value)_coronalLocation;
	}

	//------------------------------------------------------------
	// setTransverseLocation
	//------------------------------------------------------------
	inline void
		LimbConfigurationV0::setTransverseLocation(TransversePlaneLocation::Value transverseLocation)
	{
		_transverseLocation=transverseLocation;
	}

	//------------------------------------------------------------
	// getTransverseLocation
	//------------------------------------------------------------
	inline TransversePlaneLocation::Value
		LimbConfigurationV0::getTransverseLocation() const
	{
		return (TransversePlaneLocation::Value)_transverseLocation;
	}

	//------------------------------------------------------------
	// setSagittalLocation
	//------------------------------------------------------------
	inline void
		LimbConfigurationV0::setSagittalLocation(SagittalPlaneLocation::Value sagittalLocation)
	{
		_sagittalLocation=sagittalLocation;
	}

	//------------------------------------------------------------
	// getSagittalLocation
	//------------------------------------------------------------
	inline SagittalPlaneLocation::Value 
		LimbConfigurationV0::getSagittalLocation() const
	{
		return (SagittalPlaneLocation::Value)_sagittalLocation;
	}

	//------------------------------------------------------------
	// setSkeletonPartType
	//------------------------------------------------------------
	inline void
		LimbConfigurationV0::setSkeletonPartType(SkeletonPartType::Value partType)
	{
		_partType=partType;
	}

	//------------------------------------------------------------
	// getSkeletonPartType
	//------------------------------------------------------------
	inline SkeletonPartType::Value
		LimbConfigurationV0::getSkeletonPartType() const
	{
		return (SkeletonPartType::Value)_partType;
	}

	//------------------------------------------------------------
	// setDefaultReplayMode
	//------------------------------------------------------------
	inline void
		LimbConfigurationV0::setDefaultReplayMode(AnimationReplayMode::Value defaultReplayMode)
	{
		_defaultReplayMode=defaultReplayMode;
	}

	//------------------------------------------------------------
	// getDefaultReplayMode
	//------------------------------------------------------------
	inline AnimationReplayMode::Value
		LimbConfigurationV0::getDefaultReplayMode() const
	{
		return (AnimationReplayMode::Value)_defaultReplayMode;
	}

	//------------------------------------------------------------
	// getGenericBoneIndex
	//------------------------------------------------------------
	inline int
		LimbConfigurationV0::getGenericBoneIndex() const
	{
		return _genericBoneIndex;
	}

	//------------------------------------------------------------
	// setGenericBoneIndex
	//------------------------------------------------------------
	inline void
		LimbConfigurationV0::setGenericBoneIndex(int genericBoneIndex)
	{
		_genericBoneIndex = genericBoneIndex;
	}

	//------------------------------------------------------------
	// getSpineRange
	//------------------------------------------------------------
	inline int
		LimbConfigurationV0::getSpineRange() const
	{
		return _spineRange;
	}
	
	//------------------------------------------------------------
	// setSpineRange
	//------------------------------------------------------------
	inline void
		LimbConfigurationV0::setSpineRange(int spineRange)
	{
		_spineRange=spineRange;
	}
	
	//------------------------------------------------------------
	// isUsingLimb
	//------------------------------------------------------------
	inline bool
		LimbConfigurationV0::isUsingLimb() const
	{
		return _useLimb;
	}
	
	//------------------------------------------------------------
	// setUsingLimb
	//------------------------------------------------------------
	inline void
		LimbConfigurationV0::setUsingLimb(bool useLimb)
	{
		_useLimb = useLimb;
	}

	//------------------------------------------------------------
	// isUsingEffector
	//------------------------------------------------------------
	inline bool
		LimbConfigurationV0::isUsingEffector() const
	{
		return _useEffectors;
	}
	
	//------------------------------------------------------------
	// setUsingEffector
	//------------------------------------------------------------
	inline void
		LimbConfigurationV0::setUsingEffector(bool useEffector)
	{
		_useEffectors=useEffector;
	}

	//------------------------------------------------------------
	// touchConstraintSequence
	//------------------------------------------------------------
	inline GroundSupportSequence&
		LimbConfigurationV0::touchConstraintSequence()
	{
		 return _constraintSequence;
	}
	//------------------------------------------------------------
	// getConstraintSequence
	//------------------------------------------------------------
	inline const GroundSupportSequence&
		LimbConfigurationV0::getConstraintSequence() const
	{
		 return _constraintSequence;
	}		
}
