/***************************************************************************
                          kmess.h  -  description
                             -------------------
    begin                : Sun Jan  5 15:18:36 CST 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 KMESS_H
#define KMESS_H

#include "kmessdebug.h"
#include "kmessinterface.h"

#include <QList>
#include <QHash>
#include <QPointer>

#include <Solid/Networking>

// Forward declarations
class Account;
class AccountAction;
class ChatMaster;
class Contact;
class ContactList;
class NotificationManager;
class ChatHistory;
class ChatNotification;
class ContactStatusNotification;
class NewEmailNotification;
class AddressBookNotifications;
class CurrentAccount;
class IdleTimer;
class InitialView;
class LoginView;
class KMessDBus;
class KMessTest;
class KMessView;
class MsnNotificationConnection;
class NowListeningClient;
class QItemSelection;
class ContactAddedUserDialog;



/**
 * @brief The main window of the application.
 *
 * This class initializes the application and handles
 * all menu actions of the main window.
 *
 * @author Mike K. Bennett
 * @ingroup Root
 */
class KMess : public KMessInterface
{
  Q_OBJECT

  friend class KMessDBus;
  friend class KMessTest;

  public: // Public methods
    // The construtor
                       KMess( QWidget* parent=0 );
    // The destructor
    virtual           ~KMess();
    // Autologin with the first account that has autologin enabled
    void               checkAutologin(QString handle);
    // Initialize the class
    bool               initialize();
    // Check if the connection to the server is active
    bool               isConnected();
    // Something in the code wants to change status. (e.g. command handler.)
    void               changeStatus( Status newStatus, QString autoReplyMessage = QString() );

    //HACK: Remove after 2.0-final
    MsnNotificationConnection *getNsConnection();

  protected:  // Protected methods
    // Load the application's global state
    virtual void       readGlobalProperties( KConfig *sessionConfig );
    // Read in account and other properties
    virtual void       readProperties( const KConfigGroup &config = *((const KConfigGroup *)0) );
    // Save the application's global state
    virtual void       saveGlobalProperties( KConfig *sessionConfig );
    // Save account and other properties
    virtual void       saveProperties( KConfigGroup &config = *((KConfigGroup *)0) );

  private: // Private methods
    // The application is closing, after queryClose() was approved
    void               applicationClosing();
    // Create the program's default directories in .kde/share/apps/
    bool               createDirectories();
    // Initialize the chat master
    bool               initChatMaster();
    // Initialize the emoticon manager
    bool               initEmoticonManager();
    // Initialize the idle timer
    bool               initIdleTimer();
    // Initialize the MSN notification connection
    bool               initMsnNotificationConnection();
    // Initialize notification objects
    bool               initNotifications();
    // Initialize the now listening support.
    bool               initNowListening();
    // Initialize the proxy support.
    bool               initProxy();
    // Initiate a connection to the server. Use connectWithAccount() to connect, not this method.
    void               startConnection( Account *account );
    // Switch the view to the contact list
    void               switchViewToContactList();
    // Switch the view to the initial login screen
    void               switchViewToInitialScreen();

  public slots:
    // Add the account and create the GUI elements
    void               slotAccountAdded( Account *account );
    // An account's settings have been changed
    void               slotAccountChanged( Account *account, QString oldHandle, QString oldFriendlyName );
    // Delete the given account from the UI
    void               slotAccountDeleted( Account *account );

  private slots: // Private slots
    // "Add a new contact" was selected from the menu.
    void               addNewContact();
    // "Add a new group" was selected from the menu.
    void               addNewGroup();
    // A view pictures mode has been selected from the menu.
    void               changedListPictureSize( int mode );
    // A status was selected from the menu.
    void               changeStatus( QAction *action );
    // The current now listening settings have changed.
    void               changedNowListeningSettings();
    // The currently playing song was changed.
    void               changedSong( const QString &artist, const QString &album, const QString &track, bool playing );
    // The status was changed
    void               changedStatus( Account *account = 0 );
    // A view mode has been selected from the menu.
    void               changeViewMode(int mode);

    // Set the caption
    void               setCaptionToUser();
    // Show a "Contact added you" dialog
    void               showContactAddedUserDialog( const QString handle );
    // Show the context-sensitive menu item
    virtual void       showContextMenu();
    // Show "export contact list dialog"
    void               showListExportDialog();
    // Show a dialog before removing the contact
    void               showRemoveContactDialog(QString handle);
    // Show a dialog before removing the group
    void               showRemoveGroupDialog(QString groupId);
    // Show a "Rename group" dialog
    void               showRenameGroupDialog(QString groupId);
#ifdef KMESS_NETWORK_WINDOW
    // Open the network window
    void               showNetworkWindow();
#endif
    // Show the chat history dialog and, if requested, that of a specific contact
    void               showChatHistory( const QString &handle = QString() );
    // Open the transfer manager
    void               showTransferWindow();
    // Detect changes in the status of the internet connection
    void               slotConnectionStatusChanged( Solid::Networking::Status newStatus );
    // The user was presented the "contact added user" dialog and has made a choice
    void               slotContactAddedUserDialogChoice( const QString &handle, const QStringList &groupIds, const int code );
    // A connection has been made with the notification server.
    void               connected();
    // Connect to the server with the given account
    void               connectWithAccount(Account *account);
    // Connect to the server with the given account, possibly temporary or new.
    void               connectWithAccount(QString handle, QString password, bool rememberAccount, bool rememberPassword, bool autologin, Status initialStatus );
    // "Add new account" has been selected from the menu.
    void               createNewAccount();
    // Disconnect was selected from the menu.
    void               disconnectClicked();
    // The program is not connected (initially) or no longer connected (after
    //  a disconnect) to the notification server.
    void               disconnected();
    // Show the settings dialog for a given account
    void               showSettingsForAccount(Account *account);
    // Show the settings dialog for the current account.
    void               showSettingsForCurrentAccount();
    // Show the user's MSN profile.
    void               showUserProfile();
    // The "show allowed contacts" menu item has been toggled.
    void               toggleShowAllowed(bool show);
    // The "show empty groups" menu item has been toggled.
    void               toggleShowEmpty( bool show );
    // The "show history box" menu item has been toggled.
    void               toggleShowHistoryBox(bool show);
    // The "show search in contact list" menu item has been toggled.
    void               toggleShowSearchFrame(bool show);
    // The "show offline contacts" menu item has been toggled.
    void               toggleShowOffline(bool show);
    // The "Show removed contacts" menu item has been toggled.
    void               toggleShowRemoved(bool show);
    // The user has gone idle
    void               userIsIdle();
    // The user is no longer idle
    void               userIsNotIdle();
    // The user wants to reconnect
    void               reconnect();
    // Show the context-sensitive menu item
    void               updateContextMenu( const QItemSelection &selection );

  private: // Private attributes
    // The chat master - the object that controls the chat window
    ChatMaster        *chatMaster_;
    // The menu items of the connect menu
    QHash<Account*,AccountAction*> connectMenuItems_;
    // The notifications manager instance
    NotificationManager        *notificationManager_;
    // The notification object for when a contact sends us a message
    ChatNotification           *chatNotification_;
    // The notification object for when a contact changes its status
    ContactStatusNotification *contactStatusNotification_;
    // The notification object for when a new email is received
    NewEmailNotification       *newEmailNotification_;
    // The notification object for when a new contact added
    AddressBookNotifications     *addressBookNotifications_;
    // Contact added user dialog object
    QPointer<ContactAddedUserDialog> contactAddedUserDialog_;
    // A pointer to the instance of the current account
    CurrentAccount    *currentAccount_;
    // The idle timer
    IdleTimer         *idleTimer_;
    // Whether or not the object has been initialized
    bool               initialized_;
    // The initial login view widget
    InitialView       *initialView_;
    // Whether the user has forced the Idle status or if it's been changed automatically
    bool               isIdleForced_;
    // The now listening client
    NowListeningClient* nowListeningClient_;
    // The connection to the msn notification server
    MsnNotificationConnection *msnNotificationConnection_;
    // The main view widget
    KMessView         *view_;
    // The DBus class
    KMessDBus         *dbus_;
};

#endif
