#ifndef Button_H
#define Button_H

#include "TextField.h"

namespace Framework
{
    class TextField;      //! TextField.h
    class AlphaField;     //! AlphaField.h
    class Text;          //! Text.h
    class Font;       //! Font.h
    class Border;        //! Border.h
    class LTDBFile;     //! FileSystem.h
    class Button;         //! from this file
    class CheckBox; //! from this file
    class TextRenderer;

    //! A 2D GUI Framework drawing that renders a button that the user can press
    class Button : public TextField
    {
    public:
        class Style : public DrawableBackground::Style
        {
        public:
            //! Specifies whether the button text may have multiple colors
            static const __int64 MehrfarbigText = 0x0010000;
            //! Specifies whether the button has a background color
            //! while being pressed
            static const __int64 ClickColor = 0x0020000;
            //! Specifies whether the button has a background image
            //! while being pressed
            static const __int64 ClickImage = 0x0040000;
            //! Specifies whether the button uses alpha blending
            //! for the background while being pressed
            static const __int64 ClickAlpha = 0x0080000;
            //! Specifies whether the button has a color gradient
            //! while being pressed
            static const __int64 ClickBuffer = 0x0100000;

            //! Combines flags Visible, Allowed, Border,
            //! Buffered, MehrfarbigText, ClickBuffer
            static const __int64 Normal = Visible | Allowed | Border | Buffered
                                        | MehrfarbigText | ClickBuffer;
        };

    private:
        int klickColor;
        Image* clickImage;
        AlphaField* klickBuffer;
        int klickIndex;
        //! Processes mouse messages
        //! \param me The event triggered by the mouse input
        DLLEXPORT void doMouseEvent(MouseEvent& me, bool userRet) override;

    public:
        //! Constructor
        DLLEXPORT Button();
        //! Destructor
        DLLEXPORT virtual ~Button();
        //! Sets the color used as background when the button is pressed
        //! \param fc The color in A8R8G8B8 format
        DLLEXPORT void setClickColor(int fc);
        //! Sets the background image by copying, used when the button is
        //! pressed
        //! \param bild The image to copy
        DLLEXPORT void setClickImage(Image* bild);
        //! Sets a pointer to the background image used when the button is
        //! pressed
        //! \param bild The new image
        DLLEXPORT void setClickImageZ(Image* bild);
        //! Sets a pointer to the color gradient used when the button is pressed
        //! \param af The new color gradient
        DLLEXPORT void setKBZ(AlphaField* af);
        //! Sets the strength of the color gradient used when the button is
        //! pressed
        //! \param st The strength
        DLLEXPORT void setKBStrength(int st);
        //! Sets the color of the color gradient used when the button is pressed
        //! \param fc The color in A8R8G8B8 format
        DLLEXPORT void setKBColor(int fc);
        //! Processes mouse messages
        //! \param me The event triggered by the keyboard input
        DLLEXPORT void doKeyboardEvent(KeyboardEvent& te) override;
        //! Draws the object to zRObj if it is visible
        //! \param zRObj The image to draw into
        DLLEXPORT void render(Image& zRObj) override;
        //! Returns the background color in A8R8G8B8 format used when
        //! the button is pressed
        DLLEXPORT int getClickColor() const;
        //! Returns the background image used when the button is pressed
        DLLEXPORT Image* getClickImage() const;
        //! Returns the background image without increased reference counter
        //! used when the button is pressed
        DLLEXPORT Image* zClickImage() const;
        //! Returns the color gradient used when the button is pressed
        DLLEXPORT AlphaField* getKB() const;
        //! Returns the color gradient without increased reference counter
        //! used when the button is pressed
        DLLEXPORT AlphaField* zKB() const;
        //! Returns the color of the color gradient in A8R8G8B8 format
        //! used when the button is pressed
        DLLEXPORT int getKBColor() const;
        //! Returns the strength of the color gradient used when the button
        //! is pressed
        DLLEXPORT int getKBStrength() const;
        //! Copies the button so it can be modified without affecting the
        //! original
        DLLEXPORT Drawable* duplicate() const override;
    };

    //! A 2D GUI Framework drawing that renders a selectable checkbox
    //! with label
    class CheckBox : public DrawableBackground
    {
    public:
        class Style : public DrawableBackground::Style
        {
        public:
            //! Specifies whether the checkbox is selected
            static const __int64 Selected = 0x1000000;
            //! Specifies whether the label text can be multicolored
            static const __int64 MulticoloredText = 0x001000;
            //! Specifies whether the checkbox has a background color
            //! while being pressed
            static const __int64 ClickColor = 0x002000;
            //! Specifies whether the checkbox has a background image
            //! when clicked
            static const __int64 ClickImage = 0x004000;
            //! Specifies whether alpha blending is used for the
            //! checkbox background when clicked
            static const __int64 ClickAlpha = 0x008000;
            //! Specifies whether the checkbox has a color gradient
            //! when clicked
            static const __int64 ClickBuffer = 0x010000;
            //! Specifies whether the checkbox has a background color
            //! while selected
            static const __int64 SelectColor = 0x020000;
            //! Specifies whether the checkbox has a background image
            //! while selected
            static const __int64 SelectImage = 0x040000;
            //! Specifies whether alpha blending is used for the
            //! checkbox background while selected
            static const __int64 SelectAlpha = 0x080000;
            //! Specifies whether the checkbox has a color gradient
            //! while selected
            static const __int64 SelectBuffer = 0x100000;
            //! Specifies whether the checkbox has a different label
            //! while selected
            static const __int64 SelectText = 0x200000;
            //! Specifies whether the checkbox can have a multi-line label
            static const __int64 MultilineText = 0x400000;
            //! Specifies whether the checkbox is currently being clicked
            //! with the mouse. (Managed by the checkbox itself)
            static const __int64 MouseClick = 0x800000;

            //! Combines the flags Visible, Allowed, Border,
            //! ClickBuffer
            static const __int64 Normal
                = Visible | Allowed | Border | ClickBuffer;
        };

    private:
        Text* txt;
        Text* sTxt;
        int sBgF;
        int kBgF;
        Image* sBgB;
        Image* kBgB;
        AlphaField* sAf;
        AlphaField* kAf;
        Image* kasten;
        Image* sKasten;
        TextRenderer* textRd;
        int sF;
        int sGr;
        //! Processes mouse messages
        //! \param me The event triggered by the mouse input
        DLLEXPORT void doMouseEvent(MouseEvent& me, bool userRet) override;

    public:
        //! Constructor
        DLLEXPORT CheckBox();
        //! Destructor
        DLLEXPORT virtual ~CheckBox();
        //! Sets a pointer to the label text
        //! \param txt The text
        DLLEXPORT void setTextZ(Text* txt);
        //! Sets the label text
        //! \param txt The text
        DLLEXPORT void setText(Text* txt);
        //! Sets the label text
        //! \param txt The text
        DLLEXPORT void setText(const char* txt);
        //! Sets a pointer to the label text displayed while the
        //! checkbox is selected \param txt The text
        DLLEXPORT void setSTextZ(Text* txt);
        //! Sets the label text displayed while the checkbox is selected
        //! \param txt The text
        DLLEXPORT void setSText(Text* txt);
        //! Sets the label text displayed while the checkbox is selected
        //! \param txt The text
        DLLEXPORT void setSText(const char* txt);
        //! Sets the TextRenderer to use
        //! \param textRd The text renderer
        DLLEXPORT void setTextRendererZ(TextRenderer* textRd);
        //! Sets the font to use for the label
        //! \param font The font
        DLLEXPORT void setFontZ(Font* font);
        //! Sets the color of the font used for the label
        //! \param f The color in A8R8G8B8 format
        DLLEXPORT void setSColor(int f);
        //! Sets the size of the font used for the label
        //! \param f The height of a line in pixels
        DLLEXPORT void setSSize(int gr);
        //! Sets the background color used while the checkbox is selected
        //! \param f The color in A8R8G8B8 format
        DLLEXPORT void setSBgColor(int f);
        //! Sets the background color used while the checkbox is being clicked
        //! \param f The color in A8R8G8B8 format
        DLLEXPORT void setClickBgColor(int f);
        //! Sets a pointer to the background image used while the checkbox
        //! is selected \param b The image
        DLLEXPORT void setSBgImageZ(Image* b);
        //! Sets the background image by copying, used while the checkbox
        //! is selected \param b The image to copy
        DLLEXPORT void setSBgImage(Image* b);
        //! Sets a pointer to the background image used while the checkbox
        //! is being clicked \param b The image
        DLLEXPORT void setClickBgImageZ(Image* b);
        //! Sets the background image by copying, used while the checkbox
        //! is being clicked \param b The image to copy
        DLLEXPORT void setClickBgImage(Image* b);
        //! Sets a pointer to the color gradient used while the checkbox
        //! is selected \param af The color gradient
        DLLEXPORT void setSAlphaFieldZ(AlphaField* af);
        //! Sets the color of the color gradient used while the checkbox
        //! is selected \param f The color in A8R8G8B8 format
        DLLEXPORT void setSAFColor(int f);
        //! Sets the strength of the color gradient used while the checkbox
        //! is selected \param st The strength
        DLLEXPORT void setSAFStrength(int st);
        //! Sets a pointer to the color gradient used while the checkbox
        //! is being clicked \param af The color gradient
        DLLEXPORT void setClickAlphaFieldZ(AlphaField* af);
        //! Sets the color of the color gradient used while the checkbox
        //! is being clicked \param f The color in A8R8G8B8 format
        DLLEXPORT void setClickAFColor(int f);
        //! Sets the strength of the color gradient used while the checkbox
        //! is being clicked \param st The strength
        DLLEXPORT void setClickAFStrength(int st);
        //! Loads images "kasten.gif" and "skasten.gif" from an LTDB file.
        //! kasten.gif is drawn when the checkbox is not selected.
        //! skasten.gif is drawn when the checkbox is selected.
        //! \param zDat The LTDB file
        DLLEXPORT void loadData(LTDBFile* zDat);
        //! Loads images "kasten.gif" and "skasten.gif" from an LTDB file.
        //! kasten.gif is drawn when the checkbox is not selected.
        //! skasten.gif is drawn when the checkbox is selected.
        //! \param ltdb The path to the LTDB file
        DLLEXPORT void loadData(const char* ltdb);
        //! Draws the object to zRObj if it is visible
        //! \param zRObj The image to draw into
        DLLEXPORT void render(Image& zRObj) override;
        //! Returns the label
        DLLEXPORT Text* getText() const;
        //! Returns the label without increased reference counter
        DLLEXPORT Text* zText() const;
        //! Returns the label used while the checkbox is selected
        DLLEXPORT Text* getSText() const;
        //! Returns the label without increased reference counter used
        //! while the checkbox is selected
        DLLEXPORT Text* zSText() const;
        //! Returns the font used
        DLLEXPORT Font* getFont() const;
        //! Returns the font used without increased reference counter
        DLLEXPORT Font* zFont() const;
        //! Returns the font color in A8R8G8B8 format
        DLLEXPORT int getSColor() const;
        //! Returns the font size
        DLLEXPORT int getSSize() const;
        //! Returns the background color in A8R8G8B8 format used while
        //! the checkbox is selected
        DLLEXPORT int getSBgColor() const;
        //! Returns the background color in A8R8G8B8 format used while
        //! the checkbox is being clicked
        DLLEXPORT int getClickBgColor() const;
        //! Returns the background image used while the checkbox is selected
        DLLEXPORT Image* getSBgImage() const;
        //! Returns the background image without increased reference counter
        //! used while the checkbox is selected
        DLLEXPORT Image* zSBgImage() const;
        //! Returns the background image used while the checkbox is being clicked
        DLLEXPORT Image* getClickBgImage() const;
        //! Returns the background image without increased reference counter
        //! used while the checkbox is being clicked
        DLLEXPORT Image* zClickBgImage() const;
        //! Returns the color gradient used while the checkbox is selected
        DLLEXPORT AlphaField* getSAlphaField() const;
        //! Returns the color gradient without increased reference counter
        //! used while the checkbox is selected
        DLLEXPORT AlphaField* zSAlphaField() const;
        //! Returns the color gradient used while the checkbox is being clicked
        DLLEXPORT AlphaField* getClickAlphaField() const;
        //! Returns the color gradient without increased reference counter
        //! used while the checkbox is being clicked
        DLLEXPORT AlphaField* zClickAlphaField() const;
    };
} // namespace Framework

#endif