#pragma once

#include "Mix/Scene/IFlowerPackage.h"

namespace Mix{ namespace Scene{ namespace Common{

	class Planter;

	class FlowerPackage : public Mix::Scene::IFlowerPackage
	{
		////////////////////////////////////////////////////////////////////////////////////////////////////
		// Mix::Scene::Common::FlowerPackage
		////////////////////////////////////////////////////////////////////////////////////////////////////

	public:
		enum PRIVATE_VALUE
		{
			TEX_COORD_SIMPLE	= 0,
			TEX_COORD_CROSS		= 4,
			TEX_COORD_MAX		= 12,

			DAT_NEAR			= 0,
			DAT_MID				= 1,
			DAT_FAR				= 2,
			DAT_MAX				= 3,
		};

		struct INTERNAL_MODEL_DATA
		{
			UInt32 numTexCoord;
			const Mix::Vector2* texCoords;

			UInt32 numPoint;
			const Mix::Vector3* points;
		};

		struct INTERNAL_MODEL
		{
			Mix::Scene::IFlowerPackage::MODEL src;

			Mix::Vector2 texCoords[FlowerPackage::TEX_COORD_MAX];
			INTERNAL_MODEL_DATA dats[FlowerPackage::DAT_MAX];
		};

	public:
		static Boolean CheckMaterial( Mix::Scene::IMaterial* pMaterial, const wchar_t* pMes, const wchar_t* pLabel, const wchar_t* pDebugName );
		static FlowerPackage* CreateInstance( Mix::Scene::IMaterial* pMaterial, UInt32 numModel, const Mix::Scene::IFlowerPackage::MODEL* models, const wchar_t* pDebugName );

	private:
		Mix::Scene::IMaterial* m_pMaterial;
		Mix::STL::Vector<Mix::Memory::SECTION_SCENE, Mix::Scene::Common::FlowerPackage::INTERNAL_MODEL> m_ModelList;
		Mix::STL::Vector<Mix::Memory::SECTION_SCENE, Mix::Scene::Common::Planter*> m_PlanterList;

#ifdef _DEBUG
		Mix::StringW m_DebugName;
#endif //_DEBUG

	private:
		FlowerPackage( Mix::Scene::IMaterial* pMaterial, UInt32 numModel, const Mix::Scene::IFlowerPackage::MODEL* models, const wchar_t* pDebugName );
		virtual ~FlowerPackage( void );

		void FillInternalModel( FlowerPackage::INTERNAL_MODEL* model );

		void NotifyMaterialChanged( void );
		void NotifyFlowerModelModified( UInt32 index );

	public:
		void AttachPlanter( Mix::Scene::Common::Planter* pPlanter );
		void DetachPlanter( Mix::Scene::Common::Planter* pPlanter );

		Mix::Scene::IMaterial* GetMaterialPtr( void ) const;
		const Mix::Scene::Common::FlowerPackage::INTERNAL_MODEL* GetInternalModels( void ) const;

		////////////////////////////////////////////////////////////////////////////////////////////////////
		// Mix::Scene::IFlowerPackage
		////////////////////////////////////////////////////////////////////////////////////////////////////

	public:
		virtual void GetMaterial( Mix::Scene::IMaterial** ppMaterial );
		virtual Boolean SetMaterial( Mix::Scene::IMaterial* pMaterial );

		virtual UInt32 GetModelCount( void ) const;
		virtual const Mix::Scene::IFlowerPackage::MODEL& GetModel( UInt32 index ) const;
		virtual void SetModel( UInt32 index, const Mix::Scene::IFlowerPackage::MODEL& model );

	private:
		static const UInt32 VS_INPUT_SIGUNATURE;

		static const Mix::Vector3 SIMPLE_POS_TABLE[4];
		static const Mix::Vector3 CROSS1_POS_TABLE[16];
		static const Mix::Vector3 CROSS2_POS_TABLE[24];

	public:
		static const wchar_t* FAILED_CREATE;
		static const wchar_t* FAILED_SET_MATERIAL;
	};

}}}
