#ifndef KADU_PROTOCOL_H
#define KADU_PROTOCOL_H

#include <qobject.h>
#include <qstring.h>
#include <qdatetime.h>

#include "status.h"

class Protocol : public QObject
{
	Q_OBJECT
	protected:
		QDateTime ConnectionTime;

		QString ProtocolID;
		QString id;

		/**
			Bieżący status. Zmieniany po połączeniu, oraz w przypadku zmiany statusu kiedy połączenie
			jest już zainicjowane.

			@see login
			@see connected
			@see NextStatus
			@see UserStatus
			@see status
		**/
		UserStatus *CurrentStatus;

		/**
			Następny status. Ustalany zewnętrznie przy wykorzystaniu metody status i odpowiednich
			slotów klasy UserStatus. Zmiana wywołuje jedną z metod iWantGo... i w konsekwencji zmianę
			statusu (w razie konieczności też zalogowanie).

			@see login
			@see connected
			@see CurrentStatus
			@see UserStatus
			@see status
		**/
		UserStatus *NextStatus;

	public:
		Protocol(const QString &proto, const QString &id, QObject *parent = 0, const char *name = 0);
		virtual ~Protocol();

		/**
			Status użytkownika. Za pomocą tej metody możemy go zmienić, pobrać ikonę statusu i wykonać
			kilka innych ciekawych rzeczy.

			1. Zmiana statusu:
			<code>
				Protocol *proto;

				...

				proto->status().setOnline("Jestem zalogowany"); // zalogowanie i ustawienie opisu
				proto->status().setFriendsOnly(true);           // tryb tylko dla przyjaciół
				...
				proto->status().setOffline();                   // wylogowanie, usunięcie opisu
			</code>

			2. Sprawdzenie statusu:
			<code>
				Protocol *proto;

				if (proto->status().isOnline())                 // jesteśmy online
					...
				else if (proto->status().isInvisible())         // jesteśmy niewidzialni
					...

				// można też:
				switch (proto->status().status())
				{
					case Online:
						break;
					case Busy:
						break;
					case Invisible:
						break;
					case Offline:
						break;
				}
			</code>

			3. Pobranie ikony i nazwy statusu
			<code>
				QPixmap pix;
				QString name;
				Protocol *proto;

				...

				pix = proto->status().pixmap();
				name = proto->status().name();
			</code>

			@see currentStatus
		**/
		UserStatus &status() { return *NextStatus; }

		/**
			Rzeczywisty aktualny status. Można go wykorzystać tylko w trybie do odczytu (pobranie
			ikony, nazwy, sprawdzenie rzeczywistego stanu połączenia).

			@see status
		**/
		const UserStatus &currentStatus() const { return *CurrentStatus; }

		QString protocolID() const {	return ProtocolID;	}

		QString ID() const {	return id;	}

		virtual UserStatus *newStatus() const = 0;

		const QDateTime &connectionTime() const;

	signals:

		/**
			udało się zalogować
		**/
		void connected();

		/**
			rozpoczynamy procedurę logowania się
		**/
		void connecting();

		/**
			rozłączyliśmy się z serwerem
		**/
		void disconnected();

		/**
			wystąpił błąd połączenia
			@param protocol protokół
			@param reason napis do wyświetlenia dla użytkownika
		**/
		void connectionError(Protocol *protocol, const QString &reason);
	private:
		Protocol(const Protocol &) {}
		virtual Protocol &operator=(const Protocol &){return *this;}
};

#endif
