/***************************************************************************
 *   Copyright (C) 2004 by Kraschinski Arnold                              *
 *   arnold.kra67@gmx.de                                                   *
 *                                                                         *
 *   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) 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, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   51 Franklin Steet, Fifth Floor, Boston, MA 02110-1301, USA.           *
 ***************************************************************************/

// Qt header files
#include <QWidget>
#include <QLayout>
#include <QFile>
#include <QTextStream>
#include <QVector>

// KDE header files
#include <khtml_part.h>
#include <khtmlview.h>
#include <kurl.h>
#include <klocale.h>
#include <kstandarddirs.h>
#include <kdebug.h>
#include <kurl.h>
#include <kmessagebox.h>

//#include <dom/dom_node.h>
#include <dom/html_document.h>
#include <dom/html_element.h>
#include <dom/html_misc.h>
#include <dom/html_form.h>
#include <dom/dom_string.h>

// Project header files
#include "gaptrainer.h"
#include "verbdata.h"
#include "kverbossettings.h"


const int          GapTrainer::EXPECTING_INPUT = 0;
const int          GapTrainer::CORRECTED = 1;
const int          GapTrainer::CORRECT_FORMS = 2;
const int          GapTrainer::SOLVED = 3;


GapTrainer::GapTrainer(QWidget *parent )
: Trainer(parent)
{
    QGridLayout* qVerbViewLayout = new QGridLayout( this );
    qVerbViewLayout->setContentsMargins( 0, 0, 0, 0 );
    
    m_htmlRenderer = new KHTMLPart(this);
    qVerbViewLayout->addWidget(m_htmlRenderer->view(), 0, 0);
    
    connect( m_htmlRenderer , SIGNAL( nodeActivated(DOM::Node)), this, SLOT(slotNodeActivated(DOM::Node)) );
}

GapTrainer::~GapTrainer()
{
    delete m_htmlRenderer;
    m_htmlRenderer = 0;
}

bool GapTrainer::setExercise(QString exerciseFile)
{
    m_exerciseName = exerciseFile.left( exerciseFile.lastIndexOf(".") );
    //kDebug() << "This is the exercise name: " << m_exerciseName;

    exerciseFile = KStandardDirs::locate("appdata", "exercises/" + exerciseFile );
    m_htmlRenderer->openUrl( KUrl( exerciseFile ) );

    m_givenPoints = 0;
    m_mode = EXPECTING_INPUT;
    m_solution = false;
    emit signalSetNextText( i18n("Correct Input") );
    return true;
}

void GapTrainer::next()
{
    switch (m_mode) {
    case CORRECT_FORMS:
    case EXPECTING_INPUT:
        {
            QString file = KStandardDirs::locate("appdata", "exercises/" + m_exerciseName + ".solution");
            //kDebug() << "This is the solution file name: " << file;
            QDomDocument* m = new QDomDocument();
            QFile solutionFile( file );
            if ( (!solutionFile.open(QIODevice::ReadOnly)) || ( !m->setContent( &solutionFile ) ) ) {
                KMessageBox::information( this, i18n("Could not find the solution file %1. Please check your installation.", file ) );
                emit allExercisesAreDone();
            } else {
                solutionFile.close();
                
                QDomNodeList exerciseNodes = m->elementsByTagName( "exercise" );
                int n = exerciseNodes.size();
                //kDebug() << "Anzahl der Übungsknoten: " << n;

                DOM::HTMLElement body = (m_htmlRenderer->htmlDocument()).body();
                DOM::NodeList nodes = body.getElementsByTagName( "INPUT" );
                //kDebug() << nodes.length() << " so viele input elemente sind es.";
                int points = nodes.length();
                int correct = 0;

                for (unsigned int i = 0; i < nodes.length(); i++) {
                    DOM::HTMLInputElement in = (DOM::HTMLInputElement)nodes.item(i);
                    QString exerciseName = in.name().string();
                    //kDebug() << "Übungsname: " << exerciseName;
                    bool found = false;
                    for (int j = 0; j < n; j++) {
                        QDomElement elem = exerciseNodes.at( j ).toElement();
                        if ( !elem.isNull() ) {
                            if ( elem.attribute( "name" ) == exerciseName ) {
                                if ( elem.attribute( "value" ) == in.value().string() ) {
                                    in.setReadOnly( true );
                                    correct++;
                                } else {
                                    in.addCSSProperty("color", "red");
                                }
                                found = true;
                                break;
                            }
                        }
                    }
                    if ( !found ) {
                        kDebug() << "Couldn't find the solution for an exercise";
                    }
                }
                //kDebug() << "Punkte: " << points << " korrekt: " << correct;
                emit someExerciseSolved( (m_givenPoints == 0) ? points : correct - m_givenPoints,
                                          correct - m_givenPoints );
                m_givenPoints = correct;
                if ( points == correct ) {
                    m_mode = SOLVED;
                    emit signalSetNextText( i18n("Next Task") );
                } else {
                    m_mode = CORRECTED;
                    emit signalSetNextText( i18n("Show Solution") );
                }
                m_htmlRenderer->view()->repaint();
            }
        }
        break;
    case CORRECTED:
        {
            QString file = KStandardDirs::locate("appdata", "exercises/" + m_exerciseName + ".solution");
            //kDebug() << "This is the solution file name: " << file;
            QDomDocument m;
            QFile solutionFile( file );
            if ( (!solutionFile.open(QIODevice::ReadOnly)) || ( !m.setContent( &solutionFile ) ) ) {
                KMessageBox::information( this, i18n("Could not find the solution file %1. Please check your installation.", file ) );
                emit allExercisesAreDone();
            } else {
                solutionFile.close();
                
                QDomNodeList exerciseNodes = m.elementsByTagName( "exercise" );
                int n = exerciseNodes.size();
                //kDebug() << "Anzahl der Übungsknoten: " << n;

                DOM::HTMLElement body = (m_htmlRenderer->htmlDocument()).body();
                DOM::NodeList nodes = body.getElementsByTagName( "INPUT" );
                //kDebug() << nodes.length() << " so viele input elemente sind es.";

                for (unsigned int i = 0; i < nodes.length(); i++) {
                    DOM::HTMLInputElement in = (DOM::HTMLInputElement)nodes.item(i);
                    QString exerciseName = in.name().string();
                    //kDebug() << "Übungsname: " << exerciseName;
                    bool found = false;
                    for (int j = 0; j < n; j++) {
                        QDomElement elem = exerciseNodes.at( j ).toElement();
                        if ( !elem.isNull() ) {
                            if ( elem.attribute( "name" ) == exerciseName ) {
                                in.setValue( elem.attribute( "value" ) );
                                found = true;
                                break;
                            }
                        }
                    }
                    if ( !found ) {
                        in.setValue( "" );
                    }
                }
            }
        }
        emit signalSetNextText( i18n("Next Task") );
        m_mode = SOLVED;
        break;
    case SOLVED:
        emit allExercisesAreDone();
        break;
    default:
        kDebug() << "There is no mode like this: " << m_mode << endl;
    }
}

void GapTrainer::slotVerbChanged()
{
}

void GapTrainer::slotVerbEntered(const QString &s)
{
    kDebug() << s;
}

void GapTrainer::slotChar(QString ch)
{
    kDebug() << ch;
}

void GapTrainer::slotNodeActivated(DOM::Node /*node*/ )
{
    // Is this interesting for us? <TODO>
    //kDebug() << "A Node has been activated. " << node.nodeName();
    
    // There is a bug in KHTML so the INPUT-Element can not be activated
    // with the mouse only with the TAB-Button but for that reason
    // it does not work to allow the user to correct his mistages.
/*
    if ( (m_mode = CORRECTED) || (m_mode = CORRECT_FORMS ) ) {
        DOM::HTMLElement elem = (DOM::HTMLElement)node;
        elem.removeCSSProperty( "color" );
        m_mode = CORRECT_FORMS;
        emit signalSetNextText( i18n("Correct Input") );
    }
    */
}


#include "gaptrainer.moc"
