#ifndef STATUS_CHANGER
#define STATUS_CHANGER

#include <qobject.h>

#include "status.h"

class QTimer;

/**
	@class StatusChanger
	@brief Podstawowa klasa służąca do zmiany statusu użytkownika.

	Implementacje klasy dokonują zmiany statusu użytkowników na podstawie dowolnych, zależnych od
	klasy parametrów. Zmianie może ulegać zarówno opis jak i stan dostępności.
 **/
class StatusChanger : public QObject
{
	Q_OBJECT

	int Priority;

public:
	/**
		Podstawowy kontruktor. Tworzy modyfikator statusu z zadanym priorytetem.
		Modyfikatory aplikowane są w kolejności rosnących priorytetów.

		@arg priority priorytet modyfikatora
	 **/
	StatusChanger(int priority);
	virtual ~StatusChanger();

	int priority();

	/**
		Metoda zmieniająca status.

		@arg status aktualny status użytkownika, metoda może zmienić wartość argumentu
	 **/
	virtual void changeStatus(UserStatus &status) = 0;

signals:
	void statusChanged();

};

/**
	@class UserStatusChanger
	@brief Klasa umożliwiająca użytkownikowi ustawienie własnego statusu.

	Klasa posiada pole userStatus określające status, jaki użytkownik sam sobie ustawił.
	Klasa modyfikuje aktualny status użytkownika ustawiając go na wartość pola userStatus.
	Priorytet modyfikatora: 0.
 **/
class UserStatusChanger : public StatusChanger
{
	Q_OBJECT

	UserStatus userStatus;

public:
	UserStatusChanger();
	virtual ~UserStatusChanger();

	virtual void changeStatus(UserStatus &status);
	const UserStatus & status() { return userStatus; }

public slots:
	/**
		Zapisuje status, jaki użytkownik sobie ustawił.

		@param status status użytkownika
	 **/
	void userStatusSet(UserStatus &status);

};

/**
	@class SplitStatusChanger
	@brief Klasa dzieląca długie opisy na krótsze.

	Klasa dzieli długi opis na kilka krótszych, które wyświetlane są w odstępie 30 sekund od siebie.
	Dla przykładu, opis "ten opis ma więcej niż dwadzieścia znaków" przy maksymalnej długości opisu
	wynoszącej dwadzieścia znaków zostanie podzielony na następujące pod-opisy:

		"ten opis ma wię --->"
		"<--- cej niż dw --->"
		"<--- adzieścia  --->"
		"<--- znaków"

	W Gadu-Gadu limit długości wynosi 70 znaków.

	Priorytet: 1000.
 **/
class SplitStatusChanger : public StatusChanger
{
	Q_OBJECT

	unsigned int splitSize;

	unsigned int descriptionSplitBegin;
	unsigned int descriptionSplitLength;

	QTimer *splitTimer;
	QString lastDescription;

	bool enabled;

private slots:
	void timerInvoked();

public:
	/**
		Tworzy nowy obiekt dzielący opisy na pod-opisy o maksymalnej długości splitSize znaków.

		@arg splitSize maksymalna długość pod-opisu
	 **/
	SplitStatusChanger(unsigned int splitSize);
	virtual ~SplitStatusChanger();

	virtual void changeStatus(UserStatus &status);

	void enable();
	void disable();

};

/**
	@class StatusChangerManager
	@brief Manager modyfikatorów statusu.

	Klasa zarządza modyfikatorami statusu. Dołącza i odłącza na żądanie nowy modyfikatory.
	Wywołuje poszczególne modyfikatory w kolejności ich rosnących priorytetów.

	Po stworzeniu i dodaniu pierwszych modyfikatorów wymaga uruchomienia za pomocą metody enable.
 **/
class StatusChangerManager : public QObject
{
	Q_OBJECT

	QValueList<StatusChanger *> statusChangers;
	bool enabled;

public:
	static void initModule();
	static void closeModule();

	StatusChangerManager();
	virtual ~StatusChangerManager();

	/**
		Aktywuje modyfikatory.
	 **/
	void enable();

	void registerStatusChanger(StatusChanger *statusChanger);
	void unregisterStatusChanger(StatusChanger *statusChanger);

public slots:
	/**
		Slot wywoływany, gdy jeden z modyfikatorów dokona zmiany opisu.
		Wywołanie powoduje ponowne przetworzenie statusu przez wszystkie modyfikatory
		i wysłanie sygnału statusChanged(UserStatus).
	 **/
	void statusChanged();

signals:
	/**
		Sygnał wysyłany, gdy zostanie ustalony ostateczny status użytkownika.
	 **/
	void statusChanged(UserStatus);

};

extern StatusChangerManager *status_changer_manager;

#endif // STATUS_CHANGER
