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

#include <WInteractWidget>
#include <WValidator>

namespace Wt {

class WLabel;

/*! \class WFormWidget WFormWidget WFormWidget
 *  \brief A WWidget that correspond to an HTML form element.
 *
 * A %WFormWidget may receive focus, can be disabled, and can have a
 * label that acts as proxy for getting focus. It provides signals
 * which reflect changes to its value, or changes to its focus.
 */
class WT_API WFormWidget : public WInteractWidget
{
public:
  /*! \brief Construct a WFormWidget with an optional parent.
   */
  WFormWidget(WContainerWidget *parent = 0);

  /*! \brief Destroy a WFormWidget.
   *
   * If a label was associated with the widget, the label is updated
   * as well to indicate the loss of the buddy.
   */
  ~WFormWidget();

  /*! \brief Get the label associated with this widget.
   *
   * Returns the label (if there is one) that acts as a proxy for this widget.
   *
   * \sa WLabel::setBuddy(WFormWidget *)
   */
  WLabel *label() const { return label_; }

  /*! \brief Set the hidden state of this widget.
   *
   * If the widget has a label, it hidden or shown together with this
   * widget.
   */
  void setHidden(bool hidden);

  /*! \brief Return whether the widget is enabled.
   */
  bool isEnabled() const { return enabled_; }

  /*! \brief Set a validator for this field.
   *
   * The validator is used to validate the current input.
   *
   * Ownership of the validator is transferred to the form field, and
   * thus the validator will be deleted together with the form field.
   */
  void setValidator(WValidator *validator);

  /*! \brief Get the validator.
   */
  WValidator *validator() const { return validator_; }

  /*! \brief Validate the field.
   */
  virtual WValidator::State validate();

public slots:
  /*! \brief Change the enabled state of the widget.
   *
   * A widget that is disabled cannot receive focus or user interaction.
   */
  void setEnabled(bool enabled);

  /*! \brief Enable the widget.
   *
   * \sa setEnabled(bool)
   */
  void enable();

  /*! \brief Disable the widget.
   *
   * \sa setEnabled(bool)
   */
  void disable();

public:
  /*! \brief Signal emitted when the value was changed.
   */
  EventSignal<void> changed;
  /*! \brief Signal emitted when ??
   */
  EventSignal<void> selected;
  /*! \brief Signal emitted when the widget lost focus.
   */
  EventSignal<void> blurred;
  /*! \brief Signal emitted when the widget recieved focus.
   */
  EventSignal<void> focussed;

protected:
  WLabel     *label_;
  bool        enabled_;
  WValidator *validator_;

private:
  bool enabledChanged_;
  bool wasEnabled_;

  void undoEnable();
  void undoDisable();

  void setLabel(WLabel *label);

protected:
  void updateDom(DomElement& element, bool all);

  friend class WLabel;
};

}

#endif // WFORM_WIDGET_H_
