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

    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 SCRIPTINGCONTAINER_H
#define SCRIPTINGCONTAINER_H

#include <QObject>

#include <keduvoccontainer.h>

namespace Scripting
{

    /**
     * @class Container
     * @brief KEduVocContainer wrapping class for Kross scripts (inherited by Lesson)
     *
     * This class should not be used directly by a script but through Lesson class which inherits all the Container's properties. See Lesson class documentation.
     *
     * @author Avgoustinos Kadis <avgoustinos.kadis@kdemail.net>
     */
    class Container : public QObject
    {
            Q_OBJECT
            /// Container name
            Q_PROPERTY ( QString name READ name WRITE setName )
            /// Boolean value if lesson is in Practice or not
            Q_PROPERTY ( bool inPractice READ inPractice WRITE setInPractice )
            /// Container image URL
            Q_PROPERTY ( QString imageUrl READ imageUrl WRITE setImageUrl )
//             Q_PROPERTY ( QVariantList childContainers READ childContainers )
        public:

            Container ( KEduVocContainer * container = 0 );

            /* copy constructor for d-pointer safe copying */
//             Container ( const Container &other );

//             Container ( const QString& name, KEduVocContainer::EnumContainerType type, KEduVocContainer *parent = 0 );

            ~Container();

            /* destructor */
//             virtual ~KEduVocContainer();

            /* assignment operator */
//             KEduVocContainer& operator= ( const KEduVocContainer& );

            /* equality operator */
//             bool operator== ( const KEduVocContainer &other );


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

            static QList<KEduVocContainer*>  flattenContainer ( KEduVocContainer * root );

            KEduVocContainer * kEduVocContainer() { return m_container; }

            static bool enumToBool ( KEduVocContainer::EnumEntriesRecursive recursive );
            static KEduVocContainer::EnumEntriesRecursive boolToEnum ( bool recursive );

            /* set the container name
             * @param name text to set for the name
             */
            void setName ( const QString &name ) { m_container->setName ( name ); }

            /* get the container name */
            QString name() { return m_container->name(); }

            void appendChildContainer ( Container *child ) { m_container->appendChildContainer ( child->kEduVocContainer() ); }
            void insertChildContainer ( int row, Container *child ) { m_container->insertChildContainer ( row,child->kEduVocContainer() ); }
//             void deleteChildContainer ( int row ) { m_container->deleteChildContainer ( row ); }
            void removeChildContainer ( int row ) { m_container->removeChildContainer ( row ); }
            Container *childContainer ( int row ) { return new Container ( m_container->childContainer ( row ) ); }

            /*
             * Retrieve a child container by its name
             * Returns 0 if no container is found
             * @param name container name
             * @return the child container
             */
            Container *childContainer ( const QString& name ) { return new Container ( m_container->childContainer ( name ) ); }

            int childContainerCount() const { return m_container->childContainerCount(); }

            bool inPractice() { return m_container->inPractice(); }
            void setInPractice ( bool inPractice ) { m_container->setInPractice ( inPractice ); }

            /* get the image url for this container if it exists */
            QString imageUrl() { return m_container->imageUrl().path(); }

            /* set the image url for this container
             * @param url               url of the image
             */
            void setImageUrl ( const QString & url ) { m_container->setImageUrl ( url ); }

            /* finds the container with the given name */
            KEduVocContainer * findContainer(const QString& name);

            /*
             * Removes a translation. This has to be called when a language is removed from a document.
             * @param translation
             */
            void removeTranslation ( int translation ) { return m_container->removeTranslation ( translation ); }

            /*
             * Returns a list with all the child containers (lessons)
             * @return A list of Container objects
             */
            QVariantList childContainers();


        public slots:

            /** Returns an integer, the Container's unique row. Useful for Lesson::removeChildLesson() function */
            int row() const { return m_container->row(); }

//             virtual Container *parent() { return new Container ( m_container->parent() ); }

            /*
             * The type of this container. @see EnumContainerType
             * @return
             */
//             KEduVocContainer::EnumContainerType containerType();

            /*
             * Set the type of container.
             * For convenience by default this is taken over from the parent, so no need to set.
             * @param type the new type
             */
//             void setContainerType ( KEduVocContainer::EnumContainerType type );

            /**
             * Returns how many expressions of language with index @p translation have grade as @p grade
             * @param translation language index
             * @param grade grade
             * @return A number that represents the number of expressions of that grade
             */
            int expressionsOfGrade ( int translation, unsigned int grade, bool recursive ) { return m_container->expressionsOfGrade ( translation,grade, boolToEnum ( recursive ) ); }

            /**
             * Remove grades from all entries of this lessons
             * @param translation which translation to remove. -1 for all.
             * @param recursive whether to include child lessons
             */
            void resetGrades ( int translation, bool recursive ) { return m_container->resetGrades ( translation, boolToEnum ( recursive ) ); }

            /**
             * Returns the average grade of the specified @p translation considering all the lesson entries
             * @param translation language index
             * @return A double, the average lesson grade
             */
            double averageGrade ( int translation, bool recursive ) { return m_container->averageGrade ( translation, boolToEnum ( recursive ) ); }

        protected:
            KEduVocContainer * m_container;
    };

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

}


#endif
