#include "wmformatpage.h"
#include "ui_wmformatpage.h"

WmFormatPage::WmFormatPage(QWidget *parent) :
    QWizardPage(parent),
    ui(new Ui::WmFormatPage)
{
    ui->setupUi(this);

    this->setTitle("Pages Formatting");
    this->setSubTitle("Create and format the pages here.\nNote that Oni doesn't support partial words formatting so the whole line will be formatted.");
    setupComboBoxTextSize();

    ui->cbTextSize->setCurrentText("12");

    // Oni only has Tahoma as default, the user however can type any additional font which he has imported into Oni
    ui->fcbFont->clear();
    ui->fcbFont->addItem("Tahoma");
}

void WmFormatPage::initializePage()
{
    // Put here code that is dependent from previous pages

    // Clean old pages
    this->currentPages.clear();
    ui->twPages->clear();

    addPage();

    setDefaultOniFont(0);

    // If the type is diary page we disable the pages adding and removing
    // To add extra pages to diary is necessary to create additional files
    switch(static_cast<WINDOW_TYPE>(field("cbWindowType").toInt())){
    case WINDOW_TYPE::DIARY:
    case WINDOW_TYPE::HELP:
    case WINDOW_TYPE::WEAPON:
    case WINDOW_TYPE::ITEM:
        ui->pbAddPageAfter->setEnabled(false);
        ui->pbAddPageBefore->setEnabled(false);
        ui->pbDeleteCurrentPage->setEnabled(false);
        break;
    case WINDOW_TYPE::OBJECTIVE:
    case WINDOW_TYPE::TEXT_CONSOLE:
        ui->pbAddPageAfter->setEnabled(true);
        ui->pbAddPageBefore->setEnabled(true);
        ui->pbDeleteCurrentPage->setEnabled(true);
        break;
    case WINDOW_TYPE::ENUM_END:
        UtilVago::showAndLogErrorPopUp("An error ocurred: WmFormatPage::initializePage invalid WINDOW_TYPE");
        break;
    }

    windowsIsInitialized = true;
}

WmFormatPage::~WmFormatPage()
{
    delete ui;
}

bool WmFormatPage::validatePage(){

    for(const std::shared_ptr<WmPage> &currentPage : this->currentPages){

        if(
                currentPage->getMainText().toPlainText().trimmed() == "" &&
                currentPage->getFooterText().toPlainText().trimmed() == ""
                )
        {
            Util::Dialogs::showError("You need to fill at least one text section in all pages!");
            return false;
        }

    }

    // If we can add more than one page, ask the user if he already added them all
    if(ui->pbAddPageAfter->isEnabled()){
        return Util::Dialogs::showQuestion(this, "Have you added all the window pages?");
    }

    return true;

}

void WmFormatPage::addPage(bool afterCurrentPage){

    int indexForInsertion = 0;

    if(ui->twPages->currentWidget() != nullptr){
        if(afterCurrentPage){
            indexForInsertion = ui->twPages->currentIndex() + 1;
        }
        else{
            indexForInsertion = ui->twPages->currentIndex();
        }
    }

    ui->twPages->insertTab(indexForInsertion, new QWidget(ui->twPages), "Page " + QString::number(indexForInsertion+1));
    currentPages.insert(indexForInsertion, std::make_shared<WmPage>(ui->twPages->widget(indexForInsertion)));
    // Update all other tab texts
    updateTabNames(indexForInsertion+1);

    // Set the tab added as current tab
    ui->twPages->setCurrentIndex(indexForInsertion);

    // Set the default font
    setDefaultOniFont(indexForInsertion);
    // Make the current selected font the default for new tab
    setCurrentFormatting(indexForInsertion);

    switch(static_cast<WINDOW_TYPE>(field("cbWindowType").toInt())){
    case WINDOW_TYPE::HELP:
    case WINDOW_TYPE::TEXT_CONSOLE:
        // these types of page doesn't use the footer
        this->currentPages[indexForInsertion]->hideFooterText();
        break;
    case WINDOW_TYPE::DIARY:
    case WINDOW_TYPE::ITEM:
    case WINDOW_TYPE::OBJECTIVE:
    case WINDOW_TYPE::WEAPON:
        this->currentPages[indexForInsertion]->showFooterText();
        break;
    case WINDOW_TYPE::ENUM_END:
        UtilVago::showAndLogErrorPopUp("An error ocurred: WmFormatPage::addPage invalid WINDOW_TYPE");
        break;
    }

}

void WmFormatPage::setupComboBoxTextSize(){

    // Setup text size combobox
    for(int i=8; i<=12; i++){
        ui->cbTextSize->addItem(QString::number(i));
    }

    for(int i=14; i<=28; i+=2){
        ui->cbTextSize->addItem(QString::number(i));
    }

    ui->cbTextSize->addItem(QString::number(36));

}

void WmFormatPage::on_tbBold_clicked()
{
    formatText(FormatType::BOLD);
}

void WmFormatPage::on_tbItalic_clicked()
{
    formatText(FormatType::ITALIC);
}

void WmFormatPage::on_tbFontColor_clicked()
{
    formatText(FormatType::COLOR);
}

void WmFormatPage::on_fcbFont_currentFontChanged(const QFont&)
{
    if(windowsIsInitialized){
        formatText(FormatType::FONT_TYPE);
    }
}

void WmFormatPage::on_cbTextSize_currentTextChanged(const QString&)
{
    if(windowsIsInitialized){
        formatText(FormatType::FONT_SIZE);
    }
}

void WmFormatPage::formatText(FormatType desiredFormatType){

    int tabIndex = ui->twPages->currentIndex();

    QVector<QTextEdit*> textEdits;

    if(currentPages[tabIndex]->getMainText().textCursor().hasSelection()){
        textEdits << &currentPages[tabIndex]->getMainText();
    }
    if(currentPages[tabIndex]->getFooterText().textCursor().hasSelection()){
        textEdits << &currentPages[tabIndex]->getFooterText();
    }

    if(textEdits.size() == 0){
        Util::Dialogs::showInfo("Select some text first.");
        return;
    }

    for(QTextEdit* const currentTextEdit : textEdits){
        QTextCursor currentCursor = currentTextEdit->textCursor();

        // Select entire row(s) (oni only supports formatting the entire row)
        int selectionStart = currentCursor.selectionStart();
        int selectionEnd = currentCursor.selectionEnd();
        int initialRowNumber = 0;
        int finalRowNumber = 0;

        // If we have no selection skip
        if(selectionStart == selectionEnd){
            continue;
        }

        currentCursor.setPosition(selectionStart);
        initialRowNumber = currentCursor.blockNumber();
        currentCursor.setPosition(selectionEnd);
        finalRowNumber = currentCursor.blockNumber();

        // Apply the style individually for each row (this allow us to apply the same font family to all rows keeping the individual row formatting. e.g. color)
        for(int i=initialRowNumber; i<=finalRowNumber; i++){

            currentCursor.setPosition(currentTextEdit->document()->findBlockByLineNumber(i).position());
            currentCursor.movePosition(QTextCursor::EndOfLine, QTextCursor::KeepAnchor);

            QTextCharFormat format = currentCursor.charFormat();

            if(desiredFormatType == FormatType::BOLD){
                if(format.fontWeight() == QFont::Bold){
                    format.setFontWeight(QFont::Normal);
                }
                else{
                    format.setFontWeight(QFont::Bold);
                }
            }
            else if(desiredFormatType == FormatType::ITALIC){
                if(format.fontItalic()){
                    format.setFontItalic(false);
                }
                else{
                    format.setFontItalic(true);
                }
            }
            else if(desiredFormatType == FormatType::COLOR){
                QColor pickedColor = QColorDialog::getColor(Qt::green);

                if(pickedColor.isValid()){
                    format.setForeground(pickedColor);
                }
            }
            else if(desiredFormatType == FormatType::FONT_TYPE){
                format.setFontFamily(ui->fcbFont->currentFont().family());
            }
            else if(desiredFormatType == FormatType::FONT_SIZE){
                bool ok;
                double newFontSize = ui->cbTextSize->currentText().toDouble(&ok);

                if(!ok){
                    Util::Dialogs::showError("The inputted font size is not valid!");
                    ui->cbTextSize->setCurrentIndex(0); // reset to default number
                    return;
                }

                format.setFontPointSize(static_cast<qreal>(newFontSize));
            }

            currentCursor.mergeCharFormat(format);
        }
    }
}


void WmFormatPage::on_pbAddPageAfter_clicked()
{
    addPage(true);
}

void WmFormatPage::on_pbAddPageBefore_clicked()
{
    addPage(false);
}

void WmFormatPage::on_pbDeleteCurrentPage_clicked()
{
    if(ui->twPages->count() <= 1){
        Util::Dialogs::showError("You must have at least one page!");
        return;
    }

    if(Util::Dialogs::showQuestion(this, "Are you sure do you want to delete the current page?")){
        int indexToDelete = ui->twPages->currentIndex();

        currentPages.removeAt(indexToDelete);
        ui->twPages->removeTab(indexToDelete);
        updateTabNames(indexToDelete);
    }
}

void WmFormatPage::updateTabNames(int startIndex){
    // Update all other tab texts
    for(int i=startIndex; i<ui->twPages->count(); i++){
        ui->twPages->setTabText(i, "Page " + QString::number(i+1));
    }
}

void WmFormatPage::setCurrentFormatting(int index){

    QFont defaultFont;
    defaultFont.setFamily(ui->fcbFont->currentText());
    defaultFont.setPointSize(ui->cbTextSize->currentText().toInt());

    this->currentPages[index]->getMainText().setFont(defaultFont);
    this->currentPages[index]->getFooterText().setFont(defaultFont);
}

void WmFormatPage::setDefaultOniFont(int index){

    QFont defaultFont;
    defaultFont.setFamily("Tahoma");
    defaultFont.setPointSize(12);

    this->currentPages[index]->getMainText().setFont(defaultFont);
    defaultFont.setPointSize(10);
    this->currentPages[index]->getFooterText().setFont(defaultFont);

    this->currentPages[index]->getMainText().setTextColor(Qt::green);
    this->currentPages[index]->getMainText().setFontWeight(QFont::Bold);
    this->currentPages[index]->getFooterText().setTextColor(Qt::green);
    this->currentPages[index]->getFooterText().setFontWeight(QFont::Bold);
}

QList<std::shared_ptr<WmPage> >& WmFormatPage::getCurrentPages(){
    return this->currentPages;
}

// Ignore enter key in this page, so user can do enter after write the custom font
void WmFormatPage::keyPressEvent(QKeyEvent * event){

    if(event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter){
        return;
    }


    QWizardPage::keyPressEvent(event);
}


