/***************************************************************************

    Copyright 2008 Avgoustinos Kadis <avgoustinos.kadis@kdemail.net>

 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   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.                                   *
 *                                                                         *
 ***************************************************************************/
#ifndef SCRIPTINGEXPRESSION_H
#define SCRIPTINGEXPRESSION_H

#include <keduvocexpression.h>

#include "lesson.h"

#include <QObject>
#include <QVariantList>

namespace Scripting
{

    class Translation;

    /**
    * This class represents

        @author Avgoustinos Kadis <avgoustinos.kadis@kdemail.net>
    */
    class Expression : public QObject
    {
            Q_OBJECT
            /// Parent lesson (if any)
            Q_PROPERTY ( QObject * lesson READ lesson )
            /// Specifies if the entry is active or not (enabled for queries or not)
            Q_PROPERTY ( bool active READ isActive WRITE setActive )
//             Q_PROPERTY ( int sizeHint READ sizeHint WRITE setSizeHint)
        public:
            /* default constructor for an empty vocabulary expression
             */
            Expression ();

            /* Constructor for a vocabulary expression with one translation
             *
             * @param expression       translation
             */
            Expression ( const QString & expression );

            /*
             * Constructor for vocabulary expression with more than one translation
             * @param translations
             */
            Expression ( const QStringList & translations );

            Expression ( const Expression & other );

            /*
             * Constructor from a KEduVocExpression (doesn't exist in KEduVocExpression)
             * @param expression KEduVocExpression object
             */
            Expression ( KEduVocExpression * expression );

            ~Expression();

            KEduVocExpression * kEduVocExpression() const { return m_expression; }

            template <class T, class S>
            QVariantList toVariantList ( QList<T*> objList ) const;

            //Property: lesson [get method - read-only]
            QObject * lesson() const { return new Lesson ( m_expression->lesson() ); }

            /* returns flag if entry is activated for queries */
            bool isActive() const { return m_expression->isActive(); }
            /* set entry active (enabled for queries) */
            void setActive ( bool flag = true ) { m_expression->setActive ( flag ); }

            //Property: sizeHing [get/set methods] (not implemented in KEduVocExpression)
            //int sizeHint() const { return m_expression->sizeHint(); }
            //void setSizeHint( int sizeHint ) { m_expression->setSizeHint(sizeHint); }

            //for assignlable type
//             Expression & operator= ( const Expression &other );
//             bool operator== ( const Expression &other ) const;

        public slots:

            /** reset all grades of the entry
             * @param index     identifier (language)
             */
            void resetGrades ( int index ) { m_expression->resetGrades ( index ); }

            //not implemented in KEduVocExpression
//             void setTranslation( int index, QObject* translation );

            /**
             * Add a translation to this expression
             * @code
             * #how to set translations of an entry with setTranslation(index,expression)
             * import Parley
             * lesson = Parley.doc.findLesson("Lesson 2")
             * if lesson != None:
             *     new_entry = lesson.newEntry()
             *     new_entry.setTranslation(0,"day")
             *     new_entry.setTranslation(0,"jour")
             *     lesson.appendEntry(new_entry)
             * @endcode
             * @param index            number of translation = the identifier
             * @param expression       the translation
             */
            void setTranslation ( int index, const QString &expression )
            {
                m_expression->setTranslation ( index,expression );
            }

            /**
             * Sets the translations of an entry. All previous translations are removed
             * @code
             * #how to set the translations of an entry
             * import Parley
             * new_entry = Parley.activeLesson.newEntry()
             * new_entry.setTranslations(["good morning","bonjour"])
             * Parley.activeLesson.appendEntry(new_entry)
             * @endcode
             * @param translations A list of strings with the translations (must be in correct language order)
             */
            void setTranslations ( QStringList translations );

            /**
             * removes a translation
             * @code
             * #how to remove all the translations of a language from a lesson
             * import Parley
             * for entry in Parley.activeLesson.entries(True):
             *     entry.removeTranslation(1)
             * @endcode
             * @param index            number of translation 1..x
             */
            void removeTranslation ( int index ) { m_expression->removeTranslation ( index ); }

            /**
             * Get the translation of a specified @p index (translation index)
             * @param index of the language identifier
             * @return A Translation object
             */
            QObject* translation ( int index ) const;

            /** Returns a list of integers (the translation indices) */
            QVariantList translationIndices() const;

            /**
             * Returns a list of all the translations of an entry
             * @code
             * #iterate through all the translations of all the entries of the root lesson and print their text
             * for entry in Parley.doc.rootLesson.entries(True):
             *    for tr in entry.translations():
             *        print tr.text
             * @endcode
             * @return A list of Translation objects
             */
            QVariantList translations() const;

            /**
             * Returns a list of all the translations texts of an entry
             * @code
             * #iterate through all the translations of all the entries of the root lesson and print their text
             * for entry in Parley.doc.rootLesson.entries(True):
             *     print entry.translationTexts()
             * @endcode
             * @return A list of strings (list of translation.text property of every translation)
             */
            QStringList translationTexts() const;

        private:
            KEduVocExpression* m_expression;
    };

    //Template functions should not be separated from their definition (must be in the header file)
    template <class T, class S>
    QVariantList Expression::toVariantList ( QList<T*> objList ) const
    {
        QVariantList list;
        foreach ( T * t, objList )
        {
            QObject * obj = new S ( t );
            list.push_back ( qVariantFromValue ( obj ) );
        }
        return list;
    }


}

#endif
