/*
  Simple DirectMedia Layer
  Copyright (C) 1997-2020 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"

#include "SDL_error.h"
#include "SDL_haptic.h"
#include "../SDL_syshaptic.h"

#if SDL_HAPTIC_DINPUT

#include "SDL_stdinc.h"
#include "SDL_timer.h"
#include "SDL_windowshaptic_c.h"
#include "SDL_dinputhaptic_c.h"
#include "../../joystick/windows/SDL_windowsjoystick_c.h"

/*
 * External stuff.
 */
extern HWND SDL_HelperWindow;


/*
 * Internal stuff.
 */
static SDL_bool coinitialized = SDL_FALSE;
static LPDIRECTINPUT8 dinput = NULL;


/*
 * Like SDL_SetError but for DX error codes.
 */
static int
DI_SetError(const char *str, HRESULT err)
{
    return SDL_SetError("Haptic error %s", str);
}

/*
 * Callback to find the haptic devices.
 */
static BOOL CALLBACK
EnumHapticsCallback(const DIDEVICEINSTANCE * pdidInstance, VOID * pContext)
{
    (void) pContext;
    SDL_DINPUT_MaybeAddDevice(pdidInstance);
    return DIENUM_CONTINUE;  /* continue enumerating */
}

int
SDL_DINPUT_HapticInit(void)
{
    HRESULT ret;
    HINSTANCE instance;

    if (dinput != NULL) {       /* Already open. */
        return SDL_SetError("Haptic: SubSystem already open.");
    }

    ret = WIN_CoInitialize();
    if (FAILED(ret)) {
        return DI_SetError("Coinitialize", ret);
    }

    coinitialized = SDL_TRUE;

    ret = CoCreateInstance(&CLSID_DirectInput8, NULL, CLSCTX_INPROC_SERVER,
        &IID_IDirectInput8, (LPVOID *) &dinput);
    if (FAILED(ret)) {
        SDL_SYS_HapticQuit();
        return DI_SetError("CoCreateInstance", ret);
    }

    /* Because we used CoCreateInstance, we need to Initialize it, first. */
    instance = GetModuleHandle(NULL);
    if (instance == NULL) {
        SDL_SYS_HapticQuit();
        return SDL_SetError("GetModuleHandle() failed with error code %lu.",
            GetLastError());
    }
    ret = IDirectInput8_Initialize(dinput, instance, DIRECTINPUT_VERSION);
    if (FAILED(ret)) {
        SDL_SYS_HapticQuit();
        return DI_SetError("Initializing DirectInput device", ret);
    }

    /* Look for haptic devices. */
    ret = IDirectInput8_EnumDevices(dinput,
        0,
        EnumHapticsCallback,
        NULL,
        DIEDFL_FORCEFEEDBACK |
        DIEDFL_ATTACHEDONLY);
    if (FAILED(ret)) {
        SDL_SYS_HapticQuit();
        return DI_SetError("Enumerating DirectInput devices", ret);
    }
    return 0;
}

int
SDL_DINPUT_MaybeAddDevice(const DIDEVICEINSTANCE * pdidInstance)
{
    HRESULT ret;
    LPDIRECTINPUTDEVICE8 device;
    const DWORD needflags = DIDC_ATTACHED | DIDC_FORCEFEEDBACK;
    DIDEVCAPS capabilities;
    SDL_hapticlist_item *item = NULL;

    if (dinput == NULL) {
        return -1;  /* not initialized. We'll pick these up on enumeration if we init later. */
    }

    /* Make sure we don't already have it */
    for (item = SDL_hapticlist; item; item = item->next) {
        if ((!item->bXInputHaptic) && (SDL_memcmp(&item->instance, pdidInstance, sizeof(*pdidInstance)) == 0)) {
            return -1;  /* Already added */
        }
    }

    /* Open the device */
    ret = IDirectInput8_CreateDevice(dinput, &pdidInstance->guidInstance, &device, NULL);
    if (FAILED(ret)) {
        /* DI_SetError("Creating DirectInput device",ret); */
        return -1;
    }

    /* Get capabilities. */
    SDL_zero(capabilities);
    capabilities.dwSize = sizeof(DIDEVCAPS);
    ret = IDirectInputDevice8_GetCapabilities(device, &capabilities);
    IDirectInputDevice8_Release(device);
    if (FAILED(ret)) {
        /* DI_SetError("Getting device capabilities",ret); */
        return -1;
    }

    if ((capabilities.dwFlags & needflags) != needflags) {
        return -1;  /* not a device we can use. */
    }

    item = (SDL_hapticlist_item *)SDL_calloc(1, sizeof(SDL_hapticlist_item));
    if (item == NULL) {
        return SDL_OutOfMemory();
    }

    item->name = WIN_StringToUTF8(pdidInstance->tszProductName);
    if (!item->name) {
        SDL_free(item);
        return -1;
    }

    /* Copy the instance over, useful for creating devices. */
    SDL_memcpy(&item->instance, pdidInstance, sizeof(DIDEVICEINSTANCE));
    SDL_memcpy(&item->capabilities, &capabilities, sizeof(capabilities));

    return SDL_SYS_AddHapticDevice(item);
}

int
SDL_DINPUT_MaybeRemoveDevice(const DIDEVICEINSTANCE * pdidInstance)
{
    SDL_hapticlist_item *item;
    SDL_hapticlist_item *prev = NULL;

    if (dinput == NULL) {
        return -1;  /* not initialized, ignore this. */
    }

    for (item = SDL_hapticlist; item != NULL; item = item->next) {
        if (!item->bXInputHaptic && SDL_memcmp(&item->instance, pdidInstance, sizeof(*pdidInstance)) == 0) {
            /* found it, remove it. */
            return SDL_SYS_RemoveHapticDevice(prev, item);
        }
        prev = item;
    }
    return -1;
}

/*
 * Callback to get supported axes.
 */
static BOOL CALLBACK
DI_DeviceObjectCallback(LPCDIDEVICEOBJECTINSTANCE dev, LPVOID pvRef)
{
    SDL_Haptic *haptic = (SDL_Haptic *) pvRef;

    if ((dev->dwType & DIDFT_AXIS) && (dev->dwFlags & DIDOI_FFACTUATOR)) {
        const GUID *guid = &dev->guidType;
        DWORD offset = 0;
        if (WIN_IsEqualGUID(guid, &GUID_XAxis)) {
            offset = DIJOFS_X;
        } else if (WIN_IsEqualGUID(guid, &GUID_YAxis)) {
            offset = DIJOFS_Y;
        } else if (WIN_IsEqualGUID(guid, &GUID_ZAxis)) {
            offset = DIJOFS_Z;
        } else if (WIN_IsEqualGUID(guid, &GUID_RxAxis)) {
            offset = DIJOFS_RX;
        } else if (WIN_IsEqualGUID(guid, &GUID_RyAxis)) {
            offset = DIJOFS_RY;
        } else if (WIN_IsEqualGUID(guid, &GUID_RzAxis)) {
            offset = DIJOFS_RZ;
        } else {
            return DIENUM_CONTINUE;   /* can't use this, go on. */
        }

        haptic->hwdata->axes[haptic->naxes] = offset;
        haptic->naxes++;

        /* Currently using the artificial limit of 3 axes. */
        if (haptic->naxes >= 3) {
            return DIENUM_STOP;
        }
    }

    return DIENUM_CONTINUE;
}

/*
 * Callback to get all supported effects.
 */
#define EFFECT_TEST(e,s)               \
if (WIN_IsEqualGUID(&pei->guid, &(e)))   \
   haptic->supported |= (s)
static BOOL CALLBACK
DI_EffectCallback(LPCDIEFFECTINFO pei, LPVOID pv)
{
    /* Prepare the haptic device. */
    SDL_Haptic *haptic = (SDL_Haptic *) pv;

    /* Get supported. */
    EFFECT_TEST(GUID_Spring, SDL_HAPTIC_SPRING);
    EFFECT_TEST(GUID_Damper, SDL_HAPTIC_DAMPER);
    EFFECT_TEST(GUID_Inertia, SDL_HAPTIC_INERTIA);
    EFFECT_TEST(GUID_Friction, SDL_HAPTIC_FRICTION);
    EFFECT_TEST(GUID_ConstantForce, SDL_HAPTIC_CONSTANT);
    EFFECT_TEST(GUID_CustomForce, SDL_HAPTIC_CUSTOM);
    EFFECT_TEST(GUID_Sine, SDL_HAPTIC_SINE);
    /* !!! FIXME: put this back when we have more bits in 2.1 */
    /* EFFECT_TEST(GUID_Square, SDL_HAPTIC_SQUARE); */
    EFFECT_TEST(GUID_Triangle, SDL_HAPTIC_TRIANGLE);
    EFFECT_TEST(GUID_SawtoothUp, SDL_HAPTIC_SAWTOOTHUP);
    EFFECT_TEST(GUID_SawtoothDown, SDL_HAPTIC_SAWTOOTHDOWN);
    EFFECT_TEST(GUID_RampForce, SDL_HAPTIC_RAMP);

    /* Check for more. */
    return DIENUM_CONTINUE;
}

/*
 * Opens the haptic device.
 *
 *    Steps:
 *       - Set cooperative level.
 *       - Set data format.
 *       - Acquire exclusiveness.
 *       - Reset actuators.
 *       - Get supported features.
 */
static int
SDL_DINPUT_HapticOpenFromDevice(SDL_Haptic * haptic, LPDIRECTINPUTDEVICE8 device8, SDL_bool is_joystick)
{
    HRESULT ret;
    DIPROPDWORD dipdw;

    /* Allocate the hwdata */
    haptic->hwdata = (struct haptic_hwdata *)SDL_malloc(sizeof(*haptic->hwdata));
    if (haptic->hwdata == NULL) {
        return SDL_OutOfMemory();
    }
    SDL_memset(haptic->hwdata, 0, sizeof(*haptic->hwdata));

    /* We'll use the device8 from now on. */
    haptic->hwdata->device = device8;
    haptic->hwdata->is_joystick = is_joystick;

    /* !!! FIXME: opening a haptic device here first will make an attempt to
       !!! FIXME:  SDL_JoystickOpen() that same device fail later, since we
       !!! FIXME:  have it open in exclusive mode. But this will allow
       !!! FIXME:  SDL_JoystickOpen() followed by SDL_HapticOpenFromJoystick()
       !!! FIXME:  to work, and that's probably the common case. Still,
       !!! FIXME:  ideally, We need to unify the opening code. */

    if (!is_joystick) {  /* if is_joystick, we already set this up elsewhere. */
        /* Grab it exclusively to use force feedback stuff. */
        ret = IDirectInputDevice8_SetCooperativeLevel(haptic->hwdata->device,
                                                      SDL_HelperWindow,
                                                      DISCL_EXCLUSIVE |
                                                      DISCL_BACKGROUND);
        if (FAILED(ret)) {
            DI_SetError("Setting cooperative level to exclusive", ret);
            goto acquire_err;
        }

        /* Set data format. */
        ret = IDirectInputDevice8_SetDataFormat(haptic->hwdata->device,
                                                &SDL_c_dfDIJoystick2);
        if (FAILED(ret)) {
            DI_SetError("Setting data format", ret);
            goto acquire_err;
        }


        /* Acquire the device. */
        ret = IDirectInputDevice8_Acquire(haptic->hwdata->device);
        if (FAILED(ret)) {
            DI_SetError("Acquiring DirectInput device", ret);
            goto acquire_err;
        }
    }

    /* Get number of axes. */
    ret = IDirectInputDevice8_EnumObjects(haptic->hwdata->device,
                                          DI_DeviceObjectCallback,
                                          haptic, DIDFT_AXIS);
    if (FAILED(ret)) {
        DI_SetError("Getting device axes", ret);
        goto acquire_err;
    }

    /* Reset all actuators - just in case. */
    ret = IDirectInputDevice8_SendForceFeedbackCommand(haptic->hwdata->device,
                                                       DISFFC_RESET);
    if (FAILED(ret)) {
        DI_SetError("Resetting device", ret);
        goto acquire_err;
    }

    /* Enabling actuators. */
    ret = IDirectInputDevice8_SendForceFeedbackCommand(haptic->hwdata->device,
                                                       DISFFC_SETACTUATORSON);
    if (FAILED(ret)) {
        DI_SetError("Enabling actuators", ret);
        goto acquire_err;
    }

    /* Get supported effects. */
    ret = IDirectInputDevice8_EnumEffects(haptic->hwdata->device,
                                          DI_EffectCallback, haptic,
                                          DIEFT_ALL);
    if (FAILED(ret)) {
        DI_SetError("Enumerating supported effects", ret);
        goto acquire_err;
    }
    if (haptic->supported == 0) {       /* Error since device supports nothing. */
        SDL_SetError("Haptic: Internal error on finding supported effects.");
        goto acquire_err;
    }

    /* Check autogain and autocenter. */
    dipdw.diph.dwSize = sizeof(DIPROPDWORD);
    dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER);
    dipdw.diph.dwObj = 0;
    dipdw.diph.dwHow = DIPH_DEVICE;
    dipdw.dwData = 10000;
    ret = IDirectInputDevice8_SetProperty(haptic->hwdata->device,
                                          DIPROP_FFGAIN, &dipdw.diph);
    if (!FAILED(ret)) {         /* Gain is supported. */
        haptic->supported |= SDL_HAPTIC_GAIN;
    }
    dipdw.diph.dwObj = 0;
    dipdw.diph.dwHow = DIPH_DEVICE;
    dipdw.dwData = DIPROPAUTOCENTER_OFF;
    ret = IDirectInputDevice8_SetProperty(haptic->hwdata->device,
                                          DIPROP_AUTOCENTER, &dipdw.diph);
    if (!FAILED(ret)) {         /* Autocenter is supported. */
        haptic->supported |= SDL_HAPTIC_AUTOCENTER;
    }

    /* Status is always supported. */
    haptic->supported |= SDL_HAPTIC_STATUS | SDL_HAPTIC_PAUSE;

    /* Check maximum effects. */
    haptic->neffects = 128;     /* This is not actually supported as thus under windows,
                                   there is no way to tell the number of EFFECTS that a
                                   device can hold, so we'll just use a "random" number
                                   instead and put warnings in SDL_haptic.h */
    haptic->nplaying = 128;     /* Even more impossible to get this then neffects. */

    /* Prepare effects memory. */
    haptic->effects = (struct haptic_effect *)
        SDL_malloc(sizeof(struct haptic_effect) * haptic->neffects);
    if (haptic->effects == NULL) {
        SDL_OutOfMemory();
        goto acquire_err;
    }
    /* Clear the memory */
    SDL_memset(haptic->effects, 0,
               sizeof(struct haptic_effect) * haptic->neffects);

    return 0;

    /* Error handling */
  acquire_err:
    IDirectInputDevice8_Unacquire(haptic->hwdata->device);
    return -1;
}

int
SDL_DINPUT_HapticOpen(SDL_Haptic * haptic, SDL_hapticlist_item *item)
{
    HRESULT ret;
    LPDIRECTINPUTDEVICE8 device;
    LPDIRECTINPUTDEVICE8 device8;

    /* Open the device */
    ret = IDirectInput8_CreateDevice(dinput, &item->instance.guidInstance,
        &device, NULL);
    if (FAILED(ret)) {
        DI_SetError("Creating DirectInput device", ret);
        return -1;
    }

    /* Now get the IDirectInputDevice8 interface, instead. */
    ret = IDirectInputDevice8_QueryInterface(device,
        &IID_IDirectInputDevice8,
        (LPVOID *)&device8);
    /* Done with the temporary one now. */
    IDirectInputDevice8_Release(device);
    if (FAILED(ret)) {
        DI_SetError("Querying DirectInput interface", ret);
        return -1;
    }

    if (SDL_DINPUT_HapticOpenFromDevice(haptic, device8, SDL_FALSE) < 0) {
        IDirectInputDevice8_Release(device8);
        return -1;
    }
    return 0;
}

int
SDL_DINPUT_JoystickSameHaptic(SDL_Haptic * haptic, SDL_Joystick * joystick)
{
    HRESULT ret;
    DIDEVICEINSTANCE hap_instance, joy_instance;

    hap_instance.dwSize = sizeof(DIDEVICEINSTANCE);
    joy_instance.dwSize = sizeof(DIDEVICEINSTANCE);

    /* Get the device instances. */
    ret = IDirectInputDevice8_GetDeviceInfo(haptic->hwdata->device,
        &hap_instance);
    if (FAILED(ret)) {
        return 0;
    }
    ret = IDirectInputDevice8_GetDeviceInfo(joystick->hwdata->InputDevice,
        &joy_instance);
    if (FAILED(ret)) {
        return 0;
    }

    return WIN_IsEqualGUID(&hap_instance.guidInstance, &joy_instance.guidInstance);
}

int
SDL_DINPUT_HapticOpenFromJoystick(SDL_Haptic * haptic, SDL_Joystick * joystick)
{
    SDL_hapticlist_item *item;
    int index = 0;
    HRESULT ret;
    DIDEVICEINSTANCE joy_instance;

    joy_instance.dwSize = sizeof(DIDEVICEINSTANCE);
    ret = IDirectInputDevice8_GetDeviceInfo(joystick->hwdata->InputDevice, &joy_instance);
    if (FAILED(ret)) {
        return -1;
    }

    /* Since it comes from a joystick we have to try to match it with a haptic device on our haptic list. */
    for (item = SDL_hapticlist; item != NULL; item = item->next) {
        if (!item->bXInputHaptic && WIN_IsEqualGUID(&item->instance.guidInstance, &joy_instance.guidInstance)) {
            haptic->index = index;
            return SDL_DINPUT_HapticOpenFromDevice(haptic, joystick->hwdata->InputDevice, SDL_TRUE);
        }
        ++index;
    }

    SDL_SetError("Couldn't find joystick in haptic device list");
    return -1;
}

void
SDL_DINPUT_HapticClose(SDL_Haptic * haptic)
{
    IDirectInputDevice8_Unacquire(haptic->hwdata->device);

    /* Only release if isn't grabbed by a joystick. */
    if (haptic->hwdata->is_joystick == 0) {
        IDirectInputDevice8_Release(haptic->hwdata->device);
    }
}

void
SDL_DINPUT_HapticQuit(void)
{
    if (dinput != NULL) {
        IDirectInput8_Release(dinput);
        dinput = NULL;
    }

    if (coinitialized) {
        WIN_CoUninitialize();
        coinitialized = SDL_FALSE;
    }
}

/*
 * Converts an SDL trigger button to an DIEFFECT trigger button.
 */
static DWORD
DIGetTriggerButton(Uint16 button)
{
    DWORD dwTriggerButton;

    dwTriggerButton = DIEB_NOTRIGGER;

    if (button != 0) {
        dwTriggerButton = DIJOFS_BUTTON(button - 1);
    }

    return dwTriggerButton;
}


/*
 * Sets the direction.
 */
static int
SDL_SYS_SetDirection(DIEFFECT * effect, SDL_HapticDirection * dir, int naxes)
{
    LONG *rglDir;

    /* Handle no axes a part. */
    if (naxes == 0) {
        effect->dwFlags |= DIEFF_SPHERICAL;     /* Set as default. */
        effect->rglDirection = NULL;
        return 0;
    }

    /* Has axes. */
    rglDir = SDL_malloc(sizeof(LONG) * naxes);
    if (rglDir == NULL) {
        return SDL_OutOfMemory();
    }
    SDL_memset(rglDir, 0, sizeof(LONG) * naxes);
    effect->rglDirection = rglDir;

    switch (dir->type) {
    case SDL_HAPTIC_POLAR:
        effect->dwFlags |= DIEFF_POLAR;
        rglDir[0] = dir->dir[0];
        return 0;
    case SDL_HAPTIC_CARTESIAN:
        effect->dwFlags |= DIEFF_CARTESIAN;
        rglDir[0] = dir->dir[0];
        if (naxes > 1)
            rglDir[1] = dir->dir[1];
        if (naxes > 2)
            rglDir[2] = dir->dir[2];
        return 0;
    case SDL_HAPTIC_SPHERICAL:
        effect->dwFlags |= DIEFF_SPHERICAL;
        rglDir[0] = dir->dir[0];
        if (naxes > 1)
            rglDir[1] = dir->dir[1];
        if (naxes > 2)
            rglDir[2] = dir->dir[2];
        return 0;
    case SDL_HAPTIC_STEERING_AXIS:
        effect->dwFlags |= DIEFF_CARTESIAN;
        rglDir[0] = 0;
        return 0;

    default:
        return SDL_SetError("Haptic: Unknown direction type.");
    }
}

/* Clamps and converts. */
#define CCONVERT(x)   (((x) > 0x7FFF) ? 10000 : ((x)*10000) / 0x7FFF)
/* Just converts. */
#define CONVERT(x)    (((x)*10000) / 0x7FFF)
/*
 * Creates the DIEFFECT from a SDL_HapticEffect.
 */
static int
SDL_SYS_ToDIEFFECT(SDL_Haptic * haptic, DIEFFECT * dest,
                   SDL_HapticEffect * src)
{
    int i;
    DICONSTANTFORCE *constant;
    DIPERIODIC *periodic;
    DICONDITION *condition;     /* Actually an array of conditions - one per axis. */
    DIRAMPFORCE *ramp;
    DICUSTOMFORCE *custom;
    DIENVELOPE *envelope;
    SDL_HapticConstant *hap_constant;
    SDL_HapticPeriodic *hap_periodic;
    SDL_HapticCondition *hap_condition;
    SDL_HapticRamp *hap_ramp;
    SDL_HapticCustom *hap_custom;
    DWORD *axes;

    /* Set global stuff. */
    SDL_memset(dest, 0, sizeof(DIEFFECT));
    dest->dwSize = sizeof(DIEFFECT);    /* Set the structure size. */
    dest->dwSamplePeriod = 0;   /* Not used by us. */
    dest->dwGain = 10000;       /* Gain is set globally, not locally. */
    dest->dwFlags = DIEFF_OBJECTOFFSETS;        /* Seems obligatory. */

    /* Envelope. */
    envelope = SDL_malloc(sizeof(DIENVELOPE));
    if (envelope == NULL) {
        return SDL_OutOfMemory();
    }
    SDL_memset(envelope, 0, sizeof(DIENVELOPE));
    dest->lpEnvelope = envelope;
    envelope->dwSize = sizeof(DIENVELOPE);      /* Always should be this. */

    /* Axes. */
    if (src->constant.direction.type == SDL_HAPTIC_STEERING_AXIS) {
        dest->cAxes = 1;
    } else {
        dest->cAxes = haptic->naxes;
    }
    if (dest->cAxes > 0) {
        axes = SDL_malloc(sizeof(DWORD) * dest->cAxes);
        if (axes == NULL) {
            return SDL_OutOfMemory();
        }
        axes[0] = haptic->hwdata->axes[0];      /* Always at least one axis. */
        if (dest->cAxes > 1) {
            axes[1] = haptic->hwdata->axes[1];
        }
        if (dest->cAxes > 2) {
            axes[2] = haptic->hwdata->axes[2];
        }
        dest->rgdwAxes = axes;
    }

    /* The big type handling switch, even bigger than Linux's version. */
    switch (src->type) {
    case SDL_HAPTIC_CONSTANT:
        hap_constant = &src->constant;
        constant = SDL_malloc(sizeof(DICONSTANTFORCE));
        if (constant == NULL) {
            return SDL_OutOfMemory();
        }
        SDL_memset(constant, 0, sizeof(DICONSTANTFORCE));

        /* Specifics */
        constant->lMagnitude = CONVERT(hap_constant->level);
        dest->cbTypeSpecificParams = sizeof(DICONSTANTFORCE);
        dest->lpvTypeSpecificParams = constant;

        /* Generics */
        dest->dwDuration = hap_constant->length * 1000; /* In microseconds. */
        dest->dwTriggerButton = DIGetTriggerButton(hap_constant->button);
        dest->dwTriggerRepeatInterval = hap_constant->interval;
        dest->dwStartDelay = hap_constant->delay * 1000;        /* In microseconds. */

        /* Direction. */
        if (SDL_SYS_SetDirection(dest, &hap_constant->direction, dest->cAxes) < 0) {
            return -1;
        }

        /* Envelope */
        if ((hap_constant->attack_length == 0)
            && (hap_constant->fade_length == 0)) {
            SDL_free(dest->lpEnvelope);
            dest->lpEnvelope = NULL;
        } else {
            envelope->dwAttackLevel = CCONVERT(hap_constant->attack_level);
            envelope->dwAttackTime = hap_constant->attack_length * 1000;
            envelope->dwFadeLevel = CCONVERT(hap_constant->fade_level);
            envelope->dwFadeTime = hap_constant->fade_length * 1000;
        }

        break;

    case SDL_HAPTIC_SINE:
    /* !!! FIXME: put this back when we have more bits in 2.1 */
    /* case SDL_HAPTIC_SQUARE: */
    case SDL_HAPTIC_TRIANGLE:
    case SDL_HAPTIC_SAWTOOTHUP:
    case SDL_HAPTIC_SAWTOOTHDOWN:
        hap_periodic = &src->periodic;
        periodic = SDL_malloc(sizeof(DIPERIODIC));
        if (periodic == NULL) {
            return SDL_OutOfMemory();
        }
        SDL_memset(periodic, 0, sizeof(DIPERIODIC));

        /* Specifics */
        periodic->dwMagnitude = CONVERT(SDL_abs(hap_periodic->magnitude));
        periodic->lOffset = CONVERT(hap_periodic->offset);
        periodic->dwPhase = 
                (hap_periodic->phase + (hap_periodic->magnitude < 0 ? 18000 : 0)) % 36000;
        periodic->dwPeriod = hap_periodic->period * 1000;
        dest->cbTypeSpecificParams = sizeof(DIPERIODIC);
        dest->lpvTypeSpecificParams = periodic;

        /* Generics */
        dest->dwDuration = hap_periodic->length * 1000; /* In microseconds. */
        dest->dwTriggerButton = DIGetTriggerButton(hap_periodic->button);
        dest->dwTriggerRepeatInterval = hap_periodic->interval;
        dest->dwStartDelay = hap_periodic->delay * 1000;        /* In microseconds. */

        /* Direction. */
        if (SDL_SYS_SetDirection(dest, &hap_periodic->direction, dest->cAxes)
            < 0) {
            return -1;
        }

        /* Envelope */
        if ((hap_periodic->attack_length == 0)
            && (hap_periodic->fade_length == 0)) {
            SDL_free(dest->lpEnvelope);
            dest->lpEnvelope = NULL;
        } else {
            envelope->dwAttackLevel = CCONVERT(hap_periodic->attack_level);
            envelope->dwAttackTime = hap_periodic->attack_length * 1000;
            envelope->dwFadeLevel = CCONVERT(hap_periodic->fade_level);
            envelope->dwFadeTime = hap_periodic->fade_length * 1000;
        }

        break;

    case SDL_HAPTIC_SPRING:
    case SDL_HAPTIC_DAMPER:
    case SDL_HAPTIC_INERTIA:
    case SDL_HAPTIC_FRICTION:
        hap_condition = &src->condition;
        condition = SDL_malloc(sizeof(DICONDITION) * dest->cAxes);
        if (condition == NULL) {
            return SDL_OutOfMemory();
        }
        SDL_memset(condition, 0, sizeof(DICONDITION));

        /* Specifics */
        for (i = 0; i < (int) dest->cAxes; i++) {
            condition[i].lOffset = CONVERT(hap_condition->center[i]);
            condition[i].lPositiveCoefficient =
                CONVERT(hap_condition->right_coeff[i]);
            condition[i].lNegativeCoefficient =
                CONVERT(hap_condition->left_coeff[i]);
            condition[i].dwPositiveSaturation =
                CCONVERT(hap_condition->right_sat[i] / 2);
            condition[i].dwNegativeSaturation =
                CCONVERT(hap_condition->left_sat[i] / 2);
            condition[i].lDeadBand = CCONVERT(hap_condition->deadband[i] / 2);
        }
        dest->cbTypeSpecificParams = sizeof(DICONDITION) * dest->cAxes;
        dest->lpvTypeSpecificParams = condition;

        /* Generics */
        dest->dwDuration = hap_condition->length * 1000;        /* In microseconds. */
        dest->dwTriggerButton = DIGetTriggerButton(hap_condition->button);
        dest->dwTriggerRepeatInterval = hap_condition->interval;
        dest->dwStartDelay = hap_condition->delay * 1000;       /* In microseconds. */

        /* Direction. */
        if (SDL_SYS_SetDirection(dest, &hap_condition->direction, dest->cAxes)
            < 0) {
            return -1;
        }

        /* Envelope - Not actually supported by most CONDITION implementations. */
        SDL_free(dest->lpEnvelope);
        dest->lpEnvelope = NULL;

        break;

    case SDL_HAPTIC_RAMP:
        hap_ramp = &src->ramp;
        ramp = SDL_malloc(sizeof(DIRAMPFORCE));
        if (ramp == NULL) {
            return SDL_OutOfMemory();
        }
        SDL_memset(ramp, 0, sizeof(DIRAMPFORCE));

        /* Specifics */
        ramp->lStart = CONVERT(hap_ramp->start);
        ramp->lEnd = CONVERT(hap_ramp->end);
        dest->cbTypeSpecificParams = sizeof(DIRAMPFORCE);
        dest->lpvTypeSpecificParams = ramp;

        /* Generics */
        dest->dwDuration = hap_ramp->length * 1000;     /* In microseconds. */
        dest->dwTriggerButton = DIGetTriggerButton(hap_ramp->button);
        dest->dwTriggerRepeatInterval = hap_ramp->interval;
        dest->dwStartDelay = hap_ramp->delay * 1000;    /* In microseconds. */

        /* Direction. */
        if (SDL_SYS_SetDirection(dest, &hap_ramp->direction, dest->cAxes) < 0) {
            return -1;
        }

        /* Envelope */
        if ((hap_ramp->attack_length == 0) && (hap_ramp->fade_length == 0)) {
            SDL_free(dest->lpEnvelope);
            dest->lpEnvelope = NULL;
        } else {
            envelope->dwAttackLevel = CCONVERT(hap_ramp->attack_level);
            envelope->dwAttackTime = hap_ramp->attack_length * 1000;
            envelope->dwFadeLevel = CCONVERT(hap_ramp->fade_level);
            envelope->dwFadeTime = hap_ramp->fade_length * 1000;
        }

        break;

    case SDL_HAPTIC_CUSTOM:
        hap_custom = &src->custom;
        custom = SDL_malloc(sizeof(DICUSTOMFORCE));
        if (custom == NULL) {
            return SDL_OutOfMemory();
        }
        SDL_memset(custom, 0, sizeof(DICUSTOMFORCE));

        /* Specifics */
        custom->cChannels = hap_custom->channels;
        custom->dwSamplePeriod = hap_custom->period * 1000;
        custom->cSamples = hap_custom->samples;
        custom->rglForceData =
            SDL_malloc(sizeof(LONG) * custom->cSamples * custom->cChannels);
        for (i = 0; i < hap_custom->samples * hap_custom->channels; i++) {      /* Copy data. */
            custom->rglForceData[i] = CCONVERT(hap_custom->data[i]);
        }
        dest->cbTypeSpecificParams = sizeof(DICUSTOMFORCE);
        dest->lpvTypeSpecificParams = custom;

        /* Generics */
        dest->dwDuration = hap_custom->length * 1000;   /* In microseconds. */
        dest->dwTriggerButton = DIGetTriggerButton(hap_custom->button);
        dest->dwTriggerRepeatInterval = hap_custom->interval;
        dest->dwStartDelay = hap_custom->delay * 1000;  /* In microseconds. */

        /* Direction. */
        if (SDL_SYS_SetDirection(dest, &hap_custom->direction, dest->cAxes) < 0) {
            return -1;
        }

        /* Envelope */
        if ((hap_custom->attack_length == 0)
            && (hap_custom->fade_length == 0)) {
            SDL_free(dest->lpEnvelope);
            dest->lpEnvelope = NULL;
        } else {
            envelope->dwAttackLevel = CCONVERT(hap_custom->attack_level);
            envelope->dwAttackTime = hap_custom->attack_length * 1000;
            envelope->dwFadeLevel = CCONVERT(hap_custom->fade_level);
            envelope->dwFadeTime = hap_custom->fade_length * 1000;
        }

        break;

    default:
        return SDL_SetError("Haptic: Unknown effect type.");
    }

    return 0;
}


/*
 * Frees an DIEFFECT allocated by SDL_SYS_ToDIEFFECT.
 */
static void
SDL_SYS_HapticFreeDIEFFECT(DIEFFECT * effect, int type)
{
    DICUSTOMFORCE *custom;

    SDL_free(effect->lpEnvelope);
    effect->lpEnvelope = NULL;
    SDL_free(effect->rgdwAxes);
    effect->rgdwAxes = NULL;
    if (effect->lpvTypeSpecificParams != NULL) {
        if (type == SDL_HAPTIC_CUSTOM) {        /* Must free the custom data. */
            custom = (DICUSTOMFORCE *) effect->lpvTypeSpecificParams;
            SDL_free(custom->rglForceData);
            custom->rglForceData = NULL;
        }
        SDL_free(effect->lpvTypeSpecificParams);
        effect->lpvTypeSpecificParams = NULL;
    }
    SDL_free(effect->rglDirection);
    effect->rglDirection = NULL;
}

/*
 * Gets the effect type from the generic SDL haptic effect wrapper.
 */
static REFGUID
SDL_SYS_HapticEffectType(SDL_HapticEffect * effect)
{
    switch (effect->type) {
    case SDL_HAPTIC_CONSTANT:
        return &GUID_ConstantForce;

    case SDL_HAPTIC_RAMP:
        return &GUID_RampForce;

    /* !!! FIXME: put this back when we have more bits in 2.1 */
    /* case SDL_HAPTIC_SQUARE:
        return &GUID_Square; */

    case SDL_HAPTIC_SINE:
        return &GUID_Sine;

    case SDL_HAPTIC_TRIANGLE:
        return &GUID_Triangle;

    case SDL_HAPTIC_SAWTOOTHUP:
        return &GUID_SawtoothUp;

    case SDL_HAPTIC_SAWTOOTHDOWN:
        return &GUID_SawtoothDown;

    case SDL_HAPTIC_SPRING:
        return &GUID_Spring;

    case SDL_HAPTIC_DAMPER:
        return &GUID_Damper;

    case SDL_HAPTIC_INERTIA:
        return &GUID_Inertia;

    case SDL_HAPTIC_FRICTION:
        return &GUID_Friction;

    case SDL_HAPTIC_CUSTOM:
        return &GUID_CustomForce;

    default:
        return NULL;
    }
}
int
SDL_DINPUT_HapticNewEffect(SDL_Haptic * haptic, struct haptic_effect *effect, SDL_HapticEffect * base)
{
    HRESULT ret;
    REFGUID type = SDL_SYS_HapticEffectType(base);

    if (type == NULL) {
        SDL_SetError("Haptic: Unknown effect type.");
        return -1;
    }

    /* Get the effect. */
    if (SDL_SYS_ToDIEFFECT(haptic, &effect->hweffect->effect, base) < 0) {
        goto err_effectdone;
    }

    /* Create the actual effect. */
    ret = IDirectInputDevice8_CreateEffect(haptic->hwdata->device, type,
        &effect->hweffect->effect,
        &effect->hweffect->ref, NULL);
    if (FAILED(ret)) {
        DI_SetError("Unable to create effect", ret);
        goto err_effectdone;
    }

    return 0;

err_effectdone:
    SDL_SYS_HapticFreeDIEFFECT(&effect->hweffect->effect, base->type);
    return -1;
}

int
SDL_DINPUT_HapticUpdateEffect(SDL_Haptic * haptic, struct haptic_effect *effect, SDL_HapticEffect * data)
{
    HRESULT ret;
    DWORD flags;
    DIEFFECT temp;

    /* Get the effect. */
    SDL_memset(&temp, 0, sizeof(DIEFFECT));
    if (SDL_SYS_ToDIEFFECT(haptic, &temp, data) < 0) {
        goto err_update;
    }

    /* Set the flags.  Might be worthwhile to diff temp with loaded effect and
    *  only change those parameters. */
    flags = DIEP_DIRECTION |
        DIEP_DURATION |
        DIEP_ENVELOPE |
        DIEP_STARTDELAY |
        DIEP_TRIGGERBUTTON |
        DIEP_TRIGGERREPEATINTERVAL | DIEP_TYPESPECIFICPARAMS;

    /* Create the actual effect. */
    ret =
        IDirectInputEffect_SetParameters(effect->hweffect->ref, &temp, flags);
    if (ret == DIERR_NOTEXCLUSIVEACQUIRED) {
        IDirectInputDevice8_Unacquire(haptic->hwdata->device);
        ret = IDirectInputDevice8_SetCooperativeLevel(haptic->hwdata->device, SDL_HelperWindow, DISCL_EXCLUSIVE | DISCL_BACKGROUND);
        if (SUCCEEDED(ret)) {
            ret = DIERR_NOTACQUIRED;
        }
    }
    if (ret == DIERR_INPUTLOST || ret == DIERR_NOTACQUIRED) {
        ret = IDirectInputDevice8_Acquire(haptic->hwdata->device);
        if (SUCCEEDED(ret)) {
            ret = IDirectInputEffect_SetParameters(effect->hweffect->ref, &temp, flags);
        }
    }
    if (FAILED(ret)) {
        DI_SetError("Unable to update effect", ret);
        goto err_update;
    }

    /* Copy it over. */
    SDL_SYS_HapticFreeDIEFFECT(&effect->hweffect->effect, data->type);
    SDL_memcpy(&effect->hweffect->effect, &temp, sizeof(DIEFFECT));

    return 0;

err_update:
    SDL_SYS_HapticFreeDIEFFECT(&temp, data->type);
    return -1;
}

int
SDL_DINPUT_HapticRunEffect(SDL_Haptic * haptic, struct haptic_effect *effect, Uint32 iterations)
{
    HRESULT ret;
    DWORD iter;

    /* Check if it's infinite. */
    if (iterations == SDL_HAPTIC_INFINITY) {
        iter = INFINITE;
    } else {
        iter = iterations;
    }

    /* Run the effect. */
    ret = IDirectInputEffect_Start(effect->hweffect->ref, iter, 0);
    if (FAILED(ret)) {
        return DI_SetError("Running the effect", ret);
    }
    return 0;
}

int
SDL_DINPUT_HapticStopEffect(SDL_Haptic * haptic, struct haptic_effect *effect)
{
    HRESULT ret;

    ret = IDirectInputEffect_Stop(effect->hweffect->ref);
    if (FAILED(ret)) {
        return DI_SetError("Unable to stop effect", ret);
    }
    return 0;
}

void
SDL_DINPUT_HapticDestroyEffect(SDL_Haptic * haptic, struct haptic_effect *effect)
{
    HRESULT ret;

    ret = IDirectInputEffect_Unload(effect->hweffect->ref);
    if (FAILED(ret)) {
        DI_SetError("Removing effect from the device", ret);
    }
    SDL_SYS_HapticFreeDIEFFECT(&effect->hweffect->effect, effect->effect.type);
}

int
SDL_DINPUT_HapticGetEffectStatus(SDL_Haptic * haptic, struct haptic_effect *effect)
{
    HRESULT ret;
    DWORD status;

    ret = IDirectInputEffect_GetEffectStatus(effect->hweffect->ref, &status);
    if (FAILED(ret)) {
        return DI_SetError("Getting effect status", ret);
    }

    if (status == 0)
        return SDL_FALSE;
    return SDL_TRUE;
}

int
SDL_DINPUT_HapticSetGain(SDL_Haptic * haptic, int gain)
{
    HRESULT ret;
    DIPROPDWORD dipdw;

    /* Create the weird structure thingy. */
    dipdw.diph.dwSize = sizeof(DIPROPDWORD);
    dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER);
    dipdw.diph.dwObj = 0;
    dipdw.diph.dwHow = DIPH_DEVICE;
    dipdw.dwData = gain * 100;  /* 0 to 10,000 */

    /* Try to set the autocenter. */
    ret = IDirectInputDevice8_SetProperty(haptic->hwdata->device,
        DIPROP_FFGAIN, &dipdw.diph);
    if (FAILED(ret)) {
        return DI_SetError("Setting gain", ret);
    }
    return 0;
}

int
SDL_DINPUT_HapticSetAutocenter(SDL_Haptic * haptic, int autocenter)
{
    HRESULT ret;
    DIPROPDWORD dipdw;

    /* Create the weird structure thingy. */
    dipdw.diph.dwSize = sizeof(DIPROPDWORD);
    dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER);
    dipdw.diph.dwObj = 0;
    dipdw.diph.dwHow = DIPH_DEVICE;
    dipdw.dwData = (autocenter == 0) ? DIPROPAUTOCENTER_OFF :
        DIPROPAUTOCENTER_ON;

    /* Try to set the autocenter. */
    ret = IDirectInputDevice8_SetProperty(haptic->hwdata->device,
        DIPROP_AUTOCENTER, &dipdw.diph);
    if (FAILED(ret)) {
        return DI_SetError("Setting autocenter", ret);
    }
    return 0;
}

int
SDL_DINPUT_HapticPause(SDL_Haptic * haptic)
{
    HRESULT ret;

    /* Pause the device. */
    ret = IDirectInputDevice8_SendForceFeedbackCommand(haptic->hwdata->device,
        DISFFC_PAUSE);
    if (FAILED(ret)) {
        return DI_SetError("Pausing the device", ret);
    }
    return 0;
}

int
SDL_DINPUT_HapticUnpause(SDL_Haptic * haptic)
{
    HRESULT ret;

    /* Unpause the device. */
    ret = IDirectInputDevice8_SendForceFeedbackCommand(haptic->hwdata->device,
        DISFFC_CONTINUE);
    if (FAILED(ret)) {
        return DI_SetError("Pausing the device", ret);
    }
    return 0;
}

int
SDL_DINPUT_HapticStopAll(SDL_Haptic * haptic)
{
    HRESULT ret;

    /* Try to stop the effects. */
    ret = IDirectInputDevice8_SendForceFeedbackCommand(haptic->hwdata->device,
        DISFFC_STOPALL);
    if (FAILED(ret)) {
        return DI_SetError("Stopping the device", ret);
    }
    return 0;
}

#else /* !SDL_HAPTIC_DINPUT */

typedef struct DIDEVICEINSTANCE DIDEVICEINSTANCE;
typedef struct SDL_hapticlist_item SDL_hapticlist_item;

int
SDL_DINPUT_HapticInit(void)
{
    return 0;
}

int
SDL_DINPUT_MaybeAddDevice(const DIDEVICEINSTANCE * pdidInstance)
{
    return SDL_Unsupported();
}

int
SDL_DINPUT_MaybeRemoveDevice(const DIDEVICEINSTANCE * pdidInstance)
{
    return SDL_Unsupported();
}

int
SDL_DINPUT_HapticOpen(SDL_Haptic * haptic, SDL_hapticlist_item *item)
{
    return SDL_Unsupported();
}

int
SDL_DINPUT_JoystickSameHaptic(SDL_Haptic * haptic, SDL_Joystick * joystick)
{
    return SDL_Unsupported();
}

int
SDL_DINPUT_HapticOpenFromJoystick(SDL_Haptic * haptic, SDL_Joystick * joystick)
{
    return SDL_Unsupported();
}

void
SDL_DINPUT_HapticClose(SDL_Haptic * haptic)
{
}

void
SDL_DINPUT_HapticQuit(void)
{
}

int
SDL_DINPUT_HapticNewEffect(SDL_Haptic * haptic, struct haptic_effect *effect, SDL_HapticEffect * base)
{
    return SDL_Unsupported();
}

int
SDL_DINPUT_HapticUpdateEffect(SDL_Haptic * haptic, struct haptic_effect *effect, SDL_HapticEffect * data)
{
    return SDL_Unsupported();
}

int
SDL_DINPUT_HapticRunEffect(SDL_Haptic * haptic, struct haptic_effect *effect, Uint32 iterations)
{
    return SDL_Unsupported();
}

int
SDL_DINPUT_HapticStopEffect(SDL_Haptic * haptic, struct haptic_effect *effect)
{
    return SDL_Unsupported();
}

void
SDL_DINPUT_HapticDestroyEffect(SDL_Haptic * haptic, struct haptic_effect *effect)
{
}

int
SDL_DINPUT_HapticGetEffectStatus(SDL_Haptic * haptic, struct haptic_effect *effect)
{
    return SDL_Unsupported();
}

int
SDL_DINPUT_HapticSetGain(SDL_Haptic * haptic, int gain)
{
    return SDL_Unsupported();
}

int
SDL_DINPUT_HapticSetAutocenter(SDL_Haptic * haptic, int autocenter)
{
    return SDL_Unsupported();
}

int
SDL_DINPUT_HapticPause(SDL_Haptic * haptic)
{
    return SDL_Unsupported();
}

int
SDL_DINPUT_HapticUnpause(SDL_Haptic * haptic)
{
    return SDL_Unsupported();
}

int
SDL_DINPUT_HapticStopAll(SDL_Haptic * haptic)
{
    return SDL_Unsupported();
}

#endif /* SDL_HAPTIC_DINPUT */

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