/*
  Simple DirectMedia Layer
  Copyright (C) 1997-2013 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_config.h"

#ifdef SDL_HAPTIC_IOKIT

#include "SDL_haptic.h"
#include "../SDL_syshaptic.h"
#include "SDL_joystick.h"
#include "../../joystick/SDL_sysjoystick.h"     /* For the real SDL_Joystick */
#include "../../joystick/darwin/SDL_sysjoystick_c.h"    /* For joystick hwdata */

#include <IOKit/IOKitLib.h>
#include <IOKit/hid/IOHIDKeys.h>
#include <IOKit/hid/IOHIDUsageTables.h>
#include <ForceFeedback/ForceFeedback.h>
#include <ForceFeedback/ForceFeedbackConstants.h>

#ifndef IO_OBJECT_NULL
#define IO_OBJECT_NULL  ((io_service_t)0)
#endif

#define MAX_HAPTICS  32


/*
 * List of available haptic devices.
 */
static struct
{
    char name[256];             /* Name of the device. */

    io_service_t dev;           /* Node we use to create the device. */
    SDL_Haptic *haptic;         /* Haptic currently associated with it. */

    /* Usage pages for determining if it's a mouse or not. */
    long usage;
    long usagePage;
} SDL_hapticlist[MAX_HAPTICS];


/*
 * Haptic system hardware data.
 */
struct haptic_hwdata
{
    FFDeviceObjectReference device;     /* Hardware device. */
    UInt8 axes[3];
};


/*
 * Haptic system effect data.
 */
struct haptic_hweffect
{
    FFEffectObjectReference ref;        /* Reference. */
    struct FFEFFECT effect;     /* Hardware effect. */
};

/*
 * Prototypes.
 */
static void SDL_SYS_HapticFreeFFEFFECT(FFEFFECT * effect, int type);
static int HIDGetDeviceProduct(io_service_t dev, char *name);


/*
 * Like strerror but for force feedback errors.
 */
static const char *
FFStrError(HRESULT err)
{
    switch (err) {
    case FFERR_DEVICEFULL:
        return "device full";
        /* This should be valid, but for some reason isn't defined... */
        /* case FFERR_DEVICENOTREG:
           return "device not registered"; */
    case FFERR_DEVICEPAUSED:
        return "device paused";
    case FFERR_DEVICERELEASED:
        return "device released";
    case FFERR_EFFECTPLAYING:
        return "effect playing";
    case FFERR_EFFECTTYPEMISMATCH:
        return "effect type mismatch";
    case FFERR_EFFECTTYPENOTSUPPORTED:
        return "effect type not supported";
    case FFERR_GENERIC:
        return "undetermined error";
    case FFERR_HASEFFECTS:
        return "device has effects";
    case FFERR_INCOMPLETEEFFECT:
        return "incomplete effect";
    case FFERR_INTERNAL:
        return "internal fault";
    case FFERR_INVALIDDOWNLOADID:
        return "invalid download id";
    case FFERR_INVALIDPARAM:
        return "invalid parameter";
    case FFERR_MOREDATA:
        return "more data";
    case FFERR_NOINTERFACE:
        return "interface not supported";
    case FFERR_NOTDOWNLOADED:
        return "effect is not downloaded";
    case FFERR_NOTINITIALIZED:
        return "object has not been initialized";
    case FFERR_OUTOFMEMORY:
        return "out of memory";
    case FFERR_UNPLUGGED:
        return "device is unplugged";
    case FFERR_UNSUPPORTED:
        return "function call unsupported";
    case FFERR_UNSUPPORTEDAXIS:
        return "axis unsupported";

    default:
        return "unknown error";
    }
}


/*
 * Initializes the haptic subsystem.
 */
int
SDL_SYS_HapticInit(void)
{
    int numhaptics;
    IOReturn result;
    io_iterator_t iter;
    CFDictionaryRef match;
    io_service_t device;
    CFMutableDictionaryRef hidProperties;
    CFTypeRef refCF;

    /* Clear all the memory. */
    SDL_memset(SDL_hapticlist, 0, sizeof(SDL_hapticlist));

    /* Get HID devices. */
    match = IOServiceMatching(kIOHIDDeviceKey);
    if (match == NULL) {
        return SDL_SetError("Haptic: Failed to get IOServiceMatching.");
    }

    /* Now search I/O Registry for matching devices. */
    result = IOServiceGetMatchingServices(kIOMasterPortDefault, match, &iter);
    if (result != kIOReturnSuccess) {
        return SDL_SetError("Haptic: Couldn't create a HID object iterator.");
    }
    /* IOServiceGetMatchingServices consumes dictionary. */

    if (!IOIteratorIsValid(iter)) {     /* No iterator. */
        return 0;
    }

    numhaptics = 0;
    while ((device = IOIteratorNext(iter)) != IO_OBJECT_NULL) {

        /* Check for force feedback. */
        if (FFIsForceFeedback(device) == FF_OK) {

            /* Set basic device data. */
            HIDGetDeviceProduct(device, SDL_hapticlist[numhaptics].name);
            SDL_hapticlist[numhaptics].dev = device;
            SDL_hapticlist[numhaptics].haptic = NULL;

            /* Set usage pages. */
            hidProperties = 0;
            refCF = 0;
            result = IORegistryEntryCreateCFProperties(device,
                                                       &hidProperties,
                                                       kCFAllocatorDefault,
                                                       kNilOptions);
            if ((result == KERN_SUCCESS) && hidProperties) {
                refCF =
                    CFDictionaryGetValue(hidProperties,
                                         CFSTR(kIOHIDPrimaryUsagePageKey));
                if (refCF) {
                    if (!CFNumberGetValue(refCF, kCFNumberLongType,
                                          &SDL_hapticlist[numhaptics].
                                          usagePage))
                        SDL_SetError
                            ("Haptic: Recieving device's usage page.");
                    refCF =
                        CFDictionaryGetValue(hidProperties,
                                             CFSTR(kIOHIDPrimaryUsageKey));
                    if (refCF) {
                        if (!CFNumberGetValue(refCF, kCFNumberLongType,
                                              &SDL_hapticlist[numhaptics].
                                              usage))
                            SDL_SetError("Haptic: Recieving device's usage.");
                    }
                }
                CFRelease(hidProperties);
            }

            /* Device has been added. */
            numhaptics++;
        } else {                /* Free the unused device. */
            IOObjectRelease(device);
        }

        /* Reached haptic limit. */
        if (numhaptics >= MAX_HAPTICS)
            break;
    }
    IOObjectRelease(iter);

    return numhaptics;
}


/*
 * Return the name of a haptic device, does not need to be opened.
 */
const char *
SDL_SYS_HapticName(int index)
{
    return SDL_hapticlist[index].name;
}

/*
 * Gets the device's product name.
 */
static int
HIDGetDeviceProduct(io_service_t dev, char *name)
{
    CFMutableDictionaryRef hidProperties, usbProperties;
    io_registry_entry_t parent1, parent2;
    kern_return_t ret;

    hidProperties = usbProperties = 0;

    ret = IORegistryEntryCreateCFProperties(dev, &hidProperties,
                                            kCFAllocatorDefault, kNilOptions);
    if ((ret != KERN_SUCCESS) || !hidProperties) {
        return SDL_SetError("Haptic: Unable to create CFProperties.");
    }

    /* Mac OS X currently is not mirroring all USB properties to HID page so need to look at USB device page also
     * get dictionary for USB properties: step up two levels and get CF dictionary for USB properties
     */
    if ((KERN_SUCCESS ==
         IORegistryEntryGetParentEntry(dev, kIOServicePlane, &parent1))
        && (KERN_SUCCESS ==
            IORegistryEntryGetParentEntry(parent1, kIOServicePlane, &parent2))
        && (KERN_SUCCESS ==
            IORegistryEntryCreateCFProperties(parent2, &usbProperties,
                                              kCFAllocatorDefault,
                                              kNilOptions))) {
        if (usbProperties) {
            CFTypeRef refCF = 0;
            /* get device info
             * try hid dictionary first, if fail then go to USB dictionary
             */


            /* Get product name */
            refCF =
                CFDictionaryGetValue(hidProperties, CFSTR(kIOHIDProductKey));
            if (!refCF)
                refCF =
                    CFDictionaryGetValue(usbProperties,
                                         CFSTR("USB Product Name"));
            if (refCF) {
                if (!CFStringGetCString(refCF, name, 256,
                                        CFStringGetSystemEncoding())) {
                    return SDL_SetError
                        ("Haptic: CFStringGetCString error retrieving pDevice->product.");
                }
            }

            CFRelease(usbProperties);
        } else {
            return SDL_SetError
                ("Haptic: IORegistryEntryCreateCFProperties failed to create usbProperties.");
        }

        /* Release stuff. */
        if (kIOReturnSuccess != IOObjectRelease(parent2)) {
            SDL_SetError("Haptic: IOObjectRelease error with parent2.");
        }
        if (kIOReturnSuccess != IOObjectRelease(parent1)) {
            SDL_SetError("Haptic: IOObjectRelease error with parent1.");
        }
    } else {
        return SDL_SetError("Haptic: Error getting registry entries.");
    }

    return 0;
}


#define FF_TEST(ff, s) \
if (features.supportedEffects & (ff)) supported |= (s)
/*
 * Gets supported features.
 */
static unsigned int
GetSupportedFeatures(SDL_Haptic * haptic)
{
    HRESULT ret;
    FFDeviceObjectReference device;
    FFCAPABILITIES features;
    unsigned int supported;
    Uint32 val;

    device = haptic->hwdata->device;

    ret = FFDeviceGetForceFeedbackCapabilities(device, &features);
    if (ret != FF_OK) {
        return SDL_SetError("Haptic: Unable to get device's supported features.");
    }

    supported = 0;

    /* Get maximum effects. */
    haptic->neffects = features.storageCapacity;
    haptic->nplaying = features.playbackCapacity;

    /* Test for effects. */
    FF_TEST(FFCAP_ET_CONSTANTFORCE, SDL_HAPTIC_CONSTANT);
    FF_TEST(FFCAP_ET_RAMPFORCE, SDL_HAPTIC_RAMP);
    /* !!! FIXME: put this back when we have more bits in 2.1 */
    /* FF_TEST(FFCAP_ET_SQUARE, SDL_HAPTIC_SQUARE); */
    FF_TEST(FFCAP_ET_SINE, SDL_HAPTIC_SINE);
    FF_TEST(FFCAP_ET_TRIANGLE, SDL_HAPTIC_TRIANGLE);
    FF_TEST(FFCAP_ET_SAWTOOTHUP, SDL_HAPTIC_SAWTOOTHUP);
    FF_TEST(FFCAP_ET_SAWTOOTHDOWN, SDL_HAPTIC_SAWTOOTHDOWN);
    FF_TEST(FFCAP_ET_SPRING, SDL_HAPTIC_SPRING);
    FF_TEST(FFCAP_ET_DAMPER, SDL_HAPTIC_DAMPER);
    FF_TEST(FFCAP_ET_INERTIA, SDL_HAPTIC_INERTIA);
    FF_TEST(FFCAP_ET_FRICTION, SDL_HAPTIC_FRICTION);
    FF_TEST(FFCAP_ET_CUSTOMFORCE, SDL_HAPTIC_CUSTOM);

    /* Check if supports gain. */
    ret = FFDeviceGetForceFeedbackProperty(device, FFPROP_FFGAIN,
                                           &val, sizeof(val));
    if (ret == FF_OK)
        supported |= SDL_HAPTIC_GAIN;
    else if (ret != FFERR_UNSUPPORTED) {
        return SDL_SetError("Haptic: Unable to get if device supports gain: %s.",
                            FFStrError(ret));
    }

    /* Checks if supports autocenter. */
    ret = FFDeviceGetForceFeedbackProperty(device, FFPROP_AUTOCENTER,
                                           &val, sizeof(val));
    if (ret == FF_OK)
        supported |= SDL_HAPTIC_AUTOCENTER;
    else if (ret != FFERR_UNSUPPORTED) {
        return SDL_SetError
            ("Haptic: Unable to get if device supports autocenter: %s.",
             FFStrError(ret));
    }

    /* Check for axes, we have an artificial limit on axes */
    haptic->naxes = ((features.numFfAxes) > 3) ? 3 : features.numFfAxes;
    /* Actually store the axes we want to use */
    SDL_memcpy(haptic->hwdata->axes, features.ffAxes,
               haptic->naxes * sizeof(Uint8));

    /* Always supported features. */
    supported |= SDL_HAPTIC_STATUS | SDL_HAPTIC_PAUSE;

    haptic->supported = supported;
    return 0;;
}


/*
 * Opens the haptic device from the file descriptor.
 */
static int
SDL_SYS_HapticOpenFromService(SDL_Haptic * haptic, io_service_t service)
{
    HRESULT ret;
    int ret2;

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

    /* Open the device */
    ret = FFCreateDevice(service, &haptic->hwdata->device);
    if (ret != FF_OK) {
        SDL_SetError("Haptic: Unable to create device from service: %s.",
                     FFStrError(ret));
        goto creat_err;
    }

    /* Get supported features. */
    ret2 = GetSupportedFeatures(haptic);
    if (ret2 < 0) {
        goto open_err;
    }


    /* Reset and then enable actuators. */
    ret = FFDeviceSendForceFeedbackCommand(haptic->hwdata->device,
                                           FFSFFC_RESET);
    if (ret != FF_OK) {
        SDL_SetError("Haptic: Unable to reset device: %s.", FFStrError(ret));
        goto open_err;
    }
    ret = FFDeviceSendForceFeedbackCommand(haptic->hwdata->device,
                                           FFSFFC_SETACTUATORSON);
    if (ret != FF_OK) {
        SDL_SetError("Haptic: Unable to enable actuators: %s.",
                     FFStrError(ret));
        goto open_err;
    }


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

    return 0;

    /* Error handling */
  open_err:
    FFReleaseDevice(haptic->hwdata->device);
  creat_err:
    if (haptic->hwdata != NULL) {
        free(haptic->hwdata);
        haptic->hwdata = NULL;
    }
    return -1;

}


/*
 * Opens a haptic device for usage.
 */
int
SDL_SYS_HapticOpen(SDL_Haptic * haptic)
{
    return SDL_SYS_HapticOpenFromService(haptic,
                                         SDL_hapticlist[haptic->index].dev);
}


/*
 * Opens a haptic device from first mouse it finds for usage.
 */
int
SDL_SYS_HapticMouse(void)
{
    int i;

    for (i = 0; i < SDL_numhaptics; i++) {
        if ((SDL_hapticlist[i].usagePage == kHIDPage_GenericDesktop) &&
            (SDL_hapticlist[i].usage == kHIDUsage_GD_Mouse))
            return i;
    }

    return -1;
}


/*
 * Checks to see if a joystick has haptic features.
 */
int
SDL_SYS_JoystickIsHaptic(SDL_Joystick * joystick)
{
    if (joystick->hwdata->ffservice != 0)
        return SDL_TRUE;
    return SDL_FALSE;
}


/*
 * Checks to see if the haptic device and joystick are in reality the same.
 */
int
SDL_SYS_JoystickSameHaptic(SDL_Haptic * haptic, SDL_Joystick * joystick)
{
    if (IOObjectIsEqualTo((io_object_t) ((size_t)haptic->hwdata->device),
                          joystick->hwdata->ffservice))
        return 1;
    return 0;
}


/*
 * Opens a SDL_Haptic from a SDL_Joystick.
 */
int
SDL_SYS_HapticOpenFromJoystick(SDL_Haptic * haptic, SDL_Joystick * joystick)
{
    int i;
    for (i=0; i<SDL_numhaptics; i++) {
       if (IOObjectIsEqualTo((io_object_t) SDL_hapticlist[i].dev,
                             joystick->hwdata->ffservice)) {
           haptic->index = i;
           break;
       }
    }
    if (i >= SDL_numhaptics) {
       return -1;
    }

    return SDL_SYS_HapticOpenFromService(haptic, joystick->hwdata->ffservice);
}


/*
 * Closes the haptic device.
 */
void
SDL_SYS_HapticClose(SDL_Haptic * haptic)
{
    if (haptic->hwdata) {

        /* Free Effects. */
        SDL_free(haptic->effects);
        haptic->effects = NULL;
        haptic->neffects = 0;

        /* Clean up */
        FFReleaseDevice(haptic->hwdata->device);

        /* Free */
        SDL_free(haptic->hwdata);
        haptic->hwdata = NULL;
    }
}


/*
 * Clean up after system specific haptic stuff
 */
void
SDL_SYS_HapticQuit(void)
{
    int i;

    for (i = 0; i < SDL_numhaptics; i++) {
        /* Opened and not closed haptics are leaked, this is on purpose.
         * Close your haptic devices after usage. */

        /* Free the io_service_t */
        IOObjectRelease(SDL_hapticlist[i].dev);
    }
}


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

    dwTriggerButton = FFEB_NOTRIGGER;

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

    return dwTriggerButton;
}


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

    /* Handle no axes a part. */
    if (naxes == 0) {
        effect->dwFlags |= FFEFF_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 |= FFEFF_POLAR;
        rglDir[0] = dir->dir[0];
        return 0;
    case SDL_HAPTIC_CARTESIAN:
        effect->dwFlags |= FFEFF_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 |= FFEFF_SPHERICAL;
        rglDir[0] = dir->dir[0];
        if (naxes > 1)
            rglDir[1] = dir->dir[1];
        if (naxes > 2)
            rglDir[2] = dir->dir[2];
        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 FFEFFECT from a SDL_HapticEffect.
 */
static int
SDL_SYS_ToFFEFFECT(SDL_Haptic * haptic, FFEFFECT * dest,
                   SDL_HapticEffect * src)
{
    int i;
    FFCONSTANTFORCE *constant;
    FFPERIODIC *periodic;
    FFCONDITION *condition;     /* Actually an array of conditions - one per axis. */
    FFRAMPFORCE *ramp;
    FFCUSTOMFORCE *custom;
    FFENVELOPE *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(FFEFFECT));
    dest->dwSize = sizeof(FFEFFECT);    /* Set the structure size. */
    dest->dwSamplePeriod = 0;   /* Not used by us. */
    dest->dwGain = 10000;       /* Gain is set globally, not locally. */
    dest->dwFlags = FFEFF_OBJECTOFFSETS;        /* Seems obligatory. */

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

    /* Axes. */
    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 then Linux's version. */
    switch (src->type) {
    case SDL_HAPTIC_CONSTANT:
        hap_constant = &src->constant;
        constant = SDL_malloc(sizeof(FFCONSTANTFORCE));
        if (constant == NULL) {
            return SDL_OutOfMemory();
        }
        SDL_memset(constant, 0, sizeof(FFCONSTANTFORCE));

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

        /* Generics */
        dest->dwDuration = hap_constant->length * 1000; /* In microseconds. */
        dest->dwTriggerButton = FFGetTriggerButton(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(envelope);
            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(FFPERIODIC));
        if (periodic == NULL) {
            return SDL_OutOfMemory();
        }
        SDL_memset(periodic, 0, sizeof(FFPERIODIC));

        /* Specifics */
        periodic->dwMagnitude = CONVERT(hap_periodic->magnitude);
        periodic->lOffset = CONVERT(hap_periodic->offset);
        periodic->dwPhase = hap_periodic->phase;
        periodic->dwPeriod = hap_periodic->period * 1000;
        dest->cbTypeSpecificParams = sizeof(FFPERIODIC);
        dest->lpvTypeSpecificParams = periodic;

        /* Generics */
        dest->dwDuration = hap_periodic->length * 1000; /* In microseconds. */
        dest->dwTriggerButton = FFGetTriggerButton(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(envelope);
            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(FFCONDITION) * dest->cAxes);
        if (condition == NULL) {
            return SDL_OutOfMemory();
        }
        SDL_memset(condition, 0, sizeof(FFCONDITION));

        /* Specifics */
        for (i = 0; i < 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]);
            condition[i].dwNegativeSaturation =
                CCONVERT(hap_condition->left_sat[i]);
            condition[i].lDeadBand = CCONVERT(hap_condition->deadband[i]);
        }
        dest->cbTypeSpecificParams = sizeof(FFCONDITION) * dest->cAxes;
        dest->lpvTypeSpecificParams = condition;

        /* Generics */
        dest->dwDuration = hap_condition->length * 1000;        /* In microseconds. */
        dest->dwTriggerButton = FFGetTriggerButton(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(FFRAMPFORCE));
        if (ramp == NULL) {
            return SDL_OutOfMemory();
        }
        SDL_memset(ramp, 0, sizeof(FFRAMPFORCE));

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

        /* Generics */
        dest->dwDuration = hap_ramp->length * 1000;     /* In microseconds. */
        dest->dwTriggerButton = FFGetTriggerButton(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(envelope);
            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(FFCUSTOMFORCE));
        if (custom == NULL) {
            return SDL_OutOfMemory();
        }
        SDL_memset(custom, 0, sizeof(FFCUSTOMFORCE));

        /* 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(FFCUSTOMFORCE);
        dest->lpvTypeSpecificParams = custom;

        /* Generics */
        dest->dwDuration = hap_custom->length * 1000;   /* In microseconds. */
        dest->dwTriggerButton = FFGetTriggerButton(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(envelope);
            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 FFEFFECT allocated by SDL_SYS_ToFFEFFECT.
 */
static void
SDL_SYS_HapticFreeFFEFFECT(FFEFFECT * effect, int type)
{
    FFCUSTOMFORCE *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 = (FFCUSTOMFORCE *) 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.
 */
CFUUIDRef
SDL_SYS_HapticEffectType(Uint16 type)
{
    switch (type) {
    case SDL_HAPTIC_CONSTANT:
        return kFFEffectType_ConstantForce_ID;

    case SDL_HAPTIC_RAMP:
        return kFFEffectType_RampForce_ID;

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

    case SDL_HAPTIC_SINE:
        return kFFEffectType_Sine_ID;

    case SDL_HAPTIC_TRIANGLE:
        return kFFEffectType_Triangle_ID;

    case SDL_HAPTIC_SAWTOOTHUP:
        return kFFEffectType_SawtoothUp_ID;

    case SDL_HAPTIC_SAWTOOTHDOWN:
        return kFFEffectType_SawtoothDown_ID;

    case SDL_HAPTIC_SPRING:
        return kFFEffectType_Spring_ID;

    case SDL_HAPTIC_DAMPER:
        return kFFEffectType_Damper_ID;

    case SDL_HAPTIC_INERTIA:
        return kFFEffectType_Inertia_ID;

    case SDL_HAPTIC_FRICTION:
        return kFFEffectType_Friction_ID;

    case SDL_HAPTIC_CUSTOM:
        return kFFEffectType_CustomForce_ID;

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


/*
 * Creates a new haptic effect.
 */
int
SDL_SYS_HapticNewEffect(SDL_Haptic * haptic, struct haptic_effect *effect,
                        SDL_HapticEffect * base)
{
    HRESULT ret;
    CFUUIDRef type;

    /* Alloc the effect. */
    effect->hweffect = (struct haptic_hweffect *)
        SDL_malloc(sizeof(struct haptic_hweffect));
    if (effect->hweffect == NULL) {
        SDL_OutOfMemory();
        goto err_hweffect;
    }

    /* Get the type. */
    type = SDL_SYS_HapticEffectType(base->type);
    if (type == NULL) {
        goto err_hweffect;
    }

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

    /* Create the actual effect. */
    ret = FFDeviceCreateEffect(haptic->hwdata->device, type,
                               &effect->hweffect->effect,
                               &effect->hweffect->ref);
    if (ret != FF_OK) {
        SDL_SetError("Haptic: Unable to create effect: %s.", FFStrError(ret));
        goto err_effectdone;
    }

    return 0;

  err_effectdone:
    SDL_SYS_HapticFreeFFEFFECT(&effect->hweffect->effect, base->type);
  err_hweffect:
    SDL_free(effect->hweffect);
    effect->hweffect = NULL;
    return -1;
}


/*
 * Updates an effect.
 */
int
SDL_SYS_HapticUpdateEffect(SDL_Haptic * haptic,
                           struct haptic_effect *effect,
                           SDL_HapticEffect * data)
{
    HRESULT ret;
    FFEffectParameterFlag flags;
    FFEFFECT temp;

    /* Get the effect. */
    SDL_memset(&temp, 0, sizeof(FFEFFECT));
    if (SDL_SYS_ToFFEFFECT(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 = FFEP_DIRECTION |
        FFEP_DURATION |
        FFEP_ENVELOPE |
        FFEP_STARTDELAY |
        FFEP_TRIGGERBUTTON |
        FFEP_TRIGGERREPEATINTERVAL | FFEP_TYPESPECIFICPARAMS;

    /* Create the actual effect. */
    ret = FFEffectSetParameters(effect->hweffect->ref, &temp, flags);
    if (ret != FF_OK) {
        SDL_SetError("Haptic: Unable to update effect: %s.", FFStrError(ret));
        goto err_update;
    }

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

    return 0;

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


/*
 * Runs an effect.
 */
int
SDL_SYS_HapticRunEffect(SDL_Haptic * haptic, struct haptic_effect *effect,
                        Uint32 iterations)
{
    HRESULT ret;
    Uint32 iter;

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

    /* Run the effect. */
    ret = FFEffectStart(effect->hweffect->ref, iter, 0);
    if (ret != FF_OK) {
        return SDL_SetError("Haptic: Unable to run the effect: %s.",
                            FFStrError(ret));
    }

    return 0;
}


/*
 * Stops an effect.
 */
int
SDL_SYS_HapticStopEffect(SDL_Haptic * haptic, struct haptic_effect *effect)
{
    HRESULT ret;

    ret = FFEffectStop(effect->hweffect->ref);
    if (ret != FF_OK) {
        return SDL_SetError("Haptic: Unable to stop the effect: %s.",
                            FFStrError(ret));
    }

    return 0;
}


/*
 * Frees the effect.
 */
void
SDL_SYS_HapticDestroyEffect(SDL_Haptic * haptic, struct haptic_effect *effect)
{
    HRESULT ret;

    ret =
        FFDeviceReleaseEffect(haptic->hwdata->device, effect->hweffect->ref);
    if (ret != FF_OK) {
        SDL_SetError("Haptic: Error removing the effect from the device: %s.",
                     FFStrError(ret));
    }
    SDL_SYS_HapticFreeFFEFFECT(&effect->hweffect->effect,
                               effect->effect.type);
    SDL_free(effect->hweffect);
    effect->hweffect = NULL;
}


/*
 * Gets the status of a haptic effect.
 */
int
SDL_SYS_HapticGetEffectStatus(SDL_Haptic * haptic,
                              struct haptic_effect *effect)
{
    HRESULT ret;
    FFEffectStatusFlag status;

    ret = FFEffectGetEffectStatus(effect->hweffect->ref, &status);
    if (ret != FF_OK) {
        SDL_SetError("Haptic: Unable to get effect status: %s.",
                     FFStrError(ret));
        return -1;
    }

    if (status == 0)
        return SDL_FALSE;
    return SDL_TRUE;            /* Assume it's playing or emulated. */
}


/*
 * Sets the gain.
 */
int
SDL_SYS_HapticSetGain(SDL_Haptic * haptic, int gain)
{
    HRESULT ret;
    Uint32 val;

    val = gain * 100;           /* Mac OS X uses 0 to 10,000 */
    ret =
        FFDeviceSetForceFeedbackProperty(haptic->hwdata->device,
                                         FFPROP_FFGAIN, &val);
    if (ret != FF_OK) {
        return SDL_SetError("Haptic: Error setting gain: %s.", FFStrError(ret));
    }

    return 0;
}


/*
 * Sets the autocentering.
 */
int
SDL_SYS_HapticSetAutocenter(SDL_Haptic * haptic, int autocenter)
{
    HRESULT ret;
    Uint32 val;

    /* Mac OS X only has 0 (off) and 1 (on) */
    if (autocenter == 0)
        val = 0;
    else
        val = 1;

    ret = FFDeviceSetForceFeedbackProperty(haptic->hwdata->device,
                                           FFPROP_AUTOCENTER, &val);
    if (ret != FF_OK) {
        return SDL_SetError("Haptic: Error setting autocenter: %s.",
                            FFStrError(ret));
    }

    return 0;
}


/*
 * Pauses the device.
 */
int
SDL_SYS_HapticPause(SDL_Haptic * haptic)
{
    HRESULT ret;

    ret = FFDeviceSendForceFeedbackCommand(haptic->hwdata->device,
                                           FFSFFC_PAUSE);
    if (ret != FF_OK) {
        return SDL_SetError("Haptic: Error pausing device: %s.", FFStrError(ret));
    }

    return 0;
}


/*
 * Unpauses the device.
 */
int
SDL_SYS_HapticUnpause(SDL_Haptic * haptic)
{
    HRESULT ret;

    ret = FFDeviceSendForceFeedbackCommand(haptic->hwdata->device,
                                           FFSFFC_CONTINUE);
    if (ret != FF_OK) {
        return SDL_SetError("Haptic: Error pausing device: %s.", FFStrError(ret));
    }

    return 0;
}


/*
 * Stops all currently playing effects.
 */
int
SDL_SYS_HapticStopAll(SDL_Haptic * haptic)
{
    HRESULT ret;

    ret = FFDeviceSendForceFeedbackCommand(haptic->hwdata->device,
                                           FFSFFC_STOPALL);
    if (ret != FF_OK) {
        return SDL_SetError("Haptic: Error stopping device: %s.", FFStrError(ret));
    }

    return 0;
}


#endif /* SDL_HAPTIC_IOKIT */
