#ifndef RenderThread_H
#define RenderThread_H

#include "Thread.h"
#include "Critical.h"
#include <functional>

namespace Framework
{
    class Bildschirm; // Bildschirm.h
    class ZeitMesser; // ZeitMesser.h
    class Bild; // Bild.h

    // Ein Thread, der ein Bildschirm verwaltet. Er ruft die render() und tick() funktionen automatisch auf
    class RenderTh : public Thread
    {
    private:
        bool stoppen;
        Bildschirm *bildschirm;
        ZeitMesser *zeit;
        double renderTickZeit;
        void *renderParameter;
        void *tickParameter;
        std::function< void( void*, void*, Bild* ) > renderFunktion;
        std::function< void( void*, void*, double ) > tickFunktion;
        bool pause;
        Critical cs;
        int maxFps;

    public:
        // Konstruktor 
        __declspec( dllexport ) RenderTh();
        // Destruktor 
        __declspec( dllexport ) ~RenderTh();
        // Dies ist notwendig, falls mehrere Threads gleichzeitig das Objekt benutzen.
        // Wenn lock() von zwei threads aufgerufen wird, wartet der letzte so lange, bis der erste unlock() aufgerufen hat.
        __declspec( dllexport ) void lock();
        // Dies ist notwendig, falls mehrere Threads gleichzeitig das Objekt benutzen.
        // Wenn lock() von zwei threads aufgerufen wird, wartet der letzte so lange, bis der erste unlock() aufgerufen hat.
        __declspec( dllexport ) void unlock();
        // Setzt das Bildschirm Objekt, das verwaltet werden soll
        //  bildschirm: Der Bildschirm
        __declspec( dllexport ) void setBildschirm( Bildschirm *bildschirm );
        // Die Funktion, die automatisch in einem neuen Thread ausgef�hrt wird
        __declspec( dllexport ) void thread() override;
        // Beginnt den Render Thread
        __declspec( dllexport ) void beginn();
        // Beendet den Render Thread
        __declspec( dllexport ) void beenden();
        // Setzt die maximalen Bilder pro Sekunde
        //  fps: maximale Bilder pro Sekunde
        __declspec( dllexport ) void setMaxFps( int fps );
        // Pausiert den Render Thread
        //  p: 1, wenn der Thread pausiert werden soll
        __declspec( dllexport ) void setPause( bool p );
        // Setzt die R�ckruffunktion, die immer vor dem Zeichnen aufgerufen wird
        //  rF: Die R�ckruffunktion
        __declspec( dllexport ) void setRenderFunktion( std::function< void( void*, void*, Bild* ) > rF );
        // Setzt die R�ckruffunktion, die immer vor dem Aktualisieren aller Objekte aufgerufen wird
        //  tF: Die R�ckruffunktion
        __declspec( dllexport ) void setTickFunktion( std::function< void( void*, void*, double ) > tF );
        // Setzt den Parameter der R�ckruffunktion, die immer vor dem Zeichnen aufgerufen wird
        //  p: Der Parameter
        __declspec( dllexport ) void setRenderFunktionParameter( void *p );
        // Setzt den Parameter der R�ckruffunktion, die immer vor dem Aktualisieren aller Objekte aufgerufen wird
        __declspec( dllexport ) void setTickFunktionParameter( void *p );
        // Gibt den Bildschirm zur�ck, der von dem Thread verwaltet wird
        __declspec( dllexport ) Bildschirm *getBildschirm() const;
        // Gibt den Bildschirm ohne erh�hten Reference Counter zur�ck, der von dem Thread verwaltet wird
        __declspec( dllexport ) Bildschirm *zBildschirm() const;
        // Gibt die Zeit zur�ck, mit der die tick() Funktion des Bildschirms als letztes aufgerufen wurde
        __declspec( dllexport ) double getRenderTickZeit() const;
    };
}

#endif