#include <imgui/imgui.h>
#include <GLFW/glfw3.h>
#include <app.h>
#include <window.h>
#include <common.h>
#include <render/primitives.h>
#include <tinyxml2.h>
#include <game/game.h>
#include "editor.h"
#include "noteRecorder.h"
#include "levelEditor.h"

namespace editor {

Editor::Editor()
{
    LoadLevelList();
    levelEditor = nullptr;

    camera = new render::camera2D();
    camera->screenSize = vec2f(40, 22);
}

Editor::~Editor()
{
    if (levelEditor) {
        delete levelEditor;
    }

    delete camera;
}

void Editor::Update()
{
    if (levelEditor) {
        levelEditor->Update();

        if (levelEditor->ShouldClose()) {
            delete levelEditor;
            levelEditor = nullptr;
            LoadLevelList();
        }

        return;
    }

    ImGui::SetNextWindowPos({0, 0}, ImGuiCond_Always);
    ImGui::Begin("Choose level to edit", nullptr, {1280, 704}, 1, ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_MenuBar | ImGuiWindowFlags_NoCollapse);

    if (ImGui::BeginMenuBar()) {
        if (ImGui::Button("Reload list")) {
            LoadLevelList();
        }

        if (ImGui::Button("Back to game")) {
            game::SetState(game::gameState::stateMenu);
        }

        ImGui::EndMenuBar();
    }

    for (const auto &i: levelList) {
        if (ImGui::Button(i.name.c_str())) {
            LoadLevel(i);
            break;
        }
    }

    ImGui::End();
}

void Editor::Render()
{
    if (levelEditor) {
        render::bindShader(0);
        camera->bind();
        levelEditor->Render();
    }
}

void Editor::LoadLevelList()
{
    levelList.clear();

    tinyxml2::XMLDocument doc;
    doc.LoadFile("data/level.xml");

    tinyxml2::XMLElement *el = doc.RootElement()->FirstChildElement();

    do {
        game::levelInfo temp;

        temp.name = el->Attribute("name");
        temp.notesFile = el->Attribute("notes");
        temp.musicFile = el->Attribute("bgm");
        temp.backgroundFile = el->Attribute("bgi");
        temp.speed = el->FloatAttribute("speed");

        levelList.push_back(std::move(temp));

    } while ((el = el->NextSiblingElement()));
}

void Editor::LoadLevel(const game::levelInfo &info)
{
    levelEditor = new LevelEditor(info, this);
}

void Editor::Show()
{
    window::setSize({1280, 704});
    render::viewport({1280, 704}, {0, 0});
}

void Editor::Hide()
{
    window::setSize({960, 544});
    render::viewport({960, 544}, {0, 0});
}

}
