/*
 * This file is a part of VyQChat.
 *
 * Copyright (C) 2002-2004 Pawel Stolowski <yogin@linux.bydg.org>
 *
 * VyQChat is free software; you can redestribute it and/or modify it
 * under terms of GNU General Public License by Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY. See GPL for more details.
 */

#ifndef __VCPROTOCOL_H
#define __VCPROTOCOL_H

#include <qobject.h>
#include <qhostaddress.h>
#include <qtextcodec.h>
#include <qmap.h>
#include <qmemarray.h>
#include "uuid.h"

#define MAIN_CHANNEL "#Main"
#define VY_MAXPACKETSIZE 1400
#define VY_PORT 8167

//
// protocol version, introduced in VypressChat 1.9
#define VY_PROTOMAJOR 1
#define VY_PROTOMINOR 91

const char STATUS_NORMAL = '0';
const char STATUS_DND = '1';
const char STATUS_AWAY = '2';
const char STATUS_OFFLINE = '3';
const char STATUS_UNKNOWN = 'z'; //for internal purposes

const char RA_ACTIVE = '0';
const char RA_NOTACTIVE = '1';

const char WIN_NOTACTIVE = '0';
const char WIN_ACTIVE = '1';

const char GENDER_MALE = '0';
const char GENDER_FEMALE = '1';

class QSocketNotifier;
class PacketData;

class VCProtocol: public QObject
{
	Q_OBJECT
		
	private:
		int /*sendsd,*/ recvsd; //sockets
		unsigned int port;
		bool usemulticast;
		bool useutf;
		QHostAddress broadcast;
		QTextCodec *ansicodec, *utfcodec, *sndcodec;
		UUID uuid;
		QSocketNotifier *rnotifier;
		QSocketNotifier *wnotifier;
		QMap<Q_INT32, bool> usercodec;

		QTextCodec* setUserCodecUTF(const QHostAddress &addr, bool f);
		QTextCodec* setUserCodecUTF(const QHostAddress &addr, char f);
		QTextCodec *codecForUser(const QHostAddress &addr);
		void send(const QHostAddress &addr, PacketData *packet);
		bool decode(char *p_data, int p_len, const QHostAddress &source);

		bool get(QCString *str, char *buffer, int &pos, const int p_len);
		bool get(QString *str, char *buffer, int &pos, const int p_len, QTextCodec *tc);
		bool get(char *c, char *buffer, int &pos, const int p_len);
		bool get(UUID *uuid, char *buffer, int &pos, const int p_len);
		bool get(Q_INT16 *s, char *buffer, int &pos, const int p_len);
		bool get(Q_INT32 *s, char *buffer, int &pos, const int p_len);
		
	private slots:
		void dataReceived();

	signals:
		void sig_vc_say(const QString &channel, const QString &from, const QString &text);
		void sig_vc_me(const QString &channel, const QString &from, const QString &text);
		void sig_vc_whohere(const QHostAddress &source, const QString &updater);
		void sig_vc_imhere(const QHostAddress &source, const QString &updater, const QString &responder, char status, char winstate);
		void sig_vc_imhere(const QHostAddress &source, const QString &updater, const QString &responder, char status, char winstate, char gender, Q_INT16 color);
		void sig_vc_beep(const QHostAddress &source, const QString &to, const QString &from);
		void sig_vc_beepack(const QString &to, const QString &from, char gender);
		void sig_vc_join(const QHostAddress &source, const QString&, const QString&, char, char);
		void sig_vc_leave(const QString &who, const QString &channel, char gender);
		void sig_vc_private_join(const QString &from, const QString &to, char gender);
		void sig_vc_private_leave(const QString &from, const QString &to, char gender);
		void sig_vc_private_say(const QString &from, const QString &to, const QString &text);
		void sig_vc_private_me(const QString &from, const QString &to, const QString &text);
		void sig_vc_message(const QHostAddress &source, const QCString &sig, const QString &from, const QString &to, const QString &text);
		void sig_vc_massmessage(const QHostAddress &source, const QCString &sig, const QString &from, const QString &to, const QString &text);
		void sig_vc_messageack(char status, const QString &from, const QString &to, char gender, const QString &answer);
		void sig_vc_messageack(const QCString &sig, char status, const QString &from, const QString &to, char gender, const QString &answer);
		void sig_vc_herereq(const QHostAddress &source, const QString &from, const QString &channel);
		void sig_vc_hereack(const QString &to, const QString &channel, const QString &from, char ra);
		void sig_vc_inforeq(const QString &to, const QString &from);
		void sig_vc_inforeqack(const QHostAddress &source, const QString &to, const QString &from, const QString &comp, const QString &name, const QString &ip, const QString &channels, const QString &answer, const QString &computer, const QString &software, bool utf);
		void sig_vc_nickchange(const QString &from, const QString &to, char gender);
		void sig_vc_changestatus(const QString &who, char status, char gender, const QString &answer);
		void sig_vc_currenttopic(const QString &to, const QString &channel, const QString &topic);
		void sig_vc_newtopic(const QString &channel, const QString &topic);
		void sig_vc_ping(const QHostAddress &source, const QString &to, const QString &from, const QString &time);
		void sig_vc_pong(const QString &to, const QString &from, const QString &time);
		void sig_vc_floodnotify(const QString &to, const QString &from, const QString &seconds);

	public:
		VCProtocol(QTextCodec *c, const UUID &uuid, bool useutf);
		~VCProtocol();
		void setAnsiCodec(QTextCodec *c);
		void setUseUTF(bool f);
		bool setupBroadcastSockets(const QHostAddress &ip, const QHostAddress &broadcast, unsigned int port=8167);
		bool setupMulticastSockets(const QHostAddress &ip, const QHostAddress &multicastgroup, unsigned char ttl=7, unsigned int port=8167);
		void closeSockets();
		
	public slots:
		void vc_say(const QString &channel, const QString &nick, const QString &text);
		void vc_me(const QString &channel, const QString &nick, const QString &text);
		void vc_whohere(const QString &updater);
		void vc_imhere(const QHostAddress &addr, const QString &updater, const QString &responder, char status, char gender, char winstate);
		void vc_beep(const QHostAddress &addr, const QString& to, const QString& from);
		void vc_beepack(const QHostAddress &addr, const QString& to, const QString& from, char gender);
		void vc_changeactivity(const QString &who, char winstate);
		void vc_join(const QString&, const QString&, char, char);
		void vc_leave(const QString &who, const QString &channel, char gender);
		void vc_private_join(const QHostAddress &addr, const QString &from, const QString &to, char gender);
		void vc_private_leave(const QHostAddress &addr, const QString &from, const QString &to, char gender);
		void vc_private_say(const QHostAddress &addr, const QString &from, const QString &to, const QString &text);
		void vc_private_me(const QHostAddress &addr, const QString &from, const QString &to, const QString &text);
		void vc_message(const QHostAddress &addr, const QString &from, const QString &to, const QString &text);
		void vc_massmessage(const QHostAddress &addr, const QString &from, const QString &to, const QString &text);
		void vc_messageack(const QHostAddress &addr, const QByteArray &sig, char status, const QString &from, const QString &to, char gender, const QString &answer);
		void vc_herereq(const QString &from, const QString &channel);
		void vc_hereack(const QHostAddress &addr, const QString &to, const QString &channel, const QString &from, char ra);
		void vc_inforeq(const QHostAddress &addr, const QString &to, const QString &from);
		void vc_inforeqack(const QHostAddress &addr, const QString &to, const QString &from, const QString &comp, const QString &name, const QString &ip, const QString &channels, const QString &answer);
		void vc_nickchange(const QString &from, const QString &to, char gender);
		void vc_changestatus(const QString &who, char status, char gender, const QString &answer);
		void vc_currenttopic(const QHostAddress &addr, const QString &to, const QString &channel, const QString &topic);
		void vc_newtopic(const QString &channel, const QString &topic, const QString &who);
		void vc_ping(const QHostAddress &addr, const QString &to, const QString &from, const QString &time);
		void vc_pong(const QHostAddress &addr, const QString &to, const QString &from, const QString &time);
		void vc_floodnotify(const QHostAddress &addr, const QString &to, const QString &from, int seconds);
};

#endif



syntax highlighted by Code2HTML, v. 0.9.1