/***************************************************************************
                          configelem.h  -  description
                             -------------------
    begin                : Tue May 9 2000
    copyright            : (C) 2000-2001 by Eggert Ehmke
    email                : eggert.ehmke@berlin.de
 ***************************************************************************/

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

//C headers
#include <time.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>

//QT headers
#include <qstring.h>
#include <qlistview.h>
#include <qdom.h>
#include <qobject.h>
#include <qtimer.h>
#include <qregexp.h>
#include <qdir.h>
#include <qfile.h>
#include <qtextstream.h>

//KDE headers
#include <kurl.h>
#include <kconfig.h>
#include <kdebug.h>
#include <kpassdlg.h>
#include <kio/job.h>
#include <kio/global.h>
#include <kmessagebox.h>
#include <kapplication.h>

//KShowmail headers
#include "showrecord.h"
#include "constants.h"
#include "types.h"
#include "configlist.h"
#include "showmaildialog.h"
#include "decodeRFC2047.h"
#include "kshowmailview.h"
#include "encryption.h"
#include "kwalletaccess.h"
#include "headerfilter.h"
#include "filterlog.h"



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

//forward class declarations
class KshowmailView;
class ConfigList;
class ShowRecordElem;
class ShowRecord;

/**
 * @brief Represents a mail account.
 *
 * Contains all datas of the account like server, user password and so on.
 * It also contains the mails read from the server.
 * Used in class ConfigList and ConfigAccounts.
 *
 * @see ShowRecord
 * @see ConfigList
 * @see ConfigAccounts::Accounts
 * @author Eggert Ehmke <eggert.ehmke@berlin.de>
 * @author Ulrich Weigelt <ulrich.weigelt@gmx.de>
 */
class ConfigElem : public QObject {

  Q_OBJECT

  public:

    /**
     * Returned by showSelectedHeaders(), if the user has
     * clicked OK.
     */
    static const int continueShowHeaders;

    /**
     * Returned by showSelectedHeaders(), if the user has
     * clicked Cancel.
     */
    static const int cancelShowHeaders;

    /**
     * General Constructor
     * Warning: The pointer to the application configuration (ConfigList)
     * will not be set.
     */
    ConfigElem();

    /**
     * Default Constructor
     * @param config pointer to the general app configuration
     */
    ConfigElem ( ConfigList* config );

    /**
     * Copy Constructor.
     * It doesn't copy the mail list but creates a new empty one.
     * The pointer to the appropriate account list view item is set
     * to NULL.The new account is active by default.
     * @param pElem the account which will be copied
     */
    ConfigElem( ConfigElem* pElem );

    /**
     * Constructs a account which is called like the given name.
     * Creates a empty mail list. Sets the pointer to the appropriate
     * account list view item to NULL. The account is deactivated by default.
     * The url doesn't contain any server informations.
     * @param config pointer to the general app configuration
     * @param account name of the new account
     */
    ConfigElem( ConfigList* config, const QString& account );

    /**
     * Destructor
     * Does nothing.
     */
    ~ConfigElem();

    /**
     * Returns whether the account is active.
     * @return TRUE - account is active; FALSE - account is not active
     */
    bool isActive() const;

    /**
     * Sets the account active.
     * @param active TRUE - active account; FALSE - deactivate account
     */
    void setActive( bool active );

   /**
    * Gets the account name.
    * @return account name
    */
   QString getAccountName() const;

   /**
    * Sets the account name.
    * @param name the account name
    */
   void setAccountName( QString name );

   /**
    * Gets the account password.
    * @return password
    */
   QString getPassword() const;

   /**
    * Sets the account password. To save it in the configuration file
    * call saveOptions().
    * @param password new password
    */
   void setPassword( const QString& password );

   /**
    * Returns whether a password is stored.
    * @return TRUE - there is password stored; FALSE - no password stored
    */
   bool hasPassword() const;

   /**
    * Returns the url of this account.
    * @return url
    */
   KURL getURL() const;

   /**
    * Sets the pointer to the item in the account list view item.
    * @see m_pViewItem
    * @param item account list view item
    */
   void setListViewItem( QListViewItem* item );

   /**
    * Returns the pointer to the account list view item.
    * @see m_pViewItem
    * @return pointer to the appropriate list view item
    */
   QListViewItem* getListViewItem();

   /**
    * Returns TRUE, if the appropriate list view item is selected.
    * @return TRUE - list view item is selected
    * @return FALSE - list view item is not selected
    */
   bool isSelected() const;

   /**
    * Clears the mail list or creates a new one.
    */
   void clearMailList();

   /**
    * Sets the host name.
    * @param host host name
    */
   void setHost( const QString& host );

   /**
    * Returns the hostname.
    * @return the name of the host or QString::null if no host is set
    */
   QString getHost() const;

   /**
    * Sets the protocol.
    * @param protocol the protocol
    */
   void setProtocol( const QString& protocol );

   /**
    * Returns the protocol.
    * @param upperCase TRUE - transforms the protocol string to upper case
    * @return protocol
    */
   QString getProtocol( bool upperCase = false ) const;

   /**
    * Enable or disable TLS.
    * @param tls TRUE: use TLS; FALSE: don't use TLS
    */
   void setTLS( bool tls );

   /**
    * Returns whether TLS is enabled.
    * @return TRUE: TLS is enabled
    * @return FALSE: TLS is disabled
    */
   bool getTLS() const;

   /**
    * Sets the port.
    * @param port the port
    */
   void setPort( unsigned short int port );

   /**
    * Returns the port number.
    * @return port number
    */
   unsigned short int getPort() const;

   /**
    * Sets the user.
    * @param user username
    */
   void setUser( const QString& user );

   /**
    * Returns the user name.
    * @return the user name or QString::null if there is no user name
    */
   QString getUser() const;

   /**
    * Sets the password storage type.
    * The Constants are defined in constants.h
    * @param storage type of password storage; valid values are: CONFIG_VALUE_ACCOUNT_PASSWORD_DONT_SAVE, CONFIG_VALUE_ACCOUNT_PASSWORD_SAVE_FILE, CONFIG_VALUE_ACCOUNT_PASSWORD_SAVE_KWALLET
    */
   void setPasswordStorage( int storage );

   /**
    * Returns the password storage type.
    * The Constants are defined in constants.h.
    * @return type of password storage; valid values are: CONFIG_VALUE_ACCOUNT_PASSWORD_DONT_SAVE, CONFIG_VALUE_ACCOUNT_PASSWORD_SAVE_FILE, CONFIG_VALUE_ACCOUNT_PASSWORD_SAVE_KWALLET
    */
   int getPasswordStorage() const;


  /**
   * Saves the stored mails into the given
   * DOM document. It doesn't create a new DOM element but used the given one.
   * Saves the setup into the application config.
   * @param doc DOM document which contains all application settings, mails and account settings
   * @param parent DOM element in which all settings and mails of this account will be saved
   */
  void saveOptions( QDomDocument& doc, QDomElement& parent );

  /**
   * Gets the stored mails.
   * @param parent DOM element which contains the mails of this account
   */
  void readStoredMails( QDomElement& parent );

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

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

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

  /**
   * Opens a dialog to ask for a password, stores it temporarily in the account settings and
   * emits the signal sigConfigChanged.
   * Does not open a dialog if a password is already stored in the account settings.
   * @param force ask for a new password even if a password is stored
   * @return TRUE - a password is available
   * @return FALSE - no password is available
   */
  bool assertPassword( bool force = false );

  /**
   * Returns the state of the account.
   * @return account state
   */
  Types::AccountState_Type getState();

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

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

  /**
   * Refreshes the mail list.
   * This just starts the refresh and returns after then.
   * When the refresh is ready, the signal sigRefreshReady
   * will be emitted.
   * @param log Pointer to the filter log
   * @see sigRefreshReady
   */
  void refreshMailList( 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 insert it
   * into the mail list view.
   * @param view pointer to the application view
   */
  void fillMailListView( KshowmailView* view );

  /**
   * Refreshes the appropriate entry of the account list
   * (number of mails and total size)
   * Uses the pointer to the list view item stored in m_pViewItem.
   */
  void refreshAccountListItem();

  /**
   * Kills a running pop3 job.
   */
  void killPOP3Job();

  /**
   * Shows the headers of all selected mails.
   * @return continueShowHeaders - the user has clicked OK. The invoking function will show the next header
   * @return cancelShowHeaders - the user has clicked Cancel. The invoking function will not show the next header.
   * @return continueShowHeaders - no mails of this account are selected
   */
  int showSelectedHeaders();

  /**
   * Prints the setup to stdout.
   */
  void printSetup() const;

  /**
   * Reloads the settings of the filters.
   * It just calls the load() methode of the header filter.
   */
  void reloadFilterSettings();

    /**
     * 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;


  private:

    /**
     * Pointer to the configuration of the application.
     * Set by the constructors.
     */
    ConfigList* appConfig;

    /**
     * Pointer to the filter log.
     * Will be set by refreshMailList() at every refresh.
     */
    FilterLog* FLog;

    /**
     * State of the account.
     */
    Types::AccountState_Type state;

    /**
     * Type of password storage.
     * valid values are: CONFIG_VALUE_ACCOUNT_PASSWORD_DONT_SAVE, CONFIG_VALUE_ACCOUNT_PASSWORD_SAVE_FILE, CONFIG_VALUE_ACCOUNT_PASSWORD_SAVE_KWALLET
     * The Constants are defined in constants.h
     * @see saveOptions()
     * @see setPasswordStorage()
     */
    int PasswordStorage;

    /**
     * TRUE - account is active; FALSE - account is not active
     */
    bool m_bActive;

    /**
     * Account Name
     */
    QString m_strAccount;

    /**
     * Pointer to the appropriate item in the account list view.
     */
    QListViewItem* m_pViewItem;

    /**
     * List which contains all read mails from the server.
     */
    ShowRecord* m_pshowrecord;

    /**
     * Uniform Resource Locator of the account on the pop3 server.
     */
    KURL m_url;

    /**
     * Type of secure login.
     * See constants.h for valid values (CONFIG_VALUE_ACCOUNT_SECLOGIN_...)
     */
    int secureLoginType;

    /**
     * False: TLS is enabled
     */
    bool useTLS;

    /**
     * Contains a downloaded mail body.
     * Will be set by slotDataMailBody() and read by slotBodyDownloaded().
     */
    QByteArray mailbody;

   /**
    * Contains the numbers of mails which will be deleted.
    * Set by deleteSelectedMails() and applyFilters() and used by deleteNextMail() to get
    * the number of the next mail to delete.
    * @see deleteSelectedMails()
    * @see deleteNextMail()
    * @see applyFilters()
    */
    MailNumberList_Type MailsToDelete;

    /**
     * Contains the numbers of the mails shall be moved for actions like moving to mailbox or spam check.
     * Contains also some parameters (like mailbox) about the action which have to be performed.
     * Set and used by applyFilters().
     * @see applyFilters()
     */
    MailToDownloadMap_Type MailsToDownload;

    /**
     * Contains the numbers of mails for which the bodies will be shown.
     * Set by showSelectedMails() and used by showNextMail() to get
     * the number of the next mail to show.
     * @see showSelectedMails()
     * @see showNextMail()
     */
    MailNumberList_Type MailsToShow;

    /**
     * Contains the numbers of new mails.
     * Set by getHeaders() and used by getNextHeader() to download
     * the headers of the new mails.
     * @see getHeaders()
     * @see getNextHeader()
     */
    MailNumberList_Type newMails;

    /**
     * Pointer to a launched pop3 job.
     */
    KIO::TransferJob* pop3Job;

    /**
     * timeout timer. Will be started together with every pop3 job.
     * If it runs down, slotTimeout() will be invoked.
     */
    QTimer* pop3Timer;

    /**
     * While refreshing, this ShowRecord instance will be used to
     * build a new mail list. After that this pointer will be assigned
     * to m_pshowrecord.
     */
    ShowRecord* tempMailList;

    /**
     * List of received mail UIDs (unique ID).
     * Used by slotReceiveUID() and slotUIDsReceived().
     */
    QStringList receivedUIDs;

    /**
     * List of received mail sizes.
     * Used by slotReceiveSize() and slotSizesReceived().
     */
    QStringList receivedSizes;

    /**
     * A received mail header.
     * Set by slotReceiveHeader() and used by slotHeaderDownloaded().
     */
    QByteArray receivedHeader;

    /**
     * Every account has is own header filter instance.
     */
    HeaderFilter headerFilter;

    /**
     * This is a flag whether the filters was applied during a refresh cycle.
     * If the some mails was deleted (recommend by the filter), we need a actual
     * list of mails from the server. Therefore a second refresh cycle will be started.
     * To avoid a never-ending loop this flag will be set to TRUE by applyFilters().
     * If the second refresh is running this one will not invoke the filters.
     */
    bool filterApplied;

    /**
     * This flag is set by applyFilters() to indicate the deletion cycle is performed by filters and not by user.
     * The deletion methodes need it to decide on branch targets
     */
    bool deletionPerformedByFilters;

    /**
     * This flag is set by applyFiltersDeleted() to indicate the refresh cycle is the second one after a deletion which was performed by filters.
     * The refresh cycle need it to hold the remaining mails as new.
     */
    bool refreshPerformedByFilters;

    /**
     * This flag is set to TRUE by applyFilters() to indicate the mailbodies are downloading and writing to the mailboxes or spam checking.
     * When this is ended, applyFilters() will be called again and it reset this flag
     */
    bool downloadActionsInvoked;

    /**
     * Counter for moving to create an unique file name
     */
    int moveCounter;

    /**
     * Number of deleted mails by last refresh.
     */
    int nmbDeletedMailsLastRefresh;

    /**
     * Number of deleted mails since start.
     */
    int nmbDeletedMailsLastStart;

    /**
     * Number of moved mails by last refresh.
     */
    int nmbMovedMailsLastRefresh;

    /**
     * Number of moved mails since start.
     */
    int nmbMovedMailsLastStart;

    /**
     * Number of ignored mails by last refresh.
     */
    int nmbIgnoredMails;

    /**
     * Initializes the account.
     */
    void init();

    /**
     * Deletes the first mail of MailsToDelete.
     * After a succesful deletion this mail will be removed from the list
     * by slotMailDeleted() and this method will be invoked again.
     * If the list is empty, it will call commitDelete.
     * @see slotMailDeleted()
     * @see MailsToDelete
     */
    void deleteNextMail();

    /**
     * Commits the deletion.
     * Starts a pop3 job that will do the commit. Its signal
     * result is connected with slotFinalizeDeletion().
     * @see slotFinalizeDeletion()
     */
    void commitDeletion();

    /**
     * Shows the body of the first mail in MailsToShow.
     * After a succesful download and opening of the window this
     * mail will be removed from the list by slotBodyDownloaded() and this
     * method will be invoked again.
     * If the list is empty, it will call commitDownloading().
     * @see commitDownloading()
     * @see slotBodyDownloaded()
     */
    void showNextMail();

    /**
     * Commits the downloading of mail bodies.
     * Starts a pop3 job that will do the commit. Its signal
     * result is connected with slotFinalizeShowMail().
     * @see slotFinalizeShowMail()
     */
    void commitDownloading();

    /**
     * Creates a POP3 transfer job (KIO Job), which will be stored in pop3Job.
     * @param path command and parameters of the job as URL path
     */
    void startKIOJob( const QString& path );

    /**
     * Returns the timeout time in seconds which is stored in the
     * general configuration of the application.
     * Returns POP3_DEFAULT_TIMEOUT_TIME (defined in constants.h),
     * if no time is available.
     * Returns POP3_MINIMUM_TIMEOUT_TIME (defined in constants.h),
     * if the get time is less than POP3_MINIMUM_TIMEOUT_TIME.
     * @return seconds to timeout
     */
    unsigned int getTimeoutTime();

    /**
     * First step of the refresh cycle.
     * Gets the UIDs of the available mails from the server.
     * It starts a KIO job to get the UIDs. The UIDs will be stored
     * in receivedUIDs by slotReceiveUID().
     * When the job is ready, it will invoke slotUIDsReceived().
     */
    void getUIDs();

    /**
     * Second step of the refresh cycle.
     * Gets the sizes of the available mails from the server.
     * It starts a KIO job to get these. The Sizes will be temporarily
     * stored in receivedSizes by slotReceiveSize().
     * When the job is ready, it will invoke slotSizesReceived().
     */
    void getSizes();

    /**
     * Third step of the refresh cycle.
     * Gets the header of the new mails from the server.
     */
    void getHeaders();

    /**
     * Get the header of the first mail in newMails.
     * After a succesful download this
     * mail will be removed from the list by slotHeaderDownloaded() and this
     * method will be invoked again.
     * If the list is empty, it will call copyHeaders() to get the known
     * headers from the old mail list (m_pshowrecord).
     * @see copyHeaders()
     * @see slotHeaderDownloaded()
     */
    void getNextHeader();

    /**
     * Fourth step of the refresh cycle.
     * Copies the known headers of the old mails from the
     * old mail list to the new one.
     * At the end it invokes swapMailLists().
     */
    void copyHeaders();

    /**
     * Sixth step of the refresh cycle.
     * Applies the filters to the mails in the mail list.
     * Invoked by swapMailLists().
     * This methode maybe starts a new refresh cycle because after a deletion or moving we need a
     * actual list of mails on the server.
     * To avoid a never-ending loop you must not call this methode during the second refresh cycle.
     * Therefore it sets filterApplied to TRUE.
     * @see filterApplied
     * @see applyFiltersDeleted()
     */
    void applyFilters();

    /**
     * If there are mails to delete by filters applyFilters will call the regular deletion cycle of this class with set byFilter-flag.
     * Therefore the deletion will not branch to commitDeletion() but to this methode.
     * This performs a second refresh cycle to get an effective mail list from the server.
     * This new cycle will not apply the filters again, because the flag filterApplied is set to TRUE.
     * @see applyFilters()
     * @see filterApplied
     */
    void applyFiltersDeleted();

    /**
     * Cancels the refresh. Will be invoked, when a pop3 job has
     * reported an error.
     */
    void cancelRefresh();

    /**
     * Commits the refresh.
     * Starts a pop3 job that will do the commit. Its signal
     * result is connected with slotFinalizeRefresh().
     * Invoked by copyHeaders() if the filters was applied or applyFilters()
     * if not second refresh was necessary.
     * @see slotFinalizeRefresh()
     * @see applyFilters()
     */
    void commitRefresh();

    /**
     * Send a commit and restart the refresh cycle
     * We restart the refresh to get a fresh maillist after a deletion performed by the filter.
     * We need a commit before because the mails server only after a commit reorders the mail numbers
     */
    void commitBeforeRefresh();

    /**
     * Fifth step of the refresh cycle.
     * Copies the pointer to the temporary list to m_pshowrecord.
     * Invoked by copyHeaders() and slotUIDsReceived().
     * The temporary list will be the current mail list.
     * At the end it invokes commitRefresh() if the filters were applied
     * (filterApplied == TRUE) or deactive or it invokes
     * applyFilters() if the filters were not
     * applied (filterApplied == FALSE).
     * @see m_pshowrecord
     * @see copyHeaders()
     * @see slotUIDsReceived()
     * @see commitRefresh()
     * @see filterApplied
     */
    void swapMailLists();

    /**
     * Does all filter actions for which we have to download the mails
     * These are:
     * Moving, spam check
     * It doesn't removes they from the server.
     */
    void doDownloadActions();

    /**
     * Gets the body of the first mail in MailsToDownload.
     * After a succesful download and writing into the mailbox this
     * mail will be removed from the list by slotMailDownloadedforDownloadActions() and this
     * method will be invoked again.
     * If the list is empty, it will call applyFilters() to continue the filtering.
     * @see applyFilters()
     * @see slotMailDownloadedforDownloadActions()
     */
    void getNextMailForDownloadActions();

    /**
     * Returns whether the given directory is a maildir directory
     * @param path the directory for test
     * @return TRUE - directory is a maildir directory
     */
    bool isMailDir( const QDir& path );

    /**
     * Writes the given mail into the mailbox.
     * @param mail the Mail
     * @param box path to the mailbox
     * @return TRUE - Writing was succesful
     */
    bool writeToMailBox( const QString& mail, const QString& box );

  private slots:

    /**
     * Connected with signal result of the launched pop3 job.
     * Removes the deleted mail from the internal mail list (m_pshowrecord).
     * Removes the first mail from MailsToDelete and invokes
     * deleteNextMail() again to delete the next mail.
     * If the list is empty after it has removed the first item, it will call
     * commitDelete().
     * If an error is occured, it will call slotFinalizeDeletion().
     * @param job job which has emit the result signal
     * @see deleteNextMail()
     * @see MailsToDelete
     * @see pop3Job
     * @see slotFinalizeDeletion()
     */
    void slotMailDeleted( KIO::Job* job );

    /**
     * Connected with the signal result of the job which commits the deletion.
     * Finalizes the deletion of mails.
     * Emits signal sigDeleteReady.
     * @see deleteNextMail()
     * @see slotMailDeleted()
     * @see sigDeleteReady
     */
    void slotFinalizeDeletion( KIO::Job* );

    /**
     * Connected with signal result of the launched pop3 job to
     * download a mail body.
     * Opens a window (class ShowMailDialog) with the downloaded mail body.
     * Removes the first mail from MailsToShow and invokes showNextMail()
     * again to show the next mail.
     * If the list is empty after it has removed the first item, it will call
     * commitDownloading().
     * If an error is occured, it will call slotFinalizeShowMail().
     * @param job job which has emit the result signal
     * @see showNextMail()
     * @see commitDownloading()
     * @see MailsToShow
     * @see pop3Job
     * @see slotFinalizeShowMail()
     * @see ShowMailDialog
     */
    void slotBodyDownloaded( KIO::Job* job );

    /**
     * Connected with signal result of the launched pop3 job to
     * download a mail to write it into a mailbox or do a spam check.
     * Maybe it puts the number of the downloaded mail into the list of mails to delete (MailsToDelete).
     * Removes the first mail from MailsToMove and invokes getNextMailForMove()
     * again to get and write the next mail.
     * If the list is empty after it has removed the first item, it will call
     * applyFilters() to continue the filtering.
     * If an error is occured the current mail will not put into MailsToDelete. And it returns
     * to applyFilters() immediately.
     * @param job job which has emit the result signal
     * @see MailsToDownload
     * @see getNextMailForDownloadActions()
     * @see applyFilters()
     */
    void slotMailDownloadedForAction( KIO::Job* job );

    /**
     * Connected with signal data of the launched pop3 job to
     * download a mail body.
     * Receives the downloaded data from the job. This lot will be called
     * several times during the donwload. At the last one the array is empty.
     * It extracts the body from the downloaded data and stores it in DownloadedMailBody.
     * @param datas the downloaded mail
     */
    void slotDataMailBody( KIO::Job*, const QByteArray & datas );

    /**
     * Connected with the signal result of the job which commits the download
     * of the mail bodies.
     * Finalizes the downloading and showing of the selected mails.
     * Emits signal sigShowBodiesReady and sets account state to idle.
     * @see showNextMail()
     * @see slotBodyDownloaded()
     * @see sigShowBodiesReady
     */
    void slotFinalizeShowMail( KIO::Job* );

    /**
     * Connected with signal timeout() of the timeout timer pop3Timer.
     * Will be called when the timer is run down, if the pop3 job
     * has not ended on time.
     * It kills a running pop3 job and invokes the appropriate finalize slot
     * of the running operation.
     */
    void slotTimeout();

    /**
     * Connected with the signal "data" of the pop3 transfer job which gets mail
     * UIDs (Unique ID). Therefore it will be called when the job has received
     * an UIDL from the server. Every received UID causes a call of this slot.
     * When the job ends, it causes a last call but with an empty data array.
     * The UIDs will be stored in receivedUIDs.
     * @param data received data, which contain an uid
     */
    void slotReceiveUID( KIO::Job*, const QByteArray& data );

    /**
     * Connected with signal result of the launched pop3 job to get the UIDs.
     * Will be invoked, when all UIDs are received and stored in receivedUIDs.
     * Analyzes the received UID datas and creates new ShowRecordElem instances
     * in the new mail list accordingly.
     * @param job job which has emitted the result signal
     */
    void slotUIDsReceived( KIO::Job* job );

    /**
     * Connected with the signal "data" of the pop3 transfer job which gets mail
     * Sizes. Therefore it will be called when the job has received
     * a size from the server. Every received size causes a call of this slot.
     * When the job ends, it causes a last call but with an empty data array.
     * The UIDs will be stored in receivedSizes.
     * @param data received data, which contain a size
     */
    void slotReceiveSize( KIO::Job*, const QByteArray& data );

    /**
     * Connected with signal result of the launched pop3 job to get the Sizes.
     * Will be invoked, when all Sizes are received and stored in receivedSizes.
     * Analyzes the received datas and writes these in the appropriate mail instances.
     * @param job job which has emitted the result signal
     */
    void slotSizesReceived( KIO::Job* job );


    /**
     * Connected with signal result of the job which commits the refresh.
     * Finalizes a succesful refresh.
     * Emits sigRefreshReady and sets account state to idle
     */
    void slotFinalizeRefresh( KIO::Job* );

    /**
     * Connected with signal result of the launched pop3 job.
     * Stores the received headers into the appropriate instance of the mail list.
     * Removes the first mail from newMails and invokes
     * getNextHeader() again to get the next header.
     * If the list is empty after it has removed the first item, it will call
     * copyHeaders().
     * If an error has occured, it will call cancelRefresh().
     * @param job job which has emit the result signal
     * @see getNextHeader()
     * @see newMails
     * @see pop3Job
     * @see cancelRefresh()
     * @see copyHeaders()
     */
    void slotHeaderDownloaded( KIO::Job* job );

    /**
     * Connected with the signal "data" of the pop3 transfer job which gets a mail
     * header. Therefore it will be called when the job has received
     * a part of the header from the server.
     * When the job ends, it causes a last call but with an empty data array.
     * The complete header will be stored in receivedHeader.
     * @param data received data, which contains a header part
     */
    void slotReceiveHeader( KIO::Job*, const QByteArray& data );
    
    /**
     * Connected with the result signal of the pop3 job launched by commitBeforeRefresh()
     * Restarts a second refresh cycle after a deletion performed by the filter.
     * @see commitBeforeRefresh
     * @see applyFiltersDeleted
     */
    void slotCommitBeforeRefreshDone( KIO::Job* );


  signals:

    /**
     * Will be emitted when all selected mails are deleted.
     * @param account name of the account, which has emitted this signal
     */
    void sigDeleteReady( QString account );

    /**
     * Will be emitted when the bodies of all selected mails are
     * downloaded and shown.
     * @param account name of the account, which has emitted this signal
     */
    void sigShowBodiesReady( QString account );

    /**
     * Will be emitted when the settings have been changed.
     */
    void sigConfigChanged();

    /**
     * Will be emitted, when a window to show a message was opened.
     */
    void sigMessageWindowOpened();

    /**
     * Will be emitted, when a window to show a message was closed.
     */
    void sigMessageWindowClosed();

    /**
     * Will be emitted, when the mail list was refreshed.
     * @param account name of the account, which has emitted this signal
     */
    void sigRefreshReady( QString account );

  protected:

    /**
     * Forwards the given mail to SpamAssassin and returns the test result
     * @param mail the mail to test
     * @return TRUE - mail is spam
     */
    bool isSpam( QByteArray mail ) const;

    /**
     * Looks for a running spamd daemon of SpamAssassin.
     * @return TRUE - SpamAssassin is running
     */
    bool isSpamAssassinRunning() const;



};
#endif
