/*
	GameEngine and Editor
	by John Ryland
	Copyright (c) 2023
*/

////////////////////////////////////////////////////////////////////////////////////
//	NkWindow

#include "NkWindow.h"

#define WINDOW_WIDTH 1200
#define WINDOW_HEIGHT 800

static
void text_input(GLFWwindow *win, unsigned int codepoint)
{
    struct nk_context* ctx = (struct nk_context*)glfwGetWindowUserPointer(win);
    nk_input_unicode(ctx, codepoint);
}

static
void scroll_input(GLFWwindow *win, double xoff, double yoff)
{
    struct nk_context* ctx = (struct nk_context*)glfwGetWindowUserPointer(win);
    nk_input_scroll(ctx, nk_vec2((float)xoff, (float)yoff));
}

namespace GameEngine {

NkWindow::NkWindow()
{
    win = glfwCreateWindow(WINDOW_WIDTH, WINDOW_HEIGHT, "Demo", NULL, NULL);
    glfwMakeContextCurrent(win);
    glfwSetWindowUserPointer(win, &ctx);
    glfwSetCharCallback(win, text_input);
    glfwSetScrollCallback(win, scroll_input);
}

NkWindow::~NkWindow()
{
    nk_free(&ctx);
}

void NkWindow::GetSizes(int& width, int& height, int& display_width, int& display_height)
{
    glfwGetWindowSize(win, &width, &height);
    glfwGetFramebufferSize(win, &display_width, &display_height);
}

bool NkWindow::Update()
{
    double x, y;
    nk_input_begin(&ctx);
    glfwPollEvents();
    nk_input_key(&ctx, NK_KEY_DEL, glfwGetKey(win, GLFW_KEY_DELETE) == GLFW_PRESS);
    nk_input_key(&ctx, NK_KEY_ENTER, glfwGetKey(win, GLFW_KEY_ENTER) == GLFW_PRESS);
    nk_input_key(&ctx, NK_KEY_TAB, glfwGetKey(win, GLFW_KEY_TAB) == GLFW_PRESS);
    nk_input_key(&ctx, NK_KEY_BACKSPACE, glfwGetKey(win, GLFW_KEY_BACKSPACE) == GLFW_PRESS);
    nk_input_key(&ctx, NK_KEY_LEFT, glfwGetKey(win, GLFW_KEY_LEFT) == GLFW_PRESS);
    nk_input_key(&ctx, NK_KEY_RIGHT, glfwGetKey(win, GLFW_KEY_RIGHT) == GLFW_PRESS);
    nk_input_key(&ctx, NK_KEY_UP, glfwGetKey(win, GLFW_KEY_UP) == GLFW_PRESS);
    nk_input_key(&ctx, NK_KEY_DOWN, glfwGetKey(win, GLFW_KEY_DOWN) == GLFW_PRESS);
    if (glfwGetKey(win, GLFW_KEY_LEFT_CONTROL) == GLFW_PRESS ||
        glfwGetKey(win, GLFW_KEY_RIGHT_CONTROL) == GLFW_PRESS)
    {
        nk_input_key(&ctx, NK_KEY_COPY, glfwGetKey(win, GLFW_KEY_C) == GLFW_PRESS);
        nk_input_key(&ctx, NK_KEY_PASTE, glfwGetKey(win, GLFW_KEY_P) == GLFW_PRESS);
        nk_input_key(&ctx, NK_KEY_CUT, glfwGetKey(win, GLFW_KEY_X) == GLFW_PRESS);
        nk_input_key(&ctx, NK_KEY_CUT, glfwGetKey(win, GLFW_KEY_E) == GLFW_PRESS);
        nk_input_key(&ctx, NK_KEY_SHIFT, 1);
    } else {
        nk_input_key(&ctx, NK_KEY_COPY, 0);
        nk_input_key(&ctx, NK_KEY_PASTE, 0);
        nk_input_key(&ctx, NK_KEY_CUT, 0);
        nk_input_key(&ctx, NK_KEY_SHIFT, 0);
    }
    glfwGetCursorPos(win, &x, &y);
    nk_input_motion(&ctx, (int)x, (int)y);
    nk_input_button(&ctx, NK_BUTTON_LEFT, (int)x, (int)y, glfwGetMouseButton(win, GLFW_MOUSE_BUTTON_LEFT) == GLFW_PRESS);
    nk_input_button(&ctx, NK_BUTTON_MIDDLE, (int)x, (int)y, glfwGetMouseButton(win, GLFW_MOUSE_BUTTON_MIDDLE) == GLFW_PRESS);
    nk_input_button(&ctx, NK_BUTTON_RIGHT, (int)x, (int)y, glfwGetMouseButton(win, GLFW_MOUSE_BUTTON_RIGHT) == GLFW_PRESS);
    nk_input_end(&ctx);
    return !glfwWindowShouldClose(win);
}

void NkWindow::Present()
{
    glfwSwapBuffers(win);
}

struct nk_context* NkWindow::Context()
{
    return &ctx;
}

} // GameEngine namespace
