#ifndef _TCPSOCKET_H
#define _TCPSOCKET_H

#if defined(__GNUG__) && !defined(__APPLE__)
    #pragma interface "TCPSocket.h"
#endif

#ifndef _AFX
#include <wx/defs.h>
#include "wx/stream.h"
#else
#include "baselib/wxwin2mfc.h"
#include <WinSock.h>
#endif

#define TCP 'T'
#define UDP 'U'


class TCPSocket {
	
public:
	
	TCPSocket();
	~TCPSocket();
	
	bool Create();
	bool Create(char nType);
	bool Create(int nPort, char nType = TCP, bool blocking = true);

	bool Attach(TCPSocket& sock);
	
	bool Listen();
	bool WaitConnection(int ms_timeout);
	bool Accept();

	bool SetBlockMode(bool block);
	
	bool Connect(int nPort, const char *Hostname);
	
	int Send(const void *Message, int nLength);
	int Recv(void *Buffer, int nLength);
	
	char *GetRemoteIP();
	
	bool Close();
	bool InboundClose();
	bool IsConnected() { return m_connected; }
	bool Write8(wxUint8 i);
	bool Write32(wxUint32 i);
	bool WriteString(const wxString& string);
	bool ReadString(wxString& string, int ms_timeout = 0);

	wxUint8 Read8();
	bool Read32(wxUint32& value, int ms_timeout = 0);

	int GetSockFD() { return sockfd; }
	int GetBytesAvailable(int& bytes, int ms_timeout);
private:
	int sockfd, newfd;
	sockaddr_in INetAddress, RemoteAddress;

	bool m_connected;
	bool m_block_mode;
};

#ifdef __WXMSW__
class mwTCPOutputStream : public wxOutputStream
{
public:
	mwTCPOutputStream(TCPSocket* s) { m_o_socket = s; }

	wxFileOffset SeekO( wxFileOffset WXUNUSED(pos), wxSeekMode WXUNUSED(mode) )
	{ return -1; }
	wxFileOffset TellO() const
	{ return -1; }

protected:
	TCPSocket *m_o_socket;

	size_t OnSysWrite(const void *buffer, size_t bufsize)
	{
		return m_o_socket->Send(buffer, bufsize);
	}

	DECLARE_NO_COPY_CLASS(mwTCPOutputStream)
};
#endif
#endif
