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

#include <Wt/WResource>
#include <Wt/WLength>
#include <Wt/WBorder>
#include <Wt/WSignal>

#include <vector>
#include <sstream>

namespace Wt {

class WContainerWidget;
class WCssDecorationStyle;
class WDropEvent;
class WLayout;
class WLayoutItemImpl;
class WLayoutItem;
class WMouseEvent;
class WString;
class WWebWidget;
class DomElement;

/*! \brief Enumeration that indicates a direction.
 */
enum Orientation { Horizontal = 0x1, //!< Horizontal
		   Vertical   = 0x2  //!< Vertical
};

/*! \brief Enumeration that indicates a standard button for a message box.
 *
 * Multiple buttons may be specified by logically or'ing these values
 * together, e.g.
 * \code
 * Ok | Cancel
 * \endcode
 */
enum StandardButton {
  NoButton = 0x00,  //!< No button
  Ok = 0x01,        //!< An OK button.
  Cancel = 0x02,    //!< A Cancel button.
  Yes = 0x04,       //!< A Yes button.
  No = 0x08,        //!< A No button.
  Abort = 0x10,     //!< An Abort button.
  Retry = 0x20,     //!< A Retry button.
  Ignore = 0x40,    //!< An Ignore button.
  YesAll = 0x80,    //!< A Yes-to-All button.
  NoAll = 0x100     //!< A No-to-All button.
};

/*! \brief Enumeration that indiciates a standard icon for a message box.
 */
enum Icon {
  NoIcon = 0,       //!< No icon
  Information = 1,  //!< An information icon <i>(not implemented)</i>
  Warning = 2,      //!< An warning icon <i>(not implemented)</i>
  Critical = 3,     //!< An critical icon <i>(not implemented)</i>
  Question = 4      //!< An question icon <i>(not implemented)</i>
};

/*! \brief Enumeration that indicates how items may be selected.
 */
enum SelectionMode { NoSelection = 0,      //!< No selections
		     SingleSelection = 1,  //!< Single selection only
		     ExtendedSelection = 3 //!< Multiple selection
};

/*! \brief Enumeration that indicates what is being selected.
 */
enum SelectionBehavior { SelectItems = 0,    //!< Select single items 
			 SelectRows = 1      //!< Select only rows
			 /*, SelectColumns */
};

/*! \brief Enumeration that indicates what is the selection unit
 *         (<b>deprecated</b>).
 *
 * \deprecated Use SelectionBehavior instead.
 */
enum SelectionUnit { CellSelection = 0,    //!< Select inividual cells 
		     RowSelection = 1      //!< Select whole rows
};

enum SelectionFlag {
  Select = 1,
  Deselect = 2,
  ToggleSelect = 3,
  ClearAndSelect = 4
};

/*! \brief Enumeration that designates a relative location.
 *
 * Values of CenterX, CenterY, and CenterXY are only valid for
 * WCssDecorationStyle::setBackgroundImage()
 *
 * \sa setMargin(const WLength& x, int sides),
       setOffsets(const WLength& x, int sides)
 * \sa setFloatSide(Side s),
 *     setClearSides(int sides)
 * \sa WContainerWidget::setPadding(const WLength& x, int sides)
 * \sa WCssDecorationStyle::setBackgroundImage()
 */
enum Side {
  None = 0x0,                         //!< No side
  Top = 0x1,                          //!< Top side
  Bottom = 0x2,                       //!< Bottom side
  Left = 0x4,                         //!< Left side
  Right = 0x8,                        //!< Right side
  CenterX = 0x10,                     //!< Center horiziontally
  CenterY = 0x20,                     //!< Center vertically
  CenterXY = (CenterX | CenterY),     //!< (CenterX | CenterY)
  Verticals = (Left | Right),         //!< (Left | Right)
  Horizontals = (Top | Bottom),       //!< (Top | Bottom)
  All = (Top | Bottom | Left | Right) //!< All sides
};

/*! \brief Enumeration that specifies a vertical alignment.
 *
 * When used with setVerticalAlignment(), this applies only
 * to inline widgets and determines how to position itself on the
 * current line, with respect to sibling inline widgets.
 *
 * When used with WTableCell::setContentAlignment(), this determines the
 * vertical alignment of contents within the table cell.
 *
 * When used with WPainter::drawText(), this determines the vertical alignment
 * of the text with respect to the bounding rectangle.
 *
 * Not all values are applicable in all situations. The most commonly
 * used values are AlignBottom, AlignMiddle and AlignTop.
 */
enum VerticalAlignment {
  /*! \brief Align at baseline (default alignment).
   */
  AlignBaseline=0x0,
  /*! \brief Align below the baseline (as if subscript).
   */
  AlignSub=0x10,
  /*! \brief Align above the baseline (as if superscript).
   */
  AlignSuper=0x20,
  /*! \brief Align top of widget with top of tallest sibling widget.
   */
  AlignTop=0x30,
  /*! \brief Align top of widget with the top of the parent widget's font.
   */
  AlignTextTop=0x40,
  /*! \brief Align the middle to the middle of the parent widget.
   */
  AlignMiddle=0x50, 
  /*! \brief Align bottom of widget to the bottom of the lowest sigling widget.
   */
  AlignBottom=0x60,
  /*! \brief Align bottom of widget to the bottom of parent widget's font.
   */
  AlignTextBottom=0x70,
  AlignLength=0x80 // ?
};

/*! \brief Enumeration that specifies a horizontal alignment.
 *
 * When used with WContainerWidget::setContentAlignment(), this specifies how
 * contents should be aligned horizontally within the container.
 *
 * When used with WPainter::drawText(), this determines the horizontal
 * alignment of the text with respect to the bounding rectangle.
 *
 * Not all values are applicable in all situations. The most commonly
 * used values are AlignLeft, AlignCenter and AlignRight.
 */
enum HorizontalAlignment {
  AlignLeft=0x1,   //!< Align children to the left
  AlignRight=0x2,  //!< Align children to the right
  AlignCenter=0x3, //!< Align children to the center
  AlignJustify=0x4 //!< Justify children left and right
};

/*! \brief Enumeration that specifies a layout mechanism for a widget.
 *
 * The layout mechanism determines how the widget positions itself relative
 * to the parent or sibling widgets.
 *
 * \sa setPositionScheme(PositionScheme scheme)
 */
enum PositionScheme {
  /*! \brief Static position scheme.
   * 
   *  The widget is layed-out with other \link Wt::Static
   *  Static \endlink and \link Wt::Relative Relative \endlink
   *  sibling widgets, one after another.
   *
   *  Inline widgets are layed out in horizontal lines (like text),
   *  wrapping around at the end of the line to continue on the next
   *  line. Stacked widgets are stacked vertically.
   *
   *  Static widgets may also float to the left or right border,
   *  using setFloatSide().
   */
  Static,
  /*! \brief Relative position scheme.
   *
   *  The widget is first layed out according to Static layout
   *  rules, but after layout, the widget may be offset relative to
   *  where it would be in a static layout, using setOffsets().
   *
   *  Another common use of a Relative position scheme (even with no
   *  specified offsets) is to provide a new reference coordinate
   *  system for Absolutely positioned widgets.
   */
  Relative,
  /*! \brief Absolute position scheme.
   *
   *  The widget is positioned at an absolute position
   *  with respect to the nearest ancestor widget that is either:
   *  <ul>
   *    <li> a WTableCell </li>
   *    <li> or has a position scheme that is \link Wt::Relative
   *  Relative\endlink or \link Wt::Absolute Absolute\endlink. </li>
   *  </ul>
   */
  Absolute,
  /*! \brief Fixed position scheme.
   *
   *  The widget is positioned at fixed position with respect to
   *  the browser's view-pane.
   */
  Fixed
};

/*! \brief Cursor style
 *
 * \sa WCssDecorationStyle::setCursor(), WImageArea::setCursor()
 */
enum Cursor {
  ArrowCursor,        //!< Arrow, CSS 'default' cursor
  AutoCursor,         //!< Cursor chosen by the browser, CSS 'auto' cursor.
  CrossCursor,        //!< Crosshair, CSS 'cross' cursor
  PointingHandCursor, //!< Pointing hand, CSS 'pointer' cursor
  OpenHandCursor,     //!< Open hand, CSS 'move' cursor
  WaitCursor,         //!< Wait, CSS 'wait' cursor
  IBeamCursor,        //!< Text edit, CSS 'text' cursor
  WhatsThisCursor     //!< Help, CSS 'help' cursor
};

/*! \class WWidget Wt/WWidget Wt/WWidget
 *  \brief A %WWidget is the abstract base class for any %Wt widget.
 *
 * The user-interface is organized in a tree structure, in which all nodes
 * are widgets. When the parent widget is deleted, all children are deleted
 * likewise. All widgets, except for the application's root widget
 * have a parent, which is usually a WContainerWidget.
 *
 * %WWidget is abstract and cannot be instantiated. Implementations
 * either from WWebWidget (for basic widgets with a direct HTML
 * counter-part) or WCompositeWidget (for anything else). To add a
 * WWebWidget to a parent WContainerWidget, either specify the parent
 * in the constructor, or add the widget to the parent using
 * WContainerWidget::addWidget(WWidget *).
 *
 * A widget provides methods to manage its decorative style. It also
 * provides access to CSS-based layout. Alternatively, you may use
 * layout managers (see WContainerWidget::setLayout()) to manage
 * layout of widgets, in which case you should not use methods that
 * are marked as being involved in CSS-based layout only.
 */
class WT_API WWidget : public WResource
{
public:
  typedef Wt::Side Side;
  static const Side None = Wt::None;
  static const Side Top = Wt::Top;
  static const Side Bottom = Wt::Bottom;
  static const Side Left = Wt::Left;
  static const Side Right = Wt::Right;
  static const Side CenterX = Wt::CenterX;
  static const Side CenterY = Wt::CenterY;
  static const Side CenterXY = Wt::CenterXY;
  static const Side Verticals = Wt::Verticals;
  static const Side Horizontals = Wt::Horizontals;
  static const Side All = Wt::All;

  typedef Wt::VerticalAlignment VerticalAlignment;
  static const VerticalAlignment AlignBaseline = Wt::AlignBaseline;
  static const VerticalAlignment AlignSub = Wt::AlignSub;
  static const VerticalAlignment AlignSuper = Wt::AlignSuper;
  static const VerticalAlignment AlignTop = Wt::AlignTop;
  static const VerticalAlignment AlignTextTop = Wt::AlignTextTop;
  static const VerticalAlignment AlignMiddle = Wt::AlignMiddle;
  static const VerticalAlignment AlignBottom = Wt::AlignBottom;
  static const VerticalAlignment AlignTextBottom = Wt::AlignTextBottom;
  static const VerticalAlignment AlignLength = Wt::AlignLength;

  typedef Wt::HorizontalAlignment HorizontalAlignment;
  static const HorizontalAlignment AlignLeft = Wt::AlignLeft;
  static const HorizontalAlignment AlignRight = Wt::AlignRight;
  static const HorizontalAlignment AlignCenter = Wt::AlignCenter;
  static const HorizontalAlignment AlignJustify = Wt::AlignJustify;

  typedef Wt::PositionScheme PositionScheme;
  static const PositionScheme Static = Wt::Static;
  static const PositionScheme Relative = Wt::Relative;
  static const PositionScheme Absolute = Wt::Absolute;
  static const PositionScheme Fixed = Wt::Fixed;

  /*! \brief Delete a widget.
   *
   * Deletes a widget and all children (recursively). If the widget is
   * contained in another widget, it is removed first.
   *
   * \sa WContainerWidget::removeWidget()
   */
  virtual ~WWidget();

  /*! \brief Return the parent widget.
   *
   * With few exceptions, the parent is a WContainerWidget, and has
   * been set implicitly when adding the widget to a container using
   * WContainerWidget::addWidget() or by passing a container as a
   * parent to the constructor.
   */
  WWidget *parent() const { return dynamic_cast<WWidget *>(WObject::parent()); }

  /*! \brief Set the widget position scheme.
   *
   * Establishes how the widget must be layed-out relative to its
   * siblings. The default position scheme is Static.
   *
   * This applies to CSS-based layout.
   *
   * \sa Wt::PositionScheme, positionScheme()
   */
  virtual void setPositionScheme(PositionScheme scheme) = 0;

  /*! \brief Returns the widget position scheme.
   *
   * This applies to CSS-based layout.
   *
   * \sa Wt::PositionScheme, setPositionScheme(PositionScheme)
   */
  virtual PositionScheme positionScheme() const = 0;

  /*! \brief Apply offsets to a widget.
   *
   * The argument <i>sides</i> may be a logical concatenation of \link
   * Wt::Left Left\endlink, \link Wt::Right Right\endlink, \link
   * Wt::Top Top\endlink, and \link Wt::Bottom Bottom\endlink.
   *
   * This applies only to widgets that have a position scheme that is
   * \link Wt::Relative Relative\endlink, \link Wt::Absolute
   * Absolute\endlink, or \link Wt::Fixed Fixed\endlink, and has
   * a slightly different meaning for these three cases.
   *
   * For a relatively positioned widget, an offset applies relative to
   * the position the widget would have when layed-out using a \link
   * Wt::Static Static\endlink position scheme. The widget may be
   * shifted to the left or right by specifying an offset to the \link
   * Wt::Left Left\endlink or \link Wt::Right
   * Right\endlink). The widget may be shifted vertically, by
   * specifying an offset for the \link Wt::AlignTop Top\endlink
   * or \link Wt::Bottom Bottom\endlink.
   *
   * For an absolutely positioned widget, an offset specifies a
   * distance of the corresponding side of the widget with respect to
   * the corresponding side of the reference parent widget. Thus,
   * setting all offsets to 0 result in a widget that spans the entire
   * reference widget. The reference parent widget is the first
   * ancestor widget that is a table cell, or a widget with a relative,
   * absolute or fixed position scheme.
   *
   * For an fixed positioned widget, an offset specifies a distance of
   * the corresponding side of the widget with respect to the browser
   * window, regardless of scrolling. Thus, setting all offsets to 0
   * result in a widget that spans the entire browser window.
   *
   * This applies to CSS-based layout.
   *
   * \sa offset(Side) const
   */
  virtual void setOffsets(const WLength& offset, int sides = All) = 0;

  /*! \brief Apply offsets to a widget (<b>deprecated</b>).
   *
   * \deprecated use setOffsets(const WLength&, int) instead.
   *
   * This applies to CSS-based layout.
   *
   * \sa setOffsets(const WLength&, int)
   */
  void setOffset(int sides, const WLength& offset);

  /*! \brief Retrieve the offset of the widget.
   *
   * This applies to CSS-based layout.
   *
   * \sa setOffsets(const WLength&, int)
   */
  virtual WLength offset(Side side) const = 0;

  /*! \brief Resize the widget.
   *
   * Specify a new size for this widget, by specifying width and height.
   * By default a widget has automatic width and height, see WLength::isAuto().
   *
   * This applies to CSS-based layout.
   *
   * \sa width(), height()
   */
  virtual void resize(const WLength& width, const WLength& height) = 0;

  /*! \brief Returns the widget width.
   *
   * Return the width set for this widget. This is not a calculated width,
   * based on layout, but the width as specified with
   * resize(const WLength&, const WLength&).
   *
   * This applies to CSS-based layout.
   *
   * \sa resize(const WLength&, const WLength&), height()
   */
  virtual WLength width() const = 0;

  /*! \brief Returns the widget height.
   *
   * Return the height set for this widget. This is not a calculated height,
   * based on layout, but the height as specified previously with
   * resize(const WLength& width, const WLength& height).
   *
   * This applies to CSS-based layout.
   *
   * \sa resize(const WLength&, const WLength&), width()
   */
  virtual WLength height() const = 0;

  /*! \brief Set a minimum size.
   *
   * Specify a minimum size for this widget. When the widget is
   * managed using a layout manager, these sizes are also taken into
   * account.
   *
   * \sa resize(), minimumWidth(), minimumHeight()
   */
  virtual void setMinimumSize(const WLength& width, const WLength&) = 0;

  /*! \brief Returns the minimum width.
   *
   * Return the minimum width set for this widget with setMinimumSize().
   *
   * \sa setMinimumSize(), minimumHeight()
   */
  virtual WLength minimumWidth() const = 0;

  /*! \brief Returns the minimum height.
   *
   * Return the minmum height set for this widget with setMinimumSize().
   *
   * \sa setMinimumSize(), minimumWidth()
   */
  virtual WLength minimumHeight() const = 0;

  /*! \brief Set a maximum size.
   *
   * Specify a minimum size for this widget.
   *
   * \sa resize(), maximumWidth(), maximumHeight()
   */
  virtual void setMaximumSize(const WLength& width, const WLength& height) = 0;

  /*! \brief Returns the maximum width.
   *
   * Return the maximum width set for this widget with setMaximumSize().
   *
   * \sa setMaximumSize(), maximumHeight()
   */
  virtual WLength maximumWidth() const = 0;

  /*! \brief Returns the maximum height.
   *
   * Return the minmum height set for this widget with setMaximumSize().
   *
   * \sa setMaximumSize(), maximumWidth()
   */
  virtual WLength maximumHeight() const = 0;

  /*! \brief Set the line height for contained text.
   */
  virtual void setLineHeight(const WLength& height) = 0;

  /*! \brief Return the line height for contained text.
   *
   * sa setLineHeight()
   */
  virtual WLength lineHeight() const = 0;

  /*! \brief Specify a side to which the WWidget must float.
   *
   * This only applies to widgets with a \link Wt::Static Static
   * \endlink positionScheme().
   *
   * It specifies if the widget must be positioned on one of the sides
   * of the parent widget, at the current line. A typical use is to
   * position images within text. Valid values for Side or \link
   * Wt::None None \endlink, \link Wt::Left Left \endlink or \link
   * Wt::Right Right \endlink.
   *
   * This applies to CSS-based layout.
   */
  virtual void setFloatSide(Side s) = 0;

  /*! \brief Return the float side.
   *
   * \sa setFloatSide(Side)
   */
  virtual Side floatSide() const = 0;

  /*! \brief Set the sides that should be cleared of floats.
   *
   * This pushes the widget down until it is not surrounded by floats
   * at the <i>sides</i> (which may be a logical OR of \link Wt::Left
   * Left\endlink and \link Wt::Right Right\endlink.
   * 
   * This applies to CSS-based layout.
   *
   * \sa setFloatSide()
   */
  virtual void setClearSides(int sides) = 0;

  /*! \brief Returns the sides that should remain empty.
   *
   * \sa setClearSides(int)
   */
  virtual int clearSides() const = 0;

  /*! \brief Set margins around the widget.
   *
   * Setting margin has the effect of adding a distance between the widget
   * and surrounding widgets. The default margin (with an automatic length)
   * is zero.
   *
   * Use any combination of \link Wt::Left Left \endlink,
   * \link Wt::Right Right \endlink,
   * \link Wt::Bottom Bottom \endlink,
   * or \link Wt::Top Top \endlink.
   *
   * This applies to CSS-based layout.
   *
   * \sa margin(Side side);
   */
  virtual void setMargin(const WLength& margin, int sides = All) = 0;

  /*! \brief Returns the margin set for that side.
   *
   * This applies to CSS-based layout.
   *
   * \sa setMargin(WLength margin, int sides);
   */
  virtual WLength margin(Side side) const = 0;

  /*! \brief Set whether the widget must be hidden.
   *
   * Hide or show the widget (including all its descendant widgets).
   * setHidden(false) will show this widget and all child widgets that
   * are not hidden.
   *
   * \sa hide(), show()
   */
  virtual void setHidden(bool) = 0;

  /*! \brief Return whether this widget is set hidden.
   *
   * A widget that is not hidden may still be not visible when one
   * of its ancestor widgets are hidden.
   *
   * \sa setHidden()
   */
  virtual bool isHidden() const = 0;

  /*! \brief Set whether this widget is overlayed on the parent widget.
   *
   * This option only applies to widgets with a \link
   * Wt::Absolute Absolute \endlink or \link Wt::Fixed Fixed
   * \endlink positionScheme().
   *
   * This applies to CSS-based layout.
   *
   * A widget that isPopup() will be rendered on top of the parent widget.
   */
  virtual void setPopup(bool) = 0;

  /*! \brief Returns whether this widget is overlayed.
   *
   * This applies to CSS-based layout.
   *
   * \sa setPopup(bool)
   */
  virtual bool isPopup() const = 0;

  /*! \brief Set whether this widget is inline or stacked.
   *
   * This option changes whether this widget must be rendered in-line
   * with sibling widgets wrapping at the right edge of the parent
   * container (like text), or whether this widget must be stacked
   * vertically with sibling widgets. Depending on the widget type,
   * the default value is inline (such as for example for WText, or
   * WPushButton), or stacked (such as for example for WTable).
   *
   * This applies to CSS-based layout.
   */
  virtual void setInline(bool) = 0;

  /*! \brief Returns whether this widget is inline or stacked.
   *
   * \sa setInline(bool)
   */
  virtual bool isInline() const = 0;

  /*! \brief Returns the decoration style of this widget.
   *
   * This groups all decorative aspects of the widget, which do not
   * affect the widget layout (except for the border properties which
   * may behave like extra margin around the widget).
   */
  virtual WCssDecorationStyle& decorationStyle() = 0;

  /*! \brief Sets a style class.
   *
   * The CSS style class works in conjunction with style sheet, and
   * provides a flexible way to provide many widgets the same markup.
   *
   * Setting an empty string removes the style class.
   * 
   * \sa WApplication::styleSheet()
   */
  virtual void setStyleClass(const WString& styleClass) = 0;

  void setStyleClass(const char *styleClass);

  /*! \brief Returns the style class.
   *
   * \sa setStyleClass(const WString&)
   */
  virtual WString styleClass() const = 0;

  /*! \brief Set the vertical alignment of this (inline) widget.
   *
   * This only applies to inline widgets, and determines how to position
   * itself on the current line, with respect to sibling inline widgets.
   *
   * This applies to CSS-based layout.
   */
  virtual void setVerticalAlignment(VerticalAlignment alignment,
				    const WLength& length = WLength()) = 0;

  /*! \brief Returns the vertical alignment.
   *
   * This applies to CSS-based layout.
   *
   * \sa setVerticalAlignment()
   */
  virtual VerticalAlignment verticalAlignment() const = 0;

  /*! \brief Returns the fixed vertical alignment that was set.
   *
   * This applies to CSS-based layout.
   *
   * \sa setVerticalAlignment()
   */
  virtual WLength verticalAlignmentLength() const = 0;

  virtual WWebWidget *webWidget() = 0;

  /*! \brief Sets a tooltip.
   *
   * The tooltip is displayed when the cursor hovers over the widget.
   */
  virtual void setToolTip(const WString& text) = 0;

  /*! \brief Returns the tooltip text.
   */
  virtual WString toolTip() const = 0;

  /*! \brief Refresh the widget.
   *
   * The refresh method is invoked when the locale is changed using
   * WApplication::setLocale() or when the user hit the refresh button.
   *
   * The widget must actualize its contents in response.
   */
  virtual void refresh() = 0;

  /*! \brief A JavaScript expression that returns the corresponding DOM node.
   *
   * You may want to use this in conjunction with JSlot or
   * WApplication::doJavaScript() in custom JavaScript code.
   */
  std::string jsRef() const;

  /*! \brief Set an attribute value.
   *
   * Associate an extra attribute with this widget, with the given value.
   * This is only useful when processing dom nodes associated with widgets
   * in custom JavaScript code.
   *
   * \sa JSlot, WApplication::doJavaScript()
   */
  virtual void setAttributeValue(const std::string& name,
				 const WString& value) = 0;

  /*! \brief Short hand for WString::tr()
   *
   * Create a message with the given key.
   */
  static WString tr(const char *key);

  /*! \brief Load content just before the widget's content is rendered.
   *
   * As soon as a widget is inserted into the widget hierarchy, it is
   * rendered. Visible widgets are rendered immediately, and invisible
   * widgets in the back-ground. This method is called when the widget
   * is directly or indirectly inserted into the widget tree.
   *
   * The default implementation simply propagates the load signal to its
   * children. You may want to override this method to load resource-intensive
   * content only when the widget is loaded into the browser.
   */
  virtual void load() = 0;

  /*! \brief Return if this widget has been loaded.
   *
   * \sa load()
   */
  virtual bool loaded() const = 0;

  /*! \brief Set a mime type to be accepted for dropping.
   *
   * You may specify a style class that is applied to the widget when the
   * specified mimetype hovers on top of it.
   *
   * \sa dropEvent(), WInteractWidget::setDraggable(), stopAcceptDrops()
   */
  virtual void acceptDrops(const std::string& mimeType,
			   const WString& hoverStyleClass = WString());

  /*! \brief No longer accept a mime type for dropping.
   *
   * \sa acceptDrops()
   */
  virtual void stopAcceptDrops(const std::string& mimeType);

  /*! \brief Set the CSS Id.
   *
   * Sets a custom Id. Note that the Id must be unique across the whole
   * widget tree, can only be set right after construction and cannot
   * be changed.
   *
   * \sa WObject::id()
   */
  virtual void setId(const std::string& id) = 0;

  /*! \brief Stream the (X)HTML representation.
   *
   * Streams the widget as UTF8-encoded (HTML-compatible) XHTML.
   *
   * This may be useful as a debugging tool for the web-savvy, or in
   * other rare situations. Usually, you will not deal directly with
   * HTML, and calling this method on a widget that is rendered may
   * interfere with the library keeping track of changes to the
   * widget.
   */
  virtual void htmlText(std::ostream& out);

  std::string inlineCssStyle();

  std::string createJavaScript(std::stringstream& js,
			       const std::string& insertJS);

  Signal<WWidget *> destroyed;

public slots:

  /*! \brief Hide this WWidget.
   *
   * \sa setHidden(bool)
   */
  void hide();

  /*! \brief Show this WWidget.
   *
   * \sa setHidden(bool)
   */
  void show();

protected:
  /*! \brief Create a widget with a given parent.
   *
   * If a parent container is specified, the widget is added to the
   * container, using WContainerWidget::addWidget().
   */
  WWidget(WContainerWidget* parent = 0);

  std::string resourceTriggerUpdate_;

  /*! \brief Handle a drop event.
   *
   * Reimplement this method to handle a drop events for mime types you
   * declared to accept using acceptDrops.
   *
   * The default implementation simply completes the drag and drop operation
   * as if nothing happened.
   *
   * \sa acceptDrops(), WInteractWidget::setDraggable()
   */
  virtual void dropEvent(WDropEvent dropEvent);
  void getDrop(const std::string sourceId, const std::string mimeType,
	       WMouseEvent event);

  virtual void addChild(WWidget *child) = 0;
  virtual void removeChild(WWidget *child) = 0;
  virtual void setHideWithOffsets(bool how = true) = 0;

  virtual void setParent(WWidget *parent);

  virtual bool isVisible() const = 0;
  virtual bool isStubbed() const = 0;

  WWidget *adam();

  /*
   * Implement the resource methods.
   */
  virtual const std::string resourceMimeType() const;
  virtual void setArguments(const ArgumentMap& arguments);
  virtual bool streamResourceData(std::ostream& stream,
				  const ArgumentMap& arguments);
  virtual void setLayout(WLayout *layout);

private:
  bool     wasHidden_;

  void undoHideShow();

  virtual WLayoutItemImpl  *createLayoutItemImpl(WLayoutItem *layout);
  virtual WLayout          *layout();

  friend class WebRenderer;

  friend class WAbstractArea;
  friend class WContainerWidget;
  friend class WCompositeWidget;
  friend class WLayout;
  friend class WPaintedWidget;
  friend class WScrollArea;
  friend class WWebWidget;
  friend class WWidgetItem;
};

}

#endif // WWIDGET_H_
