#ifndef LoginServer_H
#define LoginServer_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 LSKlient;

class LoginServer : public Thread
{
private:
    Server *server;
    SSLServer *aServer;
    InitDatei *ini;
    LSDatenbank *db;
    CRITICAL_SECTION cs;
    RCArray< LSKlient > *klients;
    Text *fehler;
    int id;
    bool nichtPausiert;
    int empfangen;
    int gesendet;
    bool end;

public:
    // Konstruktor 
    LoginServer( InitDatei *zIni );
    // Destruktor 
    virtual ~LoginServer();
    // 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( LSKlient *zKlient );
    void addGesendet( int bytes );
    void addEmpfangen( int bytes );
    // conatant 
    bool istAn() const;
    Server *zServer() const;
    LSDatenbank *zDB() const;
    bool hatClients() const;
    int getId() const;
    char *getLetzterFehler() const;
};

class LSAKlient : public Thread
{
private:
    SSLSKlient *klient;
    Text *name;
    Text *passwort;
    int adminId;
    LoginServer *ls;
    int version;

public:
    // Konstruktor 
    LSAKlient( SSLSKlient *klient, LoginServer *ls );
    // Destruktor 
    virtual ~LSAKlient();
    // nicht constant
    void thread();
    void errorZuKlient( const char *nachricht ) const; // sendet eine Fehlernachricht zum AKlient
};

class LSKlient : public Thread
{
private:
    SKlient *klient;
    unsigned int klientNummer;
    LoginServer *ls;

public:
    // Konstruktor 
    LSKlient( SKlient *klient, LoginServer *ls );
    // Destruktor 
    virtual ~LSKlient();
    // nicht constant 
    void absturz();
    void thread();
    // constant
    void errorZuKlient( const char *nachricht ) const; // sendet eine Fehlernachricht zum Klient
    int getKlientNummer() const;
};

class MSGWeiterleitung : public virtual ReferenceCounter
{
private:
    LoginServer *ls;

public:
    // Konstruktor
    MSGWeiterleitung( LoginServer *ls );
    // Destruktor
    ~MSGWeiterleitung();
    // nicht constant
    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 );
};

#endif