/*
Copyright (c) 2007 Matt Williams matt@milliams.com

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License or (at
your option) version 3 or, at the discretion of KDE e.V. (which shall
act as a proxy as in section 14 of the GPLv3), any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#include "keducamainwidget.h"

#include "kqtiassessmenttest.h"
#include "kqtitestpart.h"
#include "kqtiassessmentsection.h"
#include "keducabuilder.h"
#include "kqtiassessmentitem.h"
#include "kqtiassessmentitemref.h"

#include <QStandardItemModel>
#include <QStandardItem>
#include <KIO/NetAccess>
#include <QFile>
#include <kdebug.h>

enum KQtiRole
{
    OBJECT = Qt::UserRole+1, //The meta-object stored in the StandardItem
    OBJECTTYPE = Qt::UserRole+2 //The type of the OBJECT
};

KEducaMainWidget::KEducaMainWidget(QWidget* parent) : QWidget(parent)
{
    setupUi(this);
    connect(testOverviewTreeView, SIGNAL(clicked(const QModelIndex&)), this, SLOT(setWidgetItem(const QModelIndex&)));
    connect(assessmentSectionEditor, SIGNAL(addQuestion(bool)), this, SLOT(addQuestion(bool)));
}

KEducaMainWidget::~KEducaMainWidget()
{
}

void KEducaMainWidget::setAssessmentTest(KQtiAssessmentTest* testItem)
{
    mTestItem = testItem;
    //testTitleEdit->setText(mTestItem->title());
    QStandardItemModel* model = new QStandardItemModel();
    QStandardItem *assessmentTestItem = new QStandardItem(testItem->title());
    foreach(KQtiTestPart* testPart, mTestItem->testParts())
    {
        QStandardItem *testPartItem = new QStandardItem(QString("Test Part"));
        testPartItem->setData(qVariantFromValue(testPart), OBJECT);
        foreach(KQtiAssessmentSection* assessmentSection, testPart->assessmentSections())
        {
            QStandardItem *assessmentSectionItem = new QStandardItem(assessmentSection->title());
            assessmentSectionItem->setData(qVariantFromValue(assessmentSection), OBJECT);
            
            foreach(KQtiSectionPart* sectionPart, assessmentSection->sectionParts())
            {
                //Only assessmentItemRefs are loaded for now.
                if(dynamic_cast<KQtiAssessmentItemRef*>(sectionPart))
                {
                    //If it's an assessmentItemRef, create an assessmentItem with the appropriate contents
                    KQtiAssessmentItemRef* itemRef = dynamic_cast<KQtiAssessmentItemRef*>(sectionPart);
                    
                    KQtiAssessmentItem* assessmentItem = new KQtiAssessmentItem(documentFromFile(QString("%1/%2").
                            arg((KUrl(qobject_cast<KEducaBuilder*>(parent())->url())).directory()). /*base url of test XML file*/
                            arg(itemRef->href())));
                    itemRef->setItem(assessmentItem);
                    
                    QStandardItem *assessmentItemRefItem = new QStandardItem(assessmentItem->title());
                    assessmentItemRefItem->setData(qVariantFromValue(itemRef), OBJECT); //set data
                    assessmentItemRefItem->setData(QString("assessmentItemRef"), OBJECTTYPE); //set data type
                
                    assessmentSectionItem->appendRow(assessmentItemRefItem);
                }
                else if(dynamic_cast<KQtiAssessmentSection*>(sectionPart))
                {
                    //TODO recursively load other sectionParts (e.g. nested assessmentSections)
                    //Do everything inside the most recent foreach loop
                }
            }
            testPartItem->appendRow(assessmentSectionItem);
        }
        assessmentTestItem->appendRow(testPartItem);
    }
    model->setItem(0, assessmentTestItem);
    testOverviewTreeView->setModel(model); //TODO delete old model
    testOverviewTreeView->expandAll();
}

void KEducaMainWidget::setWidgetItem(const QModelIndex& index)
{
    QVariant dataObject = index.data(OBJECT);
    const QStandardItemModel* model = qobject_cast<const QStandardItemModel*>(index.model());
    QStandardItem* item = model->itemFromIndex(index);
    
    if (dataObject.canConvert<KQtiAssessmentItemRef*>())
    {
        //qDebug("Setting up assessmentItem edit widget");
        KQtiAssessmentItemRef* assessmentItemRef = dataObject.value<KQtiAssessmentItemRef*>();
        questionEditor->setItem(assessmentItemRef->item());
        editorStack->setCurrentWidget(questionEditor);
    }
    else if (dataObject.canConvert<KQtiAssessmentSection*>())
    {
        //qDebug("Setting up assessmentSection edit widget");
        KQtiAssessmentSection* assessmentSection = dataObject.value<KQtiAssessmentSection*>();
        assessmentSectionEditor->setSection(assessmentSection);
        assessmentSectionEditor->setTreeItem(item);
        editorStack->setCurrentWidget(assessmentSectionEditor);
    }
    else if (dataObject.canConvert<KQtiTestPart*>())
    {
        KQtiTestPart* testPart = dataObject.value<KQtiTestPart*>();
        //testPartEditor->setSection(testPart);
        editorStack->setCurrentWidget(welcomePage);
    }
    /*else if (data.canConvert<KQti*>())
    {
    }*/
    else
    {
        kDebug() << "Can't convert";
        editorStack->setCurrentWidget(welcomePage);
    }
}

void KEducaMainWidget::addQuestion(bool)
{
    qDebug("Adding a question");
    //Create a KQtiAssessmentItem, create a child on the tree and assign the item to it.
    //TODO make "newItemRef" automatically find an empty numbered value
    KQtiAssessmentItem* assessmentItem = new KQtiAssessmentItem("newItemRef", i18n("New question")); //The assessmentItem to be stored in the model's 'meta-data'
    QStandardItem* assessmentItemRefItem = new QStandardItem(assessmentItem->title()); //The model item
    assessmentItemRefItem->setData(QString("assessmentItemRef"), OBJECTTYPE); //set data type
    qobject_cast<KEducaAssessmentSectionEditor*>(QObject::sender())->treeItem()->appendRow(assessmentItemRefItem); //Add the child tree item
    
    
    //Add a ref to the filename of the new item to QObject::sender()->section().
    KQtiAssessmentItemRef* itemRef = new KQtiAssessmentItemRef(assessmentItem->identifier(), assessmentItem->identifier() + QString(".xml")); //The refItem to be added to the KQti structure
    qobject_cast<KEducaAssessmentSectionEditor*>(QObject::sender())->section()->addSectionPart(itemRef);
    assessmentItemRefItem->setData(qVariantFromValue(itemRef), OBJECT); //set data
    itemRef->setItem(assessmentItem);
}

QList<QStandardItem*> KEducaMainWidget::assessmentItemRefSearch(const QModelIndex& index, QList<QStandardItem*> list) const
{
    for(int row=0; row < index.model()->rowCount(index); row++)
    {
        //If ''index''s child in row ''row'' is an "assessmentItemRef", add it to the list
        //if(index.child(row, 0).data(OBJECTTYPE) == qVariantFromValue(QString("assessmentItemRef")))
        if(index.child(row, 0).data(OBJECT).canConvert<KQtiAssessmentItemRef*>())
        {
            const QStandardItemModel* model = qobject_cast<const QStandardItemModel*>(index.model());
            QStandardItem* item = model->itemFromIndex(index.child(row, 0));
            list.append(item);
        }
        else //otherwise recurse inside...
        {
            QModelIndex childIndex = index.child(row, 0);
            if(childIndex.isValid())
            {
                list = assessmentItemRefSearch(childIndex, list);
            }
        }
    }
    return list;
}

QMap<KQtiAssessmentItem*,KQtiAssessmentItemRef*> KEducaMainWidget::assessmentItemRefs() const
{
    QList<QStandardItem*> list;
    
    const QStandardItemModel* model = qobject_cast<const QStandardItemModel*>(testOverviewTreeView->model());
    
    list = assessmentItemRefSearch(model->index(0,0), list);
    
    QMap<KQtiAssessmentItem*,KQtiAssessmentItemRef*> map;
    
    foreach(QStandardItem* item, list)
    {
        QVariant dataObject = item->data(OBJECT);
        KQtiAssessmentItemRef* assessmentItemRef = dataObject.value<KQtiAssessmentItemRef*>();
        
        map.insert(assessmentItemRef->item(), assessmentItemRef);
    }
    
    return map;
}

QDomDocument KEducaMainWidget::documentFromFile(const QString& fileName)
{
    QString tmpFile;
    QDomDocument doc("document.xml");
    
    if( KIO::NetAccess::download( fileName, tmpFile, this ) )
    {
        QFile file(tmpFile);
        if(!file.open(QIODevice::ReadOnly))
        {
            return QDomDocument();
        }
        doc.setContent(&file);

        KIO::NetAccess::removeTempFile(tmpFile);
        file.close();
    }
    else
    {
        kDebug() << "FileRead::openFile(): download NOT successful: " << fileName << endl;
    }
    return doc;
}

#include "keducamainwidget.moc"
