#ifndef ErhaltungServer_H
#define ErhaltungServer_H

#include <Server.h>
#include <Thread.h>
#include <Datei.h>
#include <Text.h>
#include <InitDatei.h>
#include <Zeit.h>
#ifdef WIN32
#include "..\Datenbank\Datenbank.h"
#else
#include "Datenbank.h"
#endif

using namespace Network;

class ErhaltungServer : public Thread
{
private:
	Server *server;
	Server *aServer;
	InitDatei *ini;
	ESDatenbank *db;
	Text *fehler;
	int clients;
	int id;
	bool nichtPausiert;
	int empfangen;
	int gesendet;
	bool end;
	int ref;

public:
	// Konstruktor
	ErhaltungServer( InitDatei *zIni );
	// Destruktor
	virtual ~ErhaltungServer();
	// nicht constant
	void runn();
	void thread();
	void close();
	bool serverStarten();
	bool serverPause();
	bool serverFortsetzen();
	bool serverBeenden();
	bool setMaxKlients( unsigned char mc );
	void addGesendet( int bytes );
	void addEmpfangen( int bytes );
	void clientTrennung();
	// constant
	bool istAn() const;
	Server *zServer() const;
	ESDatenbank *zDB() const;
	bool hatClients() const;
	int getId() const;
	char *getLetzterFehler() const;
	// Reference Counting
	ErhaltungServer *getThis();
	ErhaltungServer *release();
};

class ESAKlient : public Thread
{
private:
	SKlient *klient;
	Text *name;
	Text *passwort;
	int adminId;
	ErhaltungServer *es;
	int version;

public:
	// Konstruktor 
	ESAKlient( SKlient *klient, ErhaltungServer *es );
	// Destruktor 
	virtual ~ESAKlient();
	// nicht constant
	void thread();
	void errorZuKlient( const char *nachricht ) const; // sendet eine Fehlernachricht zum AKlient
};

class ESKlient;

class ESKThread : public Thread
{
private:
	ESKlient *zKlient;
	int ref;

public:
	// Konstruktor
	ESKThread( ESKlient *zKlient );
	// Destruktor
	virtual ~ESKThread();
	// nicht constant
	virtual void thread();
	// constant

	// Reference Counting
	ESKThread *getThis();
	ESKThread *release();
};

class ESKlient : public Thread
{
private:
	ESKThread *th;
	SKlient *klient;
	ZeitMesser *zeit;
	double sekunden;
	double letzteErhaltung;
	bool abgemeldet;
	unsigned int klientNummer;
	ErhaltungServer *es;
	bool encrypted;

public:
	// Konstruktor
	ESKlient( SKlient *klient, ErhaltungServer *es );
	// Destruktor
	virtual ~ESKlient();
	// nicht constant
	bool erhalten();
	virtual void thread();
	// constant
	void errorZuKlient( const char *nachricht ) const;
};

class ESGWeiterleitung
{
private:
	ErhaltungServer *es;
	int ref;

public:
	// Konstruktor
	ESGWeiterleitung( ErhaltungServer *es );
	// Destruktor
	~ESGWeiterleitung();
	// nicht constant
	bool patchServerKlientAbsturz( int klientId );
	bool registerServerKlientAbsturz( int klientId );
	bool loginServerKlientAbsturz( int klientId );
	bool informationServerKlientAbsturz( int klientId );
	bool chatServerKlientAbsturz( int klientId );
	bool anmeldungServerKlientAbsturz( int klientId );
	bool spielServerKlientAbsturz( int klientId );
	bool shopServerKlientAbsturz( int klientId );
	bool historieServerKlientAbsturz( int klientId );
    bool newsServerKlientAbsturz( int klientId );
    bool kartenServerKlientAbsturz( int klientId );
    bool editorServerKlientAbsturz( int klientId );
    bool minigameServerKlientAbsturz( int klientId );
	bool spielErstelltAbbrechen( int spielErstelltId );
	bool spielerLeavesGruppe( int gruppeId, int accountId );
	bool setGruppeAdmin( int gruppeId, int adminId );
	bool spielerLeavesChatroom( int chatroomId, int accountId );
	bool setChatroomAdmin( int chatroomId, int adminId );
	bool kickSpielerAusGruppe( int gruppeId );
	// constant

	// Reference Counting
	ESGWeiterleitung *getThis();
	ESGWeiterleitung *release();
};

#endif