// 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 WPOPUP_MENU_ITEM_H_
#define WPOPUP_MENU_ITEM_H_

#include <Wt/WCompositeWidget>

namespace Wt {

class WCheckBox;
class WPopupMenu;
class WText;

/*! \class WPopupMenuItem Wt/WPopupMenuItem Wt/WPopupMenuItem
 *  \brief An item in a popup menu.
 *
 * An item may have a text, icon, and can be checkable or lead to a
 * submenu.
 *
 * When the mouse hovers over the item, its class is changed from
 * "Wt-item" to "Wt-selected".
 *
 * \sa WPopupMenu
 */
class WT_API WPopupMenuItem : public WCompositeWidget
{
public:
  /*! \brief Creates a new item with given text.
   *
   * \sa WPopupMenu::addItem(const WString& text)
   */
  WPopupMenuItem(const WString& text);

  /*! \brief Creates a new item with given icon and text.
   *
   * The icon is displayed left to the text.
   *
   * \note The icon should have a width of 16 pixels.
   *
   * \sa WPopupMenu::addItem(const std::string& iconPath, const WString& text)
   */
  WPopupMenuItem(const std::string& iconPath, const WString& text);

  /*! \brief Destructor.
   */
  ~WPopupMenuItem();

  /*! \brief Sets the item text.
   *
   * \sa setIcon()
   */
  void setText(const WString& text);

  /*! \brief Returns the item text.
   *
   * \sa setText()
   */
  const WString& text() const;

  /*! \brief Sets the item icon path.
   *
   * The icon should have a width of 16 pixels.
   *
   * \sa setText()
   */
  void setIcon(const std::string& path);

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

  /*! \brief Sets if the item is checkable.
   *
   * When an item is checkable, a checkbox is displayed to the left of the
   * item text (instead of an icon).
   *
   * \sa setChecked(), isChecked()
   */
  void setCheckable(bool how);

  /*! \brief Returns whether the item is checkable.
   *
   * \sa setCheckable()
   */
  bool isCheckable() const { return checkBox_ != 0; }

  /*! \brief Sets a sub menu for the item.
   *
   * Sets a submenu for the item. Ownership of the submenu is transferred
   * to the item.
   *
   * \sa popupMenu()
   */
  void setPopupMenu(WPopupMenu *menu);

  /*! \brief Returns the sub menu.
   *
   * \sa setPopupMenu()
   */
  WPopupMenu *popupMenu() const { return subMenu_; }

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

  /*! \brief Returns the checked state.
   *
   * This is only used when isCheckable() == \c true.
   *
   * \sa setChecked(bool), isCheckable()
   */
  bool isChecked() const;

  /*! \brief Sets associated additional data with the item.
   */
  void setData(void *data) { data_ = data; }

  /*! \brief Returns additional data of the item.
   */
  void *data() const { return data_; }

  WCheckBox *checkBox() const { return checkBox_; }

  /*! \brief %Signal emitted when an item is activated.
   */
  Signal<>& triggered() { return triggered_; }

  virtual void load();
  virtual void setDisabled(bool disabled);

private:
  // Constructs a separator
  WPopupMenuItem(bool);

  WContainerWidget *impl_;
  WText            *text_;
  WCheckBox        *checkBox_;
  WPopupMenu       *subMenu_;
  void             *data_;
  bool              separator_;

  Signal<>          triggered_;

  void create();
  void renderOver();
  void renderOut();
  void renderSelected(bool selected);
  void onMouseUp();

  WPopupMenu *parentMenu();
  WPopupMenu *topLevelMenu();

  friend class WPopupMenu;
};

}

#endif // WPOPUP_MENU_ITEM_H_
