#include "xmltoolsinterfacecommandpreview.h"
#include "ui_xmltoolsinterfacecommandpreview.h"

XmlToolsInterfaceCommandPreview::XmlToolsInterfaceCommandPreview(const QString &currentFileLocation, const QString &previewFileLocation, QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::XmlToolsInterfaceCommandPreview)
{
    ui->setupUi(this);
    this->setAttribute(Qt::WA_DeleteOnClose, true); //destroy itself once finished.

    QFile currentFile(currentFileLocation);
    currentFile.open(QIODevice::ReadOnly);

    this->currentText = currentFile.readAll();

    ui->teCurrentFileText->setText(this->currentText);

    QFile previewFile(previewFileLocation);
    previewFile.open(QIODevice::ReadOnly);

    this->previewText = previewFile.readAll();

    ui->tePreviewFileText->setText(this->previewText);

    highlighterCurrentFile.setDocument(ui->teCurrentFileText->document());
    highlighterPreviewFile.setDocument(ui->tePreviewFileText->document());

    previewFile.close();
    currentFile.close();

    // Split and trim text of current and preview file
    this->currentTextRows = this->currentText.split("\n");
    this->previewTextRows = this->previewText.split("\n");

    for(QString &currentTextRow : this->currentTextRows){
        currentTextRow = currentTextRow.trimmed();
    }
    for(QString &previewTextRow : this->previewTextRows){
        previewTextRow = previewTextRow.trimmed();
    }


    QString currentTextRowNumbers;
    QString previewTextRowNumbers;

    for(int i=0; i<this->currentTextRows.size(); i++){
        currentTextRowNumbers += QString::number(i);
        if(i < this->currentTextRows.size()-1){
            currentTextRowNumbers += "\n";
        }
    }

    for(int i=0; i<this->previewTextRows.size(); i++){
        previewTextRowNumbers += QString::number(i);
        if(i < this->previewTextRows.size()-1){
            previewTextRowNumbers += "\n";
        }
    }

    // Create line numbers QTextEdits
    this->lineNumberDisplayCurrentFile = new LineNumberDisplay(ui->teCurrentFileText,this);
    this->lineNumberDisplayPreviewFile = new LineNumberDisplay(ui->tePreviewFileText,this);

    // Make line numbers background transparent (http://www.qtcentre.org/threads/12148-how-QTextEdit-transparent-to-his-parent-window)
    this->lineNumberDisplayCurrentFile->viewport()->setAutoFillBackground(false);
    this->lineNumberDisplayPreviewFile->viewport()->setAutoFillBackground(false);

    // Add line numbers (at beginning of the horizontal layout)
    this->ui->hlCurrentFileText->insertWidget(0,lineNumberDisplayCurrentFile);
    this->ui->hlPreviewFileText->insertWidget(0,lineNumberDisplayPreviewFile);

    // Save the default background color (OS dependent)
    this->textEditDefaultBackgroundColor = QTextCursor(this->lineNumberDisplayCurrentFile->document()).charFormat().background();

    highlightDifferences();

    // Vertical scrollbars
    connect(ui->teCurrentFileText->verticalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(verticalScrollbarMoved(int)));
    connect(ui->tePreviewFileText->verticalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(verticalScrollbarMoved(int)));

    // Horizontal scrollbars
    connect(ui->teCurrentFileText->horizontalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(horizontalScrollbarMoved(int)));
    connect(ui->tePreviewFileText->horizontalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(horizontalScrollbarMoved(int)));
}

void XmlToolsInterfaceCommandPreview::verticalScrollbarMoved(int value)
{
    if(ui->cbVerticalScrollbarsSynchronized->isChecked()){
        if(ui->teCurrentFileText->verticalScrollBar()->sliderPosition() != value){
            ui->teCurrentFileText->verticalScrollBar()->setSliderPosition(value);
        }
        else{
            ui->tePreviewFileText->verticalScrollBar()->setSliderPosition(value);
        }
    }
}

void XmlToolsInterfaceCommandPreview::horizontalScrollbarMoved(int value)
{
    if(ui->cbHorizontalScrollbarsSynchronized->isChecked()){
        if(ui->teCurrentFileText->horizontalScrollBar()->sliderPosition() != value){
            ui->teCurrentFileText->horizontalScrollBar()->setSliderPosition(value);
        }
        else{
            ui->tePreviewFileText->horizontalScrollBar()->setSliderPosition(value);
        }
    }
}

void XmlToolsInterfaceCommandPreview::on_cbWrapText_toggled(bool checked)
{
    QTextEdit::LineWrapMode wrappingMode;

    if(checked){
        wrappingMode = QTextEdit::WidgetWidth;
        this->lineNumberDisplayCurrentFile->hide();
        this->lineNumberDisplayPreviewFile->hide();
    }
    else{
        wrappingMode = QTextEdit::NoWrap;
        this->lineNumberDisplayCurrentFile->show();
        this->lineNumberDisplayPreviewFile->show();
    }

    ui->teCurrentFileText->setLineWrapMode(wrappingMode);
    ui->tePreviewFileText->setLineWrapMode(wrappingMode);
}

void XmlToolsInterfaceCommandPreview::highlightDifferences(){

    QTextCharFormat fmt;
    QTextCursor cursor;

    for(int i=0; i<currentTextRows.size(); i++){
        if(i < this->previewTextRows.size()){
            if(this->currentTextRows.at(i) != this->previewTextRows.at(i)){
                fmt.setBackground(QColor(0xFFC864)); // orange color

                cursor = QTextCursor(ui->teCurrentFileText->document());
                cursor.setPosition(ui->teCurrentFileText->document()->findBlockByLineNumber(i).position());
                cursor.select(QTextCursor::LineUnderCursor);
                cursor.setCharFormat(fmt);

                fmt.setBackground(Qt::yellow);

                cursor = QTextCursor(ui->tePreviewFileText->document());
                cursor.setPosition(ui->tePreviewFileText->document()->findBlockByLineNumber(i).position());
                cursor.select(QTextCursor::LineUnderCursor);
                cursor.setCharFormat(fmt);
            }
        }
        else{ // if we have more rows in the current file than in the preview file we highlight the the extra rows in the current file
            fmt.setBackground(QColor(0xFFC864)); // orange color

            QTextCursor cursor(ui->teCurrentFileText->document());
            cursor.setPosition(ui->teCurrentFileText->document()->findBlockByLineNumber(i).position());
            cursor.select(QTextCursor::LineUnderCursor);
            cursor.setCharFormat(fmt);
        }
    }

    // if we have less rows in the current file than in the preview file we highlight the the extra rows in the preview file
    if(this->currentTextRows.size() < this->previewTextRows.size()){
        for(int i=this->currentTextRows.size(); i<this->previewTextRows.size(); i++){
            fmt.setBackground(Qt::yellow);

            cursor = QTextCursor(ui->tePreviewFileText->document());
            cursor.setPosition(ui->tePreviewFileText->document()->findBlockByLineNumber(i).position());
            cursor.select(QTextCursor::LineUnderCursor);
            cursor.setCharFormat(fmt);
        }
    }

    highlighterPreviewFile.rehighlight();
    highlighterCurrentFile.rehighlight();
}

XmlToolsInterfaceCommandPreview::~XmlToolsInterfaceCommandPreview()
{
    delete this->lineNumberDisplayCurrentFile;
    delete this->lineNumberDisplayPreviewFile;
    delete this->ui;
}



void XmlToolsInterfaceCommandPreview::on_checkBox_toggled(bool checked)
{
    if(checked){
        highlightDifferences();
    }
    else{
        QTextCursor cursor(ui->teCurrentFileText->document());
        QTextCharFormat fmt;
        fmt.setBackground(this->textEditDefaultBackgroundColor);

        cursor.select(QTextCursor::Document);
        cursor.setCharFormat(fmt);

        cursor = QTextCursor(ui->tePreviewFileText->document());
        cursor.select(QTextCursor::Document);
        cursor.setCharFormat(fmt);
    }
}
