/***************************************************************************
                          kmessview.h  -  description
                             -------------------
    begin                : Thu Jan 9 2003
    copyright            : (C) 2003 by Mike K. Bennett
                           (C) 2005 by Diederik van der Boor
    email                : mkb137b@hotmail.com
                           vdboor --at-- codingdomain.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 KMESSVIEW_H
#define KMESSVIEW_H

#include <qwidget.h>
#include <qpixmap.h>
#include <qtooltip.h>
#include "kmessviewinterface.h"

// Forward declarations
class CurrentAccount;
class Contact;
class ContactList;
class Group;
class QListViewItem;
class QToolTip;
class ContactListViewItem;
class GroupListViewItem;
class KMessView;

class KAction;
class KActionMenu;
class KPopupMenu;

/**
 * The main view widget containing the contact list KListView and user status and email displays.
 * @author Mike K. Bennett
 */
class KMessView : public KMessViewInterface
{
  Q_OBJECT

  public:
    // The constructor
                     KMessView(QWidget *parent=0, const char *name=0);
    // The destructor
    virtual         ~KMessView();
    // The program is connected to the server.  Store the user account and
    //  update the user information.
    void             connected();
    // Called when the program has disconnected from the server.
    void             disconnected();
    // Initialize the class
    bool             initialize(const ContactList *contactList);

  private: // Private methods
    // Fix the sort positions, by making them incremental again.
    void             fixGroupSortPositions();
    // Return the contact associated with the given item
    Contact *        getContactByItem(QListViewItem *item) const;
    // Find out whether the contact is added to the group item
    ContactListViewItem * getContactItemInGroup(const QListViewItem *groupItem, const Contact *contact) const;
    // Return the group associated with the given item
    Group *          getGroupByItem(QListViewItem *item) const;
    // Return the special group the contact should be placed in.
    QString          getMetaGroupId(const Contact *contact) const;
    // Find the first group in the first
    GroupListViewItem *findFirstGroup() const;
    // Find the next group in the list
    GroupListViewItem *findNextGroup(GroupListViewItem *previousGroup) const;
    // Initialize the contact list view
    bool             initContactListView();
    // Initialize the contact popup
    bool             initContactPopup();
    // Initialize the group popup
    bool             initGroupPopup();
    // Rebuild the contents of the move-contact menu.
    void             rebuildMoveMenu(const Contact *copntact);

  private slots: // Private slots
    // Send an e-mail to the current contact.
    void             slotEmailContact();
    // The email label was clicked so open the user's preferred email url
    void             slotEmailLabelClicked();
    // Called when a contact was added.
    void             slotContactAdded(Contact *contact);
    // Called when a contact went online or offline
    void             slotContactChangedOnline(Contact *contact);
    // Called when a contact is m
    void             slotContactMoved(Contact *contact);
    // Called when a contact is removed
    void             slotContactRemoved(const Contact *contact);
    // A list item was right clicked.
    void             slotContextMenu(QListViewItem *item, const QPoint &point, int col);
    // A item was selected
    void             slotItemClicked(QListViewItem *item);
    // A list item was executed
    void             slotItemExecuted(QListViewItem *item);
    // Forward the "add contact" menu action
    void             slotForwardAddContact();
    // Forward the "allow contact" menu action
    void             slotForwardAllowContact();
    // Forward the "block contact" menu action
    void             slotForwardBlockContact();
    // Called when a contact should be moved
    void             slotForwardMoveContact(Group *group);
    // Forward the "remove contact" menu action
    void             slotForwardRemoveContact();
    // Forward the "remove group" menu action
    void             slotForwardRemoveGroup();
    // Forward the "rename group" menu action
    void             slotForwardRenameGroup();
    // Forward the "start chat" menu action
    void             slotForwardStartChat();
    // Forward the "unblock contact" menu action
    void             slotForwardUnblockContact();
    // Called when a group was added
    void             slotGroupAdded(Group *group);
    // Called when a group was removed
    void             slotGroupRemoved(const Group *group);
    // Called when a group should move down
    void             slotMoveGroupDown();
    // Called when a group should move up
    void             slotMoveGroupUp();
    // Display the profile of the current contact
    void             slotShowContactProfile();
    // Display the properties of the current contact
    void             slotShowContactProperties();
    // Change whether the allowed,removed groups are displayed.
    void             slotUpdateDisplaySettings();
    // Change whether the email label is displayed based on account settings.
    void             slotUpdateEmailDisplay();
    // Update the email count.
    void             slotUpdateNoEmails();
    // Update the user's status.
    void             slotUpdateUserStatus();
    // Update the way contact groups are displayed
    void             slotUpdateViewMode();

  private: // Private attributes
    // KActions used in the contact popup menu
    KAction         *addContact_;
    KAction         *allowContact_;
    KAction         *blockContact_;
    KAction         *unblockContact_;
    KAction         *chatWithContact_;
    KAction         *msnProfile_;
    KAction         *removeContact_;
    KAction         *emailContact_;
    KAction         *contactProperties_;
    // KActions uses in the group popup menu
    KAction         *moveGroupDown_;
    KAction         *moveGroupUp_;
    KAction         *removeGroup_;
    KAction         *renameGroup_;
    // The contact list
    const ContactList *contactList_;
    // The menu of actions possible to perform on a given contact
    KPopupMenu      *contactActionPopup_;
    // The menu of actions possible to perform on a given group
    KPopupMenu      *groupActionPopup_;
    // KSelectActions used in the contact popup menu
    KActionMenu     *moveContactToGroup_;
    // A pointer to the instance of the current account
    CurrentAccount  *currentAccount_;
    // Whether or not the object has been initialized
    bool             initialized_;
    // The background pixmap
    QPixmap          backgroundPixmap_;

    // Private class for tooltips
    class ToolTip : public QToolTip
    {
      public:
        ToolTip( KMessView *kmessView, QToolTipGroup *group = 0 );
        virtual ~ToolTip();
      protected:
        void maybeTip(const QPoint &p);
      private:
        KMessView   *kmessView_;
    };

    // Reference to the current tooltip
    ToolTip         *toolTip_;

  signals:
    void             addContact(QString handle);
    void             allowContact(QString handle);
    void             blockContact(QString handle);
    void             startChat(QString handle);
    void             moveContact(QString handle, QString fromGroupId, QString toGroupId);
    void             removeContact(QString handle);
    void             removeGroup(QString groupId);
    void             renameGroup(QString groupId);
    void             unblockContact(QString handle);
};

#endif
