/*
  Copyright (C) 1997-2023 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 joystick hotplugging */

#include <stdlib.h>

#include <SDL3/SDL.h>
#include <SDL3/SDL_main.h>

int main(int argc, char *argv[])
{
    int num_joysticks = 0;
    SDL_Joystick *joystick = NULL;
    SDL_Haptic *haptic = NULL;
    SDL_JoystickID instance = 0;
    SDL_bool keepGoing = SDL_TRUE;
    int i;
    SDL_bool enable_haptic = SDL_TRUE;
    Uint32 init_subsystems = SDL_INIT_VIDEO | SDL_INIT_JOYSTICK;

    for (i = 1; i < argc; ++i) {
        if (SDL_strcasecmp(argv[i], "--nohaptic") == 0) {
            enable_haptic = SDL_FALSE;
        }
    }

    if (enable_haptic) {
        init_subsystems |= SDL_INIT_HAPTIC;
    }

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

    SDL_SetHint(SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS, "1");

    /* Initialize SDL (Note: video is required to start event loop) */
    if (SDL_Init(init_subsystems) < 0) {
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't initialize SDL: %s\n", SDL_GetError());
        exit(1);
    }

    /*
    //SDL_CreateWindow("Dummy", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 128, 128, 0);
    */

    SDL_free(SDL_GetJoysticks(&num_joysticks));
    SDL_Log("There are %d joysticks at startup\n", num_joysticks);
    if (enable_haptic) {
        SDL_Log("There are %d haptic devices at startup\n", SDL_NumHaptics());
    }

    while (keepGoing) {
        SDL_Event event;
        while (SDL_PollEvent(&event)) {
            switch (event.type) {
            case SDL_EVENT_QUIT:
                keepGoing = SDL_FALSE;
                break;
            case SDL_EVENT_JOYSTICK_ADDED:
                if (joystick != NULL) {
                    SDL_Log("Only one joystick supported by this test\n");
                } else {
                    joystick = SDL_OpenJoystick(event.jdevice.which);
                    instance = event.jdevice.which;
                    SDL_Log("Joy Added  : %" SDL_PRIu32 " : %s\n", event.jdevice.which, SDL_GetJoystickName(joystick));
                    if (enable_haptic) {
                        if (SDL_JoystickIsHaptic(joystick)) {
                            haptic = SDL_HapticOpenFromJoystick(joystick);
                            if (haptic) {
                                SDL_Log("Joy Haptic Opened\n");
                                if (SDL_HapticRumbleInit(haptic) != 0) {
                                    SDL_Log("Could not init Rumble!: %s\n", SDL_GetError());
                                    SDL_HapticClose(haptic);
                                    haptic = NULL;
                                }
                            } else {
                                SDL_Log("Joy haptic open FAILED!: %s\n", SDL_GetError());
                            }
                        } else {
                            SDL_Log("No haptic found\n");
                        }
                    }
                }
                break;
            case SDL_EVENT_JOYSTICK_REMOVED:
                if (instance == event.jdevice.which) {
                    SDL_Log("Joy Removed: %" SDL_PRIs32 "\n", event.jdevice.which);
                    instance = 0;
                    if (enable_haptic && haptic) {
                        SDL_HapticClose(haptic);
                        haptic = NULL;
                    }
                    SDL_CloseJoystick(joystick);
                    joystick = NULL;
                } else {
                    SDL_Log("Unknown joystick diconnected\n");
                }
                break;
            case SDL_EVENT_JOYSTICK_AXIS_MOTION:
                /*
                //                    SDL_Log("Axis Move: %d\n", event.jaxis.axis);
                */
                if (enable_haptic) {
                    SDL_HapticRumblePlay(haptic, 0.25, 250);
                }
                break;
            case SDL_EVENT_JOYSTICK_BUTTON_DOWN:
                SDL_Log("Button Press: %d\n", event.jbutton.button);
                if (enable_haptic && haptic) {
                    SDL_HapticRumblePlay(haptic, 0.25, 250);
                }
                if (event.jbutton.button == 0) {
                    SDL_Log("Exiting due to button press of button 0\n");
                    keepGoing = SDL_FALSE;
                }
                break;
            case SDL_EVENT_JOYSTICK_BUTTON_UP:
                SDL_Log("Button Release: %d\n", event.jbutton.button);
                break;
            }
        }
    }

    SDL_Quit();

    return 0;
}
