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

// handling incoming connections (up or downloadrequests)

#ifndef SERVERSOCKET4661_H
#define SERVERSOCKET4661_H

#include "Preferences.h"
#include "packets.h"
#include "EMSocket.h"

#include <wx/socket.h>
#include <wx/hashmap.h>
#include <string.h>

void PrintPacket(unsigned char* packet,uint32_t size,uint8_t opcode);

class CUpDownClient;
class CPacket;
class CTimerWnd;
class CServerSocket4661;

class CServerReqSocket4661: public CEMSocket
{
	DECLARE_DYNAMIC_CLASS(CServerReqSocket4661)
	CServerReqSocket4661();
public:

	CServerReqSocket4661(CPreferences* in_prefs);
	~CServerReqSocket4661();
	void		Disconnect();

	bool		CheckTimeOut();
	void		Safe_Delete();

	long		deletethis;

	bool		Create();
	void		OnClose(int nErrorCode);

	void		OnLost(int nErrorCode);
	void		OnInput(int nErrorCode);
	void		OnOutput(int nErrorCode);

	virtual	void OnInit();
	
	uint32_t		timeout_timer;
	uint32_t		deltimer;  
	bool		hotrank;

	CPreferences* 	app_prefs;
	wxUint32	n_SourceIP;
	wxUint16	n_SourcePort;
	wxUint16	n_TempPort;
	wxUint8		b_UserHash[16];
	wxUint32	n_ClientVersion;
	wxString	a_ClientName;
	wxUint32	n_compressionflag;
	CServerSocket4661	*ssocket;

protected:
	void		 		PacketReceived(Packet* packet);
private:
	void				Delete_Timed();
	void				FromClient_0x01_HELLO(unsigned char *packet,uint32_t size,uint8_t opcode);
	void				FromClient_0x14_GETSERVERLIST(unsigned char *packet,uint32_t size,uint8_t opcode);
	void				FromClient_0x16_SEARCHREQUEST(unsigned char *packet,uint32_t size,uint8_t opcode);
	void				FromClient_0x19_GETSOURCES(unsigned char *packet,uint32_t size,uint8_t opcode);
	bool				ToClient_0x01_HELLOANSWER();
	bool				ToClient_0x33_SEARCHRESULT();
	bool				ToClient_0x34_SERVERSTATUS();
	bool				ToClient_0x38_SERVERMESSAGE(char *info);
	bool				ToClient_0x40_IDCHANGE();
	bool				ToClient_0x41_SERVERIDENT();
	bool				ProcessPacket(unsigned char* packet, uint32_t size,uint8_t opcode);
	bool				ProcessExtPacket(unsigned char* packet, uint32_t size,uint8_t opcode);
};

#include <wx/list.h>

class CServerSocket4661 : public wxSocketServer{
  DECLARE_DYNAMIC_CLASS(CServerSocket4661)

public:
	CServerSocket4661() : wxSocketServer(happyCompiler) {};
	CServerSocket4661(CPreferences* in_prefs,wxSockAddress& addr);
	~CServerSocket4661();
	bool		StartListening();
	void		StopListening();
	virtual void 	OnAccept(int nErrorCode);
	void		Process();
	void		RemoveSocket(CServerReqSocket4661* todel);
	void		AddSocket(CServerReqSocket4661* toadd);
	wxUint16	GetOpenSockets()		{return socket_list.GetCount();}
	void		KillAllSockets();
	bool		TooManySockets(bool bIgnoreInterval = false);
	wxUint32	GetMaxConnectionReached()	{return maxconnectionreached;}
	bool    	IsValidSocket(CServerReqSocket4661* totest);
	void		AddConnection();
	void		RecalculateStats();
	void		ReStartListening();

	void		Debug_ClientDeleted(CUpDownClient* deleted);
	wxUint32	n_CurrentUsers;
	wxUint32	n_CurrentFiles;
private:
	bool 		bListening;
	wxUint32	n_lowidcounter;
	wxUint16 	opensockets;
	wxUint16 	m_OpenSocketsInterval;
	wxUint32 	maxconnectionreached;
	wxIPV4address 	happyCompiler;
	wxUint16	m_ConnectionStates[3];
	wxUint16	m_nPendingConnections;
 	wxUint32	n_ServerIP;
        wxUint16	n_ServerPort;
	CPreferences* 					app_prefs;
	CTypedPtrList<CPtrList, CServerReqSocket4661*> socket_list;

public:
	MyHashMap1 	offensecounter;
	MyHashMap2 	hashbase;  
};

#endif
