#ifndef MTYPES_H
#define MTYPES_H

#include <tqstring.h>
#include <tqbuffer.h>
#include <tqvaluelist.h>

#include "miscui.h"


/** Internal class : used for client identification. */
class cId
{
 public:
	cId() {}
	cId(const TQString &gameName, const TQString &gameId);

	enum State { Accepted, LibIdClash, GameNameClash, GameIdClash };
	void check(const cId &id);
	bool accepted() const { return state==Accepted; }
	TQString errorMessage(const cId &id) const;

	friend TQDataStream &operator << (TQDataStream &s, const cId &id);
	friend TQDataStream &operator >> (TQDataStream &s, cId &id);

 private:
	TQString libId, gameName, gameId;
	State   state;
};
TQDataStream &operator << (TQDataStream &s, const cId &id);
TQDataStream &operator >> (TQDataStream &s, cId &id);

/** Flags used for the netmeeting. */
enum MeetingMsgFlag
    { IdFlag = 0, EndFlag, NewFlag, DelFlag, Mod_TextFlag, Mod_TypeFlag, Mod_OptFlag, PlayFlag };
TQDataStream &operator << (TQDataStream &s, const MeetingMsgFlag &f);
TQDataStream &operator >> (TQDataStream &s, MeetingMsgFlag &f);

/** Internal class : used in netmeeting to transport text line. */
class TextInfo
{
 public:
	TextInfo() {}

	uint i;
	TQString text;
};
TQDataStream &operator << (TQDataStream &s, const TextInfo &ti);
TQDataStream &operator >> (TQDataStream &s, TextInfo &ti);

/** Internal class : used in netmeeting to transport readiness status. */
typedef struct {
	uint i;
	MeetingCheckBox::Type type;
} TypeInfo;
TQDataStream &operator << (TQDataStream &s, const MeetingCheckBox::Type &t);
TQDataStream &operator >> (TQDataStream &s, MeetingCheckBox::Type &t);
TQDataStream &operator << (TQDataStream &s, const TypeInfo &ti);
TQDataStream &operator >> (TQDataStream &s, TypeInfo &ti);

/* Internal class : store game data. */
class BoardData
{
 public:
	BoardData() {}

	TQString              name;
	PlayerComboBox::Type type;
};
TQDataStream &operator <<(TQDataStream &, const BoardData &);
TQDataStream &operator >>(TQDataStream &, BoardData &);

/* Internal class : store extended game data (used in netmeeting). */
class ExtData
{
 public:
	ExtData() {}
	ExtData(const TQValueList<BoardData> &_bds, const TQString &_text,
			MeetingCheckBox::Type _type)
	: bds(_bds), text(_text), type(_type) {}

	TQValueList<BoardData> bds;
	TQString               text;
	MeetingCheckBox::Type type;
};
TQDataStream &operator << (TQDataStream &s, const ExtData &ed);
TQDataStream &operator >> (TQDataStream &s, ExtData &ed);

/* Internal class : store meeting line data (in netmeeting). */
class MeetingLineData
{
 public:
	MeetingLineData() {}

	ExtData ed;
	bool own;
};
TQDataStream &operator << (TQDataStream &s, const MeetingLineData &pld);
TQDataStream &operator >> (TQDataStream &s, MeetingLineData &pld);

/* Internal class : store remote host data. */
class Socket;

class RemoteHostData
{
 public:
	RemoteHostData() : socket(0) {}

	Socket                *socket;
	TQValueList<BoardData>  bds;
};

/* Internal class : store connection data (used by config. wizard). */
class ConnectionData
{
 public:
	ConnectionData() {}

	bool           network, server;
	RemoteHostData rhd;
};

/** Flags used for network communication. */
enum MetaFlag { MF_Ask = 0, MF_Data };
TQDataStream &operator << (TQDataStream &s, const MetaFlag &f);
TQDataStream &operator >> (TQDataStream &s, MetaFlag &f);

/** Internal class : encapsulate read/write TQBuffer. */
class Stream : public TQDataStream
{
 public:
	Stream(int mode);

	void clear();
	void setArray(TQByteArray a);

	TQByteArray buffer() /*const*/ { return buf.buffer(); }
	uint size() /*const*/ { return buf.buffer().size(); }

 protected:
	TQBuffer buf;

 private:
	int mode;
};

/** Internal class : encapsulate write TQBuffer. */
class WritingStream : public Stream
{
 public:
	WritingStream() : Stream(IO_WriteOnly) {}
};

/** Internal class : encapsulate read TQBuffer. */
class ReadingStream : public Stream
{
 public:
	ReadingStream() : Stream(IO_ReadOnly) {}

	bool readOk();
	void clearRead();
};

/** Internal class : include a @ref ReadingStream and a @ref WritingStream. */
class IOBuffer
{
 public:
	IOBuffer() {}

	void writingToReading();

	ReadingStream reading;
	WritingStream writing;
};

/** Internal class : array of @ref IOBuffer. */
class BufferArray
{
 public:
	BufferArray() {}
	BufferArray(uint nb) { resize(nb); }
	~BufferArray();

	void resize(uint nb);

	uint size() const { return a.size(); }
	IOBuffer *operator [](uint i) const { return a[i]; }

 private:
	TQMemArray<IOBuffer *> a;

	void clear(uint nb);
};
TQDataStream &operator <<(TQDataStream &s, const BufferArray &b);
TQDataStream &operator >>(TQDataStream &s, BufferArray &b);

#endif // MTYPES_H