// This file is a part of the xMule Project.
//
// Copyright (c) 2004 Theodore R. Smith (hopeseekr@xmule.ws / http://www.xmule.ws/)
// DSA-1024 Fingerprint: 10A0 6372 9092 85A2 BB7F 907B CB8B 654B E33B F1ED
//
// Copyright (C)2002 Merkur ( merkur-@users.sourceforge.net / http://www.xmule-project.net )
//
// 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.
// 
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
// 
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

// Client to Server communication

#ifndef _SOCKETS_H
#define _SOCKETS_H

#include <map>                              // Needed for std::map
#include <stdint.h>                         // Needed for uint32_t
#include <wx/timer.h>                       // Needed for wxTimer

#define CS_FATALERROR	-5
#define CS_DISCONNECTED	-4
#define CS_SERVERDEAD	-3
#define	CS_ERROR		-2
#define CS_SERVERFULL	-1
#define	CS_NOTCONNECTED	0
#define	CS_CONNECTING	1
#define	CS_CONNECTED	2
#define	CS_WAITFORLOGIN	3
#define CS_RETRYCONNECTTIME  30 // seconds

class CPreferences;
class CServer;
class CServerList;
class CServerSocket;
class CUDPSocket;
class Packet;

class CServerConnect{
public:
	CServerConnect(CServerList* in_serverlist, CPreferences* in_prefs);
	~CServerConnect();
	void	ConnectionFailed(CServerSocket* sender);
	void	ConnectionEstablished(CServerSocket* sender);
	
	void	ConnectToAnyServer() {ConnectToAnyServer(0,true,true);}
	void	ConnectToAnyServer(uint32_t startAt,bool prioSort=false,bool isAuto=true);
	void	ConnectToServer(CServer* toconnect, bool multiconnect=false);
	void	StopConnectionTry();
	//static  VOID CALLBACK RetryConnectCallback(HWND hWnd, UINT nMsg, UINT nId, DWORD dwTime);

	void	CheckForTimeout();
	void	DestroySocket(CServerSocket* pSck);	// safe socket closure and destruction
	bool	SendPacket(Packet* packet,bool delpacket = true, CServerSocket* to = 0);
	bool	SendUDPPacket(Packet* packet,CServer* host, bool delpacket = false );
	bool	Disconnect();
	bool	IsConnecting()	{return connecting;}
	bool	IsConnected()	{return connected;}
	wxUint32	GetClientID()		{return clientid;}
	CServer*	GetCurrentServer();
	uint32_t	clientid;
	uint8_t	pendingConnects;
	bool	IsLowID()		{return (clientid < 16777216);}
	void	SetClientID(uint32_t newid);
	bool	IsLocalServer(uint32_t dwIP, uint16_t nPort);
	void	TryAnotherConnectionrequest();
	bool	IsSingleConnect()	{return singleconnecting;}
	void	InitLocalIP();
	wxUint32	GetLocalIP()		{ return m_nLocalIP; }

private:
	bool	connecting;
	bool	singleconnecting;
	bool	connected;
	int8_t	max_simcons;
	uint32_t lastStartAt;
	CPreferences*	app_prefs;
	CServerSocket*	connectedsocket;
	CServerList*	used_list;
	CUDPSocket*		udpsocket;
	CTypedPtrList<CPtrList,void*>		m_lstOpenSockets;	// list of currently opened sockets
	//UINT			m_idRetryTimer;
	wxTimer m_idRetryTimer;
	wxUint32 	m_nLocalIP;

	std::map<uint32_t, CServerSocket *> connectionattempts;
// Added by sivka [Tarod: Tries after a LowID connection]
public: 
	void	ResetLowIDTries() {m_lowid_tries = 0;}
	int	GetLowIDTries() {return m_lowid_tries;}
	void	IncrementLowIDTries() {m_lowid_tries++;}
private:
	int	m_lowid_tries;
};
#endif
