
#include "BaseWindow.h"
#include <imfilebrowser.h>

#include <iostream>

void window_resize_callback(GLFWwindow *window, int width, int height)
{
    glViewport(0, 0, width, height);
}

BaseWindow::BaseWindow(int width, int height, const char *title, Color clear_color, Audio audio_handler)
    : m_window_height(height),
      m_window_width(width),
      m_window_title(title),
      m_clear_color(clear_color),
      m_audio_handler(audio_handler) {}

BaseWindow::~BaseWindow()
{
    glfwTerminate();
}

int BaseWindow::run()
{
    glfwInit();

    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
    glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);

    m_window = glfwCreateWindow(m_window_width, m_window_height, m_window_title, NULL, NULL);
    if (m_window == NULL)
    {
        std::cout << "could not intialize GLFW Window"
                  << "\n";
        glfwTerminate();
        return -1;
    }

    glfwMakeContextCurrent(m_window);

    if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
    {
        std::cout << "Failed to initialize GLAD" << std::endl;
        return -1;
    }

    glfwSetFramebufferSizeCallback(m_window, window_resize_callback);
    IMGUI_CHECKVERSION();
    ImGui::CreateContext();
    ImGuiIO &io = ImGui::GetIO();
    (void)io;
    ImGui::StyleColorsDark();
    ImGui_ImplGlfw_InitForOpenGL(m_window, true);
    ImGui_ImplOpenGL3_Init("#version 330");

    ImGui::FileBrowser fileDialog;
    fileDialog.SetTitle("title");
    fileDialog.SetTypeFilters({".mp3"});

    // Main game loop
    while (!glfwWindowShouldClose(m_window))
    {

        // Create new imgui frames
        ImGui_ImplOpenGL3_NewFrame();
        ImGui_ImplGlfw_NewFrame();
        ImGui::NewFrame();

        // Draw IMGUI
        ImGui::Begin("Hello!");
        {
            static int clicked = 0;
            if (ImGui::Button("Add Music"))
            {
                fileDialog.Open();
            }

            static std::filesystem::path selected;
            if (m_audio_handler.loaded_files().size() > 0)
            {
                if (ImGui::BeginListBox("##", ImVec2(-FLT_MIN, 5 * ImGui::GetTextLineHeightWithSpacing())))
                {

                    for (auto file : m_audio_handler.loaded_files())
                    {
                        bool is_selected = selected.compare(file);
                        if (ImGui::Selectable(file.string().c_str(), is_selected))
                        {
                            selected = file;
                            m_audio_handler.select_file(file);
                        }

                        if (is_selected)
                        {
                            ImGui::SetItemDefaultFocus();
                        }
                    }
                }
                ImGui::EndListBox();
            }
        }
        ImGui::End();
        fileDialog.Display();
        if (fileDialog.HasSelected())
        {
            m_audio_handler.load_file(fileDialog.GetSelected());
            m_audio_handler.select_file(fileDialog.GetSelected());
            fileDialog.ClearSelected();
        }

        ImGui::Begin("Player controls");
        {
            if (ImGui::Button("Play"))
            {
                m_audio_handler.play();
            }
            if (ImGui::Button("Stop"))
            {
                m_audio_handler.stop();
            }
        }
        ImGui::End();

        if (m_audio_handler.decoder().is_finished)
        {
            m_audio_handler.next_music();
        }

        ImGui::Render();

        glClearColor(m_clear_color.r, m_clear_color.g, m_clear_color.b, m_clear_color.a);
        glClear(GL_COLOR_BUFFER_BIT);
        ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
        glfwSwapBuffers(m_window);
        glfwPollEvents();
    }

    // Unload and destroy
    ImGui_ImplOpenGL3_Shutdown();
    ImGui_ImplGlfw_Shutdown();
    ImGui::DestroyContext();
    glfwDestroyWindow(m_window);
    glfwTerminate();
    return 0;
}
