#pragma once

#include <vector>
#include <string>

#include "Mix/Tool/Win32/Core/Object.h"
#include "Mix/Tool/Win32/Core/File/InputStream.h"
#include "Mix/Tool/Win32/Core/File/OutputStream.h"

namespace Mix{ namespace Tool{ namespace Win32{ namespace Graphics{

	class ObjectModel;

	class MotionCurve : public Mix::Tool::Win32::Object
	{
	private:
		struct MC_DESC
		{
			wchar_t linkNodeName[32];

			unsigned int sKeyCount;
			unsigned int rKeyCount;
			unsigned int tKeyCount;

			unsigned int reserve;
		};

		struct MC_S_KEY
		{
			float time;
			float value[3];

			MC_S_KEY( void ) {}

			MC_S_KEY( const Mix::Tool::Win32::Graphics::VECTOR_KEY& key )
			{
				time = key.time;
				value[0] = key.value.x;
				value[1] = key.value.y;
				value[2] = key.value.z;
			}
		};

		struct MC_R_KEY
		{
			float time;
			float reserve;
			float value[4];

			MC_R_KEY( void ) {}

			MC_R_KEY( const Mix::Tool::Win32::Graphics::QUATERNION_KEY& key )
			{
				time = key.time;
				reserve = 0.0f;
				value[0] = key.value.x;
				value[1] = key.value.y;
				value[2] = key.value.z;
				value[3] = key.value.w;
			}

			MC_R_KEY( float _time, const D3DXQUATERNION& _value )
			{
				time = _time;
				reserve = 0.0f;
				value[0] = _value.x;
				value[1] = _value.y;
				value[2] = _value.z;
				value[3] = _value.w;
			}
		};

		struct MC_T_KEY
		{
			float time;
			float value[3];

			MC_T_KEY( void ) {}

			MC_T_KEY( const Mix::Tool::Win32::Graphics::VECTOR_KEY& key )
			{
				time = key.time;
				value[0] = key.value.x;
				value[1] = key.value.y;
				value[2] = key.value.z;
			}

			MC_T_KEY( float _time, const D3DXVECTOR3& _value )
			{
				time = _time;
				value[0] = _value.x;
				value[1] = _value.y;
				value[2] = _value.z;
			}

			MC_T_KEY( float _time, float _x, float _y, float _z )
			{
				time = _time;
				value[0] = _x;
				value[1] = _y;
				value[2] = _z;
			}
		};

	private:
		int m_Index;
		std::wstring m_LinkNodeName;

		Mix::Tool::Win32::Graphics::VectorKeyList m_ScalingKeyList;
		Mix::Tool::Win32::Graphics::QuaternionKeyList m_RotationKeyList;
		Mix::Tool::Win32::Graphics::VectorKeyList m_TranslationKeyList;

		bool m_bEnabled;

	private:
//		void Finish( Mix::Tool::Win32::Graphics::ObjectModel* pObjectModel );
//		bool Read( Mix::Tool::Win32::File::InputStream& input );
		bool Write(	Mix::Tool::Win32::File::OutputStream& output,
					unsigned int rtFlags,
					MOTION_RT_HORIZONAL rtHoriz,
					MOTION_RT_VERTICAL rtVert,
					const D3DXQUATERNION& defR,
					const D3DXVECTOR3& defT );

	public:
		MotionCurve( int index );
		MotionCurve( int index, const wchar_t* pLinkNodeName );
		~MotionCurve( void );

	public:
		void ReserveKeyList( unsigned int sKeyCount, unsigned int rKeyCount, unsigned int tKeyCount );

		void AddScalingKey( int time, const D3DXVECTOR3& value );
		unsigned int GetScalingKeyCount( void ) const;
		const Mix::Tool::Win32::Graphics::VECTOR_KEY& GetScalingKey( int index ) const;
		void ClearScalingKey( void );

		void AddRotationKey( int time, const D3DXQUATERNION& value );
		unsigned int GetRotationKeyCount( void ) const;
		const Mix::Tool::Win32::Graphics::QUATERNION_KEY& GetRotationKey( int index ) const;
		void ClearRotationKey( void );

		void AddTranslationKey( int time, const D3DXVECTOR3& value );
		void SetTranslationValue( unsigned int index, const D3DXVECTOR3& value );
		unsigned int GetTranslationKeyCount( void ) const;
		const Mix::Tool::Win32::Graphics::VECTOR_KEY& GetTranslationKey( int index ) const;
		void ClearTranslationKey( void );

		float GetLastTime( void );

		D3DXVECTOR3 GetScaling( float time );
		D3DXQUATERNION GetRotation( float time );
		D3DXVECTOR3 GetTranslation( float time );

		int GetIndex( void ) const;

		const wchar_t* GetLinkNodeName( void ) const;

		void SetEnabled( bool state );
		bool GetEnabled( void ) const;

	public:
		virtual Mix::Tool::Win32::Object::TYPE GetType( void ) const;

		friend class Motion;
	};

}}}}
