/***************************************************************************
 *   Copyright (C) 2007 by Arnold Kraschinski                              *
 *   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 Street, Fifth Floor, Boston, MA 02110-1301, USA.          *
 ***************************************************************************/


#ifndef VERBSELECTION_H
#define VERBSELECTION_H

#include <QList>
#include <QStringList>
#include <QTreeWidgetItem>
#include <QTabWidget>

#include "verbdata.h"

class QGridLayout;
class QCheckBox;
class KConfigDialog;
class KLineEdit;
//class KPushButton;
class VerbSelection;
class MyTreeWidgetItem;

/**
 * This struct is used in the TabView of the configuratino
 * dialogue. It brings together the different controls on the two
 * tabs of the dialogue and the corresponding verb.
 */
struct MappingInfo
{
    Verb*              verb;
    MyTreeWidgetItem*  alphabetItem;
    MyTreeWidgetItem*  grammarItem;
    MyTreeWidgetItem*  selectedItem;
    /** To use the QtAlgorithms qSort function it is necessary to implement operator<()  The
     * criteria to sort MappingInfo objects is the order of the verb->infinitives.
     *
     * @param m the MappingInfo object which should be compared
     * @return if the this object is smaller than the argument object
     */
    bool operator<(const MappingInfo& m) const { return *verb < *(m.verb); };
};

/**
 * MyTreeWidgetItem is a child of QTreeWidgetItem. 
 *
 * @short part of the kverbos configuration dialogue
 * @author Kraschinski Arnold <arnold.kra67@gmx.de>
 * @version 2.00.00
 */
class MyTreeWidgetItem : public QTreeWidgetItem
{
public:
    MyTreeWidgetItem (MappingInfo* map, QTreeWidgetItem* parent, const QStringList& strings, int type = Type );
    MyTreeWidgetItem (MappingInfo* map, QTreeWidget* parent, const QStringList& strings, int type = Type);
    virtual ~MyTreeWidgetItem();
    /** For each item exists a MappingInfo which contains information about the Verb
     *  and the QTreeWidgetItems that are displaying this verb. 
     *
     * @return a pointer to a MappingInfo
     */
    MappingInfo* mappingInfo() { return m_mappingInfo; };
    /**
     * @param partner a pointer to the MappingInfo that belongs to the verb
     */
    void setMappingInfo(MappingInfo* mappingInfo) { m_mappingInfo = mappingInfo; };
private:
    MappingInfo*        m_mappingInfo;
};

/**
 * MyTabWidget is a child of QTabWidget. It has an additional property and 
 * according read and write functions. 
 *
 * @short part of the kverbos configuration dialogue
 * @author Kraschinski Arnold <arnold.kra67@gmx.de>
 * @version 2.00.00
 */
class MyTabWidget : public QTabWidget
{
    Q_OBJECT
    Q_PROPERTY (QStringList verbselection READ verblist WRITE setVerblist USER true)
public:
    MyTabWidget (QWidget* parent = 0);
    virtual ~MyTabWidget();
    /** get the list of the selected verbs from the MyTabWidget.
     *
     * @return the list of the selected verbs
     */
    QStringList verblist();
    /** Send the list of the selected verbs to the MyTabWidget
     *
     * @param list the list of the selected verbs
     */
    void setVerblist(QStringList verbselection);
    /** Add a verb to the list of selected verbs or remove it from the list. The
     *  pointer to the verb is stored in the MappingInfo. The MappingInfo contains
     *  pointer to all related MyTreeWidgetItems, too.
     *
     * @param map the MappingInfo with the information about the verb and MyTreeWidgetItems
     * @param add if true, the verb is added to the list, if false, the verb is removed from the list
     */
    void handleVerb(MappingInfo* map, bool add);
signals:
    /** The signal is necessary to intergrate the class into the standard KDE
     *  KConfigDialogue
     */
    void settingsChanged();
    void changed();
private:
    QStringList                 verbselection;
    QList<Verb*>                m_selection;
    VerbSelection*              m_parent;
    QTreeWidgetItem*            m_partner;
};

/**
 * VerbSelection is part of the KVerbos configuration dialogues.
 * The user can select the verbs for the training and he can
 * get an overview over his selected verbs.
 *
 * @short part of the kverbos configuration dialogue
 * @author Kraschinski Arnold <arnold.kra67@gmx.de>
 * @version 2.00.00
 */
class VerbSelection : public QWidget
{
    Q_OBJECT
public:
    explicit VerbSelection(QWidget *parent);
    ~VerbSelection();
    /** Block the signals from the QTreeWidgets: selectedTree, alphabetTree and grammarTree
     *
     *  @param block if true the signals are blocked, if false they aren't blocked
     */
    void blockTreeSignals(bool block);
    /** Search a Mappinginfo in the m_map list, that belongs to a given verb object
     *
     *  @param verb a pointer to a verb object
     */
    MappingInfo* findMap(Verb* verb);
    /** Go through the alphabet-tree and the grammar-tree and test the check state
     *  of all parent elements according to its child elements
     */
    void checkAllParentItems();
private:
    /** Adjust the width of the columns in the QTreeWidget.
     *
     *  @param w Pointer to the QTreeWidget where the column width has to be adjusted.
     */
    void adjustColumnWidth(QTreeWidget* w);
    /** An item in the QTreeWidget has been changed now other items have to be
     *  adopted to the change. 
     *
     *  @param item the item that has been changed
     */
    void changeItem(QTreeWidgetItem* item);
    /** Find out which QT::CheckState all the items in an array should have.
     *
     *  @param a an array of items
     *  @param n the number of items in the array
     */
    void findAllCheckState(QTreeWidgetItem* a[], int n);
    /** Find out which QT::CheckState an item should have according to its child
     *  elements.
     *
     *  @param item the item that has to be checked
     */
    void findCheckState(QTreeWidgetItem* item);

public slots:
    /** If the checkstate of one of the items in the QTreeWidgets is changed this
     *  function makes sure that the parent or the children are adapted.
     * 
     *  @param current the current QTreeWidgetItem that has been changed
     *  @param int the column of the current item that has been changed
     */
    void itemChanged(QTreeWidgetItem* current, int column);

signals:
    /** The signal is necessary to intergrate the class into the standard KDE
     *  KConfigDialogue
     */
    void settingsChanged();
    void changed();

private:
    KConfigDialog*          m_parent;
    QTreeWidgetItem*        m_alphabetItem[26];
    QTreeWidgetItem*        m_grammarItem[GROUPCOUNT];
    QList<MappingInfo*>     m_map;

public:
    QGridLayout             *gridLayout;
    QTabWidget              *kcfg_verbselection;
    KLineEdit               *infinitiveLine;
    //KPushButton             *selectAll;
    //KPushButton             *dropAll;
    QWidget                 *selected;
    QGridLayout             *gridLayout1;
    QTreeWidget             *selectedTree;
    QWidget                 *alphabet;
    QGridLayout             *gridLayout2;
    QTreeWidget             *alphabetTree;
    QWidget                 *grammar;
    QGridLayout             *gridLayout3;
    QTreeWidget             *grammarTree;
        
    static const int ParentTypeAlphabet;
    static const int ParentTypeGrammar;
    static const int ChildType;
    static const int VerbType;
};



#endif

