#pragma once

#define DIRECTINPUT_VERSION 0x0800
#define _CRT_SECURE_NO_DEPRECATE
#ifndef _WIN32_DCOM
#define _WIN32_DCOM
#endif

#include <windows.h>
#include <commctrl.h>
#include <basetsd.h>
#include <dinput.h>
#include <dinputd.h>
#include <scol.h>
#include <set>

#include "ou_thread.h"

using namespace std;
using namespace openutils;

//-----------------------------------------------------------------------------
// Function-prototypes
//-----------------------------------------------------------------------------
BOOL CALLBACK    EnumObjectsCallback( const DIDEVICEOBJECTINSTANCE* pdidoi, VOID* pContext );
BOOL CALLBACK    EnumJoysticksCallback( const DIDEVICEINSTANCE* pdidInstance, VOID* pContext );

// Stuff to filter out XInput devices
#include <wbemidl.h>
HRESULT SetupForIsXInputDevice();
bool IsXInputDevice( const GUID* pGuidProductFromDirectInput );
void CleanupForIsXInputDevice();

// Needed for std::set works with GUIDs.
inline bool operator<( const GUID & lhs, const GUID & rhs)
{
  return (memcmp(&lhs, &rhs, sizeof(GUID)) < 0 ? true : false);
}

struct XINPUT_DEVICE_NODE
{
    DWORD dwVidPid;
    XINPUT_DEVICE_NODE* pNext;
};

struct DI_ENUM_CONTEXT
{
    DIJOYCONFIG* pPreferredJoyCfg;
    bool bPreferredJoyCfgValid;
};


class Joypad : public Thread
{
public:
  Joypad(void);
  ~Joypad(void);

  bool isrunning ;
  void run() ;
  UINT tick;
  GUID instanceid;

  HRESULT InitDirectInput();
  VOID FreeDirectInput();
  HRESULT UpdateInputState();

  LPDIRECTINPUTDEVICE8 pJoystick;
  DI_ENUM_CONTEXT pEnumContext;
  DIJOYSTATE2 js;           // DInput joystick state 
};
