/*
  Copyright (C) 1997-2024 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:  Loop, watching keystrokes
   Note that you need to call SDL_PollEvent() or SDL_WaitEvent() to
   pump the event loop and catch keystrokes.
*/

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

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

#include "SDL.h"
#include "SDL_test_font.h"

static SDL_Window *window;
static SDL_Renderer *renderer;
static SDLTest_TextWindow *textwin;
static int done;

/* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */
static void
quit(int rc)
{
    SDL_Quit();
    exit(rc);
}

static void
print_string(char **text, size_t *maxlen, const char *fmt, ...)
{
    int len;
    va_list ap;

    va_start(ap, fmt);
    len = SDL_vsnprintf(*text, *maxlen, fmt, ap);
    if (len > 0) {
        *text += len;
        if (((size_t)len) < *maxlen) {
            *maxlen -= (size_t)len;
        } else {
            *maxlen = 0;
        }
    }
    va_end(ap);
}

static void
print_modifiers(char **text, size_t *maxlen)
{
    int mod;
    print_string(text, maxlen, " modifiers:");
    mod = SDL_GetModState();
    if (!mod) {
        print_string(text, maxlen, " (none)");
        return;
    }
    if (mod & KMOD_LSHIFT) {
        print_string(text, maxlen, " LSHIFT");
    }
    if (mod & KMOD_RSHIFT) {
        print_string(text, maxlen, " RSHIFT");
    }
    if (mod & KMOD_LCTRL) {
        print_string(text, maxlen, " LCTRL");
    }
    if (mod & KMOD_RCTRL) {
        print_string(text, maxlen, " RCTRL");
    }
    if (mod & KMOD_LALT) {
        print_string(text, maxlen, " LALT");
    }
    if (mod & KMOD_RALT) {
        print_string(text, maxlen, " RALT");
    }
    if (mod & KMOD_LGUI) {
        print_string(text, maxlen, " LGUI");
    }
    if (mod & KMOD_RGUI) {
        print_string(text, maxlen, " RGUI");
    }
    if (mod & KMOD_NUM) {
        print_string(text, maxlen, " NUM");
    }
    if (mod & KMOD_CAPS) {
        print_string(text, maxlen, " CAPS");
    }
    if (mod & KMOD_MODE) {
        print_string(text, maxlen, " MODE");
    }
    if (mod & KMOD_SCROLL) {
        print_string(text, maxlen, " SCROLL");
    }
}

static void
PrintModifierState(void)
{
    char message[512];
    char *spot;
    size_t left;

    spot = message;
    left = sizeof(message);

    print_modifiers(&spot, &left);
    SDL_Log("Initial state:%s\n", message);
}

static void
PrintKey(SDL_Keysym *sym, SDL_bool pressed, SDL_bool repeat)
{
    char message[512];
    char *spot;
    size_t left;

    spot = message;
    left = sizeof(message);

    /* Print the keycode, name and state */
    if (sym->sym) {
        print_string(&spot, &left,
                     "Key %s:  scancode %d = %s, keycode 0x%08X = %s ",
                     pressed ? "pressed " : "released",
                     sym->scancode,
                     SDL_GetScancodeName(sym->scancode),
                     sym->sym, SDL_GetKeyName(sym->sym));
    } else {
        print_string(&spot, &left,
                     "Unknown Key (scancode %d = %s) %s ",
                     sym->scancode,
                     SDL_GetScancodeName(sym->scancode),
                     pressed ? "pressed " : "released");
    }
    print_modifiers(&spot, &left);
    if (repeat) {
        print_string(&spot, &left, " (repeat)");
    }
    SDL_Log("%s\n", message);
}

static void
PrintText(const char *eventtype, const char *text)
{
    const char *spot;
    char expanded[1024];

    expanded[0] = '\0';
    for (spot = text; *spot; ++spot) {
        size_t length = SDL_strlen(expanded);
        (void)SDL_snprintf(expanded + length, sizeof(expanded) - length, "\\x%.2x", (unsigned char)*spot);
    }
    SDL_Log("%s Text (%s): \"%s%s\"\n", eventtype, expanded, *text == '"' ? "\\" : "", text);
}

void loop(void)
{
    SDL_Event event;
    /* Check for events */
    /*SDL_WaitEvent(&event); emscripten does not like waiting*/

    while (SDL_PollEvent(&event)) {
        switch (event.type) {
        case SDL_KEYDOWN:
        case SDL_KEYUP:
            PrintKey(&event.key.keysym, (event.key.state == SDL_PRESSED) ? SDL_TRUE : SDL_FALSE, (event.key.repeat) ? SDL_TRUE : SDL_FALSE);
            if (event.type == SDL_KEYDOWN) {
                switch (event.key.keysym.sym) {
                case SDLK_BACKSPACE:
                    SDLTest_TextWindowAddText(textwin, "\b");
                    break;
                case SDLK_RETURN:
                    SDLTest_TextWindowAddText(textwin, "\n");
                    break;
                default:
                    break;
                }
            }
            break;
        case SDL_TEXTEDITING:
            PrintText("EDIT", event.edit.text);
            break;
        case SDL_TEXTEDITING_EXT:
            PrintText("EDIT_EXT", event.editExt.text);
            SDL_free(event.editExt.text);
            break;
        case SDL_TEXTINPUT:
            PrintText("INPUT", event.text.text);
            SDLTest_TextWindowAddText(textwin, "%s", event.text.text);
            break;
        case SDL_FINGERDOWN:
            if (SDL_IsTextInputActive()) {
                SDL_Log("Stopping text input\n");
                SDL_StopTextInput();
            } else {
                SDL_Log("Starting text input\n");
                SDL_StartTextInput();
            }
            break;
        case SDL_MOUSEBUTTONDOWN:
            /* Left button quits the app, other buttons toggles text input */
            if (event.button.button == SDL_BUTTON_LEFT) {
                done = 1;
            } else {
                if (SDL_IsTextInputActive()) {
                    SDL_Log("Stopping text input\n");
                    SDL_StopTextInput();
                } else {
                    SDL_Log("Starting text input\n");
                    SDL_StartTextInput();
                }
            }
            break;
        case SDL_QUIT:
            done = 1;
            break;
        default:
            break;
        }
    }

    SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
    SDL_RenderClear(renderer);
    SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
    SDLTest_TextWindowDisplay(textwin, renderer);
    SDL_RenderPresent(renderer);

    /* Slow down framerate */
    SDL_Delay(100);

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

int main(int argc, char *argv[])
{
    /* Enable standard application logging */
    SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO);

    /* Disable mouse emulation */
    SDL_SetHint(SDL_HINT_TOUCH_MOUSE_EVENTS, "0");

    /* Enable extended text editing events */
    SDL_SetHint(SDL_HINT_IME_SUPPORT_EXTENDED_TEXT, "1");

    /* Initialize SDL */
    if (SDL_Init(SDL_INIT_VIDEO) < 0) {
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't initialize SDL: %s\n", SDL_GetError());
        return 1;
    }

    /* Set 640x480 video mode */
    window = SDL_CreateWindow("CheckKeys Test",
                              SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
                              640, 480, 0);
    if (!window) {
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create 640x480 window: %s\n",
                     SDL_GetError());
        quit(2);
    }

    renderer = SDL_CreateRenderer(window, -1, 0);
    if (!renderer) {
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create renderer: %s\n",
                     SDL_GetError());
        quit(2);
    }

    textwin = SDLTest_TextWindowCreate(0, 0, 640, 480);

#ifdef __IPHONEOS__
    /* Creating the context creates the view, which we need to show keyboard */
    SDL_GL_CreateContext(window);
#endif

    SDL_StartTextInput();

    /* Print initial modifier state */
    SDL_PumpEvents();
    PrintModifierState();

    /* Watch keystrokes */
    done = 0;

#ifdef __EMSCRIPTEN__
    emscripten_set_main_loop(loop, 0, 1);
#else
    while (!done) {
        loop();
    }
#endif

    SDL_Quit();
    return 0;
}

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