#include "srcedit_storyconcept.h"
#include "keywordshighlighter.h"

#include <QComboBox>
#include <QMenu>
#include <QSpinBox>
#include <QTextStream>
#include <QVBoxLayout>

using namespace Components;
using namespace Enhancement;

StoryconceptSourceEdit::StoryconceptSourceEdit()
    : highlighter_ins(new KeywordsHighlighter(this)),
      edit_square(new QTextEdit)
{
    highlighter_ins->setDocument(this->edit_square->document());
    connect(edit_square,    &QTextEdit::textChanged,  [this](){
        emit this->dataChanged(filepath_store);
    });
}

void StoryconceptSourceEdit::concept_jump(const QList<QString> &path)
{
    auto fpath = this->absoluteTargetPath();
    auto core = core_ins->parseCore();
    if(path.size()){
        auto storynode = core->queryStoryConcept(path[0]).first();
        auto first_word = storynode->refered()[0];

        auto textblock = this->edit_square->document()->findBlockByNumber(first_word->row());
        auto cur = this->edit_square->textCursor();
        cur.setPosition(textblock.position());
        cur.select(QTextCursor::SelectionType::LineUnderCursor);
        this->edit_square->setTextCursor(cur);

        if(path.size() > 1){
            auto storypoint = core->queryStoryStrongPoint(storynode, path[1]).first();
            first_word = storypoint->refered()[0];

            auto textblock = this->edit_square->document()->findBlockByNumber(first_word->row());
            cur.setPosition(textblock.position());
            cur.select(QTextCursor::SelectionType::LineUnderCursor);
            this->edit_square->setTextCursor(cur);
        }
    }

    edit_square->setFocus();
}

void StoryconceptSourceEdit::modeReset(const QString &type) const
{

}

QList<QString> StoryconceptSourceEdit::modes() const
{
    return QList<QString>() << "源码编辑";
}

QString StoryconceptSourceEdit::currentMode() const
{
    return "源码编辑";
}

void StoryconceptSourceEdit::contexBinding(Core::AppCore *app) { this->core_ins = app; }

void StoryconceptSourceEdit::renderRepeat() const
{
    this->highlighter_ins->rehighlight();
}

QList<QString> StoryconceptSourceEdit::suffixes() const
{
    return QList<QString>() << "storyconcept";
}

std::tuple<bool, QString> StoryconceptSourceEdit::create(const QDir &target, const QString &name, const QString &suffix)
{
    auto path = target.filePath(QString("%1.%2").arg(name, suffix));
    if(QFileInfo::exists(path))
        return std::make_tuple(false, path);

    QFile nwf(path);
    if(!nwf.open(QIODevice::WriteOnly|QIODevice::Text))
        throw new SimpleException("指定文件无法创建："+path);

    return std::make_tuple(true, target.relativeFilePath(path));
}

MakeTools::FilePresent *StoryconceptSourceEdit::newInst() const
{
    return new StoryconceptSourceEdit();
}

QWidget *StoryconceptSourceEdit::widget() const
{
    return edit_square;
}

QString StoryconceptSourceEdit::name() const
{
    return this->name_store;
}

void StoryconceptSourceEdit::load(const QFileInfo &target_file)
{
    if(!target_file.exists())
        throw new SimpleException("参数错误：传入的文件不存在");
    if(!target_file.isFile())
        throw new SimpleException("参数错误：传入参数非文件类型");

    filepath_store = target_file.absoluteFilePath();
    QFile bin(filepath_store);
    if(!bin.open(QIODevice::ReadOnly|QIODevice::Text))
        throw new SimpleException("参数错误：指定的文件无法打开");

    QTextStream tin(&bin);
    tin.setCodec("UTF-8");
    this->edit_square->setText(tin.readAll());
}

void StoryconceptSourceEdit::saveAs(const QString &path)
{
    if(!path.isEmpty())
        filepath_store = path;

    QFile bout(filepath_store);
    if(!bout.open(QIODevice::WriteOnly|QIODevice::Text))
        throw new SimpleException("参数错误：指定的文件无法打开");

    QTextStream tout(&bout);
    tout.setCodec("UTF-8");
    tout << this->edit_square->toPlainText();
    tout.flush();
}

QString StoryconceptSourceEdit::relativeTargetPath(const QDir &base) const
{
    return base.relativeFilePath(filepath_store);
}

QString StoryconceptSourceEdit::absoluteTargetPath() const
{
    return filepath_store;
}

QString StoryconceptSourceEdit::getText() const
{
    return edit_square->toPlainText();
}

bool StoryconceptSourceEdit::isModified() const
{
    return true;
}

void StoryconceptSourceEdit::applySetting(const QString &name, Core::AppCore *core)
{
    this->name_store = name;

}

MakeTools::FilePresent::Features StoryconceptSourceEdit::features()
{
    return Feature::Compile | Feature::HighLight;
}
void StoryconceptSourceEdit::jumpTo(const QList<QString> &path)
{
    concept_jump(path);
}
