#pragma once

#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 MSKlient;

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

public:
    // Konstruktor 
    MinigameServer( InitDatei *zIni );
    // Destruktor 
    virtual ~MinigameServer();
    // 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( MSKlient *zKlient );
    void addGesendet( int bytes );
    void addEmpfangen( int bytes );
    // conatant 
    bool istAn() const;
    Server *zServer() const;
    MSDatenbank *zDB() const;
    bool hatClients() const;
    int getId() const;
    char *getLetzterFehler() const;
    InitDatei *zInit() const;
    // Reference Counting
    MinigameServer *getThis();
    MinigameServer *release();
};

class MSAKlient : public Thread
{
private:
    SKlient *klient;
    Text *name;
    Text *passwort;
    int adminId;
    MinigameServer *ms;
    int version;

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

class MSKlient : public Thread
{
private:
    SKlient     *klient;
    unsigned int klientNummer;
    MinigameServer *ms;
    int ref;

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