#include "wmfinalpage.h"
#include "ui_wmfinalpage.h"

WmFinalPage::WmFinalPage(QString AppDir, QString wmLocation, QList<std::shared_ptr<WmPage> > &pages, QWidget *parent) :
    QWizardPage(parent), ui(new Ui::wmfinalpage), pages(pages)
{
    ui->setupUi(this);
    this->wmLocation=wmLocation;

    this->oniSplitCommands = new QStringList();
    this->myConverter = new Converter(AppDir, this->oniSplitCommands);

    ui->lbComplete->setText("<html>The wizard is now complete. The window messages have been converted. "
                            "You can view all converted files clicking <a href=' '>here.</a><br />"
                            "<br />Click restart to create more window messages from the wizard beggining, "
                            "otherwise click finish.</html>"); // Don't use rich text in qtdesigner because it generates platform dependent code

    connectSlots();
}

void WmFinalPage::openSoundsFolder(){
    QDesktopServices::openUrl(QUrl("file:///"+this->wmLocation));
}

void WmFinalPage::initializePage(){
    startProcessing();
}

void WmFinalPage::startProcessing(){
    // Check if images folder exists and create it if necessary
    QDir saveDir(this->wmLocation);

    if(!saveDir.exists())
    {
        saveDir.mkpath("."); // http://stackoverflow.com/questions/2241808/checking-if-a-folder-exists-and-creating-folders-in-qt-c thanks Petrucio
    }

    QString filePath = this->wmLocation + "/" + field("leFileName").toString() + ".xml";

    int globalSectionCounter = -1;
    int currentIGPGId = globalSectionCounter;
    int currentIGSAId = globalSectionCounter;
    int currentIGSTId = globalSectionCounter;

    pugi::xml_document doc;

    pugi::xml_node rootNode = doc.append_child("Oni");
    pugi::xml_node typeNode;

    // Define type node
    switch(static_cast<WINDOW_TYPE>(field("cbWindowType").toInt())){
    case WINDOW_TYPE::OBJECTIVE:
    {
        typeNode = rootNode.append_child("OPge");
        typeNode.append_attribute("id").set_value(++globalSectionCounter);
        typeNode.append_child("LevelNumber").append_child(pugi::xml_node_type::node_pcdata).set_value(QSTR_TO_CSTR(field("leLevelId").toString()));
        typeNode.append_child("Pages").append_child(pugi::xml_node_type::node_pcdata).set_value(QSTR_TO_CSTR(QString("#") + QString::number(++globalSectionCounter)));
        pugi::xml_node igpaNode = rootNode.append_child("IGPA");
        igpaNode.append_attribute("id").set_value(globalSectionCounter);
        pugi::xml_node pagesNode = igpaNode.append_child("Pages");
        currentIGPGId = globalSectionCounter;
        for(int i=0; i<this->pages.size(); i++){
            pagesNode.append_child("Link").append_child(pugi::xml_node_type::node_pcdata).set_value(QSTR_TO_CSTR("#" + QString::number(++globalSectionCounter)));
        }
        break;
    }
    case  WINDOW_TYPE::DIARY:
        typeNode = rootNode.append_child("DPge");
        typeNode.append_attribute("id").set_value(++globalSectionCounter);
        typeNode.append_child("LevelNumber").append_child(pugi::xml_node_type::node_pcdata).set_value(QSTR_TO_CSTR(field("leLevelId").toString()));
        typeNode.append_child("PageNumber").append_child(pugi::xml_node_type::node_pcdata).set_value(QSTR_TO_CSTR(field("lePageNumber").toString()));
        typeNode.append_child("IsLearnedMove").append_child(pugi::xml_node_type::node_pcdata).set_value(QSTR_TO_CSTR(QString::number(static_cast<int>(field("cbIsLearnedMove").toBool()))));
        currentIGPGId = globalSectionCounter;
        typeNode.append_child("Page").append_child(pugi::xml_node_type::node_pcdata).set_value(QSTR_TO_CSTR("#" + QString::number(++globalSectionCounter)));
        break;
    case  WINDOW_TYPE::HELP:
        typeNode = rootNode.append_child("HPge");
        typeNode.append_attribute("id").set_value(++globalSectionCounter);
        currentIGPGId = globalSectionCounter;
        typeNode.append_child("Page").append_child(pugi::xml_node_type::node_pcdata).set_value(QSTR_TO_CSTR("#" + QString::number(++globalSectionCounter)));
        break;
    case  WINDOW_TYPE::TEXT_CONSOLE:
    {
        typeNode = rootNode.append_child("TxtC");
        typeNode.append_attribute("id").set_value(++globalSectionCounter);
        typeNode.append_child("Pages").append_child(pugi::xml_node_type::node_pcdata).set_value(QSTR_TO_CSTR("#" + QString::number(++globalSectionCounter)));
        pugi::xml_node igpaNode = rootNode.append_child("IGPA");
        igpaNode.append_attribute("id").set_value(globalSectionCounter);
        currentIGPGId = globalSectionCounter;
        pugi::xml_node pagesNode = igpaNode.append_child("Pages");
        for(int i=0; i<this->pages.size(); i++){
            pagesNode.append_child("Link").append_child(pugi::xml_node_type::node_pcdata).set_value(QSTR_TO_CSTR("#" + QString::number(++globalSectionCounter)));
        }
        break;
    }
    case  WINDOW_TYPE::WEAPON:
        typeNode = rootNode.append_child("WPge");
        typeNode.append_attribute("id").set_value(++globalSectionCounter);
        typeNode.append_child("WeaponClass").append_child(pugi::xml_node_type::node_pcdata).set_value(QSTR_TO_CSTR(field("leWeaponClassName").toString()));
        currentIGPGId = globalSectionCounter;
        typeNode.append_child("Page").append_child(pugi::xml_node_type::node_pcdata).set_value(QSTR_TO_CSTR("#" + QString::number(++globalSectionCounter)));
        break;
    case  WINDOW_TYPE::ITEM:
        typeNode = rootNode.append_child("IPge");
        typeNode.append_attribute("id").set_value(++globalSectionCounter);
        typeNode.append_child("PageNumber").append_child(pugi::xml_node_type::node_pcdata).set_value(QSTR_TO_CSTR(field("lePageNumber").toString()));
        currentIGPGId = globalSectionCounter;
        typeNode.append_child("Page").append_child(pugi::xml_node_type::node_pcdata).set_value(QSTR_TO_CSTR("#" + QString::number(++globalSectionCounter)));
        break;
    case WINDOW_TYPE::ENUM_END:
        UtilVago::showAndLogErrorPopUp("An error ocurred: WmFinalPage::startProcessing invalid WINDOW_TYPE");
        break;
    }

    // Write pages text
    for(int i=0; i<this->pages.size(); i++){

        QTextEdit &mainText = this->pages[i]->getMainText();
        int mainTextNumberOfRows = mainText.toPlainText().split("\n").size();

        QTextEdit &footerText = this->pages[i]->getFooterText();
        int footerTextNumberOfRows = footerText.toPlainText().split("\n").size();

        // Create TXMP image if exists
        QString imageLocation = this->pages[i]->getMiddleImage().toolTip();
        QString imageTXMPName;

        if(!imageLocation.isEmpty()){

            imageTXMPName = "TXMP" + QFileInfo(imageLocation).baseName();

            this->oniSplitCommands->clear();
            this->oniSplitCommands->append("-create:txmp " + Util::String::insertQuotes(this->wmLocation) + " -format:bgr32 " + Util::String::insertQuotes(imageLocation));

            this->myConverter->start(); // finally process the onisplit commands
            this->myConverter->wait(); // wait for it to complete
        }

        // IGPG
        pugi::xml_node igpgNode = rootNode.append_child("IGPG");

        igpgNode.append_attribute("id").set_value(++currentIGPGId);

        pugi::xml_node igpgFontNode = igpgNode.append_child("Font");
        igpgFontNode.append_child("Family").append_child(pugi::xml_node_type::node_pcdata).set_value("TSFFTahoma");
        igpgFontNode.append_child("Style").append_child(pugi::xml_node_type::node_pcdata).set_value("Bold");
        igpgFontNode.append_child("Color").append_child(pugi::xml_node_type::node_pcdata).set_value("255 127 0");
        igpgFontNode.append_child("Size").append_child(pugi::xml_node_type::node_pcdata).set_value("12");
        igpgFontNode.append_child("Flags").append_child(pugi::xml_node_type::node_pcdata).set_value("Family Style Color Size");

        currentIGSAId = globalSectionCounter;

        igpgNode.append_child("Image").append_child(pugi::xml_node_type::node_pcdata).set_value(QSTR_TO_CSTR(imageTXMPName));
        igpgNode.append_child("Text1").append_child(pugi::xml_node_type::node_pcdata).set_value(QSTR_TO_CSTR("#" + QString::number(++globalSectionCounter)));
        igpgNode.append_child("Text2").append_child(pugi::xml_node_type::node_pcdata).set_value(QSTR_TO_CSTR("#" + QString::number(++globalSectionCounter)));

        // IGSA

        ////// Main Text
        pugi::xml_node igsaMainTextNode = rootNode.append_child("IGSA");
        igsaMainTextNode.append_attribute("id").set_value(++currentIGSAId);
        pugi::xml_node igsaMainTextStringsNode = igsaMainTextNode.append_child("Strings");

        currentIGSTId = globalSectionCounter;

        for(int i=0; i<mainTextNumberOfRows; i++){
            igsaMainTextStringsNode.append_child("Link").append_child(pugi::xml_node_type::node_pcdata).set_value(QSTR_TO_CSTR("#" + QString::number(++globalSectionCounter)));
        }

        ////// Footer
        pugi::xml_node igsaFooterTextNode = rootNode.append_child("IGSA");
        igsaFooterTextNode.append_attribute("id").set_value(++currentIGSAId);
        pugi::xml_node igsaFooterTextStringsNode = igsaFooterTextNode.append_child("Strings");
        for(int i=0; i<footerTextNumberOfRows; i++){
            igsaFooterTextStringsNode.append_child("Link").append_child(pugi::xml_node_type::node_pcdata).set_value(QSTR_TO_CSTR("#" + QString::number(++globalSectionCounter)));
        }

        // IGSt

        auto setIGStXmlSection = [&rootNode, &currentIGSTId](QTextEdit &currentTextEdit, int numberOfRows){

            for(int i=0; i<numberOfRows; i++){

                QTextCursor currentCursor = currentTextEdit.textCursor();
                currentCursor.setPosition(currentTextEdit.document()->findBlockByLineNumber(i).position());
                currentCursor.movePosition(QTextCursor::StartOfLine);
                currentCursor.movePosition(QTextCursor::EndOfLine, QTextCursor::KeepAnchor);
                QTextCharFormat format = currentCursor.charFormat();
                QString colorRGB =  QString::number(format.foreground().color().red()) + " " +
                        QString::number(format.foreground().color().green()) + " " +
                        QString::number(format.foreground().color().blue());
                QString style = (QString(format.fontItalic() ? "Italic " : "") + (format.fontWeight() == QFont::Bold ? "Bold " : "")).trimmed();

                if(style.isEmpty()){
                    style = "Normal";
                }


                pugi::xml_node igstMainTextNode = rootNode.append_child("IGSt");
                igstMainTextNode.append_attribute("id").set_value(++currentIGSTId);

                pugi::xml_node igstMainTextFontNode = igstMainTextNode.append_child("Font");
                igstMainTextFontNode.append_child("Family").append_child(pugi::xml_node_type::node_pcdata).set_value(QSTR_TO_CSTR("TSFF" + format.font().family()));
                igstMainTextFontNode.append_child("Style").append_child(pugi::xml_node_type::node_pcdata).set_value(QSTR_TO_CSTR(style));
                igstMainTextFontNode.append_child("Color").append_child(pugi::xml_node_type::node_pcdata).set_value(QSTR_TO_CSTR(colorRGB));
                igstMainTextFontNode.append_child("Size").append_child(pugi::xml_node_type::node_pcdata).set_value(QSTR_TO_CSTR(QString::number(format.font().pointSize())));
                igstMainTextFontNode.append_child("Flags").append_child(pugi::xml_node_type::node_pcdata).set_value("Family Style Color Size");

                QString currentRowText = currentCursor.selection().toPlainText();

                pugi::xml_node currentIGStNode = igstMainTextNode.append_child("Text");

                if(!currentRowText.trimmed().isEmpty()){
                    currentIGStNode.append_child(pugi::xml_node_type::node_pcdata).set_value(QSTR_TO_CSTR(currentRowText));
                }
                else{
                    // Empty paragraph use OniSplit correct representation (<Text xml:space="preserve"> </Text>)
                    currentIGStNode.append_child(pugi::xml_node_type::node_pcdata).set_value(" ");
                    currentIGStNode.append_attribute("xml:space").set_value("preserve");
                }
            }

        };

        //////  Main Text
        setIGStXmlSection(mainText, mainTextNumberOfRows);

        ////// Footer
        setIGStXmlSection(footerText, footerTextNumberOfRows);
    }

    if(!doc.save_file(QSTR_TO_CSTR(filePath))){
        UtilVago::showAndLogErrorPopUpLogButton("Couldn't create " + filePath + " file!");
        return;
    }

    // Convert XML file to Oni
    this->oniSplitCommands->clear();
    this->oniSplitCommands->append("-create " + Util::String::insertQuotes(this->wmLocation) + " " +  Util::String::insertQuotes(filePath));

    this->myConverter->start(); // finally process the onisplit commands
    this->myConverter->wait(); // wait for it to complete
}

void WmFinalPage::catchOSplitProcessingErrors(QString result, int numErrors){

    if(numErrors!=0){
        QString sNumErrors=QString::number(numErrors);
        if(numErrors>1){
            UtilVago::showErrorPopUpLogButton(result+"\n This is the last of " + sNumErrors + " errors.");
        }
        else{
            UtilVago::showErrorPopUpLogButton(result);
        }
    }
}

void WmFinalPage::connectSlots(){
    //This signal is for thread that is working setup the progress bar (make it visible and set it's min-max)
    connect(this->myConverter, SIGNAL(resultConversion(QString, int)), this, SLOT(catchOSplitProcessingErrors(QString, int)));
    connect(ui->lbComplete, SIGNAL(linkActivated(const QString & )), this, SLOT(openSoundsFolder()));
}

WmFinalPage::~WmFinalPage()
{
    delete this->oniSplitCommands;
    delete this->myConverter;
    delete ui;
}
