//------------------------------------------------------------------------------
// emButton.h
//
// Copyright (C) 2005-2010,2014,2016 Oliver Hamann.
//
// Homepage: http://eaglemode.sourceforge.net/
//
// This program is free software: you can redistribute it and/or modify it under
// the terms of the GNU General Public License version 3 as published by the
// Free Software Foundation.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU General Public License version 3 for
// more details.
//
// You should have received a copy of the GNU General Public License version 3
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//------------------------------------------------------------------------------

#ifndef emButton_h
#define emButton_h

#ifndef emBorder_h
#include <emCore/emBorder.h>
#endif


//==============================================================================
//================================== emButton ==================================
//==============================================================================

class emButton : public emBorder {

public:

        // Class for a button. Buttons can be triggered (clicked) by the user to
        // perform a function. The label is shown in the button face.

        emButton(
                ParentArg parent, const emString & name,
                const emString & caption=emString(),
                const emString & description=emString(),
                const emImage & icon=emImage()
        );
                // Constructor.
                // Arguments:
                //   parent      - Parent for this panel (emPanel or emView).
                //   name        - The name for this panel.
                //   caption     - The label's caption, or empty.
                //   description - The label's description, or empty.
                //   icon        - The label's icon, or empty.

        virtual ~emButton();
                // Destructor.

        bool IsNoEOI() const;
        void SetNoEOI(bool noEOI=true);
                // Whether clicking this button is not an "End Of Interaction".
                // If false (the default), GetView().SignalEOIDelayed() is
                // called on every click.

        const emSignal & GetClickSignal() const;
                // This signal is signaled when the button has been clicked.

        const emSignal & GetPressStateSignal() const;
                // This signal is signaled when the press state has changed (see
                // IsPressed()).

        bool IsPressed() const;
                // Whether the button is currently pressed or not.

        void Click(bool shift=false);
                // Perform a button click programmatically.

protected:

        virtual void Clicked();
                // Called when the button has been clicked.

        virtual void PressStateChanged();
                // Called when the press state has changed.

        virtual void Input(emInputEvent & event, const emInputState & state,
                           double mx, double my);

        virtual bool HasHowTo() const;
        virtual emString GetHowTo() const;

        virtual void PaintContent(
                const emPainter & painter, double x, double y, double w,
                double h, emColor canvasColor
        ) const;

        virtual void PaintBoxSymbol(
                const emPainter & painter, double x, double y, double w,
                double h, emColor canvasColor
        ) const;

        virtual bool CheckMouse(double mx, double my) const;

        bool IsShownChecked() const;
        bool IsShownBoxed() const;
        bool IsShownRadioed() const;
        void SetShownChecked(bool shownChecked);
        void SetShownBoxed(bool shownBoxed);
        void SetShownRadioed(bool shownRadioed);
                // Yes, this class has the ability to paint all our button
                // types.

        // - - - - - - - - - - Depreciated methods - - - - - - - - - - - - - - -
        // The following virtual non-const methods have been replaced by const
        // methods (see above). The old versions still exist here with the
        // "final" keyword added, so that old overridings will fail to compile.
        // If you run into this, please adapt your overridings by adding "const".
        virtual bool CheckMouse(double mx, double my) final;
        // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

private:

        enum DoButtonFunc {
                BUTTON_FUNC_PAINT,
                BUTTON_FUNC_CHECK_MOUSE
        };
        void DoButton(
                DoButtonFunc func, const emPainter * painter,
                emColor canvasColor,
                double mx, double my, bool * pHit
        ) const;

        emSignal ClickSignal;
        emSignal PressStateSignal;
        unsigned Pressed : 1;
        unsigned NoEOI : 1;
        unsigned ShownChecked : 1;
        unsigned ShownBoxed : 1;
        unsigned ShownRadioed : 1;

        static const char * HowToButton;
        static const char * HowToEOIButton;
};

inline bool emButton::IsNoEOI() const
{
        return NoEOI;
}

inline const emSignal & emButton::GetClickSignal() const
{
        return ClickSignal;
}

inline const emSignal & emButton::GetPressStateSignal() const
{
        return PressStateSignal;
}

inline bool emButton::IsPressed() const
{
        return Pressed;
}

inline bool emButton::IsShownChecked() const
{
        return ShownChecked;
}

inline bool emButton::IsShownBoxed() const
{
        return ShownBoxed;
}

inline bool emButton::IsShownRadioed() const
{
        return ShownRadioed;
}


#endif