#include "Mix/Tool/CLR/Core/Graphics/MotionController.h"

namespace Mix{ namespace Tool{ namespace Graphics{

////////////////////////////////////////////////////////////////////////////////////////////////////
// MotionController::MotionCollection
////////////////////////////////////////////////////////////////////////////////////////////////////

MotionController::MotionCollection::MotionCollection( void ) :
impl( NULL ),
m_List( gcnew System::Collections::Generic::List<Mix::Tool::Graphics::Motion^>() )
{
}

MotionController::MotionCollection::~MotionCollection( void )
{
	if( m_List->Count > 0 )
	{
		for each ( Mix::Tool::Graphics::Motion^ motion in m_List )
		{
			delete motion;
		}

		m_List->Clear();
	}

	impl = NULL;
}

void MotionController::MotionCollection::Initialize( Mix::Tool::Win32::Graphics::MotionController* _impl )
{
	if( _impl == NULL )
	{
		throw gcnew System::ArgumentNullException( L"_impl" );
	}

	if( impl != NULL )
	{
		throw gcnew System::InvalidOperationException( L"モーションコレクションはすでに初期化されています" );
	}

	impl = _impl;

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// リストを作成
	////////////////////////////////////////////////////////////////////////////////////////////////////

	unsigned int count = impl->GetCount();

	for( unsigned int i = 0; i < count; i++ )
	{
		Mix::Tool::Win32::Graphics::Motion* implMotion = impl->Get( i );
		Mix::Tool::Graphics::Motion^ motion = gcnew Mix::Tool::Graphics::Motion( implMotion );

		m_List->Add( motion );
	}
}

int MotionController::MotionCollection::Count::get( void )
{
	return m_List->Count;
}

Mix::Tool::Graphics::Motion^ MotionController::MotionCollection::default::get( int index )
{
	return m_List[index];
}

Mix::Tool::Graphics::Motion^ MotionController::MotionCollection::default::get( System::String^ name )
{
	for each ( Mix::Tool::Graphics::Motion^ mot in m_List )
	{
		if( mot->Name->Equals( name ) == true )
		{
			return mot;
		}
	}

	return nullptr;
}

void MotionController::MotionCollection::Add( Mix::Tool::Graphics::Motion^ item )
{
	if( impl == NULL )
	{
		throw gcnew System::InvalidOperationException( L"モーションコントローラーが初期化されていないか、既に解放されているため、この操作は行えません" );
	}

	if( item == nullptr )
	{
		throw gcnew System::ArgumentNullException( "item" );
	}

	if( item->impl == NULL )
	{
		throw gcnew System::ArgumentException( "追加しようとしたモーションは既に解放されています" );
	}

	if( m_List->Contains( item ) == false )
	{
		impl->Add( item->impl );
		m_List->Add( item );
	}
}

void MotionController::MotionCollection::Remove( Mix::Tool::Graphics::Motion^ item )
{
	if( impl == NULL )
	{
		throw gcnew System::InvalidOperationException( L"モーションコントローラーが初期化されていないか、既に解放されているため、この操作は行えません" );
	}

	if( item == nullptr )
	{
		throw gcnew System::ArgumentNullException( "item" );
	}

	if( m_List->Contains( item ) == true )
	{
		if( item->impl != NULL )
		{
			impl->Remove( item->impl );
		}

		m_List->Remove( item );
	}
}

System::Collections::IEnumerator^ MotionController::MotionCollection::GetEnumerator( void )
{
	return m_List->GetEnumerator();
}

////////////////////////////////////////////////////////////////////////////////////////////////////
// MotionController
////////////////////////////////////////////////////////////////////////////////////////////////////

MotionController::MotionController( void ) :
impl( NULL ),
m_Motions( nullptr )
{
	m_Motions = gcnew MotionController::MotionCollection();
}

MotionController::~MotionController( void )
{
	if( m_Motions != nullptr )
	{
		delete m_Motions;
	}

	if( impl != NULL )
	{
		impl->Destroy();
		impl = NULL;
	}
}

void MotionController::Initialize( Mix::Tool::Win32::Graphics::MotionController* _impl )
{
	if( _impl == NULL )
	{
		throw gcnew System::ArgumentNullException( L"_impl" );
	}

	if( impl != NULL )
	{
		throw gcnew System::InvalidOperationException( L"モーションコントローラーは既に初期化されています" );
	}

	impl = _impl;

	m_Motions->Initialize( _impl );
}

bool MotionController::Assigned::get( void )
{
	if( impl == NULL )
	{
		throw gcnew System::InvalidOperationException( L"モーションコントローラーが初期化されていないか、既に解放されているため、この操作は行えません" );
	}

	return impl->IsAssigned();
}

System::String^ MotionController::Name::get( void )
{
	if( impl == NULL )
	{
		throw gcnew System::InvalidOperationException( L"モーションコントローラーが初期化されていないか、既に解放されているため、この操作は行えません" );
	}

	return gcnew System::String( impl->GetName() );
}

void MotionController::Name::set( System::String^ value )
{
	if( impl == NULL )
	{
		throw gcnew System::InvalidOperationException( L"モーションコントローラーが初期化されていないか、既に解放されているため、この操作は行えません" );
	}

	if( impl->IsAssigned() == false )
	{
		throw gcnew System::Exception( "未分類のモーションコントローラーの名前は変更できません" );
	}

	pin_ptr<const wchar_t> wpValue = PtrToStringChars( value );

	impl->SetName( wpValue );
}

unsigned int MotionController::Priority::get( void )
{
	if( impl == NULL )
	{
		throw gcnew System::InvalidOperationException( L"モーションコントローラーが初期化されていないか、既に解放されているため、この操作は行えません" );
	}

	return impl->GetPriority();
}

void MotionController::Priority::set( unsigned int value )
{
	if( impl == NULL )
	{
		throw gcnew System::InvalidOperationException( L"モーションコントローラーが初期化されていないか、既に解放されているため、この操作は行えません" );
	}

	if( impl->IsAssigned() == false )
	{
		throw gcnew System::Exception( "未分類のモーションコントローラーのプライオリティは変更できません" );
	}

	impl->SetPriority( value );
}

MotionController::MotionCollection^ MotionController::Motions::get( void )
{
	return m_Motions;
}

}}}
