#pragma once

#include <vector>

namespace Mix{ namespace HID{

	class Gamepad;

	class GamepadManager
	{
	private:
		enum PRIVATE_VALUE
		{
			DIDFT_OPTIONAL = 0x80000000,
		};

		static const wchar_t* FAILED_INITIALIZE;

		static DIOBJECTDATAFORMAT OBJ_DATA_FORMAT[61];
		static const DIDATAFORMAT DATA_FORMAT;

	private:
		//デバイス列挙構造体
		struct ENUMDEVICE
		{
			GamepadManager* pMgr;
			Mix::UserFile* pSysReport;
			UInt32 port;
		};

		//軸列挙構造体
		struct ENUMAXIS
		{
			LPDIRECTINPUTDEVICE8 pDevice;
			Boolean bSuccess;
		};

	private:
		HWND m_hWnd;
		LPDIRECTINPUT8 m_pDI;
		Mix::HID::Gamepad* m_pGamepadList[Mix::HID::GAMEPAD_PORT_MAX];

	public:
		MIX_DECLARE_ALLOCATOR();

		GamepadManager( void );
		virtual ~GamepadManager( void );

	private:
		static Boolean CheckXInputDevice( const GUID& productGuid );
		static BOOL CALLBACK DI_EnumDeviceCallback( LPCDIDEVICEINSTANCE lpddi, LPVOID pvRef );
		static BOOL CALLBACK DI_EnumAxisCallback( LPCDIDEVICEOBJECTINSTANCE lpddoi, LPVOID pvRef );

	public:
		Boolean Start( HWND hWnd, Mix::UserFile* pSysReport );
		void Terminate( void );
		void Update( void );

		Boolean Get( UInt32 port, Mix::HID::IGamepad** ppGamepad );
		Boolean Find( Mix::HID::GAMEPAD_API api, Mix::HID::IGamepad** ppGamepad );
	};

}}
