/***************************************************************************
                          contact.h  -  description
                             -------------------
    begin                : Sun Jan 5 2003
    copyright            : (C) 2003 by Mike K. Bennett
    email                : mkb137b@hotmail.com
 ***************************************************************************/

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

#include "contactbase.h"

#include <QStringList>


// Forward declarations
class MsnObject;
class ContactExtension;

class KConfigGroup;


/**
 * @brief Data class for contact information.
 *
 * Each contact of the ContactList is represented by a Contact object.
 * It stores the data received from the MSN Messenger servers,
 * and maintains the state of the contact. Contacts are organized in the following lists:
 * - The Allow List (<code>AL</code>) contains all contacts who may see your online state.
 * - The Block List (<code>BL</code>) contains all contacts who are denied to contact you.
 * - The Friends List (<code>FL</code>) contains all contact who are visible in the contact list window.
 * - The Reverse List (<code>RL</code>) contains all contacts who added you.
 * - The Pending List (<code>PL</code>) contains all contact who are not moved to another list yet.
 *
 * The main contact list window (KMess class, KMessView widget) only displays contacts who are in the Friends List (this can be configured).
 * The contacts in the Friends List can be added to multiple groups.
 * Note the difference here between the terms "lists" and "groups";
 * groups are only filled with contacts of the Friends List.
 *
 * When properties change, the representive signals are fired so the user interface
 * can update (a Model-View-Controller design).
 * The controller is the MsnNotificationConnection, the view is the ContactListViewItem class.
 *
 * Users can also specify additional properties for their contacts.
 * Those settings are saved in the ContactExtension class,
 * and not part of the server-side contact properties.
 * This class strictly stores the data from the MSN Messenger servers only.
 *
 * @author Mike K. Bennett
 * @ingroup Contact
 */
class Contact : public ContactBase
{
  Q_OBJECT

  public: // Public constants

  // Contact list constants
  enum MsnContactLists
  {
    MSN_LIST_FRIEND  = 1,   // The contact is visible in the contact list (was added to FL list)
    MSN_LIST_ALLOWED = 2,   // The contact is only allowed                (was added to AL list)
    MSN_LIST_BLOCKED = 4,   // The contact is blocked                     (was added to BL list)
    MSN_LIST_REVERSE = 8,   // The contact has you on his/hers list       (added by server to RL list)
    MSN_LIST_PENDING = 16   // The contact is on a pending list, should be added to AL/FL or BL
  };


  public: // Public methods
    // The constructor
                        Contact( const QString& handle, const QString& friendlyName, int lists,
                                 const QStringList& groupIds, const QString& guid );
    // The destructor
    virtual             ~Contact();
    // Add the groupID to the list of current groups
    void                 addGroupId(const QString &groupId);
    // Return the contact's display picture, scaled to the right size for the contact list.
    QPixmap &             getScaledDisplayPicture();
    // Return the path to the contact's picture
    const QString        getContactPicturePath() const;
    // Return the current media type
    const QString &      getCurrentMediaType() const;
    // Return the current media type
    const QString &      getCurrentMediaString() const;
    // Return a pointer to the extension class
    ContactExtension    *getExtension() const;
    // Return the contact's friendly name
    const QString&       getFriendlyName( FormattingMode mode = STRING_CLEANED ) const;
    // Return the group ID's the contact is added to
    const QStringList&   getGroupIds() const;
    // Return the contact's globally unique identifier
    const QString &      getGuid() const;
    // Return the contact's information
    const QVariant       getInformation( const QString &information ) const;
    // Return the contact's previous status
    Status               getLastStatus() const;
    // Return the contact's personal message
    const QString &      getPersonalMessage( FormattingMode mode = STRING_CLEANED ) const;
    // Return the contact's status
    Status               getStatus() const;
    // Return the contact's true friendly name, regardless of extension
    const QString&       getTrueFriendlyName( FormattingMode mode = STRING_CLEANED ) const;
    // Return an MSN Object
    const MsnObject*     getMsnObject() const;
    // Whether or not the contact is allowed
    bool                 isAllowed() const;
    // Whether or not the contact is blocked
    bool                 isBlocked() const;
    // Whether or not the contact is on the friends list
    bool                 isFriend() const;
    // Whether the contact is a Messenger user
    bool                 isMessengerUser() const;
    // Whether or not the contact is on the pending list
    bool                 isPending() const;
    // Whether or not the contact is on the reverse list
    bool                 isReverse() const;
    // Setup and load a string representing an MSNObject
    void                 loadMsnObject( QString msnObject );
    // Load cached state for a contact
    void                 readProperties( const KConfigGroup &config );
    // Remove the group from the list of group IDs
    void                 removeGroupId(const QString &groupId);
    // Save cached state for for a contact
    void                 saveProperties( KConfigGroup &config );
    // Set whether or not the contact is allowed
    void                 setAllowed(bool allowed);
    // Set whether or not the contact is blocked
    void                 setBlocked(bool blocked);
    // Set whether or not the contact is on the friends list
    void                 setFriend(bool isFriend);
    // Change the contact's friendly name
    void                 setFriendlyName(QString newName);
    // Set whether or not the contact is a Messenger user
    void                 setMessengerUser( bool isMessengerUser );
    // Change the GUID of the contact, this is only known when the contact is added to the friends list.
    void                 setGuid(const QString &guid);
    // Set the extra information retrieved by soap response
    void                 setInformations( const QHash<QString, QVariant> &informations );
    // Set wether or not the contact is on pending list
    void                 setPending( bool isPending );
    // Set the contacts Personal message
    void                 setPersonalStatus(const QString &message, const QString &mediaType = QString::null, const QString &mediaString = QString::null);
    // Set whether or not the contact is on the reverse list
    void                 setReverse(bool reverse);
    // Set the contact's status
    void                 setStatus( const Status newStatus, bool showBaloon = true );

  private: // Private attributes
    // Whether or not the contact is "allowed"
    bool                 allowed_;
    // Whether or not the contact is blocked
    bool                 blocked_;
    // The current media type
    QString              currentMediaType_;
    // The current media type
    QString              currentMediaString_;
    // The extensions class
    ContactExtension    *extension_;
    // Whether or not the contact is a friend
    bool                 friend_;
    // The contact's group id
    QStringList          groupIds_;
    // The contact's globally unique identifier
    QString              guid_;
    // Extra informations
    QHash<QString, QVariant> informations_;
    // Whether the contact is a Messenger user
    bool                 isMessengerUser_;
    // The previous contact's status of the contact
    Status               lastStatus_;
    // Name of the original group when the contact is being moved
    QString              movingFrom_;
    // msn object
    MsnObject           *msnObject_;
    // Whether or not the contact is on the pending list
    bool                 pending_;
    // The contact's personal message
    FormattedString      personalMessage_;
    // Whether or not the contact is on the reverse list
    bool                 reverse_;
    // The contact's online status
    Status               status_;
    // the contact's scaled display picture.
    QPixmap               scaledDisplayPicture_;
    // the scaled size of the dp (used for caching)
    int                  scaledDPSize_;

  private slots:
    void                 slotChangedPicture();
    void                 slotEmoticonSettingsChanged();

  signals: // Public signals
    // Signal that the contact may have changed list affiliation
    void                 changedList(Contact *contact);
    // Signal that the contact may have moved to a different group
    void                 changedGroup(Contact *contact);
    // Signal that the contact's msnobject has changed
    void                 changedMsnObject(Contact *contact);
    // Signal that the contact may have changed it's personal message
    void                 changedPersonalMessage(Contact *contact);
    // Signal if the contact goes offline
    void                 contactOffline(Contact *contact, bool showBaloon);
    // Signal if the contact goes online
    void                 contactOnline(Contact *contact, bool showBaloon);
};

#endif
