#ifndef Animation_H
#define Animation_H

#include "Critical.h"
#include "Drawing.h"

namespace Framework
{
    class Image;    //! Image.h
    class LTDBFile; //! FileSystem.h
    class InitFile; //! InitFile.h
    class Border;   //! Border.h

    //! Contains all images of a video animation
    class Animation2DData : public virtual ReferenceCounter
    {
    private:
        Image** bilder;
        int imageCount;
        int fps;
        bool repeat;
        bool transparent;
        ReadWriteLock rwLock;

    public:
        //! Constructor
        DLLEXPORT Animation2DData();
        //! Destructor
        DLLEXPORT ~Animation2DData();
        //! returns a lock for reading the animation data.
        DLLEXPORT Lock& readLock();
        //! returns a lock for writing the animation data.
        DLLEXPORT Lock& writeLock();
        //! Loads all images from an InitFile. The values 'fps',
        //! 'repeat' (true, false), 'transparent' (true, false) are also
        //! interpreted. The images must be in the correct order in the file.
        //! The name of the values does not matter, the value is the path to
        //! the ltdb file with /imagename appended. Example: fps=30
        //!           x=a.ltdb\aaaa.jpg
        //!           y=a.ltdb\aaab.jpg
        //! \param datei The already loaded InitFile
        DLLEXPORT void loadAnimation(InitFile* datei);
        //! Loads all images from an LTDB file in the order they are stored.
        //! \param datei The LTDB file
        DLLEXPORT void loadAnimation(LTDBFile* datei);
        //! Sets the frames per second of the video animation
        //! \param fps The number of frames per second
        DLLEXPORT void setFPS(int fps);
        //! Sets whether the animation repeats when it reaches the end
        //! \param wh 1 if the animation should repeat
        DLLEXPORT void setWiederhohlend(bool wh);
        //! Sets whether alpha blending should be used when drawing the images
        //! \param trp 1 if alpha blending should be used
        DLLEXPORT void setTransparent(bool trp);
        //! Deletes all images from the animation and resets all values to
        //! their defaults
        DLLEXPORT void reset();
        //! Returns a specific image of the animation
        //! \param i The index of the image
        DLLEXPORT Image* getImage(int i) const;
        //! Returns a specific image of the animation without increasing the
        //! reference counter
        //! \param i The index of the image
        DLLEXPORT Image* zImage(int i) const;
        //! Returns the number of images in the animation
        DLLEXPORT int getImageCount() const;
        //! Returns the number of frames per second
        DLLEXPORT int getFPS() const;
        //! Returns whether the animation repeats when it reaches the last
        //! image
        DLLEXPORT bool isRepeating() const;
        //! Returns whether alpha blending is used when drawing the images
        DLLEXPORT bool isTransparent() const;
    };

    //! A drawing that renders a video animation
    class Animation2D : public Drawable
    {
    private:
        Animation2DData* data;
        int now;
        double compensation;
        unsigned char alpha;
        unsigned char maxAlpha;
        bool border;
        Border* ram;
        int aps;
        bool visible;

    public:
        //! Constructor
        DLLEXPORT Animation2D();
        //! Destructor
        DLLEXPORT virtual ~Animation2D();
        //! Sets whether a border should be drawn around the animation
        //! \param ram 1 if a border should be drawn
        DLLEXPORT void setBorder(bool ram);
        //! Sets a pointer to the used border
        //! \param ram The border
        DLLEXPORT void setBorderZ(Border* ram);
        //! Sets the width of the border
        //! \param br The width in pixels
        DLLEXPORT void setBorderWidth(int br);
        //! Sets the color of the border
        //! \param fc The color in A8R8G8B8 format
        DLLEXPORT void setBorderColor(int fc);
        //! Sets the animation to be displayed
        //! \param data The animation data
        DLLEXPORT void setAnimationDataZ(Animation2DData* data);
        //! Sets the transparency of the entire animation
        //! \param alpha The transparency
        DLLEXPORT void setAlphaMaske(unsigned char alpha);
        //! Sets the speed at which the animation fades in and out
        //! \param aps Alpha per second
        DLLEXPORT void setAPS(int aps);
        //! Sets the visibility of the animation
        //! \param visible 1 if the animation should be shown, 0 if it should
        //! be hidden
        DLLEXPORT void setVisible(bool visible);
        //! Processes the time that has passed since the last call of this
        //! function
        //! \param zeit The elapsed time in seconds
        DLLEXPORT bool tick(double zeit) override;
        //! Draws the animation into a specific image
        //! \param zRObj The image to draw into
        DLLEXPORT void render(Image& zRObj) override;
        //! Returns the animation data
        DLLEXPORT Animation2DData* getAnimationData() const;
        //! Returns the animation data without increasing the reference counter
        DLLEXPORT Animation2DData* zAnimationData() const;
        //! Returns whether the animation is visible
        DLLEXPORT bool isVisible() const;
        //! Returns the index of the currently displayed image
        DLLEXPORT int getJetzt() const;
        //! Returns the transparency of the animation
        DLLEXPORT unsigned char getAlphaMaske() const;
        //! Returns whether a border is drawn around the animation
        DLLEXPORT bool hasBorder() const;
        //! Returns the border of the animation
        DLLEXPORT Border* getBorder() const;
        //! Returns the border of the animation without increasing the
        //! reference counter
        DLLEXPORT Border* zBorder() const;
        //! Returns the width of the border in pixels
        DLLEXPORT int getBorderWidth() const;
        //! Returns the color of the border in A8R8G8B8 format
        DLLEXPORT int getBorderColor() const;
        //! Copies the animation so that it can be modified without
        //! affecting the original
        DLLEXPORT Drawable* duplicate() const override;
    };
} // namespace Framework

#endif