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

/* This is the game controller API for Simple DirectMedia Layer */

#include "SDL_events.h"
#include "SDL_assert.h"
#include "SDL_sysjoystick.h"
#include "SDL_hints.h"
#include "SDL_gamecontrollerdb.h"

#if !SDL_EVENTS_DISABLED
#include "../events/SDL_events_c.h"
#endif
#define ABS(_x) ((_x) < 0 ? -(_x) : (_x))

#define SDL_CONTROLLER_PLATFORM_FIELD "platform:"

/* a list of currently opened game controllers */
static SDL_GameController *SDL_gamecontrollers = NULL;

/* keep track of the hat and mask value that transforms this hat movement into a button/axis press */
struct _SDL_HatMapping
{
    int hat;
    Uint8 mask;
};

#define k_nMaxReverseEntries 20

/**
 * We are encoding the "HAT" as 0xhm. where h == hat ID and m == mask
 * MAX 4 hats supported
 */
#define k_nMaxHatEntries 0x3f + 1

/* our in memory mapping db between joystick objects and controller mappings */
struct _SDL_ControllerMapping
{
    SDL_JoystickGUID guid;
    const char *name;

    /* mapping of axis/button id to controller version */
    int axes[SDL_CONTROLLER_AXIS_MAX];
    int buttonasaxis[SDL_CONTROLLER_AXIS_MAX];

    int buttons[SDL_CONTROLLER_BUTTON_MAX];
    int axesasbutton[SDL_CONTROLLER_BUTTON_MAX];
    struct _SDL_HatMapping hatasbutton[SDL_CONTROLLER_BUTTON_MAX];

    /* reverse mapping, joystick indices to buttons */
    SDL_GameControllerAxis raxes[k_nMaxReverseEntries];
    SDL_GameControllerAxis rbuttonasaxis[k_nMaxReverseEntries];

    SDL_GameControllerButton rbuttons[k_nMaxReverseEntries];
    SDL_GameControllerButton raxesasbutton[k_nMaxReverseEntries];
    SDL_GameControllerButton rhatasbutton[k_nMaxHatEntries];

};


/* our hard coded list of mapping support */
typedef struct _ControllerMapping_t
{
    SDL_JoystickGUID guid;
    char *name;
    char *mapping;
    struct _ControllerMapping_t *next;
} ControllerMapping_t;

static ControllerMapping_t *s_pSupportedControllers = NULL;
#if defined(SDL_JOYSTICK_DINPUT) || defined(SDL_JOYSTICK_XINPUT)
static ControllerMapping_t *s_pXInputMapping = NULL;
#endif

/* The SDL game controller structure */
struct _SDL_GameController
{
    SDL_Joystick *joystick; /* underlying joystick device */
    int ref_count;
    Uint8 hatState[4]; /* the current hat state for this controller */
    struct _SDL_ControllerMapping mapping; /* the mapping object for this controller */
    struct _SDL_GameController *next; /* pointer to next game controller we have allocated */
};


int SDL_PrivateGameControllerAxis(SDL_GameController * gamecontroller, SDL_GameControllerAxis axis, Sint16 value);
int SDL_PrivateGameControllerButton(SDL_GameController * gamecontroller, SDL_GameControllerButton button, Uint8 state);

/*
 * Event filter to fire controller events from joystick ones
 */
int SDL_GameControllerEventWatcher(void *userdata, SDL_Event * event)
{
    switch( event->type )
    {
    case SDL_JOYAXISMOTION:
        {
            SDL_GameController *controllerlist;

            if ( event->jaxis.axis >= k_nMaxReverseEntries ) break;

            controllerlist = SDL_gamecontrollers;
            while ( controllerlist )
            {
                if ( controllerlist->joystick->instance_id == event->jaxis.which )
                {
                    if ( controllerlist->mapping.raxes[event->jaxis.axis] >= 0 ) /* simple axis to axis, send it through */
                    {
                        SDL_GameControllerAxis axis = controllerlist->mapping.raxes[event->jaxis.axis];
                        Sint16 value = event->jaxis.value;
                        switch (axis)
                        {
                            case SDL_CONTROLLER_AXIS_TRIGGERLEFT:
                            case SDL_CONTROLLER_AXIS_TRIGGERRIGHT:
                                /* Shift it to be 0 - 32767. */
                                value = value / 2 + 16384;
                            default:
                                break;
                        }
                        SDL_PrivateGameControllerAxis( controllerlist, axis, value );
                    }
                    else if ( controllerlist->mapping.raxesasbutton[event->jaxis.axis] >= 0 ) /* simulate an axis as a button */
                    {
                        SDL_PrivateGameControllerButton( controllerlist, controllerlist->mapping.raxesasbutton[event->jaxis.axis], ABS(event->jaxis.value) > 32768/2 ? SDL_PRESSED : SDL_RELEASED );
                    }
                    break;
                }
                controllerlist = controllerlist->next;
            }
        }
        break;
    case SDL_JOYBUTTONDOWN:
    case SDL_JOYBUTTONUP:
        {
            SDL_GameController *controllerlist;

            if ( event->jbutton.button >= k_nMaxReverseEntries ) break;

            controllerlist = SDL_gamecontrollers;
            while ( controllerlist )
            {
                if ( controllerlist->joystick->instance_id == event->jbutton.which )
                {
                    if ( controllerlist->mapping.rbuttons[event->jbutton.button] >= 0 ) /* simple button as button */
                    {
                        SDL_PrivateGameControllerButton( controllerlist, controllerlist->mapping.rbuttons[event->jbutton.button], event->jbutton.state );
                    }
                    else if ( controllerlist->mapping.rbuttonasaxis[event->jbutton.button] >= 0 ) /* an button pretending to be an axis */
                    {
                        SDL_PrivateGameControllerAxis( controllerlist, controllerlist->mapping.rbuttonasaxis[event->jbutton.button], event->jbutton.state > 0 ? 32767 : 0 );
                    }
                    break;
                }
                controllerlist = controllerlist->next;
            }
        }
        break;
    case SDL_JOYHATMOTION:
        {
            SDL_GameController *controllerlist;

            if ( event->jhat.hat >= 4 ) break;

            controllerlist = SDL_gamecontrollers;
            while ( controllerlist )
            {
                if ( controllerlist->joystick->instance_id == event->jhat.which )
                {
                    Uint8 bSame = controllerlist->hatState[event->jhat.hat] & event->jhat.value;
                    /* Get list of removed bits (button release) */
                    Uint8 bChanged = controllerlist->hatState[event->jhat.hat] ^ bSame;
                    /* the hat idx in the high nibble */
                    int bHighHat = event->jhat.hat << 4;

                    if ( bChanged & SDL_HAT_DOWN )
                        SDL_PrivateGameControllerButton( controllerlist, controllerlist->mapping.rhatasbutton[bHighHat | SDL_HAT_DOWN], SDL_RELEASED );
                    if ( bChanged & SDL_HAT_UP )
                        SDL_PrivateGameControllerButton( controllerlist, controllerlist->mapping.rhatasbutton[bHighHat | SDL_HAT_UP], SDL_RELEASED );
                    if ( bChanged & SDL_HAT_LEFT )
                        SDL_PrivateGameControllerButton( controllerlist, controllerlist->mapping.rhatasbutton[bHighHat | SDL_HAT_LEFT], SDL_RELEASED );
                    if ( bChanged & SDL_HAT_RIGHT )
                        SDL_PrivateGameControllerButton( controllerlist, controllerlist->mapping.rhatasbutton[bHighHat | SDL_HAT_RIGHT], SDL_RELEASED );

                    /* Get list of added bits (button press) */
                    bChanged = event->jhat.value ^ bSame;

                    if ( bChanged & SDL_HAT_DOWN )
                        SDL_PrivateGameControllerButton( controllerlist, controllerlist->mapping.rhatasbutton[bHighHat | SDL_HAT_DOWN], SDL_PRESSED );
                    if ( bChanged & SDL_HAT_UP )
                        SDL_PrivateGameControllerButton( controllerlist, controllerlist->mapping.rhatasbutton[bHighHat | SDL_HAT_UP], SDL_PRESSED );
                    if ( bChanged & SDL_HAT_LEFT )
                        SDL_PrivateGameControllerButton( controllerlist, controllerlist->mapping.rhatasbutton[bHighHat | SDL_HAT_LEFT], SDL_PRESSED );
                    if ( bChanged & SDL_HAT_RIGHT )
                        SDL_PrivateGameControllerButton( controllerlist, controllerlist->mapping.rhatasbutton[bHighHat | SDL_HAT_RIGHT], SDL_PRESSED );

                    /* update our state cache */
                    controllerlist->hatState[event->jhat.hat] = event->jhat.value;

                    break;
                }
                controllerlist = controllerlist->next;
            }
        }
        break;
    case SDL_JOYDEVICEADDED:
        {
            if ( SDL_IsGameController(event->jdevice.which ) )
            {
                SDL_Event deviceevent;
                deviceevent.type = SDL_CONTROLLERDEVICEADDED;
                deviceevent.cdevice.which = event->jdevice.which;
                SDL_PushEvent(&deviceevent);
            }
        }
        break;
    case SDL_JOYDEVICEREMOVED:
        {
            SDL_GameController *controllerlist = SDL_gamecontrollers;
            while ( controllerlist )
            {
                if ( controllerlist->joystick->instance_id == event->jdevice.which )
                {
                    SDL_Event deviceevent;
                    deviceevent.type = SDL_CONTROLLERDEVICEREMOVED;
                    deviceevent.cdevice.which = event->jdevice.which;
                    SDL_PushEvent(&deviceevent);
                    break;
                }
                controllerlist = controllerlist->next;
            }
        }
        break;
    default:
        break;
    }

    return 1;
}

/*
 * Helper function to scan the mappings database for a controller with the specified GUID
 */
ControllerMapping_t *SDL_PrivateGetControllerMappingForGUID(SDL_JoystickGUID *guid)
{
    ControllerMapping_t *pSupportedController = s_pSupportedControllers;
    while ( pSupportedController )
    {
        if ( !SDL_memcmp( guid, &pSupportedController->guid, sizeof(*guid) ) )
        {
            return pSupportedController;
        }
        pSupportedController = pSupportedController->next;
    }
    return NULL;
}

/*
 * Helper function to determine pre-calculated offset to certain joystick mappings
 */
ControllerMapping_t *SDL_PrivateGetControllerMapping(int device_index)
{
#if defined(SDL_JOYSTICK_DINPUT) || defined(SDL_JOYSTICK_XINPUT)
    if ( SDL_SYS_IsXInputDeviceIndex(device_index) && s_pXInputMapping )
    {
        return s_pXInputMapping;
    }
    else
#endif
    {
        SDL_JoystickGUID jGUID = SDL_JoystickGetDeviceGUID( device_index );
        return SDL_PrivateGetControllerMappingForGUID(&jGUID);
    }
}

static const char* map_StringForControllerAxis[] = {
    "leftx",
    "lefty",
    "rightx",
    "righty",
    "lefttrigger",
    "righttrigger",
    NULL
};

/*
 * convert a string to its enum equivalent
 */
SDL_GameControllerAxis SDL_GameControllerGetAxisFromString( const char *pchString )
{
    int entry;
    if ( !pchString || !pchString[0] )
        return SDL_CONTROLLER_AXIS_INVALID;

    for ( entry = 0; map_StringForControllerAxis[entry]; ++entry)
    {
        if ( !SDL_strcasecmp( pchString, map_StringForControllerAxis[entry] ) )
            return entry;
    }
    return SDL_CONTROLLER_AXIS_INVALID;
}

/*
 * convert an enum to its string equivalent
 */
const char* SDL_GameControllerGetStringForAxis( SDL_GameControllerAxis axis )
{
    if (axis > SDL_CONTROLLER_AXIS_INVALID && axis < SDL_CONTROLLER_AXIS_MAX)
    {
        return map_StringForControllerAxis[axis];
    }
    return NULL;
}

static const char* map_StringForControllerButton[] = {
    "a",
    "b",
    "x",
    "y",
    "back",
    "guide",
    "start",
    "leftstick",
    "rightstick",
    "leftshoulder",
    "rightshoulder",
    "dpup",
    "dpdown",
    "dpleft",
    "dpright",
    NULL
};

/*
 * convert a string to its enum equivalent
 */
SDL_GameControllerButton SDL_GameControllerGetButtonFromString( const char *pchString )
{
    int entry;
    if ( !pchString || !pchString[0] )
        return SDL_CONTROLLER_BUTTON_INVALID;

    for ( entry = 0; map_StringForControllerButton[entry]; ++entry)
    {
        if ( !SDL_strcasecmp( pchString, map_StringForControllerButton[entry] ) )
        return entry;
    }
    return SDL_CONTROLLER_BUTTON_INVALID;
}

/*
 * convert an enum to its string equivalent
 */
const char* SDL_GameControllerGetStringForButton( SDL_GameControllerButton axis )
{
    if (axis > SDL_CONTROLLER_BUTTON_INVALID && axis < SDL_CONTROLLER_BUTTON_MAX)
    {
        return map_StringForControllerButton[axis];
    }
    return NULL;
}

/*
 * given a controller button name and a joystick name update our mapping structure with it
 */
void SDL_PrivateGameControllerParseButton( const char *szGameButton, const char *szJoystickButton, struct _SDL_ControllerMapping *pMapping )
{
    int iSDLButton = 0;
    SDL_GameControllerButton button;
    SDL_GameControllerAxis axis;
    button = SDL_GameControllerGetButtonFromString( szGameButton );
    axis = SDL_GameControllerGetAxisFromString( szGameButton );
    iSDLButton = SDL_atoi( &szJoystickButton[1] );

    if ( szJoystickButton[0] == 'a' )
    {
        if ( iSDLButton >= k_nMaxReverseEntries )
        {
            SDL_SetError("Axis index too large: %d", iSDLButton );
            return;
        }
        if ( axis != SDL_CONTROLLER_AXIS_INVALID )
        {
            pMapping->axes[ axis ] = iSDLButton;
            pMapping->raxes[ iSDLButton ] = axis;
        }
        else if ( button != SDL_CONTROLLER_BUTTON_INVALID )
        {
            pMapping->axesasbutton[ button ] = iSDLButton;
            pMapping->raxesasbutton[ iSDLButton ] = button;
        }
        else
        {
            SDL_assert( !"How did we get here?" );
        }

    }
    else if ( szJoystickButton[0] == 'b' )
    {
        if ( iSDLButton >= k_nMaxReverseEntries )
        {
            SDL_SetError("Button index too large: %d", iSDLButton );
            return;
        }
        if ( button != SDL_CONTROLLER_BUTTON_INVALID )
        {
            pMapping->buttons[ button ] = iSDLButton;
            pMapping->rbuttons[ iSDLButton ] = button;
        }
        else if ( axis != SDL_CONTROLLER_AXIS_INVALID )
        {
            pMapping->buttonasaxis[ axis ] = iSDLButton;
            pMapping->rbuttonasaxis[ iSDLButton ] = axis;
        }
        else
        {
            SDL_assert( !"How did we get here?" );
        }
    }
    else if ( szJoystickButton[0] == 'h' )
    {
        int hat = SDL_atoi( &szJoystickButton[1] );
        int mask = SDL_atoi( &szJoystickButton[3] );
        if (hat >= 4) {
            SDL_SetError("Hat index too large: %d", iSDLButton );
        }

        if ( button != SDL_CONTROLLER_BUTTON_INVALID )
        {
            int ridx;
            pMapping->hatasbutton[ button ].hat = hat;
            pMapping->hatasbutton[ button ].mask = mask;
            ridx = (hat << 4) | mask;
            pMapping->rhatasbutton[ ridx ] = button;
        }
        else if ( axis != SDL_CONTROLLER_AXIS_INVALID )
        {
            SDL_assert( !"Support hat as axis" );
        }
        else
        {
            SDL_assert( !"How did we get here?" );
        }
    }
}


/*
 * given a controller mapping string update our mapping object
 */
static void
SDL_PrivateGameControllerParseControllerConfigString( struct _SDL_ControllerMapping *pMapping, const char *pchString )
{
    char szGameButton[20];
    char szJoystickButton[20];
    SDL_bool bGameButton = SDL_TRUE;
    int i = 0;
    const char *pchPos = pchString;

    SDL_memset( szGameButton, 0x0, sizeof(szGameButton) );
    SDL_memset( szJoystickButton, 0x0, sizeof(szJoystickButton) );

    while ( pchPos && *pchPos )
    {
        if ( *pchPos == ':' )
        {
            i = 0;
            bGameButton = SDL_FALSE;
        }
        else if ( *pchPos == ' ' )
        {

        }
        else if ( *pchPos == ',' )
        {
            i = 0;
            bGameButton = SDL_TRUE;
            SDL_PrivateGameControllerParseButton( szGameButton, szJoystickButton, pMapping );
            SDL_memset( szGameButton, 0x0, sizeof(szGameButton) );
            SDL_memset( szJoystickButton, 0x0, sizeof(szJoystickButton) );

        }
        else if ( bGameButton )
        {
            if ( i >=  sizeof(szGameButton))
            {
                SDL_SetError( "Button name too large: %s", szGameButton );
                return;
            }
            szGameButton[i] = *pchPos;
            i++;
        }
        else
        {
            if ( i >=  sizeof(szJoystickButton))
            {
                SDL_SetError( "Joystick button name too large: %s", szJoystickButton );
                return;
            }
            szJoystickButton[i] = *pchPos;
            i++;
        }
        pchPos++;
    }

    SDL_PrivateGameControllerParseButton( szGameButton, szJoystickButton, pMapping );

}

/*
 * Make a new button mapping struct
 */
void SDL_PrivateLoadButtonMapping( struct _SDL_ControllerMapping *pMapping, SDL_JoystickGUID guid, const char *pchName, const char *pchMapping )
{
    int j;

    pMapping->guid = guid;
    pMapping->name = pchName;

    /* set all the button mappings to non defaults */
    for ( j = 0; j < SDL_CONTROLLER_AXIS_MAX; j++ )
    {
        pMapping->axes[j] = -1;
        pMapping->buttonasaxis[j] = -1;
    }
    for ( j = 0; j < SDL_CONTROLLER_BUTTON_MAX; j++ )
    {
        pMapping->buttons[j] = -1;
        pMapping->axesasbutton[j] = -1;
        pMapping->hatasbutton[j].hat = -1;
    }

    for ( j = 0; j < k_nMaxReverseEntries; j++ )
    {
        pMapping->raxes[j] = SDL_CONTROLLER_AXIS_INVALID;
        pMapping->rbuttonasaxis[j] = SDL_CONTROLLER_AXIS_INVALID;
        pMapping->rbuttons[j] = SDL_CONTROLLER_BUTTON_INVALID;
        pMapping->raxesasbutton[j] = SDL_CONTROLLER_BUTTON_INVALID;
    }

    for (j = 0; j < k_nMaxHatEntries; j++)
    {
        pMapping->rhatasbutton[j] = SDL_CONTROLLER_BUTTON_INVALID;
    }

    SDL_PrivateGameControllerParseControllerConfigString( pMapping, pchMapping );
}


/*
 * grab the guid string from a mapping string
 */
char *SDL_PrivateGetControllerGUIDFromMappingString( const char *pMapping )
{
    const char *pFirstComma = SDL_strchr( pMapping, ',' );
    if ( pFirstComma )
    {
        char *pchGUID = SDL_malloc( pFirstComma - pMapping + 1 );
        if ( !pchGUID )
        {
            SDL_OutOfMemory();
            return NULL;
        }
        SDL_memcpy( pchGUID, pMapping, pFirstComma - pMapping );
        pchGUID[ pFirstComma - pMapping ] = 0;
        return pchGUID;
    }
    return NULL;
}


/*
 * grab the name string from a mapping string
 */
char *SDL_PrivateGetControllerNameFromMappingString( const char *pMapping )
{
    const char *pFirstComma, *pSecondComma;
    char *pchName;

    pFirstComma = SDL_strchr( pMapping, ',' );
    if ( !pFirstComma )
        return NULL;

    pSecondComma = SDL_strchr( pFirstComma + 1, ',' );
    if ( !pSecondComma )
        return NULL;

    pchName = SDL_malloc( pSecondComma - pFirstComma );
    if ( !pchName )
    {
        SDL_OutOfMemory();
        return NULL;
    }
    SDL_memcpy( pchName, pFirstComma + 1, pSecondComma - pFirstComma );
    pchName[ pSecondComma - pFirstComma - 1 ] = 0;
    return pchName;
}


/*
 * grab the button mapping string from a mapping string
 */
char *SDL_PrivateGetControllerMappingFromMappingString( const char *pMapping )
{
    const char *pFirstComma, *pSecondComma;

    pFirstComma = SDL_strchr( pMapping, ',' );
    if ( !pFirstComma )
        return NULL;

    pSecondComma = SDL_strchr( pFirstComma + 1, ',' );
    if ( !pSecondComma )
        return NULL;

    return SDL_strdup(pSecondComma + 1); /* mapping is everything after the 3rd comma */
}

void SDL_PrivateGameControllerRefreshMapping( ControllerMapping_t *pControllerMapping )
{
    SDL_GameController *gamecontrollerlist = SDL_gamecontrollers;
    while ( gamecontrollerlist )
    {
        if ( !SDL_memcmp( &gamecontrollerlist->mapping.guid, &pControllerMapping->guid, sizeof(pControllerMapping->guid) ) )
        {
            SDL_Event event;
            event.type = SDL_CONTROLLERDEVICEREMAPPED;
            event.cdevice.which = gamecontrollerlist->joystick->instance_id;
            SDL_PushEvent(&event);

            /* Not really threadsafe.  Should this lock access within SDL_GameControllerEventWatcher? */
            SDL_PrivateLoadButtonMapping(&gamecontrollerlist->mapping, pControllerMapping->guid, pControllerMapping->name, pControllerMapping->mapping);
        }

        gamecontrollerlist = gamecontrollerlist->next;
    }
}

/*
 * Add or update an entry into the Mappings Database
 */
int
SDL_GameControllerAddMappingsFromRW( SDL_RWops * rw, int freerw )
{
    const char *platform = SDL_GetPlatform();
    int controllers = 0;
    char *buf, *line, *line_end, *tmp, *comma, line_platform[64];
    size_t db_size, platform_len;
    
    if (rw == NULL) {
        return SDL_SetError("Invalid RWops");
    }
    db_size = (size_t)SDL_RWsize(rw);
    
    buf = (char *)SDL_malloc(db_size + 1);
    if (buf == NULL) {
        if (freerw) {
            SDL_RWclose(rw);
        }
        return SDL_SetError("Could allocate space to not read DB into memory");
    }
    
    if (SDL_RWread(rw, buf, db_size, 1) != 1) {
        if (freerw) {
            SDL_RWclose(rw);
        }
        SDL_free(buf);
        return SDL_SetError("Could not read DB");
    }
    
    if (freerw) {
        SDL_RWclose(rw);
    }
    
    buf[db_size] = '\0';
    line = buf;
    
    while (line < buf + db_size) {
        line_end = SDL_strchr( line, '\n' );
        if (line_end != NULL) {
            *line_end = '\0';
        }
        else {
            line_end = buf + db_size;
        }
        
        /* Extract and verify the platform */
        tmp = SDL_strstr(line, SDL_CONTROLLER_PLATFORM_FIELD);
        if ( tmp != NULL ) {
            tmp += SDL_strlen(SDL_CONTROLLER_PLATFORM_FIELD);
            comma = SDL_strchr(tmp, ',');
            if (comma != NULL) {
                platform_len = comma - tmp + 1;
                if (platform_len + 1 < SDL_arraysize(line_platform)) {
                    SDL_strlcpy(line_platform, tmp, platform_len);
                    if(SDL_strncasecmp(line_platform, platform, platform_len) == 0
                        && SDL_GameControllerAddMapping(line) > 0) {
                        controllers++;
                    }
                }
            }
        }
        
        line = line_end + 1;
    }

    SDL_free(buf);
    return controllers;
}

/*
 * Add or update an entry into the Mappings Database
 */
int
SDL_GameControllerAddMapping( const char *mappingString )
{
    char *pchGUID;
    char *pchName;
    char *pchMapping;
    SDL_JoystickGUID jGUID;
    ControllerMapping_t *pControllerMapping;
#if defined(SDL_JOYSTICK_DINPUT) || defined(SDL_JOYSTICK_XINPUT)
    SDL_bool is_xinput_mapping = SDL_FALSE;
#endif

    pchGUID = SDL_PrivateGetControllerGUIDFromMappingString( mappingString );
    if (!pchGUID) {
        return SDL_SetError("Couldn't parse GUID from %s", mappingString);
    }
#if defined(SDL_JOYSTICK_DINPUT) || defined(SDL_JOYSTICK_XINPUT)
    if ( !SDL_strcasecmp( pchGUID, "xinput" ) ) {
        is_xinput_mapping = SDL_TRUE;
    }
#endif
    jGUID = SDL_JoystickGetGUIDFromString(pchGUID);
    SDL_free(pchGUID);

    pchName = SDL_PrivateGetControllerNameFromMappingString( mappingString );
    if (!pchName) {
        return SDL_SetError("Couldn't parse name from %s", mappingString);
    }

    pchMapping = SDL_PrivateGetControllerMappingFromMappingString( mappingString );
    if (!pchMapping) {
        SDL_free( pchName );
        return SDL_SetError("Couldn't parse %s", mappingString);
    }

    pControllerMapping = SDL_PrivateGetControllerMappingForGUID(&jGUID);

    if (pControllerMapping) {
        /* Update existing mapping */
        SDL_free( pControllerMapping->name );
        pControllerMapping->name = pchName;
        SDL_free( pControllerMapping->mapping );
        pControllerMapping->mapping = pchMapping;
        /* refresh open controllers */
        SDL_PrivateGameControllerRefreshMapping( pControllerMapping );
        return 0;
    } else {
        pControllerMapping = SDL_malloc( sizeof(*pControllerMapping) );
        if (!pControllerMapping) {
            SDL_free( pchName );
            SDL_free( pchMapping );
            return SDL_OutOfMemory();
        }
#if defined(SDL_JOYSTICK_DINPUT) || defined(SDL_JOYSTICK_XINPUT)
        if ( is_xinput_mapping )
        {
            s_pXInputMapping = pControllerMapping;
        }
#endif
        pControllerMapping->guid = jGUID;
        pControllerMapping->name = pchName;
        pControllerMapping->mapping = pchMapping;
        pControllerMapping->next = s_pSupportedControllers;
        s_pSupportedControllers = pControllerMapping;
        return 1;
    }
}

/*
 * Get the mapping string for this GUID
 */
char *
SDL_GameControllerMappingForGUID( SDL_JoystickGUID guid )
{
    char *pMappingString = NULL;
    ControllerMapping_t *mapping = SDL_PrivateGetControllerMappingForGUID(&guid);
    if (mapping) {
        char pchGUID[33];
        size_t needed;
        SDL_JoystickGetGUIDString(guid, pchGUID, sizeof(pchGUID));
        /* allocate enough memory for GUID + ',' + name + ',' + mapping + \0 */
        needed = SDL_strlen(pchGUID) + 1 + SDL_strlen(mapping->name) + 1 + SDL_strlen(mapping->mapping) + 1;
        pMappingString = SDL_malloc( needed );
        SDL_snprintf( pMappingString, needed, "%s,%s,%s", pchGUID, mapping->name, mapping->mapping );
    }
    return pMappingString;
}

/*
 * Get the mapping string for this device
 */
char *
SDL_GameControllerMapping( SDL_GameController * gamecontroller )
{
    return SDL_GameControllerMappingForGUID( gamecontroller->mapping.guid );
}

static void
SDL_GameControllerLoadHints()
{
    const char *hint = SDL_GetHint(SDL_HINT_GAMECONTROLLERCONFIG);
    if ( hint && hint[0] ) {
        size_t nchHints = SDL_strlen( hint );
        char *pUserMappings = SDL_malloc( nchHints + 1 );
        char *pTempMappings = pUserMappings;
        SDL_memcpy( pUserMappings, hint, nchHints );
        pUserMappings[nchHints] = '\0';
        while ( pUserMappings ) {
            char *pchNewLine = NULL;

            pchNewLine = SDL_strchr( pUserMappings, '\n' );
            if ( pchNewLine )
                *pchNewLine = '\0';

            SDL_GameControllerAddMapping( pUserMappings );

            if ( pchNewLine )
                pUserMappings = pchNewLine + 1;
            else
                pUserMappings = NULL;
        }
        SDL_free(pTempMappings);
    }
}

/*
 * Initialize the game controller system, mostly load our DB of controller config mappings
 */
int
SDL_GameControllerInit(void)
{
    int i = 0;
    const char *pMappingString = NULL;
    s_pSupportedControllers = NULL;
    pMappingString = s_ControllerMappings[i];
    while ( pMappingString ) {
        SDL_GameControllerAddMapping( pMappingString );

        i++;
        pMappingString = s_ControllerMappings[i];
    }

    /* load in any user supplied config */
    SDL_GameControllerLoadHints();

    /* watch for joy events and fire controller ones if needed */
    SDL_AddEventWatch( SDL_GameControllerEventWatcher, NULL );

    /* Send added events for controllers currently attached */
    for (i = 0; i < SDL_NumJoysticks(); ++i) {
        if (SDL_IsGameController(i)) {
            SDL_Event deviceevent;
            deviceevent.type = SDL_CONTROLLERDEVICEADDED;
            deviceevent.cdevice.which = i;
            SDL_PushEvent(&deviceevent);
        }
    }

    return (0);
}


/*
 * Get the implementation dependent name of a controller
 */
const char *
SDL_GameControllerNameForIndex(int device_index)
{
    ControllerMapping_t *pSupportedController =  SDL_PrivateGetControllerMapping(device_index);
    if ( pSupportedController )
    {
        return pSupportedController->name;
    }
    return NULL;
}


/*
 * Return 1 if the joystick at this device index is a supported controller
 */
SDL_bool
SDL_IsGameController(int device_index)
{
    ControllerMapping_t *pSupportedController =  SDL_PrivateGetControllerMapping(device_index);
    if ( pSupportedController )
    {
        return SDL_TRUE;
    }

    return SDL_FALSE;
}

/*
 * Open a controller for use - the index passed as an argument refers to
 * the N'th controller on the system.  This index is the value which will
 * identify this controller in future controller events.
 *
 * This function returns a controller identifier, or NULL if an error occurred.
 */
SDL_GameController *
SDL_GameControllerOpen(int device_index)
{
    SDL_GameController *gamecontroller;
    SDL_GameController *gamecontrollerlist;
    ControllerMapping_t *pSupportedController = NULL;

    if ((device_index < 0) || (device_index >= SDL_NumJoysticks())) {
        SDL_SetError("There are %d joysticks available", SDL_NumJoysticks());
        return (NULL);
    }

    gamecontrollerlist = SDL_gamecontrollers;
    /* If the controller is already open, return it */
    while ( gamecontrollerlist )
    {
        if ( SDL_SYS_GetInstanceIdOfDeviceIndex(device_index) == gamecontrollerlist->joystick->instance_id ) {
                gamecontroller = gamecontrollerlist;
                ++gamecontroller->ref_count;
                return (gamecontroller);
        }
        gamecontrollerlist = gamecontrollerlist->next;
    }

    /* Find a controller mapping */
    pSupportedController =  SDL_PrivateGetControllerMapping(device_index);
    if ( !pSupportedController ) {
        SDL_SetError("Couldn't find mapping for device (%d)", device_index );
        return (NULL);
    }

    /* Create and initialize the joystick */
    gamecontroller = (SDL_GameController *) SDL_malloc((sizeof *gamecontroller));
    if (gamecontroller == NULL) {
        SDL_OutOfMemory();
        return NULL;
    }

    SDL_memset(gamecontroller, 0, (sizeof *gamecontroller));
    gamecontroller->joystick = SDL_JoystickOpen(device_index);
    if ( !gamecontroller->joystick ) {
        SDL_free(gamecontroller);
        return NULL;
    }

    SDL_PrivateLoadButtonMapping( &gamecontroller->mapping, pSupportedController->guid, pSupportedController->name, pSupportedController->mapping );

    /* Add joystick to list */
    ++gamecontroller->ref_count;
    /* Link the joystick in the list */
    gamecontroller->next = SDL_gamecontrollers;
    SDL_gamecontrollers = gamecontroller;

    SDL_SYS_JoystickUpdate( gamecontroller->joystick );

    return (gamecontroller);
}

/*
 * Manually pump for controller updates.
 */
void
SDL_GameControllerUpdate(void)
{
    /* Just for API completeness; the joystick API does all the work. */
    SDL_JoystickUpdate();
}


/*
 * Get the current state of an axis control on a controller
 */
Sint16
SDL_GameControllerGetAxis(SDL_GameController * gamecontroller, SDL_GameControllerAxis axis)
{
    if ( !gamecontroller )
        return 0;

    if (gamecontroller->mapping.axes[axis] >= 0 )
    {
        Sint16 value = ( SDL_JoystickGetAxis( gamecontroller->joystick, gamecontroller->mapping.axes[axis]) );
        switch (axis)
        {
            case SDL_CONTROLLER_AXIS_TRIGGERLEFT:
            case SDL_CONTROLLER_AXIS_TRIGGERRIGHT:
                /* Shift it to be 0 - 32767. */
                value = value / 2 + 16384;
            default:
                break;
        }
        return value;
    }
    else if (gamecontroller->mapping.buttonasaxis[axis] >= 0 )
    {
        Uint8 value;
        value = SDL_JoystickGetButton( gamecontroller->joystick, gamecontroller->mapping.buttonasaxis[axis] );
        if ( value > 0 )
            return 32767;
        return 0;
    }
    return 0;
}


/*
 * Get the current state of a button on a controller
 */
Uint8
SDL_GameControllerGetButton(SDL_GameController * gamecontroller, SDL_GameControllerButton button)
{
    if ( !gamecontroller )
        return 0;

    if ( gamecontroller->mapping.buttons[button] >= 0 )
    {
        return ( SDL_JoystickGetButton( gamecontroller->joystick, gamecontroller->mapping.buttons[button] ) );
    }
    else if ( gamecontroller->mapping.axesasbutton[button] >= 0 )
    {
        Sint16 value;
        value = SDL_JoystickGetAxis( gamecontroller->joystick, gamecontroller->mapping.axesasbutton[button] );
        if ( ABS(value) > 32768/2 )
            return 1;
        return 0;
    }
    else if ( gamecontroller->mapping.hatasbutton[button].hat >= 0 )
    {
        Uint8 value;
        value = SDL_JoystickGetHat( gamecontroller->joystick, gamecontroller->mapping.hatasbutton[button].hat );

        if ( value & gamecontroller->mapping.hatasbutton[button].mask )
            return 1;
        return 0;
    }

    return 0;
}

/*
 * Return if the joystick in question is currently attached to the system,
 *  \return 0 if not plugged in, 1 if still present.
 */
SDL_bool
SDL_GameControllerGetAttached( SDL_GameController * gamecontroller )
{
    if ( !gamecontroller )
        return SDL_FALSE;

    return SDL_JoystickGetAttached(gamecontroller->joystick);
}


/*
 * Get the number of multi-dimensional axis controls on a joystick
 */
const char *
SDL_GameControllerName(SDL_GameController * gamecontroller)
{
    if ( !gamecontroller )
        return NULL;

    return (gamecontroller->mapping.name);
}


/*
 * Get the joystick for this controller
 */
SDL_Joystick *SDL_GameControllerGetJoystick(SDL_GameController * gamecontroller)
{
    if ( !gamecontroller )
        return NULL;

    return gamecontroller->joystick;
}

/**
 * Get the SDL joystick layer binding for this controller axis mapping
 */
SDL_GameControllerButtonBind SDL_GameControllerGetBindForAxis(SDL_GameController * gamecontroller, SDL_GameControllerAxis axis)
{
    SDL_GameControllerButtonBind bind;
    SDL_memset( &bind, 0x0, sizeof(bind) );

    if ( !gamecontroller || axis == SDL_CONTROLLER_AXIS_INVALID )
        return bind;

    if (gamecontroller->mapping.axes[axis] >= 0 )
    {
        bind.bindType = SDL_CONTROLLER_BINDTYPE_AXIS;
        bind.value.button = gamecontroller->mapping.axes[axis];
    }
    else if (gamecontroller->mapping.buttonasaxis[axis] >= 0 )
    {
        bind.bindType = SDL_CONTROLLER_BINDTYPE_BUTTON;
        bind.value.button = gamecontroller->mapping.buttonasaxis[axis];
    }

    return bind;
}


/**
 * Get the SDL joystick layer binding for this controller button mapping
 */
SDL_GameControllerButtonBind SDL_GameControllerGetBindForButton(SDL_GameController * gamecontroller, SDL_GameControllerButton button)
{
    SDL_GameControllerButtonBind bind;
    SDL_memset( &bind, 0x0, sizeof(bind) );

    if ( !gamecontroller || button == SDL_CONTROLLER_BUTTON_INVALID )
        return bind;

    if ( gamecontroller->mapping.buttons[button] >= 0 )
    {
        bind.bindType = SDL_CONTROLLER_BINDTYPE_BUTTON;
        bind.value.button = gamecontroller->mapping.buttons[button];
    }
    else if ( gamecontroller->mapping.axesasbutton[button] >= 0 )
    {
        bind.bindType = SDL_CONTROLLER_BINDTYPE_AXIS;
        bind.value.axis = gamecontroller->mapping.axesasbutton[button];
    }
    else if ( gamecontroller->mapping.hatasbutton[button].hat >= 0 )
    {
        bind.bindType = SDL_CONTROLLER_BINDTYPE_HAT;
        bind.value.hat.hat = gamecontroller->mapping.hatasbutton[button].hat;
        bind.value.hat.hat_mask = gamecontroller->mapping.hatasbutton[button].mask;
    }

    return bind;
}


/*
 * Close a joystick previously opened with SDL_JoystickOpen()
 */
void
SDL_GameControllerClose(SDL_GameController * gamecontroller)
{
    SDL_GameController *gamecontrollerlist, *gamecontrollerlistprev;

    if ( !gamecontroller )
        return;

    /* First decrement ref count */
    if (--gamecontroller->ref_count > 0) {
        return;
    }

    SDL_JoystickClose( gamecontroller->joystick );

    gamecontrollerlist = SDL_gamecontrollers;
    gamecontrollerlistprev = NULL;
    while ( gamecontrollerlist )
    {
        if (gamecontroller == gamecontrollerlist)
        {
            if ( gamecontrollerlistprev )
            {
                /* unlink this entry */
                gamecontrollerlistprev->next = gamecontrollerlist->next;
            }
            else
            {
                SDL_gamecontrollers = gamecontroller->next;
            }

            break;
        }
        gamecontrollerlistprev = gamecontrollerlist;
        gamecontrollerlist = gamecontrollerlist->next;
    }

    SDL_free(gamecontroller);
}


/*
 * Quit the controller subsystem
 */
void
SDL_GameControllerQuit(void)
{
    ControllerMapping_t *pControllerMap;
    while ( SDL_gamecontrollers )
    {
        SDL_gamecontrollers->ref_count = 1;
        SDL_GameControllerClose(SDL_gamecontrollers);
    }

    while ( s_pSupportedControllers )
    {
        pControllerMap = s_pSupportedControllers;
        s_pSupportedControllers = s_pSupportedControllers->next;
        SDL_free( pControllerMap->name );
        SDL_free( pControllerMap->mapping );
        SDL_free( pControllerMap );
    }

    SDL_DelEventWatch( SDL_GameControllerEventWatcher, NULL );

}

/*
 * Event filter to transform joystick events into appropriate game controller ones
 */
int
SDL_PrivateGameControllerAxis(SDL_GameController * gamecontroller, SDL_GameControllerAxis axis, Sint16 value)
{
    int posted;

    /* translate the event, if desired */
    posted = 0;
#if !SDL_EVENTS_DISABLED
    if (SDL_GetEventState(SDL_CONTROLLERAXISMOTION) == SDL_ENABLE) {
        SDL_Event event;
        event.type = SDL_CONTROLLERAXISMOTION;
        event.caxis.which = gamecontroller->joystick->instance_id;
        event.caxis.axis = axis;
        event.caxis.value = value;
        posted = SDL_PushEvent(&event) == 1;
    }
#endif /* !SDL_EVENTS_DISABLED */
    return (posted);
}


/*
 * Event filter to transform joystick events into appropriate game controller ones
 */
int
SDL_PrivateGameControllerButton(SDL_GameController * gamecontroller, SDL_GameControllerButton button, Uint8 state)
{
    int posted;
#if !SDL_EVENTS_DISABLED
    SDL_Event event;

    if ( button == SDL_CONTROLLER_BUTTON_INVALID )
        return (0);

    switch (state) {
    case SDL_PRESSED:
        event.type = SDL_CONTROLLERBUTTONDOWN;
        break;
    case SDL_RELEASED:
        event.type = SDL_CONTROLLERBUTTONUP;
        break;
    default:
        /* Invalid state -- bail */
        return (0);
    }
#endif /* !SDL_EVENTS_DISABLED */

    /* translate the event, if desired */
    posted = 0;
#if !SDL_EVENTS_DISABLED
    if (SDL_GetEventState(event.type) == SDL_ENABLE) {
        event.cbutton.which = gamecontroller->joystick->instance_id;
        event.cbutton.button = button;
        event.cbutton.state = state;
        posted = SDL_PushEvent(&event) == 1;
    }
#endif /* !SDL_EVENTS_DISABLED */
    return (posted);
}

/*
 * Turn off controller events
 */
int
SDL_GameControllerEventState(int state)
{
#if SDL_EVENTS_DISABLED
    return SDL_IGNORE;
#else
    const Uint32 event_list[] = {
        SDL_CONTROLLERAXISMOTION, SDL_CONTROLLERBUTTONDOWN, SDL_CONTROLLERBUTTONUP,
        SDL_CONTROLLERDEVICEADDED, SDL_CONTROLLERDEVICEREMOVED, SDL_CONTROLLERDEVICEREMAPPED,
    };
    unsigned int i;

    switch (state) {
    case SDL_QUERY:
        state = SDL_IGNORE;
        for (i = 0; i < SDL_arraysize(event_list); ++i) {
            state = SDL_EventState(event_list[i], SDL_QUERY);
            if (state == SDL_ENABLE) {
                break;
            }
        }
        break;
    default:
        for (i = 0; i < SDL_arraysize(event_list); ++i) {
            SDL_EventState(event_list[i], state);
        }
        break;
    }
    return (state);
#endif /* SDL_EVENTS_DISABLED */
}

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