/*
 * psievent.h - events
 * Copyright (C) 2001, 2002  Justin Karneges
 *
 * 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 option) 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 library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 */

#ifndef PSIEVENT_H
#define PSIEVENT_H

#include <qdatetime.h>
#include <qobject.h>
#include <qptrlist.h>
#include <qdom.h>
#include <qguardedptr.h>

#include"im.h"

namespace XMPP
{
	class FileTransfer;
};

using namespace XMPP;

class PsiCon;
class PsiAccount;


class PsiEvent : public QObject
{
	Q_OBJECT
public:
	PsiEvent(PsiAccount *);
	PsiEvent(const PsiEvent &);
	virtual ~PsiEvent() = 0;

	enum {
		Message,
		Auth,
		PGP,
		File
	};
	virtual int type() const = 0;

	virtual Jid from() const = 0;
	virtual void setFrom(const Jid &j) = 0;

	Jid jid() const;
	void setJid(const Jid &);

	bool originLocal() const;
	bool late() const;
	QDateTime timeStamp() const;

	void setOriginLocal(bool b);
	void setLate(bool b);
	void setTimeStamp(const QDateTime &t);

	PsiAccount *account() const;

	virtual QDomElement toXml(QDomDocument *) const;
	virtual bool fromXml(PsiCon *, PsiAccount *, const QDomElement *);

	virtual int priority() const;

	virtual PsiEvent *copy() const;

private:
	bool v_originLocal, v_late;
	QDateTime v_ts;
	Jid v_jid;
	PsiAccount *v_account;
};

// normal, chat, error, headline, etc
class MessageEvent : public PsiEvent
{
	Q_OBJECT
public:
	MessageEvent(PsiAccount *acc);
	MessageEvent(const MessageEvent &from);
	MessageEvent(const XMPP::Message &, PsiAccount *acc);
	~MessageEvent();

	int type() const;
	Jid from() const;
	void setFrom(const Jid &j);

	bool sentToChatWindow() const;
	const XMPP::Message & message() const;

	void setSentToChatWindow(bool b);
	void setMessage(const XMPP::Message &m);

	QDomElement toXml(QDomDocument *) const;
	bool fromXml(PsiCon *, PsiAccount *, const QDomElement *);

	virtual int priority() const;

	virtual PsiEvent *copy() const;

private:
	XMPP::Message v_m;
	bool v_sentToChatWindow;
};

// subscribe, subscribed, unsubscribe, unsubscribed
class AuthEvent : public PsiEvent
{
	Q_OBJECT
public:
	AuthEvent(const Jid &j, const QString &authType, PsiAccount *acc);
	AuthEvent(const AuthEvent &from);
	~AuthEvent();

	int type() const;
	Jid from() const;
	void setFrom(const Jid &j);

	QString authType() const;

	QDomElement toXml(QDomDocument *) const;
	bool fromXml(PsiCon *, PsiAccount *, const QDomElement *);

	virtual int priority() const;

	virtual PsiEvent *copy() const;

private:
	Jid v_from;
	QString v_at;
};

// request pgp passphrase
class PGPEvent : public PsiEvent
{
	Q_OBJECT
public:
	PGPEvent(PsiAccount *acc) : PsiEvent(acc) {}
	PGPEvent(const PGPEvent &from)
	: PsiEvent(from) {}
	~PGPEvent() {}
	int type() const { return PGP; }
	Jid from() const { return QString(); }
	void setFrom(const Jid &) {}
};

// incoming file transfer
class FileEvent : public PsiEvent
{
	Q_OBJECT
public:
	FileEvent(const Jid &j, FileTransfer *ft, PsiAccount *acc);
	~FileEvent();

	int type() const { return File; }
	Jid from() const;
	void setFrom(const Jid &);
	FileTransfer *takeFileTransfer();

	virtual int priority() const;

private:
	Jid v_from;
	QGuardedPtr<FileTransfer> ft;
};

// event queue
class EventQueue : public QObject
{
	Q_OBJECT
public:
	EventQueue(PsiAccount *);
	EventQueue(const EventQueue &);
	~EventQueue();

	EventQueue &operator= (const EventQueue &);

	int nextId() const;
	int count() const;
	int count(const Jid &, bool compareRes=true) const;
	void enqueue(PsiEvent *);
	void dequeue(PsiEvent *);
	PsiEvent *dequeue(const Jid &, bool compareRes=true);
	PsiEvent *peek(const Jid &, bool compareRes=true) const;
	PsiEvent *dequeueNext();
	PsiEvent *peekNext() const;
	bool hasChats(const Jid &, bool compareRes=true) const;
	PsiEvent *peekFirstChat(const Jid &, bool compareRes=true) const;
	void extractChats(QPtrList<PsiEvent> *list, const Jid &, bool compareRes=true);
	void printContent() const;
	void clear();
	void clear(const Jid &, bool compareRes=true);

	QDomElement toXml(QDomDocument *) const; // these work with pointers, to save inclusion of qdom.h, which is pretty large
	bool fromXml(const QDomElement *);

	bool toFile(const QString &fname);
	bool fromFile(const QString &fname);

signals:
	void handleEvent(PsiEvent *);
	void queueChanged();

private:
	class Private;
	Private *d;
};



#endif
