//
// Created by sfd on 25-4-17.
//

#include "WindowsWindow.h"

#include <iostream>
#include <Hazel/Core/Log.h>
#include <Platform/OpenGL/OpenGLContext.h>
#include <glad/glad.h>
#include <Hazel/Debug/Instrumentor.h>


namespace Hazel
{
    static bool s_SDLInitialized = false;

    WindowsWindow::WindowsWindow(const WindowProps& props)
    {
        HZ_PROFILE_FUNCTION();
        Init(props);
    }

    Scope<Window> Window::Create(const WindowProps& props) {
        return CreateScope<WindowsWindow>(props);
    }


    WindowsWindow::~WindowsWindow()
    {
        HZ_PROFILE_FUNCTION();
        Shutdown();
    }

    void WindowsWindow::Init(const WindowProps& props)
    {
        HZ_PROFILE_FUNCTION();
        m_Data.title = props.title;
        m_Data.width = props.width;
        m_Data.height = props.height;

        HZ_CORE_INFO("Creating window {0} ( {1}, {2})", props.title, props.width, props.height);

        if (!s_SDLInitialized)
        {
            if (!SDL_Init(SDL_INIT_VIDEO))
            {
                HZ_CORE_ERROR("Could not initialize SDL: {}", SDL_GetError());
                exit(EXIT_FAILURE);
            }


            s_SDLInitialized = true;
        }

        m_Window = SDL_CreateWindow(m_Data.title.c_str(), props.width, props.height, SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE);
        if (!m_Window)
        {
            HZ_CORE_ERROR("Could not create window: {}", SDL_GetError());
            exit(EXIT_FAILURE);
        }

        m_windowID = SDL_GetWindowID(m_Window);


        SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4);
        SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 6);
        SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);

        m_Context = new OpenGLContext(m_Window);
        m_Context->Init();

        HZ_CORE_INFO("Initing GLAD...");
        if (!gladLoadGLLoader(reinterpret_cast<GLADloadproc>(SDL_GL_GetProcAddress)))
        {
            HZ_CORE_ERROR("Could not initialize GLAD context!");
        }
        HZ_CORE_INFO("Init GLAD OK!");


        SetVSync(true);
    }

    void WindowsWindow::Shutdown()
    {
        HZ_PROFILE_FUNCTION();
        SDL_DestroyWindow(m_Window);
        SDL_Quit();
    }

    void WindowsWindow::OnUpdate()
    {
        HZ_PROFILE_FUNCTION();
        SDL_Event event;

        while (SDL_PollEvent(&event))
        {
            if (event.type == SDL_EVENT_WINDOW_RESIZED && event.window.windowID == m_windowID)
            {
                m_Data.width = event.window.data1;
                m_Data.height = event.window.data2;

                if (this->OnWindowResize != nullptr)
                {
                    OnWindowResize(event);
                }
            }
            if (m_Data.eventCallback != nullptr)
            {
                m_Data.eventCallback(event);
            }
        }

        m_Context->SwapBuffers();
    }

    void WindowsWindow::SetVSync(bool enabled)
    {
        HZ_PROFILE_FUNCTION();
        if (enabled)
        {
            SDL_GL_SetSwapInterval(enabled);
        }
        else
        {
            SDL_GL_SetSwapInterval(false);
        }

        m_Data.vSync = enabled;
    }

    bool WindowsWindow::IsVSync() const
    {
        return m_Data.vSync;
    }
}
