#include <GLFW/glfw3.h>
#include <imgui/imgui.h>
#include <app.h>
#include <window.h>
#include "levelEditor.h"
#include "editor.h"

namespace editor {

void LevelEditor::UpdateTimeline()
{
    ImGui::SetNextWindowPos(ImVec2{0, 480}, ImGuiCond_Always);
    ImGui::Begin("editor", nullptr, {1280, 224}, 0, ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_MenuBar);

    if (ImGui::BeginMenuBar()) {

        if (this->musicPlaying) {
            if (ImGui::Button("Stop")) {
                this->StopRealTimeRecord();
            }
        } else if (ImGui::Button("Play music")) {
            this->StartMusic(songPosition);
        }

        /*if (ImGui::BeginMenu("Test", !this->musicPlaying)) {
            ImGui::MenuItem("From start");
            ImGui::MenuItem("From current position");

            ImGui::EndMenu();
        }*/

        if (ImGui::BeginMenu("Add note", !this->musicPlaying)) {
            if (ImGui::MenuItem("Manual insert")) {
                InsertDefaultNote(songPosition);
            }

            if (ImGui::BeginMenu("Real time input", !recorder->recording)) {
                if (ImGui::MenuItem("From start")) {
                    StartRealTimeRecord(0.5);
                }
                if (ImGui::MenuItem("From current position")) {
                    StartRealTimeRecord(songPosition);
                }
                ImGui::EndMenu();
            }

            ImGui::EndMenu();
        }

        //ImGui::Button("Add text");

        ImGui::EndMenuBar();
    }

    if (ImGui::SliderFloat("##time-slider", &songPosition, 0.5, songLength)) {
        songPosition -= fmod(songPosition, 0.1);
        this->SeekMusic(songPosition);
    }
    ImGui::SameLine();
    ImGui::SetNextItemWidth(320);
    if (ImGui::InputFloat("##time-input", &songPosition, 0.1, 1, 2)) {
        songPosition = clamp(songPosition, 0.5f, songLength);
        this->SeekMusic(songPosition);
    }

    ImGui::End();
}

void LevelEditor::RenderTimeline()
{
    constexpr float sizeOfSecond = 40 / timelineZoom;
    constexpr float halfTime = timelineZoom / 2;


    float timelineOffset = 0;

    if (songPosition > halfTime) {
        timelineOffset = -fmod(songPosition - halfTime, 1);
    }

    render::primitives2d::quad({0, 15}, {40, 7}, color::uint2rgba(0x0e0e0e));
    render::primitives2d::quad({0, 18.7}, {40, 3.3}, color::uint2rgba(0xc0cbdc));

    for (int i = 0; i < timelineZoom + 1; i++) {
        render::primitives2d::quad({(timelineOffset + i) * sizeOfSecond, 18.7}, {0.05, 3.3}, color::uint2rgba(0x8b9bb4));
    }

    if (songPosition < halfTime) {
        timelineOffset = songPosition / halfTime;
        render::primitives2d::quad({timelineOffset * 20, 18.7}, {0.1, 3.3}, color::red);
    } else {
        render::primitives2d::quad({19.95, 18.7}, {0.1, 3.3}, color::red);
    }

    float noteRenderOffset = 0;

    if (songPosition > halfTime) {
        noteRenderOffset = songPosition - halfTime;
    }

    auto renderNote = [noteRenderOffset, sizeOfSecond, this](const game::noteInfo *i, bool shadow) {
        float x = i->time - noteRenderOffset;
        vec4f noteColor;

        render::sprite::icon *noteIcon = &buttonIcons[i->type == 2][i->button];

        if (i == (*activeNote)) {
            noteIcon->scale = 1.5;
        } else {
            noteIcon->scale = 1;
        }

        if (shadow) {
            noteIcon->color = color::gray;
            longIcon.color = color::gray;
        } else {
            noteIcon->color = noteColors[i->button];
            longIcon.color = noteColors[i->button];
        }

        if (i->type == 1) {
            if (i->duration > 0) {
                longIcon.scale.x = i->duration * sizeOfSecond;
            } else {
                longIcon.scale.x = (songPosition - i->time) * sizeOfSecond;
            }

            longIcon.draw({x * sizeOfSecond, 21.4});
        }

        noteIcon->draw({x * sizeOfSecond, 21.4});

        if (i->type == 1 && i->duration > 0) {
            noteIcon->draw({(x + i->duration) * sizeOfSecond, 21.4});
        }

    };

    for (game::noteInfo *i: notesOnScreen) {
        renderNote(i, recorder->recording);
    }

    if (recorder->recording) {
        for (game::noteInfo *i: recorder->recordedNotes) {
            if ((i->type == 1 && i->duration == 0) || i->getEndTime() + halfTime > songPosition) {
                renderNote(i, false);
            }
        }
    }

    render::primitives2d::quad({0, 19.7}, {40, 0.1}, color::black);
    render::primitives2d::quad({0, 20.8}, {40, 0.1}, color::black);
}

}

