#ifndef RenderThread_H
#define RenderThread_H

#include <functional>

#include "Critical.h"
#include "Thread.h"

namespace Framework
{
    class Screen; //! Screen.h
    class Timer;  //! Timer.h
    class Image;  //! Image.h

    //! A thread that manages a screen. It calls the render() and
    //! tick() functions automatically
    class RenderTh : public Thread
    {
    private:
        bool stop;
        Screen* screen;
        Timer* timer;
        double renderTickTime;
        void* renderParameter;
        void* tickParameter;
        std::function<void(void*, void*, Image*)> renderFunktion;
        std::function<void(void*, void*, double)> tickFunktion;
        bool pause;
        ReadWriteLock rwLock;
        int maxFps;
        bool quiet;

    public:
        //! Constructor
        DLLEXPORT RenderTh();
        //! Destructor
        DLLEXPORT ~RenderTh();
        //! returns a lock for reading the object.
        DLLEXPORT Lock& readLock();
        //! returns a lock for writing the object.
        DLLEXPORT Lock& writeLock();
        //! Sets the screen object to be managed
        //! \param screen The screen
        DLLEXPORT void setScreen(Screen* screen);
        //! The function that is automatically executed in a new thread
        DLLEXPORT void thread() override;
        //! Starts the render thread
        DLLEXPORT void beginn();
        //! Stops the render thread
        DLLEXPORT void terminate();
        //! if true, then nothing will be printed to std::cout
        DLLEXPORT void setQuiet(bool quiet);
        //! Sets the maximum frames per second
        //! \param fps Maximum frames per second
        DLLEXPORT void setMaxFps(int fps);
        //! Pauses the render thread
        //! \param p 1 if the thread should be paused
        DLLEXPORT void setPause(bool p);
        //! Sets the callback function that is always called before drawing
        //! \param rF The callback function
        DLLEXPORT void setRenderFunktion(
            std::function<void(void*, void*, Image*)> rF);
        //! Sets the callback function that is always called before updating
        //! all objects \param tF The callback function
        DLLEXPORT void setTickFunktion(
            std::function<void(void*, void*, double)> tF);
        //! Sets the parameter of the callback function that is always called
        //! before drawing \param p The parameter
        DLLEXPORT void setRenderFunktionParameter(void* p);
        //! Sets the parameter of the callback function that is always called
        //! before updating all objects
        DLLEXPORT void setTickFunktionParameter(void* p);
        //! Returns the screen managed by this thread
        DLLEXPORT Screen* getScreen() const;
        //! Returns the screen without increased reference counter managed
        //! by this thread
        DLLEXPORT Screen* zScreen() const;
        //! Returns the time with which the tick() function of the screen
        //! was last called
        DLLEXPORT double getRenderTickZeit() const;
    };
} // namespace Framework

#endif