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

namespace Mix{ namespace Tool{ namespace Graphics{

RootTransform::RootTransform( Mix::Tool::Win32::Graphics::ObjectModel* _impl ) :
impl( _impl ),
m_bUpdate( true )
{
}

RootTransform::~RootTransform( void )
{
	impl = NULL;
}

Mix::Tool::Graphics::RootTransformFlags RootTransform::Active::get( void )
{
	unsigned int flags = impl->GetRootTransformActive();
	RootTransformFlags ret = RootTransformFlags::Init;

	if( ( flags & Mix::Tool::Win32::Graphics::MOTION_RT_ROTATION ) == Mix::Tool::Win32::Graphics::MOTION_RT_ROTATION )
	{
		ret = ret | RootTransformFlags::Rotation;
	}
	if( ( flags & Mix::Tool::Win32::Graphics::MOTION_RT_TRANSLATION ) == Mix::Tool::Win32::Graphics::MOTION_RT_TRANSLATION )
	{
		ret = ret | RootTransformFlags::Translation;
	}

	return ret;
}

void RootTransform::Active::set( Mix::Tool::Graphics::RootTransformFlags value )
{
	unsigned int flags = 0;

	if( ( value & RootTransformFlags::Rotation ) == RootTransformFlags::Rotation )
	{
		flags |= Mix::Tool::Win32::Graphics::MOTION_RT_ROTATION;
	}
	if( ( value & RootTransformFlags::Translation ) == RootTransformFlags::Translation )
	{
		flags |= Mix::Tool::Win32::Graphics::MOTION_RT_TRANSLATION;
	}

	impl->SetRootTransformActive( flags );
}

System::String^ RootTransform::NodeName::get( void )
{
	const wchar_t* pNodeName = impl->GetRootTransformNodeName();

	return gcnew System::String( ( pNodeName != NULL )? pNodeName : L"" );
}

void RootTransform::NodeName::set( System::String^ value )
{
	pin_ptr<const wchar_t> wpValue = PtrToStringChars( value );
	int index = impl->GetNodeIndexByName( wpValue );

	impl->SetRootTransformNodeIndex( index );

	Update();
}

Mix::Tool::Graphics::RootTransformAxis^ RootTransform::RotationAxis::get( void )
{
	const Mix::Tool::Win32::Graphics::MOTION_RT_AXIS& axis = impl->GetRootRotationAxis();

	return gcnew Mix::Tool::Graphics::RootTransformAxis( ToCLRVector( axis.x ), ToCLRVector( axis.y ), ToCLRVector( axis.z ) );
}

void RootTransform::RotationAxis::set( Mix::Tool::Graphics::RootTransformAxis^ value )
{
	Mix::Tool::Win32::Graphics::MOTION_RT_AXIS axis;
	
	axis.x = ToWIN32Vector( value->X );
	axis.y = ToWIN32Vector( value->Y );
	axis.z = ToWIN32Vector( value->Z );

	impl->SetRootRotationAxis( axis );

	Update();
}

Mix::Tool::Graphics::RootTransformHorizonal RootTransform::TranslationHorizonal::get( void )
{
	Mix::Tool::Graphics::RootTransformHorizonal ret;

	switch( impl->GetRootTranslationHorizonal() )
	{
	case Mix::Tool::Win32::Graphics::MOTION_RT_H_XY:
		ret = Mix::Tool::Graphics::RootTransformHorizonal::XY;
		break;
	case Mix::Tool::Win32::Graphics::MOTION_RT_H_XZ:
		ret = Mix::Tool::Graphics::RootTransformHorizonal::XZ;
		break;
	case Mix::Tool::Win32::Graphics::MOTION_RT_H_YZ:
		ret = Mix::Tool::Graphics::RootTransformHorizonal::YZ;
		break;
	}

	return ret;
}

void RootTransform::TranslationHorizonal::set( Mix::Tool::Graphics::RootTransformHorizonal value )
{
	Mix::Tool::Win32::Graphics::MOTION_RT_HORIZONAL set;

	switch( value )
	{
	case Mix::Tool::Graphics::RootTransformHorizonal::XY:
		set = Mix::Tool::Win32::Graphics::MOTION_RT_H_XY;
		break;
	case Mix::Tool::Graphics::RootTransformHorizonal::XZ:
		set = Mix::Tool::Win32::Graphics::MOTION_RT_H_XZ;
		break;
	case Mix::Tool::Graphics::RootTransformHorizonal::YZ:
		set = Mix::Tool::Win32::Graphics::MOTION_RT_H_YZ;
		break;
	}

	impl->SetRootTranslationHorizonal( set );
}

Mix::Tool::Graphics::RootTransformVertical RootTransform::TranslationVertical::get( void )
{
	Mix::Tool::Graphics::RootTransformVertical ret;

	switch( impl->GetRootTranslationVertical() )
	{
	case Mix::Tool::Win32::Graphics::MOTION_RT_V_X:
		ret = Mix::Tool::Graphics::RootTransformVertical::X;
		break;
	case Mix::Tool::Win32::Graphics::MOTION_RT_V_Y:
		ret = Mix::Tool::Graphics::RootTransformVertical::Y;
		break;
	case Mix::Tool::Win32::Graphics::MOTION_RT_V_Z:
		ret = Mix::Tool::Graphics::RootTransformVertical::Z;
		break;
	}

	return ret;
}

void RootTransform::TranslationVertical::set( Mix::Tool::Graphics::RootTransformVertical value )
{
	Mix::Tool::Win32::Graphics::MOTION_RT_VERTICAL set;

	switch( value )
	{
	case Mix::Tool::Graphics::RootTransformVertical::X:
		set = Mix::Tool::Win32::Graphics::MOTION_RT_V_X;
		break;
	case Mix::Tool::Graphics::RootTransformVertical::Y:
		set = Mix::Tool::Win32::Graphics::MOTION_RT_V_Y;
		break;
	case Mix::Tool::Graphics::RootTransformVertical::Z:
		set = Mix::Tool::Win32::Graphics::MOTION_RT_V_Z;
		break;
	}

	impl->SetRootTranslationVertical( set );
}

Mix::Tool::Graphics::RootTransformAxis^ RootTransform::TranslationAxis::get( void )
{
	const Mix::Tool::Win32::Graphics::MOTION_RT_AXIS& axis = impl->GetRootTranslationAxis();

	return gcnew Mix::Tool::Graphics::RootTransformAxis( ToCLRVector( axis.x ), ToCLRVector( axis.y ), ToCLRVector( axis.z ) );
}

void RootTransform::TranslationAxis::set( Mix::Tool::Graphics::RootTransformAxis^ value )
{
	Mix::Tool::Win32::Graphics::MOTION_RT_AXIS axis;
	
	axis.x = ToWIN32Vector( value->X );
	axis.y = ToWIN32Vector( value->Y );
	axis.z = ToWIN32Vector( value->Z );

	impl->SetRootTranslationAxis( axis );

	Update();
}

void RootTransform::BeginUpdate( void )
{
	m_bUpdate = false;
}

void RootTransform::EndUpdate( void )
{
	m_bUpdate = true;

	Update();
}

void RootTransform::Update( void )
{
	if( m_bUpdate == true )
	{
		impl->UpdateRootTransform();
	}
}

Mix::Tool::Graphics::RootTransformVector RootTransform::ToCLRVector( Mix::Tool::Win32::Graphics::MOTION_RT_VECTOR src )
{
	Mix::Tool::Graphics::RootTransformVector ret;

	switch( src )
	{
	case Mix::Tool::Win32::Graphics::MOTION_RT_NEGATIVE_X:
		ret = Mix::Tool::Graphics::RootTransformVector::NegativeX;
		break;
	case Mix::Tool::Win32::Graphics::MOTION_RT_POSITIVE_X:
		ret = Mix::Tool::Graphics::RootTransformVector::PositiveX;
		break;
	case Mix::Tool::Win32::Graphics::MOTION_RT_NEGATIVE_Y:
		ret = Mix::Tool::Graphics::RootTransformVector::NegativeY;
		break;
	case Mix::Tool::Win32::Graphics::MOTION_RT_POSITIVE_Y:
		ret = Mix::Tool::Graphics::RootTransformVector::PositiveY;
		break;
	case Mix::Tool::Win32::Graphics::MOTION_RT_NEGATIVE_Z:
		ret = Mix::Tool::Graphics::RootTransformVector::NegativeZ;
		break;
	case Mix::Tool::Win32::Graphics::MOTION_RT_POSITIVE_Z:
		ret = Mix::Tool::Graphics::RootTransformVector::PositiveZ;
		break;
	}

	return ret;
}

Mix::Tool::Win32::Graphics::MOTION_RT_VECTOR RootTransform::ToWIN32Vector( Mix::Tool::Graphics::RootTransformVector src )
{
	Mix::Tool::Win32::Graphics::MOTION_RT_VECTOR ret;

	switch( src )
	{
	case Mix::Tool::Graphics::RootTransformVector::NegativeX:
		ret = Mix::Tool::Win32::Graphics::MOTION_RT_NEGATIVE_X;
		break;
	case Mix::Tool::Graphics::RootTransformVector::PositiveX:
		ret = Mix::Tool::Win32::Graphics::MOTION_RT_POSITIVE_X;
		break;
	case Mix::Tool::Graphics::RootTransformVector::NegativeY:
		ret = Mix::Tool::Win32::Graphics::MOTION_RT_NEGATIVE_Y;
		break;
	case Mix::Tool::Graphics::RootTransformVector::PositiveY:
		ret = Mix::Tool::Win32::Graphics::MOTION_RT_POSITIVE_Y;
		break;
	case Mix::Tool::Graphics::RootTransformVector::NegativeZ:
		ret = Mix::Tool::Win32::Graphics::MOTION_RT_NEGATIVE_Z;
		break;
	case Mix::Tool::Graphics::RootTransformVector::PositiveZ:
		ret = Mix::Tool::Win32::Graphics::MOTION_RT_POSITIVE_Z;
		break;
	}

	return ret;
}

}}}
