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

#include <Wt/WFormWidget>

namespace Wt {

/*! \class WLineEdit Wt/WLineEdit Wt/WLineEdit
 *  \brief A widget that provides a single line edit.
 *
 * To act upon text changes, connect a slot to the changed()
 * signal. This signal is emitted when the user changed the content,
 * and subsequently removes the focus from the line edit.
 *
 * To act upon editing, connect a slot to the keyWentUp() signal because the
 * keyPressed() signal is fired before the line edit has interpreted the 
 * keypress to change its text.
 *
 * At all times, the current content may be accessed with the text()
 * method.
 *
 * You may specify a maximum length for the input using
 * setMaxLength(). If you wish to provide more detailed input
 * validation, you may set a validator using the
 * setValidator(WValidator *) method. Validators provide, in general,
 * both client-side validation (as visual feed-back only) and
 * server-side validation when calling validate().
 *
 * \if cpp
 * Usage example:
 * \code
 * Wt::WContainerWidget *w = new Wt::WContainerWidget();
 * Wt::WLabel *label = new Wt::WLabel("Age:", w);
 * Wt::WLineEdit *edit = new Wt::WLineEdit("13", w);
 * edit->setValidator(new Wt::WIntValidator(0, 200));
 * label->setBuddy(edit);
 * \endcode
 * \endif
 *
 * The widget corresponds to the HTML <tt>&lt;input type="text"&gt;</tt> or
 * <tt>&lt;input type="password"&gt;</tt> tag.
 *
 * %WLineEdit is an \link WWidget::setInline(bool) inline \endlink widget.
 *
 * <h3>CSS</h3>
 *
 * The emptyText style can be configured via .Wt-edit-emptyText,
 * other styling can be done using inline or external CSS as appropriate.
 *
 * \sa WTextArea
 */
class WT_API WLineEdit : public WFormWidget
{
public:
  /*! \brief Enumeration that describes how the contents is displayed.
   *
   * \sa setEchoMode(EchoMode)
   */
  enum EchoMode { Normal,   //!< Characters are shown.
		  Password  //!< Hide the contents as for a password.
  };

  /*! \brief Creates a line edit with empty content and optional parent.
   */
  WLineEdit(WContainerWidget *parent = 0);

  /*! \brief Creates a line edit with given content and optional parent.
   */
  WLineEdit(const WT_USTRING& content, WContainerWidget *parent = 0);

  /*! \brief Specifies the width of the line edit in number of characters.
   *
   * This specifies the width of the line edit that is roughly
   * equivalent with \p chars characters. This does not limit the
   * maximum length of a string that may be entered, which may be set
   * using setMaxLength(int).
   *
   * The default value is 10.
   */
  void setTextSize(int chars);

  /*! \brief Returns the current width of the line edit in number of characters.
   *
   * \sa setTextSize(int)
   */
  int textSize() const { return textSize_; }

  /*! \brief Sets the content of the line edit.
   *
   * The default value is "".
   *
   * \sa text()
   */
  virtual void setText(const WT_USTRING& text);

  /*! \brief Returns the current content.
   *
   * \sa setText()
   */
  const WT_USTRING& text() const { return content_; }

  /*! \brief Specifies the maximum length of text that can be entered.
   *
   * A value <= 0 indicates that there is no limit.
   *
   * The default value is -1.
   */
  void setMaxLength(int length);

  /*! \brief Returns the maximum length of text that can be entered.
   *
   * \sa setMaxLength(int)
   */
  int maxLength() const { return maxLength_; }

  /*! \brief Sets the echo mode.
   *
   * The default echo mode is Normal.
   */
  void setEchoMode(EchoMode echoMode);

  /*! \brief Returns the echo mode.
   *
   * \sa setEchoMode(EchoMode)
   */
  EchoMode echoMode() const { return echoMode_; }

  /*! \brief Returns the current selection start.
   *
   * Returns -1 if there is no selected text.
   *
   * \sa hasSelectedText(), selectedText()
   */
  int selectionStart() const;

  /*! \brief Returns the currently selected text.
   *
   * Returns an empty string if there is currently no selected text.
   *
   * \sa hasSelectedText()
   */
  WT_USTRING selectedText() const;

  /*! \brief Returns whether there is selected text.
   *
   * \sa selectedtext()
   */
  bool hasSelectedText() const;

  /*! \brief Returns the current cursor position.
   *
   * Returns -1 if the widget does not have the focus.
   */
  int cursorPosition() const;

  /*! \brief Returns the current value.
   *
   * Returns text().
   */
  virtual WT_USTRING valueText() const;

  /*! \brief Sets the current value.
   *
   * Calls setText().
   */
  virtual void setValueText(const WT_USTRING& value);

private:
  WT_USTRING content_;
  int        textSize_;
  int        maxLength_;
  EchoMode   echoMode_;

  static const int BIT_CONTENT_CHANGED    = 0;
  static const int BIT_TEXT_SIZE_CHANGED  = 1;
  static const int BIT_MAX_LENGTH_CHANGED = 2;
  static const int BIT_ECHO_MODE_CHANGED  = 3;

  std::bitset<4> flags_;

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

  virtual int boxPadding(Orientation orientation) const;
  virtual int boxBorder(Orientation orientation) const;
};

}

#endif // WLINEEDIT_H_
