// 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_FORMFIELD_H_
#define EXT_FORMFIELD_H_

#include <Wt/Ext/Component>
#include <Wt/WValidator>
#include <sstream>

namespace Wt {

  class WLabel;
  class WFormWidget;

  namespace Ext {

/*! \class FormField Wt/Ext/FormField Wt/Ext/FormField
 *  \brief An abstract base class for form fields.
 *
 * \ingroup ext
 */
class WT_EXT_API FormField : public Component
{
protected:
  /*! \brief Create a form field.
   */
  FormField(WContainerWidget *parent = 0);

public:
  /*! \brief The location of the validation error message.
   */
  enum MessageLocation { 
    FancyToolTip,  //!< Display in a fancy (JavaScript) tool tip
    PlainToolTip,  //!< Display in a plain HTML tool tip
    Below,         //!< Display below the field
    Besides        //!< Display next to the field
  };

  /*! \brief Set the location of the validation error message.
   */
  void setErrorMessageLocation(MessageLocation location);

  /*! \brief Set a validator.
   *
   * The validator will be used for both client side and server side
   * validation (if it is, or inherits from, one of the four
   * validators provided by %Wt: WDateValidator, WDoubleValidator,
   * WIntValidator, WLengthValidator, WRegExpValidator).
   *
   * If the validator has no parent yet, ownership of the validator is
   * transferred to the form field.
   *
   * \sa validate()
   */
  void setValidator(WValidator *validator);

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

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

  /*! \brief Return the label associate with this formfield
   *
   * Returns the label (if there is one) that acts as a proxy for this widget.
   *
   * \sa WLabel::setBuddy(Ext::FormField *)
   */
  WLabel *label() const;

  /*! \brief Give focus to this widget.
   */
  void setFocus();

  virtual void refresh();

  /*! \brief Signal emitted when the value was changed.
   */
  EventSignal<>& changed();

  /*! \brief Signal emitted when the widget lost focus.
   */
  EventSignal<>& blurred();

  /*! \brief Signal emitted when the widget recieved focus.
   */
  EventSignal<>& focussed();

protected:
  void applyToWidget(WWebWidget *widget, std::stringstream& js,
		     DomElement *inContainer);

  void createConfig(std::ostream& config);

  virtual WFormWidget *formWidget() const = 0;

  virtual void render(WFlags<RenderFlag> flags);

private:
  MessageLocation  errorMessageLocation_;
  WValidator      *validator_;
  bool             focusWhenRendered_;

  virtual void useAsTableViewEditor() = 0;
  friend class TableView;
  friend class Wt::WLabel;
};

  }
}

#endif // EXT_FORMFIELD_H_
