#ifndef _KVI_APP_H_
#define _KVI_APP_H_

//=============================================================================
//
//   File : kvi_app.h
//   Creation date : Sun Jun 18 2000 12:40:00 CEST by Szymon Stefanek
//
//   This file is part of the KVirc irc client distribution
//   Copyright (C) 1999-2000 Szymon Stefanek (stefanek@tin.it)
//
//   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 opinion) any later version.
//
//   This program 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. ,59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
//=============================================================================

#include "kvi_settings.h"
#include "kvi_string.h"
#include "kvi_tal_application.h"
#include "kvi_list.h"

#include <qlistbox.h>

#ifdef COMPILE_ON_WINDOWS
	// The brain damaged MSVC compiler can't instantiate templates without this
	#include "kvi_frame.h"
	#include "kvi_window.h"
#else
	class KviFrame;
	class KviWindow;
#endif

class KviConsole;
#ifndef COMPILE_NO_IPC
	class KviIpcSentinel;
#endif

class QPopupMenu;
class QPixmap;

class KviRegisteredUser;

typedef struct _KviPendingAvatarChange
{
	KviConsole * pConsole;
	KviStr       szFileName;
	KviStr       szNick;
	KviStr       szUser;
	KviStr       szHost;
} KviPendingAvatarChange;

#undef Unsorted
#undef None

class KVIRC_API KviApp : public KviTalApplication
{
	friend class KviFrame;
	friend class KviWindow;
	friend class KviSetupWizard; // this resides in a module!
	Q_OBJECT
public:
	KviApp(int argc,char ** argv);
	~KviApp();

protected:
	KviPtrList<KviFrame>               * m_pFrameList;
	// directories
	KviStr                          m_szGlobalKvircDir;
	KviStr                          m_szLocalKvircDir;
	bool                            m_bFirstTimeRun;
	KviWindow                     * m_pActiveWindow;
	bool                            m_bUpdateGuiPending;
	KviPtrList<KviPendingAvatarChange> * m_pPendingAvatarChanges;
	bool                            m_bSetupDone;
#ifdef COMPILE_PSEUDO_TRANSPARENCY
	bool                            m_bUpdatePseudoTransparencyPending;
#endif
#ifndef COMPILE_NO_IPC
	KviIpcSentinel                * m_pIpcSentinel;
#endif
public:
	// setup stuff (accessed from kvi_main.cpp: consider private othwerise)
	const char      * m_pConfigFile;        // setup
	bool              m_bCreateConfig;      // setup           
	KviStr            m_szExecAfterStartup;
public:
	// FIXME: "Plugins" and "ConfigPlugins" should become "Modules" and "ConfigModules"
	enum KvircSubdir
	{
		None,        Pics,          Config ,
		Help,        HelpEN,        HelpNoIntl,
		Log,         Incoming,      Audio,
		Scripts,     Plugins,       ConfigPlugins,
		Trash,       MsgColors,     Charmaps,
		Avatars,     DefScript,     License,
		Modules,     ConfigScripts, Filters,
		Tmp
	};

public:

	void getClipboardText(KviStr &buffer);
	void setClipboardText(const KviStr &str);

	QString getClipboardText();
	void setClipboardText(const QString &str);


	void collectGarbage(QObject * garbage);

	void destroyFrame(KviFrame *frm);
	void setup();                                  // THIS SHOULD BE PRIVATE! (but is accessed from kvi_main.cpp)

#ifndef COMPILE_NO_IPC
	void ipcMessage(char * message);
#endif

	static unsigned int defaultTextEncoding();

	static int getGloballyUniqueId(); // returns an unique integer identifier across the application

	bool firstTimeRun(){ return m_bFirstTimeRun; };

	// kvi_app.cpp (Saving options)
	void saveIrcServerDataBase();
	void saveProxyDataBase();
	void saveRecentEntries();
	void saveEvents();
	void saveRawEvents();
	void saveMediaTypes();
	void saveRegisteredUsers();
	void saveFileOffers();
	void savePopups();
	void saveAliases();
	void saveNickServ();
	void saveTextIcons();
	void saveRegisteredChannels();
	void saveInputHistory();
#ifdef COMPILE_SCRIPTTOOLBAR
	void saveToolBars();
#endif // COMPILE_SCRIPTTOOLBAR

	// kvi_options.cpp : Options saving and loading (kvi.main.conf))
	void loadOptions();
	void saveOptions();
	void listAvailableOptions(KviWindow *wnd);
	bool getOptionString(const char * optName,KviStr &buffer);
	bool setOptionValue(const char * optName,const char * value);
	void optionResetUpdate(int flags);

	// kvi_app_fs.cpp : Filesystem thingies
	void getGlobalKvircDirectory(KviStr &szData,KvircSubdir dir,const char *appendFile = 0);
	void getLocalKvircDirectory(KviStr &szData,KvircSubdir dir,const char *appendFile = 0,bool bCreateIfNeeded = true);
	void getTmpFileName(KviStr &szBuffer,const char * pattern = 0);
	bool trashFile(const char *filename);
	void getChannelDumpLogFileName(KviStr &str);

	// if the mediatype can be guessed ,it is looked up in the media type save path
	// if found , true is returned
	// if not found or the mediatype can't be guessed then false is returned
	bool findFileByMediaType(KviStr &szRetPath,const char * filename);
	bool findImageInImageSearchPath(KviStr &szRetPath,const char * filename);
	bool findUserFile(KviStr &szRetPath,const char *filename);
	bool findImage(KviStr &szRetPath,const char *filename);
	// tries to map the full path filename to one of the KVIrc's mapped directories
	// if it doesn't succeed it just returns the complete filename in szRetPath
	bool mapImageFile(KviStr &szRetPath,const char * filename);

	//void getDefaultDccSaveFilePath(KviStr &path,const char *filename);
	void completeDirectory(const KviStr &word,KviPtrList<KviStr> * matches);
	//
	// Returns a config path suitable for reading (at least)
	// First lookups the user local config directory,
	// if no config file is found, it earches in the global one
	// returns false if no config file has been found
	// If bNoFail is true, the buffer is filled with the file name even
	// if no config file has been found: in this case the local config
	// directory is used
	//
	bool getReadOnlyConfigPath(KviStr &buffer,const char *config_name,KvircSubdir sbd = Config,bool bNoFail = false);

	// kvi_app.cpp : Window stuff
	KviWindow       * findWindow(const char * windowId);
	KviWindow       * findWindowByCaption(const char * windowCaption);
	KviConsole      * findConsole(unsigned int ircContextId);
	KviConsole      * findConsole(KviStr & server,KviStr & nick);
	bool              isAnyConsoleConnected();
	KviConsole      * topmostConnectedConsole();
	// KviConsole   * preferredConsole(KviConsole *c,KviFrame *f);  // unused
	// KviFrame     * preferredFrame(KviFrame *f);                  // unused
	KviWindow       * activeWindow();
	KviConsole      * activeConsole();
	KviFrame        * activeFrame();
	int               frameCount(){ return m_pFrameList->count(); };
	KviPtrList<KviFrame> * frameList(){ return m_pFrameList; };
	bool              windowExists(KviWindow *wnd);
	unsigned int      windowCount();

	// kvi_app.cpp : Utilities
	void resetAvatarForMatchingUsers(KviRegisteredUser * u);
	void restartNotifyLists();
	void triggerUpdateGui();
#ifdef COMPILE_PSEUDO_TRANSPARENCY
	void triggerUpdatePseudoTransparency();
#endif

	// kvi_app.cpp : DCC (and CTCP AVATAR & SOUND) related stuff
	void setAvatarOnFileReceived(KviConsole * pConsole,const char * fileName,const char * nick,const char * user,const char * host);
	KviPendingAvatarChange * findPendingAvatarChange(KviConsole * pConsole,const char * nick,const char * fileName);
	void dccFileReceived(const char * sendFileName,const char * localFileName,const char * nick);

	bool playFile(const char * filename,KviStr &error,KviWindow * w = 0);

	void addRecentNickname(const char * newNick);
	void addRecentChannel(const char * chan);
	void addRecentServer(const char * server);
	void fillRecentServersPopup(QPopupMenu * m);
	void fillRecentNicknamesPopup(QPopupMenu * m,KviConsole * pConsole);
	void fillRecentChannelsPopup(QPopupMenu * m,KviConsole * pConsole);
protected:
	// kvi_app.cpp : KviWindow global database
	void registerWindow(KviWindow *wnd);
	void unregisterWindow(KviWindow *wnd);
public slots:
	// kvi_app.cpp : Slots
	void createNewFrame();
	void saveConfiguration();
	void updateGui();
	void kdeRootPixmapDownloadComplete(bool bSuccess);
	void updatePseudoTransparency();
	void restoreDefaultScript();
private:
#ifdef COMPILE_SPLASH_SCREEN
	void createSplashScreen();
	void destroySplashScreen();
#endif

	// kvi_app_setup.cpp : Setup stuff
	void loadDirectories();
	void findGlobalKvircDirectory();
	bool findLocalKvircDirectory();
	bool checkGlobalKvircDirectory(const char *);
	bool checkLocalKvircDirectory(const char *);
	void saveKvircDirectory();

	// kvi_app.cpp : GUI stuff
	void updateFrameCaptions();
	void updateApplicationFont();
	void updateGuiEffects();
	void updateTaskBar();

#ifdef COMPILE_PSEUDO_TRANSPARENCY
	void createGlobalBackgrounds(QPixmap * pix);
	void destroyPseudoTransparency();
	#ifdef COMPILE_KDE_SUPPORT
		void downloadKdeRootPixmap();
	#endif //COMPILE_KDE_SUPPORT
#endif //COMPILE_PSEUDO_TRANSPARENCY

	void loadDefaultScript();
private:

	// kvi_app.cpp : parts of setup()
	void createSharedGraphicGlobals();
	void destroySharedGraphicGlobals();
	void loadRecentEntries();
#ifndef COMPILE_NO_IPC
	void createIpcSentinel();
	void destroyIpcSentinel();
#endif //!COMPILE_NO_IPC
};

extern KVIRC_API KviApp * g_pApp;

#endif //_KVI_APP_H_
