#ifndef Bild_H
#define Bild_H

#include "Array.h"
#include "Punkt.h"
#include "Zeichnung.h"

namespace Framework
{
    class Bild; //! from this file
#ifdef WIN32
    class VScrollBar;    //! Scroll.h
    class HScrollBar;    //! Scroll.h
    class Rahmen;        //! Rahmen.h
    struct MausEreignis; //! MausEreignis.h
    class Text;          //! Text.h
#endif

    //! Manages an image as an array of pixel colors in A8R8G8B8 format
    //! that can be drawn to
    class Bild : public virtual ReferenceCounter
    {
    private:
        int* fc;
        bool delFc;
        Punkt size;
        Punkt* drawOff;
        Punkt* dPosA;
        Punkt* dSizeA;
        int doa;
        unsigned char* alpha;
        int alphaAnzahl;
        bool rend;
        bool alpha3D;

        //! private
        inline void alphaPixelP(int x, int y, int f);
        inline void alphaPixelP3D(int x, int y, int f);
        inline void alphaPixelP(int& fc, int f);
        inline void alphaPixelP3D(int& fc, int f);
        inline void alphaPixelAssozP(int& fc, int f);
        inline char getOutCode(Punkt p) const;
        void drawFlatDreieck(
            int y1, int y2, float m1, float b1, float m2, float b2, int farbe);
        void drawFlatDreieckTextur(int y1,
            int y2,
            double m1,
            double b1,
            double m2,
            double b2,
            double tx1,
            double ty1,
            double tx2,
            double ty2,
            double tx_1o,
            double ty_1o,
            double tx_2o,
            double ty_2o,
            double txf,
            double tyf,
            const Bild& textur);
        void drawFlatDreieckAlpha(
            int y1, int y2, float m1, float b1, float m2, float b2, int farbe);
        void drawFlatDreieckTexturAlpha(int y1,
            int y2,
            double m1,
            double b1,
            double m2,
            double b2,
            double tx1,
            double ty1,
            double tx2,
            double ty2,
            double tx_1o,
            double ty_1o,
            double tx_2o,
            double ty_2o,
            double txf,
            double tyf,
            const Bild& textur);
        void drawLinieHTextur(Vec2<double> p,
            double length,
            Vec2<double> ta,
            Vec2<double> tb,
            double txo,
            double tyo,
            const Bild& textur);
        void drawLinieHTexturAlpha(Vec2<double> p,
            double length,
            Vec2<double> ta,
            Vec2<double> tb,
            double txo,
            double tyo,
            const Bild& textur);

    public:
        //! Constructor
        //! \param options 1 if the image should create buffers for drawing,
        //! such as for temporary drawing area boundaries and
        //! transparency filters
        //!  Uses about 50 kb more memory per image
        DLLEXPORT Bild(bool options = 0);
        //! Destructor
        DLLEXPORT ~Bild();
        //! Checks whether a rectangle is fully or partially within the drawing
        //! area.
        //!  return 0 if the rectangle is not in the drawing area, 1 otherwise
        DLLEXPORT bool isAreaDrawable(int x, int y, int width, int height);
        //! If this flag is set, when alpha blending and the previous color
        //! is 0, the new color is only copied with its alpha value.
        //! This is useful for use in the 3D screen, where the drawn image
        //! is later displayed using alpha blending. The flag is set
        //! automatically in the 3D screen
        DLLEXPORT void setAlpha3D(bool erlaubt);
        //! Sets the minimum transparency of everything drawn next,
        //! until the corresponding releaseAlpha() call is made.
        DLLEXPORT void setAlpha(unsigned char alpha);
        //! Removes the last alpha limit set with setAlpha()
        DLLEXPORT void releaseAlpha();
        //! Setzt einen Zeiger auf die Pixel, in die gezeichnet werden soll
        //! \param buffer Ein Array mit den A8R8G8B8 Farbwerten
        //! \param deleteBuffer 1, fals der Array vom Bild geloescht werden soll
        //! \param breite Die Breite in Pixeln
        //! \param height Die Hoehe in Pixeln
        DLLEXPORT void setPixelBuffer(
            int* buffer, bool deleteBuffer, int breite, int height);
        //! Erstellt ein neues Bild
        //! \param breite Die Breite des Bildes in Pixeln
        //! \param hoehe Die Hoehe des Bildes in Pixeln
        //! \param fillColor Die startfarbe, auf die alle Pixel gesetzt werden
        DLLEXPORT void neuBild(int breite, int height, int fillColor);
        //! Blendet mittels Alphablending eine Farbe auf einen bestimmten Pixel
        //! Beachtet nicht die begrenzung der Zeichnenflaeche und das Skroll
        //! Offset \param x Die X Koordinate des Pixels \param y Die Y
        //! Koordinate des Pixels \param f Die Farbe in A8R8G8B8 Format, die
        //! geblendet werden soll
        DLLEXPORT void alphaPixel2D(int x, int y, int f);
        DLLEXPORT void alphaPixel3D(int x, int y, int f);
        //! Blendet mittels Alphablending eine Farbe auf einen bestimmten Pixel
        //! Beachtet nicht die begrenzung der Zeichnenflaeche und das Skroll
        //! Offset \param i Der Index des Pixels im Pixel Array \param f Die
        //! Farbe in A8R8G8B8 Format, die geblendet werden soll
        DLLEXPORT void alphaPixel2D(int i, int f);
        DLLEXPORT void alphaPixel3D(int i, int f);
        //! Blendet mittels Alphablending eine Farbe auf einen bestimmten Pixel
        //! \param x Die X Koordinate des Pixels
        //! \param y Die Y Koordinate des Pixels
        //! \param f Die Farbe in A8R8G8B8 Format, die geblendet werden soll
        DLLEXPORT void alphaPixelDP2D(int x, int y, int f);
        DLLEXPORT void alphaPixelDP3D(int x, int y, int f);
        //! Blendet mittels Alphablending eine Farbe auf einen bestimmten Pixel
        //! \param i Der Index des Pixels im Pixel Array
        //! \param f Die Farbe in A8R8G8B8 Format, die geblendet werden soll
        DLLEXPORT void alphaPixelDP2D(int i, int f);
        DLLEXPORT void alphaPixelDP3D(int i, int f);
        //! Setzt die Farbe eines besimmten Pixels
        //! \param x Die X Koordinate des Pixels
        //! \param y Die Y Koordinate des Pixels
        //! \param f Die neue Farbe in A8R8G8B8 Format
        DLLEXPORT void setPixelDP(int x, int y, int f);
        //! Setzt die Farbe eines besimmten Pixels
        //! \param i Der Index des Pixels im Pixel Array
        //! \param f Die neue Farbe in A8R8G8B8 Format
        DLLEXPORT void setPixelDP(int i, int f);
        //! Setzt die Farbe aller Pixel des Bildes
        //! \param f Die neue Farbe
        DLLEXPORT void setFarbe(int f);
        //! Setzt die Farben aller Pixel in einem Rechteck
        //! \param x Die X Koordinate
        //! \param y Die Y Koordinate
        //! \param b Die Breite des Rechtecks
        //! \param h Die Hoehe des Rechtecks
        //! \param fc Die Farbe im A8R8G8B8 Format
        DLLEXPORT void fillRegion(int x, int y, int b, int h, int fc);
        //! Blendet eine Farbe mit Alphablending in einem Rechteck
        //! \param x Die X Koordinate
        //! \param y Die Y Koordinate
        //! \param b Die Breite des Rechtecks
        //! \param h Die Hoehe des Rechtecks
        //! \param fc Die Farbe im A8R8G8B8 Format
        DLLEXPORT void alphaRegion(int x, int y, int b, int h, int fc);
        //! Zeichnet eine horizontale Linie
        //! \param x Die X Koordinate des Startpunktes der Linie
        //! \param y Die Y Koordinate des Startpunktes der Linie
        //! \param length Die Laenge der Linie
        //! \param fc Die Farbe im A8R8G8B8 Format
        DLLEXPORT void drawLinieH(int x, int y, int length, int fc);
        //! Zeichnet eine vertikale Linie
        //! \param x Die X Koordinate des Startpunktes der Linie
        //! \param y Die Y Koordinate des Startpunktes der Linie
        //! \param length Die Laenge der Linie
        //! \param fc Die Farbe im A8R8G8B8 Format
        DLLEXPORT void drawLinieV(int x, int y, int length, int fc);
        //! Zeichnet eine horizontale Linie mit Alpha blending
        //! \param x Die X Koordinate des Startpunktes der Linie
        //! \param y Die Y Koordinate des Startpunktes der Linie
        //! \param length Die Laenge der Linie
        //! \param fc Die Farbe im A8R8G8B8 Format
        DLLEXPORT void drawLinieHAlpha(int x, int y, int length, int fc);
        //! Zeichnet eine vertikale Linie mit Alpha Blending
        //! \param x Die X Koordinate des Startpunktes der Linie
        //! \param y Die Y Koordinate des Startpunktes der Linie
        //! \param length Die Laenge der Linie
        //! \param fc Die Farbe im A8R8G8B8 Format
        DLLEXPORT void drawLinieVAlpha(int x, int y, int length, int fc);
        //! Zeichnet eine Linie
        //! \param a Der Startpunkt der Linie
        //! \param b der Endpunkt der Linie
        //! \param fc Die Farbe im A8R8G8B8 Format
        DLLEXPORT void drawLinieBordered(Punkt a, Punkt b, int bc, int fc);
        //! Zeichnet eine Linie
        //! \param a Der Startpunkt der Linie
        //! \param b der Endpunkt der Linie
        //! \param fc Die Farbe im A8R8G8B8 Format
        DLLEXPORT void drawLinieBorderedAlpha(Punkt a, Punkt b, int bc, int fc);
        //! Zeichnet eine Linie
        //! \param a Der Startpunkt der Linie
        //! \param b der Endpunkt der Linie
        //! \param fc Die Farbe im A8R8G8B8 Format
        DLLEXPORT void drawLinie(Punkt a, Punkt b, int fc);
        //! Zeichnet eine Linie mit Alpha Blending
        //! \param a Der Startpunkt der Linie
        //! \param b der Endpunkt der Linie
        //! \param fc Die Farbe im A8R8G8B8 Format
        DLLEXPORT void drawLinieAlpha(Punkt a, Punkt b, int fc);
        //! Fuellt einen Kreis mit einer Farbe. (Unfertig)
        //! \param xOff Die X Koordinate des Kreismittelpunktes
        //! \param yOff Die Y Koordinate des Kreismittelpunktes
        //! \param r Der Radius des Kreises in Pixeln
        //! \param fc Die Farbe im A8R8G8B8 Format
        DLLEXPORT void fillCircle(int xOff, int yOff, int r, int fc);
        //! Zeichnet den Umriss eines Kreises
        //! \param xOff Die X Koordinate des Kreismittelpunktes
        //! \param yOff Die Y Koordinate des Kreismittelpunktes
        //! \param r Der Radius des Kreises in Pixeln
        //! \param fc Die Farbe im A8R8G8B8 Format
        DLLEXPORT void drawKreis(int xOff, int yOff, int r, int fc);
        //! Zeichnet den Umriss eines Kreises mit Alpha Blending
        //! \param xOff Die X Koordinate des Kreismittelpunktes
        //! \param yOff Die Y Koordinate des Kreismittelpunktes
        //! \param r Der Radius des Kreises in Pixeln
        //! \param fc Die Farbe im A8R8G8B8 Format
        DLLEXPORT void drawKreisAlpha(int xOff, int yOff, int r, int fc);
        //! Zeichnet ein Bild in ein bestimmtes Feld ohne Skallierung
        //! \param x Die X Koordinate der linken oberen Ecke des Rechtecks in
        //! dem das Bild gezeichnet werden soll \param y Die Y Koordinate der
        //! linken oberen Ecke des Rechtecks in dem das Bild gezeichnet werden
        //! soll \param br Die Breite des Rechecks in dem das Bild gezeichnet
        //! werden soll \param hi Die Hoehe des Rechecks in dem das Bild
        //! gezeichnet werden soll \param zBild Das Bild, was gezeichnet werden
        //! soll
        DLLEXPORT void drawBild(
            int x, int y, int br, int hi, const Bild& zBild);
        //! Zeichnet ein Bild in ein bestimmtes Feld ohne Skallierung mit alpha
        //! blending \param x Die X Koordinate der linken oberen Ecke des
        //! Rechtecks in dem das Bild gezeichnet werden soll \param y Die Y
        //! Koordinate der linken oberen Ecke des Rechtecks in dem das Bild
        //! gezeichnet werden soll \param br Die Breite des Rechecks in dem das
        //! Bild gezeichnet werden soll \param hi Die Hoehe des Rechecks in dem
        //! das Bild gezeichnet werden soll \param zBild Das Bild, was
        //! gezeichnet werden soll
        DLLEXPORT void alphaBild(
            int x, int y, int br, int hi, const Bild& zBild);
        //! Zeichnet ein Bild in ein bestimmtes Feld ohne Skallierung mit alpha
        //! blending \param x Die X Koordinate der linken oberen Ecke des
        //! Rechtecks in dem das Bild gezeichnet werden soll \param y Die Y
        //! Koordinate der linken oberen Ecke des Rechtecks in dem das Bild
        //! gezeichnet werden soll \param br Die Breite des Rechecks in dem das
        //! Bild gezeichnet werden soll \param hi Die Hoehe des Rechecks in dem
        //! das Bild gezeichnet werden soll \param zBild Das Bild, was
        //! gezeichnet werden soll
        DLLEXPORT void alphaBildAssoz(
            int x, int y, int br, int hi, const Bild& zBild);
        //! Zeichnet ein Bild um 90 grad nach rechts gedreht in ein bestimmtes
        //! Feld ohne Skallierung \param x Die X Koordinate der linken oberen
        //! Ecke des Rechtecks in dem das Bild gezeichnet werden soll \param y
        //! Die Y Koordinate der linken oberen Ecke des Rechtecks in dem das
        //! Bild gezeichnet werden soll \param br Die Breite des Rechecks in dem
        //! das Bild gezeichnet werden soll \param hi Die Hoehe des Rechecks in
        //! dem das Bild gezeichnet werden soll \param zBild Das Bild, was
        //! gezeichnet werden soll
        DLLEXPORT void drawBild90(
            int x, int y, int br, int hi, const Bild& zBild);
        //! Zeichnet ein Bild um 90 grad nach rechts gedreht in ein bestimmtes
        //! Feld ohne Skallierung mit alpha Blending \param x Die X Koordinate
        //! der linken oberen Ecke des Rechtecks in dem das Bild gezeichnet
        //! werden soll \param y Die Y Koordinate der linken oberen Ecke des
        //! Rechtecks in dem das Bild gezeichnet werden soll \param br Die
        //! Breite des Rechecks in dem das Bild gezeichnet werden soll \param hi
        //! Die Hoehe des Rechecks in dem das Bild gezeichnet werden soll \param
        //! zBild Das Bild, was gezeichnet werden soll
        DLLEXPORT void alphaBild90(
            int x, int y, int br, int hi, const Bild& zBild);
        //! Zeichnet ein Bild um 180 grad nach rechts gedreht in ein bestimmtes
        //! Feld ohne Skallierung \param x Die X Koordinate der linken oberen
        //! Ecke des Rechtecks in dem das Bild gezeichnet werden soll \param y
        //! Die Y Koordinate der linken oberen Ecke des Rechtecks in dem das
        //! Bild gezeichnet werden soll \param br Die Breite des Rechecks in dem
        //! das Bild gezeichnet werden soll \param hi Die Hoehe des Rechecks in
        //! dem das Bild gezeichnet werden soll \param zBild Das Bild, was
        //! gezeichnet werden soll
        DLLEXPORT void drawBild180(
            int x, int y, int br, int hi, const Bild& zBild);
        //! Zeichnet ein Bild um 180 grad nach rechts gedreht in ein bestimmtes
        //! Feld ohne Skallierung mit alpha Blending \param x Die X Koordinate
        //! der linken oberen Ecke des Rechtecks in dem das Bild gezeichnet
        //! werden soll \param y Die Y Koordinate der linken oberen Ecke des
        //! Rechtecks in dem das Bild gezeichnet werden soll \param br Die
        //! Breite des Rechecks in dem das Bild gezeichnet werden soll \param hi
        //! Die Hoehe des Rechecks in dem das Bild gezeichnet werden soll \param
        //! zBild Das Bild, was gezeichnet werden soll
        DLLEXPORT void alphaBild180(
            int x, int y, int br, int hi, const Bild& zBild);
        //! Zeichnet ein Bild um 270 grad nach rechts gedreht in ein bestimmtes
        //! Feld ohne Skallierung \param x Die X Koordinate der linken oberen
        //! Ecke des Rechtecks in dem das Bild gezeichnet werden soll \param y
        //! Die Y Koordinate der linken oberen Ecke des Rechtecks in dem das
        //! Bild gezeichnet werden soll \param br Die Breite des Rechecks in dem
        //! das Bild gezeichnet werden soll \param hi Die Hoehe des Rechecks in
        //! dem das Bild gezeichnet werden soll \param zBild Das Bild, was
        //! gezeichnet werden soll
        DLLEXPORT void drawBild270(
            int x, int y, int br, int hi, const Bild& zBild);
        //! Zeichnet ein Bild um 270 grad nach rechts gedreht in ein bestimmtes
        //! Feld ohne Skallierung mit alpha Blending \param x Die X Koordinate
        //! der linken oberen Ecke des Rechtecks in dem das Bild gezeichnet
        //! werden soll \param y Die Y Koordinate der linken oberen Ecke des
        //! Rechtecks in dem das Bild gezeichnet werden soll \param br Die
        //! Breite des Rechecks in dem das Bild gezeichnet werden soll \param hi
        //! Die Hoehe des Rechecks in dem das Bild gezeichnet werden soll \param
        //! zBild Das Bild, was gezeichnet werden soll
        DLLEXPORT void alphaBild270(
            int x, int y, int br, int hi, const Bild& zBild);
        //! Zeichnet ein Bild in ein bestimmtes Feld mit Skallierung
        //! \param x Die X Koordinate der linken oberen Ecke des Rechtecks in
        //! dem das Bild gezeichnet werden soll \param y Die Y Koordinate der
        //! linken oberen Ecke des Rechtecks in dem das Bild gezeichnet werden
        //! soll \param br Die Breite des Rechecks in dem das Bild gezeichnet
        //! werden soll \param hi Die Hoehe des Rechecks in dem das Bild
        //! gezeichnet werden soll \param zBild Das Bild, was gezeichnet werden
        //! soll
        DLLEXPORT void drawBildSkall(
            int x, int y, int br, int hi, const Bild& zBild);
        //! Zeichnet ein Bild in ein bestimmtes Feld mit Skallierung mit Alpha
        //! Blending \param x Die X Koordinate der linken oberen Ecke des
        //! Rechtecks in dem das Bild gezeichnet werden soll \param y Die Y
        //! Koordinate der linken oberen Ecke des Rechtecks in dem das Bild
        //! gezeichnet werden soll \param br Die Breite des Rechecks in dem das
        //! Bild gezeichnet werden soll \param hi Die Hoehe des Rechecks in dem
        //! das Bild gezeichnet werden soll \param zBild Das Bild, was
        //! gezeichnet werden soll
        DLLEXPORT void alphaBildSkall(
            int x, int y, int br, int hi, const Bild& zBild);
        //! Fuellt ein Dreieck mit einer bestimmten Farbe
        //! \param a Eine Ecke des Dreiecks
        //! \param b Eine Ecke des Dreiecks
        //! \param c Eine Ecke des Dreiecks
        //! \param farbe die Farbe im A8R8G8B8 Format
        DLLEXPORT void drawDreieck(Punkt a, Punkt b, Punkt c, int farbe);
        //! Fuellt ein Dreieck mit einer bestimmten Textur
        //! \param a Eine Ecke des Dreiecks
        //! \param b Eine Ecke des Dreiecks
        //! \param c Eine Ecke des Dreiecks
        //! \param ta Die Koordinaten von a in der Textur
        //! \param tb Die Koordinaten von b in der Textur
        //! \param tc Die Koordinaten von c in der Textur
        //! \param textur Das Bild, was als Textur verwendet werden soll
        DLLEXPORT void drawDreieckTextur(Punkt a,
            Punkt b,
            Punkt c,
            Punkt ta,
            Punkt tb,
            Punkt tc,
            const Bild& textur);
        //! Fuellt ein Dreieck mit einer bestimmten Farbe mit alpha blending
        //! \param a Eine Ecke des Dreiecks
        //! \param b Eine Ecke des Dreiecks
        //! \param c Eine Ecke des Dreiecks
        //! \param farbe die Farbe im A8R8G8B8 Format
        DLLEXPORT void drawDreieckAlpha(Punkt a, Punkt b, Punkt c, int farbe);
        //! Fuellt ein Dreieck mit einer bestimmten Textur mit alpha blending
        //! \param a Eine Ecke des Dreiecks
        //! \param b Eine Ecke des Dreiecks
        //! \param c Eine Ecke des Dreiecks
        //! \param ta Die Koordinaten von a in der Textur
        //! \param tb Die Koordinaten von b in der Textur
        //! \param tc Die Koordinaten von c in der Textur
        //! \param textur Das Bild, was als Textur verwendet werden soll
        DLLEXPORT void drawDreieckTexturAlpha(Punkt a,
            Punkt b,
            Punkt c,
            Punkt ta,
            Punkt tb,
            Punkt tc,
            const Bild& textur);
        //! Ersetzt eine bestimmte Farbe durch Transparenz
        DLLEXPORT void replaceColorWithAlpha(int color);
        //! Begrenzt die Zeichenflaeche in die bis zum naechsten aufruf von
        //! releaseDrawOptions() gezeichnet werden kann. Alles ausserhalb der
        //! Flaeche wird automatisch ignoriert. Wenn die Zeichenflaeche ueber den
        //! Rand einer bestehenden Zeichenflaeche hinausragt, wird sie
        //! automatisch auf die bestehende Zeichnenflaeche beschnitten. \param
        //! pos Die Koordinaten der linken oberen Ecke der Zeichenflaeche \param
        //! gr Die Groesse der Zeichenflaeche \return 1, falls die neue
        //! Zeichenflaeche ganz oder teilweise innerhalb der bestehenden
        //! Zeichenflaeche ligt. Wenn 0 zurueckgegeben wird, wurde die
        //! Zeichenflaeche nicht gesetzt und es braucht nicht
        //! releaseDrawOptions() aufgerufen werden
        DLLEXPORT bool setDrawOptions(const Punkt& pos, const Punkt& gr);
        //! Begrenzt die Zeichenflaeche in die bis zum naechsten aufruf von
        //! releaseDrawOptions() gezeichnet werden kann. Alles ausserhalb der
        //! Flaeche wird automatisch ignoriert. Wenn die Zeichenflaeche ueber den
        //! Rand einer bestehenden Zeichenflaeche hinausragt, wird sie
        //! automatisch auf die bestehende Zeichnenflaeche beschnitten. \param x
        //! Die X Koordinate der linken oberen Ecke der Zeichenflaeche \param y
        //! Die X Koordinate der linken oberen Ecke der Zeichenflaeche \param br
        //! Die Breite der Zeichenflaeche \param hi Die Hoehe der Zeichenflaeche
        //! \return 1, falls die neue Zeichenflaeche ganz oder teilweise
        //! innerhalb der bestehenden Zeichenflaeche ligt. Wenn 0 zurueckgegeben
        //! wird, wurde die Zeichenflaeche nicht gesetzt und es braucht nicht
        //! releaseDrawOptions() aufgerufen werden
        DLLEXPORT bool setDrawOptions(int x, int y, int br, int hi);
        //! Begrenzt die Zeichenflaeche in die bis zum naechsten aufruf von
        //! releaseDrawOptions() gezeichnet werden kann. Alles ausserhalb der
        //! Flaeche wird automatisch ignoriert. Wenn die Zeichenflaeche darf ueber
        //! den Rand einer bestehenden Zeichenflaeche hinausragen \param pos Die
        //! Koordinaten der linken oberen Ecke der Zeichenflaeche \param gr Die
        //! Groesse der Zeichenflaeche \return 1, falls die neue Zeichenflaeche ganz
        //! oder teilweise innerhalb des Bildes ligt. Wenn 0 zurueckgegeben wird,
        //! wurde die Zeichenflaeche nicht gesetzt und es braucht nicht
        //! releaseDrawOptions() aufgerufen werden
        DLLEXPORT bool setDrawOptionsErzwingen(
            const Punkt& pos, const Punkt& gr);
        //! Begrenzt die Zeichenflaeche in die bis zum naechsten aufruf von
        //! releaseDrawOptions() gezeichnet werden kann. Alles ausserhalb der
        //! Flaeche wird automatisch ignoriert. Wenn die Zeichenflaeche darf ueber
        //! den Rand einer bestehenden Zeichenflaeche hinausragen \param x Die X
        //! Koordinate der linken oberen Ecke der Zeichenflaeche \param y Die X
        //! Koordinate der linken oberen Ecke der Zeichenflaeche \param br Die
        //! Breite der Zeichenflaeche \param hi Die Hoehe der Zeichenflaeche
        //! \return 1, falls die neue Zeichenflaeche ganz oder teilweise
        //! innerhalb des Bildes ligt. Wenn 0 zurueckgegeben wird, wurde die
        //! Zeichenflaeche nicht gesetzt und es braucht nicht
        //! releaseDrawOptions() aufgerufen werden
        DLLEXPORT bool setDrawOptionsErzwingen(int x, int y, int br, int hi);
        //! Setzt neue Draw options auf bildgroesse
        DLLEXPORT void setDrawOptionsReset();
        //! Setzt Koordinaten, die bei den Zeichenfunktionen von den Positionen
        //! abgezogen werden Vorher sollte eine Zeichenflaeche mit SetDrawOptions
        //! gesetzt worden sein. Die Werte werden mit dem aufruf von
        //! releaseDrawOptions() wieder zurueckgesetzt. \param xOff Ein Wert, der
        //! von allen X Koordinaten abgezogen wird \param yOff Ein Wert, der von
        //! allen Y Koordinaten abgezogen wird
        DLLEXPORT void addScrollOffset(int xOff, int yOff);
        //! Entfernt die als letztes gesetzte begrenzung der Zeichenflaeche und
        //! alle seit dem gesetzten Scroll Offsets Stellt die vorherige
        //! Zeichenflaeche und die zugehoerigen Scroll Offsets wieder her
        DLLEXPORT void releaseDrawOptions();
        //! Gibt zurueck, ob sich das Bild seit dem letzten Aufruf dieser
        //! Funktion veraendert hat
        DLLEXPORT bool getRend();
        //! Gibt den Array mit A8R8G8B8 Farbwerten der Pixel zurueck
        //! Der Index eines Pixels berechnet sich durch x + y * Bildbreite
        DLLEXPORT int* getBuffer() const;
        //! Gibt den A8R8G8B8 Farbwert eines Pixels zurueck
        //! \param x Die X Koordinate des Pixels
        //! \param y Die Y Koordinate des Pixels
        DLLEXPORT int getPixel(int x, int y) const;
        //! Gibt die Groesse des Bildes zurueck
        DLLEXPORT const Punkt& getSize() const;
        //! Gibt die Breite des Bildes zurueck
        DLLEXPORT int getBreite() const;
        //! Gibt die Hoehe des Bildes zurueck
        DLLEXPORT int getHeight() const;
        //! Gibt den aktuellen mindest Transparenz Wert zurueck
        DLLEXPORT unsigned char getAlpha() const;
        //! Gibt die Koordinaten der linken oberen Ecke der aktuellen
        //! Zeichenflaeche zurueck
        DLLEXPORT const Punkt& getDrawPos() const;
        //! Gibt die Groesse der aktuelen Zeichenflaeche zurueck
        DLLEXPORT const Punkt& getDrawGr() const;
        //! Gibt die Koordinaten zurueck, die zu allen Positionen vor dem
        //! Zeichnen hinzugefuegt werden
        DLLEXPORT const Punkt& getDrawOff() const;
        //! Wird dieser Flag gesetzt, so wird beim Alpha Blending wenn die
        //! vorheriege Farbe 0 ist nur die neue mit ihrem Alpha Wert kopiert.
        //! Das ist sinnvoll fuer die Verwendung im 3DBildschirm, wo das
        //! Gezeichnette Bild spaeter mittels Alpha Blending angezeigt wird. Der
        //! Flag wird im 3DBildschirm automatisch gesetzt
        DLLEXPORT bool hasAlpha3D() const;
        //! Berechnet die durchschnittliche Farbe aller Pixel des Bildes
        DLLEXPORT int getAverageColor() const;
    };

    //! Eine Zeichnung des 2d GUI Frameworks, die ein Bild anzeigt.
    class BildZ : public ZeichnungHintergrund
    {
    public:
        class Style : public ZeichnungHintergrund::Style
        {
        public:
            //! Wenn dieser Flag gesetzt ist, wird zum Zeichnen des Bildes Alpha
            //! Blending verwendet
            static const __int64 Alpha = 0x1000;
            //! Wenn dieser Flag gesetzt ist, wird das Bild in die Zeichenflaeche
            //! skalliert
            static const __int64 Skalliert = 0x2000;

            //! Der Normale Style einer Bild Zeichnung Bestehend aus HScroll,
            //! Sichtbar, Erlaubt, Rahmen, VScroll
            static const __int64 normal
                = HScroll | Sichtbar | Erlaubt | Rahmen | VScroll;
        };

    private:
        Bild* bild;

    protected:
        //! Verarbeitet ein Maus Ereignis. Wird vom Framework automatisch
        //! aufgerufen. \param me Das Ereignis
        DLLEXPORT void doMausEreignis(MausEreignis& me, bool userRet) override;

    public:
        //! Konstruktor
        DLLEXPORT BildZ();
        //! Destruktor
        DLLEXPORT virtual ~BildZ();
        //! Setzt einen Zeiger auf das Bild, was angezeigt werden soll
        //! \param b Das Bild
        DLLEXPORT void setBildZ(Bild* b);
        //! Setzt das Bild, was angezeigt werden soll. Der Inhalt des Bildes
        //! wird Kopiert \param b Das Bild
        DLLEXPORT void setBild(Bild* b);
        //! Updated den Zeichenhintergrund
        //! \param tickVal Die vergangene Zeit in Sekunden, die seit dem Letzten
        //! Aufruf dieser Funktion verstrichen ist \return 1, wenn das Bild neu
        //! gezeichnet werden muss. 0 sonnst
        DLLEXPORT bool tick(double tickVal) override;
        //! Zeichnet die Zeihnung in ein bestimmtes Bild
        //! \param zRObj Das Bild, in das gezeichnet werden soll
        DLLEXPORT void render(Bild& zRObj) override;
        //! Gibt das angezeigte Bild zurueck
        DLLEXPORT Bild* getBild() const;
        //! Gbt das angezeigte Bild ohne erhoehten Reference Counter zurueck
        DLLEXPORT Bild* zBild() const;
        //! Kopiert die Komplette Zeichnung, so dass sie ohne Effekt auf das
        //! Original veraendert werden kann
        DLLEXPORT Zeichnung* dublizieren() const override;
    };

#ifdef WIN32
    //! Laedt ein Bild aus einer .bmp, .jpg, .gif oder .png Datei
    //! \param pfad Der Pfad zur Bilddatei
    //! \param zError Ein Zeiger auf ein Text Objekt, in dem ein moeglicher
    //! Fehler zurueckgegeben wird \return Das geladene Bild
    DLLEXPORT Bild* ladeBild(const char* pfad, Text* zError);
#endif
} // namespace Framework
#endif