#include "ConsolView.hpp"

TSE::EDITOR::ConsolView::ConsolView() : GuiWindow("Console", ImGuiWindowFlags_MenuBar | ImGuiWindowFlags_NoCollapse)
{
    Debug::AddCallback(CreateLogEntry);
    textbuffer[0] = '\0';
}

TSE::EDITOR::ConsolView::~ConsolView()
{
    delete[] textbuffer;
}

void TSE::EDITOR::ConsolView::MenuBar()
{
    if(ImGui::BeginMenuBar())
    {
        if(ImGui::MenuItem("Clear"))
        {
            entries.clear();
        }
        bool style = logs;
        if(style) ImGui::PushStyleColor(ImGuiCol_Text, {0,1,0,1});
        if(ImGui::MenuItem("Logs")) logs = !logs;
        if(style) ImGui::PopStyleColor();
        style = warnings;
        if(style) ImGui::PushStyleColor(ImGuiCol_Text, {0,1,0,1});
        if(ImGui::MenuItem("Warning")) warnings = !warnings;
        if(style) ImGui::PopStyleColor();
        style = errors;
        if(style) ImGui::PushStyleColor(ImGuiCol_Text, {0,1,0,1});
        if(ImGui::MenuItem("Errors")) errors = !errors;
        if(style) ImGui::PopStyleColor();
        style = autoScroll;
        if(style) ImGui::PushStyleColor(ImGuiCol_Text, {0,1,0,1});
        if(ImGui::MenuItem("Auto Scroll")) autoScroll = !autoScroll;
        if(style) ImGui::PopStyleColor();
    }
    ImGui::EndMenuBar();
}

void TSE::EDITOR::ConsolView::LogList()
{
    float footer_height_to_reserve = ImGui::GetStyle().ItemSpacing.y + ImGui::GetFrameHeightWithSpacing();
    if(ImGui::BeginChild("ScrollingRegion", {0, -footer_height_to_reserve}, ImGuiChildFlags_NavFlattened, ImGuiWindowFlags_HorizontalScrollbar))
    {
        ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, {4, 1});
        for(auto entry : entries)
        {
            switch (entry.type)
            {
                case LogEntryType::Warning:
                    if (warnings) continue;
                    ImGui::PushStyleColor(ImGuiCol_Text, {1,1,0,1});
                    ImGui::TextUnformatted(entry.CreateTimedMSG().c_str());
                    ImGui::PopStyleColor();
                    break;
                case LogEntryType::Error:
                    if (errors) continue;
                    ImGui::PushStyleColor(ImGuiCol_Text, {1,0,0,1});
                    ImGui::TextUnformatted(entry.CreateTimedMSG().c_str());
                    ImGui::PopStyleColor();
                    break;
                case LogEntryType::Log:
                    if (logs) continue;
                    ImGui::TextUnformatted(entry.CreateTimedMSG().c_str());
                    break;
            }
        }
        if (autoScroll && ImGui::GetScrollY() >= ImGui::GetScrollMaxY())
            ImGui::SetScrollHereY(1.0f);

        ImGui::PopStyleVar();

    }
    ImGui::EndChild();
    ImGui::Separator();
}

int Callback(ImGuiInputTextCallbackData* data)
{
    return 0;
}

void TSE::EDITOR::ConsolView::Input()
{
    ImGuiInputTextFlags _flags = ImGuiInputTextFlags_EnterReturnsTrue | ImGuiInputTextFlags_EscapeClearsAll | ImGuiInputTextFlags_CallbackCompletion | ImGuiInputTextFlags_CallbackHistory;
    
    if(ImGui::InputText("<-- Command", textbuffer, 512, _flags, Callback))
    {
        HandleInput(std::string(textbuffer));
        textbuffer[0] = '\0';
    }
}

void TSE::EDITOR::ConsolView::Define()
{
    MenuBar();
    LogList();
    Input();
}

void TSE::EDITOR::ConsolView::HandleInput(const string &input)
{
    LuaStateHandler::RunLuaString(input);
}

void TSE::EDITOR::ConsolView::CreateLogEntry(const string &msg, const LogEntryType &t)
{
    if(entries.size() > 0 && entries[entries.size() - 1].msg == msg)
    {
        entries[entries.size() - 1].count += 1;
        return;
    }
    LogEntry entry(msg, t);
    entries.push_back(entry);
}
