#include "qscilexerremarkup.h"
#include <qsciscintilla.h>
#include <QRegularExpression>

QRegularExpression patternBold("\\*\\*(.+?)\\*\\*");
QRegularExpression patternItalic("(?<!:)//(.+?)//");
QRegularExpression patternHighlighted("(?<!:)!!(.+?)!!");
QRegularExpression patternUnderlined("(?<!:)__(.+?)__");
QRegularExpression patternMonospace("(?<!:)`(.+?)`");

const char*
QsciLexerRemarkup::language() const
{
        return "Remarkup";
}

QString
QsciLexerRemarkup::description(int style) const
{
    switch(style){
        case QsciLexerRemarkupStyles::Default:
            return "Default";
        case QsciLexerRemarkupStyles::Bold:
            return "Bold";
        case QsciLexerRemarkupStyles::Italic:
            return "Italic";
        case QsciLexerRemarkupStyles::Hidden:
            return "Hidden";
        case QsciLexerRemarkupStyles::Highlight:
            return "Highlight";

        case QsciLexerRemarkupStyles::Underline:
            return "Underline";

        case QsciLexerRemarkupStyles::Monospace:
            return "Monospace";

        default: break;
    }

    return QString();
}

QColor
QsciLexerRemarkup::defaultColor(int style) const
{
    switch(style){
        case QsciLexerRemarkupStyles::Default:
                break;

        case QsciLexerRemarkupStyles::Bold:
            return Qt::red;

        default: break;
    }

    return QsciLexer::defaultColor();
}

QFont
QsciLexerRemarkup::defaultFont(int style) const
{
    Q_UNUSED(style);
//    QFont f = QsciLexer::defaultFont();

//    switch(style){
//        case Default:
//                break;

//        case Bold:
//            f.setBold(true);
//            f.setCapitalization(QFont::AllUppercase);
//            break;
//    }

//    return f;
    return QsciLexer::defaultFont();
}

QColor
QsciLexerRemarkup::defaultPaper(int style) const
{
    Q_UNUSED(style);
    return QsciLexer::defaultPaper();
}

QsciStyle
QsciLexerRemarkup::getStyle(int style)
{
    return QsciStyle(style, description(style), defaultColor(style),
            defaultPaper(style), defaultFont(style));
}

QsciLexerRemarkup::QsciLexerRemarkup(QObject * parent)
    :QsciLexerCustom(parent)
{

}

QsciLexerRemarkup::~QsciLexerRemarkup()
{}

void
QsciLexerRemarkup::styleText(int start, int end){
    if (!editor())      return;
    if (start == end) return;
    QsciScintilla* e = editor();

    //reset styles:
    startStyling(start);
    setStyling(end-start, (int) QsciLexerRemarkupStyles::Default);

    char * chars = new char[end - start + 1];
    e->SendScintilla(QsciScintilla::SCI_GETTEXTRANGE, start, end, chars);
    QString source = QString::fromUtf8(chars);
    delete [] chars;

    runPhutilRemarkupBoldRule(source,start);
    runPhutilRemarkupItalicRule(source,start);
    runPhutilRemarkupHighlightedRule(source, start);
    runPhutilRemarkupUnderlinedRule(source, start);
    runPhutilRemarkupMonospaceRule(source, start);
}

void
QsciLexerRemarkup::runPhutilRemarkupBoldRule(const QString& source, int index){
    int pos =0;
    while(true) {
        QRegularExpressionMatch result = patternBold.match(source, pos);
        if (!result.hasMatch()){break;}

        //hide:
        startStyling(index + result.capturedStart(0));
        setStyling(result.capturedLength(0), (int) QsciLexerRemarkupStyles::Hidden);

        QString r = result.captured(1);
        startStyling(index + result.capturedStart(1));
        setStyling(result.capturedLength(1), (int) QsciLexerRemarkupStyles::Bold);
        pos = result.capturedEnd(1) + 1;
    }
}

void
QsciLexerRemarkup::runPhutilRemarkupItalicRule(const QString& source, int index){
    int pos =0;
    while(true) {
        QRegularExpressionMatch result = patternItalic.match(source, pos);
        if (!result.hasMatch()){break;}

        //hide:
        startStyling(index + result.capturedStart(0));
        setStyling(result.capturedLength(0), (int) QsciLexerRemarkupStyles::Hidden);

        startStyling(index + result.capturedStart(1));
        setStyling(result.capturedLength(1), (int) QsciLexerRemarkupStyles::Italic);
        pos = result.capturedEnd(1) + 1;
    }
}

void
QsciLexerRemarkup::runPhutilRemarkupHighlightedRule(const QString& source, int index){
    int pos =0;
    while(true) {
        QRegularExpressionMatch result = patternHighlighted.match(source, pos);
        if (!result.hasMatch()){break;}

        //hide:
        startStyling(index + result.capturedStart(0));
        setStyling(result.capturedLength(0), (int) QsciLexerRemarkupStyles::Hidden);

        startStyling(index + result.capturedStart(1));
        setStyling(result.capturedLength(1), (int) QsciLexerRemarkupStyles::Highlight);
        pos = result.capturedEnd(1) + 1;
    }
}

void
QsciLexerRemarkup::runPhutilRemarkupUnderlinedRule(const QString& source, int index){
    int pos =0;
    while(true) {
        QRegularExpressionMatch result = patternUnderlined.match(source, pos);
        if (!result.hasMatch()){break;}

        //hide:
        startStyling(index + result.capturedStart(0));
        setStyling(result.capturedLength(0), (int) QsciLexerRemarkupStyles::Hidden);

        startStyling(index + result.capturedStart(1));
        setStyling(result.capturedLength(1), (int) QsciLexerRemarkupStyles::Underline);
        pos = result.capturedEnd(1) + 1;
    }
}

void
QsciLexerRemarkup::runPhutilRemarkupMonospaceRule(const QString& source, int index){
    int pos =0;
    while(true) {
        QRegularExpressionMatch result = patternMonospace.match(source, pos);
        if (!result.hasMatch()){break;}

        //hide:
        startStyling(index + result.capturedStart(0));
        setStyling(result.capturedLength(0), (int) QsciLexerRemarkupStyles::Hidden);

        startStyling(index + result.capturedStart(1));
        setStyling(result.capturedLength(1), (int) QsciLexerRemarkupStyles::Monospace);
        pos = result.capturedEnd(1) + 1;
    }
}

//"PhutilRemarkupBoldRule.php: **bold**
//PhutilRemarkupItalicRule.php: //italic//

/*
"PhutilRemarkupDelRule.php"
"PhutilRemarkupDocumentLinkRule.php"
"PhutilRemarkupEscapeRemarkupRule.php"
"PhutilRemarkupHighlightRule.php"
"PhutilRemarkupHyperlinkRule.php"

"PhutilRemarkupLinebreaksRule.php"
"PhutilRemarkupMonospaceRule.php"
"PhutilRemarkupRule.php"
"PhutilRemarkupUnderlineRule.php"
*/

