#ifndef AnmeldungServer_H
#define AnmeldungServer_H

#include <Server.h>
#include <Thread.h>
#include <Datei.h>
#include <Text.h>
#include <InitDatei.h>
#include "Datenbank.h"

using namespace Framework;
using namespace Network;

class ASKlient;

class AnmeldungServer : public Thread
{
private:
	Server *server;
	Server *aServer;
	InitDatei *ini;
	ASDatenbank *db;
	CRITICAL_SECTION cs;
	RCArray< ASKlient > *klients;
	Text *fehler;
	int klientAnzahl;
	int id;
	bool nichtPausiert;
	int empfangen;
	int gesendet;
	bool end;
	int ref;

public:
	// Konstruktor 
	AnmeldungServer( InitDatei *zIni );
	// Destruktor 
	virtual ~AnmeldungServer();
	// nicht constant 
	void runn();
	void thread();
	void close();
	bool serverStarten();
	bool serverPause();
	bool serverFortsetzen();
	bool serverBeenden();
	bool setMaxKlients( int mc );
	bool absturzKlient( int klientId );
	bool removeKlient( ASKlient *zKlient );
	void addGesendet( int bytes );
	void addEmpfangen( int bytes );
	// conatant 
	bool istAn() const;
	Server *zServer() const;
	ASDatenbank *zDB() const;
	bool hatClients() const;
	int getId() const;
	char *getLetzterFehler() const;
	char *getIp() const;
	// Reference Counting
	AnmeldungServer *getThis();
	AnmeldungServer *release();
};

class ASAKlient : public Thread
{
private:
	SKlient *klient;
	Text *name;
	Text *passwort;
	int adminId;
	AnmeldungServer *as;
	int version;

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

class ASKlient : public Thread
{
private:
	SKlient     *klient;
	unsigned int klientNummer;
	AnmeldungServer *as;
	int accountId;
	int ref;

public:
	// Konstruktor 
	ASKlient( SKlient *klient, AnmeldungServer *as );
	// Destruktor 
	virtual ~ASKlient();
	// nicht constant
	void absturz();
	virtual void thread();
	// constant
	void errorZuKlient( const char *nachricht ) const; // sendet eine Fehlernachricht zum Klient
	int getKlientNummer() const;
	// Reference Counting
	ASKlient *getThis();
	ASKlient *release();
};

class MsgWeiterleitung
{
private:
	AnmeldungServer *as;
	int accountId;
	int ref;
	Text *fehler;

public:
	// Konstruktor
	MsgWeiterleitung( int accountId, AnmeldungServer *as );
	// Destruktor
	virtual ~MsgWeiterleitung();
	// nicht constant
	bool spielerBetrittGruppe( int gruppeId );
	bool spielerLeavesGruppe( int gruppeId );
	bool setGruppeAdmin( int gruppeId, int admin );
	bool kickSpielerAusGruppe( int accountId, int gruppeId );
	bool gruppenNachricht( int gruppeId, char *txt );
	bool gruppeAngemeldet( int gruppeId );
	bool gruppeAbgemeldet( int gruppeId );
	bool gruppeSpielStarten( int gruppeId, bool starten );
	bool spielEinladung( int gruppeId, int accountId );
	bool spielEinladungAbbrechen( int gruppeId, int accountId );
	bool spielEinladungAblehnen( int gruppeId );
	// constant
	int getAccountId() const;
	Text *getLetzterFehler() const;
	Text *zLetzterFehler() const;
	// Reference Counting
	MsgWeiterleitung *getThis();
	MsgWeiterleitung *release();
};

#endif