#pragma once

#include <map>
#include <vector>
#include <string>

#include "Mix/Tool/Win32/Core/File/OutputStream.h"
#include "Mix/Tool/Win32/Core/Graphics/SceneObject.h"
#include "Mix/Tool/Win32/Core/Graphics/LineHelper.h"

namespace Mix{ namespace Tool{ namespace Win32{ namespace Graphics{

	class Camera;
	class Material;
	class MaterialSlot;

	class DrawObject : public Mix::Tool::Win32::Graphics::SceneObject
	{
	protected:
		enum DRAW_FLAG
		{
			DF_BODY					= 0x00000001,
			DF_VIEWVOLUME			= 0x00000002,
			DF_BONE					= 0x00000004,
			DF_KINEMATIC_CHARACTER	= 0x00000008,
			DF_COLLISION			= 0x00000010,
			DF_JOINT				= 0x00000020,
		};

		struct DRAW_EVENT_ARGS
		{
			unsigned int flags;

			D3DXVECTOR4 selectColor;
			float axisScale;

			D3DXVECTOR4 viewVolumeColor;
			D3DXVECTOR4 boneColor;

			D3DXVECTOR4 kinematicCharacterColor;
			D3DXVECTOR4 sensorColor;
			D3DXVECTOR4 collisionColor;
			D3DXVECTOR4 jointAxisColor;
			D3DXVECTOR4 jointBallColor;
			D3DXVECTOR4 jointLimitColor;
			float jointScale;

			const Mix::Tool::Win32::Graphics::Camera* pCamera;

			Mix::Tool::Win32::Graphics::LineHelper* pLineHelper;

			std::vector<Mix::Tool::Win32::Graphics::OPACITY_SUBSET>* pOpacitySubsets;
			std::vector<Mix::Tool::Win32::Graphics::TRANSPARENCY_SUBSET>* pTransparencySubsets;
			std::vector<Mix::Tool::Win32::Graphics::REFRACT_SUBSET>* pRefractSubsets;

			std::vector<Mix::Tool::Win32::Graphics::OPACITY_SUBSET>* pSelectMapSubsets;
			std::vector<Mix::Tool::Win32::Graphics::TRANSPARENCY_SUBSET>* pSelectSubsets;

			DRAW_EVENT_ARGS( void )
			{
				flags = 0;

				selectColor = D3DXVECTOR4( 1.0f, 1.0f, 1.0f, 1.0f );
				axisScale = 0.1f;

				viewVolumeColor = D3DXVECTOR4( 1.0f, 1.0f, 1.0f, 1.0f );
				boneColor = D3DXVECTOR4( 1.0f, 1.0f, 1.0f, 1.0f );

				sensorColor = D3DXVECTOR4( 1.0f, 1.0f, 1.0f, 1.0f );
				collisionColor = D3DXVECTOR4( 1.0f, 1.0f, 1.0f, 1.0f );
				jointAxisColor = D3DXVECTOR4( 1.0f, 1.0f, 1.0f, 1.0f );
				jointBallColor = D3DXVECTOR4( 1.0f, 1.0f, 1.0f, 1.0f );
				jointLimitColor = D3DXVECTOR4( 1.0f, 1.0f, 1.0f, 1.0f );
				jointScale = 1.0f;

				pLineHelper = NULL;

				pOpacitySubsets = NULL;
				pTransparencySubsets = NULL;
				pRefractSubsets = NULL;

				pSelectMapSubsets = NULL;
				pSelectSubsets = NULL;
			}
		};

	private:
		static const unsigned int MAX_SLOTNAME_NUMBER;

	private:
//		D3DXVECTOR3 m_Scaling;
//		D3DXVECTOR3 m_Rotation;
//		D3DXVECTOR3 m_Translation;

		int m_DisableCount;

		D3DXMATRIX m_WorldMatrix;

		Mix::Tool::Win32::Geometry::SPHERE m_RotationLightVolume;

		std::vector<Mix::Tool::Win32::Graphics::MaterialSlot*> m_MaterialSlotList;

	private:
		bool CreateMaterialSlotName( Mix::Tool::Win32::Graphics::MaterialSlot* pMaterialSlot, const wchar_t* pRequestName, std::wstring& name );
//		void UpdateWorldMatrix( void );

	protected:
		//すべてのマテリアルスロットを更新( 描画オブジェクトへは通知しません )
		void UpdateAllMaterialSlot( void );

		//すべてのデフォルトマテリアルを書き込む
		bool WriteAllMaterials( const wchar_t* pFilePath, Mix::Tool::Win32::File::OutputStream& output );

		//ライト回転用ボリュームの設定
		void SetRotationLightVolume( const Mix::Tool::Win32::Geometry::SPHERE& sphere );

	public:
		DrawObject( void );
		virtual ~DrawObject( void );
/*
		//スケーリング
		void SetScaling( const D3DXVECTOR3& scaling );
		const D3DXVECTOR3& GetScaling( void ) const;

		//ローテーション
		void SetRotation( const D3DXVECTOR3& rot );
		const D3DXVECTOR3& GetRotation( void ) const;

		//トランスレーション
		void SetTranslation( const D3DXVECTOR3& translation );
		const D3DXVECTOR3& GetTranslation( void ) const;
*/
		//有効、無効
		int Enable( void );
		int Disable( void );
		int GetDisableCount( void ) const;

		//ワールド行列
		const D3DXMATRIX& GetWorldMatrix( void ) const;
		void SetWorldMatrix( const D3DXMATRIX& worldMat );
		void ResetWorldMatrix( void );

		//ライト回転用ボリュームの取得
		const Mix::Tool::Win32::Geometry::SPHERE& GetRotationLightVolume( void ) const;

		//マテリアルスロット
		unsigned int GetMaterialSlotCount( void ) const;
		unsigned int GetMaterialSlotIndex( const char* pName ) const;
		unsigned int GetMaterialSlotIndex( const wchar_t* pName ) const;
		Mix::Tool::Win32::Graphics::MaterialSlot* GetMaterialSlotByIndex( unsigned int index );
		Mix::Tool::Win32::Graphics::MaterialSlot* GetMaterialSlotByName( const char* pName );
		Mix::Tool::Win32::Graphics::MaterialSlot* GetMaterialSlotByName( const wchar_t* pName );
		Mix::Tool::Win32::Graphics::Material* AddMaterialSlot( const char* pName );
		Mix::Tool::Win32::Graphics::Material* AddMaterialSlot( const wchar_t* pName );
		Mix::Tool::Win32::Graphics::Material* GetMaterial( unsigned int index ) const;

		//マテリアルの保存(ファイル)
		bool SaveMaterials( void );

	protected:
		virtual void OnUpdate( void ) {}
		virtual void OnRefresh( void ) {}
		virtual void OnDraw( DrawObject::DRAW_EVENT_ARGS& args ) {}
		virtual void OnRefreshMesh( unsigned int materialSlotIndex ) {}

	public:
		virtual Mix::Tool::Win32::Object::TYPE GetType( void ) const;
		virtual bool QueryType( Mix::Tool::Win32::Object::TYPE type ) const;

		friend class Scene;
		friend class MaterialSlot;
	};

}}}}
