#include "Mix/Tool/CLR/Core/Dynamics/Design/Actor.h"

#include "Mix/Tool/CLR/Core/Dynamics/World.h"
#include "Mix/Tool/CLR/Core/Dynamics/KinematicCharacter.h"
#include "Mix/Tool/Win32/Core/Dynamics/Design/Actor.h"

namespace Mix{ namespace Tool{ namespace Dynamics{ namespace Design{
		
Actor::Actor( Mix::Tool::Win32::Dynamics::Design::Actor* _implActor ) : Basic( _implActor ),
implActor( _implActor ),
m_KinematicCharacter( nullptr ),
m_World( nullptr )
{
	if( _implActor == NULL )
	{
		throw gcnew System::ArgumentNullException( L"_implActor" );
	}
}

Actor::~Actor( void )
{
	if( implActor != NULL )
	{
		implActor->KinematicCharacter_Set( NULL );
		implActor->SetWorld( NULL );
		implActor = NULL;
	}

	m_KinematicCharacter = nullptr;
	m_World = nullptr;
}

Mix::Tool::Dynamics::KinematicCharacter^ Actor::KinematicCharacter::get( void )
{
	return m_KinematicCharacter;
}

void Actor::KinematicCharacter::set( Mix::Tool::Dynamics::KinematicCharacter^ value )
{
	if( implActor == NULL )
	{
		throw gcnew System::InvalidOperationException();
	}

	if( m_KinematicCharacter != value )
	{
		if( value != nullptr )
		{
			if( value->ImplW32KinematicCharacter == NULL )
			{
				throw gcnew System::Exception( L"設定しようとしたキネマティックキャラクターは既に破棄されています" );
			}

			implActor->KinematicCharacter_Set( value->ImplW32KinematicCharacter );
		}
		else
		{
			implActor->KinematicCharacter_Set( NULL );
		}

		if( m_KinematicCharacter != nullptr )
		{
			delete m_KinematicCharacter;
			m_KinematicCharacter = nullptr;
		}

		m_KinematicCharacter = value;
	}
}

Mix::Tool::Math::Vector^ Actor::KinematicCharacterCenterPosition::get( void )
{
	if( implActor == NULL )
	{
		throw gcnew System::InvalidOperationException();
	}

	const D3DXVECTOR3& pos = implActor->KinematicCharacter_GetCenterPosition();

	return gcnew Mix::Tool::Math::Vector( pos.x, pos.y, pos.z, 1.0f );
}

void Actor::KinematicCharacterCenterPosition::set( Mix::Tool::Math::Vector^ value )
{
	if( implActor == NULL )
	{
		throw gcnew System::InvalidOperationException();
	}

	implActor->KinematicCharacter_SetCenterPosition( D3DXVECTOR3( value->X, value->Y, value->Z ) );
}

Mix::Tool::Dynamics::World^ Actor::World::get( void )
{
	return m_World;
}

void Actor::World::set( Mix::Tool::Dynamics::World^ value )
{
	if( implActor == NULL )
	{
		throw gcnew System::InvalidOperationException();
	}

	implActor->SetWorld( ( value != nullptr )? value->Impl : NULL );

	m_World = value;
}

Mix::Tool::Dynamics::Design::SimulationMode Actor::SimulationMode::get( void )
{
	if( implActor == NULL )
	{
		throw gcnew System::InvalidOperationException();
	}

	Mix::Tool::Dynamics::Design::SimulationMode mode;

	switch( implActor->GetMode() )
	{
	case Mix::Tool::Win32::Dynamics::Design::Basic::EDIT:
		mode = Mix::Tool::Dynamics::Design::SimulationMode::Stop;
		break;
	case Mix::Tool::Win32::Dynamics::Design::Basic::STAND:
		mode = Mix::Tool::Dynamics::Design::SimulationMode::Stand;
		break;
	case Mix::Tool::Win32::Dynamics::Design::Basic::RAGDOLL:
		mode = Mix::Tool::Dynamics::Design::SimulationMode::Ragdoll;
		break;
	}

	return mode;
}

void Actor::SimulationMode::set( Mix::Tool::Dynamics::Design::SimulationMode value )
{
	if( implActor == NULL )
	{
		throw gcnew System::InvalidOperationException();
	}

	Mix::Tool::Win32::Dynamics::Design::Basic::MODE mode;

	switch( value )
	{
	case Mix::Tool::Dynamics::Design::SimulationMode::Stop:
		mode = Mix::Tool::Win32::Dynamics::Design::Basic::EDIT;
		break;
	case Mix::Tool::Dynamics::Design::SimulationMode::Stand:
		mode = Mix::Tool::Win32::Dynamics::Design::Basic::STAND;
		break;
	case Mix::Tool::Dynamics::Design::SimulationMode::Ragdoll:
		mode = Mix::Tool::Win32::Dynamics::Design::Basic::RAGDOLL;
		break;
	}

	implActor->SetMode( mode );
}

}}}}
