#include <QFile>
#include <QXmlStreamReader>
#include <QDomDocument>
#include <QMessageBox>
#include "doctaskswidget.h"
#include "ui_doctaskswidget.h"

DocTasksWidget::DocTasksWidget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::DocTasksWidget)
{
    ui->setupUi(this);

    treeWidget = new QTreeWidget();

    connect(treeWidget, &QTreeWidget::currentItemChanged, this, &DocTasksWidget::on_treeWidget_currentItemChanged);

    ui->horizontalLayout_2->addWidget(treeWidget);

    preparationTreeWidget();

    loadDocTasksFromXML();

    updateTreeWidget();
}

DocTasksWidget::~DocTasksWidget()
{
    deleteAllModuls();
    delete ui;
}

void DocTasksWidget::on_treeWidget_currentItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous)
{
    if(current == nullptr)
        return;

    int id = current->text(ColumnsTree::clmn_ID).toInt();

    Module* module = searchModuleByID(id);

    if(module)
    {
        QString type = "Code";
        QString code = "";

        if(module->getType() == ModuleType::TYPE_PM)
        {
            PM* PMmodul = static_cast<PM*>(module);
            type = "PM";
            code = PMmodul->pmCode();
        }
        else
        {
            DM* DMmodul = static_cast<DM*>(module);
            type = "DM";
            code = DMmodul->dmCode();
        }

        ui->label->setText(type + " Code");
        ui->editCode->setText(code);
    }
}

void DocTasksWidget::domElementParser(QDomElement element, Module* moduleParent)
{
    QString name;

    QDomElement childElement = element.firstChildElement();
    if(childElement.isNull())
        return;

    Module* module = nullptr;

    do
    {
        name = childElement.nodeName();

       QDomNamedNodeMap nodeMap = childElement.attributes();

       if(name == "pm")
       {
           module = new PM();
           PM* PMmodul = static_cast<PM*>(module);

           PMmodul->initialize(nodeMap.namedItem("modelIdentCode").nodeValue(),
                               nodeMap.namedItem("pmIssuer").nodeValue(),
                               nodeMap.namedItem("pmNumber").nodeValue(),
                               nodeMap.namedItem("pmVolume").nodeValue());

           if(moduleParent)
           {
               PMmodul->setParentModule(moduleParent);

               PM* PMmodulParent = static_cast<PM*>(moduleParent);
               PMmodulParent->addChildModule(module);
           }
       }
       else if(name == "dm")
       {
           module = new DM();
           DM* DMmodul = static_cast<DM*>(module);

           DMmodul->initialize(nodeMap.namedItem("modelIdentCode").nodeValue(),
                               nodeMap.namedItem("systemDiffCode").nodeValue(),
                               nodeMap.namedItem("systemCode").nodeValue(),
                               nodeMap.namedItem("subSystemCode").nodeValue(),
                               nodeMap.namedItem("subSubSystemCode").nodeValue(),
                               nodeMap.namedItem("assyCode").nodeValue(),
                               nodeMap.namedItem("disassyCode").nodeValue(),
                               nodeMap.namedItem("disassyCodeVariant").nodeValue(),
                               nodeMap.namedItem("infoCode").nodeValue(),
                               nodeMap.namedItem("infoCodeVariant").nodeValue(),
                               nodeMap.namedItem("itemLocationCode").nodeValue());

           if(moduleParent)
           {
               DMmodul->setParentModule(moduleParent);

               PM* PMmodulParent = static_cast<PM*>(moduleParent);
               PMmodulParent->addChildModule(module);
           }
       }
       else if(name == "rus" || name == "eng")
       {
           if(moduleParent)
           {
               if(moduleParent->getType() == ModuleType::TYPE_PM)
               {//PM
                   PM* PMmodulParent = static_cast<PM*>(moduleParent);

                   if(name == "rus")
                        PMmodulParent->setLangStructRus(nodeMap.namedItem("title").nodeValue());
                   else
                        PMmodulParent->setLangStructEng(nodeMap.namedItem("title").nodeValue());
               }
               else
               {//DM
                   DM* DMmodulParent = static_cast<DM*>(moduleParent);

                   if(name == "rus")
                        DMmodulParent->setLangStructRus(nodeMap.namedItem("techName").nodeValue(),
                                                        nodeMap.namedItem("infoName").nodeValue(),
                                                        nodeMap.namedItem("pdf").nodeValue(),
                                                        nodeMap.namedItem("bookmark").nodeValue(),
                                                        nodeMap.namedItem("xml").nodeValue());
                   else
                       DMmodulParent->setLangStructEng(nodeMap.namedItem("techName").nodeValue(),
                                                       nodeMap.namedItem("infoName").nodeValue(),
                                                       nodeMap.namedItem("pdf").nodeValue(),
                                                       nodeMap.namedItem("bookmark").nodeValue(),
                                                       nodeMap.namedItem("xml").nodeValue());
               }
           }

       }

        domElementParser(childElement, module);

        if(moduleParent == nullptr)
            listAllModules.append(module);

    }while (! (childElement = childElement.nextSiblingElement()).isNull());
}

void DocTasksWidget::loadDocTasksFromXML()
{
    QDomDocument docTasksDOM;
    QString xmlFileName = "./docs.xml";
    QFile xmlInFile(xmlFileName);
    if (!xmlInFile.open(QFile::ReadOnly | QFile::Text))
    {
        QMessageBox::critical(nullptr, tr("Attention!"), tr("The file could not be opened ") + xmlFileName);
        return;
    }
    else
    {
        docTasksDOM.setContent(xmlInFile.readAll());
        xmlInFile.close();

        QDomElement manifestElement = docTasksDOM.firstChildElement("manifest");
        if(manifestElement.isNull())
            return;

        //deleteAllModuls();

        domElementParser(manifestElement, nullptr);
    }
}

void DocTasksWidget::deleteAllModuls()
{
    for(Module* module: listAllModules)
    {
        if(module->getType() == ModuleType::TYPE_PM)
            delete static_cast<PM*>(module);
        else
            delete static_cast<DM*>(module);
    }
    listAllModules.clear();
}

Module *DocTasksWidget::searchModuleByID(int id)
{
    Module* ptrModule = nullptr;

    for(Module* module: listAllModules)
    {
        ptrModule = module->getModuleByID(id);
        if(ptrModule)
            return ptrModule;
    }

    return nullptr;
}

void DocTasksWidget::preparationTreeWidget()
{
    treeWidget->setColumnCount(2);

    reSetHeadTreeWidget();

    //treeWidget->header()->setStyleSheet(QStringLiteral("font-size: 10pt;"));
    treeWidget->setStyleSheet(QStringLiteral("font-size: 10pt;"
                                             "font-family: Tahoma;"));

    treeWidget->setColumnWidth(ColumnsTree::clmn_ID, 80);
    treeWidget->setColumnWidth(ColumnsTree::clmn_PMorDM, 900);

    //treeWidget->setColumnHidden(ColumnsTree::clmn_ID, true);
}

void DocTasksWidget::reSetHeadTreeWidget()
{
    QStringList listHeaders = {tr("PM/DM"), tr("ID")};
    treeWidget->setHeaderLabels(listHeaders);
}

void DocTasksWidget::updateTreeWidget()
{
    //Обновление дерева
    treeWidget->clear();

    for(Module* module : listAllModules)
    {
        addModuleToTreeWidget(module);
    }
}

void DocTasksWidget::addModuleToTreeWidget(Module *module, QTreeWidgetItem* parentItem)
{
    QTreeWidgetItem* itemModule = nullptr;

    QString text;
    QString ID = QString::number(module->getID());

    if(parentItem)
    {
        itemModule = new QTreeWidgetItem();
        parentItem->addChild(itemModule);
    }
    else
    {
        itemModule = new QTreeWidgetItem(treeWidget);
    }

    if(module->getType() == ModuleType::TYPE_PM)
    {
        PM* PMmodul = static_cast<PM*>(module);
        text = PMmodul->getLangStructRus().title;

        for(Module* module : PMmodul->getListChildModules())
        {
            addModuleToTreeWidget(module, itemModule);
        }
    }
    else
    {
        DM* DMmodul = static_cast<DM*>(module);
        text = DMmodul->getLangStructRus().techName;
    }

    itemModule->setText(ColumnsTree::clmn_PMorDM, text);
    itemModule->setText(ColumnsTree::clmn_ID, ID);
}

