/***************************************************************************
                          cconnectionmanager.h  -  description
                             -------------------
    begin                : Don Mai 16 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 CCONNECTIONMANAGER_H
#define CCONNECTIONMANAGER_H

/**
  *@author Mathias Küster
  *
  * This handles the list of hub connections.
  *
  * The main thing lacking here is some threading, so that all the hubs
  * are not run on the one dclib thread.
  */

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

enum eHubState {
	ehsNONE,
	ehsONLINE,
	ehsOFFLINE
};

class CClient;
class DCHubObject;
class CMessageSearchFile;
class CDCMessage;
class CMessageMyInfo;
class _CCallback0;

#include <map>

class CConnectionManager : public CSingleton<CConnectionManager> {
public:
	/** */
	CConnectionManager();
	/** */
	virtual ~CConnectionManager();

	/** */
	void ConnectClient( CString hubname, CString server );

	/** send message to all connected servers */
	int SendStringToConnectedServers( CString s, CString hubname = CString(), bool encode = true );
	/** send a search string (extracted from message) to all connected servers */
	int SendSearchToConnectedServers( CMessageSearchFile *sf, CString hubhost = CString() );
	/** send myinfo to all connected servers */
	int SendMyInfoToConnectedServers();
	/** 0: send -1: user offline -2: hub not ready (connection state/handshake) -3: hub offline -4: send error */
	int SendConnectionRequest( CString nick, CString hubname, CString hubhost );
	/** */
	bool SetUserTransferInfo( CString hubname, CString hubhost, CString nick, CDCMessage * msg );
	/** */
	bool IsUserOnline( CString nick, CString hubname, CString hubhost, CList<DCHubObject> * list = 0 );
	/** */
	eHubState IsHubOnline( CString hubname, CString hubhost );
	/** */
	bool IsAdmin( CString hubname, CString hubhost, CString nick = CString() );
	/** */
	bool GetUserMyInfo( CString hubname, CString hubhost, CString nick, CMessageMyInfo * p );
	/** */
	CString GetHubHost( CString hubname );
	/** */
	CString GetNick( CString hubname, CString hubhost );
	/**
	 * Fills in the paramaters with hubname, hubhost and hubip for the first
	 * hub whose hubname, hubhost or hubip matches id.
	 *
	 * Returns true if the details have been filled in.
	 */
	bool GetHubDetails( const CString & id, CString & name, CString & host, CString & ip );
	
	/** */
	long GetConnectedHubCount( bool admin = false );
	
	/** Returns the number of hubs which we logged into with a password */
	long GetConnectedHubPasswordCount();

	/** */
	std::map<CString, CString> * GetConnectedHubServerMap();

	/** */
	void Connect( CString hubname, CString server, CClient * client, bool sslconnect = false );
	
	/** callback function */
	virtual int DC_CallBack( CDCMessage * ) { return -1; };

protected:
	/** */
	void AddHub( CClient * client );
	/** */
	void RemoveHub( CClient * client );

	/** */
	CClient * GetHub( CString hubname, CString hubhost );

	/** */
	CMutex m_Mutex;
	/** FIXME why two mutexes? */
	CMutex * m_pClientListMutex;
	/** client list */
	CList<CClient> * m_pClientList;

private:
	/** */
	CClient * GetHubObject( CString hubname, CString hubhost );
	/** */
	void UpdateMyInfo( CClient* client );
	
	/** Called by CManager via the callback instead of starting out own thread */
	int Callback();

	/** */
	bool m_bUpdateMyinfo;

	/** */
	_CCallback0 * m_pCallback;
};

#endif
