/***************************************************************************/
/*                                                                         */
/*  gamepad.h                                                              */
/*                                                                         */
/***************************************************************************/
/*
     *****************************************************************
  ***                                                                 ***  
***        | iAnalogStick                                  Y   B        ***
*       ___|___               xfactordev.net                               *
*          |                                             X    A            *
  *        |                                                              *
  *                                                                      *
   *          x bButtonPad                                  |           *
    *         x                                          ___|___       *
     *    xxxxxxxxx    *****************************        |         *
      *       x       *                             *       |        *
	  *       x      *    start         back         * iRightStick  *
	   *             *                               *             * 
	    *           *                                 *           *
	      *********                                     *********


*/
/***************************************************************************/
/*                                                                         */
/*  How the class works?                                                   */
/*                                                                         */
/***************************************************************************/
/*
	CGamePad p;			// Create global instance
	p.InitGamePad();    // Initilise it once.

	// Every time you check for button-presses, first call the member function,
	// GetInput().  The member variable will contain the changes and
	// can be tested for as follows.
	p.GetInput();
	
	// Then we can test for button presses using the functions such as
	
	p.bBlackButtonPressed();
	p.iRightStickUp();
	...etc..etc

	You can pass an integer to them, e.g. 0, 1, 2, 3...for the various
	gamepads, if you don't pass a number, the default gamepad is the first
	one, gamepad 0 (very left one).

  
/***************************************************************************/





#ifndef _GAMEPAD_H
#define _GAMEPAD_H

#include <xtl.h>


// Deadzone for thumbsticks
#define XBINPUT_DEADZONE 0.35f
const SHORT XINPUT_DEADZONE = (SHORT)( 0.2f * FLOAT(0X7FFF) );

class CGamePad
{
public:
//---------------------------------------------------------------------------
// These few methods will be the means of getting our feedback!  Testing for
// for button presses etc.
//---------------------------------------------------------------------------
// Default gamepad is 0...so if you dont' specify which one, it will assume
// the very left gamepad.

float fLeftTrigger(int iWhichGamePad = 0);
float fRightTrigger(int iWhichGamepad = 0);


bool bBlackButtonPressed(int iWhichGamePad = 0);
bool bWhiteButtonPressed( int iWhichGamePad = 0);

bool bYellowButtonPressed( int iWhichGamePad = 0);
bool bRedButtonPressed( int iWhichGamePad = 0);
bool bBlueButtonPressed( int iWhichGamePad = 0);
bool bGreenButtonPressed( int iWhichGamePad = 0);

bool bStartButton( int iWhichGamePad = 0);
bool bBackButton( int iWhichGamePad = 0);

//---------------------------------------------------------------------------

float iAnalogStickUp   ( int iWhichGamePad = 0);
float iAnalogStickDown ( int iWhichGamePad = 0);
float iAnalogStickLeft ( int iWhichGamePad = 0);
float iAnalogStickRight( int iWhichGamePad = 0);

//---------------------------------------------------------------------------

bool bButtonPadUp   ( int iWhichGamePad = 0);
bool bButtonPadDown ( int iWhichGamePad = 0);
bool bButtonPadRight( int iWhichGamePad = 0);
bool bButtonPadLeft ( int iWhichGamePad = 0);

//[NOTE]
//Single button depresses, e.g. will not repeat. The button has
//to be pressed repeatedly.
//if( m_Gamepads[0].wPressedButtons & XINPUT_GAMEPAD_DPAD_UP)
//if( m_Gamepads[0].wPressedButtons & XINPUT_GAMEPAD_DPAD_DOWN)
//if( m_Gamepads[0].wPressedButtons & XINPUT_GAMEPAD_DPAD_LEFT)
//if( m_Gamepads[0].wPressedButtons & XINPUT_GAMEPAD_DPAD_RIGHT)
//---------------------------------------------------------------------------



float iRightStickUp   ( int iWhichGamePad = 0); // default is first gamepad
float iRightStickDown ( int iWhichGamePad = 0);
float iRightStickLeft ( int iWhichGamePad = 0);
float iRightStickRight( int iWhichGamePad = 0);

//---------------------------------------------------------------------------


public:

//----------------------------------------------------------------------------
// Name: struct XBGAMEPAD
// Desc: structure for holding Game pad data
//----------------------------------------------------------------------------
struct XBGAMEPAD : public XINPUT_GAMEPAD
{
    // The following members are inherited from XINPUT_GAMEPAD:
    //    WORD    wButtons;
    //    BYTE    bAnalogButtons[8];
    //    SHORT   sThumbLX;
    //    SHORT   sThumbLY;
    //    SHORT   sThumbRX;
    //    SHORT   sThumbRY;

    // Thumb stick values converted to range [-1,+1]
    FLOAT      fX1;
    FLOAT      fY1;
    FLOAT      fX2;
    FLOAT      fY2;
    
    // State of buttons tracked since last poll
    WORD       wLastButtons;
    BOOL       bLastAnalogButtons[8];
    WORD       wPressedButtons;
    BOOL       bPressedAnalogButtons[8];

    // Rumble properties
    XINPUT_RUMBLE   Rumble;
    XINPUT_FEEDBACK Feedback;

    // Device properties
    XINPUT_CAPABILITIES caps;
    HANDLE     hDevice;

    // Flags for whether game pad was just inserted or removed
    BOOL       bInserted;
    BOOL       bRemoved;
};




public:

	void InitGamePad();   // ~1~

	void GetInput();      // ~2~

	void Rumble(int iWhichGamePad, float lMotor, float rMotor);

	void CheckResetCall();

protected:
	HRESULT CreateGamepads();

	//XDEVICE_PREALLOC_TYPE*	m_InputDeviceTypes;
	//DWORD					m_dwNumInputDeviceTypes;
	XINPUT_STATE			m_InputStates[4];


	XBGAMEPAD m_Gamepads[4];

};



#endif //_GAMEPAD_H