/*
  Copyright (C) 1997-2019 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.
*/

/* Simple program to test the SDL game controller routines */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "SDL.h"

#ifdef __EMSCRIPTEN__
#include <emscripten/emscripten.h>
#endif

#ifndef SDL_JOYSTICK_DISABLED

#ifdef __IPHONEOS__
#define SCREEN_WIDTH    480
#define SCREEN_HEIGHT    320
#else
#define SCREEN_WIDTH    512
#define SCREEN_HEIGHT   320
#endif

/* This is indexed by SDL_GameControllerButton. */
static const struct { int x; int y; } button_positions[] = {
    {387, 167},  /* A */
    {431, 132},  /* B */
    {342, 132},  /* X */
    {389, 101},  /* Y */
    {174, 132},  /* BACK */
    {233, 132},  /* GUIDE */
    {289, 132},  /* START */
    {75,  154},  /* LEFTSTICK */
    {305, 230},  /* RIGHTSTICK */
    {77,  40},   /* LEFTSHOULDER */
    {396, 36},   /* RIGHTSHOULDER */
    {154, 188},  /* DPAD_UP */
    {154, 249},  /* DPAD_DOWN */
    {116, 217},  /* DPAD_LEFT */
    {186, 217},  /* DPAD_RIGHT */
};

/* This is indexed by SDL_GameControllerAxis. */
static const struct { int x; int y; double angle; } axis_positions[] = {
    {74,  153, 270.0},  /* LEFTX */
    {74,  153, 0.0},  /* LEFTY */
    {306, 231, 270.0},  /* RIGHTX */
    {306, 231, 0.0},  /* RIGHTY */
    {91, -20, 0.0},     /* TRIGGERLEFT */
    {375, -20, 0.0},    /* TRIGGERRIGHT */
};

SDL_Renderer *screen = NULL;
SDL_bool retval = SDL_FALSE;
SDL_bool done = SDL_FALSE;
SDL_Texture *background, *button, *axis;

static SDL_Texture *
LoadTexture(SDL_Renderer *renderer, const char *file, SDL_bool transparent)
{
    SDL_Surface *temp = NULL;
    SDL_Texture *texture = NULL;

    temp = SDL_LoadBMP(file);
    if (temp == NULL) {
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't load %s: %s", file, SDL_GetError());
    } else {
        /* Set transparent pixel as the pixel at (0,0) */
        if (transparent) {
            if (temp->format->BytesPerPixel == 1) {
                SDL_SetColorKey(temp, SDL_TRUE, *(Uint8 *)temp->pixels);
            }
        }

        texture = SDL_CreateTextureFromSurface(renderer, temp);
        if (!texture) {
            SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create texture: %s\n", SDL_GetError());
        }
    }
    if (temp) {
        SDL_FreeSurface(temp);
    }
    return texture;
}

void
loop(void *arg)
{
    SDL_Event event;
    int i;
    SDL_GameController *gamecontroller = (SDL_GameController *)arg;

    /* blank screen, set up for drawing this frame. */
    SDL_SetRenderDrawColor(screen, 0xFF, 0xFF, 0xFF, SDL_ALPHA_OPAQUE);
    SDL_RenderClear(screen);
    SDL_RenderCopy(screen, background, NULL, NULL);

    while (SDL_PollEvent(&event)) {
        switch (event.type) {
        case SDL_CONTROLLERAXISMOTION:
            SDL_Log("Controller axis %s changed to %d\n", SDL_GameControllerGetStringForAxis((SDL_GameControllerAxis)event.caxis.axis), event.caxis.value);
            break;
        case SDL_CONTROLLERBUTTONDOWN:
        case SDL_CONTROLLERBUTTONUP:
            SDL_Log("Controller button %s %s\n", SDL_GameControllerGetStringForButton((SDL_GameControllerButton)event.cbutton.button), event.cbutton.state ? "pressed" : "released");
            /* First button triggers a 0.5 second full strength rumble */
            if (event.type == SDL_CONTROLLERBUTTONDOWN &&
                event.cbutton.button == SDL_CONTROLLER_BUTTON_A) {
                SDL_GameControllerRumble(gamecontroller, 0xFFFF, 0xFFFF, 500);
            }
            break;
        case SDL_KEYDOWN:
            if (event.key.keysym.sym != SDLK_ESCAPE) {
                break;
            }
            /* Fall through to signal quit */
        case SDL_QUIT:
            done = SDL_TRUE;
            break;
        default:
            break;
        }
    }

    /* Update visual controller state */
    for (i = 0; i < SDL_CONTROLLER_BUTTON_MAX; ++i) {
        if (SDL_GameControllerGetButton(gamecontroller, (SDL_GameControllerButton)i) == SDL_PRESSED) {
            const SDL_Rect dst = { button_positions[i].x, button_positions[i].y, 50, 50 };
            SDL_RenderCopyEx(screen, button, NULL, &dst, 0, NULL, SDL_FLIP_NONE);
        }
    }

    for (i = 0; i < SDL_CONTROLLER_AXIS_MAX; ++i) {
        const Sint16 deadzone = 8000;  /* !!! FIXME: real deadzone */
        const Sint16 value = SDL_GameControllerGetAxis(gamecontroller, (SDL_GameControllerAxis)(i));
        if (value < -deadzone) {
            const SDL_Rect dst = { axis_positions[i].x, axis_positions[i].y, 50, 50 };
            const double angle = axis_positions[i].angle;
            SDL_RenderCopyEx(screen, axis, NULL, &dst, angle, NULL, SDL_FLIP_NONE);
        } else if (value > deadzone) {
            const SDL_Rect dst = { axis_positions[i].x, axis_positions[i].y, 50, 50 };
            const double angle = axis_positions[i].angle + 180.0;
            SDL_RenderCopyEx(screen, axis, NULL, &dst, angle, NULL, SDL_FLIP_NONE);
        }
    }

    SDL_RenderPresent(screen);

    if (!SDL_GameControllerGetAttached(gamecontroller)) {
        done = SDL_TRUE;
        retval = SDL_TRUE;  /* keep going, wait for reattach. */
    }

#ifdef __EMSCRIPTEN__
    if (done) {
        emscripten_cancel_main_loop();
    }
#endif
}

SDL_bool
WatchGameController(SDL_GameController * gamecontroller)
{
    const char *name = SDL_GameControllerName(gamecontroller);
    const char *basetitle = "Game Controller Test: ";
    const size_t titlelen = SDL_strlen(basetitle) + SDL_strlen(name) + 1;
    char *title = (char *)SDL_malloc(titlelen);
    SDL_Window *window = NULL;

    retval = SDL_FALSE;
    done = SDL_FALSE;

    if (title) {
        SDL_snprintf(title, titlelen, "%s%s", basetitle, name);
    }

    /* Create a window to display controller state */
    window = SDL_CreateWindow(title, SDL_WINDOWPOS_CENTERED,
                              SDL_WINDOWPOS_CENTERED, SCREEN_WIDTH,
                              SCREEN_HEIGHT, 0);
    SDL_free(title);
    title = NULL;
    if (window == NULL) {
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create window: %s\n", SDL_GetError());
        return SDL_FALSE;
    }

    screen = SDL_CreateRenderer(window, -1, 0);
    if (screen == NULL) {
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create renderer: %s\n", SDL_GetError());
        SDL_DestroyWindow(window);
        return SDL_FALSE;
    }

    SDL_SetRenderDrawColor(screen, 0x00, 0x00, 0x00, SDL_ALPHA_OPAQUE);
    SDL_RenderClear(screen);
    SDL_RenderPresent(screen);
    SDL_RaiseWindow(window);

    /* scale for platforms that don't give you the window size you asked for. */
    SDL_RenderSetLogicalSize(screen, SCREEN_WIDTH, SCREEN_HEIGHT);

    background = LoadTexture(screen, "controllermap.bmp", SDL_FALSE);
    button = LoadTexture(screen, "button.bmp", SDL_TRUE);
    axis = LoadTexture(screen, "axis.bmp", SDL_TRUE);

    if (!background || !button || !axis) {
        SDL_DestroyRenderer(screen);
        SDL_DestroyWindow(window);
        return SDL_FALSE;
    }
    SDL_SetTextureColorMod(button, 10, 255, 21);
    SDL_SetTextureColorMod(axis, 10, 255, 21);

    /* !!! FIXME: */
    /*SDL_RenderSetLogicalSize(screen, background->w, background->h);*/

    /* Print info about the controller we are watching */
    SDL_Log("Watching controller %s\n",  name ? name : "Unknown Controller");

    /* Loop, getting controller events! */
#ifdef __EMSCRIPTEN__
    emscripten_set_main_loop_arg(loop, gamecontroller, 0, 1);
#else
    while (!done) {
        loop(gamecontroller);
    }
#endif

    SDL_DestroyRenderer(screen);
    screen = NULL;
    background = NULL;
    button = NULL;
    axis = NULL;
    SDL_DestroyWindow(window);
    return retval;
}

int
main(int argc, char *argv[])
{
    int i;
    int nController = 0;
    int retcode = 0;
    char guid[64];
    SDL_GameController *gamecontroller;

    /* Enable standard application logging */
    SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO);

    /* Initialize SDL (Note: video is required to start event loop) */
    if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER ) < 0) {
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't initialize SDL: %s\n", SDL_GetError());
        return 1;
    }
    
    SDL_GameControllerAddMappingsFromFile("gamecontrollerdb.txt");

    /* Print information about the mappings */
    if (!argv[1]) {
        SDL_Log("Supported mappings:\n");
        for (i = 0; i < SDL_GameControllerNumMappings(); ++i) {
            char *mapping = SDL_GameControllerMappingForIndex(i);
            if (mapping) {
                SDL_Log("\t%s\n", mapping);
                SDL_free(mapping);
            }
        }
        SDL_Log("\n");
    }

    /* Print information about the controller */
    for (i = 0; i < SDL_NumJoysticks(); ++i) {
        const char *name;
        const char *description;

        SDL_JoystickGetGUIDString(SDL_JoystickGetDeviceGUID(i),
                                  guid, sizeof (guid));

        if ( SDL_IsGameController(i) )
        {
            nController++;
            name = SDL_GameControllerNameForIndex(i);
            description = "Controller";
        } else {
            name = SDL_JoystickNameForIndex(i);
            description = "Joystick";
        }
        SDL_Log("%s %d: %s (guid %s, VID 0x%.4x, PID 0x%.4x)\n",
            description, i, name ? name : "Unknown", guid,
            SDL_JoystickGetDeviceVendor(i), SDL_JoystickGetDeviceProduct(i));
    }
    SDL_Log("There are %d game controller(s) attached (%d joystick(s))\n", nController, SDL_NumJoysticks());

    if (argv[1]) {
        SDL_bool reportederror = SDL_FALSE;
        SDL_bool keepGoing = SDL_TRUE;
        SDL_Event event;
        int device = atoi(argv[1]);
        if (device >= SDL_NumJoysticks()) {
            SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "%i is an invalid joystick index.\n", device);
            retcode = 1;
        } else {
            SDL_JoystickGetGUIDString(SDL_JoystickGetDeviceGUID(device),
                                      guid, sizeof (guid));
            SDL_Log("Attempting to open device %i, guid %s\n", device, guid);
            gamecontroller = SDL_GameControllerOpen(device);

            if (gamecontroller != NULL) {
                SDL_assert(SDL_GameControllerFromInstanceID(SDL_JoystickInstanceID(SDL_GameControllerGetJoystick(gamecontroller))) == gamecontroller);
            }

            while (keepGoing) {
                if (gamecontroller == NULL) {
                    if (!reportederror) {
                        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't open gamecontroller %d: %s\n", device, SDL_GetError());
                        retcode = 1;
                        keepGoing = SDL_FALSE;
                        reportederror = SDL_TRUE;
                    }
                } else {
                    reportederror = SDL_FALSE;
                    keepGoing = WatchGameController(gamecontroller);
                    SDL_GameControllerClose(gamecontroller);
                }

                gamecontroller = NULL;
                if (keepGoing) {
                    SDL_Log("Waiting for attach\n");
                }
                while (keepGoing) {
                    SDL_WaitEvent(&event);
                    if ((event.type == SDL_QUIT) || (event.type == SDL_FINGERDOWN)
                        || (event.type == SDL_MOUSEBUTTONDOWN)) {
                        keepGoing = SDL_FALSE;
                    } else if (event.type == SDL_CONTROLLERDEVICEADDED) {
                        gamecontroller = SDL_GameControllerOpen(event.cdevice.which);
                        if (gamecontroller != NULL) {
                            SDL_assert(SDL_GameControllerFromInstanceID(SDL_JoystickInstanceID(SDL_GameControllerGetJoystick(gamecontroller))) == gamecontroller);
                        }
                        break;
                    }
                }
            }
        }
    }

    SDL_QuitSubSystem(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER);

    return retcode;
}

#else

int
main(int argc, char *argv[])
{
    SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL compiled without Joystick support.\n");
    exit(1);
}

#endif

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