#ifndef CHAT_H
#define CHAT_H

#include <qcolor.h>
#include <qdialog.h>
#include <qmap.h>
#include <qmultilineedit.h>
#include <qpushbutton.h>
#include <qrect.h>
#include <qsplitter.h>
#include <qvariant.h>
#include <qvaluelist.h>

#include "emoticons.h"
#include "misc.h"
#include "userbox.h"

class Chat;
class QHBox;
class ChatSlots;
/** \typedef QValueList<Chat*> ChatList */
typedef QValueList<Chat*> ChatList;

/**

	Klasa przechowująca informacje o wiadomości, która ma się pojawić
	w oknie Chat.
	\class ChatMessage
	\brief Klasa przechowująca informacje o wiadomości.
**/
class ChatMessage
{
	public:
	QString nick;/*!< nazwa użytkownika */
	QDateTime date; /*!< data otrzymania wiadomości */
	QDateTime sdate; /*!< data wysłania wiadomości */
	QString unformattedMessage; /*!< niesformatowana wiadomość */
	bool isMyMessage; /*!< zmienna mowiąca czy wiadomośc została 
				napisana przez nas */
	QColor backgroundColor; /*!< tło wiadomości */
	QColor textColor; /*!< kolor wiadomości */
	
	
	QMap<QString, bool> attributes; /*!<
		Może służyć do przechowywania informacji o tym
		czy wiadomość była potwierdzona, szyfrowana, ...
		W zamyśle ma służyć do określania czy jakiś obrazek
		ma być dodawany do wiadomości czy nie - jaki obrazek -
		ta informacja będzie gdzie indziej
		*/
	
	//inne atrybuty?
	//QMap<QString, QString> stringAttributes;
	
	bool needsToBeFormatted;/*!< zmienna mowiąca czy wiadomośc powinna 
				  być sformatowana */
	
	QString message;/*!<
			Sformatowana wiadomość (razem z \<p\> lub \<table\>)
			**/


	/**
		\fn ChatMessage(const QString &nick, const QString &unformattedMessage, bool myMessage, QDateTime date, QDateTime sdate=QDateTime())
		Konstruktor ustawiający nick, niesformatowaną wiadomość,
		czy wiadomość pochodzi od nas, datę wiadomości,
		datę nadania wiadomości przez serwer
		\param nick nazwa użytkownika
		\param unformattedMessage niesformatowana wiadomość
		\param myMessage zmienna mowiąca czy wiadomość pochodzi od nas
		\param date data otrzymania wiadomości
		\param sdate data wysłania wiadomości
	**/
	ChatMessage(const QString &nick, const QString &unformattedMessage, bool myMessage, QDateTime date, QDateTime sdate=QDateTime());
	/**
		\fn ChatMessage(const QString &formattedMessage, const QColor &bgColor=Qt::white, const QColor &textColor=Qt::black)
		Konstruktor ustawiający sformatowaną wiadomość,
		kolor tła i liter wiadomości
		\param nick nazwa użytkownika
		\param unformattedMessage niesformatowana wiadomość
		\param myMessage zmienna mowiąca czy wiadomość pochodzi od nas
		\param date data otrzymania wiadomości
		\param sdate data wysłania wiadomości
	**/
	ChatMessage(const QString &formattedMessage, const QColor &bgColor=Qt::white, const QColor &textColor=Qt::black);
};
/**
	Klasa pozwalająca zarządzać otwartymi oknami rozmów: otwierać,
	zamykac, szukać okna ze wględu na listę użytkowników itp.
	\class ChatManager
	\brief Klasa zarządzająca oknami Chat
**/
class ChatManager : public QObject
{
	Q_OBJECT

	private:
		ChatList Chats;/*!< lista okien*/
		
		static ChatSlots *chatslots;
		/**
		\fn int openPendingMsg(int index, ChatMessage &msg)
		Funkcja otwierająca zakolejkowaną wiadomość
		\param index nr wiadomości z kolejki
		\param msg wiadomość z kolejki
		\return zwracany jest nr okna w którym została otwarta wiadomość
		**/
		int openPendingMsg(int index, ChatMessage &msg);
		
		/** 
		\struct ChatInfo
		Struktura przechowuje informacje o danym oknie
		**/
		struct ChatInfo
		{
			UinsList uins;/*!< lista użytkowników 
					identyfikująca okno */
			QMap<QString, QVariant> map; /*!< parametry 
							danego okna */
		};
		QValueList<ChatInfo> addons; /*!< lista parametrów okien */

	public:	
		/**
		\fn ChatManager(QObject* parent=NULL, const char* name=NULL)
		Konstruktor tworzący obiekt zarządzający oknami
		\param parent rodzic okna
		\param name nazwa obiektu
		**/
		ChatManager(QObject* parent=NULL, const char* name=NULL);
		
		/**
			\fn ~ChatManager()
			Destruktor zamyka wszystkie otwarte okna
		**/
		
		~ChatManager();
		
		/**
			\fn const ChatList& chats() const
			Funkcja zwraca liste otwartych okien Chat
		**/

		/**
			\fn static void initModule()
			Rejestruje opcje modulu Chat w oknie konfiguracji
		**/
		static void initModule();
		static void closeModule();

		const ChatList& chats() const;
		
		/**
			\fn Chat* findChatByUins(const UinsList &uins) const
			Funkcja zwraca wskaźnik do okna z listą 
			użytkowników uins
			\param uins lista użytkowników
			\return wskaźnik do okna jeśli istnieje w przeciwnym
			 wypadku zwraca NULL
		**/
		Chat* findChatByUins(const UinsList &uins) const;
		
		/**
			\fn QVariant& getChatProperty(const UinsList &uins, const QString &name)
			Funkcja zwraca wartość własności "name" okna 
			określonego przez uins
			\param uins lista użytkowników identyfikująca okno
			\param name nazwa własności
			\return zwraca wartość własności jeśli określone okno 
			istnieje,\n jeśli nie to tworzy taką 
			własność (ustawia na pustą)
		**/
		QVariant& getChatProperty(const UinsList &uins, const QString &name);
		
	public slots:
	
		/**
			\fn void chatMsgReceived(UinsList senders,const QString& msg,time_t time,bool& grab)
			Slot informujący o odebraniu wiadomości
			\param senders lista użytkowników identyfikujących okno
			\param msg treść otrzymanej wiadomości
			\param time czas otrzymania wiadomości
			\param grab 
		**/
		void chatMsgReceived(UinsList senders,const QString& msg,time_t time,bool& grab);

		/**
			\fn int openChat(UinsList senders,time_t time=0)
			Funkcja otwiera nowe okno Chat z wymienionymi rozmowcami.
			\param senders lista użytkowników identyfikujących okno
			\param time parametr sluzy do sprawdzenia ile wiadomosci
			z historii ma sie pojawic w oknie.
			\return zwracany jest numer otwartego okna 
		**/
		int openChat(UinsList senders,time_t time=0);		
		
		/**
			\fn void openPendingMsgs(UinsList uins)
			Funkcja wpisuje zakolejkowane wiadomości do okna
			z użytkownikami "uins"
			\param uins lista użytkowników identyfikujących okno
		**/
		void openPendingMsgs(UinsList uins);
		
		/**
			\fn void openPendingMsgs()
			Funkcja wpisuje wszystkie zakolejkowane wiadomości 
			do odpowiednich okien
		**/
		void openPendingMsgs();
		
		//TODO: opisac funkcje sendMessage(..)
		/*
			Niebardzo rozumiem tej funkcji (czemu jest uin i uins)	
		*/
		void sendMessage(UinType uin,UinsList selected_uins);
		
		/**
			\fn void closeAllWindows()
			Funkcja zamyka wszystkie okna chat
		**/
		void closeAllWindows();
		
		/**
			\fn int registerChat(Chat* chat)
			Dodaje okno do menadżera
			\param chat wskaźnik do okna ktore chcemy dodać
			\return zwraca numer naszego okna po zarejestrowaniu
		**/
		int registerChat(Chat* chat);
		
		/**
			\fn void unregisterChat(Chat* chat)
			Funkcja wyrejestrowuje okno z managera \n
			Zapisuje własności okna \n
			wysyła sygnał chatDestroying i chatDestroyed
			\param chat okno które będzie wyrejestrowane
		**/
		void unregisterChat(Chat* chat);
		
		/**
			\fn void refreshTitles()
			Funkcja odświeża tytuły wszystkich okien
		**/
		void refreshTitles();
		
		/**
			\fn void refreshTitlesForUin(UinType uin)
			Funkcja odświeża tytuły okien które zawierają uin
			\param uin nr użytkownika, którego 
			opis/status będzie odświeżany
		**/
		void refreshTitlesForUin(UinType uin);
		
		/**
			\fn void changeAppearance()
			Funkcja odświeża kolory i czcionki we wszystkich oknach
		**/
		void changeAppearance();
		
		/**
			\fn void setChatProperty(const UinsList &uins, const QString &name, const QVariant &value)
			Funkcja pozwala przypisać określonemu czatowi 
			(nawet jeżeli on jeszcze nie istnieje) pewne własności
			\param uins lista użytkowników identyfikujących okno
			\param name nazwa własności
			\param value wartość własności
		**/
		void setChatProperty(const UinsList &uins, const QString &name, const QVariant &value);
		
	signals:
		
		/**
			\fn void chatCreated(const UinsList& senders)
		 	Sygnał ten jest wysyłany po utworzeniu nowego okna chat
			\param senders lista uin-ów z którymi tworzymy nowy chat
		**/
		void chatCreated(const UinsList& senders);
		
		/**
			\fn void chatDestroying(const UinsList& senders)
		 	Sygnał ten jest wysyłany przed zamnknięciem okna chat
			\param senders lista uin-ów które występują w tym chacie
		**/
		void chatDestroying(const UinsList& senders);
		
		/**
			\fn void chatDestroyed(const UinsList& senders)
		 	Sygnał ten jest wysyłany po zamnknięciem okna chat
			\param senders lista uin-ów które 
			występowały w tym chacie
		**/
		void chatDestroyed(const UinsList& senders);
		
		/**
			\fn void chatOpen(const UinsList& senders)
			Sygnał ten jest wysyłaniy podczas każdej próby 
			otwarcia nowego okna chat nawet jeśli już taki istnieje
			\param senders lista uin-ów
		**/
		void chatOpen(const UinsList& senders);
};

/** 
	wskaźnik do obiektu ChatManager'a 
**/
extern ChatManager* chat_manager; 

class EmoticonSelector;
class ColorSelector;
/**
	\class CustomInput
	\brief Klasa umożliwiająca wpisywanie wiadomości
**/
class CustomInput : public QMultiLineEdit
{
	Q_OBJECT

	protected:
		
		bool autosend_enabled;/*!< zmienna informująca czy włączone jest 
					automatyczne wysyłanie */
		/**
			\fn virtual void keyPressEvent(QKeyEvent *e)
			Funkcja obsługująca naciśnięcie przycisku
			\param e wskaźnik do obiektu obsługującego klawisze
		**/
		virtual void keyPressEvent(QKeyEvent *e);
		
		/**
			\fn virtual void keyReleaseEvent(QKeyEvent *e)
			Funkcja obsługująca zwolnienie przycisku
			\param e wskaźnik do obiektu obsługującego klawisze
		**/
		virtual void keyReleaseEvent(QKeyEvent* e);

	public:
		
		/*! Typ wyliczeniowy mowiący o rodzaju pisanych znaków */
		enum
		{
			KEY_BOLD,/*!< pogrubienie */
			KEY_ITALIC,/*!< kursywa */
			KEY_UNDERLINE/*!< podkreślenie */
		};
		
		/**
			\fn CustomInput(QWidget* parent = 0, const char* name = 0)
			Konstruktor tworzący obiekt 
			i ustawiający odpowiedni styl
			\param parent rodzic okna
			\param name nazwa obiektu
		**/
		CustomInput(QWidget* parent = 0, const char* name = 0);

	public slots:
		
		/**
			\fn void paste()
			Slot wkleja czysty tekst
		**/
		void paste();
		
		/**
			\fn void setAutosend(bool on)
			Ustawia/wyłącza automatyczne wysyłanie wiadomości
			\param on zmienna ustawiająca autosend
		**/
		void setAutosend(bool on);

	signals:
		
		/**
			\fn void sendMessage()
			Sygnał zostaje wysłany kiedy naciśnięto 
			klawisz wysłania wiadomości
		**/
		void sendMessage();
		
		/**
			\fn void specialKeyPressed(int key)
			Sygnał zostaje wysłany gdy naciśnięto specjalny 
			klawisz (skrót) odpowiadający np KEY_BOLD
			\param key wartość z typu wyliczeniowego KEY_*
		**/
		void specialKeyPressed(int key);
		
		/**
			\fn void keyPressed(QKeyEvent* e, CustomInput* sender)
			Dowolny przycisk klawiatury został naciśnięty.
			Przekazany zostaje także obiekt, który wywołał akcję -
			 czyli this
			\param e wskaźnik do obiektu obsługującego klawisze
			\param sender wskaźnik do obiektu, który
			wywołał ten sygnał
		**/
		void keyPressed(QKeyEvent* e, CustomInput* sender);
		
		/**
			\fn void keyReleased(QKeyEvent* e, CustomInput* sender)
			Dowolny przycisk klawiatury został zwolniony.
			Przekazany zostaje także obiekt, który wywołał akcję -
			 czyli this.
			\param e wskaźnik do obiektu obsługującego klawisze
			\param sender wskaźnik do obiektu, który
			wywołał ten sygnał
		**/
		void keyReleased(QKeyEvent* e, CustomInput* sender);
};

/**
	Klasa wykorzystana do oddzielenia listy użytkowników od historii
	i pola do wpisywania wiadomości
	\class KaduSplitter
	\brief Klasa rozdzielająca kontrolki

**/
class KaduSplitter : public QSplitter
{
	protected:
		QValueList<KaduTextBrowser*> textbrowsers;
		void drawContents(QPainter* p);
		void childEvent(QChildEvent* c);

	public:
	/**
		Konstruktor tworzący obiekt
		\fn KaduSplitter(QWidget* parent = 0, const char* name = 0)
		\param parent rodzic okna
		\param name nazwa obiektu

	**/
		KaduSplitter(QWidget* parent = 0, const char* name = 0);
	
	/**
		Konstruktor tworzący obiekt o danej orientacji
		\fn KaduSplitter(Orientation o, QWidget* parent = 0, const char* name = 0)
		\param parent rodzic okna
		\param name nazwa obiektu
		\param o orientacja separatora
	**/
		KaduSplitter(Orientation o, QWidget* parent = 0, const char* name = 0);
};

class QMimeSourceFactory;

/**
	Klasa tworząca okno rozmowy, rejestrująca przyciski,
	formatująca wiadomość itp.
	\class Chat
	\brief Okno rozmowy
**/
class Chat : public QWidget
{
	Q_OBJECT

	private:
		friend class ChatManager;
		/**
		\struct RegisteredButton struktura przechowująca informacje o zarejestrowanym przycisku
		**/
		struct RegisteredButton
		{
			QString name; /*!< nazwa przycisku */
			QObject* receiver; /*!< obiekt z którego wykorzystana
					będzie funkcja do obsługi przycisku */
			QString slot; /*!< funkcja podpięta pod obsługę
						tego przycisku */
		};
		static QValueList<RegisteredButton> RegisteredButtons;/*!<
				zarejestrowane przyciski w oknie rozmowy */
		QMap<QString,QPushButton*> Buttons; /*!< przyciski z okna */
		
		QValueList<ChatMessage *> ChatMessages; /*!< wiadomości wpisane 
							w oknie rozmowy */
	
		UinsList Uins; /*!< lista użytkowników w danym oknie */
		int index;	/*!< nr okna (z chat menadżera) */
		QString title_buffer; /*!< tytuł okna */
		QTimer* title_timer;  /*!< zmienna przechowująca czas od ostatniego 
					odświeżenia tytułu okna */
		QColor actcolor; /*!< zmienna przechowująca aktualny kolor */
		
		QMimeSourceFactory *bodyformat; /*!< zmienna ustawiający format */
		EmoticonSelector* emoticon_selector; /*!< okienko do 
							wyboru emotikonek */
		ColorSelector* color_selector; /*!< okienko do wyboru koloru */
		QPushButton* boldbtn; /*!< przycisk pogrubiający czcionkę */
		QPushButton* italicbtn; /*!< przycisk ustawiający 
					czcionkę na kursywę */			
		QPushButton* underlinebtn; /*!< przycisk podkreślający tekst */
		QPushButton* colorbtn; /*!< przycisk umożliwiający 
					wybór koloru czcionki*/
		QPushButton* iconsel;
		QPushButton* autosend; /*!< przycisk automatycznego wysyłania */
		QPushButton* lockscroll; /*!< przisk blokowania 
						przesuwania rozmowy */
		QAccel* acc; /*!< zmienna potrzebna do
				 rejestracji skrótów klawiszowych*/
		QPushButton* sendbtn; /*!< przycisk do wysyłania wiadomości */
		UserBox* userbox; /*!< lista kontaktów przydatna gdy jesteśmy w
						 konferencji */
		QString myLastMessage;/*!< zmienna przechowująca 
					naszą ostatnią wiadomość */
		unsigned int myLastFormatsLength; /* ?? */
		void* myLastFormats; /* ?? */
		int seq; /* ?? */
		KaduSplitter *vertSplit, *horizSplit; /*!< obiekty oddzielające
							 kontrolki od siebie */
		int ParagraphSeparator; /* ?? */
		QDateTime lastMsgTime; /*!< czas ostatniej wiadomości */

		/**
			\fn void pruneWindow()
			Funkcja czyszcząca okno rozmowy
		**/
		void pruneWindow(); 

	private slots:
		
		/**
			\fn void userWhois()
			Slot wyświetlający informacje o zaznaczonym kontakcie
		**/
		void userWhois();
		
		/**
			\fn void emoticonSelectorClicked()
			Slot wyświetlający okno z wyborem emotikonek
		**/
		void emoticonSelectorClicked();
		
		/**
			\fn void changeColor()
			Slot zmieniający kolor czcionki
		**/
		void changeColor();
		
		/**
			\fn void addMyMessageToHistory()
			Slot dodaje wysłaną wiadomość do historii rozmowy
		**/
		void addMyMessageToHistory();
		
		/**
			\fn void clearChatWindow()
			Slot czyszczący okno rozmowy
		**/
		void clearChatWindow();
		
		/**
			\fn void pageUp()
			Slot przewijający historię rozmowy w górę
		**/
		void pageUp();
		
		/**
			\fn void pageDown()
			Slot przewijający historię rozmowy w dół
		**/
		void pageDown();
		
		/**
			\fn void insertImage()
			Slot wklejający obrazek do okna rozmowy (wybór obrazka)
		**/
		void insertImage();
		
		/**
			\fn void imageReceivedAndSaved(UinType sender,uint32_t size,uint32_t crc32,const QString& path)
			Slot obsługujący odebranie i zapis obrazka
			\param sender osoba, która wysłała obrazek
			\param size rozmiar obrazka
			\param crc32 suma kontrolna obrazka
			\param path ścieżka do obrazka
		**/
		void imageReceivedAndSaved(UinType sender,uint32_t size,uint32_t crc32,const QString& path);

		/**
			\fn void connectAcknowledgeSlots();
			Slot podłączający potwierdzenie dostarczenia wiadomości
		**/
		void connectAcknowledgeSlots();
		
		/**
			\fn void disconnectAcknowledgeSlots();
			Slot odłączający potwierdzenie dostarczenia wiadomości
		**/
		void disconnectAcknowledgeSlots();

	protected:
		/**
			\fn virtual void closeEvent(QCloseEvent* e)
			Funkcja obsługująca zamknięcie okna
		**/
		virtual void closeEvent(QCloseEvent* e);
		
		/**
			\fn QString convertCharacters(QString text, const QColor &bgcolor, EmoticonsStyle style)
			Funkcja zamienia specjalne tagi na emotikonki,
			html na czysty tekst itp.
			\param text tekst do konwersji
			\param bgcolor kolor tła
			\param style styl emotikonek
		**/
		QString convertCharacters(QString text, const QColor &bgcolor, EmoticonsStyle style);
		
		/**
			\fn virtual void windowActivationChange(bool oldActive)
			Funkcja sterująca mruganiem napisu okna
		**/
		virtual void windowActivationChange(bool oldActive);
		
		/**
			\fn virtual void keyPressEvent(QKeyEvent* e)
			Funkcja obsługująca naciśnięcie przycisku
			\param e wskaźnik do obiektu obsługującego klawisze
		**/
		virtual void keyPressEvent(QKeyEvent* e);
		
		/**
			\fn virtual void keyReleaseEvent(QKeyEvent* e)
			Funkcja obsługująca zwolnienie przycisku
			\param e wskaźnik do obiektu obsługującego klawisze
		**/
		virtual void mouseReleaseEvent(QMouseEvent *e);

	public:
		// FIXME - nie powinno byc publicznych zmiennych
		KaduTextBrowser* body; /*!< historia rozmowy */
		CustomInput* edit; /*!< okno do wpisywania wiadomości */
		QHBox* buttontray;/* ?? */
		
		/**
			Konstruktor okna rozmowy
			\fn Chat(UinsList uins, QWidget* parent = 0, const char* name = 0)
			\param parent rodzic okna
			\param name nazwa obiektu
		**/
		Chat(UinsList uins, QWidget* parent = 0, const char* name = 0);
		
		/**
			\fn ~Chat()
			Destruktor okna rozmowy
		**/
		~Chat();
		
		/**
			\fn static void registerButton(const QString& name, QObject* receiver, const QString& slot)
			Rejestruje przycisk w oknie chat, ustawia funkcje do obsługi 
			sygnału "clicked"
			\param name nazwa przycisku aby moc się do niego odwołać
			\param receiver obiekt który zawiera funkcje do obsługi zdarzenia
			\param slot funkcja która będzie obsługiwać zdarzenie "clicked"
		**/
		static void registerButton(const QString& name, QObject* receiver, const QString& slot);
		
		/**
			\fn static void unregisterButton(const QString& name)
			Wyrejestrowuje przycisk ze wszystkich okien
			\param name nazwa przycisku do wyrejestrowania
		**/
		static void unregisterButton(const QString& name);
		
		/**
			\fn QPushButton* button(const QString& name) const
			Zwraca wskaźnik do przycisku 
			\param name nazwa przycisku
			\return wskaźnik do przycisku, jeśli przycisk 
			nie istnieje zwraca NULL
		**/
		QPushButton* button(const QString& name) const;
		
		/**
			\fn void formatMessages(QValueList<ChatMessage *> &msgs)
			Formatuje wszystkie wiadomości na html'a,
			dodaje kolory tła i czcionek
			\param msgs lista wiadomości do sformatowania
		**/
		void formatMessages(QValueList<ChatMessage *> &msgs);
		/**
			\fn void formatMessage(ChatMessage &msg,
				QColor myBgColor=QColor(), QColor usrBgColor=QColor(),
				QColor myFontColor=QColor(), QColor usrFontColor=QColor(),
				EmoticonsStyle style=(EmoticonsStyle)config_file.readNumEntry("Chat","EmoticonsStyle"))

			Formatuje wiadomość na html'a
			\param msg wiadomość która będzie sformatowana
			\param myBgColor kolor który będzie ustawiony jako tło
			w naszych wiadomościach
			\param usrBgColor kolor, który będzie ustawiony jako tło
			wiadomości naszego rozmówcy
			\param myFontColor kolor naszej czcionki
			\param usrFontColor kolor czcionki naszego rozmówcy
			\param style styl ikonek 
		**/
		void formatMessage(ChatMessage &msg,
				QColor myBgColor=QColor(), QColor usrBgColor=QColor(),
				QColor myFontColor=QColor(), QColor usrFontColor=QColor(),
				EmoticonsStyle style=(EmoticonsStyle)config_file.readNumEntry("Chat","EmoticonsStyle"));
		
		/**
			\fn void checkPresence(UinsList, const QString&, time_t, QValueList<ChatMessage *> &messages)
			Dodaje wiadomość do okna
			\param senders lista użytkowników
			\param msg wiadomośc
			\param time czas 
			\param messages lista wiadomości do wpisania do okna
		**/
		void checkPresence(UinsList senders, const QString &msg, time_t time, QValueList<ChatMessage *> &messages);
		
		/**
			\fn void writeMessagesFromHistory(UinsList senders, time_t time)
			Wpisuje do okna historię rozmowy
			\param senders lista użytkowników identyfikujących okno
			\param time ..
		**/
		void writeMessagesFromHistory(UinsList senders, time_t time);
		
		/**
			\fn const UinsList& uins() const
			Zwraca listę numerów rozmowców.
		**/
		const UinsList& uins() const;
		
		/**
			\fn QValueList<ChatMessage*>& chatMessages()
			Daje dostęp do wiadomości aktualnie przechowywanych
			w oknie chat. Metody tej można użyć do zmiany treści
			lub właściwości którejś z wiadomości w odpowiedzi
			na jakieś zdarzenie.
		**/
		QValueList<ChatMessage*>& chatMessages();
		
		/**
			\fn void repaintMessages()
			Odświeża zawartość okna uwzględniając ewentualne
			zmiany dokonane w którejś wiadomości z listy
			uzyskanej za pomocą metody chatMessages(),
			dodanie nowych wiadomości lub usunięcie istniejących.
		**/
		void repaintMessages();
		
		/**
			\fn const QString& title() const
			Zwraca aktualny tytuł okna
		**/
		const QString& title() const;

	public slots:
		
		/**
			\fn void changeAppearance()
			Slot zmieniający kolory i czcionki w oknie
		**/
		void changeAppearance();
		
		/**
			\fn void setTitle()
			Slot ustawiający tytuł okna zgodnie z konfiguracją
		**/
		void setTitle();
		
		/**
			\fn void addEmoticon(QString)
			Slot dodaje ikonke do pola wpisywania wiadomości
			\param emot ikonka np. <lol>
		**/
		void addEmoticon(QString);
		
		/**
			\fn void scrollMessages(const QValueList<ChatMessage *> &)
			Slot dodaj wiadomości do okna
			\param messages lista wiadomości
		**/
		void scrollMessages(const QValueList<ChatMessage *> &);
		
		/**
			\fn void alertNewMessage()
			Slot informujący o nowej wiadomości 
			mruganie jeśli okno jest nieaktywne
		**/
		void alertNewMessage();
		
		/**
			\fn void HistoryBox()
			Slot wywoływany po naciśnięciu przycisku historii
		**/
		void HistoryBox();
		
		/**
			\fn void sendMessage()
			Slot wywoływany po naciśnięciu przycisku 
			do wysyłania wiadomości
		**/
		void sendMessage();
		
		/**
			\fn void cancelMessage()
			Slot wywoływany po naciśnieciu przycisku anulowania
			wysyłaniu wiadomości
		**/
		void cancelMessage();
		
		/**
			\fn void writeMyMessage()
			Slot wpisujący wiadomość do okna
			\see sendMessage
		**/
		void writeMyMessage();
		
		/**
			\fn void changeTitle()
			Slot zmieniający tytuł 
			\see setTitle
		**/
		void changeTitle();
		
		/**
			\fn void toggledBold(bool on)
			Slot wywoływany przy naciśnięciu przycisku pogrubienia
			\param on ustawia pogrubienie
		**/
		void toggledBold(bool on);
		
		/**
			\fn void toggledItalic(bool on)
			Slot wywoływany przy naciśnięciu przycisku kursywy
			\param on ustawia kursywę
		**/
		void toggledItalic(bool on);
		
		/**
			\fn void toggledUnderline(bool on)
			Slot wywoływany przy naciśnięciu przycisku podkreślenia
			\param on ustawia podkreślenie
		**/
		void toggledUnderline(bool on);
		
		/**
			\fn void curPosChanged(int para, int pos)
			Slot wywoływany kiedy pozycja kursosa zmieniła się
			\param  para nie obslugiwane
			\param pos nie obslugiwane
		**/
		void curPosChanged(int para, int pos);
		
		/**
			\fn void specialKeyPressed(int key)
			Slot zostaje wywołany gdy naciśnięto specjalny klawisz (skrót)
			odpowiadający np KEY_BOLD
			\param key wartość naciśniętego specjalnego klawisza
		**/
		void specialKeyPressed(int key);
		
		/**
			\fn void colorChanged(const QColor& color)
			Slot zostaje wywołwany gdy użytkownik zmienił kolor czcionki
			którą będzie pisał
			\param color wartość zmienionego koloru
		**/
		void colorChanged(const QColor& color);
		
		/**
			\fn void colorSelectorAboutToClose()
			Slot zostaje wywołany przy zamykaniu okna wyboru ikonek
		**/
		void colorSelectorAboutToClose();
		
		/**
			\fn void messageBlockedSlot(int seq, UinType uin)
			Slot zostaje wywołany gdy nasza wiadomość została zablokowana
			przez serwer
			\param seq 
			\param uin
		**/
		void messageBlockedSlot(int seq, UinType uin);
		
		/**
			\fn void messageBoxFullSlot(int seq, UinType uin)
			Slot zostaje wywołany gdy skrzynka na wiadomości
			została zapełniona
			\param seq
			\param uin
		**/
		void messageBoxFullSlot(int seq, UinType uin);
		
		/**
			\fn void messageNotDeliveredSlot(int seq, UinType uin)
			Slot zostaje wywołany gdy wiadomość nie została dostarczona
			\param seq
			\param uin
		**/
		void messageNotDeliveredSlot(int seq, UinType uin);
		
		/**
			\fn void messageAcceptedSlot(int seq, UinType uin)
			Slot zostaje wywołany gdy wiadomość została poprawnie wysłana
			\param seq
			\param uin
		**/
		void messageAcceptedSlot(int seq, UinType uin);
		
	signals:
		/**
			\fn void messageSendRequested(Chat* chat)
			Sygnal jest emitowany gdy uzytkownik wyda polecenie
			wyslania wiadomosci, np klikajac na guzik "wyslij".
			\param chat wskaźnik do okna które emituje sygnał
		**/
		void messageSendRequested(Chat* chat);
		
		/**
			\fn void messageFiltering(const UinsList& uins, QCString& msg, bool& stop)
			Sygnal daje mozliwosc operowania na wiadomoci
			ktora ma byc wyslana do serwera juz w jej docelowej
			formie po konwersji z unicode i innymi zabiegami.
			Tresc wiadomosci mozna zmienic podmieniajac wskaznik
			msg na nowy bufor i zwalniajac stary (za pomoca free).
			Mozna tez przerwac dalsza jej obrobke ustawiajac
			wskaznik stop na true.
			\param uins lista użytkowników
			\param msg wiadomość 
			\param stop zakończenie dalszej obróbki sygnału
		**/
		void messageFiltering(const UinsList& uins, QCString& msg, bool& stop);
		
		/**
			\fn void messageSent(Chat* chat)
			Sygnal jest emitowany gdy zakonczy sie proces
			wysylania wiadomosci i zwiazanych z tym czynnosci.
			Oczywiscie nie wiemy czy wiadomosc dotarla.
			\param chat wskaźnik do okna rozmowy,
			 które emitowało sygnał
		**/		
		void messageSent(Chat* chat);
};

/**
	\class ColoSelectorButton
	\brief Klasa do wyboru koloru za pomocą przycisku
**/
class ColorSelectorButton : public QPushButton
{
	Q_OBJECT

	private:
		QColor color;/*!< kolor czcionki */

	private slots:
		/**
			\fn void buttonClicked()
			Slot obsługujący naciśnięcie przycisku
		**/
		void buttonClicked();

	public:
		/**
			\fn ColorSelectorButton(QWidget* parent, const QColor& qcolor, int width=1, const char *name=0)
			Konstruktor tworzący okno do wyboru koloru
		**/
		ColorSelectorButton(QWidget* parent, const QColor& qcolor, int width=1, const char *name=0);

	signals:
		/**
			\fn void clicked(const QColor& color)
			Sygnał zostaje wysłany po wybraniu koloru
		**/
		void clicked(const QColor& color);
};

/**
	\clas ColorSelector
	\brief Klasa do wyboru kolorów
**/
class ColorSelector : public QWidget
{
	Q_OBJECT

	private slots:
		/**
			\fn void iconClicked(const QColor& color);
			Slot obsługujący wybranie koloru
		**/
		void iconClicked(const QColor& color);

	protected:
		/**
			\fn void closeEvent(QCloseEvent*)
			Funkcja obsługująca zamknięcie okna wyboru kolorów
		**/
		void closeEvent(QCloseEvent*);

	public:
		/**
			\fn ColorSelector(const QColor &defColor, QWidget* parent = 0, const char* name = 0)
			Konstruktor obiektu do wyboru kolorów
		**/
		ColorSelector(const QColor &defColor, QWidget* parent = 0, const char* name = 0);

	public slots:
		/**
			\fn void alignTo(QWidget* w)
		  	Slot wyrównuje pozycję do widgeta
			\param w wkaźnik do obiektu ktorego będziemy wyrównywac
		**/
		void alignTo(QWidget* w);

	signals:
		/**
			\fn void aboutToClose()
			Sygnał jest emitowany gdy zamykany jest wybór kolorów
		**/
		void aboutToClose();
		
		/**
			\fn void colorSelect(const QColor&)
			Sygnał jest emitowany gdy wybrano kolor
			
		**/
		void colorSelect(const QColor&);
};
/**
	\class ChatSlots
	\brief Sloty do obsługi okna konfiguracji
**/
class ChatSlots :public QObject
{
	Q_OBJECT

	private:
		/**
			\fn void updatePreview()
			Odświeżenie wyglądu
		**/
		void updatePreview();
	public:
		/**
			Konstruktor obiektu
			\param parent rodzic obiektu
			\param name nazwa obiektu
		**/
		ChatSlots(QObject* parent=0, const char* name=0);

	public slots:
		/**
			\fn void onCreateConfigDialog()
			Slot jest wywoływany gdy otwierane jest okno konfiguracji
		**/
		void onCreateConfigDialog();
		
		/**
			\fn void onDestroyConfigDialog()
			Slot jest wywoływany gdy zamykane jest okno konfiguracji
		**/
		void onDestroyConfigDialog();
		
		/**
			\fn void chooseEmoticonsStyle(int index)
			Slot jest wywoływany gdy wybierany jest styl ikonek
			\param index nr stylu emotikonek
		**/
		void chooseEmoticonsStyle(int index);
		
		/**
			\fn void onPruneChat(bool toggled)
			Slot jest wywoływany gdy wybierane jest czy otwierane okno
			ma być pusty czy nie
			\param toggled 
		**/
		void onPruneChat(bool toggled);
		
		/**
			\fn void onFoldLink(bool toggled)
			\param toggled
		**/
		void onFoldLink(bool toggled);
		
		/**
			\fn void onBlockClose(bool toggled)
			Slot jest wywoływany gdy wybierany jest maksymalny czas
			blokowania zamknięcia okna po otrzymaniu wiadomości
			\param toggled
		**/
		void onBlockClose(bool toggled);
		
		/**
			\fn void chooseColor(const char* name, const QColor& color)
			Slot jest wywoływany gdy zmieniono kolor,
			aby uaktualnić podgląd 
			\param name nazwa koloru
			\param color kolor
		**/
		void chooseColor(const char* name, const QColor& color);
		
		/**
			\fn void chooseFont(const char* name, const QFont& font)
			Slot jest wywoływany gdy zmieniono czcionke,
			aby uaktualnić podgląd 
			\param name nazwa czcionki
			\param font czcionka
		**/
		void chooseFont(const char* name, const QFont& font);
		
		/**
			\fn void findAndSetWebBrowser(int selectedBrowser)
			Slot jest wywoływany gdy wybrano z listy przeglądarkę
			\param selectedBrowser nr przeglądarki
		**/
		void findAndSetWebBrowser(int selectedBrowser);
		
		/**
			\fn void findAndSetBrowserOption(int selectedOption)
			Slot jest wywoływany gdy aktywowane pole do wpisania opcji
			\param selectedOption wybrana opcja
		**/
		void findAndSetBrowserOption(int selectedOption);
		
		/**
			\fn static void initBrowserOptions(QComboBox *browserCombo, QComboBox *browserOptionsCombo, QLineEdit *browserPath)
			Slot ustawia przeglądarki wraz z opcjami
			\param browserCombo
			\param browserOptionsCombo
			\param browserPath
		**/
		static void initBrowserOptions(QComboBox *browserCombo, QComboBox *browserOptionsCombo, QLineEdit *browserPath);
		
		/**
			\fn static void findBrowser(int selectedBrowser, QComboBox *browserCombo, QComboBox *browserOptionsCombo, QLineEdit *browserPath)
			Slot jest wywoływany gdy wybrano z listy przeglądarkę
			\param selectedBrowser
			\param browserCombo
			\param browserOptionsCombo
			\param browserPath
		**/
		static void findBrowser(int selectedBrowser, QComboBox *browserCombo, QComboBox *browserOptionsCombo, QLineEdit *browserPath);
		
		/**
			\fn static void setBrowserOption(int selectedOption, QLineEdit *browserPathEdit, int chosenBrowser)
			Slot ustawia przeglądarki wraz z opcjami
			\param selectedOption
			\param browsePathEdit
			\param chosenBrowser
		**/
		static void setBrowserOption(int selectedOption, QLineEdit *browserPathEdit, int chosenBrowser);
};

#endif
