/*
  Simple DirectMedia Layer
  Copyright (C) 1997-2016 Sam Lantinga <slouken@libsdl.org>

  This software is provided 'as-is', without any express or implied
  warranty.  In no event will the authors be held liable for any damages
  arising from the use of this software.

  Permission is granted to anyone to use this software for any purpose,
  including commercial applications, and to alter it and redistribute it
  freely, subject to the following restrictions:

  1. The origin of this software must not be misrepresented; you must not
     claim that you wrote the original software. If you use this software
     in a product, an acknowledgment in the product documentation would be
     appreciated but is not required.
  2. Altered source versions must be plainly marked as such, and must not be
     misrepresented as being the original software.
  3. This notice may not be removed or altered from any source distribution.
*/
#include "../../SDL_internal.h"

#if SDL_JOYSTICK_DINPUT || SDL_JOYSTICK_XINPUT

/* DirectInput joystick driver; written by Glenn Maynard, based on Andrei de
 * A. Formiga's WINMM driver.
 *
 * Hats and sliders are completely untested; the app I'm writing this for mostly
 * doesn't use them and I don't own any joysticks with them.
 *
 * We don't bother to use event notification here.  It doesn't seem to work
 * with polled devices, and it's fine to call IDirectInputDevice8_GetDeviceData and
 * let it return 0 events. */

#include "SDL_error.h"
#include "SDL_assert.h"
#include "SDL_events.h"
#include "SDL_timer.h"
#include "SDL_mutex.h"
#include "SDL_events.h"
#include "SDL_hints.h"
#include "SDL_joystick.h"
#include "../SDL_sysjoystick.h"
#include "../../thread/SDL_systhread.h"
#include "../../core/windows/SDL_windows.h"
#if !defined(__WINRT__)
#include <dbt.h>
#endif

#define INITGUID /* Only set here, if set twice will cause mingw32 to break. */
#include "SDL_windowsjoystick_c.h"
#include "SDL_dinputjoystick_c.h"
#include "SDL_xinputjoystick_c.h"

#include "../../haptic/windows/SDL_dinputhaptic_c.h"    /* For haptic hot plugging */
#include "../../haptic/windows/SDL_xinputhaptic_c.h"    /* For haptic hot plugging */


#ifndef DEVICE_NOTIFY_WINDOW_HANDLE
#define DEVICE_NOTIFY_WINDOW_HANDLE 0x00000000
#endif

/* local variables */
static SDL_bool s_bDeviceAdded = SDL_FALSE;
static SDL_bool s_bDeviceRemoved = SDL_FALSE;
static SDL_JoystickID s_nInstanceID = -1;
static SDL_cond *s_condJoystickThread = NULL;
static SDL_mutex *s_mutexJoyStickEnum = NULL;
static SDL_Thread *s_threadJoystick = NULL;
static SDL_bool s_bJoystickThreadQuit = SDL_FALSE;

JoyStick_DeviceData *SYS_Joystick;    /* array to hold joystick ID values */

static SDL_bool s_bWindowsDeviceChanged = SDL_FALSE;

#ifdef __WINRT__

typedef struct
{
    int unused;
} SDL_DeviceNotificationData;

static void
SDL_CleanupDeviceNotification(SDL_DeviceNotificationData *data)
{
}

static int
SDL_CreateDeviceNotification(SDL_DeviceNotificationData *data)
{
    return 0;
}

static void
SDL_CheckDeviceNotification(SDL_DeviceNotificationData *data)
{
}

#else /* !__WINRT__ */

typedef struct
{
    HRESULT coinitialized;
    WNDCLASSEX wincl;
    HWND messageWindow;
    HDEVNOTIFY hNotify;
} SDL_DeviceNotificationData;


/* windowproc for our joystick detect thread message only window, to detect any USB device addition/removal */
static LRESULT CALLBACK
SDL_PrivateJoystickDetectProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message) {
    case WM_DEVICECHANGE:
        switch (wParam) {
        case DBT_DEVICEARRIVAL:
            if (((DEV_BROADCAST_HDR*)lParam)->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE) {
                s_bWindowsDeviceChanged = SDL_TRUE;
            }
            break;
        case DBT_DEVICEREMOVECOMPLETE:
            if (((DEV_BROADCAST_HDR*)lParam)->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE) {
                s_bWindowsDeviceChanged = SDL_TRUE;
            }
            break;
        }
        return 0;
    }

    return DefWindowProc (hwnd, message, wParam, lParam);
}

static void
SDL_CleanupDeviceNotification(SDL_DeviceNotificationData *data)
{
    if (data->hNotify)
        UnregisterDeviceNotification(data->hNotify);

    if (data->messageWindow)
        DestroyWindow(data->messageWindow);

    UnregisterClass(data->wincl.lpszClassName, data->wincl.hInstance);

    if (data->coinitialized == S_OK) {
        WIN_CoUninitialize();
    }
}

static int
SDL_CreateDeviceNotification(SDL_DeviceNotificationData *data)
{
    DEV_BROADCAST_DEVICEINTERFACE dbh;
    GUID GUID_DEVINTERFACE_HID = { 0x4D1E55B2L, 0xF16F, 0x11CF, { 0x88, 0xCB, 0x00, 0x11, 0x11, 0x00, 0x00, 0x30 } };

    SDL_zerop(data);

    data->coinitialized = WIN_CoInitialize();

    data->wincl.hInstance = GetModuleHandle(NULL);
    data->wincl.lpszClassName = L"Message";
    data->wincl.lpfnWndProc = SDL_PrivateJoystickDetectProc;      /* This function is called by windows */
    data->wincl.cbSize = sizeof (WNDCLASSEX);

    if (!RegisterClassEx(&data->wincl)) {
        WIN_SetError("Failed to create register class for joystick autodetect");
        SDL_CleanupDeviceNotification(data);
        return -1;
    }

    data->messageWindow = (HWND)CreateWindowEx(0,  L"Message", NULL, 0, 0, 0, 0, 0, HWND_MESSAGE, NULL, NULL, NULL);
    if (!data->messageWindow) {
        WIN_SetError("Failed to create message window for joystick autodetect");
        SDL_CleanupDeviceNotification(data);
        return -1;
    }

    SDL_zero(dbh);
    dbh.dbcc_size = sizeof(dbh);
    dbh.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
    dbh.dbcc_classguid = GUID_DEVINTERFACE_HID;

    data->hNotify = RegisterDeviceNotification(data->messageWindow, &dbh, DEVICE_NOTIFY_WINDOW_HANDLE);
    if (!data->hNotify) {
        WIN_SetError("Failed to create notify device for joystick autodetect");
        SDL_CleanupDeviceNotification(data);
        return -1;
    }
    return 0;
}

static void
SDL_CheckDeviceNotification(SDL_DeviceNotificationData *data)
{
    MSG msg;

    if (!data->messageWindow) {
        return;
    }

    while (PeekMessage(&msg, data->messageWindow, 0, 0, PM_NOREMOVE)) {
        if (GetMessage(&msg, data->messageWindow, 0, 0) != 0)  {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }
}

#endif /* __WINRT__ */

/* Function/thread to scan the system for joysticks. */
static int
SDL_JoystickThread(void *_data)
{
    SDL_DeviceNotificationData notification_data;

#if SDL_JOYSTICK_XINPUT
    SDL_bool bOpenedXInputDevices[XUSER_MAX_COUNT];
    SDL_zero(bOpenedXInputDevices);
#endif

    if (SDL_CreateDeviceNotification(&notification_data) < 0) {
        return -1;
    }

    SDL_LockMutex(s_mutexJoyStickEnum);
    while (s_bJoystickThreadQuit == SDL_FALSE) {
        SDL_bool bXInputChanged = SDL_FALSE;

        SDL_CondWaitTimeout(s_condJoystickThread, s_mutexJoyStickEnum, 300);

        SDL_CheckDeviceNotification(&notification_data);

#if SDL_JOYSTICK_XINPUT
        if (SDL_XINPUT_Enabled() && XINPUTGETCAPABILITIES) {
            /* scan for any change in XInput devices */
            Uint8 userId;
            for (userId = 0; userId < XUSER_MAX_COUNT; userId++) {
                XINPUT_CAPABILITIES capabilities;
                const DWORD result = XINPUTGETCAPABILITIES(userId, XINPUT_FLAG_GAMEPAD, &capabilities);
                const SDL_bool available = (result == ERROR_SUCCESS);
                if (bOpenedXInputDevices[userId] != available) {
                    bXInputChanged = SDL_TRUE;
                    bOpenedXInputDevices[userId] = available;
                }
            }
        }
#endif /* SDL_JOYSTICK_XINPUT */

        if (s_bWindowsDeviceChanged || bXInputChanged) {
            SDL_UnlockMutex(s_mutexJoyStickEnum);  /* let main thread go while we SDL_Delay(). */
            SDL_Delay(300); /* wait for direct input to find out about this device */
            SDL_LockMutex(s_mutexJoyStickEnum);

            s_bDeviceRemoved = SDL_TRUE;
            s_bDeviceAdded = SDL_TRUE;
            s_bWindowsDeviceChanged = SDL_FALSE;
        }
    }
    SDL_UnlockMutex(s_mutexJoyStickEnum);

    SDL_CleanupDeviceNotification(&notification_data);

    return 1;
}

void SDL_SYS_AddJoystickDevice(JoyStick_DeviceData *device)
{
    device->send_add_event = SDL_TRUE;
    device->nInstanceID = ++s_nInstanceID;
    device->pNext = SYS_Joystick;
    SYS_Joystick = device;

    s_bDeviceAdded = SDL_TRUE;
}

/* Function to scan the system for joysticks.
 * Joystick 0 should be the system default joystick.
 * It should return 0, or -1 on an unrecoverable fatal error.
 */
int
SDL_SYS_JoystickInit(void)
{
    if (SDL_DINPUT_JoystickInit() < 0) {
        SDL_SYS_JoystickQuit();
        return -1;
    }

    if (SDL_XINPUT_JoystickInit() < 0) {
        SDL_SYS_JoystickQuit();
        return -1;
    }

    s_mutexJoyStickEnum = SDL_CreateMutex();
    s_condJoystickThread = SDL_CreateCond();
    s_bDeviceAdded = SDL_TRUE; /* force a scan of the system for joysticks this first time */

    SDL_SYS_JoystickDetect();

    if (!s_threadJoystick) {
        /* spin up the thread to detect hotplug of devices */
        s_bJoystickThreadQuit = SDL_FALSE;
        s_threadJoystick = SDL_CreateThreadInternal(SDL_JoystickThread, "SDL_joystick", 64 * 1024, NULL);
    }
    return SDL_SYS_NumJoysticks();
}

/* return the number of joysticks that are connected right now */
int
SDL_SYS_NumJoysticks()
{
    int nJoysticks = 0;
    JoyStick_DeviceData *device = SYS_Joystick;
    while (device) {
        nJoysticks++;
        device = device->pNext;
    }

    return nJoysticks;
}

/* detect any new joysticks being inserted into the system */
void
SDL_SYS_JoystickDetect()
{
    JoyStick_DeviceData *pCurList = NULL;

    /* only enum the devices if the joystick thread told us something changed */
    if (!s_bDeviceAdded && !s_bDeviceRemoved) {
        return;  /* thread hasn't signaled, nothing to do right now. */
    }

    SDL_LockMutex(s_mutexJoyStickEnum);

    s_bDeviceAdded = SDL_FALSE;
    s_bDeviceRemoved = SDL_FALSE;

    pCurList = SYS_Joystick;
    SYS_Joystick = NULL;

    /* Look for DirectInput joysticks, wheels, head trackers, gamepads, etc.. */
    SDL_DINPUT_JoystickDetect(&pCurList);

    /* Look for XInput devices. Do this last, so they're first in the final list. */
    SDL_XINPUT_JoystickDetect(&pCurList);

    SDL_UnlockMutex(s_mutexJoyStickEnum);

    while (pCurList) {
        JoyStick_DeviceData *pListNext = NULL;

        if (pCurList->bXInputDevice) {
            SDL_XINPUT_MaybeRemoveDevice(pCurList->XInputUserId);
        } else {
            SDL_DINPUT_MaybeRemoveDevice(&pCurList->dxdevice);
        }

        SDL_PrivateJoystickRemoved(pCurList->nInstanceID);

        pListNext = pCurList->pNext;
        SDL_free(pCurList->joystickname);
        SDL_free(pCurList);
        pCurList = pListNext;
    }

    if (s_bDeviceAdded) {
        JoyStick_DeviceData *pNewJoystick;
        int device_index = 0;
        s_bDeviceAdded = SDL_FALSE;
        pNewJoystick = SYS_Joystick;
        while (pNewJoystick) {
            if (pNewJoystick->send_add_event) {
                if (pNewJoystick->bXInputDevice) {
                    SDL_XINPUT_MaybeAddDevice(pNewJoystick->XInputUserId);
                } else {
                    SDL_DINPUT_MaybeAddDevice(&pNewJoystick->dxdevice);
                }

                SDL_PrivateJoystickAdded(device_index);

                pNewJoystick->send_add_event = SDL_FALSE;
            }
            device_index++;
            pNewJoystick = pNewJoystick->pNext;
        }
    }
}

/* Function to get the device-dependent name of a joystick */
const char *
SDL_SYS_JoystickNameForDeviceIndex(int device_index)
{
    JoyStick_DeviceData *device = SYS_Joystick;

    for (; device_index > 0; device_index--)
        device = device->pNext;

    return device->joystickname;
}

/* Function to perform the mapping between current device instance and this joysticks instance id */
SDL_JoystickID
SDL_SYS_GetInstanceIdOfDeviceIndex(int device_index)
{
    JoyStick_DeviceData *device = SYS_Joystick;
    int index;

    for (index = device_index; index > 0; index--)
        device = device->pNext;

    return device->nInstanceID;
}

/* Function to open a joystick for use.
   The joystick to open is specified by the device index.
   This should fill the nbuttons and naxes fields of the joystick structure.
   It returns 0, or -1 if there is an error.
 */
int
SDL_SYS_JoystickOpen(SDL_Joystick * joystick, int device_index)
{
    JoyStick_DeviceData *joystickdevice = SYS_Joystick;

    for (; device_index > 0; device_index--)
        joystickdevice = joystickdevice->pNext;

    /* allocate memory for system specific hardware data */
    joystick->instance_id = joystickdevice->nInstanceID;
    joystick->hwdata =
        (struct joystick_hwdata *) SDL_malloc(sizeof(struct joystick_hwdata));
    if (joystick->hwdata == NULL) {
        return SDL_OutOfMemory();
    }
    SDL_zerop(joystick->hwdata);
    joystick->hwdata->guid = joystickdevice->guid;

    if (joystickdevice->bXInputDevice) {
        return SDL_XINPUT_JoystickOpen(joystick, joystickdevice);
    } else {
        return SDL_DINPUT_JoystickOpen(joystick, joystickdevice);
    }
}

/* return true if this joystick is plugged in right now */
SDL_bool 
SDL_SYS_JoystickAttached(SDL_Joystick * joystick)
{
    return joystick->hwdata && !joystick->hwdata->removed;
}

void
SDL_SYS_JoystickUpdate(SDL_Joystick * joystick)
{
    if (!joystick->hwdata || joystick->hwdata->removed) {
        return;
    }

    if (joystick->hwdata->bXInputDevice) {
        SDL_XINPUT_JoystickUpdate(joystick);
    } else {
        SDL_DINPUT_JoystickUpdate(joystick);
    }

    if (joystick->hwdata->removed) {
        joystick->force_recentering = SDL_TRUE;
    }
}

/* Function to close a joystick after use */
void
SDL_SYS_JoystickClose(SDL_Joystick * joystick)
{
    if (joystick->hwdata->bXInputDevice) {
        SDL_XINPUT_JoystickClose(joystick);
    } else {
        SDL_DINPUT_JoystickClose(joystick);
    }

    SDL_free(joystick->hwdata);
}

/* Function to perform any system-specific joystick related cleanup */
void
SDL_SYS_JoystickQuit(void)
{
    JoyStick_DeviceData *device = SYS_Joystick;

    while (device) {
        JoyStick_DeviceData *device_next = device->pNext;
        SDL_free(device->joystickname);
        SDL_free(device);
        device = device_next;
    }
    SYS_Joystick = NULL;

    if (s_threadJoystick) {
        SDL_LockMutex(s_mutexJoyStickEnum);
        s_bJoystickThreadQuit = SDL_TRUE;
        SDL_CondBroadcast(s_condJoystickThread); /* signal the joystick thread to quit */
        SDL_UnlockMutex(s_mutexJoyStickEnum);
        SDL_WaitThread(s_threadJoystick, NULL); /* wait for it to bugger off */

        SDL_DestroyMutex(s_mutexJoyStickEnum);
        SDL_DestroyCond(s_condJoystickThread);
        s_condJoystickThread= NULL;
        s_mutexJoyStickEnum = NULL;
        s_threadJoystick = NULL;
    }

    SDL_DINPUT_JoystickQuit();
    SDL_XINPUT_JoystickQuit();

    s_bDeviceAdded = SDL_FALSE;
    s_bDeviceRemoved = SDL_FALSE;
}

/* return the stable device guid for this device index */
SDL_JoystickGUID
SDL_SYS_JoystickGetDeviceGUID(int device_index)
{
    JoyStick_DeviceData *device = SYS_Joystick;
    int index;

    for (index = device_index; index > 0; index--)
        device = device->pNext;

    return device->guid;
}

SDL_JoystickGUID
SDL_SYS_JoystickGetGUID(SDL_Joystick * joystick)
{
    return joystick->hwdata->guid;
}

#endif /* SDL_JOYSTICK_DINPUT || SDL_JOYSTICK_XINPUT */

/* vi: set ts=4 sw=4 expandtab: */
