/***************************************************************************
                          dcobject.h  -  description
                             -------------------
    begin                : Fri Feb 22 2002
    copyright            : (C) 2002-2004 by Mathias Küster
    email                : mathen@users.berlios.de
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   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.                                   *
 *                                                                         *
 ***************************************************************************/

#ifndef _DCOBJECT_H_
#define _DCOBJECT_H_

/**
  *@author Mathias Küster
  *
  * These are various dclib objects, usually there is one object
  * for each NMDC protocol command, but some objects may be for
  * more than one command e.g. $Get / $GetZBlock / $UGetBlock
  * all use CMessageGet.
  *
  * There are also dclib objects, usually sent to valknut
  * with information about a file or transfer.
  *
  * An alternative system is to have one object to handle all
  * protocol commands, with an enum for which command and then
  * a map of parameters and their values. Mainly for ADC,
  * where all commands have a common format.
  */

#include <time.h>

#include <dclib/dcos.h>
#include <dclib/core/types.h>
#include <dclib/core/cstring.h>
#include <dclib/core/clist.h>
#include <dclib/core/types.h>

#include <list>

#define DC_USER_FILELIST_HE3 	"MyList.DcLst"
#define DC_USER_FILELIST 	DC_USER_FILELIST_HE3
#define DC_USER_FILELIST_BZ 	"MyList.bz2"
#define DC_USER_FILELIST_XMLBZ	"files.xml.bz2"
#define DC_USER_FILELIST_XML	"files.xml"
#define DC_USER_INDEXLIST	"index.lst"

enum eDCMessage {
	DC_MESSAGE_PARSE_ERROR=0,

	DC_MESSAGE_CONNECTION_STATE,	// internal con. state
	DC_MESSAGE_TRANSFER,		// transfer state

	DC_MESSAGE_UNKNOWN,

	// direct connect proto
	DC_MESSAGE_LOCK,
	DC_MESSAGE_HELLO,
	DC_MESSAGE_HUBNAME,
	DC_MESSAGE_CHAT,
	DC_MESSAGE_MYINFO,
	DC_MESSAGE_QUIT,
	DC_MESSAGE_NICKLIST,		// 10
	DC_MESSAGE_OPLIST,
	DC_MESSAGE_CONNECTTOME,
	DC_MESSAGE_KEY,
	DC_MESSAGE_PRIVATECHAT,
	DC_MESSAGE_REVCONNECTTOME,
	DC_MESSAGE_SEARCHRESULT,
	DC_MESSAGE_FORCEMOVE,
	DC_MESSAGE_MYNICK,		// connect to me
	DC_MESSAGE_DIRECTION,		// 20 connect to me
	DC_MESSAGE_MAXEDOUT,
	DC_MESSAGE_FILELENGTH,
	DC_MESSAGE_ERROR,		// file not found ...
	DC_MESSAGE_GET,
	DC_MESSAGE_GETLISTLEN,
	DC_MESSAGE_VALIDATEDENIDE,
	DC_MESSAGE_GETINFO,
	DC_MESSAGE_AGE,
	DC_MESSAGE_HUBISFULL,
	DC_MESSAGE_LISTLEN,		// 30
	DC_MESSAGE_SEND,
	DC_MESSAGE_PING,
	DC_MESSAGE_GETPASS,		// user need a password
	DC_MESSAGE_BADPASS,		// wrong password
	DC_MESSAGE_LOGEDIN,		// admin
	DC_MESSAGE_CANCEL,		// cancel a transfer
	DC_MESSAGE_CANCELED,		// the transfer is canceled
	DC_MESSAGE_SUPPORTS,

	// download manager types
	DC_MESSAGE_FILE_OBJECT,		// 40
	DC_MESSAGE_TRANSFER_OBJECT,
	DC_MESSAGE_FILELIST_OBJECT,
	DC_MESSAGE_SLOT_OBJECT,
	DC_MESSAGE_LOG,
	DC_MESSAGE_DM_INFO,

	// search manager types
	DC_MESSAGE_SEARCH_FILE,
	DC_MESSAGE_SEARCH_USER,
	DC_MESSAGE_SEARCHRESULT_USER,

	// file manager
	DC_MESSAGE_FM_INFO,

	// traffic control
	DC_MESSAGE_TRAFFIC,
	// file transferrate
	DC_MESSAGE_FILE_TRANSFER_RATE,
	DC_MESSAGE_GETHUBLIST,
	DC_MESSAGE_CONNECT_CLIENT,

	// verlihub extension
	DC_MESSAGE_HUB_TOPIC,

	// nmdc
	DC_MESSAGE_GET_NET_INFO,
	// user command
	DC_MESSAGE_USER_COMMAND,
	// ZLIB compression
	DC_MESSAGE_GETZBLOCK,
	DC_MESSAGE_SENDING,
	//DC_MESSAGE_FAILED
	// ADCGET
	DC_MESSAGE_ADCGET,
	DC_MESSAGE_ADCSND,
	// UserIP2 message
	DC_MESSAGE_USERIP
};

/*
 * The initialization phase of the constructor has to be used
 * because m_eType is const, and it really does not make
 * any sense for m_eType NOT to be const. Alternatively
 * a virtual type() function could return a hard coded value.
 */
class CDCMessage {
public:
	/** */
	CDCMessage() : m_eType( DC_MESSAGE_UNKNOWN ) {};
	/** */
	virtual ~CDCMessage() {};

	/** */
	const eDCMessage m_eType;

protected:
	/** */
	CDCMessage( eDCMessage type ) : m_eType ( type ) {};
};

class CMessagePing : public CDCMessage {
public:
	/** */
	CMessagePing() : CDCMessage(DC_MESSAGE_PING) {};
	/** */
	virtual ~CMessagePing() {};
};

class CMessageHubTopic : public CDCMessage {
public:
	/** */
	CMessageHubTopic() : CDCMessage(DC_MESSAGE_HUB_TOPIC) {};
	/** */
	virtual ~CMessageHubTopic() {};

	/** */
	CMessageHubTopic & operator = (const CMessageHubTopic & p)
	{
		m_sTopic = p.m_sTopic;
		return *this;
	};

	/** */
	CString m_sTopic;
};

class CMessageGetInfo : public CDCMessage {
public:
	/** */
	CMessageGetInfo() : CDCMessage(DC_MESSAGE_GETINFO) {};
	/** */
	virtual ~CMessageGetInfo() {};

	/** */
	CMessageGetInfo & operator = (const CMessageGetInfo & p)
	{
		m_sSrcNick = p.m_sSrcNick;
		m_sDstNick = p.m_sDstNick;

		return *this;
	};

	/** */
	CString m_sSrcNick;
	/** */
	CString m_sDstNick;
};

class CMessageGetNetInfo : public CDCMessage {
public:
	/** */
	CMessageGetNetInfo() : CDCMessage(DC_MESSAGE_GET_NET_INFO) {};
	/** */
	virtual ~CMessageGetNetInfo() {};
};

class CMessageConnectionState : public CDCMessage {
public:
	/** */
	CMessageConnectionState() : CDCMessage(DC_MESSAGE_CONNECTION_STATE) {
		m_eState = estNONE;
	};
	/** */
	virtual ~CMessageConnectionState() {};

	/** */
	CMessageConnectionState & operator = (const CMessageConnectionState & p)
	{
		m_eState   = p.m_eState;
		m_sMessage = p.m_sMessage;

		return *this;
	};

	/** */
	eConnectionState m_eState;
	/** */
	CString m_sMessage;
};

class CMessageTransfer : public CDCMessage {
public:
	/** */
	CMessageTransfer() : CDCMessage(DC_MESSAGE_TRANSFER) {
		m_eDirection  = edNONE;
		m_nTransfered = 0;
		m_nLength     = 0;
	};
	/** */
	virtual ~CMessageTransfer() {};

	/** */
	CMessageTransfer & operator = (const CMessageTransfer & p)
	{
		m_eDirection  = p.m_eDirection;
		m_nTransfered = p.m_nTransfered;
		m_nLength     = p.m_nLength;

		return *this;
	};

	/** */
	eDirection m_eDirection;
	/** */
	ulonglong m_nTransfered;
	/** */
	ulonglong m_nLength;
};

class CMessageFileTransferRate : public CDCMessage {
public:
	/** */
	CMessageFileTransferRate() : CDCMessage(DC_MESSAGE_FILE_TRANSFER_RATE) {
		m_nRate      = 0;
	};
	/** */
	virtual ~CMessageFileTransferRate() {};

	/** */
	CMessageFileTransferRate & operator = (const CMessageFileTransferRate & p)
	{
		m_sLocalFile = p.m_sLocalFile;
		m_nRate      = p.m_nRate;

		return *this;
	};

	/** */
	CString m_sLocalFile;
	/** */
	ulonglong m_nRate;
};

class CMessageSupports : public CDCMessage {
public:
	/** */
	CMessageSupports();
	/** */
	virtual ~CMessageSupports();

	/** */
	CMessageSupports & operator = (const CMessageSupports & p);

	/** */
	CString m_sContent;
	/** */
	bool m_bBZList;
	/** */
	bool m_bSSL;
	/** */
	bool m_bChunk;
	/** */
	bool m_bMiniSlots;
	/** */
	bool m_bXMLBZList;
	/** */
	bool m_bZBlock;
	/** */
	bool m_bADCGet;
	/** */
	bool m_bTTHL;
	/** */
	bool m_bTTHF;
	/** */
	bool m_bZLIG;
};

class CMessageError : public CDCMessage {
public:
	/** */
	CMessageError() : CDCMessage(DC_MESSAGE_ERROR) {};
	/** */
	virtual ~CMessageError() {};

	/** */
	CMessageError & operator = (const CMessageError & p)
	{
		m_sError = p.m_sError;

		return *this;
	};

	/** */
	CString m_sError;
};

class CMessageGet : public CDCMessage {
public:
	/** */
	CMessageGet() : CDCMessage(DC_MESSAGE_GET) {
		m_nPos  = 0;
		m_nSize = 0;
		m_bUGet = false;
		m_bZLib = false;
	};
	/** */
	virtual ~CMessageGet() {};

	/** */
	CMessageGet & operator = (const CMessageGet & p)
	{
		m_sFilename = p.m_sFilename;
		m_nPos      = p.m_nPos;
		m_nSize     = p.m_nSize;
		m_bUGet     = p.m_bUGet;
		m_bZLib	    = p.m_bZLib;

		return *this;
	};

	/** */
	CString m_sFilename;
	/** */
	ulonglong m_nPos;
	/** */
	ulonglong m_nSize;
	/** True if remote did $UGetBlock, false if $Get was used */
	bool m_bUGet;
	/** True if remote did $GetZBlock / $UGetZBlock */
	bool m_bZLib;
};

class CMessageADCGet : public CDCMessage {
public:
	/** */
	CMessageADCGet() : CDCMessage(DC_MESSAGE_ADCGET) {
		m_eADCType = eAdcFile;
		m_nPos  = 0;
		m_nSize = -1;
		m_bZlib = false;
	};
	/** */
	virtual ~CMessageADCGet() {};
	
	/** */
	CMessageADCGet & operator = (const CMessageADCGet & p)
	{
		m_eADCType = p.m_eADCType;
		m_sTTH  = p.m_sTTH;
		m_nPos  = p.m_nPos;
		m_nSize = p.m_nSize;
		m_bZlib = p.m_bZlib;
		m_sFile = p.m_sFile;
		
		return *this;
	};
	
	/** file, tthl, or list */
	eADCType m_eADCType;
	/** TTH without prefix or empty if using file */
	CString m_sTTH;
	/** */
	ulonglong m_nPos;
	/** */
	long long m_nSize;
	/** */
	bool m_bZlib;
	/** File if not using TTH, empty otherwise */
	CString m_sFile;
};

class CMessageADCSnd : public CDCMessage {
public:
	/** */
	CMessageADCSnd() : CDCMessage(DC_MESSAGE_ADCSND) {
		m_eADCType = eAdcFile;
		m_nPos  = 0;
		m_nSize = -1;
		m_bZlib = false;
	};
	/** */
	virtual ~CMessageADCSnd() {};
	
	/** */
	CMessageADCSnd & operator = (const CMessageADCSnd & p)
	{
		m_eADCType = p.m_eADCType;
		m_sTTH  = p.m_sTTH;
		m_nPos  = p.m_nPos;
		m_nSize = p.m_nSize;
		m_bZlib = p.m_bZlib;
		m_sFile = p.m_sFile;
		
		return *this;
	};
	
	/** file, tthl, or list */
	eADCType m_eADCType;
	/** TTH without prefix or empty if using file*/
	CString m_sTTH;
	/** */
	ulonglong m_nPos;
	/** */
	long long m_nSize;
	/** */
	bool m_bZlib;
	/** File if not using TTH, empty otherwise */
	CString m_sFile;
};

class CMessageGetPass : public CDCMessage {
public:
	/** */
	CMessageGetPass() : CDCMessage(DC_MESSAGE_GETPASS) {};
	/** */
	virtual ~CMessageGetPass() {};
};

class CMessageCancel : public CDCMessage {
public:
	/** */
	CMessageCancel() : CDCMessage(DC_MESSAGE_CANCEL) {};
	/** */
	virtual ~CMessageCancel() {};
};

class CMessageCanceled : public CDCMessage {
public:
	/** */
	CMessageCanceled() : CDCMessage(DC_MESSAGE_CANCELED) {};
	/** */
	virtual ~CMessageCanceled() {};
};

class CMessageKey : public CDCMessage {
public:
	/** */
	CMessageKey() : CDCMessage(DC_MESSAGE_KEY) {};
	/** */
	virtual ~CMessageKey() {};
};

class CMessageBadPass : public CDCMessage {
public:
	/** */
	CMessageBadPass() : CDCMessage(DC_MESSAGE_BADPASS) {};
	/** */
	virtual ~CMessageBadPass() {};
};

class CMessageLogedIn : public CDCMessage {
public:
	/** */
	CMessageLogedIn() : CDCMessage(DC_MESSAGE_LOGEDIN) {};
	/** */
	virtual ~CMessageLogedIn() {};

	/** */
	CMessageLogedIn & operator = (const CMessageLogedIn & p)
	{
		m_sNick = p.m_sNick;

		return *this;
	};

	/** */
	CString m_sNick;
};

class CMessageSend : public CDCMessage {
public:
	/** */
	CMessageSend() : CDCMessage(DC_MESSAGE_SEND) {};
	/** */
	virtual ~CMessageSend() {};
};

class CMessageValidateDenide : public CDCMessage {
public:
	/** */
	CMessageValidateDenide() : CDCMessage(DC_MESSAGE_VALIDATEDENIDE) {};
	/** */
	virtual ~CMessageValidateDenide() {};
};

class CMessageHubIsFull : public CDCMessage {
public:
	/** */
	CMessageHubIsFull() : CDCMessage(DC_MESSAGE_HUBISFULL) {};
	/** */
	virtual ~CMessageHubIsFull() {};
};

class CMessageMaxedOut : public CDCMessage {
public:
	/** */
	CMessageMaxedOut() : CDCMessage(DC_MESSAGE_MAXEDOUT) {};
	/** */
	virtual ~CMessageMaxedOut() {};
};

class CMessageGetListLen : public CDCMessage {
public:
	/** */
	CMessageGetListLen() : CDCMessage(DC_MESSAGE_GETLISTLEN) {};
	/** */
	virtual ~CMessageGetListLen() {};
};

class CMessageLock : public CDCMessage {
public:
	/** */
	CMessageLock() : CDCMessage(DC_MESSAGE_LOCK) {
		m_eClientVersion = eucvNONE;
		m_bExtProtocol   = false;
		m_nVersionMajor  = 0;
		m_nVersionMinor  = 0;
		m_nVersionPatch  = 0;
	};
	/** */
	virtual ~CMessageLock() {};

	/** */
	CMessageLock & operator = (const CMessageLock & p)
	{
		m_sPK            = p.m_sPK;
		m_sData          = p.m_sData;
		m_eClientVersion = p.m_eClientVersion;
		m_sVersionString = p.m_sVersionString;
		m_nVersionMajor  = p.m_nVersionMajor;
		m_nVersionMinor  = p.m_nVersionMinor;
		m_nVersionPatch  = p.m_nVersionPatch;
		m_bExtProtocol   = p.m_bExtProtocol;

		return *this;
	};

	/** */
	CString m_sPK;
	/** */
	CString m_sData;
	/** */
	eUserClientVersion m_eClientVersion;
	/** */
	CString m_sVersionString;
	/** */
	int m_nVersionMajor;
	/** */
	int m_nVersionMinor;
	/** */
	int m_nVersionPatch;
	/** */
	bool m_bExtProtocol;
};

class CMessageFileLength : public CDCMessage {
public:
	/** */
	CMessageFileLength() : CDCMessage(DC_MESSAGE_FILELENGTH) {
		m_nFileLength = 0;
	};
	/** */
	virtual ~CMessageFileLength() {};

	/** */
	CMessageFileLength & operator = (const CMessageFileLength & p)
	{
		m_nFileLength = p.m_nFileLength;

		return *this;
	};

	/** */
	ulonglong m_nFileLength;
};

class CMessageSending : public CDCMessage {
public:
	/** */
	CMessageSending() : CDCMessage(DC_MESSAGE_SENDING) {
		m_nLength = 0;
	};
	/** */
	virtual ~CMessageSending() {};

	/** */
	CMessageSending & operator = (const CMessageSending & p)
	{
		m_nLength = p.m_nLength;

		return *this;
	};

	/** */
	ulonglong m_nLength;
};

class CMessageDirection : public CDCMessage {
public:
	/** */
	CMessageDirection() : CDCMessage(DC_MESSAGE_DIRECTION) {
		m_nLevel     = 0;
		m_eDirection = edNONE;
	};
	/** */
	virtual ~CMessageDirection() {};

	/** */
	CMessageDirection & operator = (const CMessageDirection & p)
	{
		m_eDirection = p.m_eDirection;
		m_nLevel     = p.m_nLevel;

		return *this;
	};

	/** */
	eDirection m_eDirection;
	/** */
	int m_nLevel;
};

class CMessageNickList : public CDCMessage {
public:
	/** */
	CMessageNickList();
	/**
	 * Copy constructor that does a deep copy of the list.
	 */
	CMessageNickList( const CMessageNickList & other );
	/** */
	virtual ~CMessageNickList();
	
	/** */
	CMessageNickList & operator = (const CMessageNickList & rhs);

	/** */
	CList<CString> m_NickList;
};

class CMessageOpList : public CDCMessage {
public:
	/** */
	CMessageOpList();
	/**
	 * Copy constructor that does a deep copy of the list.
	 */
	CMessageOpList( const CMessageOpList & other );
	/** */
	virtual ~CMessageOpList();
	
	/** */
	CMessageOpList & operator = (const CMessageOpList & rhs);

	/** */
	CList<CString> m_NickList;
};

class CMessageMyNick : public CDCMessage {
public:
	/** */
	CMessageMyNick() : CDCMessage(DC_MESSAGE_MYNICK) {};
	/** */
	virtual ~CMessageMyNick() {};

	CMessageMyNick & operator = (const CMessageMyNick & p)
	{
		m_sNick = p.m_sNick;

		return *this;
	};

	/** */
	CString m_sNick;
};

class CMessageHello : public CDCMessage {
public:
	/** */
	CMessageHello() : CDCMessage(DC_MESSAGE_HELLO) {};
	/** */
	virtual ~CMessageHello() {};

	CMessageHello & operator = (const CMessageHello & p)
	{
		m_sNick = p.m_sNick;

		return *this;
	};

	/** */
	CString m_sNick;
};

class CMessageQuit : public CDCMessage {
public:
	/** */
	CMessageQuit() : CDCMessage(DC_MESSAGE_QUIT) {};
	/** */
	virtual ~CMessageQuit() {};

	CMessageQuit & operator = (const CMessageQuit & p)
	{
		m_sNick = p.m_sNick;

		return *this;
	};

	/** */
	CString m_sNick;
};

class CMessageChat : public CDCMessage {
public:
	/** */
	CMessageChat() : CDCMessage(DC_MESSAGE_CHAT) {};
	/** */
	virtual ~CMessageChat() {};

	CMessageChat & operator = (const CMessageChat & p)
	{
		m_sNick    = p.m_sNick;
		m_sMessage = p.m_sMessage;

		return *this;
	};

	/** */
	CString m_sNick;
	/** */
	CString m_sMessage;
};

class CMessageMyInfo : public CDCMessage {
public:
	/** */
	CMessageMyInfo();
	/** */
	virtual ~CMessageMyInfo();

	/** */
	CMessageMyInfo & operator = (const CMessageMyInfo & p);

	/** */
	CMessageLock m_MessageLock;
	/** */
	CMessageSupports m_MessageSupports;

	/** the nickname */
	CString m_sNick;
	/** the comment */
	CString m_sComment;
	/** */
	CString m_sUnknown;
	/** the speed string */
	CString m_sUserSpeed;
	/** the email */
	CString m_sEMail;
	/** version */
	CString m_sVerComment;
	/** */
	CString m_sTransferHost;

	/** sharesize */
	ulonglong m_nShared;
	/** parsed speed */
	eUserSpeed m_eUserSpeed;
	/** away mode */
	eUserAwayMode m_eAwayMode;
	/** parsed client version */
	eUserClientVersion m_eClientVersion;
	/** client mode */
	eClientMode m_eClientMode;
	/** true if myinfo recv. */
	bool m_bValid;
	/** operator status */
	bool m_bOperator;
	/** Server flag set - special icon */
	bool m_bServerFlag;
	/** Fireball flag set - special icon */
	bool m_bFireballFlag;
	/** Supports NMDC TLS port */
	bool m_bTLSFlag;
	
protected:
	/** For CMessageSearchResultUser */
	CMessageMyInfo( eDCMessage type );
};

class CMessageConnectToMe : public CDCMessage {
public:
	/** */
	CMessageConnectToMe() : CDCMessage(DC_MESSAGE_CONNECTTOME) {
		m_nPort = 0;
		m_bCrypto = false;
	};
	/** */
	virtual ~CMessageConnectToMe() {};

	CMessageConnectToMe & operator = (const CMessageConnectToMe & p)
	{
		m_sNick = p.m_sNick;
		m_sHost = p.m_sHost;
		m_nPort = p.m_nPort;
		m_bCrypto = p.m_bCrypto;

		return *this;
	};

	/** */
	CString m_sNick;
	/** */
	CString m_sHost;
	/** */
	int m_nPort;
	/** StrongDC NMDC TLS port extension */
	bool m_bCrypto;
};

class CMessageRevConnectToMe : public CDCMessage {
public:
	/** */
	CMessageRevConnectToMe() : CDCMessage(DC_MESSAGE_REVCONNECTTOME) {};
	/** */
	virtual ~CMessageRevConnectToMe() {};

	CMessageRevConnectToMe & operator = (const CMessageRevConnectToMe & p)
	{
		m_sNick    = p.m_sNick;
		m_sDstNick = p.m_sDstNick;

		return *this;
	};

	/** */
	CString m_sNick;
	/** */
	CString m_sDstNick;
};

class CMessageForceMove : public CDCMessage {
public:
	/** */
	CMessageForceMove() : CDCMessage(DC_MESSAGE_FORCEMOVE) {
		m_nPort = 0;
	};
	/** */
	virtual ~CMessageForceMove() {};

	/** */
	CMessageForceMove & operator = (const CMessageForceMove & p)
	{
		m_sHost = p.m_sHost;
		m_nPort = p.m_nPort;

		return *this;
	};

	/** */
	CString m_sHost;
	/** */
	int m_nPort;
};

class CMessageSearchResult : public CDCMessage {
public:
	/** */
	CMessageSearchResult() : CDCMessage(DC_MESSAGE_SEARCHRESULT) {
		m_nFreeSlot = 0;
		m_nMaxSlot  = 0;
		m_nSize     = 0;
		m_bFolder   = false;
	};
	/** */
	virtual ~CMessageSearchResult() {};

	/** */
	CMessageSearchResult & operator = (const CMessageSearchResult & p)
	{
		m_sNick     = p.m_sNick;
		m_sFile     = p.m_sFile;
		m_nSize     = p.m_nSize;
		m_sHubName  = p.m_sHubName;
		m_sHubHost  = p.m_sHubHost;
		m_sHash     = p.m_sHash;
		m_sSrcIP    = p.m_sSrcIP;
		m_nFreeSlot = p.m_nFreeSlot;
		m_nMaxSlot  = p.m_nMaxSlot;
		m_bFolder   = p.m_bFolder;

		return *this;
	};

	/** */
	CString m_sNick;
	/** */
	CString m_sFile;
	/** */
	ulonglong m_nSize;
	/** */
	CString m_sHubName;
	/** */
	CString m_sHubHost;
	/** */
	CString m_sHash;
	/**
	 * The source (client not hub) IP if you are in active mode,
	 * always empty if you are in passive mode.
	 */
	CString m_sSrcIP;
	/** */
	unsigned int m_nFreeSlot;
	/** */
	unsigned int m_nMaxSlot;
	/** True if the result is a folder, false if the result is a file*/
	bool m_bFolder;
};

class CMessagePrivateChat : public CDCMessage {
public:
	/** */
	CMessagePrivateChat() : CDCMessage(DC_MESSAGE_PRIVATECHAT) {
		m_eSecureState = esecsNONE;
	};
	/** */
	virtual ~CMessagePrivateChat() {};

	/** */
	CMessagePrivateChat & operator = (const CMessagePrivateChat & p)
	{
		m_sDstNick      = p.m_sDstNick;
		m_sSrcNick      = p.m_sSrcNick;
		m_sMultiSrcNick = p.m_sMultiSrcNick;
		m_sMessage      = p.m_sMessage;
		m_eSecureState  = p.m_eSecureState;

		return *this;
	};

	/** */
	CString m_sDstNick;
	/** */
	CString m_sSrcNick;
	/** */
	CString m_sMultiSrcNick;
	/** */
	CString m_sMessage;
	/** */
	eSecureState m_eSecureState;
};

class CMessageHubName : public CDCMessage {
public:
	/** */
	CMessageHubName() : CDCMessage(DC_MESSAGE_HUBNAME) {};
	/** */
	virtual ~CMessageHubName() {};

	/** */
	CMessageHubName & operator = (const CMessageHubName & p)
	{
		m_sHubName    = p.m_sHubName;
		m_sOldHubName = p.m_sOldHubName;

		return *this;
	};
	
	/** */
	CString m_sHubName;
	/** */
	CString m_sOldHubName;
};

// download manager object classes

class CMessageDMFileObject : public CDCMessage {
public:
	/** */
	CMessageDMFileObject();
	/** Copy constructor that does deep copy */
	CMessageDMFileObject( const CMessageDMFileObject & other );
	/** */
	virtual ~CMessageDMFileObject();

	/** */
	CMessageDMFileObject & operator = (const CMessageDMFileObject & p);

	/** */
	CString m_sNick;
	/** */
	CString m_sHubName;
	/** */
	CString m_sHubHost;
	/** remote file */
	CString m_sRemoteFile;
	/** the local file */
	CString m_sLocalFile;
	/** */
	CString m_sTTH;
	/** */
	time_t m_tTimeout;
	/** */
	eTransferWaitState m_eTransferWaitState;
	/** */
	int m_nConnections;
	/** */
	eTransferFileState m_eTransferFileState;
	/** file size */
	ulonglong m_nSize;
	/** current file position */
	ulonglong m_nStartPosition;
	/** current file position */
	ulonglong m_nCurrentPosition;
	/** file end position */
	ulonglong m_nEndPosition;
	/** */
	int m_nPriority;
	/** list of directories to download */
	std::list<CString> * m_pDirList;
	/** */
	bool m_bMulti;
	/** */
	bool m_bRemoveFile;
};

class CMessageDMTransferObject : public CDCMessage {
public:
	/** */
	CMessageDMTransferObject();
	/** */
	virtual ~CMessageDMTransferObject();

	/** */
	CMessageDMTransferObject & operator = (const CMessageDMTransferObject & p);

	/** */
	ulonglong m_nTransferID;
	/** */
	CString m_sSrcNick;
	/** */
	CString m_sDstNick;
	/** */
	CString sHost;
	/** */
	CString m_sHubHost;
	/** */
	CString sHubName;
	/** remote file */
	CString m_sDstFile;
	/** local file */
	CString m_sSrcFile;
	/** */
	CString m_sTTH;
	/** */
	eConnectionState eState;
	/** file size */
	ulonglong lSize;
	/** file size done */
	ulonglong lSizeDone;
	/** rate of transfer */
	ulonglong lRate;
	/** rate of all transfers */
	ulonglong m_nMultiRate;
	/** */
	ulonglong lStartPosition;
	/** */
	ulonglong lTransfered;
	/** */
	ulonglong lEndPosition;
	/** */
	bool bRemoveTransfer;
	/** */
	bool m_bEncrypted;
};

class CMessageDMFileListObject : public CDCMessage {
public:
	/** */
	CMessageDMFileListObject();
	/** Does a deep copy of the optional list */
	CMessageDMFileListObject( const CMessageDMFileListObject & other );
	/** */
	virtual ~CMessageDMFileListObject();

	/** */
	CMessageDMFileListObject & operator = (const CMessageDMFileListObject & p);

	/** */
	CString sNick;
	/** */
	CString sHubName;
	/** */
	CString sHubHost;
	/** */
	CString sLocalFile;
	/** open filelist at file/folder */
	CString sJumpTo;
	/** list of directories to download */
	std::list<CString> * m_pDirList;
};

class CMessageDMSlotObject : public CDCMessage {
public:
	/** */
	CMessageDMSlotObject() : CDCMessage(DC_MESSAGE_SLOT_OBJECT) {
		iSlots     = 0;
		bPermanent = false;
	};
	/** */
	virtual ~CMessageDMSlotObject() {};

	/** */
	CString sNick;
	/** */
	CString sHubName;
	/** */
	int iSlots;
	/** */
	bool bPermanent;
};

class CMessageLog : public CDCMessage {
public:
	/** */
	CMessageLog() : CDCMessage(DC_MESSAGE_LOG) {};
	/** */
	virtual ~CMessageLog() {};

	/** */
	CString sMessage;
};

class CMessageSearchUser : public CDCMessage {
public:
	/** */
	CMessageSearchUser() : CDCMessage(DC_MESSAGE_SEARCH_USER) {};
	/** */
	virtual ~CMessageSearchUser() {};
	
	/** */
	CString m_sNick;
};

class CMessageSearchResultUser : public CMessageMyInfo {
public:
	/** */
	CMessageSearchResultUser() : CMessageMyInfo( DC_MESSAGE_SEARCHRESULT_USER ) {};
	/** */
	virtual ~CMessageSearchResultUser() {};

	CMessageSearchResultUser & operator = (const CMessageSearchResultUser & rhs)
	{
		(CMessageMyInfo&)*this = (CMessageMyInfo&)rhs;
		
		m_sHubName = rhs.m_sHubName;
		
		return *this;
	};

	/** */
	CString m_sHubName;
};

class CMessageSearchFile : public CDCMessage {
public:
	/** */
	CMessageSearchFile();
	/** */
	virtual ~CMessageSearchFile();

	CMessageSearchFile & operator = (const CMessageSearchFile & rhs);

	/** search string */
	CString m_sString;
	/** the source, nick or host */
	CString m_sSource;
	/** if source a host, this is the port */
	int m_nPort;
	/** search options */
	enum eSearchSizeType m_eSizeType;
	/** search options */
	ulonglong m_nSize;
	/** search options */
	eFileTypes m_eFileType;
	/** search options */
	bool m_bSizeLimit;
	/** local or global search */
	bool m_bLocal;
	/** extended protocol */
	bool m_bExtended;
	/** hub network search */
	bool m_bMulti;
};

class DCHubObject {
public:
	/** */
	DCHubObject() {
		m_bActive = false;
	};
	/** */
	DCHubObject( DCHubObject * o ) {
		m_bActive  = o->m_bActive;
		m_sHubName = o->m_sHubName;
		m_sHubHost = o->m_sHubHost;
	};

	/** */
	~DCHubObject() {};

	/** */
	bool m_bActive;
	/** */
	CString m_sHubName;
	/** */
	CString m_sHubHost;
};

class DCMessageTraffic : public CDCMessage {
public:
	/** */
	DCMessageTraffic() : CDCMessage(DC_MESSAGE_TRAFFIC) {
		m_nRx        = 0;
		m_nTx        = 0;
		m_nDataRx    = 0;
		m_nDataTx    = 0;
		m_nControlRx = 0;
		m_nControlTx = 0;
	};
	/** */
	virtual ~DCMessageTraffic() {};

	DCMessageTraffic & operator = (const DCMessageTraffic & s)
	{
		m_nRx        = s.m_nRx;
		m_nTx        = s.m_nTx;
		m_nDataRx    = s.m_nDataRx;
		m_nDataTx    = s.m_nDataTx;
		m_nControlRx = s.m_nControlRx;
		m_nControlTx = s.m_nControlTx;

		return *this;
	};

	/** */
	ulonglong m_nRx;
	/** */
	ulonglong m_nTx;
	/** */
	ulonglong m_nDataRx;
	/** */
	ulonglong m_nDataTx;
	/** */
	ulonglong m_nControlRx;
	/** */
	ulonglong m_nControlTx;
};

class DCMessageGetHubList : public CDCMessage {
public:
	/** */
	DCMessageGetHubList() : CDCMessage(DC_MESSAGE_GETHUBLIST) {
		m_bRun = false;
	};
	/** */
	virtual ~DCMessageGetHubList() {};

	/** */
	bool m_bRun;
};

class DCMessageConnectClient : public CDCMessage {
public:
	/** */
	DCMessageConnectClient() : CDCMessage(DC_MESSAGE_CONNECT_CLIENT) {};
	/** */
	virtual ~DCMessageConnectClient() {};

	/** */
	CString m_sHubName;
	/** */
	CString m_sHubHost;
};

class CMessageUserIP : public CDCMessage {
public:
	/** Creates a new UserIP object */
	CMessageUserIP() : CDCMessage(DC_MESSAGE_USERIP) {};
	/** */
	virtual ~CMessageUserIP() {};
	
	/** List of nicks */
	std::list<CString> m_lNicks;
	/** List of IPs */
	std::list<CString> m_lIPs;
};

class CMessageUserCommand : public CDCMessage {
public:
	/** */
	CMessageUserCommand() : CDCMessage(DC_MESSAGE_USER_COMMAND) {
		type = -1;
		context = -1;
	};
	/** */
	virtual ~CMessageUserCommand() {};
	
	/** Command type - raw, raw once, remove or clear commands etc. */
	int type;
	/** Command context - which menus it goes in */
	int context;
	/** Command name */
	CString name;
	/** The command itself */
	CString command;
};

#endif
