/***************************************************************************
                          cclient.h  -  description
                             -------------------
    begin                : Sun Sep 30 2001
    copyright            : (C) 2001-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 CCLIENT_H
#define CCLIENT_H

/**
  *@author Mathias Küster
  */

#include <dclib/dcos.h>
#include <dclib/core/cstring.h>
#include <dclib/core/ccallback.h>
#include <dclib/dcobject.h>
#include <dclib/cdcproto.h>
#include <dclib/cclientssl.h>
#include <dclib/cuserlist.h>

/** */
typedef enum eReconnectState {
	ersNONE,
	ersFORCEMOVE,
	ersDISABLED,
	ersENABLED
} eReconnectState;


class CClient;
class CObject;
class CStringList;
class CThreadStringList;
class CMessageNickList;
class CMessageMyInfo;

class DLL_EXPORT CClient : public CDCProto {

public:
	/** */
	CClient();
	/** */
	virtual ~CClient();

	/** */
	void UpdateUserSlots( CMessageSearchResult * pSearchResult );
	/** */
	bool SetUserTransferInfo( CString nick, CDCMessage * msg );

	/** */
	inline void SetHubName( CString hubname );
	/** */
	inline CString GetHubName() const;
	/** */
	inline void SetHubTopic( CString hubtopic );
	/** */
	inline CString GetHubTopic() const;
	/** */
	inline void SetVersion( CString version );
	/** */
	inline CString GetVersion() const;
	
	/** */
	inline void SetNick( CString nick );
	/** */
	inline CString GetNick() const;
	/** */
	inline void SetEMail( CString email );
	/** */
	inline CString GetEMail() const;
	/** */
	inline void SetConnectionType( CString ctype );
	/** */
	inline CString GetConnectionType() const;
	/** */
	inline void SetComment( CString comment );
	/** */
	inline CString GetComment() const;
	/** */
	inline void SetShareSize( CString sharesize );
	/** */
	inline CString GetShareSize() const;
	/** */
	inline void SetMode( eClientMode mode );
	/** */
	inline eClientMode GetMode() const;
	/** */
	inline void SetAwayMode( eUserAwayMode mode );
	/** */
	inline eUserAwayMode GetAwayMode() const;
	
	/** */
	inline bool IsHandshake() const;
	
	/** */
	inline void SetHandleUserList( bool b );
	/** */
	inline void SetHandleSearch( bool b );
	/** */
	inline void SetHandleMyinfo( bool b );
	/** */
	inline void SetSendMyinfo( bool b );
	/** */
	inline void SetHandleForceMove( bool b );
	/** */
	inline void SetHandleTransfer( bool b );
	/** */
	inline void SetSSLMode( bool b );

	/** */
	inline CUserList * UserList() { return &m_UserList; };

	/** */
	inline void SetCallBackFunction( _CCallback * callback );

	/** */
	int HandleMessage( const CString & message );

	/** send private message */
	virtual int SendPrivateMessage( CString sNick, CString sTo, CString sMsg, CString sFromNick = "" );
	/** */
	virtual int RequestNickList();

	/** */
	virtual void DataAvailable( const char * buffer, int len );
	/** */
	virtual void DataTimeout();
	/** */
	virtual void Notify();
	/** */
	virtual void ConnectionState( eConnectionState state );
	/** callback function */
	virtual int DC_CallBack( CObject * ) { return -1; };

	/** */
	int Disconnect( bool force = FALSE );

protected:
	/** */
	void UpdateReconnect( eReconnectState state, int count = -1 );

private:
	/** user list */
	CUserList m_UserList;
	/** */
	CClientSSL m_pMessageSSL;
	/** user myinfo */
	CMessageMyInfo m_MyInfo;
	/** hubname */
	CString m_sHubName;
	/** hubtopic */
	CString m_sHubTopic;
	/** client version */
	CString m_sVersion;

	/** */
	bool m_bHandshake;
	/** */
	bool m_bSSLMode;
	/** */
	bool m_bHandleUserList;
	/** */
	bool m_bHandleSearch;
	/** */
	bool m_bHandleMyinfo;
	/** */
	bool m_bHandleForceMove;
	/** */
	bool m_bHandleTransfer;
	/** */
	bool m_bUpdateMyinfo;
	/** */
	bool m_bSendMyinfo;
	/** */
	time_t m_timeMyinfoTimeout;
	
	/** */
	CString m_sBuffer;
	/** callback function */
	_CCallback * m_pCallback;
	/** */
	CThread m_ClientThread;
	/** */
	time_t m_timeReconnectTimeout;
	/** */
	eReconnectState m_eReconnectState;
	/** */
	int m_nReconnectCount;
	/** */
	int m_nNickListHandler;
	/** */
	int m_nOpListHandler;
	/** */
	CMessageCapabilities m_MessageCapabilities;
	/** */
	CMessageSupports m_MessageSupports;
};

/** inline functions */

/** */
inline void CClient::SetNick( CString nick )
{ m_ClientThread.Lock(); if ( m_MyInfo.m_sNick != nick ) { m_bUpdateMyinfo = TRUE; m_MyInfo.m_sNick=nick; } m_ClientThread.UnLock(); }
/** */
inline CString CClient::GetNick() const
{ return m_MyInfo.m_sNick; }
/** */
inline void CClient::SetEMail( CString email )
{ m_ClientThread.Lock(); if ( m_MyInfo.m_sEMail != email ) { m_bUpdateMyinfo = TRUE; m_MyInfo.m_sEMail=email; } m_ClientThread.UnLock(); }
/** */
inline CString CClient::GetEMail() const
{ return m_MyInfo.m_sEMail; }
/** */
inline void CClient::SetConnectionType( CString ctype )
{ m_ClientThread.Lock(); if ( m_MyInfo.m_sUserSpeed != ctype ) { m_bUpdateMyinfo = TRUE; m_MyInfo.m_sUserSpeed=ctype; } m_ClientThread.UnLock(); }
/** */
inline CString CClient::GetConnectionType() const
{ return m_MyInfo.m_sUserSpeed; }
/** */
inline void CClient::SetComment( CString comment )
{ m_ClientThread.Lock(); if ( m_MyInfo.m_sComment != comment ) { m_bUpdateMyinfo = TRUE; m_MyInfo.m_sComment=comment; } m_ClientThread.UnLock(); }
/** */
inline CString CClient::GetComment() const
{ return m_MyInfo.m_sComment; }
/** */
inline void CClient::SetShareSize( CString sharesize )
{ m_ClientThread.Lock(); if ( m_MyInfo.m_nShared != sharesize.asULL() ) { m_bUpdateMyinfo = TRUE; m_MyInfo.m_nShared = sharesize.asULL(); } m_ClientThread.UnLock(); }
/** */
inline CString CClient::GetShareSize() const
{ return CString().setNum(m_MyInfo.m_nShared); }
/** */
inline void CClient::SetMode( eClientMode mode )
{ m_ClientThread.Lock(); m_MyInfo.m_eClientMode=mode; m_ClientThread.UnLock(); }
/** */
inline eClientMode CClient::GetMode() const
{ return m_MyInfo.m_eClientMode; }
/** */
inline void CClient::SetAwayMode( eUserAwayMode mode )
{ m_ClientThread.Lock(); if ( m_MyInfo.m_eAwayMode != mode ) { m_bUpdateMyinfo = TRUE; m_MyInfo.m_eAwayMode = mode; } m_ClientThread.UnLock(); }
/** */
inline eUserAwayMode CClient::GetAwayMode() const
{ return m_MyInfo.m_eAwayMode; }

/** */
inline void CClient::SetVersion( CString version )
{ m_ClientThread.Lock(); m_sVersion = version; m_ClientThread.UnLock(); }
/** */
inline CString CClient::GetVersion() const
{ return m_sVersion; }
/** */
inline void CClient::SetHubName( CString hubname )
{ m_ClientThread.Lock(); m_sHubName = hubname; m_ClientThread.UnLock(); }
/** */
inline CString CClient::GetHubName() const
{ return m_sHubName; }
/** */
inline void CClient::SetHubTopic( CString hubtopic )
{ m_ClientThread.Lock(); m_sHubTopic = hubtopic; m_ClientThread.UnLock(); }
/** */
inline CString CClient::GetHubTopic() const
{ return m_sHubTopic; }

/** */
inline bool CClient::IsHandshake() const
{ return m_bHandshake; }
/** */
inline void CClient::SetCallBackFunction( _CCallback * callback )
{ m_ClientThread.Lock(); if ( m_pCallback ) delete m_pCallback; m_pCallback = callback; m_ClientThread.UnLock(); }
/** */
inline void CClient::SetHandleUserList( bool b )
{ m_ClientThread.Lock(); m_bHandleUserList = b; m_ClientThread.UnLock(); }
/** */
inline void CClient::SetHandleSearch( bool b )
{ m_ClientThread.Lock(); m_bHandleSearch = b; m_ClientThread.UnLock(); }
/** */
inline void CClient::SetHandleMyinfo( bool b )
{ m_ClientThread.Lock(); m_bHandleMyinfo = b; m_ClientThread.UnLock(); }
/** */
inline void CClient::SetSendMyinfo( bool b )
{ m_ClientThread.Lock(); m_bSendMyinfo = b; m_ClientThread.UnLock(); }
/** */
inline void CClient::SetHandleForceMove( bool b )
{ m_ClientThread.Lock(); m_bHandleForceMove = b; m_ClientThread.UnLock(); }
/** */
inline void CClient::SetHandleTransfer( bool b )
{ m_ClientThread.Lock(); m_bHandleTransfer = b; m_ClientThread.UnLock(); }
/** */
inline void CClient::SetSSLMode( bool b )
{ m_ClientThread.Lock(); m_bSSLMode = b; m_ClientThread.UnLock(); }

#endif
