/***************************************************************************
                          configlist.h  -  description
                             -------------------
    begin                : Tue May 9 2000
    copyright            : (C) 2000-2001 by Eggert Ehmke
                           (C) 2007 by Ulrich Weigelt
    email                : eggert.ehmke@berlin.de
                           ulrich.weigelt@gmx.de

    26 Sep 2002 - Allow for columns to be hidden. Allistar Melville
 ***************************************************************************/

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

//Qt header
#include <qptrlist.h>
#include <qlistview.h>
#include <qobject.h>

//KDE headers
#include <kcombobox.h>
#include <kprocess.h>
#include <kdebug.h>

//KShowmail headers
#include "configelem.h"
#include "constants.h"
#include "kshowmailview.h"
#include "types.h"
#include "encryption.h"
#include "kwalletaccess.h"
#include "filteritem.h"
#include "headerfilter.h"
#include "filterlog.h"

using namespace Constants;
using namespace Types;
using namespace Encryption;

class ConfigElem;
class KshowmailView;

/**
 * Contains the application and account settings. The account
 * settings are stored in ConfigElem objects.
 * @author Eggert Ehmke
 * @author Ulrich Weigelt
 */
class ConfigList : public QObject, public QPtrList<ConfigElem>
{

  Q_OBJECT

  public:

    /**
    * Constructor.
    */
    ConfigList ();

    /**
    * Destructor
    */
    virtual ~ConfigList () {};

    /**
     * Reads the setup from the configuration file (kshowmailrc) and
     * sets the properties.
     * @param view pointer to the account list view
     */
    void refreshSetup( KListView* view );

    /**
     * Reloads the filter settings
     */
    void refreshFilterSetup();

    /**
    * Returns the auto refresh time interval.
    * @return refresh time interval [minutes]
    */
    int getRefreshTimeInterval() const;

    /**
    * Sets the auto refresh time interval.
    * @param interval the new time interval [minutes]
    */
    void setRefreshTimeInterval( unsigned int interval );

    /**
    * Returns whether auto refresh is on.
    * @return TRUE - auto refresh is on; FALSE - auto refresh is off
    */
    bool AutoRefreshOn() const;

    /**
     * Sets whether the user has to confirm a deletion.
     * @param confirm TRUE - user has to confirm; FALSE - the user does not have to confirm
     */
    void setConfirmDeletion( bool confirm );

    /**
     * Returns whether the user has to confirm a deletion.
     * @return TRUE - the user has to confirm
     * @return FALSE - the user does not have to confirm
     */
    bool confirmDeletion();

    /**
     * Returns whether the user has to confirm window close.
     * @return TRUE - user has to confirm
     * @return FALSE - user does not have to confirm
     */
    bool confirmClose() const;

    /**
     * Returns whether the app shall start minimized.
     * @return TRUE - start minimized
     * @return FALSE - don't start minimized
     */
    bool startMinimized() const;

    /**
     * Returns whether the close button leaves the application running in tray.
     * @return TRUE - leaves running
     * @return FALSE - app will be closed
     */
    bool closeToTray() const;

    /**
     * Returns whether minimizes to the tray rather than to the taskbar.
     * @return TRUE - minimizes to the tray
     * @return FALSE - minimizes to the taskbar
     */
    bool minimizesToTray() const;

    /**
     * Returns whether connection errors will be shown during refresh.
     * @return TRUE - show errors
     * @return FALSE - don't show errors
     */
    bool showConnectionErrors() const;

    /**
     * Sets whether the mail show dialog has to use HTML.
     * @param allowHTML TRUE - the dialog has to use HTML; FALSE - the dialog must not use HTML
     * @see m_bAllowHTML
     * */
    void setAllowHTML( bool allowHTML );

    /**
     * Returns whether the mail show dialog has to use HTML.
     * @return TRUE - the dialog has to use HTML
     * @return FALSE - the dialog must not use HTML
     * @see m_bAllowHTML
     */
    bool allowHTML() const;

    /**
     * Returns whether there are active accounts.
     * Doesn't set the current account.
     * @return TRUE - Yes, there are active accounts (at least one :o) ); FALSE - no active accounts
     */
    bool hasActiveAccounts();

    /**
     * Returns the number of seconds the application will be wait for a pop3 job.
     * @return seconds to timeout
     */
    uint getTimeoutTime() const;

    /**
     * Sets the number of seconds the application will be wait for a pop3 job.
     * Minimum time is POP3_MINIMUM_TIMEOUT_TIME seconds.
     * @param time seconds to timeout
     * @see constants.h
     */
    void setTimeoutTime( uint time );

    /**
     * Returns the first account, for which an appropriate item is
     * selected in the account list view.
     * @return pointer to the selected account object
     * @return NULL - no account is selected
     */
    ConfigElem* getSelectedAccount();

    /**
     * Deletes all selected mails from the servers and the mail lists.
     * This just starts the deletion and returns after then. When all
     * accounts are ready the signal sigDeleteReady will be emitted.
     */
    void deleteSelectedMails();

    /**
     * Connects the signals of the accounts with the slots of this
     * class.
     * It is necessary to do this after an account has been appended to the
     * list and it is a good idea to call this method before you invoke
     * an operation on an account that may emit a signal.
     * The reason is that the pointer list seemingly often changes the
     * adresses of the inserted accounts. After that the connections are corrupt.
     */
    void connectAccounts();

    /**
     * Returns the subjects of the selected mails.
     * @return subjects of selected mails
     */
    QStringList getSelectedSubjects() const;

    /**
     * Returns whether there are mails in this list which are selected
     * in the list view.
     * @return TRUE - there are selected mails
     * @return FALSE - there aren't selected mails
     */
    bool hasSelectedMails();

    /**
     * Downloads and shows the bodies of the selected mails.
     * This just starts the download and returns after then. When all
     * bodies are downloaded and shown the signal sigShowBodiesReady will be
     * emitted.
     */
    void showSelectedMails();

    /**
     * Refreshes the mail list of all accounts.
     * This just starts the refresh and returns after then. When all
     * accounts have refreshed their mail list the signal sigRefreshReady will be
     * emitted.
     * @param log Pointer to the filter log.
     */
    void refreshMailLists( FilterLog* log = NULL );

    /**
     * Returns the number of new mails.
     * @return number of new mails
     */
    int getNumberNewMails();

    /**
     * Returns the number of mails.
     * @return number of mails
     */
    int getNumberMails();

    /**
     * Returns the total size of all mails.
     * @return total size
     */
    long getTotalSize();

    /**
     * Creates for every mail a list view item and inserts it
     * into the mail list view.
     * @param view pointer to the application view
     */
    void fillMailListView( KshowmailView* view );

    /**
     * Returns whether the main window will be shown, if
     * new mails was received.
     * @return TRUE - main window will be shown
     * @return FALSE - main window will not be shown
     */
    bool showMainWindowForNewMails();

    /**
     * Returns whether an alert message will be shown if
     * new mails were received.
     * @return TRUE - will be shown
     * @return FALSE - will not be shown
     */
    bool showAlertMessageForNewMails();

    /**
     * Returns whether the app will be terminated if
     * no new mails were received.
     * @return TRUE - will be terminated
     * @return FALSE - will not be terminated
     */
    bool quitNoNewMails();

    /**
     * Returns whether the main window will be minimized, if
     * no new mails were received.
     * @return TRUE - main window will be minimized
     * @return FALSE - main window will not be minimized
     */
    bool minimizeMainWindowNoNewMails();

    /**
     * Returns the configured time to the first refresh.
     * @return time to the first refresh (seconds)
     */
    int getInitTime();

    /**
     * Sets the time to the first refresh.
     * @param time time (seconds) to the first refresh
     */
    void setInitTime( int time );

    /**
     * Returns whether a time to first refresh is configured.
     * @return TRUE - init time configured
     * @return FALSE - no init time configured
     */
    bool hasInitTime();

    /**
     * Refreshes the account list (number of mails and total size).
     */
    void refreshAccountList();

    /**
     * Kills all running pop3 jobs.
     */
    void killPOP3Jobs();

    /**
     * Shows the headers of all selected mails.
     */
    void showSelectedHeaders();

    /**
     * Executes the configure new mail command.
     * Does nothing, if the command option is switched off (m_bCommand == false).
     */
    void executeNewMailCommand();

    /**
     * Returns whether all new mails will keep new status until the app is closed.
     * @return TRUE - mails keep new status at next refresh
     * @return FALSE - mails don't keep new status at next refresh
     */
    bool keepNew();

    /**
     * Prints the setup.
     */
    void printSetup();

    /**
     * Saves the current mails data and the account setups.
     * The mails data will be saved into an XML file (kshowmail.xml).
     * The account setups will be saved into the application config file (kshowmailrc).
     */
    void saveOptions();

    /**
     * Reads stored mails data.
     * At every setup saving (e.g. at exit) the mails data will be stored into the file kshowmail.xml.
     * At application start we read this file to identify mails which are not new at first refresh.
     */
    void readStoredMails();

    /**
     * Returns the action to used on spam mails
     * @return action to used on spam mails
     */
     FilterAction_Type getSpamAction();

    /**
     * Returns the mailbox for spam mails
     * @return mailbox for spam
     */
     QString getSpamMailbox();

    /**
      * Returns the number of deleted mails by last refresh.
      * @return number of deleted mails by last refresh
      */
     int numberDeletedMailsLastRefresh();

    /**
      * Returns the number of deleted mails since start.
      * @return number of deleted mails since start
      */
     int numberDeletedMailsStart();

    /**
      * Returns the number of moved mails by last refresh.
      * @return number of moved mails by last refresh
      */
     int numberMovedMailsLastRefresh();

    /**
      * Returns the number of moved mails since start.
      * @return number of moved mails since start
      */
     int numberMovedMailsStart();

    /**
      * Returns the number of ignored mails by last refresh.
      * @return number of ignored mails by last refresh
      */
     int numberIgnoredMails();

    /**
     * Returns the senders of the selected mails
     * @return senders of the selected mails
     */
     QStringList getSelectedSenders() const;

	bool setItem (const char* item);
	void setList (QListView* list);
	void beep ();
	void playSound ();
	void playSound (const char* file);


  private:

    /**
     * Connector to the configuration file
     */
    KConfig* config;

    /**
     * Time in minutes to the next automatic refresh.
     */
    int m_nIntervalTimer;

    /**
     * Number of seconds the application will wait for a pop3 job to complete.
     */
    uint m_nPop3Timer;

    /**
     * This map is used by the delete methods.
     * deleteSelectedMails() clears it and after that inserts for every account
     * an item. The Key is the account name and the data is TRUE.
     * When slotCheckDeletionState() is invoked by a signal sent by an account,
     * this slot will set the appropriate item data to FALSE. If the data of all
     * items are set to FALSE, the method will know all accounts have ended the
     * deletion and will emit sigDeleteReady.
     * @see deleteSelectedMails()
     * @see slotCheckDeletionState()
     */
    AccountTaskMap_Type AccountDeletionMap;

    /**
     * This map is used by the methods to show the mail body.
     * showSelectedMails() clears it and after that inserts for every account
     * an item. The Key is the account name and the data is TRUE.
     * When slotCheckShowBodiesState() is invoked by a signal sent by an account,
     * this slot will set the appropriate item data to FALSE. If the data of all
     * items are set to FALSE, the method will know all accounts have shown the
     * mail body and will emit sigShowBodiesReady.
     * @see showSelectedMails()
     * @see slotCheckShowBodiesState()
     */
    AccountTaskMap_Type AccountShowBodiesMap;

    /**
     * This map is used by the methods to refresh the account mail lists.
     * refreshMailLists() clears it and after that inserts for every account
     * an item. The Key ist the account name and the data is TRUE.
     * When slotCheckRefreshState() is invoked by a signal sent by an account,
     * this slot will set the appropriate item data to FALSE. If the data of all
     * items are set to FALSE, the method will know all accounts have refreshed their
     * mail list and will emit sigRefreshReady.
     * @see refreshMailLists()
     * @see slotCheckRefreshState()
     */
    AccountTaskMap_Type AccountRefreshMap;

    /**
     * TRUE - the user has to confirm a deletion,
     * FALSE - the user does not have to confirm a deletion
     */
    bool m_bConfirmDelete;

    /**
     * TRUE - allow HTML formatting in the mail show dialog box
     * FALSE - don't allow HTML formatting
     * @see setAllowHTML()
     * @see allowHTML()
     */
    bool m_bAllowHTML;

    /**
     * Number of windows, which have been opened by the accounts to show mails.
     * Used by slotMessageWindowOpened() and slotMessageWindowClosed().
     * @see slotMessageWindowOpened
     * @see slotMessageWindowClosed
     */
    int ctrOpenMessageWindows;

    /**
     * Contains the time (seconds) to first refresh.
     * @see setInitTime()
     * @see getInitTime()
     */
    int m_nInitTimer;

    /**
     * TRUE - If a new mail is arrived an alert window will be shown.
     */
    bool m_bShowMessage;

    /**
     * TRUE - If a new mail is arrived the main window will be shown.
     */
    bool m_bShowMainWindow;

    /**
     * TRUE - If a new mail is arrived the system will beep.
     */
    bool m_bBeep;

    /**
     * TRUE - If a new mail is arrived a sound will be played.
     */
    bool m_bSound;

    /**
     * Sound file which will be played if a new mail is arrived.
     */
    QString m_strSoundFile;

    /**
     * TRUE - If a new mail is arrived a command will be executed.
     */
    bool m_bCommand;

    /**
     * Path to command which will be executed if a new mail is arrived.
     */
    QString m_strCommandPath;

    /**
     * TRUE - If no new mail is arrived the application will be ended.
     */
    bool m_bTerminate;

    /**
     * TRUE - If no new mail is arrived the main window will be minimized.
     */
    bool m_bMinimize;

    /**
     * TRUE - If a connection error occures during refresh an error message will be shown.
     */
    bool m_bShowConnectionErrors;

    /**
     * TRUE - The user has to confirm window close.
     */
    bool m_bConfirmClose;

    /**
     * TRUE - the app starts minimized.
     */
    bool m_bStartMinimized;

    /**
     * TRUE - the close button leaves the application running in tray
     */
    bool m_bCloseMinimizes;

    /**
     * TRUE - minimizes to the tray rather than to the taskbar
     */
    bool m_bMinimizeToTray;

    /**
     * TRUE - mails keep new until termination
     */
    bool m_bKeepNew;

    /**
     * Mailbox for Spam, if configured
     */
     QString spamMailbox;

    /**
     * Action which shall be done, if the mail is Spam
     */
      FilterAction_Type spamAction;


  protected:

    /**
     * Makes a copy from the given account object and returns the pointer to it.
     * Reimplementation of QPtrList::newItem().
     * Used by QPtrList to add new items.
     * @param item account object
     * @return pointer to the new account object
     */
    virtual QCollection::Item newItem( QCollection::Item item );

    /**
     * Compares two ConfigElem objects.
     * Reimplementation of QPtrList::compareItems(). Used by inSort().
     * @param item1 account 1
     * @param item2 account 2
     * @return 0 if account name 1 == account name 2
     * @return nonzero if account name 2 != account name 2
     */
    virtual int compareItems( QCollection::Item item1, QCollection::Item item2 );

    /**
     * Returns whether the given account is in the list
     * @param name name of the searched account
     * @return TRUE - account is existent
     * @return FALSE - account is not existent
     */
    bool hasAccount( const QString& name ) const;

    /**
     * Returns the pointer to the account named like the given name.
     * @param name of the searched account
     * @return account or NULL, if the account was not found
     */
    ConfigElem* getAccount( const QString& name ) const;

  protected slots:

    /**
     * Connected with signal sigConfigChanged of all accounts.
     * Emits the signal sigConfigChanged.
     */
    void slotAccountConfigChanged();

    /**
     * Connected with signal sigDeleteReady of all accounts.
     * When an account has sent this signal its appropriate item
     * in AccountDeletionMap will set to FALSE.
     * When all accounts have done the deletion it will emit signal
     * sigDeleteReady.
     * @param account name of the account which has emitted the signal
     * @see AccountDeletionMap
     */
    void slotCheckDeletionState( QString account );

    /**
     * Connected with signal sigShowBodiesReady of all accounts.
     * When an account has sent this signal its appropriate item
     * in AccountShowBodiesMap will set to FALSE.
     * When all accounts have shown the mail it will emit signal
     * sigShowBodiesReady.
     * @param account name of the account which has emitted the signal
     * @see AccountShowBodiesMap
     */
    void slotCheckShowBodiesState( QString account );

    /**
     * Connected with signal sigMessageWindowOpened of all accounts.
     * When an account has sent this signal the counter ctrOpenMessageWindows
     * will be incremented.
     * When the counter was incremented from zero (the first window was opened)
     * the signal sigMessageWindowOpened will be emitted.
     * @see ctrOpenMessageWindows
     * @see sigMessageWindowOpened
     */
    void slotMessageWindowOpened();

    /**
     * Connected with signal sigMessageWindowClosed of all accounts.
     * When an account has sent this signal the counter ctrOpenMessageWindows
     * will be decremented.
     * When the counter has reached zero the signal sigAllMessageWindowsClosed
     * will be emitted.
     * @see ctrOpenMessageWindows
     * @see sigAllMessageWindowsClosed
     */
    void slotMessageWindowClosed();

    /**
     * Connected with signal sigRefreshReady of all accounts.
     * When an account has sent this signal its appropriate item
     * in AccountRefreshMap will set to FALSE.
     * When all accounts have refreshed their mail list it will emit
     * signal sigRefreshReady.
     * @param account name of the account which has emitted the signal
     * @see AccountRefreshMap
     */
    void slotCheckRefreshState( QString account );

  signals:

    /**
     * Will be emitted when the configuration of an account or of the app
     * was changed.
     */
    void sigConfigChanged();

    /**
     * Will be emitted when all selected mails are deleted.
     */
    void sigDeleteReady();

    /**
     * Will be emitted when all selected mails are shown.
     */
    void sigShowBodiesReady();

    /**
     * Will be emitted by slotMessageWindowOpened when an account has
     * opened a window to show a mail.
     * @see slotMessageWindowOpened
     */
    void sigMessageWindowOpened();

    /**
     * Will be emitted by slotMessageWindowClosed when all accounts have
     * closed their windows to show mails.
     * @see slotMessageWindowClosed
     */
    void sigAllMessageWindowsClosed();

    /**
     * Will be emitted, when all accounts have refreshed their mail list.
     */
    void sigRefreshReady();

};

#endif
