#ifndef AppServer_H
#define AppServer_H

#include <Server.h>
#include <Thread.h>
#include <InitDatei.h>
#include <Zeit.h>
#include "Datenbank.h"

using namespace Framework;
using namespace Network;

class AppSKTimeOut;

class AppServer : public Thread
{
private:
    Server *server;
    SSLServer *aServer;
    InitDatei *dat;
    AppSDatenbank *db;
    CRITICAL_SECTION cs;
    int empfangen;
    int gesendet;
    int clients;
    bool end;
    int ref;

public:
    // Konstruktor 
    AppServer( InitDatei *zDat );
    // Destruktor 
    virtual ~AppServer();
    // nicht constant 
    void runn();
    void thread();
    void close();
    bool serverStarten();
    void serverBeenden();
    void addGesendet( int bytes );
    void addEmpfangen( int bytes );
    void clientTrennung();
    // constant 
    InitDatei *zIni() const;
    Server *zServer() const;
    AppSDatenbank *zDB() const;
    int getClients() const;
    bool hatClients() const;
    // Reference Counting
    AppServer *getThis();
    AppServer *release();
};

class AppSAKlient : public Thread
{
private:
    SSLSKlient *klient;
    Text *name;
    Text *passwort;
    int adminId;
    AppServer *appS;

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

class AppSKlient : public Thread
{
private:
    SKlient *klient;
    AppServer *appS;
    int accountId;
    AppSKTimeOut *tmo;

public:
    // Konstruktor 
    AppSKlient( SKlient *klient, AppServer *appS );
    // Destruktor 
    virtual ~AppSKlient();
    // nicht constant 
    void thread() override;
    void timeout();
    void errorZuKlient( const char *nachricht ) const; // sendet eine Fehlernachricht zum Klient
};

class AppSKTimeOut : public Thread
{
private:
    __int64 lastConnect;
    AppSKlient *zKlient;
    ZeitMesser *zm;
    bool st;

public:
    // Konstruktor
    AppSKTimeOut( AppSKlient *zK );
    // Destruktor
   virtual  ~AppSKTimeOut();
    // nicht constant
    void thread() override;
    void stop();
    void addConnect();
};

#endif