module external.directx.xinput;

import external.directx.win32;

version = XINPUT_USE_1_3;

version (XINPUT_USE_9_1_0)
{
    enum XINPUT_DLL_A = "xinput9_1_0.dll";
    enum XINPUT_DLL_W = "xinput9_1_0.dll"w;
}
else
{
    enum XINPUT_DLL_A = "xinput1_3.dll";
    enum XINPUT_DLL_W = "xinput1_3.dll"w;
}

alias XINPUT_DLL = XINPUT_DLL_W;
enum XINPUT_DEVTYPE_GAMEPAD = 0x01;
enum XINPUT_DEVSUBTYPE_GAMEPAD = 0x01;

version (XINPUT_USE_9_1_0)
{
}
else
{
    enum XINPUT_DEVSUBTYPE_WHEEL = 0x02;
    enum XINPUT_DEVSUBTYPE_ARCADE_STICK = 0x03;
    enum XINPUT_DEVSUBTYPE_FLIGHT_SICK = 0x04;
    enum XINPUT_DEVSUBTYPE_DANCE_PAD = 0x05;
    enum XINPUT_DEVSUBTYPE_GUITAR = 0x06;
    enum XINPUT_DEVSUBTYPE_DRUM_KIT = 0x08;
}

enum XINPUT_CAPS_VOICE_SUPPORTED = 0x0004;
enum XINPUT_GAMEPAD_DPAD_UP = 0x0001;
enum XINPUT_GAMEPAD_DPAD_DOWN = 0x0002;
enum XINPUT_GAMEPAD_DPAD_LEFT = 0x0004;
enum XINPUT_GAMEPAD_DPAD_RIGHT = 0x0008;
enum XINPUT_GAMEPAD_START = 0x0010;
enum XINPUT_GAMEPAD_BACK = 0x0020;
enum XINPUT_GAMEPAD_LEFT_THUMB = 0x0040;
enum XINPUT_GAMEPAD_RIGHT_THUMB = 0x0080;
enum XINPUT_GAMEPAD_LEFT_SHOULDER = 0x0100;
enum XINPUT_GAMEPAD_RIGHT_SHOULDER = 0x0200;
enum XINPUT_GAMEPAD_A = 0x1000;
enum XINPUT_GAMEPAD_B = 0x2000;
enum XINPUT_GAMEPAD_X = 0x4000;
enum XINPUT_GAMEPAD_Y = 0x8000;
enum XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE = 7849;
enum XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE = 8689;
enum XINPUT_GAMEPAD_TRIGGER_THRESHOLD = 30;
enum XINPUT_FLAG_GAMEPAD = 0x00000001;

version (XINPUT_USE_9_1_0)
{
}
else
{
    enum BATTERY_DEVTYPE_GAMEPAD = 0x00;
    enum BATTERY_DEVTYPE_HEADSET = 0x01;
    enum BATTERY_TYPE_DISCONNECTED = 0x00;
    enum BATTERY_TYPE_WIRED = 0x01;
    enum BATTERY_TYPE_ALKALINE = 0x02;
    enum BATTERY_TYPE_NIMH = 0x03;
    enum BATTERY_TYPE_UNKNOWN = 0xFF;
    enum BATTERY_LEVEL_EMPTY = 0x00;
    enum BATTERY_LEVEL_LOW = 0x01;
    enum BATTERY_LEVEL_MEDIUM = 0x02;
    enum BATTERY_LEVEL_FULL = 0x03;
    enum XUSER_MAX_COUNT = 4;
    enum XUSER_INDEX_ANY = 0x000000FF;
    enum VK_PAD_A = 0x5800;
    enum VK_PAD_B = 0x5801;
    enum VK_PAD_X = 0x5802;
    enum VK_PAD_Y = 0x5803;
    enum VK_PAD_RSHOULDER = 0x5804;
    enum VK_PAD_LSHOULDER = 0x5805;
    enum VK_PAD_LTRIGGER = 0x5806;
    enum VK_PAD_RTRIGGER = 0x5807;
    enum VK_PAD_DPAD_UP = 0x5810;
    enum VK_PAD_DPAD_DOWN = 0x5811;
    enum VK_PAD_DPAD_LEFT = 0x5812;
    enum VK_PAD_DPAD_RIGHT = 0x5813;
    enum VK_PAD_START = 0x5814;
    enum VK_PAD_BACK = 0x5815;
    enum VK_PAD_LTHUMB_PRESS = 0x5816;
    enum VK_PAD_RTHUMB_PRESS = 0x5817;
    enum VK_PAD_LTHUMB_UP = 0x5820;
    enum VK_PAD_LTHUMB_DOWN = 0x5821;
    enum VK_PAD_LTHUMB_RIGHT = 0x5822;
    enum VK_PAD_LTHUMB_LEFT = 0x5823;
    enum VK_PAD_LTHUMB_UPLEFT = 0x5824;
    enum VK_PAD_LTHUMB_UPRIGHT = 0x5825;
    enum VK_PAD_LTHUMB_DOWNRIGHT = 0x5826;
    enum VK_PAD_LTHUMB_DOWNLEFT = 0x5827;
    enum VK_PAD_RTHUMB_UP = 0x5830;
    enum VK_PAD_RTHUMB_DOWN = 0x5831;
    enum VK_PAD_RTHUMB_RIGHT = 0x5832;
    enum VK_PAD_RTHUMB_LEFT = 0x5833;
    enum VK_PAD_RTHUMB_UPLEFT = 0x5834;
    enum VK_PAD_RTHUMB_UPRIGHT = 0x5835;
    enum VK_PAD_RTHUMB_DOWNRIGHT = 0x5836;
    enum VK_PAD_RTHUMB_DOWNLEFT = 0x5837;
    enum XINPUT_KEYSTROKE_KEYDOWN = 0x0001;
    enum XINPUT_KEYSTROKE_KEYUP = 0x0002;
    enum XINPUT_KEYSTROKE_REPEAT = 0x0004;

}

struct _XINPUT_GAMEPAD
{
    WORD wButtons;
    byte bLeftTrigger;
    byte bRightTrigger;
    SHORT sThumbLX;
    SHORT sThumbLY;
    SHORT sThumbRX;
    SHORT sThumbRY;
}

alias XINPUT_GAMEPAD = _XINPUT_GAMEPAD;
alias PXINPUT_GAMEPAD = _XINPUT_GAMEPAD*;

struct _XINPUT_STATE
{
    DWORD dwPacketNumber;
    XINPUT_GAMEPAD Gamepad;
}

alias XINPUT_STATE = _XINPUT_STATE;
alias PXINPUT_STATE = _XINPUT_STATE*;

struct _XINPUT_VIBRATION
{
    WORD wLeftMotorSpeed;
    WORD wRightMotorSpeed;
}

alias XINPUT_VIBRATION = _XINPUT_VIBRATION;
alias PXINPUT_VIBRATION = _XINPUT_VIBRATION*;

struct _XINPUT_CAPABILITIES
{
    byte Type;
    byte SubType;
    WORD Flags;
    XINPUT_GAMEPAD Gamepad;
    XINPUT_VIBRATION Vibration;
}

alias XINPUT_CAPABILITIES = _XINPUT_CAPABILITIES;
alias PXINPUT_CAPABILITIES = _XINPUT_CAPABILITIES*;

version (XINPUT_USE_9_1_0)
{
}
else
{
    struct _XINPUT_BATTERY_INFORMATION
    {
        byte BatteryType;
        byte BatteryLevel;
    }

    alias XINPUT_BATTERY_INFORMATION = _XINPUT_BATTERY_INFORMATION;
    alias PXINPUT_BATTERY_INFORMATION = _XINPUT_BATTERY_INFORMATION*;

    struct _XINPUT_KEYSTROKE
    {
        WORD VirtualKey;
        WCHAR Unicode;
        WORD Flags;
        byte UserIndex;
        byte HidCode;
    }

    alias XINPUT_KEYSTROKE = _XINPUT_KEYSTROKE;
    alias PXINPUT_KEYSTROKE = _XINPUT_KEYSTROKE*;
}

extern (Windows)
{
    DWORD XInputGetState(in DWORD dwUserIndex, XINPUT_STATE* pState);
    DWORD XInputSetState(in DWORD dwUserIndex, in XINPUT_VIBRATION* pVibration);
    DWORD XInputGetCapabilities(in DWORD dwUserIndex, in DWORD dwFlags, XINPUT_CAPABILITIES* pCapabilities);
    void XInputEnable(in bool enable);
    DWORD XInputGetDSoundAudioDeviceGuids(in DWORD dwUserIndex, GUID* pDSoundRenderGuid, GUID* pDSoundCaptureGuid);
    version (XINPUT_USE_9_1_0)
    {
    }
    else
    {
        DWORD XInputGetBatteryInformation(in DWORD dwUserIndex, in byte devType, XINPUT_BATTERY_INFORMATION* pBatteryInformation);
        DWORD XInputGetKeystroke(in DWORD dwUserIndex, DWORD dwReserved, PXINPUT_KEYSTROKE pKeystroke);
    }
}
