#include <SDL2/SDL.h>
#include <SDL2/SDL_gpu.h>
#include <cstring>

#include "fmt/format.h"

#include "engine/window.h"
#include "engine/util.h"

// Static member declarations
SDL_Window *Window::window = NULL;
GPU_Target *Window::windowTarget = NULL;
int Window::windowId = -1;
bool Window::isRunning = false;


Window::Window(int height, int width, std::string title)
{
    windowHeight = height;
    windowWidth = width;
    windowTitle = title;
}

bool Window::Init()
{
    // Initialization flag
    bool success = true;

    GPU_SetDebugLevel(GPU_DEBUG_LEVEL_MAX);

    // Initialize SDL
    if (SDL_Init(SDL_INIT_VIDEO) < 0)
    {
        Util::log(
                ERROR,
                fmt::format("[Error] Could not initialize SDL;\n\tSDL_Error: {}\n", SDL_GetError()),
                __FILE__,
                __LINE__
        );
        success = false;
    }
    else
    {
        // Create window
        Window::window = SDL_CreateWindow(
                Window::windowTitle.c_str(),
                SDL_WINDOWPOS_UNDEFINED,
                SDL_WINDOWPOS_UNDEFINED,
                windowWidth,
                windowHeight,
            SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL);

        if (Window::window == NULL)
        {
            Util::log(
                    ERROR,
                    fmt::format("Failed to create window;\n\tSDL_Error: {}\n", SDL_GetError()),
                    __FILE__,
                    __LINE__
            );
            success = false;
        }
        else
        {
            // Get window id and target window for GPU init
            Window::windowId = SDL_GetWindowID(Window::window);
            GPU_SetInitWindow(Window::windowId);
            windowTarget = GPU_Init(
                    windowWidth,
                    windowHeight,
                SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL | SDL_RENDERER_PRESENTVSYNC);

            // Set our running bool to true
            Window::isRunning = true;
        }
    }
    return success;
}


void Window::Close()
{
    // Deallocate any resources we have

    // Stop GPU usage and destroy window
    GPU_Quit();
    SDL_DestroyWindow(Window::window);

    //Quit SDL subsystems
    SDL_Quit();
}