// This may look like C code, but it's really -*- C++ -*-
/*
 * Copyright (C) 2008 Emweb bvba, Kessel-Lo, Belgium.
 *
 * See the LICENSE file for terms of use.
 */
#ifndef EXT_ABSTRACT_BUTTON_H_
#define EXT_ABSTRACT_BUTTON_H_

#include <Wt/Ext/Component>
#include <Wt/WJavaScript>

namespace Wt {
  namespace Ext {

class Menu;
class ToolTipConfig;

/*! \class AbstractButton Wt/Ext/AbstractButton Wt/Ext/AbstractButton
 *  \brief Abstract base class for a (toolbar) button or menu item.
 *
 * You may set the button text using setText() and icon use setIcon(),
 * and configure whether the button/menu item can be checked or
 * toggled using setCheckable().
 *
 * To respond to a click, you can connect to the activated() signal,
 * and for a checkable button/item you may listen to the toggled()
 * signal.
 *
 * \sa Button, MenuItem, AbstractToggleButton
 *
 * \ingroup ext
 */
class WT_EXT_API AbstractButton : public Component
{
protected:
  AbstractButton(WContainerWidget *parent = 0);

public:
  /*! \brief Set the item text.
   */
  void setText(const WString& text);

  /*! \brief Get the item text.
   */
  const WString& text() const { return text_; }

  /*! \brief Set the item icon path.
   */
  void setIcon(const std::string& path);

  /*! \brief Get the item icon path.
   */
  const std::string& icon() const { return icon_; }

  /*! \brief Set if the item is checkable.
   */
  void setCheckable(bool how);

  /*! \brief Return if the item is checkable.
   */
  bool isCheckable() const { return checkable_; }

  /*! \brief Set a menu that popups up when the item is activated.
   */
  void setMenu(Menu *menu);

  /*! \brief Change the checked state.
   *
   * This is only used when the isCheckable() == true.
   *
   * \sa setCheckable(bool), isCheckable()
   */
  void setChecked(bool how);

  /*! \brief Get the checked state.
   */
  bool isChecked() const { return checked_; }

  /*! \brief Configure the tool tip associated with this item.
   *
   * If the config has no parent, then ownership is transferred to this
   * widget.
   */
  void configureToolTip(ToolTipConfig *config);

  /*! \brief %Signal emitted when a item gets activated.
   *
   * This signal is emitted for non-checkable items (for who
   * isCheckable() == false), when the user activates the item
   * (by clicking it).
   *
   * \sa setCheckable(bool), isCheckable()
   */
  JSignal<>& activated() { return activated_; }

  /*! \brief %Signal emitted when a item gets toggled.
   *
   * This signal is emitted for checkable items (for who
   * isCheckable() == false), when the user changed toggles the item
   * state. The new state is passed as a parameter value.
   *
   * \sa setCheckable(bool), isCheckable()
   */
  JSignal<bool>& toggled() { return toggled_; }

  virtual void refresh();

protected:
  std::string createJSHelper(const std::string& extClassName,
			     bool intoElement = false);
  virtual void updateExt();
  virtual void createConfig(std::ostream& js);

private:
  JSignal<>      activated_;
  JSignal<bool>  toggled_;
  WString        text_;
  std::string    icon_;
  bool           checkable_;
  bool           checked_;
  Menu          *menu_;
  ToolTipConfig *toolTipConfig_;

  virtual std::string checkMethodJS() const = 0;
  virtual std::string checkEventJS() const = 0;
  virtual std::string checkInitialState() const = 0;

  void wasToggled(bool how);
};

  }
}

#endif // EXT_ABSTRACT_BUTTON_H_
