/***************************************************************************
                          cconnection.h  -  description
                             -------------------
    begin                : Sat Oct 6 2001
    copyright            : (C) 2001-2003 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 CCONNECTION_H
#define CCONNECTION_H

/**
  *@author Mathias Küster
  *
  * A network connection, it extends CSocket to provide some
  * buffers and state, and also a loop to send and receive the data.
  *
  * Although it inherits CThread dclib does not start any, the
  * Thread() function is probably called by CConnectionManager for
  * hubs or CDownloadManager for peers, which in turn run on CManager's
  * thread.
  */

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

class CByteArray;
class CMutex;

class CConnection : public CThread, public CSocket {
public:
	/** */
	CConnection();
	/** */
	virtual ~CConnection();

	/** */
	int Connect();
	/** */
	int Connect( CString ip, eSocketType sockettype = estTCP );
	/** */
	int Connect( CString ip, int port, eSocketType sockettype = estTCP );
	/** */
	virtual int Disconnect( bool force = false );
	/** */
	int SetSocket( int handle, eSocketType sockettype = estTCP );

	/** */
	virtual void DataAvailable( const char *, int ) {};
	/** */
	virtual void DataSend() {};
	/** */
	virtual void DataTimeout() {};
	/** */
	virtual void Notify() {};
	/** */
	virtual void ConnectionState( eConnectionState ) {};
	/** */
	virtual void Thread();

	/**
	  * true  if all data send from the queue and the queue is empty
	  * false if data to send in the queue
	  */
	bool IsSendQueueEmpty();

	/** */
	virtual bool ChangeSocketMode( eSocketMode mode, CString cert = CString(), CString key = CString() );
	/** */
	void SetHost( CString ip, int port = 411 );
	/** */
	CString GetHost( bool peername = false );
	/** */
	CString GetIP() const;
	/** */
	int GetPort() const;
	/** */
	eConnectionState GetConnectionState() const;

protected:
	/** */
	int Write( const unsigned char * buffer, int len, bool direct = false );

private:
	/** */
	void StateConnect();
	/** */
	void StateConnecting();
	/** */
	void StateRead();
	/** */
	void StateSend();
	/** */
	void StateDisconnect();
	/** */
	void connectionState( eConnectionState e );

	/** */
	eConnectionState m_eState;
	/** */
	time_t m_timeNotify;
	/** check for connection/data timeout */
	time_t m_timeConnection;
	/** */
	CMutex * m_pConnMutex;
	/** */
	bool m_bForceDisconnect;
	/** */
	CString m_sIP;
	/** */
	int m_nPort;
	/** */
	CMutex * m_pSendListMutex;
	/** */
	CList<CByteArray> * m_pSendList;
	/** */
	CByteArray * m_pBuffer;
	/** */
	int m_nConnectTimeout;
};

/** inline functions */

/** */
inline void CConnection::SetHost( CString ip, int port )
{ m_sIP=ip;m_nPort=port; }
/** */
inline CString CConnection::GetIP() const
{ return m_sIP; }
/** */
inline int CConnection::GetPort() const
{ return m_nPort; }
/** */
inline eConnectionState CConnection::GetConnectionState() const
{ return m_eState; }

#endif
