/*
    This file is part of KMail, the KDE mail client.
    Copyright (c) 2002 Don Sanders <sanders@kde.org>

    Based on the work of Stefan Taferner <taferner@kde.org>

    KMail is free software; you can redistribute it and/or modify it
    under the terms of the GNU General Public License, version 2, as
    published by the Free Software Foundation.

    KMail is distributed in the hope that it will be useful, but
    WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
*/

#ifndef __KMMAINWIDGET
#define __KMMAINWIDGET

#include <kurl.h>
#include <kxmlguiclient.h>
#include <tqguardedptr.h>
#include <tqlistview.h>
#include <tqvbox.h>
#include <tqvaluevector.h>

#include "kmreaderwin.h" //for inline actions
#include "kmkernel.h" // for access to config
#include "messageactions.h"
#include <tdeaction.h>

class TQVBoxLayout;
class TQSplitter;
class TQSignalMapper;

class TDEActionMenu;
class TDEActionCollection;
class TDEConfig;
class TDERadioAction;
class TDEToggleAction;
class KMenuBar;
class KStatusBarLabel;

class KMFolder;
class KMFolderDir;
class KMFolderTree;
class KMFolderTreeItem;
class KMCommand;
class KMMetaFilterActionCommand;
class FolderShortcutCommand;
class KMMessage;
class KMFolder;
class KMAccount;
class KMSystemTray;
class KMHeaders;

template <typename T> class TQValueList;
template <typename T, typename S> class TQMap;
template <typename T> class TQGuardedPtr;

namespace TDEIO {
  class Job;
}

namespace KMail {
  class Vacation;
  class SieveDebugDialog;
  class FolderJob;
  class HeaderListQuickSearch;
  class SearchWindow;
  class ImapAccountBase;
  class FavoriteFolderView;
}

typedef TQMap<int,KMFolder*> KMMenuToFolder;


class KDE_EXPORT KMMainWidget : public TQWidget
{
  Q_OBJECT
  

public:
  KMMainWidget(TQWidget *parent, const char *name,
               KXMLGUIClient *aGUIClient,
               TDEActionCollection *actionCollection,
         TDEConfig*config = KMKernel::config() );
  virtual ~KMMainWidget();
  void destruct();

  /** Read configuration options before widgets are created. */
  virtual void readPreConfig(void);

  /** Read configuration for current folder. */
  virtual void readFolderConfig(void);

  /** Write configuration for current folder. */
  virtual void writeFolderConfig(void);

  /** Read configuration options after widgets are created. */
  virtual void readConfig(void);

  /** Write configuration options. */
  virtual void writeConfig(void);

  /** Easy access to main components of the window. */
  KMReaderWin* messageView(void) const { return mMsgView; }
  KMFolderTree* folderTree(void) const  { return mFolderTree; }
  KMail::FavoriteFolderView *favoriteFolderView() const { return mFavoriteFolderView; }

  static void cleanup();

  TDEAction *action( const char *name ) { return mActionCollection->action( name ); }
  TDEActionMenu *customReplyAction() const { return mCustomReplyActionMenu; }
  TDEActionMenu *customReplyAllAction() const { return mCustomReplyAllActionMenu; }
  TDEActionMenu *forwardMenu() const { return mForwardActionMenu; }
  TDEAction *forwardInlineAction() const { return mForwardInlineAction; }
  TDEAction *forwardAttachedAction() const { return mForwardAttachedAction; }
  TDEAction *forwardDigestAction() const { return mForwardDigestAction; }
  TDEAction *redirectAction() const { return mRedirectAction; }
  TDEActionMenu *customForwardAction() const { return mCustomForwardActionMenu; }
  TDEActionMenu *filterMenu() const { return mFilterMenu; }
  TDEAction *printAction() const { return mPrintAction; }
  TDEAction *trashAction() const { return mTrashAction; }
  TDEAction *deleteAction() const { return mDeleteAction; }
  TDEAction *trashThreadAction() const { return mTrashThreadAction; }
  TDEAction *deleteThreadAction() const { return mDeleteThreadAction; }
  TDEAction *saveAsAction() const { return mSaveAsAction; }
  TDEAction *editAction() const { return mMsgActions->editAction(); }
  TDEAction *useAction() const { return mUseAction; }
  TDEAction *sendAgainAction() const { return mSendAgainAction; }
  TDEAction *applyAllFiltersAction() const { return mApplyAllFiltersAction; }
  TDEAction *findInMessageAction() const { return mFindInMessageAction; }
  TDEAction *saveAttachmentsAction() const { return mSaveAttachmentsAction; }
  TDEAction *openAction() const { return mOpenAction; }
  TDEAction *viewSourceAction() const { return mViewSourceAction; }
  KMail::MessageActions *messageActions() const { return mMsgActions; }

  TDEActionMenu *statusMenu()  const{ return mMsgActions->messageStatusMenu(); }
  TDEActionMenu *threadStatusMenu() const { return mThreadStatusMenu; }
  TDEActionMenu *moveActionMenu() const{ return mMoveActionMenu; }
  TDEActionMenu *mopyActionMenu() const { return mCopyActionMenu; }
  TDEActionMenu *applyFilterActionsMenu() const { return mApplyFilterActionsMenu; }

  TDEToggleAction *watchThreadAction() const { return mWatchThreadAction; }
  TDEToggleAction *ignoreThreadAction() const { return mIgnoreThreadAction; }

  KMHeaders *headers() const { return mHeaders; }
  void toggleSystemTray();

  void updateListFilterAction();

  /** Returns a list of all KMMainWidgets. Warning, the list itself can be 0.
   * @return the list of all main widgets, or 0 if it is not yet initialized */
  static const TQValueList<KMMainWidget*>* mainWidgetList() { return s_mainWidgetList; }

  KMSystemTray *systray() const;

  /** Checks a shortcut against the actioncollection and returns whether it
   * is already used and therefor not valid or not. */
  bool shortcutIsValid( const TDEShortcut& ) const;


  void modifyFolder( KMFolderTreeItem* folderItem );

  /**
   * Enable or disable the global accelerators. This is useful for keyboard
   * navigation inside child widgets like combo boxes.
   */
  void setAccelsEnabled( bool enabled = true );

  /**
   * Sets up action list for forward menu.
  */
  void setupForwardingActionsList();

  KStatusBarLabel* vacationScriptIndicator() const { return mVacationScriptIndicator; }
  void updateVactionScripStatus() { updateVactionScripStatus( mVacationIndicatorActive ); }

public slots:
  void slotMoveMsgToFolder( KMFolder *dest);
  void slotTrashMsg();   // move to trash

  virtual void show();
  virtual void hide();
  /** sven: moved here as public */
  void slotCheckMail();

  /**
   * Select the given folder
   * If the folder is 0 the intro is shown
   */
  void folderSelected( KMFolder*, bool forceJumpToUnread = false );

  /** Reselect current folder */
  void folderSelected();

  /** Select the folder and jump to the next unread msg */
  void folderSelectedUnread( KMFolder* );

  void slotMsgSelected( KMMessage * );
  /**
    Open a separate viewer window containing the specified message.
  */
  void slotMsgActivated( KMMessage * );

  void slotMsgChanged();

  /** Change the current folder, select a message in the current folder */
  void slotSelectFolder(KMFolder*);
  void slotSelectMessage(KMMessage*);

  void slotReplaceMsgByUnencryptedVersion();

  /** Update message menu */
  void updateMessageMenu();
  /** Start a timer to update message actions */
  void startUpdateMessageActionsTimer();
  /** Update message actions */
  void updateMessageActions();

  /** Launch subscription-dialog (server side) */
  void slotSubscriptionDialog();

  /** Launch dialog for local (client side) subscription configuration */
  void slotLocalSubscriptionDialog();

  /** The columns of the foldertree changed */
  void slotFolderTreeColumnsChanged();

  /** Clear and create actions for marked filters */
  void clearFilterActions();
  void initializeFilterActions();

  /** Create IMAP-account-related actions if applicable */
  void initializeIMAPActions() { initializeIMAPActions( true ); }

  /** Create actions for the folder shortcuts. */
  void initializeFolderShortcutActions();

  /** Add, remove or adjust the folder's shortcut. */
  void slotShortcutChanged( KMFolder *folder );

  void updateCustomTemplateMenus();
  void slotEditVacation();

signals:
  void messagesTransfered( bool );
  void captionChangeRequest( const TQString & caption );

protected:
  void setupActions();
  void createWidgets();
  void activatePanners();
  void showMsg( KMReaderWin *win, KMMessage *msg );
  void updateFileMenu();
  void newFromTemplate( KMMessage *msg );

  TDEActionCollection * actionCollection() const { return mActionCollection; }

  /** @return the correct config dialog depending on whether the parent of the mainWidget
   *          is a KPart or a KMMainWindow. When dealing with geometries, use this pointer
   */
  TDEConfig * config();

protected slots:
  void slotCheckOneAccount(int);
  void slotMailChecked( bool newMail, bool sendOnCheck,
                        const TQMap<TQString, int> & newInFolder );
  void getAccountMenu();
  void getTransportMenu();
  void slotHelp();
  void slotFilter();
  void slotPopFilter();
  void slotManageSieveScripts();
  void slotAddrBook();
  void slotImport();
  void slotViewChange();
  void slotCompose();
  void slotPostToML();
  void slotModifyFolder();
  void slotFolderMailingListProperties();
  void slotFolderShortcutCommand();
  void slotExpireFolder();
  void slotExpireAll();
  void slotInvalidateIMAPFolders();
  void slotMarkAllAsRead();
  void slotArchiveFolder();
  void slotRemoveFolder();
  void slotEmptyFolder();
  void slotCompactFolder();
  void slotRefreshFolder();
  void slotTroubleshootFolder();
  void slotCompactAll();
  void slotOverrideHtml();
  void slotOverrideHtmlLoadExt();
  void slotOverrideThread();
  void slotToggleSubjectThreading();
  void slotMessageQueuedOrDrafted();
  void slotUseTemplate();
  //void slotTrashMsg();   // move to trash
  void slotDeleteMsg( bool confirmDelete = true );  // completely delete message
  void slotTrashThread();
  void slotDeleteThread( bool confirmDelete = true );  // completely delete thread
  void slotUndo();
  void slotReadOn();
  void slotSaveMsg();
  void slotOpenMsg();
  void slotSaveAttachments();
  void slotJumpToFolder();
  void slotMoveMsg();
  //void slotMoveMsgToFolder( KMFolder *dest);
  void slotCopyMsgToFolder( KMFolder *dest);
  void slotCopyMsg();
  void slotResendMsg();
  void slotCheckVacation();
  void slotDebugSieve();
  void slotStartCertManager();
  void slotStartWatchGnuPG();
  void slotApplyFilters();
  void slotExpandThread();
  void slotExpandAllThreads();
  void slotCollapseThread();
  void slotCollapseAllThreads();
  void slotShowMsgSrc();
  void slotSetThreadStatusNew();
  void slotSetThreadStatusUnread();
  void slotSetThreadStatusRead();
  void slotSetThreadStatusTodo();
  void slotSetThreadStatusFlag();
  void slotSetThreadStatusWatched();
  void slotSetThreadStatusIgnored();
  void slotToggleUnread();
  void slotToggleTotalColumn();
  void slotToggleSizeColumn();
  void slotSendQueued();
  void slotSendQueuedVia( int item );
  void slotOnlineStatus();
  void slotUpdateOnlineStatus( GlobalSettings::EnumNetworkState::type );
  void slotMsgPopup(KMMessage &msg, const KURL &aUrl, const TQPoint&);
  void slotMarkAll();
  void slotMemInfo();
  void slotSearch();
  void slotSearchClosed();
  void slotFind();
  void slotIntro();
  void slotShowStartupFolder();
  /** Show tip-of-the-day, forced */
  void slotShowTip();
  void slotAntiSpamWizard();
  void slotAntiVirusWizard();
  void slotFilterLogViewer();

  /** Message navigation */
  void slotNextMessage();
  void slotNextUnreadMessage();
  void slotNextImportantMessage();
  void slotNextUnreadFolder();
  void slotPrevMessage();
  void slotPrevUnreadMessage();
  void slotPrevImportantMessage();
  void slotPrevUnreadFolder();

  /** etc. */
  void slotDisplayCurrentMessage();

  void slotShowNewFromTemplate();
  void slotNewFromTemplate( int );

  /** Update the undo action */
  void slotUpdateUndo();

  /** Move selected messages to folder with corresponding to given menuid */
  virtual void moveSelectedToFolder( int menuId );
  /** Copy selected messages to folder with corresponding to given menuid */
  virtual void copySelectedToFolder( int menuId );
  /** Update html and threaded messages preferences in Folder menu. */
  void updateFolderMenu();
  /** Enable or disable the "mark all as read" action. Needs to happen more
   * often the the other updates and is therefor in its own method. */
  void updateMarkAsReadAction();

  /** Settings menu */
  void slotToggleShowQuickSearch();

  /** XML-GUI stuff */
  void slotEditNotifications();
  void slotEditKeys();

  /** changes the caption and displays the foldername */
  void slotChangeCaption(TQListViewItem*);
  void removeDuplicates();

  void slotCustomReplyToMsg( int tid );
  void slotCustomReplyAllToMsg( int tid );
  void slotForwardInlineMsg();
  void slotForwardAttachedMsg();
  void slotForwardDigestMsg();
  void slotRedirectMsg();
  void slotCustomForwardMsg( int tid );
  void slotNoQuoteReplyToMsg();
  void slotSubjectFilter();
  void slotMailingListFilter();
  void slotFromFilter();
  void slotToFilter();
  void slotPrintMsg();
  void slotCreateTodo();

  void slotConfigChanged();
  /** Remove the shortcut actions associated with a folder. */
  void slotFolderRemoved( KMFolder *folder );

  /** Show a splash screen for the longer-lasting operation */
  void slotShowBusySplash();
  /** Show a message screen explaining that we are currently offline, when
   * an online folder is selected. */
  void showOfflinePage();

private:
  /** Get override character encoding. */
  TQString overrideEncoding() const;

  void initializeIMAPActions( bool setState );

  /** Helper which finds the associated account if there is a current
   * folder and it is an imap or disconnected imap one.
   */
  KMail::ImapAccountBase* findCurrentImapAccountBase();

  /** Helper which finds the associated IMAP path if there is a current
   * folder and it is an imap or disconnected imap one.
   */
  TQString findCurrentImapPath();

  /**
   * This function adds or updates the actions of the forward action menu, taking the
   * preference whether to forward inline or as attachment by default into account.
   * This has to be called when that preference config has been changed.
   */
  void setupForwardActions();

  void setupFolderView();

private slots:
  void slotRequestFullSearchFromQuickSearch();
  void updateVactionScripStatus( bool active );

private:
  // Message actions
  TDEAction *mTrashAction, *mDeleteAction, *mTrashThreadAction,
    *mDeleteThreadAction, *mSaveAsAction, *mUseAction,
    *mSendAgainAction, *mApplyAllFiltersAction, *mFindInMessageAction,
    *mSaveAttachmentsAction, *mOpenAction, *mViewSourceAction,
    *mFavoritesCheckMailAction,
    *mMoveMsgToFolderAction;
  // Composition actions
  TDEAction *mPrintAction,
    *mForwardInlineAction, *mForwardAttachedAction, *mForwardDigestAction,
    *mRedirectAction;
  TDEActionMenu *mForwardActionMenu;
  // Filter actions
  TDEActionMenu *mFilterMenu;
  TDEAction *mSubjectFilterAction, *mFromFilterAction, *mToFilterAction,
      *mListFilterAction;
  TDEActionMenu *mTemplateMenu;

  // Custom template actions menu
  TDEActionMenu *mCustomReplyActionMenu,
              *mCustomReplyAllActionMenu,
              *mCustomForwardActionMenu;
  // Signal mappers for custom template actions
  TQSignalMapper *mCustomReplyMapper,
                *mCustomReplyAllMapper,
                *mCustomForwardMapper;

  TDEActionMenu *mThreadStatusMenu,
    *mMoveActionMenu, *mCopyActionMenu, *mApplyFilterActionsMenu;
  TDEAction *mMarkThreadAsNewAction;
  TDEAction *mMarkThreadAsReadAction;
  TDEAction *mMarkThreadAsUnreadAction;
  TDEToggleAction *mToggleThreadTodoAction;
  TDEToggleAction *mToggleThreadFlagAction;

  TDEToggleAction *mWatchThreadAction, *mIgnoreThreadAction;

  /** we need to access those TDEToggleActions from the foldertree-popup */
  TDERadioAction* mUnreadColumnToggle;
  TDERadioAction* mUnreadTextToggle;
  TDEToggleAction* mTotalColumnToggle;
  TDEToggleAction* mSizeColumnToggle;

  TDEToggleAction *mToggleShowQuickSearchAction;

  KMFolderTree *mFolderTree;
  KMail::FavoriteFolderView *mFavoriteFolderView;
  TQWidget      *mFolderView;
  TQSplitter    *mFolderViewParent;
  KMReaderWin  *mMsgView;
  TQSplitter    *mPanner1, *mPanner2;
  TQSplitter    *mFolderViewSplitter;
  KMHeaders    *mHeaders;
  TQVBox        *mSearchAndHeaders;
  TDEToolBar     *mSearchToolBar;
  KMail::HeaderListQuickSearch *mQuickSearchLine;
  TQGuardedPtr<KMFolder> mFolder;
  KMFolder     *mTemplateFolder;
  TQPopupMenu   *mViewMenu, *mBodyPartsMenu;
  TDEAction       *mlistFilterAction;
  bool		mIntegrated;
  bool          mBeepOnNew;
  bool          mConfirmEmpty;
  TQString       mStartupFolder;
  int		mMessageStatusId;
  TQValueList<int> mPanner1Sep, mPanner2Sep;
  KURL          mUrlCurrent;
  TQPopupMenu	*mActMenu;
  TQPopupMenu    *mSendMenu;
  TQPopupMenu	*mFileMenu;

  bool mLongFolderList;

  bool		mStartupDone;
  KMMenuToFolder mMenuToFolder;
  int copyId, moveId, htmlId, threadId;
  bool mHtmlPref, mHtmlLoadExtPref, mThreadPref,
       mFolderHtmlPref, mFolderHtmlLoadExtPref, mFolderThreadPref,
       mFolderThreadSubjPref, mReaderWindowActive, mReaderWindowBelow;
  bool mEnableFavoriteFolderView;

//  TQPopupMenu *mMessageMenu;
  KMail::SearchWindow *mSearchWin;

  TDEAction *mNewFolderAction, *mModifyFolderAction, *mRemoveFolderAction, *mExpireFolderAction,
      *mCompactFolderAction, *mRefreshFolderAction, *mEmptyFolderAction,
      *mMarkAllAsReadAction, *mFolderMailingListPropertiesAction,
      *mFolderShortCutCommandAction, *mTroubleshootFolderAction,
      *mRemoveDuplicatesAction, *mArchiveFolderAction;
  TDEToggleAction *mPreferHtmlAction, *mPreferHtmlLoadExtAction, *mThreadMessagesAction;
  TDEToggleAction *mThreadBySubjectAction;
  TDEToggleAction *mFolderAction, *mHeaderAction, *mMimeAction;

  TQTimer *menutimer;
  TQTimer *mShowBusySplashTimer;

  TQGuardedPtr<KMail::Vacation> mVacation;
#if !defined(NDEBUG)
  TQGuardedPtr<KMail::SieveDebugDialog> mSieveDebugDialog;
#endif
  TDEActionCollection *mActionCollection;
  TDEActionSeparator  *mToolbarActionSeparator;
  TQVBoxLayout *mTopLayout;
  bool mDestructed, mForceJumpToUnread, mShowingOfflineScreen;
  TQPtrList<TDEAction> mFilterMenuActions;
  TQPtrList<TDEAction> mFilterTBarActions;
  TQPtrList<KMMetaFilterActionCommand> mFilterCommands;
  TQDict<FolderShortcutCommand> mFolderShortcutCommands;
  TQGuardedPtr <KMail::FolderJob> mJob;

  TQValueVector<TQString> mCustomTemplates;
  TQPtrList<TDEAction> mCustomTemplateActions;

  KMSystemTray  *mSystemTray;
  TDEConfig *mConfig;
  KXMLGUIClient *mGUIClient;

  KMail::MessageActions *mMsgActions;

  static TQValueList<KMMainWidget*>* s_mainWidgetList;

  KStatusBarLabel *mVacationScriptIndicator;
  bool mVacationIndicatorActive;
};

#endif

