#pragma once

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 環境の定義
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

#ifndef WINVER
	//! @def WINVER
	//! @brief Windowsのバージョン
	#define WINVER 0x0600	//WindowsVista 以降
#endif //WINVER

#ifndef _WIN32_WINNT
	//! @def _WIN32_WINNT
	//! @brief Windowsのバージョン
	#define _WIN32_WINNT 0x0600	//WindowsVista 以降
#endif //_WIN32_WINNT

#ifndef _WIN32_IE
	//! @def _WIN32_IE
	//! @brief IEのバージョン
	#define _WIN32_IE 0x560		//IE5.6以降
#endif //_WIN32_IE

#ifndef STRICT
	//! @def STRICT
	//! @brief ストリクト
	#define STRICT
#endif //STRICT

#ifndef DIRECTINPUT_VERSION
	//! @def DIRECTINPUT_VERSION
	//! @brief DirectInputのバージョン
	#define DIRECTINPUT_VERSION 0x800
#endif //DIRECTINPUT_VERSION

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// インクルード
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

#include <winsock2.h>
#include <ws2tcpip.h>
#include <winuser.h>
#include <typeinfo>
#include <memory>
#include <algorithm>
#include <time.h>
#include <math.h>
#include <mmsystem.h>
#include <mmreg.h>
#include <msacm.h>
#include <process.h>
#include <shlobj.h>
#include <Imm.h>
#include <list>
#include <vector>
#include <map>

#include <InitGuid.h>
#include <d3dcompiler.h>
#include <ddraw.h>
#include <d3d9.h>
#include <d3d11.h>
#include <dxgi.h>
#include <dinput.h>
#include <XInput.h>
#include <XAudio2.h>
#include <X3daudio.h>

#include "btBulletDynamicsCommon.h"
#include "BulletWorldImporter/btBulletWorldImporter.h"
#include "BulletCollision/CollisionDispatch/btGhostObject.h"
#include "BulletDynamics/Character/btKinematicCharacterController.h"

#include "Mix/Standard.h"
#include "Mix/Private/Logger.h"

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// マクロ
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

// Mix のメモリ管理を使用した、メモリの確保、解放 //

#define MIX_LIB_MALLOC( section, size ) Mix::Memory::Allocate( section, size, __FILEW__, __LINE__ )
#define MIX_LIB_MALLOC_T( section, T, count ) static_cast<T*>( Mix::Memory::Allocate( section, sizeof( T ) * count, __FILEW__, __LINE__ ) )
#define MIX_LIB_ALIGNED_MALLOC( section, alignment, size ) Mix::Memory::AllocateAligned( section, alignment, size, __FILEW__, __LINE__ )
#define MIX_LIB_ALIGNED_MALLOC_T( section, alignment, T, count ) static_cast<T*>( Mix::Memory::Allocate( section, alignment, sizeof( T ) * count, __FILEW__, __LINE__ ) )
#define MIX_LIB_FREE( ptr ) if( ptr != NULL ) { Mix::Memory::Free( ptr, __FILEW__, __LINE__ ); ptr = NULL; }

#define MIX_LIB_REALLOC( ptr, size ) Mix::Memory::Reallocate( ptr, size, __FILEW__, __LINE__ )
#define MIX_LIB_REALLOC_T( ptr, T, count ) static_cast<T*>( Mix::Memory::Reallocate( ptr, sizeof( T ) * count ), __FILEW__, __LINE__ )

// Mix のメモリ管理を使用した、インスタンスの作成、削除 //

#define MIX_LIB_NEW_T( section, T, ... ) new( section, __FILEW__, __LINE__ ) T( __VA_ARGS__ )
#define MIX_LIB_ALIGNED_NEW_T( section, align, T, ... ) new( section, align, __FILEW__, __LINE__ ) T( __VA_ARGS__ )

#define MIX_LIB_DELETE_T( T, ptr ) \
	if( ptr != NULL ) \
	{ \
		ptr->~T(); \
		Mix::Memory::Free( ptr, __FILEW__, __LINE__ ); \
		ptr = NULL; \
	}

#define MIX_LIB_DELETE_THIS_T( T, ptr ) \
	ptr->~T(); \
	Mix::Memory::Free( ptr, __FILEW__, __LINE__ );

// Mix のメモリ管理を使用した、インスタンス配列の作成、削除 //

#define MIX_LIB_NEW_ARRAY_T( section, T, count ) new( section, __FILEW__, __LINE__ ) T[count]
#define MIX_LIB_ALIGNED_NEW_ARRAY_T( section, align, T, count ) new( section, align, __FILEW__, __LINE__ ) T[count]

#define MIX_LIB_DELETE_ARRAY_T( T, ptr ) MIX_DELETE_ARRAY_T( T, ptr )
#define MIX_LIB_DELETE_PTR_ARRAY_T( ptr ) MIX_DELETE_PTR_ARRAY_T( ptr )

// 専用のメモリ管理を持っているライブラリ ( Bullet など ) などの、インスタンスの作成、削除 //

#define MIX_LIB_NEW new

#define MIX_LIB_DELETE( ptr ) \
	if( ptr != NULL ) \
	{ \
		delete ptr; \
		ptr = NULL; \
	}

#define MIX_LIB_DELETE_THIS( ptr ) delete ptr

#define MIX_LIB_DELETE_ARRAY( ptr ) \
	if( ptr != NULL ) \
	{ \
		delete [] ptr; \
		ptr = NULL; \
	}

//構造体メンバへのオフセットを取得
#define MIX_OFFSETOF( Class, Value ) static_cast<UInt16>( offsetof( Class, Value ) )

//ネームで NULL を渡さないようにするための定義
//#define MIX_SAFE_NAME( name ) ( name != NULL )? name : L"UNKNOWN"
#define MIX_SAFE_NAME( name ) ( ( name == NULL ) || ( wcslen( name ) == 0 ) )? Mix::STR_UNKNOWN : name

//文字列の長さを取得
#define MIX_STR_LENGTH( str ) ( ( str != NULL )? ::wcslen( str ) : 0 )
//文字列をNULLでも返せるように
#define MIX_SAFE_STR( str ) ( ( str != NULL )? str : L"" )

//ログ : サポート
#define MIX_LOG_STR( str ) ( str != NULL )? str : L"NULL"	//文字列
#define MIX_LOG_PTR( ptr ) ( ptr != NULL )? L"○" : L"×"	//ポインタ
#define MIX_LOG_BOOLEAN( state ) ( ( state ) == True )? L"○" : L"×"	//Boolean

//ログ : 情報
#ifdef _DEBUG
	#define MIX_LOG_INFO( format, ... ) Logger::Instance()->WriteText( Mix::Logger::L_INFO, 0, format, __VA_ARGS__ )
	#define MIX_LOG_INFO_NO( format, ... ) Logger::Instance()->WriteText( Mix::Logger::L_INFO, Mix::Logger::F_NO_OVERLAP, format, __VA_ARGS__ )
	#define MIX_LOG_INFO_SL_NO() Logger::Instance()->WriteSectionLine( Mix::Logger::L_INFO, Mix::Logger::F_NO_OVERLAP );
	#define MIX_LOG_INFO_SECT_START( format, ... ) Logger::Instance()->WriteSctionStart( Mix::Logger::L_INFO, Mix::Logger::F_NO_OVERLAP, format, __VA_ARGS__ )
	#define MIX_LOG_INFO_SECT_END() Logger::Instance()->WriteSctionEnd( Mix::Logger::L_INFO, Mix::Logger::F_NO_OVERLAP )
#else //_DEBUG
	#define MIX_LOG_INFO( format, ... )
	#define MIX_LOG_INFO_NO( format, ... )
	#define MIX_LOG_INFO_SL_NO()
	#define MIX_LOG_INFO_SECT_START( format, ... )
	#define MIX_LOG_INFO_SECT_END()
#endif //_DEBUG

//ログ : 情報( リリースでも出力する )
#define MIX_LOG_INFO_F( format, ... ) Logger::Instance()->WriteText( Mix::Logger::L_INFO_FORCE, 0, format, __VA_ARGS__ )
#define MIX_LOG_INFO_F_NO( format, ... ) Logger::Instance()->WriteText( Mix::Logger::L_INFO_FORCE, Mix::Logger::F_NO_OVERLAP, format, __VA_ARGS__ )
#define MIX_LOG_INFO_F_SL_NO() Logger::Instance()->WriteSectionLine( Mix::Logger::L_INFO_FORCE, Mix::Logger::F_NO_OVERLAP );
#define MIX_LOG_INFO_F_SECT_START( format, ... ) Logger::Instance()->WriteSctionStart( Mix::Logger::L_INFO_FORCE, 0, format, __VA_ARGS__ )
#define MIX_LOG_INFO_F_SECT_END() Logger::Instance()->WriteSctionEnd( Mix::Logger::L_INFO_FORCE, 0 )

//ログ : 警告
#define MIX_LOG_WARNING( format, ... ) Logger::Instance()->WriteText( Mix::Logger::L_WARNING, 0, format, __VA_ARGS__ )
#define MIX_LOG_WARNING_NO( format, ... ) Logger::Instance()->WriteText( Mix::Logger::L_WARNING, Mix::Logger::F_NO_OVERLAP, format, __VA_ARGS__ )
#define MIX_LOG_WARNING_SL_NO() Logger::Instance()->WriteSectionLine( Mix::Logger::L_WARNING, Mix::Logger::F_NO_OVERLAP );
#define MIX_LOG_WARNING_SECT_START( format, ... ) Logger::Instance()->WriteSctionStart( Mix::Logger::L_WARNING, 0, format, __VA_ARGS__ )
#define MIX_LOG_WARNING_SECT_END() Logger::Instance()->WriteSctionEnd( Mix::Logger::L_WARNING, 0 )

//ログ : エラー
#define MIX_LOG_ERROR( format, ... ) Logger::Instance()->WriteText( Mix::Logger::L_ERROR, 0, format, __VA_ARGS__ )
#define MIX_LOG_ERROR_NO( format, ... ) Logger::Instance()->WriteText( Mix::Logger::L_ERROR, Mix::Logger::F_NO_OVERLAP, format, __VA_ARGS__ )
#define MIX_LOG_ERROR_SL_NO() Logger::Instance()->WriteSectionLine( Mix::Logger::L_ERROR, Mix::Logger::F_NO_OVERLAP );
#define MIX_LOG_ERROR_SECT_START( format, ... ) Logger::Instance()->WriteSctionStart( Mix::Logger::L_ERROR, 0, format, __VA_ARGS__ )
#define MIX_LOG_ERROR_SECT_END() Logger::Instance()->WriteSctionEnd( Mix::Logger::L_ERROR, 0 )

#ifdef _MIX_DEVELOP

	//ログ : 情報(DEVELOP)
	#define MIX_LOG_DEV_INFO( format, ... ) Logger::Instance()->WriteText( Mix::Logger::L_INFO, Mix::Logger::F_DEVELOP, format, __VA_ARGS__ )
	#define MIX_LOG_DEV_INFO_NO( format, ... ) Logger::Instance()->WriteText( Mix::Logger::L_INFO, Mix::Logger::F_DEVELOP | Mix::Logger::F_NO_OVERLAP, format, __VA_ARGS__ )
	#define MIX_LOG_DEV_INFO_SL_NO() Logger::Instance()->WriteSectionLine( Mix::Logger::L_INFO, Mix::Logger::F_DEVELOP | Mix::Logger::F_NO_OVERLAP );
	#define MIX_LOG_DEV_INFO_SECT_START( format, ... ) Logger::Instance()->WriteSctionStart( Mix::Logger::L_INFO, Mix::Logger::F_DEVELOP, format, __VA_ARGS__ )
	#define MIX_LOG_DEV_INFO_SECT_END() Logger::Instance()->WriteSctionEnd( Mix::Logger::L_INFO, Mix::Logger::F_DEVELOP )

	//ログ : 警告(DEVELOP)
	#define MIX_LOG_DEV_WARNING( format, ... ) Logger::Instance()->WriteText( Mix::Logger::L_WARNING, Mix::Logger::F_DEVELOP, format, __VA_ARGS__ )
	#define MIX_LOG_DEV_WARNING_NO( format, ... ) Logger::Instance()->WriteText( Mix::Logger::L_WARNING, Mix::Logger::F_DEVELOP | Mix::Logger::F_NO_OVERLAP, format, __VA_ARGS__ )
	#define MIX_LOG_DEV_WARNING_SL_NO() Logger::Instance()->WriteSectionLine( Mix::Logger::L_WARNING, Mix::Logger::F_DEVELOP | Mix::Logger::F_NO_OVERLAP );
	#define MIX_LOG_DEV_WARNING_SECT_START( format, ... ) Logger::Instance()->WriteSctionStart( Mix::Logger::L_WARNING, Mix::Logger::F_DEVELOP, format, __VA_ARGS__ )
	#define MIX_LOG_DEV_WARNING_SECT_END() Logger::Instance()->WriteSctionEnd( Mix::Logger::L_WARNING, Mix::Logger::F_DEVELOP )

	//ログ : エラー(DEVELOP)
	#define MIX_LOG_DEV_ERROR( format, ... ) Logger::Instance()->WriteText( Mix::Logger::L_ERROR, Mix::Logger::F_DEVELOP, format, __VA_ARGS__ )
	#define MIX_LOG_DEV_ERROR_NO( format, ... ) Logger::Instance()->WriteText( Mix::Logger::L_ERROR, Mix::Logger::F_DEVELOP | Mix::Logger::F_NO_OVERLAP, format, __VA_ARGS__ )
	#define MIX_LOG_DEV_ERROR_SL_NO Logger::Instance()->WriteSectionLine( Mix::Logger::L_ERROR, Mix::Logger::F_DEVELOP | Mix::Logger::F_NO_OVERLAP )
	#define MIX_LOG_DEV_ERROR_SECT_START( format, ... ) Logger::Instance()->WriteSctionStart( Mix::Logger::L_ERROR, Mix::Logger::F_DEVELOP, format, __VA_ARGS__ )
	#define MIX_LOG_DEV_ERROR_SECT_END() Logger::Instance()->WriteSctionEnd( Mix::Logger::L_ERROR, Mix::Logger::F_DEVELOP )

#else //_MIX_DEVELOP

	//ログ : 情報(DEVELOP)
	#define MIX_LOG_DEV_INFO( format, ... )
	#define MIX_LOG_DEV_INFO_NO( format, ... )
	#define MIX_LOG_DEV_INFO_SL_NO()
	#define MIX_LOG_DEV_INFO_SECT_START( format, ... )
	#define MIX_LOG_DEV_INFO_SECT_END()

	//ログ : 警告(DEVELOP)
	#define MIX_LOG_DEV_WARNING( format, ... )
	#define MIX_LOG_DEV_WARNING_NO( format, ... )
	#define MIX_LOG_DEV_WARNING_SL_NO()
	#define MIX_LOG_DEV_WARNING_SECT_START( format, ... )
	#define MIX_LOG_DEV_WARNING_SECT_END()

	//ログ : エラー(DEVELOP)
	#define MIX_LOG_DEV_ERROR( format, ... )
	#define MIX_LOG_DEV_ERROR_NO( format, ... )
	#define MIX_LOG_DEV_ERROR_SL_NO
	#define MIX_LOG_DEV_ERROR_SECT_START
	#define MIX_LOG_DEV_ERROR_SECT_END()

#endif //_MIX_DEVELOP

//ログ : 段落
#define MIX_LOG_PAR_PLUS() Logger::Instance()->Par( +1 )
#define MIX_LOG_PAR_MINUS() Logger::Instance()->Par( -1 )

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 内部定義
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

namespace Mix
{
	class Engine;

	//エラー
	enum ERR
	{
		ERR_GRAPHICS_DRIVERERROR	= 0,	//グラフィックス : グラフィックスドライバでエラーが発生( 強制終了 )
		ERR_GRAPHICS_CHANGEMODE		= 1,	//グラフィックス : モードの変更に失敗( 強制終了 )
	};

	//予約ウィンドウメッセージ
	enum WINDOWMESSAGE
	{
		WM_MIX_INTERNALERROR = ( WM_APP + 100 ), //Mixライブラリの内部エラーメッセージ( wParam エラータイプ(ERR) lParam 強制終了する場合は True )
	};

	//ユーザー定義
	static const wchar_t* DEF_USERDIRECTORYNAME = L"mix\\";			//デフォルトのユーザーフォルダ名
	static const wchar_t* SYSTEM_FILENAME = L"mix_system.txt";		//システムファイル名
	static const wchar_t* LOG_FILENAME = L"mix_log.txt";			//ログファイル名

	//文字列リソース
	static const wchar_t* STR_ILLEGALARG = L"不正な引数が渡されました";
	static const wchar_t* STR_ERR_NOT_SUPPORT_VERSION = L"このバージョンはサポートされていません";
	static const wchar_t* STR_ILLEGALFORMAT = L"ファイルフォーマットが不正です";
	static const wchar_t* STR_FORMAT_NOT_SUPPORT = L"指定されたフォーマットはサポートしていません"; 
	static const wchar_t* STR_FILE_FORMAT_NOT_SUPPORT = L"指定されたファイルフォーマットはサポートしていません"; 
	static const wchar_t* STR_TYPE_NOT_SUPPORT = L"指定されたタイプはサポートしていません"; 
	static const wchar_t* STR_OUTOFMEMORY = L"システムメモリが不足しています";
	static const wchar_t* STR_FILENOTFOUND = L"ファイルが見つかりません";
	static const wchar_t* STR_RETERROR = L"がエラーを返しました";
	static const wchar_t* STR_UNUSABLE = L"は使用できません";
	static const wchar_t* STR_INITERROR = L"初期化中にエラーが発生しました";
	static const wchar_t* STR_NULL = L"";
	static const wchar_t* STR_UNKNOWN = L"不明";
	static const wchar_t* STR_ERROR = L"エラー";
	static const wchar_t* STR_CAPACITY = L"Capacity";
	static const wchar_t* STR_TYPE = L"Type";
	static const wchar_t* STR_NAME = L"Name";
	static const wchar_t* STR_FORMAT = L"Format";
	static const wchar_t* STR_RESULT = L"Result";
	static const wchar_t* STR_DEBUGNAME = L"DebugName";
	static const wchar_t* STR_DIRPATH = L"DirectoryPath";
	static const wchar_t* STR_FILEPATH = L"FilePath";
	static const wchar_t* STR_FILENAME = L"FileName";
	static const wchar_t* STR_WIDTH = L"Width";
	static const wchar_t* STR_HEIGHT = L"Height";
	static const wchar_t* STR_SIZE = L"Size";

	HINSTANCE GetInternalInstanceHandle( void );

	Mix::Engine* GetInternalEnginePtr( void );
};

//メモリ
namespace Mix{ namespace Memory{

	static const UInt32 SECTION_TYPE_MAX = SECTION_USER + 1;

}}

//入出力
namespace Mix{ namespace IO{

	class Manager;

	static const UInt32 DIRECTORY_IDENT_MAX = 5; //ディレクトリ識別子の最大数

	Mix::IO::Manager* GetInternalManagerPtr( void );
}}

//ヒューマンインターフェースデバイス
namespace Mix{ namespace HID{

	class Manager;

	static const UInt32 DI_POV_MAX = 8;
	static const UInt32 DI_BUTTON_MAX = 32;
	static const UInt32 DI_BUTTON_MIN = 10;
	static const UInt32 DI_AXIS_MAX = 28;
	static const UInt32 DI_AXIS_MIN = 4;

	struct DI_GAMEPAD_DATA
	{
		UInt8 buttons[DI_BUTTON_MAX];
		Int32 axis[DI_AXIS_MAX];
		UInt32 pov;
	};

	static const UInt32 GAMEPAD_FINGER_MAX = 2;

	Mix::HID::Manager* GetInternalManagerPtr( void );
}}

//ダイナミクス
namespace Mix{ namespace Dynamics{

	class Manager;

	static const Mix::Dynamics::MATERIAL DEF_MATERIAL; //デフォルトマテリアル
	static const UInt32 JOINT_TYPE_MAX = 5; //ジョイントタイプの最大
	static const UInt32 OBJECT_TYPE_MAX = 6; //オブジェクトタイプの最大
	static const UInt32 RB_STATUS_MAX = 3;	//リジッドボディのステータスの最大
	static const UInt32 DDC_MAX = 9; //デバッグ描画色の最大

	static const UInt32 LCPS_MIN_ITE = 4;  // LCP ソルバーの最小反復数
	static const UInt32 LCPS_MAX_ITE = 20; // LCP ソルバーの最大反復数

	static const Float32 CCD_MIN_PENE	= 0.0001f; // CCD ペネトレーションの最小値

	Mix::Dynamics::Manager* GetInternalManagerPtr( void );

}}

//グラフィックス
namespace Mix{ namespace Graphics{

	namespace Common
	{
		class Manager;
	}

	static const UInt32 SHADER_MODEL_MAX			= 3;	//シェーダーモデルの最大数
	static const UInt32 SHADER_TARGET_MAX			= 16;	//シェーダーターゲットの最大数
	static const UInt32 TARGET_MAX					= 4;	//ターゲット最大数
	static const UInt32 VERTEX_ELEMENT_SEMANTIC_MAX	= 9;	//バーテックスエレメントのセマンティックタイプの最大数
	static const UInt32 VERTEX_ELEMENT_FORMAT_MAX	= 14;	//バーテックスエレメントのフォーマットの最大数
	static const UInt32 FILL_MAX					= 2;	//フィルモード最大数
	static const UInt32 CULL_MAX					= 3;	//カリングモード最大数
	static const UInt32 BLEND_MAX					= 6;	//ブレンドモード最大数
	static const UInt32 COLOR_WRITE_MASK_MAX		= 3;	//カラー書き込みマスク最大数
	static const UInt32 ZFUNC_MAX					= 8;	//Zファンクション最大数
	static const UInt32 TEXTURESTAGE_MAX			= 8;	//テクスチャステージ最大数
	static const UInt32 TEXTUREFILTER_MAX			= 3;	//テクスチャフィルタ最大数
	static const UInt32 TEXTUREADDRESS_MAX			= 2;	//テクスチャー座標の解決手法の最大数
	static const UInt32 CUBEMAP_FACE_MAX			= 6;	//キューブマップのフェイス最大数
	static const UInt32 FMT_MAX						= 15;	//フォーマット最大数
	static const UInt32 PT_MAX						= 5;	//プリミティブタイプ数
	static const UInt32 QT_MAX						= 2;	//クエリタイプ数
	static const UInt32 IT_MAX						= 2;	//インデックスタイプ数

	//シェーダーターゲットテーブル
	static const char* SHADER_TARGET_TABLE[Mix::Graphics::SHADER_TARGET_MAX] =
	{
		"vs_3_0",
		"ps_3_0",

		"cs_4_0",
		"gs_4_0",
		"vs_4_0",
		"ps_4_0",

		"cs_4_1",
		"gs_4_1",
		"vs_4_1",
		"ps_4_1",

		"cs_5_0",
		"ds_5_0",
		"gs_5_0",
		"hs_5_0",
		"vs_5_0",
		"ps_5_0",
	};

	Mix::Graphics::Common::Manager* GetInternalManagerPtr( void );

}}

//グラフィックス( ユーティリティ )
namespace Mix{ namespace Graphics{ namespace Utility{

	static const UInt32 MATERIAL_TRANSPARENCY_MAX		= 2;	//半透明メソッドの最大数
	static const UInt32 MOTION_DRIVE_AXIS_MAX			= 3;	//モーションドライブ軸の最大数
	static const UInt32 SCENE_TYPE_MAX					= 1;	//シーンタイプの最大数
	static const UInt32 SCENE_RENDERING_QUALITY_MAX		= 3;	//シーンのレンダリング品質最大数
	static const UInt32 SCENE_SHADOW_QUALITY_MAX		= 3;	//シーンの影品質最大数
	static const UInt32 SCENE_POSTEFFECT_QUALITY_MAX	= 3;	//シーンのポストエフェクト品質最大数

}}}

//サウンド
namespace Mix{ namespace Sound{

	class Manager;

	Mix::Sound::Manager* GetInternalManagerPtr( void );

}}

//並列
namespace Mix{ namespace Parallel{

	class Manager;

	Mix::Parallel::Manager* GetInternalManagerPtr( void );
}}

//シーン
namespace Mix{ namespace Scene{

	namespace Common
	{
		class Manager;
	}

	//ダイナミクス : フィルター構造体
	struct DYNAMICS_FILTER
	{
		UInt16 group;	//グループ
		UInt16 mask;	//マスク
	};

	static const UInt32 MATERIAL_TRANSPARENCY_MAX		= 2;			//半透明メソッドの最大数

	static const UInt32 WCR_MAX							= 4;			//ウォーター判定結果の最大数

	static const UInt32 DKC_MAX							= 2;			//キネマティックキャラクターのモード数

	static const Float32 BRIGHT_PASS_MIN_OFFSET			= 0.0001f;		//ブライトパス : 最小のオフセット

	static const Int32 KS_BLUR_MIN_ITERATION			= 1;			//カーネルサイズを指定するタイプのブラーの最小繰り返し数
	static const Int32 KS_BLUR_MAX_ITERATION			= 16;			//カーネルサイズを指定するタイプのブラーの最大繰り返し数

	static const Float32 GAUSSIAN_BLUR_MIN_DISPERSION	= 000.0001f;	//ガウシアンブラーの最小分散値
	static const Float32 GAUSSIAN_BLUR_MAX_DISPERSION	= 128.0000f;	//ガウシアンブラーの最大分散値
	static const Int32 GAUSSIAN_BLUR_EX_MIN_RADIUS		= 4;			//ガウシアンブラーEXの最小半径
	static const Int32 GAUSSIAN_BLUR_EX_MAX_RADIUS		= 64;			//ガウシアンブラーEXの最大半径

	static const UInt32 DDC_DYNAMICS_FIRST				= 0;			//デバッグ : 描画色 : ダイナミクスの最初
	static const UInt32 DDC_DYNAMICS_LAST				= 8;			//デバッグ : 描画色 : ダイナミクスの最後
	static const UInt32 DDC_MAX							= 21;			//デバッグ : 描画色 : 最大数

	static const wchar_t* STR_DISABLED_DYNAMICS			= L"ダイナミクスが無効になっています。";

	Mix::Scene::Common::Manager* GetInternalManagerPtr( void );

}}

//プラグイン
namespace Mix{ namespace Plugin{

	static const UInt32 TYPE_MAX = 3;	//プラグインのタイプ数( [0]は使用していない )

}}

//STL ( Mix のメモリ管理を使用した List Vector Map の定義 )
namespace Mix{ namespace STL{

	template<Mix::Memory::SECTION_TYPE ST, typename T>
	using List = std::list<T, Mix::Memory::STLAllocator<ST, T>>;

	template<Mix::Memory::SECTION_TYPE ST, typename T>
	using Vector = std::vector<T, Mix::Memory::STLAllocator<ST, T>>;

	template<Mix::Memory::SECTION_TYPE ST, typename KT, typename VT>
	using Map = std::map<KT, VT, std::less<KT>, Mix::Memory::STLAllocator<ST, std::pair<const KT, VT>>>;

	template<Mix::Memory::SECTION_TYPE ST, typename VT>
	Boolean Vector_Contains( const std::vector<VT, Mix::Memory::STLAllocator<ST, VT>>& vector, VT const value )
	{
		return ( std::find( vector.begin(), vector.end(), value ) != vector.end() );
	}

	template<Mix::Memory::SECTION_TYPE ST, typename VT>
	void Vector_FirstErase( std::vector<VT, Mix::Memory::STLAllocator<ST, VT>>& vector,
							size_t index )
	{
		MIX_ASSERT( vector.size() > index );

		size_t lastIndex = vector.size() - 1;

		if( lastIndex > 0 )
		{
			VT temp = vector[index];
			vector[index] = vector[lastIndex];
			vector[lastIndex] = temp;
		}

		vector.pop_back();
	}

	template<Mix::Memory::SECTION_TYPE ST, typename VT>
	void Vector_FirstErase( std::vector<VT, Mix::Memory::STLAllocator<ST, VT>>& vector,
							typename std::vector<VT, Mix::Memory::STLAllocator<ST, VT>>::iterator& it )
	{
		MIX_ASSERT( vector.size() > 0 );

		size_t index = std::distance( vector.begin(), it );
		size_t lastIndex = vector.size() - 1;

		MIX_ASSERT( index <= lastIndex );

		if( lastIndex > 0 )
		{
			VT temp = vector[index];
			vector[index] = vector[lastIndex];
			vector[lastIndex] = temp;
		}

		vector.pop_back();
	}

	template<Mix::Memory::SECTION_TYPE ST, typename VT>
	Boolean Vector_FirstErase(	std::vector<VT, Mix::Memory::STLAllocator<ST, VT>>& vector,
								VT value )
	{
		size_t count = vector.size();
		if( count == 0 )
		{
			return False;
		}

		size_t lastIndex = vector.size() - 1;
		if( lastIndex > 0 )
		{
			std::vector<VT, Mix::Memory::STLAllocator<ST, VT>>::iterator it = std::find( vector.begin(), vector.end(), value );

			if( it != vector.end() )
			{
				size_t index = std::distance( vector.begin(), it );

				VT tempValue = vector[index];
				vector[index] = vector[lastIndex];
				vector[lastIndex] = tempValue;
			}
			else
			{
				return False;
			}
		}

		vector.pop_back();

		return True;
	}

}}
