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

#include <Wt/WInteractWidget>

namespace Wt {

  class WFormWidget;
  class WImage;
  class WText;

  namespace Ext {

    class FormField;

  }

/*! \class WLabel Wt/WLabel Wt/WLabel
 *  \brief A label for a form field.
 *
 * The label may contain an image and/or text. It acts like a proxy
 * for giving focus to a WFormWidget. When both an image and text are
 * specified, the image is put to the left of the text.
 *
 * Usage example:
 * \if cpp
 * \code
 * Wt::WContainerWidget *w = new Wt::WContainerWidget();
 * Wt::WLabel *label = new Wt::WLabel("Favourite Actress: ", w);
 * Wt::WLineEdit *edit = new Wt::WLineEdit("Renee Zellweger", w);
 * label->setBuddy(edit);
 * \endcode
 * \elseif java
 * \code
 * WContainerWidget w = new WContainerWidget();
 * WLabel label = new WLabel("Favourite Actress: ", w);
 * WLineEdit edit = new WLineEdit("Renee Zellweger", w);
 * label.setBuddy(edit);
 * \endcode
 * \endif
 *
 * The widget corresponds to the HTML <tt>&lt;label&gt;</tt> tag. When
 * no buddy is set, it is rendered using an HTML <tt>&lt;span&gt;</tt>
 * or <tt>&lt;div&gt;</tt> to avoid click event handling misbehavior
 * on Microsoft Internet Explorer.
 *
 * %WLabel is an \link WWidget::setInline(bool) inline \endlink widget.
 *
 * <h3>CSS</h3>
 * 
 * This widget does not provide styling, and can be styled using
 * inline or external CSS as appropriate.  A label's text may be
 * styled via a nested <tt>&lt;span&gt;</tt> element, and it's
 * image may be styled via a nested <tt>&lt;img&gt;</tt> element.
 */
class WT_API WLabel : public WInteractWidget
{
public:
  /*! \brief Creates a label with empty text and optional parent.
   */
  WLabel(WContainerWidget *parent = 0);

  /*! \brief Creates a label with a given text.
   */
  WLabel(const WString& text, WContainerWidget *parent = 0);

  /*! \brief Creates a label with an image.
   */
  WLabel(WImage *image, WContainerWidget *parent = 0);

  ~WLabel();

  /*! \brief Returns the buddy of this label.
   *
   * \sa setBuddy(WFormWidget *)
   */
  WFormWidget *buddy() const { return buddy_; }

  /*! \brief Sets the buddy of this label.
   *
   * Sets the buddy FormWidget for which this label acts as a proxy.
   * 
   * \if cpp
   * \sa WFormWidget::label(), setBuddy(Ext::FormField *), buddy()
   * \elseif java
   * \sa WFormWidget::label(), buddy()
   * \endif 
   */
  void setBuddy(WFormWidget *buddy);

  #ifndef WT_TARGET_JAVA
  /*! \brief Sets the buddy of this label.
   *
   * Sets the buddy Ext::FormField for which this label acts as a proxy.
   * When using this method, the result of buddy() is not defined.
   *
   * \sa Ext::FormField::label(), setBuddy(WFormWidget *)
   */
  void setBuddy(Ext::FormField *buddy);
  #endif //WT_TARGET_JAVA

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

  /*! \brief Returns the label text.
   */
  const WString& text() const;

  /*! \brief Sets the text format.
   *
   * The textFormat controls how the string should be interpreted:
   * either as plain text, which is displayed literally, or as
   * XHTML-markup.
   *
   * When changing the textFormat to Wt::XHTMLText, and the
   * current text is literal (not created using WString::tr()), the
   * current text is parsed using an XML parser which discards
   * malicious tags and attributes silently. When the parser
   * encounters an XML parse error, the textFormat is left unchanged,
   * and this method returns false.
   *
   * Returns whether the textFormat could be set for the current text.
   *
   * The default format is Wt::XHTMLText.
   */
  bool setTextFormat(TextFormat format);

  /*! \brief Returns the text format.
   *
   * \sa setTextFormat()
   */
  TextFormat textFormat() const;

  /*! \brief Sets the image.
   */
  void setImage(WImage *image, Side side = Left);

  /*! \brief Returns the image.
   */
  WImage *image() const { return image_; }

  /*! \brief Configures word wrapping.
   *
   * When \p wordWrap is \c true, the widget may break lines, creating a
   * multi-line text. When \p wordWrap is \c false, the text will displayed
   * on a single line, unless the text contains end-of-lines (for
   * Wt::PlainText) or &lt;br /&gt; tags or other block-level tags
   * (for Wt::XHTMLText).
   *
   * The default value is \c false.
   *
   * \sa wordWrap()
   */
  void setWordWrap(bool wordWrap);

  /*! \brief Returns whether word wrapping is on.
   *
   * \sa setWordWrap()
   */
  bool wordWrap() const;

private:
  WFormWidget *buddy_;
  WText  *text_;
  WImage *image_;
  Side    imageSide_;

  bool buddyChanged_, newImage_, newText_;

protected:
  virtual void           updateDom(DomElement& element, bool all);
  virtual DomElementType domElementType() const;
  virtual void           getDomChanges(std::vector<DomElement *>& result,
				       WApplication *app);
  virtual void           propagateRenderOk(bool deep);
  virtual void           propagateSetEnabled(bool enabled);

  void updateImage(DomElement& element, bool all, WApplication *app, int pos);
  void updateText(DomElement& element, bool all, WApplication *app, int pos);

  friend class WAnchor;
};

}

#endif // WLABEL_H_
