#ifndef Animation_H
#define Animation_H

#include "Critical.h"
#include "Zeichnung.h"

namespace Framework
{
    class Bild;      //! Bild.h
    class LTDBDatei; //! DateiSystem.h
    class InitDatei; //! InitDatei.h
    class Rahmen;    //! Rahmen.h

    //! Enthält alle Bilder einer Video Animation
    class Animation2DData : public virtual ReferenceCounter
    {
    private:
        Bild** bilder;
        int bildAnzahl;
        int fps;
        bool wiederhohlen;
        bool transparent;
        Critical cs;

    public:
        //! Konstruktor
        DLLEXPORT Animation2DData();
        //! Destruktor
        DLLEXPORT ~Animation2DData();
        //! Dies ist notwendig, falls mehrere Threads gleichzeitig dieses Objekt
        //! benutzen. Wenn lock() von zwei threads aufgerufen wird, wartet der
        //! letzte so lange, bis der erste unlock() aufgerufen hat.
        DLLEXPORT void lock();
        //! Dies ist notwendig, falls mehrere Threads gleichzeitig dieses Objekt
        //! benutzen. Wenn lock() von zwei threads aufgerufen wird, wartet der
        //! letzte so lange, bis der erste unlock() aufgerufen hat.
        DLLEXPORT void unlock();
        //! Lädt alle Bilder aus einer InitDatei ein. Auch die Werte 'fps',
        //! 'wiederhohlen' (true, false), 'transparent' (true, false) werden
        //! interpretiert. Die Bilder müssen in der richtiegen Reihenfolge in
        //! der Datei stehen. Der Name der Werte ist egal undder Wert ist der
        //! Pfad zur ltdb Datei mit /bildname hinten drann Beispiel: fps=30
        //!           x=a.ltdb\aaaa.jpg
        //!           y=a.ltdb\aaab.jpg
        //! \param datei Die bereits eingelesene InitDatei
        DLLEXPORT void ladeAnimation(InitDatei* datei);
        //! Lädt alle Bilder aus einer LTDB Datei der reihenfolge nach ein, in
        //! der sie gespeichert sind. \param datei Die LTDB Datei
        DLLEXPORT void ladeAnimation(LTDBDatei* datei);
        //! Setzt die Bilder pro Sekunde der Video Animation
        //! \param fps Die Anzahl an Bildern pro Sekunde
        DLLEXPORT void setFPS(int fps);
        //! Legt fest, ob die Animation sich wiederhohlt, wenn sie am ende
        //! angelangt ist \param wh 1, wenn sich die Animation wiederhohlen soll
        DLLEXPORT void setWiederhohlend(bool wh);
        //! Legt fest, ob beim Zeichnen der Bilder Alphablending benutzt werden
        //! soll \param trp 1, wenn Alphablending benutzt werden soll
        DLLEXPORT void setTransparent(bool trp);
        //! Löscht alle Bilder aus der Animation und setzt alle Werte auf die
        //! Standartwerte zurück
        DLLEXPORT void reset();
        //! Gibt ein Bestimmtes Bild der Animation zurück
        //! \param i Der Index des Bildes
        DLLEXPORT Bild* getBild(int i) const;
        //! Gibt ein Bestimmtes Bild der Animation ohne erhöhten Reference
        //! Counter zurück \param i Der Index des Bildes
        DLLEXPORT Bild* zBild(int i) const;
        //! Gibt die Anzahl der Bilder in der Animation zurück
        DLLEXPORT int getBildAnzahl() const;
        //! Gibt die Anzahl an Bildern pro Sekunde zurück
        DLLEXPORT int getFPS() const;
        //! Gibt zurück, ob sich die Animation wiederhohlt, wenn sie beim
        //! letzten Bild angelangt ist
        DLLEXPORT bool istWiederhohlend() const;
        //! Gibt zurück, ob beim Zeichnen der Bilder Alphablending benutzt wird
        DLLEXPORT bool istTransparent() const;
    };

    //! Eine Zeichnung, die eine Video Animation zeichnet
    class Animation2D : public Zeichnung
    {
    private:
        Animation2DData* data;
        int jetzt;
        double ausgleich;
        unsigned char alpha;
        unsigned char maxAlpha;
        bool rahmen;
        Rahmen* ram;
        int aps;
        bool sichtbar;

    public:
        //! Konstruktor
        DLLEXPORT Animation2D();
        //! Destruktor
        DLLEXPORT virtual ~Animation2D();
        //! Legt fest, ob ein Rahmen um die Animation gezeichnet werden soll
        //! \param ram 1, wenn ein Rahmen gezeichnet werden soll
        DLLEXPORT void setRahmen(bool ram);
        //! Setzt einen Zeiger auf den verfenteten Rahmen
        //! \param ram Der Rahmen
        DLLEXPORT void setRahmenZ(Rahmen* ram);
        //! Setzt die Breite des Rahmens
        //! \param br Die Breite in Pixeln
        DLLEXPORT void setRahmenBreite(int br);
        //! Setzt die Farbe des Rahmens
        //! \param fc Die Farbe im A8R8G8B8 Format
        DLLEXPORT void setRahmenFarbe(int fc);
        //! Setzt die Animation, die Angezeigt werden soll
        //! \param data Die Animationsdaten
        DLLEXPORT void setAnimationDataZ(Animation2DData* data);
        //! Setzt die Transparenz der gesammten Animation
        //! \param alpha Die Transparenz
        DLLEXPORT void setAlphaMaske(unsigned char alpha);
        //! Setzt die Geschwindigkeit, in der die Animation ein und ausgeblendet
        //! wird \param aps Alpha pro sekunde
        DLLEXPORT void setAPS(int aps);
        //! Setzt die Sichtbarkeit der Animation
        //! \param sichtbar 1, wenn die Animation eingeblendet werden soll. 0,
        //! wenn sie ausgeblendet werden soll
        DLLEXPORT void setSichtbar(bool sichtbar);
        //! Verarbeitet die Zeit, die seit dem letzten aufruf dieser Funktion
        //! vergangen ist \param zeit Die vergangene Zeit in Sekunden
        DLLEXPORT bool tick(double zeit) override;
        //! Zeichnet die Animation in ein bestimmtes Bild
        //! \param zRObj Das Bild, in das gezeichnet werden soll
        DLLEXPORT void render(Bild& zRObj) override;
        //! Gibt die Animationsdaten zurück
        DLLEXPORT Animation2DData* getAnimationData() const;
        //! Gibt die Animationsdaten ohne erhöhten Reference Counter zurück
        DLLEXPORT Animation2DData* zAnimationData() const;
        //! Gibt zurück ob die Animation sichtbar ist
        DLLEXPORT bool istSichtbar() const;
        //! Gibt den Index des aktuell angezeigten Bildes zurück
        DLLEXPORT int getJetzt() const;
        //! Gibt die Transparenz der Animation zurück
        DLLEXPORT unsigned char getAlphaMaske() const;
        //! Gibt zurück, ob ein Rahmen um die Animation gezeichnet wird
        DLLEXPORT bool hatRahmen() const;
        //! Gibt den Rahmen der Animation zurück
        DLLEXPORT Rahmen* getRahmen() const;
        //! Gibt den Rahmen der Animation ohne erhöhten Reference Counter zurück
        DLLEXPORT Rahmen* zRahmen() const;
        //! Gibt die Breite des Rahmens in Pixeln zurück
        DLLEXPORT int getRahmenBreite() const;
        //! Gibt die Farbe des Rahmens im A8R8G8B8 Format zurück
        DLLEXPORT int getRahmenFarbe() const;
        //! Kopiert die Animation, so dass sie ohne auswirkungen auf das
        //! Original verändert werden kann
        DLLEXPORT Zeichnung* dublizieren() const override;
    };
} // namespace Framework

#endif