/*
  Copyright (C) 1997-2026 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 <SDL3/SDL.h>
#include <SDL3/SDL_main.h>
#include <SDL3/SDL_test.h>

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

#define TEXT_WINDOW_OFFSET_X    2.0f
#define TEXT_WINDOW_OFFSET_Y    (2.0f + FONT_LINE_HEIGHT)

#define CURSOR_BLINK_INTERVAL_MS    500

typedef struct
{
    SDLTest_TextWindow *textwindow;
    char *edit_text;
    int edit_cursor;
    int edit_length;
} TextWindowState;

static SDLTest_CommonState *state;
static TextWindowState *windowstates;
static bool escape_pressed;
static bool cursor_visible;
static Uint64 last_cursor_change;
static int done;

static TextWindowState *GetTextWindowStateForWindowID(SDL_WindowID id)
{
    int i;

    for (i = 0; i < state->num_windows; ++i) {
        if (id == SDL_GetWindowID(state->windows[i])) {
            return &windowstates[i];
        }
    }
    return NULL;
}

static SDLTest_TextWindow *GetTextWindowForWindowID(SDL_WindowID id)
{
    TextWindowState *windowstate = GetTextWindowStateForWindowID(id);
    if (windowstate) {
        return windowstate->textwindow;
    }
    return NULL;
}

static void UpdateTextWindowInputRect(SDL_WindowID id)
{
    int i;

    for (i = 0; i < state->num_windows; ++i) {
        if (id == SDL_GetWindowID(state->windows[i])) {
            SDLTest_TextWindow *textwindow = windowstates[i].textwindow;
            int w, h;
            SDL_Rect rect;
            int cursor = 0;
            int current = textwindow->current;
            const char *current_line = textwindow->lines[current];

            SDL_GetWindowSize(state->windows[i], &w, &h);

            if (current_line) {
                cursor = (int)SDL_utf8strlen(current_line) * FONT_CHARACTER_SIZE;
            }

            rect.x = (int)TEXT_WINDOW_OFFSET_X;
            rect.y = (int)TEXT_WINDOW_OFFSET_Y + current * FONT_LINE_HEIGHT;
            rect.w = (int)(w - (2 * TEXT_WINDOW_OFFSET_X));
            rect.h = FONT_CHARACTER_SIZE;
            SDL_SetTextInputArea(state->windows[i], &rect, cursor);
            return;
        }
    }
}

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, SDL_Keymod mod)
{
    print_string(text, maxlen, " modifiers:");
    if (mod == SDL_KMOD_NONE) {
        print_string(text, maxlen, " (none)");
        return;
    }
    if ((mod & SDL_KMOD_SHIFT) == SDL_KMOD_SHIFT) {
        print_string(text, maxlen, " SHIFT");
    } else {
        if (mod & SDL_KMOD_LSHIFT) {
            print_string(text, maxlen, " LSHIFT");
        }
        if (mod & SDL_KMOD_RSHIFT) {
            print_string(text, maxlen, " RSHIFT");
        }
    }
    if ((mod & SDL_KMOD_CTRL) == SDL_KMOD_CTRL) {
        print_string(text, maxlen, " CTRL");
    } else {
        if (mod & SDL_KMOD_LCTRL) {
            print_string(text, maxlen, " LCTRL");
        }
        if (mod & SDL_KMOD_RCTRL) {
            print_string(text, maxlen, " RCTRL");
        }
    }
    if ((mod & SDL_KMOD_ALT) == SDL_KMOD_ALT) {
        print_string(text, maxlen, " ALT");
    } else {
        if (mod & SDL_KMOD_LALT) {
            print_string(text, maxlen, " LALT");
        }
        if (mod & SDL_KMOD_RALT) {
            print_string(text, maxlen, " RALT");
        }
    }
    if ((mod & SDL_KMOD_GUI) == SDL_KMOD_GUI) {
        print_string(text, maxlen, " GUI");
    } else {
        if (mod & SDL_KMOD_LGUI) {
            print_string(text, maxlen, " LGUI");
        }
        if (mod & SDL_KMOD_RGUI) {
            print_string(text, maxlen, " RGUI");
        }
    }
    if (mod & SDL_KMOD_NUM) {
        print_string(text, maxlen, " NUM");
    }
    if (mod & SDL_KMOD_CAPS) {
        print_string(text, maxlen, " CAPS");
    }
    if (mod & SDL_KMOD_MODE) {
        print_string(text, maxlen, " MODE");
    }
    if (mod & SDL_KMOD_LEVEL5) {
        print_string(text, maxlen, " LEVEL5");
    }
    if (mod & SDL_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_GetModState());
    SDL_Log("Initial state:%s", message);
}

static void PrintKey(SDL_KeyboardEvent *event)
{
    char message[512];
    char *spot;
    size_t left;

    spot = message;
    left = sizeof(message);

    /* Print the keycode, name and state */
    if (event->key) {
        print_string(&spot, &left,
                     "Key %s:  raw 0x%.2x, scancode %d = %s, keycode 0x%08X = %s ",
                     event->down ? "pressed " : "released",
                     event->raw,
                     event->scancode,
                     event->scancode == SDL_SCANCODE_UNKNOWN ? "UNKNOWN" : SDL_GetScancodeName(event->scancode),
                     event->key, SDL_GetKeyName(event->key));
    } else {
        print_string(&spot, &left,
                     "Unknown Key (raw 0x%.2x, scancode %d = %s) %s ",
                     event->raw,
                     event->scancode,
                     event->scancode == SDL_SCANCODE_UNKNOWN ? "UNKNOWN" : SDL_GetScancodeName(event->scancode),
                     event->down ? "pressed " : "released");
    }
    print_modifiers(&spot, &left, event->mod);
    if (event->repeat) {
        print_string(&spot, &left, " (repeat)");
    }
    SDL_Log("%s", 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\"", eventtype, expanded, *text == '"' ? "\\" : "", text);
}

static void CountKeysDown(void)
{
    int i, count = 0, max_keys = 0;
    const bool *keystate = SDL_GetKeyboardState(&max_keys);

    for (i = 0; i < max_keys; ++i) {
        if (keystate[i]) {
            ++count;
        }
    }
    SDL_Log("Keys down: %d", count);
}

static void DrawCursor(int i)
{
    SDL_FRect rect;
    TextWindowState *windowstate = &windowstates[i];
    SDLTest_TextWindow *textwindow = windowstate->textwindow;
    int current = textwindow->current;
    const char *current_line = textwindow->lines[current];

    rect.x = TEXT_WINDOW_OFFSET_X;
    if (current_line) {
        rect.x += SDL_utf8strlen(current_line) * FONT_CHARACTER_SIZE;
    }
    if (windowstate->edit_cursor > 0) {
        rect.x += (float)windowstate->edit_cursor * FONT_CHARACTER_SIZE;
    }
    rect.y = TEXT_WINDOW_OFFSET_Y + current * FONT_LINE_HEIGHT;
    rect.w = FONT_CHARACTER_SIZE * 0.75f;
    rect.h = (float)FONT_CHARACTER_SIZE;

    SDL_SetRenderDrawColor(state->renderers[i], 0xAA, 0xAA, 0xAA, 255);
    SDL_RenderFillRect(state->renderers[i], &rect);
}

static void DrawEditText(int i)
{
    SDL_FRect rect;
    TextWindowState *windowstate = &windowstates[i];
    SDLTest_TextWindow *textwindow = windowstate->textwindow;
    int current = textwindow->current;
    const char *current_line = textwindow->lines[current];

    if (windowstate->edit_text == NULL) {
        return;
    }

    /* Draw the highlight under the selected text */
    if (windowstate->edit_length > 0) {
        rect.x = TEXT_WINDOW_OFFSET_X;
        if (current_line) {
            rect.x += SDL_utf8strlen(current_line) * FONT_CHARACTER_SIZE;
        }
        if (windowstate->edit_cursor > 0) {
            rect.x += (float)windowstate->edit_cursor * FONT_CHARACTER_SIZE;
        }
        rect.y = TEXT_WINDOW_OFFSET_Y + current * FONT_LINE_HEIGHT;
        rect.w = (float)windowstate->edit_length * FONT_CHARACTER_SIZE;
        rect.h = (float)FONT_CHARACTER_SIZE;

        SDL_SetRenderDrawColor(state->renderers[i], 0xAA, 0xAA, 0xAA, 255);
        SDL_RenderFillRect(state->renderers[i], &rect);
    }

    /* Draw the edit text */
    rect.x = TEXT_WINDOW_OFFSET_X;
    if (current_line) {
        rect.x += SDL_utf8strlen(current_line) * FONT_CHARACTER_SIZE;
    }
    rect.y = TEXT_WINDOW_OFFSET_Y + current * FONT_LINE_HEIGHT;
    SDL_SetRenderDrawColor(state->renderers[i], 255, 255, 0, 255);
    SDLTest_DrawString(state->renderers[i], rect.x, rect.y, windowstate->edit_text);
}

static void loop(void)
{
    SDL_Event event;
    Uint64 now;
    int i;
    char line[1024];

    while (SDL_PollEvent(&event)) {
        switch (event.type) {
        case SDL_EVENT_KEY_DOWN:
        case SDL_EVENT_KEY_UP:
            PrintKey(&event.key);
            if (event.type == SDL_EVENT_KEY_DOWN) {
                switch (event.key.key) {
                case SDLK_BACKSPACE:
                    SDLTest_TextWindowAddText(GetTextWindowForWindowID(event.key.windowID), "\b");
                    UpdateTextWindowInputRect(event.key.windowID);
                    break;
                case SDLK_RETURN:
                    SDLTest_TextWindowAddText(GetTextWindowForWindowID(event.key.windowID), "\n");
                    UpdateTextWindowInputRect(event.key.windowID);
                    break;
                default:
                    break;
                }
                if (event.key.key == SDLK_ESCAPE) {
                    /* Pressing escape twice will stop the application */
                    if (escape_pressed) {
                        done = 1;
                    } else {
                        escape_pressed = true;
                    }
                } else {
                    escape_pressed = true;
                }
            }
            CountKeysDown();
            break;
        case SDL_EVENT_TEXT_EDITING:
        {
            TextWindowState *windowstate = GetTextWindowStateForWindowID(event.edit.windowID);
            if (windowstate->edit_text) {
                SDL_free(windowstate->edit_text);
                windowstate->edit_text = NULL;
            }
            if (event.edit.text && *event.edit.text) {
                windowstate->edit_text = SDL_strdup(event.edit.text);
            }
            windowstate->edit_cursor = event.edit.start;
            windowstate->edit_length = event.edit.length;

            SDL_snprintf(line, sizeof(line), "EDIT %" SDL_PRIs32 ":%" SDL_PRIs32, event.edit.start, event.edit.length);
            PrintText(line, event.edit.text);
            break;
        }
        case SDL_EVENT_TEXT_INPUT:
            PrintText("INPUT", event.text.text);
            SDLTest_TextWindowAddText(GetTextWindowForWindowID(event.text.windowID), "%s", event.text.text);
            UpdateTextWindowInputRect(event.text.windowID);
            break;
        case SDL_EVENT_FINGER_DOWN:
        {
            SDL_Window *window = SDL_GetWindowFromEvent(&event);
            if (SDL_TextInputActive(window)) {
                SDL_Log("Stopping text input for window %" SDL_PRIu32, event.tfinger.windowID);
                SDL_StopTextInput(window);
            } else {
                SDL_Log("Starting text input for window %" SDL_PRIu32, event.tfinger.windowID);
                SDL_StartTextInput(window);
            }
            break;
        }
        case SDL_EVENT_MOUSE_BUTTON_DOWN:
            if (event.button.button == SDL_BUTTON_RIGHT) {
                SDL_Window *window = SDL_GetWindowFromEvent(&event);
                if (SDL_TextInputActive(window)) {
                    SDL_Log("Stopping text input for window %" SDL_PRIu32, event.button.windowID);
                    SDL_StopTextInput(window);
                } else {
                    SDL_Log("Starting text input for window %" SDL_PRIu32, event.button.windowID);
                    SDL_StartTextInput(window);
                }
            }
            break;
        case SDL_EVENT_KEYMAP_CHANGED:
            SDL_Log("Keymap changed!");
            break;
        case SDL_EVENT_QUIT:
            done = 1;
            break;
        default:
            break;
        }
    }

    now = SDL_GetTicks();
    for (i = 0; i < state->num_windows; i++) {
        char caption[1024];

        /* Clear the window */
        SDL_SetRenderDrawColor(state->renderers[i], 0, 0, 0, 255);
        SDL_RenderClear(state->renderers[i]);

        /* Draw the text */
        SDL_SetRenderDrawColor(state->renderers[i], 255, 255, 255, 255);
        SDL_snprintf(caption, sizeof(caption), "Text input %s (click right mouse button to toggle)\n", SDL_TextInputActive(state->windows[i]) ? "enabled" : "disabled");
        SDLTest_DrawString(state->renderers[i], TEXT_WINDOW_OFFSET_X, TEXT_WINDOW_OFFSET_X, caption);
        SDLTest_TextWindowDisplay(windowstates[i].textwindow, state->renderers[i]);

        /* Draw the cursor */
        if ((now - last_cursor_change) >= CURSOR_BLINK_INTERVAL_MS) {
            cursor_visible = !cursor_visible;
            last_cursor_change = now;
        }
        if (cursor_visible) {
            DrawCursor(i);
        }

        /* Draw the composition text */
        DrawEditText(i);

        SDL_RenderPresent(state->renderers[i]);
    }

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

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

int main(int argc, char *argv[])
{
    int i;

    /* This is not necessary for text input handling, we just
     * want to verify that input works with raw keyboard enabled.
     */
    SDL_SetHint(SDL_HINT_WINDOWS_RAW_KEYBOARD, "1");

    /* Initialize test framework */
    state = SDLTest_CommonCreateState(argv, SDL_INIT_VIDEO);
    if (!state) {
        return 1;
    }
    state->window_title = "CheckKeys Test";

    /* Parse commandline */
    if (!SDLTest_CommonDefaultArgs(state, argc, argv)) {
        return 1;
    }

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

    /* Enable text editing events and tell SDL that we'll handle rendering compositions. */
    SDL_SetHint(SDL_HINT_IME_IMPLEMENTED_UI, "composition");

    /* Initialize SDL */
    if (!SDLTest_CommonInit(state)) {
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't initialize SDL: %s", SDL_GetError());
        return 1;
    }

    windowstates = (TextWindowState *)SDL_calloc(state->num_windows, sizeof(*windowstates));
    if (!windowstates) {
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't allocate text windows: %s", SDL_GetError());
        goto done;
    }

    for (i = 0; i < state->num_windows; ++i) {
        int w, h;
        SDL_FRect rect;

        SDL_GetWindowSize(state->windows[i], &w, &h);
        rect.x = TEXT_WINDOW_OFFSET_X;
        rect.y = TEXT_WINDOW_OFFSET_Y;
        rect.w = w - (2 * TEXT_WINDOW_OFFSET_X);
        rect.h = h - TEXT_WINDOW_OFFSET_Y;
        windowstates[i].textwindow = SDLTest_TextWindowCreate(rect.x, rect.y, rect.w, rect.h);
    }

#ifdef SDL_PLATFORM_IOS
    {
        /* Creating the context creates the view, which we need to show keyboard */
        for (i = 0; i < state->num_windows; i++) {
            SDL_GL_CreateContext(state->windows[i]);
        }
    }
#endif

    for (i = 0; i < state->num_windows; ++i) {
        UpdateTextWindowInputRect(SDL_GetWindowID(state->windows[i]));

        SDL_StartTextInput(state->windows[i]);
    }

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

    /* Watch keystrokes */
    done = 0;

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

done:
    if (windowstates) {
        for (i = 0; i < state->num_windows; ++i) {
            SDLTest_TextWindowDestroy(windowstates[i].textwindow);
        }
        SDL_free(windowstates);
    }
    SDLTest_CleanupTextDrawing();
    SDLTest_CommonQuit(state);
    return 0;
}
