// 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_TOOLBAR_H_
#define EXT_TOOLBAR_H_

#include <Wt/Ext/Widget>
#include <Wt/Ext/Button>
#include <sstream>

namespace Wt {
  namespace Ext {

class Menu;
class Panel;

/*! \class ToolBar Wt/Ext/ToolBar Wt/Ext/ToolBar
 *  \brief A class that represents a tool bar (or a menu bar).
 *
 * A tool bar shows buttons (and other widgets). When using text-only
 * buttons, the tool bar behaves like a top-level menu.
 *
 * \image html ExtToolBar-1.png "Example of a ToolBar"
 *
 * \ingroup ext
 */
class WT_EXT_API ToolBar : public Widget
{
public:
  /*! \brief Create a new tool bar.
   */
  ToolBar(WContainerWidget *parent = 0);

  /*! \brief Add a button with given text.
   */
  Button *addButton(const WString& text);

  /*! \brief Add a button with given icon and text.
   */
  Button *addButton(const std::string& iconPath, const WString& text);

  /*! \brief Add a button with given text, and specify a slot method to be
   *         called when activated.
   *
   * The <i>target</i> and <i>method</i> are connected to the
   * Button::activated() signal.
   */
  template<class T, class V>
    Button *addButton(const WString& text,
		      T *target, void (V::*method)());
    
  /*! \brief Add a button with given text and icon, and specify a slot
   *         method to be called when activated.
   *
   * The <i>target</i> and <i>method</i> are connected to the
   * Button::activated() signal.
   */
   template<class T, class V>
    Button *addButton(const std::string& iconPath, const WString& text,
		      T *target, void (V::*method)());

  /*! \brief Add a menu button, with given text.
   */
  Button *addButton(const WString& text, Menu *menu);

  /*! \brief Add a menu button, with given icon and text.
   */
  Button *addButton(const std::string& iconPath, const WString& text,
		    Menu *menu);

  /*! \brief Add a button to the tool bar.
   */
  void add(Button *item);

  /*! \brief Add a widget to the tool bar.
   */
  void add(WWidget *item);

  /*! \brief Insert a button in the tool bar.
   */
  void insert(int index, Button *item);

  /*! \brief Insert a widget in the tool bar.
   *
   * \note A widget can ony be inserted before initial rendering.
   */
  void insert(int index, WWidget *item);

  /*! \brief Add a separator to the tool bar.
   */
  void addSeparator();

  /*! \brief Adds stretch to the tool bar.
   *
   * This is an empty space that will stretch and push contents to the
   * right of it away to the very right end.
   */
  void addStretch();

protected:
  void removeChild(WWidget *child);

  std::vector<WWidget *> items_;

  virtual void jsAfterPanelRendered(std::stringstream& js);

private:
  virtual std::string createJS(DomElement *inContainer);

  friend class Panel;
};

#ifndef JAVA
template<class T, class V>
Button *ToolBar::addButton(const WString& text,
			   T *target, void (V::*method)())
{
  return addButton(std::string(), text, target, method);
}

template<class T, class V>
Button *ToolBar::addButton(const std::string& iconPath, const WString& text,
			   T *target, void (V::*method)())
{
  Button *button = addButton(iconPath, text);
  button->activated().connect(target, method);
  return button;
}
#endif // JAVA

  }
}

#endif // EXT_TOOLBAR_H_
