#pragma once

#include "Mix/Private/HID/Gamepad.h"

namespace Mix{ namespace HID{ namespace XB{

	class Gamepad : public Mix::HID::Gamepad
	{
	private:
		struct TRIGGER_CAP
		{
			UInt8 threshold;
			Float32 norm;
		};

	public:
		static Gamepad* CreateInstance( UInt32 index );

	private:
		UInt32 m_Index;
		XINPUT_STATE m_XIState;
		UInt32 m_ButtonStateList[Mix::HID::GAMEPAD_BUTTON_MAX];
		Gamepad::TRIGGER_CAP m_TriggerCap[Mix::HID::GAMEPAD_FINGER_MAX];
		Float32 m_Trigger[Mix::HID::GAMEPAD_FINGER_MAX];
		Mix::Vector2 m_Stick[Mix::HID::GAMEPAD_FINGER_MAX];
		Boolean m_bRefreshButtonState;
		Boolean m_bAvailable;

	private:
		Gamepad( UInt32 index );
		virtual ~Gamepad( void );

		void UpdateState( const XINPUT_STATE& state );
		void ResetState( void );

	public:
		virtual void Update( void );
		virtual void Dispose( void );

	public:
		virtual UInt32 GetButtonState( UInt32 index ) const;
		virtual Float32 GetTriggerState( UInt32 index ) const;
		virtual const Mix::Vector2& GetStickState( UInt32 index ) const;
		virtual Boolean IsAvailable( void ) const;
		virtual Mix::HID::GAMEPAD_API GetAPI( void ) const;
		virtual UInt8 GetSourceButtonValue( UInt32 index ) const;
		virtual UInt32 GetSourcePovValue( UInt32 index ) const;
		virtual void SetButtonAssignment( UInt32 targetIndex, UInt32 sourceIndex );
		virtual UInt32 GetButtonAssignment( UInt32 targetIndex ) const;
		virtual void SetTriggerAssignment( UInt32 targetIndex, UInt32 sourceIndex );
		virtual UInt32 GetTriggerAssignment( UInt32 targetIndex ) const;
		virtual void SetTriggerThreshold( UInt32 index, UInt8 threshold );
		virtual UInt8 GetTriggerThreshold( UInt32 index ) const;

	private:
		static const UInt32 XI_BUTTON_TABLE[Mix::HID::GAMEPAD_BUTTON_MAX];
	};

}}}
