/***************************************************************************
                          contactlistmodelitem.h  -  description
                             -------------------
    begin                : Sat Feb 16 2008
    copyright            : (C) 2008 by Valerio Pilo
    email                : valerio@kmess.org
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   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 CONTACTLISTMODELITEM_H
#define CONTACTLISTMODELITEM_H

#include <QString>
#include <QVariant>


// Forward declarations
class Contact;
class Group;
class ContactListModelItem;


// Custom types
typedef QMap<QString, QVariant> ModelDataList;
typedef QList<ContactListModelItem *> ModelItemList;



// Custom operator to display nodes and items in the debug output
QDebug operator<<( QDebug s, const ContactListModelItem *item );



/**
 * This class represent a Contact List node or leaf in the Model/View paradigm.
 *
 * The Model is a way to universally represent data which could be reused later by different views:
 * for example, the contact list, or a list of contacts available to be invited in a chat. The data is
 * organized in form of a tree, with a root element containing the user's groups, and the contacts within
 * the groups.
 * The Model Item is an element of the tree. It can assume the role of a root element, of a node (a group) or
 * of a contact (a leaf).
 * The data output by the model items can be easily expanded for future uses.
 *
 * @author Valerio Pilo <valerio@kmess.org>
 * @ingroup Contact
 */
class ContactListModelItem
{
  public:  // Public enumerations
    enum ItemType
    {
      ItemRoot     = -1      // This element should be unique, it contains no object
    , ItemGroup    =  1      // Groups have this item type
    , ItemContact  =  2      // Contacts have this type
    };
    enum DataRoles
    {
      DataRole     = Qt::DisplayRole  // Role used to retrieve the actual object data
    , SortRole     = Qt::UserRole + 1 // Role used to obtain sorting data
    , SearchRole   = Qt::UserRole + 2 // Role used to obtain searching data
    };


  public:  // Public methods
    // Contact constructor, creates a root item
                                  ContactListModelItem();
    // Contact constructor, creates a Contact item
    explicit                      ContactListModelItem( Contact *contact, ContactListModelItem *parent = 0 );
    // Group constructor, creates a Group item
    explicit                      ContactListModelItem( Group *group, ContactListModelItem *parent = 0 );
    // Destructor
                                 ~ContactListModelItem();
    
    // Return a child item identified by its row
    ContactListModelItem         *child( int row );
    // Return a child Contact identified by its handle
    ContactListModelItem         *childContact( const QString &handle );
    // Return all Contact children identified by an handle
    ModelItemList                 childContacts( const QString &handle );
    // Return the number of children of this item
    int                           childCount() const;
    // Return a child Group identified by its ID
    ContactListModelItem         *childGroup( const QString &id );
    // Return all Groups children
    ModelItemList                 childGroups();
    // Return the number of data columns
    int                           columnCount() const;
    // Return a collection of data from this item
    const QVariant                data( int role ) const;
    // Return the type of the internal stored object
    ItemType                      getType() const;
    // Move this item to another parent
    void                          moveTo( ContactListModelItem *newParent );
    // Return the stored object
    void                         *object() const;
    // Get the parent node of this item
    ContactListModelItem         *parent() const;
    // Get this item's position within the parent node
    int                           row() const;

  private:  // Private methods
    // Add a new child item
    void                          appendChild( ContactListModelItem *child );
    // Remove a child item
    int                           removeChild( ContactListModelItem *child );

  private:  // Private properties
    // The internal list of the item's children
    ModelItemList                 childItems_;
    // Pointer to the parent node
    ContactListModelItem         *parentNode_;
    // Pointer to this item's data
    void                         *object_;
    // Type of the contained data
    ItemType                      itemType_;
};

#endif
