#ifndef Network_H
#define Network_H

#ifdef WIN32
#ifdef _DEBUG
#ifndef _LTMDB
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
#define DEBUG_CLIENTBLOCK   new( _CLIENT_BLOCK, __FILE__, __LINE__)
#define new DEBUG_CLIENTBLOCK
#define _LTMDB
#endif
#endif
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include <WinSock2.h>
#else
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <unistd.h>
#include <fcntl.h>
#include <iostream>
#define __declspec( x )
#define __int64           long long
#ifndef SOCKET
#define SOCKET            int
#define SOCKADDR_IN       sockaddr_in
#define ADDR_ANY          INADDR_ANY
#define closesocket       close
#define PHOSTENT          hostent*
#endif
#endif
#include <Reader.h>
#include <Writer.h>

namespace Framework
{
	class Text;
}

namespace Network
{
	__declspec(dllexport) void Start(int maxClients);
	__declspec(dllexport) void getHostName(char* name, int bufferLen);
	__declspec(dllexport) char* getHostAddresse();
	__declspec(dllexport) void Exit();


	class Verbindung
	{
	public:
		virtual bool sende(const char* nachricht, int len) = 0; // sendet Nachricht
		virtual bool getNachricht(char* nachricht, int len) = 0; // empf�ngt Nachricht
	};

	class EncryptedVerbindung : public Verbindung
	{
	public:
		virtual bool sendeEncrypted(const char* nachricht, int len) = 0; // sendet Nachricht
		virtual bool getNachrichtEncrypted(char* nachricht, int len) = 0; // empf�ngt Nachricht
	};

	class NetworkReader : public Framework::StreamReader
	{
	private:
		Verbindung* verbindung;

	public:
		__declspec(dllexport) NetworkReader(Verbindung* v);
		__declspec(dllexport) virtual ~NetworkReader();
		//! Lie�t aus der Datei
		//! \param bytes Ein Array, der mit Bytes aus der Resource gef�llt werden soll
		//! \param len Wie viele Bytes aus der Resource gelesen werden sollen
		__declspec(dllexport) void lese(char* bytes, int len) override;
		//! Lie�t die n�chste zeile der Resource ein
		//! \return Die gelesene Zeile als Text mit zeilenumbruch
		__declspec(dllexport) Framework::Text* leseZeile() override;
		//! Pr�ft, ob die Resource vollst�ndig gelesen wurde
		//!  return 1, wenn die Resource vollst�ndig gelesen wurde. 0, sonst
		__declspec(dllexport) bool istEnde() const override;
	};

	class NetworkWriter : public Framework::StreamWriter
	{
	private:
		Verbindung* verbindung;

	public:
		__declspec(dllexport) NetworkWriter(Verbindung* v);
		__declspec(dllexport) virtual ~NetworkWriter();
		//! Schreibt in die Resource
		//! \param bytes Ein Array, der die Bytes enth�lt, welche in die Resource geschrieben werden soll
		//! \param len Wie viele Bytes in die Resource geschrieben werden sollen
		__declspec(dllexport) void schreibe(const char* bytes, int len) override;
		//! Pr�ft, ob die Resource vollst�ndig geschrieben wurde
		//!  return 1, wenn die Resource vollst�ndig geschrieben wurde. 0, sonst
		__declspec(dllexport) bool istEnde() const override;
	};

	class EncryptedNetworkReader : public Framework::StreamReader
	{
	private:
		EncryptedVerbindung* verbindung;

	public:
		__declspec(dllexport) EncryptedNetworkReader(EncryptedVerbindung* v);
		//! Lie�t aus der Datei
		//! \param bytes Ein Array, der mit Bytes aus der Resource gef�llt werden soll
		//! \param len Wie viele Bytes aus der Resource gelesen werden sollen
		__declspec(dllexport) void lese(char* bytes, int len) override;
		//! Lie�t die n�chste zeile der Resource ein
		//! \return Die gelesene Zeile als Text mit zeilenumbruch
		__declspec(dllexport) Framework::Text* leseZeile() override;
		//! Pr�ft, ob die Resource vollst�ndig gelesen wurde
		//!  return 1, wenn die Resource vollst�ndig gelesen wurde. 0, sonst
		__declspec(dllexport) bool istEnde() const override;
	};

	class EncryptedNetworkWriter : public Framework::StreamWriter
	{
	private:
		EncryptedVerbindung* verbindung;

	public:
		__declspec(dllexport) EncryptedNetworkWriter(EncryptedVerbindung* v);
		//! Schreibt in die Resource
		//! \param bytes Ein Array, der die Bytes enth�lt, welche in die Resource geschrieben werden soll
		//! \param len Wie viele Bytes in die Resource geschrieben werden sollen
		__declspec(dllexport) void schreibe(const char* bytes, int len) override;
		//! Pr�ft, ob die Resource vollst�ndig geschrieben wurde
		//!  return 1, wenn die Resource vollst�ndig geschrieben wurde. 0, sonst
		__declspec(dllexport) bool istEnde() const override;
	};
}

#endif