#pragma once

#include <map>
#include "Mix/Private/Scene/Common/EffectPackage.h"

namespace Mix{ namespace Scene{ namespace Standard{ namespace Common{

	class EffectPackage : public Mix::Scene::Common::EffectPackage
	{
	protected:
		//シェーダータイプ列挙定数
		enum SHADER_TYPES
		{
			// その他 //

			SHADER_SAMPLING_VS					= 1,	// VS : サンプリング
			SHADER_SAMPLING_COPY_PS				= 2,	// PS : サンプリング : コピー
			SHADER_SAMPLING_DOWN2X_PS			= 3,	// PS : サンプリング : ダウン2X
			SHADER_SAMPLING_DOWN4X_PS			= 4,	// PS : サンプリング : ダウン4X

			SHADER_BLUR3X_X_PS					= 5,	// PS : ブラー : 3サンプル : X
			SHADER_BLUR3X_Y_PS					= 6,	// PS : ブラー : 3サンプル : Y
			SHADER_BLUR5X_X_PS					= 7,	// PS : ブラー : 5サンプル : X
			SHADER_BLUR5X_Y_PS					= 8,	// PS : ブラー : 5サンプル : Y

			SHADER_GAUSSIAN_BLUR_X_VS			= 9,	// VS : ガウシアンブラー : デフォルト X
			SHADER_GAUSSIAN_BLUR_X_PS			= 10,	// PS : ガウシアンブラー : デフォルト X
			SHADER_GAUSSIAN_BLUR_Y_VS			= 11,	// VS : ガウシアンブラー : デフォルト Y
			SHADER_GAUSSIAN_BLUR_Y_PS			= 12,	// PS : ガウシアンブラー : デフォルト Y

			SHADER_GAUSSIAN_BLUR_EX_PS			= 13,	// PS : ガウシアンブラー : エクセレント

			SHADER_BP____PS						= 14,	// PS : ブライトパス --- ( L=LUM A=AUTO_MIDDLEGRAY )
			SHADER_BP_L__PS						= 15,	// PS : ブライトパス L--
			SHADER_BP_LA_PS						= 16,	// PS : ブライトパス LA-

			// スカイドーム //

			SHADER_SKYDOME_DEFAULT_VS			= 20,	// VS : デフォルト
			SHADER_SKYDOME_DEFAULT______PS		= 21,	// PS : デフォルト : ---- : ( B=BASE_TEXTURE ( C=CLOUD or C2=CLOUD_LAYER ) L=CLOUD_LIGHTING )
			SHADER_SKYDOME_DEFAULT__C___PS		= 22,	// PS : デフォルト : -C--
			SHADER_SKYDOME_DEFAULT__C2__PS		= 23,	// PS : デフォルト : _C2-
			SHADER_SKYDOME_DEFAULT_B____PS		= 24,	// PS : デフォルト : B---
			SHADER_SKYDOME_DEFAULT_BC___PS		= 25,	// PS : デフォルト : BC--
			SHADER_SKYDOME_DEFAULT_BC2__PS		= 26,	// PS : デフォルト : BC2-

			SHADER_SKYDOME_ATMOSPHERE_VS		= 27,	// VS : 大気散乱シミュレーション
			SHADER_SKYDOME_ATMOSPHERE______PS	= 28,	// PS : 大気散乱シミュレーション : ----
			SHADER_SKYDOME_ATMOSPHERE__C___PS	= 29,	// PS : 大気散乱シミュレーション : -C--
			SHADER_SKYDOME_ATMOSPHERE__C_L_PS	= 30,	// PS : 大気散乱シミュレーション : -C-L
			SHADER_SKYDOME_ATMOSPHERE__C2__PS	= 31,	// PS : 大気散乱シミュレーション : -C2-
			SHADER_SKYDOME_ATMOSPHERE__C2L_PS	= 32,	// PS : 大気散乱シミュレーション : -C2L
			SHADER_SKYDOME_ATMOSPHERE_B____PS	= 33,	// PS : 大気散乱シミュレーション : B---
			SHADER_SKYDOME_ATMOSPHERE_BC___PS	= 34,	// PS : 大気散乱シミュレーション : BC--
			SHADER_SKYDOME_ATMOSPHERE_BC_L_PS	= 35,	// PS : 大気散乱シミュレーション : BC-L
			SHADER_SKYDOME_ATMOSPHERE_BC2__PS	= 36,	// PS : 大気散乱シミュレーション : BC2-
			SHADER_SKYDOME_ATMOSPHERE_BC2L_PS	= 37,	// PS : 大気散乱シミュレーション : BC2L

			SHADER_SKYDOME_PANORAMA_VS			= 38,	// VS : パノラマ
			SHADER_SKYDOME_PANORAMA_FA_VS		= 39,	// VS : パノラマ : フォグ ( 大気散乱シミュレーション )
			SHADER_SKYDOME_PANORAMA_PS			= 40,	// PS : パノラマ
			SHADER_SKYDOME_PANORAMA_FD_PS		= 41,	// PS : パノラマ : フォグ ( デフォルト )
			SHADER_SKYDOME_PANORAMA_FA_PS		= 42,	// PS : パノラマ : フォグ ( 大気散乱シミュレーション )

			// ポストエフェクト //

			SHADER_SSAO_PS						= 50,	// PS : SSAO
			SHADER_SSAO_TEX_PS					= 51,	// PS : SSAO( テクスチャ有り )

			SHADER_SM_FINISH____PS				= 52,	// PS : シャドウマッピング : フィニッシュ : ボケ無し
			SHADER_SM_FINISH__B_PS				= 53,	// PS : シャドウマッピング : フィニッシュ : ボケ有り
			SHADER_SM_FINISH_R__PS				= 54,	// PS : シャドウマッピング : フィニッシュ : ボケ無し( 屈折 )
			SHADER_SM_FINISH_RB_PS				= 55,	// PS : シャドウマッピング : フィニッシュ : ボケ有り( 屈折 )

			SHADER_UNDER_WATER_PS				= 56,	// PS : 水中

			SHADER_LUM_TRANSFORM_INITAL_PS		= 57,	// PS : 輝度 : トランスフォーム : 初期化
			SHADER_LUM_TRANSFORM_ITERATE_PS		= 58,	// PS : 輝度 : トランスフォーム : 繰り返し
			SHADER_LUM_TRANSFORM_FINAL_PS		= 59,	// PS : 輝度 : トランスフォーム : 最後
			SHADER_LUM_ADAPTED_PS				= 60,	// PS : 輝度 : アダプテッド

			SHADER_LUM_OPERATOR_STATIC_PS		= 61,	// PS : 輝度 : オペレータ : 中間色は指定
			SHADER_LUM_OPERATOR_DYNAMIC_PS		= 62,	// PS : 輝度 : オペレータ : 中間色は自動

			SHADER_LUM_OPERATOR___B_PS			= 63,	// PS : 輝度 : オペレータ __B ( T=TONE_MAPPING A=AUTOMATIC_MIDDLEGRAY B=BLUE_SHIFT )
			SHADER_LUM_OPERATOR_T___PS			= 64,	// PS : 輝度 : オペレータ T__
			SHADER_LUM_OPERATOR_T_B_PS			= 65,	// PS : 輝度 : オペレータ T_B
			SHADER_LUM_OPERATOR_TA__PS			= 66,	// PS : 輝度 : オペレータ TA_
			SHADER_LUM_OPERATOR_TAB_PS			= 67,	// PS : 輝度 : オペレータ TAB

			SHADER_LS_INIT___PS					= 68,	// PS : ライトシャフト : 初期化 ( A=ACUITY_TEX )
			SHADER_LS_INIT_A_PS					= 69,	// PS : ライトシャフト : 初期化
			SHADER_LS_BLUR_L_PS					= 70,	// PS : ライトシャフト : ブラー( LOW )
			SHADER_LS_BLUR_M_PS					= 71,	// PS : ライトシャフト : ブラー( MIDDLE )
			SHADER_LS_BLUR_H_PS					= 72,	// PS : ライトシャフト : ブラー( HIGH )

			SHADER_LENS_DIST___PS				= 73,	// PS : レンズ : ディストーション( K=K_CUBE )
			SHADER_LENS_DIST_K_PS				= 74,	// PS : レンズ : ディストーション

			SHADER_LF_IMAGE____PS				= 75,	// PS : レンズフレア : イメージ( G=GHOST_TEX H=HALO )
			SHADER_LF_IMAGE__H_PS				= 76,	// PS : レンズフレア : イメージ _H
			SHADER_LF_IMAGE_G__PS				= 77,	// PS : レンズフレア : イメージ G_
			SHADER_LF_IMAGE_GH_PS				= 78,	// PS : レンズフレア : イメージ GH
			SHADER_LF_MODIFY____PS				= 79,	// PS : レンズフレア : モディファイ( D=DIRT B=BRUSH )
			SHADER_LF_MODIFY_D__PS				= 80,	// PS : レンズフレア : モディファイ D
			SHADER_LF_MODIFY__B_PS				= 81,	// PS : レンズフレア : モディファイ B
			SHADER_LF_MODIFY_DB_PS				= 82,	// PS : レンズフレア : モディファイ DB

			SHADER_FI_HEJL_PS					= 83,	// PS : フィルミック : Jim Hejl
			SHADER_FI_HABLE_PS					= 84,	// PS : フィルミック : John Hable

			SHADER_GAMMA_PS						= 85,	// PS : ガンマ補正

			SHADER_CAM_MOTION_BLUR_L_PS			= 86,	// PS : カメラモーションブラー Low
			SHADER_CAM_MOTION_BLUR_M_PS			= 87,	// PS : カメラモーションブラー Middle
			SHADER_CAM_MOTION_BLUR_H_PS			= 88,	// PS : カメラモーションブラー High

			SHADER_CA_IMAGE___PS				= 89,	// PS : 色収差 : イメージ _ ( K=K_CUBE )
			SHADER_CA_IMAGE_K_PS				= 90,	// PS : 色収差 : イメージ K
			SHADER_CA_FINISH___PS				= 91,	// PS : 色収差 : フィニッシュ _ ( D=DEPTH )
			SHADER_CA_FINISH_D_PS				= 92,	// PS : 色収差 : フィニッシュ D

			SHADER_DOF_PS						= 93,	// PS : 被写界深度

			SHADER_VIGNETTE_PS					= 94,	// PS : ビネット

			SHADER_AA_FXAA_PS					= 95,	// PS : アンチアイリアス : FXAA
		};

		//シェーダーバイナリ構造体
		struct SHADER_BINARY
		{
			enum VALUE{ NAME_SIZE = 64, };

			wchar_t name[SHADER_BINARY::NAME_SIZE];
			const void* pData;
			UInt32 dataSize;
		};

	public:
		//エフェクトタイプ列挙定数
		enum EFFECT_TYPE
		{
			E_RESIDENT = 0,
			E_MATERIAL = 1,
		};

		//常駐エフェクトオプション列挙定数
		enum EFFECT_RESIDENT_OPT
		{
			ER_SAMPLING				= 0,
			ER_BLUR3X				= 1,
			ER_BLUR5X				= 2,
			ER_GAUSSIAN_BLUR		= 3,
			ER_GAUSSIAN_BLUR_EX		= 4,
			ER_BRIGHTPASS			= 5,

			ER_SKYDOME_DEFAULT		= 6,
			ER_SKYDOME_ATMOSPHERE	= 7,
			ER_SKYDOME_PANORAMA_D	= 8,
			ER_SKYDOME_PANORAMA_A	= 9,

			ER_SSAO					= 10,
			ER_SM					= 11,
			ER_UNDER_WATER			= 12,
			ER_LUMINANCE			= 13,
			ER_LIGHT_SHAFTS			= 14,
			ER_LENS_FLARE			= 15,
			ER_FILMIC				= 16,
			ER_CAM_MOTION_BLUR		= 17,
			ER_GAMMA				= 18,
			ER_CHROMATISM			= 19,
			ER_DOF					= 20,
			ER_LENS_DIST			= 21,
			ER_VIGNETTE				= 22,
			ER_FXAA					= 23,
		};

		//バーテックスエフェクトシェーダー構造体
		enum VERTEX_EFFECT_SHADER
		{
			VES_DEFAULT				= 0,

			VES_GAUSSIAN_BLUR_X		= 0,
			VES_GAUSSIAN_BLUR_Y		= 1,

			VES_SKYDOME_PANORAMA	= 0,
			VES_SKYDOME_PANORAMA_F	= 1,

			VES_MATERIAL_COLOR		= 0,
			VES_MATERIAL_MASK		= 1,
			VES_MATERIAL_SHADOW		= 2,
			VES_MATERIAL_MAX		= 3,
		};

		//ピクセルエフェクトシェーダー構造体
		enum PIXEL_EFFECT_SHADER
		{
			PES_DEFAULT					= 0,

			PES_MATERIAL_COLOR			= 0,
			PES_MATERIAL_MASK			= 1,
			PES_MATERIAL_SHADOW			= 2,
			PES_MATERIAL_MAX			= 3,

			PES_SD_DEF_____				= 0,
			PES_SD_DEF__C__				= 1,
			PES_SD_DEF__C2_				= 2,
			PES_SD_DEF_B___				= 3,
			PES_SD_DEF_BC__				= 4,
			PES_SD_DEF_BC2_				= 5,

			PES_SD_ASS_____				= 0,
			PES_SD_ASS__C__				= 1,
			PES_SD_ASS__C_L				= 2,
			PES_SD_ASS__C2_				= 3,
			PES_SD_ASS__C2L				= 4,
			PES_SD_ASS_B___				= 5,
			PES_SD_ASS_BC__				= 6,
			PES_SD_ASS_BC_L				= 7,
			PES_SD_ASS_BC2_				= 8,
			PES_SD_ASS_BC2L				= 9,

			PES_SD_PANORAMA				= 0,
			PES_SD_PANORAMA_F			= 1,

			PES_SAMPLING_COPY			= 0,
			PES_SAMPLING_DOWN2X			= 1,
			PES_SAMPLING_DOWN4X			= 2,

			PES_COMMON_BLUR_X			= 0,
			PES_COMMON_BLUR_Y			= 1,

			PES_BP___					= 0,
			PES_BP_L_					= 1,
			PES_BP_LA					= 2,

			PES_SSAO					= 0,
			PES_SSAO_TEX				= 1,

			PES_SM_FINISH___			= 0,
			PES_SM_FINISH__B			= 1,
			PES_SM_FINISH_R_			= 2,
			PES_SM_FINISH_RB			= 3,

			PES_LUM_TR_INITAL			= 0,
			PES_LUM_TR_ITERATE			= 1,
			PES_LUM_TR_FINAL			= 2,
			PES_LUM_ADAPTED				= 3,
			PES_LUM_OP___B				= 4,
			PES_LUM_OP_T__				= 5,
			PES_LUM_OP_T_B				= 6,
			PES_LUM_OP_TA_				= 7,
			PES_LUM_OP_TAB				= 8,

			PES_LS_INIT__				= 0,
			PES_LS_INIT_A				= 1,
			PES_LS_BLUR_L				= 2,
			PES_LS_BLUR_M				= 3,
			PES_LS_BLUR_H				= 4,

			PES_FI_HEJL					= 0,
			PES_FI_HABLE				= 1,

			PES_CMB_L					= 0,
			PES_CMB_M					= 1,
			PES_CMB_H					= 2,

			PES_LF_IMAGE___				= 0,
			PES_LF_IMAGE__H				= 1,
			PES_LF_IMAGE_G_				= 2,
			PES_LF_IMAGE_GH				= 3,
			PES_LF_MODIFY___			= 4,
			PES_LF_MODIFY_D_			= 5,
			PES_LF_MODIFY__B			= 6,
			PES_LF_MODIFY_DB			= 7,

			PES_CA_IMAGE__				= 0,
			PES_CA_IMAGE_K				= 1,
			PES_CA_FINISH__				= 2,
			PES_CA_FINISH_D				= 3,
			
			PES_LD__					= 0,
			PES_LD_K					= 1,
		};

		//エフェクトプロセスフラグ
		enum EFFECT_PROCESS_FLAG
		{
			EP_FOG			= 0x00000001,
			EP_SHADOW		= 0x00000002,
			EP_REFRACT		= 0x00000004,
			EP_ATMOSPHERE	= 0x00000040,
			EP_SSAO			= 0x00000100,
		};

		//MEPの値
		enum MEP_VALUE
		{
			MEP_MAGICNUMBER		= 0x5F50454D,

			MEP_VERSION_OLD		= 0x01000000,
			MEP_VERSION			= 0x01010000,

			MEP_MTL_SHADER_MAX	= 3,
		};

		//MEPレンダラータイプ列挙定数
		enum MEP_RENDERER_TYPE
		{
			MEP_RT_STANDARD = 0,
			MEP_RT_MAX		= 1,
		};

		//MEPデータヘッダ構造体
		struct MEP_DATA_HEADER
		{
			UInt32 rendererType;
			UInt32 processFlags;
			UInt32 vertexShaderNum;
			UInt32 pixelShaderNum;
		};

		//MEPバーテックスシェーダーヘッダ構造体
		struct MEP_VS_HEADER
		{
			UInt32 id;
			UInt32 buffSize[EffectPackage::VES_MATERIAL_MAX];
			UInt32 elementNum;
			UInt32 reserve;
		};

		//MEPピクセルシェーダーヘッダ構造体
		struct MEP_PS_HEADER
		{
			UInt32 id;
			UInt32 buffSize[EffectPackage::PES_MATERIAL_MAX];
		};

	private:
		typedef std::map<UInt32, EffectPackage::VERTEX_EFFECT> VertexEffectMap;
		typedef std::map<UInt32, EffectPackage::PIXEL_EFFECT> PixelEffectMap;

		Mix::Graphics::IDevice* m_pGraphicsDev;

		Mix::StringW m_DirPath;
		Mix::StringW m_Name;
		Mix::StringW m_FilePath;
		UInt32 m_ProcFlags;

		EffectPackage::VertexEffectMap m_ResidentVEMap;
		EffectPackage::PixelEffectMap m_ResidentPEMap;
		EffectPackage::VertexEffectMap m_MaterialVEMap;
		EffectPackage::PixelEffectMap m_MaterialPEMap;

	protected:
		EffectPackage( const wchar_t* pDirPath, const wchar_t* pName, const wchar_t* pFilePath );
		virtual ~EffectPackage( void );

		virtual void GetShaderBinary( EffectPackage::SHADER_TYPES type, EffectPackage::SHADER_BINARY& out ) = 0;

	public:
		////////////////////////////////////////////////////////////////////////////////////////////////////
		// Mix::Scene::Standard::Common::EffectPackage
		////////////////////////////////////////////////////////////////////////////////////////////////////

		Boolean Initialize(	Mix::IO::IReader* pReader );
		UInt32 GetProcessFlags( void ) const;
		UInt32 ModifyRendererCaps( UInt32 caps ) const;

		////////////////////////////////////////////////////////////////////////////////////////////////////
		// Mix::Scene::Common::EffectPackage
		////////////////////////////////////////////////////////////////////////////////////////////////////

		virtual EffectPackage::VERTEX_EFFECT* GetVertexEffectPtr( UInt32 type, UInt32 opt );
		virtual EffectPackage::PIXEL_EFFECT* GetPixelEffectPtr( UInt32 type, UInt32 opt );

		////////////////////////////////////////////////////////////////////////////////////////////////////
		// Mix::Scene::IEffectPackage
		////////////////////////////////////////////////////////////////////////////////////////////////////

		virtual Mix::Scene::IRenderer::TYPE GetRendererType( void ) const;
		virtual Mix::Scene::IMaterial::TYPE GetMaterialType( void ) const;

	private:
		static const wchar_t* MEP_RENDERER_TYPE_TABLE[EffectPackage::MEP_RT_MAX];
	};

}}}}
