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

#include "Mix/Tool/Win32/Core/Graphics/MapMesh.h"
#include "Mix/Tool/Win32/Core/Graphics/MapModel.h"
#include "Mix/Tool/CLR/Core/Dynamics/Design/Terrain.h"

namespace Mix{ namespace Tool{ namespace Graphics{

////////////////////////////////////////////////////////////////////////////////////////////////////
// MapModel::ImportConfig
////////////////////////////////////////////////////////////////////////////////////////////////////

MapModel::ImportConfig::ImportConfig( void ) :
m_FilePath( gcnew System::String( L"" ) ),
m_Option( Mix::Tool::Graphics::ModelImportOption::Default ),
m_bSmooting( false ),
m_SmootingAngle( 45.0f ),
m_Scaling( 1.0f ),
m_Rotation( gcnew Mix::Tool::Math::Vector( 0.0f, 0.0f, 0.0f ) ),
m_Translation( gcnew Mix::Tool::Math::Vector( 0.0f, 0.0f, 0.0f ) ),
m_CellSize( gcnew Mix::Tool::Math::Vector( 100.0f, 100.0f, 100.0f ) )
{
}

System::String^ MapModel::ImportConfig::FilePath::get( void )
{
	return gcnew System::String( m_FilePath->ToCharArray() );
}

void MapModel::ImportConfig::FilePath::set( System::String^ value )
{
	if( value != nullptr )
	{
		m_FilePath = gcnew System::String( value->ToCharArray() );
	}
	else
	{
		m_FilePath = gcnew System::String( L"" );
	}
}

Mix::Tool::Graphics::ModelImportOption MapModel::ImportConfig::Option::get( void )
{
	return m_Option;
}

void MapModel::ImportConfig::Option::set( Mix::Tool::Graphics::ModelImportOption value )
{
	m_Option = value;
}

float MapModel::ImportConfig::Scaling::get( void )
{
	return m_Scaling;
}

void MapModel::ImportConfig::Scaling::set( float value )
{
	m_Scaling = value;
}

Mix::Tool::Math::Vector^ MapModel::ImportConfig::Rotation::get( void )
{
	return gcnew Mix::Tool::Math::Vector( m_Rotation );
}

void MapModel::ImportConfig::Rotation::set( Mix::Tool::Math::Vector^ value )
{
	m_Rotation->X = value->X;
	m_Rotation->Y = value->Y;
	m_Rotation->Z = value->Z;
}

Mix::Tool::Math::Vector^ MapModel::ImportConfig::Translation::get( void )
{
	return gcnew Mix::Tool::Math::Vector( m_Translation );
}

void MapModel::ImportConfig::Translation::set( Mix::Tool::Math::Vector^ value )
{
	m_Translation->X = value->X;
	m_Translation->Y = value->Y;
	m_Translation->Z = value->Z;
}

Mix::Tool::Math::Vector^ MapModel::ImportConfig::CellSize::get( void )
{
	return gcnew Mix::Tool::Math::Vector( m_CellSize );
}

void MapModel::ImportConfig::CellSize::set( Mix::Tool::Math::Vector^ value )
{
	if( value->X >= 1.0f )
	{
		m_CellSize->X = value->X;
	}
	else
	{
		m_CellSize->X = 1.0f;
	}

	if( value->Y >= 1.0f )
	{
		m_CellSize->Y = value->Y;
	}
	else
	{
		m_CellSize->Y = 1.0f;
	}

	if( value->Z >= 1.0f )
	{
		m_CellSize->Z = value->Z;
	}
	else
	{
		m_CellSize->Z = 1.0f;
	}
}

bool MapModel::ImportConfig::Smooting::get( void )
{
	return m_bSmooting;
}

void MapModel::ImportConfig::Smooting::set( bool value )
{
	m_bSmooting = value;
}

float MapModel::ImportConfig::SmootingAngle::get( void )
{
	return m_SmootingAngle;
}

void MapModel::ImportConfig::SmootingAngle::set( float value )
{
	m_SmootingAngle = value;
}

////////////////////////////////////////////////////////////////////////////////////////////////////
// MapModel
////////////////////////////////////////////////////////////////////////////////////////////////////

MapModel::MapModel( void ) :
implMapModel( new Mix::Tool::Win32::Graphics::MapModel() ),
m_DynamicsDesigner( nullptr )
{
	implModel = implMapModel;
	implDrawObject = implMapModel;

	m_DynamicsDesigner = gcnew Mix::Tool::Dynamics::Design::Terrain( implMapModel->GetDynamicsDesignerPtr() );
}

MapModel::~MapModel( void )
{
	ReleaseNodeTree();

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

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

bool MapModel::Import( MapModel::ImportConfig^ config )
{
	Mix::Tool::Win32::Graphics::MapModel::IMPORT_CONFIG cfg;

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// 解放
	////////////////////////////////////////////////////////////////////////////////////////////////////

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

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// インポート
	////////////////////////////////////////////////////////////////////////////////////////////////////

	pin_ptr<const wchar_t> ppwFilePath = PtrToStringChars( config->FilePath );

	cfg.pFilePath = ppwFilePath;

	cfg.opt = Model::ToWin32ImportOption( config->Option );

	cfg.scaling = config->Scaling;
	cfg.rotation.x = config->Rotation->X;
	cfg.rotation.y = config->Rotation->Y;
	cfg.rotation.z = config->Rotation->Z;
	cfg.translation.x = config->Translation->X;
	cfg.translation.y = config->Translation->Y;
	cfg.translation.z = config->Translation->Z;

	cfg.cellSize.x = config->CellSize->X;
	cfg.cellSize.y = config->CellSize->Y;
	cfg.cellSize.z = config->CellSize->Z;

	cfg.bSmooting = config->Smooting;
	cfg.smootingAngle = config->SmootingAngle;

	if( implMapModel->Import( cfg ) == false )
	{
		return false;
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// 描画オブジェクトのマテリアルスロットコレクションを初期化
	////////////////////////////////////////////////////////////////////////////////////////////////////

	DrawObject::InitializeMaterialSlotCollection();

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// ノードツリーを構築
	////////////////////////////////////////////////////////////////////////////////////////////////////

	Model::InitializeNodeTree();

	////////////////////////////////////////////////////////////////////////////////////////////////////

	return true;
}

bool MapModel::ImportFinalize( void )
{
	return implMapModel->ImportFinalize();
}

bool MapModel::SaveModel( void )
{
	return implMapModel->SaveModel();
}

Mix::Tool::Dynamics::Design::Terrain^ MapModel::DynamicsDesigner::get( void )
{
	return m_DynamicsDesigner;
}

}}}
