#include "jui.h"
#include "jdraw.h"
#include "jinput.h"
#include <string.h>
#include <SDL3/SDL.h>

namespace ui
{
    static int current_spin = -1;
    static int selected_spin = -1;
    static int hovering_spin = -1;

    void start()
    {
        current_spin = -1;
    }

    void label(const char *label, const int x, const int y, const int w, const int h, const int color)
    {
        draw::color(color);
        draw::fillrect(x, y, w, h);
        draw::color(WHITE);
        draw::rect(x, y, w, h);
        draw::print(label, x+3, y+3, BLACK, 0);
    }

    const bool button(const char *label, const int x, const int y, const int w, const int h, const bool pressed)
    {
        const int mx = draw::getLocalX(input::mouseX());
        const int my = draw::getLocalY(input::mouseY());
        const bool btnDown = input::mouseBtn(1) || input::mouseBtn(3);
        const bool inside = (mx>=x) && (mx<x+w) && (my>=y) && (my<y+h);
        const int txt_size = strlen(label)*4;
        const int txt_x = x+(w-txt_size)/2;

        draw::color(WHITE);
        draw::fillrect(x, y, w, h);

        draw::color((inside&&btnDown)||pressed?BLACK:LIGHT+WHITE);
        draw::hline(x, y, w);
        draw::vline(x, y, h);

        draw::color((inside&&btnDown)||pressed?LIGHT+WHITE:BLACK);
        draw::hline(x, y+h-1, w);
        draw::vline(x+w-1, y, h);

        draw::print(label, 1+txt_x, y+3, LIGHT+(pressed?YELLOW:WHITE), PAPER);

        if (inside)
        {
            if (input::mouseClk(1)) return true;
            //if (input::mouseClk(3)) return 3;
        }
        return false;
    }

    const int check(const char *label, const int x, const int y, const int w, const int h, const bool checked)
    {
        const int mx = draw::getLocalX(input::mouseX());
        const int my = draw::getLocalY(input::mouseY());
        const bool btnDown = input::mouseBtn(1) || input::mouseBtn(3);
        const bool inside = (mx>=x) && (mx<x+w) && (my>=y) && (my<y+h);
        const int txt_size = strlen(label)*4;
        const int txt_x = x+(w-txt_size)/2;
        const bool action = (inside&&btnDown)||checked;

        draw::color(WHITE);
        draw::fillrect(x, y, w, h);

        draw::color(action?BLACK:LIGHT+WHITE);
        draw::hline(x, y, w);
        draw::vline(x, y, h);

        draw::color(action?LIGHT+WHITE:BLACK);
        draw::hline(x, y+h-1, w);
        draw::vline(x+w-1, y, h);

        draw::print(label, 1+txt_x, y+3, action?LIGHT+WHITE:PAPER, action?PAPER:0);

        if (inside)
        {
            draw::color(PAPER);
            draw::rect(x+1, y+1, w-2, h-2);
            if (input::mouseClk(1)) return 1;
            if (input::mouseClk(3)) return 3;
        }
        return 0;
    }

    const int combo(const char *label, const int x, const int y, const int w, const int h)
    {
        const int mx = draw::getLocalX(input::mouseX());
        const int my = draw::getLocalY(input::mouseY());
        const bool btnDown = input::mouseBtn(1) || input::mouseBtn(3);
        const bool inside = (mx>=x) && (mx<x+w) && (my>=y) && (my<y+h);

        draw::color(LIGHT+WHITE);
        draw::fillrect(x, y, w, h);
        draw::color(WHITE);
        draw::rect(x, y, w, h);
        draw::vline(x+w-11,y+1,h-2);

        draw::print(label, x+3, y+3, PAPER, 0);

        draw::color(WHITE);
        draw::fillrect(x+w-10, y+1, 9, h-2);

        draw::color(inside&&btnDown?BLACK:LIGHT+WHITE);
        draw::hline(x+w-10,y+1,9);
        draw::vline(x+w-10,y+1,h-2);

        draw::color(inside&&btnDown?LIGHT+WHITE:BLACK);
        draw::hline(x+w-10,y+h-2,9);
        draw::vline(x+w-2,y+1,h-2);

        draw::print("v", x+w-7, y+2, PAPER, 0);

        if (inside)
        {
            draw::color(PAPER);
            draw::rect(x+1, y+1, w-11, h-2);
            if (input::mouseClk(1)) return 1;
            if (input::mouseClk(3)) return 3;
        }
        return 0;
    }

    char temp[10];

    const char *spin(const char *lbl, const int x, const int y, const int w, const int h)
    {
        current_spin++;
        const int mx = draw::getLocalX(input::mouseX());
        const int my = draw::getLocalY(input::mouseY());
        //const bool btnDown = input::mouseBtn(1) || input::mouseBtn(3);
        const bool inside = (mx>=x) && (mx<x+w) && (my>=y) && (my<y+h);
        if (inside && current_spin!=hovering_spin)
        {
            hovering_spin=current_spin;
            selected_spin=-1;
        }
        //const int txt_size = strlen(label)*4;
        //const int txt_x = x+(w-txt_size)/2;
        char label[100];
        if (current_spin!=selected_spin) {
            label[0]='0'; label[1]='\0';
        } else {
            strcpy(label, lbl);
        }

        draw::color(LIGHT+WHITE);
        draw::fillrect(x, y, w, h);
        draw::color(WHITE);
        draw::rect(x, y, w, h);
        draw::print(lbl, x+3, y+3, PAPER, 0);

        if (inside)
        {
            draw::color(PAPER);
            draw::rect(x+1, y+1, w-2, h-2);
            const uint8_t key = input::getKeyPressed();
            if (key==SDL_SCANCODE_BACKSPACE) {
                selected_spin=current_spin;
                strcpy(temp, label); const int size = strlen(label);
                temp[size-1] = '\0';
                return temp;
            } else if (key==SDL_SCANCODE_0 || key==SDL_SCANCODE_KP_0) {
                selected_spin=current_spin;
                strcpy(temp, label); const int size = strlen(label);
                temp[size] = '0'; temp[size+1] = '\0';
                return temp;
            } else if ( (key>=SDL_SCANCODE_1 && key<=SDL_SCANCODE_9) || (key>=SDL_SCANCODE_KP_1 && key<=SDL_SCANCODE_KP_9) ) {
                selected_spin=current_spin;
                strcpy(temp, label); const int size = strlen(label);
                temp[size] = key<40 ? key+19 : key-40; temp[size+1] = '\0';
                return temp;
            }
            const int wheel = input::mouseWheel();
            if (wheel != 0) {
                selected_spin=current_spin;
                const int value = SDL_atoi(lbl)+wheel*(input::keyDown(SDL_SCANCODE_LCTRL)?32:1);
                SDL_itoa(value, temp, 10);
                return temp;
            }
            //if (input::mouseClk(1)) return 1;
            //if (input::mouseClk(3)) return 3;
        }
        return nullptr;
    }


    const int textbox(const char *label, const int x, const int y, const int w, const int h)
    {
        const int mx = draw::getLocalX(input::mouseX());
        const int my = draw::getLocalY(input::mouseY());
        const bool inside = (mx>=x) && (mx<x+w) && (my>=y) && (my<y+h);

        draw::color(LIGHT+WHITE);
        draw::fillrect(x, y, w, h);
        draw::color(WHITE);
        draw::rect(x, y, w, h);
        draw::print(label, x+3, y+3, BLACK, 0);

        if (inside)
        {
            draw::color(PAPER);
            draw::rect(x+1, y+1, w-2, h-2);
            return input::getKeyPressed();
        }
        return 0;
    }
}
