/***************************************************************************
                          SIMPLY POWERFUL TOOLKIT (SPTK)
                          CButton.h  -  description
                             -------------------
    begin                : Mon Apr 17 2000
    copyright            : (C) 2000-2005 by Alexey S.Parshin
    email                : alexeyp@gmail.com
 ***************************************************************************/

/***************************************************************************
   This library is free software; you can redistribute it and/or modify it 
   under the terms of the GNU Library General Public License as published by
   the Free Software Foundation; either version 2 of the License, or (at 
   your option) any later version.

   This library 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 Library
   General Public License for more details.

   You should have received a copy of the GNU Library General Public License
   along with this library; if not, write to the Free Software Foundation, 
   Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.

   Please report all bugs and problems to "alexeyp@gmail.com"
 ***************************************************************************/

#ifndef _CBUTTON_H__
#define _CBUTTON_H__

#include <sptk3/sptk.h>
#include <sptk3/CLayoutClient.h>
#include <sptk3/CThemes.h>
#include <string>

#include <FL/Fl_Button.H>

/// @addtogroup gui GUI Classes
/// @{

/// @brief Button widget kind
///
/// The button kind defines a picture and a default label for the button.
enum CButtonKind {
   SP_UNDEFINED_BUTTON = 0,            ///< default button without image
   SP_OK_BUTTON        = 1,            ///< 'Ok' button
   SP_CANCEL_BUTTON    = 2,            ///< 'Cancel' button
   SP_NO_BUTTON        = 4,            ///< 'No' button
   SP_ADD_BUTTON       = 8,            ///< 'Add' button
   SP_DELETE_BUTTON    = 0x10,         ///< 'Delete' button
   SP_EDIT_BUTTON      = 0x20,         ///< 'Edit' button
   SP_BROWSE_BUTTON    = 0x40,         ///< 'Browse' button
   SP_REFRESH_BUTTON   = 0x80,         ///< 'Refresh' button
   SP_CALENDAR_BUTTON  = 0x100,        ///< 'Calendar' button
   SP_OPEN_BUTTON      = 0x200,        ///< 'Open' button
   SP_PRINT_BUTTON     = 0x400,        ///< 'Print' button
   SP_SAVE_BUTTON      = 0x800,        ///< 'Save' button
   SP_SAVE_AS_BUTTON   = 0x1000,       ///< 'Save As' button
   SP_COPY_BUTTON      = 0x2000,       ///< 'Copy' button
   SP_LEFT_BUTTON      = 0x4000,       ///< 'Left' button
   SP_NEW_BUTTON       = 0x8000,       ///< 'New' button
   SP_NEXT_BUTTON      = 0x10000,      ///< 'Next' button
   SP_PRINTER_BUTTON   = 0x20000,      ///< 'Printer' button
   SP_PRIOR_BUTTON     = 0x40000,      ///< 'Prior' button
   SP_RIGHT_BUTTON     = 0x80000,      ///< 'Right' button
   SP_SEARCH_BUTTON    = 0x100000,     ///< 'Left' button
   SP_SEND_BUTTON      = 0x200000,     ///< 'Send' button
   SP_STEPLEFT_BUTTON  = 0x400000,     ///< 'Step Left' button
   SP_STEPRIGHT_BUTTON = 0x800000,     ///< 'Step Right' button
   SP_VIEW_BUTTON      = 0x1000000,    ///< 'View' button
   SP_HOME_BUTTON      = 0x2000000,    ///< 'Home' button
   SP_CONFIGURE_BUTTON = 0x4000000,    ///< 'Configure' button
   SP_EXEC_BUTTON      = 0x8000000,    ///< 'Execute' button
   SP_STOP_BUTTON      = 0x10000000,   ///< 'Stop' button
   SP_EXIT_BUTTON      = 0x20000000,   ///< 'Exit' button
   SP_HELP_BUTTON      = 0x40000000,   ///< 'Help' button
   SP_MAX_BUTTON       = 0x40000001    ///< Max button id
};

class Fl_Image;

/// @brief Base button widget
///
/// Base class for CButton and CSmallButton, uses Fl_Image * or a stock image of CButtonKind. 
class SP_EXPORT CBaseButton : public Fl_Button, public CLayoutClient {
   bool              m_default;  ///< Is this button a default button?
   CThemeButtonSize  m_type;     ///< Button type - normal, thin, or combo box button

    /// Draws the dotted line. The line angle should be divided by 45 degrees w/o remains.
    /// @param xs int, x-coordinate for the starting point
    /// @param ys int, y-coordinate for the starting point
    /// @param xe int, x-coordinate for the ending point
    /// @param ye int, y-coordinate for the ending point
   void drawFocusLine(int xs,int ys,int xe,int ye);

protected:    

   Fl_Image         *m_image;    ///< Internal image pointer
   std::string		   m_label;    ///< Button label, a safe copy

    /// Sets the large pixmap of kind buttonKind and label
   void largePixmap(int buttonKind,const char *label);

    /// Sets the samll pixmap of kind buttonKind and label
   void smallPixmap(int buttonKind);

    /// Draws the button
   void draw();

    /// Draws the focus for the button.
    /// @param usingTheme bool, to use theme's value for the focus corner radius. Otherwise, radius is 0.
   void drawFocus(bool usingTheme);

    /// Special handle() method
   int  handle(int event);
protected:
    /// Preferred size for the button computes the optimal size for the button
   virtual void preferredSize(int& w,int& h);

   /// Constructor in SPTK style 
   /// @param kind CButtonKind, stock image id
   /// @param layoutAlign CLayoutAlign, widget align in layout
   /// @param is_small bool, true for the small button (small pixmap, no label)
   /// @param label const char * label
   /// @param tbt CThemeButtonSize, the type of button
   CBaseButton(CButtonKind kind,CLayoutAlign layoutAlign=SP_ALIGN_RIGHT,bool is_small=false,const char *label=0,CThemeButtonSize tbt=THM_BUTTON_NORMAL);

   /// Constructor in SPTK style. The image should be assigned separately.
   /// @param label const char *, label
   /// @param layoutAlign CLayoutAlign, widget align in layout
   /// @param tbt CThemeButtonSize, the type of button
   CBaseButton(const char *label=0,CLayoutAlign layoutAlign=SP_ALIGN_RIGHT,CThemeButtonSize tbt=THM_BUTTON_NORMAL);

#ifdef __COMPATIBILITY_MODE__    
   /// Constructor in FLTK style 
   /// @param kind CButtonKind, stock image id
   /// @param x int, x-position
   /// @param y int, y-position
   /// @param w int, width
   /// @param h int, height
   /// @param label const char *, label
   /// @param tbt CThemeButtonSize, the type of button
   CBaseButton(CButtonKind kind,int x,int y,int w,const char *l=0,CThemeButtonSize tbt=THM_BUTTON_NORMAL);
#endif
public:
   /// Is used to define a button as default for the current
   /// window of CDialog class. The default button is activated when an Enter button
   /// is pressed inside CDialog on the widget and the widget doesn't process Enter
   /// button.
   /// @param defaultBtn bool makes button default or not
   void defaultButton(bool defaultBtn);

   /// Returns true if the button is a default button
   /// @returns button type - default or not
   bool defaultButton() const { return m_default; }

   /// Sets the stock image to the button. Purely virtual.
   /// @param bkind CButtonKind stock image id.
   virtual void buttonImage(CButtonKind bkind) = 0;

   /// Sets the image to the button. Purely virtual.
   /// @param image Fl_Image * image pointer
   virtual void buttonImage(Fl_Image *image) = 0;

   /// Returns the button's image. Purely virtual.
   /// @returns image pointer
   virtual Fl_Image *buttonImage() const = 0;

   /// Returns button label
   /// @returns button label
   const char *label() const { return m_label.c_str(); }

   /// Sets button label
   /// @param lbl const char *, new button label
   void label(const char *lbl);
};

/// @brief Button widget
///
/// Button that displays an a regular Fl_Image *, or as a stock image of CButtonKind. 
class SP_EXPORT CButton : public CBaseButton {
public:
#ifdef __COMPATIBILITY_MODE__
    /// Constructor in FLTK style 
    /// @param kind CButtonKind stock image id
    /// @param x int x-position
    /// @param y int y-position
    /// @param w int width
    /// @param h int height
    /// @param label const char * label
   CButton(CButtonKind kind,int x,int y,int w,const char *label=0,CThemeButtonSize tbt=THM_BUTTON_NORMAL)
   : CBaseButton(kind,x,y,w,label,tbt) {}
#endif    

    /// Constructor in SPTK style 
    /// @param kind CButtonKind stock image id
    /// @param layoutAlign CLayoutAlign widget align in layout
    /// @param label const char * label
    /// @param tbt CThemeButtonSize, the size type of the button
   CButton(CButtonKind kind,CLayoutAlign layoutAlign=SP_ALIGN_RIGHT,const char *label=0,CThemeButtonSize tbt=THM_BUTTON_NORMAL) 
   : CBaseButton(kind,layoutAlign,false,label,tbt) {}

    /// Default constructor in SPTK style 
    /// @param label const char * label
    /// @param layoutAlign CLayoutAlign widget align in layout
    /// @param tbt CThemeButtonSize, the button type (size)
   CButton(const char *label=0,CLayoutAlign layoutAlign=SP_ALIGN_RIGHT,CThemeButtonSize tbt=THM_BUTTON_NORMAL)
   : CBaseButton(label,layoutAlign,tbt) {}

    /// Sets the image to the button. 
    /// @param image Fl_Image * image pointer
   virtual void buttonImage(Fl_Image *image) { m_image = image; }

    /// Sets the stock image to the button.
    /// @param bkind CButtonKind stock image id. 
   virtual void buttonImage(CButtonKind bkind) { largePixmap(bkind,label()); }

    /// Returns the button's image.
    /// @returns image pointer
   virtual Fl_Image *buttonImage() const { return m_image; }
};    

/// @brief Small button widget
///
/// Displays a regular Fl_Image *, or as a stock image of CButtonKind. 
/// The button label is ignored
class SP_EXPORT CSmallButton : public CBaseButton {
public:
#ifdef __COMPATIBILITY_MODE__    
   /// Constructor in FLTK style 
   /// @param kind CButtonKind stock image id
   /// @param x int x-position
   /// @param y int y-position
   /// @param w int width
   /// @param h int height
   /// @param label const char * label
   CSmallButton(CButtonKind kind,int x,int y,int w,const char *label=0)
   : CBaseButton(kind,x,y,w,label,THM_BUTTON_COMBO) {}
#endif    

   /// Default constructor in SPTK style 
   /// @param kind CButtonKind stock image id
   /// @param layoutAlign CLayoutAlign widget align in layout
   /// @param label const char *, label
   CSmallButton(CButtonKind kind,CLayoutAlign layoutAlign=SP_ALIGN_RIGHT,const char *label=0) 
   : CBaseButton(kind,layoutAlign,true,label,THM_BUTTON_COMBO) {}

   /// Sets the image to the button. 
   /// @param image Fl_Image *, image pointer
   virtual void buttonImage(Fl_Image *image) { m_image = image; }

   /// Sets the stock image to the button.
   /// @param bkind CButtonKind, stock image id. 
   virtual void buttonImage(CButtonKind bkind) { smallPixmap(bkind); }

   /// Returns the button's image.
   /// @returns image pointer
   virtual Fl_Image *buttonImage() const { return m_image; }
};    

/// @}

#endif
