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

namespace Mix{ namespace Tool{ namespace Graphics{

////////////////////////////////////////////////////////////////////////////////////////////////////
// GeneralProperty
////////////////////////////////////////////////////////////////////////////////////////////////////

GeneralProperty::GeneralProperty( Mix::Tool::Win32::Graphics::Scene* _impl ) :
impl( _impl ),
m_bSelectedAlwaysDisplay( true )
{
}

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

Mix::Tool::Math::Vector^ GeneralProperty::BackgroundColor::get( void )
{
	const D3DXVECTOR4& col = impl->GetBackgroundColor();

	return gcnew Mix::Tool::Math::Vector( col.x, col.y, col.z, col.w );
}

void GeneralProperty::BackgroundColor::set( Mix::Tool::Math::Vector^ value )
{
	impl->SetBackgroundColor( D3DXVECTOR4( value->X, value->Y, value->Z, value->W ) );
}

Mix::Tool::Math::Vector^ GeneralProperty::TextColor::get( void )
{
	const D3DXVECTOR4& col = impl->GetTextColor();

	return gcnew Mix::Tool::Math::Vector( col.x, col.y, col.z, col.w );
}

void GeneralProperty::TextColor::set( Mix::Tool::Math::Vector^ value )
{
	impl->SetTextColor( D3DXVECTOR4( value->X, value->Y, value->Z, value->W ) );
}

Mix::Tool::Math::Vector^ GeneralProperty::BoneColor::get( void )
{
	const D3DXVECTOR4& col = impl->GetBoneColor();

	return gcnew Mix::Tool::Math::Vector( col.x, col.y, col.z, col.w );
}

void GeneralProperty::BoneColor::set( Mix::Tool::Math::Vector^ value )
{
	impl->SetBoneColor( D3DXVECTOR4( value->X, value->Y, value->Z, value->W ) );
}

Mix::Tool::Math::Vector^ GeneralProperty::ViewVolumeColor::get( void )
{
	const D3DXVECTOR4& col = impl->GetViewVolumeColor();

	return gcnew Mix::Tool::Math::Vector( col.x, col.y, col.z, col.w );
}

void GeneralProperty::ViewVolumeColor::set( Mix::Tool::Math::Vector^ value )
{
	impl->SetViewVolumeColor( D3DXVECTOR4( value->X, value->Y, value->Z, value->W ) );
}

Mix::Tool::Math::Vector^ GeneralProperty::KinematicCharacterColor::get( void )
{
	const D3DXVECTOR4& col = impl->GetKinematicCharacterColor();

	return gcnew Mix::Tool::Math::Vector( col.x, col.y, col.z, col.w );
}

void GeneralProperty::KinematicCharacterColor::set( Mix::Tool::Math::Vector^ value )
{
	impl->SetKinematicCharacterColor( D3DXVECTOR4( value->X, value->Y, value->Z, value->W ) );
}

Mix::Tool::Math::Vector^ GeneralProperty::SensorColor::get( void )
{
	const D3DXVECTOR4& col = impl->GetSensorColor();

	return gcnew Mix::Tool::Math::Vector( col.x, col.y, col.z, col.w );
}

void GeneralProperty::SensorColor::set( Mix::Tool::Math::Vector^ value )
{
	impl->SetSensorColor( D3DXVECTOR4( value->X, value->Y, value->Z, value->W ) );
}

Mix::Tool::Math::Vector^ GeneralProperty::CollisionColor::get( void )
{
	const D3DXVECTOR4& col = impl->GetCollisionColor();

	return gcnew Mix::Tool::Math::Vector( col.x, col.y, col.z, col.w );
}

void GeneralProperty::CollisionColor::set( Mix::Tool::Math::Vector^ value )
{
	impl->SetCollisionColor( D3DXVECTOR4( value->X, value->Y, value->Z, value->W ) );
}

Mix::Tool::Math::Vector^ GeneralProperty::JointAxisColor::get( void )
{
	const D3DXVECTOR4& col = impl->GetJointAxisColor();

	return gcnew Mix::Tool::Math::Vector( col.x, col.y, col.z, col.w );
}

void GeneralProperty::JointAxisColor::set( Mix::Tool::Math::Vector^ value )
{
	impl->SetJointAxisColor( D3DXVECTOR4( value->X, value->Y, value->Z, value->W ) );
}

Mix::Tool::Math::Vector^ GeneralProperty::JointBallColor::get( void )
{
	const D3DXVECTOR4& col = impl->GetJointBallColor();

	return gcnew Mix::Tool::Math::Vector( col.x, col.y, col.z, col.w );
}

void GeneralProperty::JointBallColor::set( Mix::Tool::Math::Vector^ value )
{
	impl->SetJointBallColor( D3DXVECTOR4( value->X, value->Y, value->Z, value->W ) );
}

Mix::Tool::Math::Vector^ GeneralProperty::JointLimitColor::get( void )
{
	const D3DXVECTOR4& col = impl->GetJointLimitColor();

	return gcnew Mix::Tool::Math::Vector( col.x, col.y, col.z, col.w );
}

void GeneralProperty::JointLimitColor::set( Mix::Tool::Math::Vector^ value )
{
	impl->SetJointLimitColor( D3DXVECTOR4( value->X, value->Y, value->Z, value->W ) );
}

float GeneralProperty::JointScale::get( void )
{
	return impl->GetJointScale();
}

void GeneralProperty::JointScale::set( float value )
{
	impl->SetJointScale( value );
}

Mix::Tool::Math::Vector^ GeneralProperty::SelectedColor::get( void )
{
	const D3DXVECTOR4& col = impl->GetSelectedColor();

	return gcnew Mix::Tool::Math::Vector( col.x, col.y, col.z, col.w );
}

void GeneralProperty::SelectedColor::set( Mix::Tool::Math::Vector^ value )
{
	impl->SetSelectedColor( D3DXVECTOR4( value->X, value->Y, value->Z, value->W ) );
}

bool GeneralProperty::SelectedAlwaysDisplay::get( void )
{
	return m_bSelectedAlwaysDisplay;
}

void GeneralProperty::SelectedAlwaysDisplay::set( bool value )
{
	m_bSelectedAlwaysDisplay = value;
}

float GeneralProperty::AxisScale::get( void )
{
	return impl->GetAxisScale();
}

void GeneralProperty::AxisScale::set( float value )
{
	impl->SetAxisScale( value );
}

////////////////////////////////////////////////////////////////////////////////////////////////////
// GridProperty
////////////////////////////////////////////////////////////////////////////////////////////////////

GridProperty::GridProperty( Mix::Tool::Win32::Graphics::Scene* _impl ) :
impl( _impl )
{
}

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

Mix::Tool::Math::Vector^ GridProperty::Color::get( void )
{
	const D3DXVECTOR4& col = impl->GetGridColor();

	return gcnew Mix::Tool::Math::Vector( col.x, col.y, col.z, col.w );
}

void GridProperty::Color::set( Mix::Tool::Math::Vector^ value )
{
	impl->SetGridColor( D3DXVECTOR4( value->X, value->Y, value->Z, value->W ) );
}

float GridProperty::Pitch::get( void )
{
	if( impl == nullptr )
	{
		return 1.0f;
	}

	return impl->GetGridPitch();
}

void GridProperty::Pitch::set( float value )
{
	if( impl != nullptr )
	{
		impl->SetGridPitch( value );
	}
}

float GridProperty::Extent::get( void )
{
	if( impl == nullptr )
	{
		return 20.0f;
	}

	return impl->GetGridExtent();
}

void GridProperty::Extent::set( float value )
{
	if( impl != nullptr )
	{
		impl->SetGridExtent( value );
	}
}

////////////////////////////////////////////////////////////////////////////////////////////////////
// LightProperty
////////////////////////////////////////////////////////////////////////////////////////////////////

LightProperty::LightProperty( Mix::Tool::Win32::Graphics::Scene* _impl ) :
impl( _impl )
{
}

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

Mix::Tool::Math::Vector^ LightProperty::AmbientColor::get( void )
{
	const D3DXVECTOR4& col = impl->GetLightAmbientColor();

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

void LightProperty::AmbientColor::set( Mix::Tool::Math::Vector^ value )
{
	const D3DXVECTOR4& col = impl->GetLightAmbientColor(); // w が影の濃度

	impl->SetLightAmbientColor( D3DXVECTOR4( value->X, value->Y, value->Z, col.w ) );
}

Mix::Tool::Math::Vector^ LightProperty::DiffuseColor::get( void )
{
	if( impl == nullptr )
	{
		return gcnew Mix::Tool::Math::Vector( 1.0f, 1.0f, 1.0f, 1.0f );
	}

	const D3DXVECTOR4& temp = impl->GetLightDiffuseColor();

	return gcnew Mix::Tool::Math::Vector( temp.x, temp.y, temp.z, temp.w );
}

void LightProperty::DiffuseColor::set( Mix::Tool::Math::Vector^ value )
{
	if( impl != nullptr )
	{
		impl->SetLightDiffuseColor( D3DXVECTOR4( value->X, value->Y, value->Z, value->W ) );
	}
}

float LightProperty::Shading::get( void )
{
	if( impl == nullptr )
	{
		return 0.5f;
	}

	return impl->GetLightAmbientColor().w;
}

void LightProperty::Shading::set( float value )
{
	if( impl != nullptr )
	{
		const D3DXVECTOR4& col = impl->GetLightAmbientColor(); // w が影の濃度

		impl->SetLightAmbientColor( D3DXVECTOR4( col.x, col.y, col.z, value ) );
	}
}

float LightProperty::Scale::get( void )
{
	if( impl == nullptr )
	{
		return 1.0f;
	}

	return impl->GetLightDrawScale();
}

void LightProperty::Scale::set( float value )
{
	if( impl != nullptr )
	{
		impl->SetLightDrawScale( value );
	}
}

Mix::Tool::Math::Vector^ LightProperty::Pose::get( void )
{
	const D3DXQUATERNION& quat = impl->GetLightPoseQuat();

	return gcnew Mix::Tool::Math::Vector( quat.x, quat.y, quat.z, quat.w );
}

void LightProperty::Pose::set( Mix::Tool::Math::Vector^ value )
{
	impl->SetLightPoseQuat( D3DXQUATERNION( value->X, value->Y, value->Z, value->W ) );
}

void LightProperty::ResetPose( void )
{
	if( impl != nullptr )
	{
		impl->ResetLightPoseMatrix();
	}
}

////////////////////////////////////////////////////////////////////////////////////////////////////
// CameraCollection
////////////////////////////////////////////////////////////////////////////////////////////////////

CameraCollection::CameraCollection( Mix::Tool::Win32::Graphics::Scene* _impl ) :
impl( _impl )
{
}

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

void CameraCollection::Add( Mix::Tool::Graphics::Camera^ camera )
{
	if( camera == nullptr )
	{
		throw gcnew System::ArgumentNullException( "camera" );
	}

	if( impl != nullptr )
	{
		impl->AddCamera( camera->impl );
	}
}

void CameraCollection::Remove( Mix::Tool::Graphics::Camera^ camera )
{
	if( camera == nullptr )
	{
		throw gcnew System::ArgumentNullException( "camera" );
	}

	if( impl != nullptr )
	{
		impl->RemoveCamera( camera->impl );
	}
}

////////////////////////////////////////////////////////////////////////////////////////////////////
// Scene
////////////////////////////////////////////////////////////////////////////////////////////////////

Scene::Scene( void ) :
impl( new Mix::Tool::Win32::Graphics::Scene() ),
m_DrawObject( nullptr )
{
	impl->Initialize();

	m_GeneProp = gcnew Mix::Tool::Graphics::GeneralProperty( impl );
	m_GridProp = gcnew Mix::Tool::Graphics::GridProperty( impl );
	m_LightProp = gcnew Mix::Tool::Graphics::LightProperty( impl );
	m_Cameras = gcnew Mix::Tool::Graphics::CameraCollection( impl );
}

Scene::~Scene( void )
{
	m_DrawObject = nullptr;

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

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

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

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

	if( impl != NULL )
	{
		delete impl;
		impl = NULL;
	}
}

Mix::Tool::Graphics::GeneralProperty^ Scene::General::get( void )
{
	return m_GeneProp;
}

Mix::Tool::Graphics::GridProperty^ Scene::Grid::get( void )
{
	return m_GridProp;
}

Mix::Tool::Graphics::LightProperty^ Scene::Light::get( void )
{
	return m_LightProp;
}

Mix::Tool::Graphics::CameraCollection^ Scene::Cameras::get( void )
{
	return m_Cameras;
}

Mix::Tool::Graphics::DrawObject^ Scene::DrawObject::get( void )
{
	return m_DrawObject;
}

void Scene::DrawObject::set( Mix::Tool::Graphics::DrawObject^ value )
{
	m_DrawObject = value;

	impl->SetDrawObject( ( m_DrawObject != nullptr )? m_DrawObject->implDrawObject : NULL );
}

System::String^ Scene::ReflectionTextureFileName::get( void )
{
	return gcnew System::String( impl->GetReflectionTexture() );
}

void Scene::ReflectionTextureFileName::set( System::String^ value )
{
	pin_ptr<const wchar_t> wpValue = PtrToStringChars( value );

	impl->SetReflectionTexture( wpValue );
}

}}}
