#include "toolreg.hpp"

// ***ToolReg
ToolReg::ToolReg() {
    nextKey = 0;
}

void ToolReg::add(TextEdit* ed) {
    int i = nextKey;
    nextKey++;
    tools[i] = ed;
    editors[i] = ed;
    ed->setKey(i);
}

void ToolReg::add(FMan* fman) {
    int i = nextKey;
    nextKey++;
    tools[i] = fman;
    fman->setKey(i);
}

void ToolReg::add(Search* s) {
    int i = nextKey;
    nextKey++;
    tools[i] = s;
    s->setKey(i);
}

void ToolReg::add(TextBuffer* buffer) {
    int i = nextKey;
    nextKey++;
    tools[i] = buffer;
    buffer->setKey(i);
}

bool ToolReg::remove(Tool* tool) {
    if (tool->type == ToolType::FMan || tool->type == ToolType::Search) { return false; }
    if (tool->type == ToolType::TextEdit && editors.size() == 1) {
        // don't close the last editor
        editors[tool->getKey()]->closeFile();
        return false;
    }
    tools.erase(tool->getKey());
    if (tool->type == ToolType::TextEdit) { editors.erase(tool->getKey()); }
    return true;
}

bool ToolReg::remove(TextEdit* ed) {
    // returns true if the Tool should be removed from the UI
    // returns false if it's the last Editor and should be kept
    if (editors.size() == 1) {
        ed->closeFile();
        return false;
    }
    editors.erase(ed->getKey());
    tools.erase(ed->getKey());
    return true;
}

Tool* ToolReg::tool(TextEdit* ed) {
    return tools[ed->getKey()];
}

Tool* ToolReg::tool(FMan* fman) {
    return tools[fman->getKey()];
}

Tool* ToolReg::toolInFocus() {
    for (auto const& [key, tool] : tools) {
        if (tool->hasFocus()) { return tool; }
    }
    // If nothing has focus, focus on the default
    // If there is nothing to focus on (ie tools is empty) this SHOULD crash
    for (auto const& [key, tool] : tools) {
        tool->setFocus();
        return tool;
    }
    // TODO: crash here
    ERROR("NO TOOLS REMAINING!!");
    return NULL;
}

TextEdit* ToolReg::editorInFocus() {
    for (auto const& [key, ed] : editors) {
        if (ed->hasFocus()) { return ed; }
    }
    // TODO: implement result pattern
    return NULL;
}

std::optional<TextEdit*> ToolReg::isThereABlankEditor() {
    for (auto const& [key, ed] : editors) {
        if (ed->isEmpty()) {
            return ed;
        }
    }
    return std::nullopt;
}

std::optional<TextEdit*> ToolReg::isThereAnEditorWithFilename(QString filename) {
    for (auto const& [key, ed] : editors) {
        if (ed->currentFilename() == filename) {
            return ed;
        }
    }
    return std::nullopt;
}
