#ifndef _KVI_WINDOW_H_
#define _KVI_WINDOW_H_
//
//   File : kvi_window.h
//   Creation date : Tue Jul 6 1999 14:52:20 by Szymon Stefanek
//
//   This file is part of the KVirc irc client distribution
//   Copyright (C) 1999-2002 Szymon Stefanek (pragma at kvirc dot net)
//
//   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_string.h"
#include "kvi_wstring.h"
#include "kvi_settings.h"

#ifdef COMPILE_ON_WINDOWS
	// The brain-damaged MSVC compiler can't instantiate QList templates without a destructor definition
	#include "kvi_mdichild.h"
#else
	class KviMdiChild;
#endif
class KviFrame;
class KviTaskBarItem;
class KviConfig;
class KviIrcView;
class KviInput;
class KviConsole;

class QPopupMenu;
class QPixmap;
class QSplitter;
class QHBox;
class QAccel;
class QToolButton;

#ifdef COMPILE_CRYPT_SUPPORT
	class KviCryptController;
	typedef struct _KviCryptSessionInfo KviCryptSessionInfo;
#endif

#include <qwidget.h>

//
// Window types
//
// There are KVI_WINDOW_NUM_TYPES predefined
// window types: these are used by the KVIrc core and distributed modules
// If you add a new def, increase KVI_WINDOW_NUM_TYPES
//

#define KVI_WINDOW_TYPE_CONSOLE 0
#define KVI_WINDOW_TYPE_CHANNEL 1
#define KVI_WINDOW_TYPE_QUERY 2
#define KVI_WINDOW_TYPE_HELP 3
#define KVI_WINDOW_TYPE_TERM 4
#define KVI_WINDOW_TYPE_EDITOR 5
#define KVI_WINDOW_TYPE_DCCCHAT 6
#define KVI_WINDOW_TYPE_DCCSEND 7
#define KVI_WINDOW_TYPE_SOCKETSPY 8
#define KVI_WINDOW_TYPE_LINKS 9
#define KVI_WINDOW_TYPE_ICQ 10 /* actually dead */
#define KVI_WINDOW_TYPE_GNUTELLA 11
#define KVI_WINDOW_TYPE_DIRBROWSER 12
#define KVI_WINDOW_TYPE_DCCCANVAS 13
#define KVI_WINDOW_TYPE_DCCVOICE 14
#define KVI_WINDOW_TYPE_LIST 15
#define KVI_WINDOW_TYPE_OFFER 16
#define KVI_WINDOW_TYPE_LOGVIEW 17
#define KVI_WINDOW_TYPE_DEADCHANNEL 18
#define KVI_WINDOW_TYPE_DEADQUERY 19
#define KVI_WINDOW_TYPE_SCRIPTEDITOR 20
#define KVI_WINDOW_TYPE_SCRIPTOBJECT 21

#define KVI_WINDOW_NUM_TYPES 22

#define KVI_WINDOW_TYPE_USER 10000


class KVIRC_API KviWindow : public QWidget
{
	friend class KviInput;
	friend class KviFrame;
	friend class KviTaskBarItem;
	friend class KviTaskBarButton;
	friend class KviTreeTaskBarItem;
	friend class KviTreeTaskBar;
	Q_OBJECT
public:
	KviWindow(int type,KviFrame * lpFrm,const char * name,KviConsole * lpConsole = 0);
	virtual ~KviWindow();
protected: // almost private: don't touch :D
	KviFrame                            * m_pFrm;
	KviConsole                          * m_pConsole;
	int                                   m_iType;
	KviTaskBarItem                      * m_pTaskBarItem;
	QWidget                             * m_pFocusHandler;
	QString                               m_szPlainTextCaption;
	QString                               m_szHtmlActiveCaption;
	QString                               m_szHtmlInactiveCaption;
	KviIrcView                          * m_pIrcView;
	KviInput                            * m_pInput;
	QSplitter                           * m_pSplitter;
	QHBox                               * m_pButtonBox;
	KviStr                                m_szId;
#ifdef COMPILE_CRYPT_SUPPORT
	QToolButton                         * m_pCryptControllerButton;
	KviCryptController                  * m_pCryptController;
	KviCryptSessionInfo                 * m_pCryptSessionInfo;
#endif
	QToolButton                         * m_pTextEncodingButton;
	QWidget                             * m_pLastFocusedChild;
	QAccel                              * m_pAccel;
	static const char                   * m_typeTable[KVI_WINDOW_NUM_TYPES + 1];
	unsigned int                          m_uTextEncoding;
public:
	// The global ID of this window: unique in the application
	const char * id(){ return m_szId.ptr(); };

	// Window type management
	int type() const { return m_iType; };
	// This returns a descriptive name of the window type
	// if the window is an user window, the typeString returned
	// by THIS implementation is "unknown"
	virtual const char * typeString();

	// The frame that this window belongs to
	// It is always non-null and never changes
	KviFrame * frame() const { return m_pFrm; };
	// The KviIrcView of this window: may be NULL if the window has no KviIrcView (and thus supports no direct output)
	KviIrcView * view() const { return m_pIrcView; };
	// The mdiParent widget: may be nulll if the window is undocked
	KviMdiChild * mdiParent(){ return (KviMdiChild *)parent(); };
	// The console that this window belongs to: may be null for windows that aren't bound to irc contexts
	KviConsole * console(){ return m_pConsole; };
	// The splitter of this window: it *shouldn't* be null... but ... well.. who knows ? :D ...better check it
	QSplitter * splitter(){ return m_pSplitter; };
	// The window has ALWAYS a taskbar item
	KviTaskBarItem * taskBarItem(){ return m_pTaskBarItem; };
	// The window *might* have a button container
	QHBox * buttonContainer(){ return m_pButtonBox; };
	// The window *might* have an output proxy: if it has no view() for example
	virtual KviWindow * outputProxy();

	// The target of this window: empty when it makes no sense :D
	virtual const char * target(){ return KviStr::emptyString(); };
	// The local nickname bound to this window: might be empty when a local nickname makes no sense
	virtual const char * localNick(){ return KviStr::emptyString(); };

#ifdef COMPILE_CRYPT_SUPPORT
	KviCryptSessionInfo * cryptSessionInfo(){ return m_pCryptSessionInfo; };
#endif

	virtual void getTaskBarTipText(QString &buffer);

	// This is meaningful only if view() is non NULL
	const QString & lastLineOfText();

	unsigned int textEncoding(){ return m_uTextEncoding; };

	void contextPopup();
	// Raises the window (after a light delay to prevent focus pingpongs)
	void delayedAutoRaise();
	// Window state: might work :D
	bool isMinimized();
	bool isMaximized();
	// Retrieves the default log file name: this is pre-build
	void getDefaultLogFileName(KviStr &buffer);
	// Well...the external geometry :)
	QRect externalGeometry();

	void delayedClose(); // close that jumps out of the current event loop

	// Interesting overridables:
	virtual void fillContextPopup(QPopupMenu * p);
	virtual void getConfigGroupName(KviStr &buf);
	virtual void getBaseLogFileName(KviStr &buffer);
	virtual void updateCaption();
	virtual void updateIcon();
	virtual void applyOptions();
	virtual void ownMessage(const char * text){};
	virtual void ownAction(const char * text){};
	virtual const QString & plainTextCaption(){ return m_szPlainTextCaption; };
	virtual const QString & htmlActiveCaption(){ return m_szHtmlActiveCaption; };
	virtual const QString & htmlInactiveCaption(){ return m_szHtmlInactiveCaption; };

	// You *might* want to override these too.. but better don't touch them :D
	virtual void output(int msg_type,const char * format,...);
	virtual void outputNoFmt(int msg_type,const char * text);
	virtual void output(int msg_type,const kvi_wchar_t * format,...);
	virtual void outputNoFmt(int msg_type,const kvi_wchar_t * text);

	// Just helpers.. FIXME: might be redesigned in some other way
	void updateBackgrounds(QObject * obj = 0);



	// This should die, probably
	void listWindowTypes();
public slots:
	void dock();
	void undock();
	void autoRaise();
	void maximize();
	void minimize();
	void restore();
protected slots:
	void savePropertiesAsDefault();
	void toggleCryptController();     // This has to be here even if the crypt support is enabled...moc does not support conditionals
	void cryptControllerFinished();   // same as above
	void cryptSessionInfoDestroyed(); //  same as above
	void textEncodingButtonClicked();
	void systemPopupRequest(const QPoint &pnt);
	void systemTextEncodingPopupActivated(int id);

protected:
	// Loading and saving of properties
	// Protected: only KviFrame can call these
	virtual void saveProperties(KviConfig *cfg);
	virtual void loadProperties(KviConfig *cfg);
	// Creation and destruction events: overridden in windows that have script events bound to creation and destruction
	virtual void triggerCreationEvents(){};
	virtual void triggerDestructionEvents(){};
	// Internal: do not touch :D (KviFrame)
	virtual void createTaskBarItem();
	virtual void destroyTaskBarItem();
	// Sets the progress for the taskbar item: if "progress" makes sense in your window , well , use this
	void setProgress(int progress);
	// call this in the constructor if your caption is fixed:
	// it will set m_szPlainTextCaption to szCaption and it will
	// automatically use it without the need of overriding fillCaptionBuffers
	void setFixedCaption(const QString &szCaption);
	// this by default calls fillSingleColorCaptionBuffer(plainTextCaption());
	virtual void fillCaptionBuffers();
	// protected helper
	void fillSingleColorCaptionBuffers(const QString &szName);
	// Virtual events that signal dock state change
	virtual void youAreDocked();
	virtual void youAreUndocked();
	// Reimplement to show a special icon in the taskbar items and captions
	virtual QPixmap * myIconPtr();
	// Sets the type of this window: be careful with this
	void setType(int iType);

	bool eventFilter(QObject *o,QEvent *e);

	// Virtuals overridden to manage the internal layouts...
	virtual void moveEvent(QMoveEvent *e);
	virtual void closeEvent(QCloseEvent *e);
	virtual void wheelEvent(QWheelEvent *e);
	virtual void childEvent(QChildEvent *e);
	virtual void focusInEvent(QFocusEvent *e);

	void childInserted(QWidget * o);
	void childRemoved(QWidget * o);

	void activateSelf();

	// Internal helpers
	void createCryptControllerButton(QWidget * par);
	void createTextEncodingButton(QWidget * par);
	void createSystemTextEncodingPopup();

	QToolButton * createToolButton(QWidget * par,const char * nam,int pixon,int pixoff,const QString & tooltip,bool bOn);
	// This is called by KviInput: actually it links the widgetAdded
	virtual void childrenTreeChanged(QWidget * widgetAdded);
};

#endif //_KVI_WINDOW_H_
