#include "textedit.hpp"

Editor::Editor() : QTextEdit () {
}

void Editor::keyPressEvent(QKeyEvent* e) {
    switch (e->key()) {
        case Qt::Key_Tab:
            QTextEdit::insertPlainText("    ");
            break;
        default:
            QTextEdit::keyPressEvent(e);
    }
}

TextEdit::TextEdit() : Tool() {
    type = ToolType::TextEdit;
    label = "ed";
    filename = "";
    ed = new Editor;
    //hl = new Highlighter(ed->document());
    setFocusProxy(ed);
    QHBoxLayout* lo = new QHBoxLayout(this);
    lo->addWidget(ed);
    // TODO: add overview
    // TODO: add margin
    // TODO: add line numbers
}

void TextEdit::spawn(QMainWindow* parent) {
    Tool::spawn(parent);
    Tool::moveToCenter();
    // hg = new Highlighter(ed->document());
    
    ed->setPlaceholderText("Welcome to qed.");
}

QString TextEdit::currentFilename() {
    return filename;
}

QString TextEdit::saveFile() {
    if (!filename.isEmpty()) {
        QSaveFile file(filename);
        if (file.open(QSaveFile::WriteOnly | QSaveFile::Text)) {
            QTextStream outputStream(&file);
            outputStream << ed->toPlainText();
            file.commit();
            ed->document()->setModified(false);
            return tr("Saved %1").arg(QDir::toNativeSeparators(filename));
        } else {
            return tr("Save %1 failed: %2").arg(
                    QDir::toNativeSeparators(filename),
                    file.errorString());
        }
    }
    return "";
}

bool TextEdit::isUnsaved() {
    return ed->document()->isModified();
}

bool TextEdit::isEmpty() {
    return (!hasFilename() && !isUnsaved());
}

bool TextEdit::hasFilename() {
    return filename.length() != 0;
}

void TextEdit::openFile(const QString filename) {
    DEBUG("TextEdit::openFile(" << filename.toStdString());
    // TODO: what's slow here?
    if (!filename.isEmpty()) {
        QFile file(filename);
        if (file.open(QFile::ReadOnly | QFile::Text)) {
            this->filename = filename;
            ed->setPlainText(file.readAll());
            hl = new Highlighter(ed->document(), filenameToLang(filename));
        }
    }
}

void TextEdit::closeFile() {
    ed->clear();
    this->filename = "";
}

void TextEdit::findNext(QString exp) {
    QTextCursor tc = ed->textCursor();
    QRegularExpression re {exp};
    bool found = ed->find(re);
    if (!found) {
        // try again with wrapping
        tc = ed->document()->find(re, ed->document()->begin().position());
        if (tc.hasSelection()) {
            ed->setTextCursor(tc);
        }
    }
}

void TextEdit::findFirst(QString exp) {
    QTextCursor tc = ed->textCursor();
    tc.setPosition(tc.anchor());
    ed->setTextCursor(tc);
    // if you don't do this it searches from the end of the current selection
    // messing up search as you type
    QRegularExpression re {exp};
    bool found = ed->find(re);
    if (!found) {
        // try again with wrapping
        tc = ed->document()->find(re, ed->document()->begin().position());
        if (tc.hasSelection()) {
            ed->setTextCursor(tc);
        }
    }
}

void TextEdit::findNextWithCase(QString exp) {
    QTextCursor tc = ed->textCursor();
    QRegularExpression re {exp};
    bool found = ed->find(re, QTextDocument::FindCaseSensitively);
    if (!found) {
        // try again with wrapping
        tc = ed->document()->find(re, ed->document()->begin().position(),
                QTextDocument::FindCaseSensitively);
        if (tc.hasSelection()) {
            ed->setTextCursor(tc);
        }
    }
}

void TextEdit::findFirstWithCase(QString exp) {
    QTextCursor tc = ed->textCursor();
    tc.setPosition(tc.anchor());
    ed->setTextCursor(tc);
    // if you don't do this it searches from the end of the current selection
    // messing up search as you type
    QRegularExpression re {exp};
    bool found = ed->find(re, QTextDocument::FindCaseSensitively);
    if (!found) {
        // try again with wrapping
        tc = ed->document()->find(re, ed->document()->begin().position(),
                QTextDocument::FindCaseSensitively);
        if (tc.hasSelection()) {
            ed->setTextCursor(tc);
        }
    }
}

QString TextEdit::filenameToLang(QString fn) {
    // update highlighting language
    if (fn.endsWith("c", Qt::CaseInsensitive) 
            || fn.endsWith("h", Qt::CaseInsensitive)) {
        return "c";
    } else if (fn.endsWith("cpp", Qt::CaseInsensitive) 
            || fn.endsWith("hpp", Qt::CaseInsensitive)) {
        return "cpp";
    } else if (fn.endsWith("js", Qt::CaseInsensitive)) {
        return "javascript";
    } else if (fn.endsWith("json", Qt::CaseInsensitive)) {
        return "json";
    } else if (fn.endsWith("lua", Qt::CaseInsensitive)) {
        return "lua";
    } else if (fn.endsWith("py", Qt::CaseInsensitive)) {
        return "python";
    }
    return "Unknown";
}
