/*
 * Copyright (C) 1998-2002 The gtkmm Development Team
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include <gtkmm/widget.h>
#include <gtkmm/editable.h>
#include <gtkmm/menu.h>
#include <gtkmm/celleditable.h>
#include <gtkmm/entrycompletion.h>
#include <gtkmm/adjustment.h>
#include <gtkmm/image.h> //For ImageType.
#include <gtkmm/border.h>
#include <gtkmm/entrybuffer.h>
#include <pangomm/attrlist.h>
#include <pangomm/tabarray.h>

_DEFS(gtkmm,gtk)
_PINCLUDE(gtkmm/private/widget_p.h)

#m4begin
_PUSH(SECTION_CC_PRE_INCLUDES)
#undef GTK_DISABLE_DEPRECATED
#define GDK_DISABLE_DEPRECATION_WARNINGS 1
_POP()
#m4end

namespace Gtk
{

_WRAP_ENUM(EntryIconPosition, GtkEntryIconPosition)

/** A single line text entry field.
 *
 * The Gtk::Entry widget is a single line text entry widget. A fairly large
 * set of key bindings are supported by default. If the entered text is
 * longer than the allocation of the widget, the widget will scroll so that
 * the cursor position is visible.
 *
 * The Entry widget looks like this:
 * @image html entry1.png
 *
 * @ingroup Widgets
 */
class Entry
: public Widget,
  public Editable,
  public CellEditable
{
  _CLASS_GTKOBJECT(Entry,GtkEntry,GTK_ENTRY,Gtk::Widget,GtkWidget)
  _IMPLEMENTS_INTERFACE(Editable)
  _IMPLEMENTS_INTERFACE(CellEditable)
public:

  _CTOR_DEFAULT
  _WRAP_CTOR(Entry(const Glib::RefPtr<EntryBuffer>& buffer), gtk_entry_new_with_buffer)

  _WRAP_METHOD(Glib::RefPtr<EntryBuffer> get_buffer(), gtk_entry_get_buffer, refreturn)
  _WRAP_METHOD(Glib::RefPtr<const EntryBuffer> get_buffer() const, gtk_entry_get_buffer, refreturn, constversion)

  /** Returns the area where the entry's text is drawn.
   * This function is useful when drawing something to the entry in a draw callback.
   *
   * See also get_icon_area().
   *
   * @result The location for the text area.
   *
   * @newin{3,0}
   **/
  Gdk::Rectangle get_text_area() const;
  _IGNORE(gtk_entry_get_text_area)

  _WRAP_METHOD(void set_buffer(const Glib::RefPtr<EntryBuffer>& buffer), gtk_entry_set_buffer)
  _WRAP_METHOD(void set_visibility(bool visible = true), gtk_entry_set_visibility)
  _WRAP_METHOD(bool get_visibility() const, gtk_entry_get_visibility)
  _WRAP_METHOD(void set_invisible_char(gunichar ch), gtk_entry_set_invisible_char)
  _WRAP_METHOD(void unset_invisible_char(), gtk_entry_unset_invisible_char)
  _WRAP_METHOD(gunichar get_invisible_char() const, gtk_entry_get_invisible_char)
  _WRAP_METHOD(void set_has_frame(bool setting = true), gtk_entry_set_has_frame)
  _WRAP_METHOD(bool get_has_frame() const, gtk_entry_get_has_frame)

  _WRAP_METHOD(void set_inner_border(const Border& border), gtk_entry_set_inner_border, deprecated "Use the standard border and padding CSS properties instead (through classes like StyleContext and CssProvider).")
  _WRAP_METHOD(Border get_inner_border() const, gtk_entry_get_inner_border, deprecated "Use the standard border and padding CSS properties instead (through classes like StyleContext and CssProvider).")

  _WRAP_METHOD(void set_overwrite_mode(bool overwrite = true), gtk_entry_set_overwrite_mode)
  _WRAP_METHOD(bool get_overwrite_mode() const, gtk_entry_get_overwrite_mode)
  _WRAP_METHOD(void set_max_length(int max), gtk_entry_set_max_length)
  _WRAP_METHOD(int get_max_length() const, gtk_entry_get_max_length)
  _WRAP_METHOD(guint16 get_text_length() const, gtk_entry_get_text_length)
  _WRAP_METHOD(void set_activates_default(bool setting = true), gtk_entry_set_activates_default)
  _WRAP_METHOD(gboolean get_activates_default() const, gtk_entry_get_activates_default)
  _WRAP_METHOD(void set_width_chars(int n_chars), gtk_entry_set_width_chars)
  _WRAP_METHOD(int get_width_chars() const, gtk_entry_get_width_chars)
  _WRAP_METHOD(void set_text(const Glib::ustring &text), gtk_entry_set_text)
  _WRAP_METHOD(Glib::ustring get_text() const, gtk_entry_get_text)
  _WRAP_METHOD(Glib::RefPtr<Pango::Layout> get_layout(), gtk_entry_get_layout, refreturn)
  _WRAP_METHOD(Glib::RefPtr<const Pango::Layout> get_layout() const, gtk_entry_get_layout, refreturn, constversion)
  _WRAP_METHOD(void get_layout_offsets(int& x, int& y), gtk_entry_get_layout_offsets)

  _WRAP_METHOD(int layout_index_to_text_index(int layout_index) const, gtk_entry_layout_index_to_text_index)
  _WRAP_METHOD(int text_index_to_layout_index(int text_index) const, gtk_entry_text_index_to_layout_index)

  _WRAP_METHOD(void set_cursor_hadjustment(const Glib::RefPtr<Adjustment>& adjustment), gtk_entry_set_cursor_hadjustment)
  _WRAP_METHOD(Glib::RefPtr<Adjustment> get_cursor_hadjustment(), gtk_entry_get_cursor_hadjustment, refreturn)
  _WRAP_METHOD(Glib::RefPtr<const Adjustment> get_cursor_hadjustment() const, gtk_entry_get_cursor_hadjustment, refreturn, constversion)

  _WRAP_METHOD(void set_alignment(float xalign), gtk_entry_set_alignment)
  _WRAP_METHOD(void set_alignment(Align xalign), gtk_entry_set_alignment)
  _WRAP_METHOD(float get_alignment() const, gtk_entry_get_alignment)

  _WRAP_METHOD(void set_completion(const Glib::RefPtr<EntryCompletion>& completion), gtk_entry_set_completion)
  _WRAP_METHOD(Glib::RefPtr<EntryCompletion> get_completion(), gtk_entry_get_completion, refreturn)
  _WRAP_METHOD(Glib::RefPtr<const EntryCompletion> get_completion() const, gtk_entry_get_completion, refreturn, constversion)

  _WRAP_METHOD(void set_progress_fraction(double fraction), gtk_entry_set_progress_fraction)
  _WRAP_METHOD(double get_progress_fraction() const, gtk_entry_get_progress_fraction)
  _WRAP_METHOD(void set_progress_pulse_step(double fraction), gtk_entry_set_progress_pulse_step)
  _WRAP_METHOD(double get_progress_pulse_step(), gtk_entry_get_progress_pulse_step)
  _WRAP_METHOD(void progress_pulse(), gtk_entry_progress_pulse)

  _WRAP_METHOD(Glib::ustring get_placeholder_text() const, gtk_entry_get_placeholder_text)
  _WRAP_METHOD(void set_placeholder_text(const Glib::ustring& text), gtk_entry_set_placeholder_text)

  //We hand-code these so we can change the parameter order, so we can have a default parameter value:
  _WRAP_METHOD_DOCS_ONLY(gtk_entry_set_icon_from_pixbuf)
  void set_icon_from_pixbuf(const Glib::RefPtr<Gdk::Pixbuf>& pixbuf, EntryIconPosition icon_pos = ENTRY_ICON_PRIMARY);
  _IGNORE(gtk_entry_set_icon_from_pixbuf)

  _WRAP_METHOD(void set_icon_from_stock(const StockID& stock_id{.}, EntryIconPosition icon_pos{.} = ENTRY_ICON_PRIMARY), gtk_entry_set_icon_from_stock, deprecated "Use set_icon_from_icon_name() instead.")

  _WRAP_METHOD_DOCS_ONLY(gtk_entry_set_icon_from_icon_name)
  void set_icon_from_icon_name(const Glib::ustring& icon_name, EntryIconPosition icon_pos = ENTRY_ICON_PRIMARY);
  _IGNORE(gtk_entry_set_icon_from_icon_name)

  _WRAP_METHOD_DOCS_ONLY(gtk_entry_set_icon_from_gicon)
  void set_icon_from_gicon(const Glib::RefPtr<Gio::Icon>& icon, EntryIconPosition icon_pos = ENTRY_ICON_PRIMARY);
  _IGNORE(gtk_entry_set_icon_from_gicon)

  /** Do not show any icon in the specified position.
   * See set_icon_from_pixbuf(), set_icon_from_stock(), set_icon_from_icon_name(),
   * and set_icon_from_gicon().
   *
   * @param icon_pos The icon position.
   *
   * @newin{3,0}
   */
  void unset_icon(EntryIconPosition icon_pos = ENTRY_ICON_PRIMARY);

  _WRAP_METHOD(ImageType get_icon_storage_type(EntryIconPosition icon_pos = ENTRY_ICON_PRIMARY) const, gtk_entry_get_icon_storage_type)
  _WRAP_METHOD(Glib::RefPtr<Gdk::Pixbuf> get_icon_pixbuf(EntryIconPosition icon_pos = ENTRY_ICON_PRIMARY), gtk_entry_get_icon_pixbuf, refreturn)
  _WRAP_METHOD(Glib::RefPtr<const Gdk::Pixbuf> get_icon_pixbuf(EntryIconPosition icon_pos = ENTRY_ICON_PRIMARY) const, gtk_entry_get_icon_pixbuf, refreturn, constversion)
  _WRAP_METHOD(StockID get_icon_stock(EntryIconPosition icon_pos = ENTRY_ICON_PRIMARY) const, gtk_entry_get_icon_stock, deprecated "Use get_icon_name() instead.")
  _WRAP_METHOD(Glib::ustring get_icon_name(EntryIconPosition icon_pos = ENTRY_ICON_PRIMARY) const, gtk_entry_get_icon_name)
  _WRAP_METHOD(Glib::RefPtr<Gio::Icon> get_icon_gicon(EntryIconPosition icon_pos = ENTRY_ICON_PRIMARY), gtk_entry_get_icon_gicon, refreturn)
  _WRAP_METHOD(Glib::RefPtr<const Gio::Icon> get_icon_gicon(EntryIconPosition icon_pos = ENTRY_ICON_PRIMARY) const, gtk_entry_get_icon_gicon, refreturn, constversion)

  _WRAP_METHOD_DOCS_ONLY(gtk_entry_set_icon_activatable)
  void set_icon_activatable(bool activatable = true, EntryIconPosition icon_pos = ENTRY_ICON_PRIMARY);
  _IGNORE(gtk_entry_set_icon_activatable)

  _WRAP_METHOD(bool get_icon_activatable(EntryIconPosition icon_pos = ENTRY_ICON_PRIMARY) const, gtk_entry_get_icon_activatable)
  _WRAP_METHOD(void set_icon_sensitive(EntryIconPosition icon_pos = ENTRY_ICON_PRIMARY, bool sensitive = true), gtk_entry_set_icon_sensitive)
  _WRAP_METHOD(bool get_icon_sensitive(EntryIconPosition icon_pos = ENTRY_ICON_PRIMARY), gtk_entry_get_icon_sensitive)
  _WRAP_METHOD(int get_icon_at_pos(int x, int y) const, gtk_entry_get_icon_at_pos)

  _WRAP_METHOD_DOCS_ONLY(gtk_entry_set_icon_tooltip_text)
  void set_icon_tooltip_text(const Glib::ustring& tooltip, EntryIconPosition icon_pos = ENTRY_ICON_PRIMARY);
  _IGNORE(gtk_entry_set_icon_tooltip_text)

  _WRAP_METHOD(Glib::ustring get_icon_tooltip_text(EntryIconPosition icon_pos = ENTRY_ICON_PRIMARY) const, gtk_entry_get_icon_tooltip_text)

  _WRAP_METHOD_DOCS_ONLY(gtk_entry_set_icon_tooltip_markup)
  void set_icon_tooltip_markup(const Glib::ustring& tooltip, EntryIconPosition icon_pos = ENTRY_ICON_PRIMARY);
  _IGNORE(gtk_entry_set_icon_tooltip_markup)

  _WRAP_METHOD(Glib::ustring get_icon_tooltip_markup(EntryIconPosition icon_pos = ENTRY_ICON_PRIMARY) const, gtk_entry_get_icon_tooltip_markup)

  _WRAP_METHOD_DOCS_ONLY(gtk_entry_set_icon_drag_source)
  void set_icon_drag_source(const Glib::RefPtr<TargetList>& target_list, Gdk::DragAction actions = Gdk::ACTION_COPY, EntryIconPosition icon_pos = ENTRY_ICON_PRIMARY);
  _IGNORE(gtk_entry_set_icon_drag_source)

  /** Returns the area where entry's icon at @a icon_pos is drawn.
   * This function is useful when drawing something to the
   * entry in a draw callback.
   *
   * See also get_text_area().
   *
   * @param icon_pos Icon position.
   * @result The location for the icon area.
   *
   * @newin{3,0}
   */
  Gdk::Rectangle get_icon_area(EntryIconPosition icon_pos = ENTRY_ICON_PRIMARY) const;
  _IGNORE(gtk_entry_get_icon_area)

  _WRAP_METHOD(int get_current_icon_drag_source(), gtk_entry_get_current_icon_drag_source)
  _WRAP_METHOD(bool im_context_filter_keypress(GdkEventKey* event), gtk_entry_im_context_filter_keypress)
  _WRAP_METHOD(void reset_im_context(), gtk_entry_reset_im_context)

  _WRAP_METHOD(void set_input_purpose(InputPurpose purpose), gtk_entry_set_input_purpose)
  _WRAP_METHOD(InputPurpose get_input_purpose() const, gtk_entry_get_input_purpose)

  _WRAP_METHOD(void set_input_hints(InputHints hints), gtk_entry_set_input_hints)
  _WRAP_METHOD(InputHints get_input_hints() const, gtk_entry_get_input_hints)

  _WRAP_METHOD(void set_attributes(Pango::AttrList& attrs), gtk_entry_set_attributes)
  _WRAP_METHOD(Pango::AttrList get_attributes() const, gtk_entry_get_attributes)

#m4 _CONVERSION(`PangoTabArray*',`Pango::TabArray',`Pango::TabArray(($3))')
#m4 _CONVERSION(`const Pango::TabArray&',`PangoTabArray*',`const_cast<Pango::TabArray&>($3).gobj()')
  _WRAP_METHOD(void set_tabs(const Pango::TabArray& tabs), gtk_entry_set_tabs)
  _WRAP_METHOD(Pango::TabArray get_tabs() const, gtk_entry_get_tabs)

  //TODO: This signal now takes a GtkWidget* instead of just a GtkMenu*,
  //so change that when we can break ABI.
  //See https://git.gnome.org/browse/gtk+/commit/?id=88623b98a7ca0afca08ac21bc3aa662c6ed3ab7f
#m4 _CONVERSION(`Menu*',`GtkWidget*',`GTK_WIDGET(($3)->gobj())')
  _WRAP_SIGNAL(void populate_popup(Menu* menu), "populate_popup")

#m4 _CONVERSION(`const char*',`const Glib::ustring&',__GCHARP_TO_USTRING)
  _WRAP_SIGNAL(void insert_at_cursor(const Glib::ustring& str), "insert_at_cursor")

  //Note that the GTK+ C documentation for the activate signal says (as of 2012-06) that it should be used by applications even though it is a keybinding signal.
  _WRAP_SIGNAL(void activate(), "activate")

  _WRAP_SIGNAL(void icon_release(EntryIconPosition icon_position, const GdkEventButton* event), "icon-release", no_default_handler)
  _WRAP_SIGNAL(void icon_press(EntryIconPosition icon_position, const GdkEventButton* event), "icon-press", no_default_handler)

  _IGNORE_SIGNAL("move_cursor")
  _IGNORE_SIGNAL("delete_from_cursor")
  _IGNORE_SIGNAL("cut_clipboard")
  _IGNORE_SIGNAL("copy_clipboard")
  _IGNORE_SIGNAL("paste_clipboard")
  _IGNORE_SIGNAL("toggle_overwrite")
  _IGNORE_SIGNAL("backspace")
  _IGNORE_SIGNAL("preedit-changed")

  _WRAP_PROPERTY("buffer", Glib::RefPtr<EntryBuffer>)
  _WRAP_PROPERTY("cursor-position", int)
  _WRAP_PROPERTY("selection-bound", int)
  _WRAP_PROPERTY("editable", bool)
  _WRAP_PROPERTY("max-length", int)
  _WRAP_PROPERTY("visibility", bool)
  _WRAP_PROPERTY("has-frame", bool)
  _WRAP_PROPERTY("inner-border", Border, deprecated "Use the standard border and padding CSS properties (through objects like StyleContext and CssProvider); the value of this style property is ignored.")
  _WRAP_PROPERTY("invisible-char", gunichar)
  _WRAP_PROPERTY("invisible-char-set", bool)
  _WRAP_PROPERTY("activates-default", bool)
  _WRAP_PROPERTY("width-chars", int)
  _WRAP_PROPERTY("scroll-offset", int)
  _WRAP_PROPERTY("shadow-type", ShadowType)
  _WRAP_PROPERTY("text", Glib::ustring)
  _WRAP_PROPERTY("xalign", float)
  _WRAP_PROPERTY("truncate-multiline", bool)
  _WRAP_PROPERTY("overwrite-mode", bool)
  _WRAP_PROPERTY("text-length", guint)
  _WRAP_PROPERTY("caps-lock-warning", bool)
  _WRAP_PROPERTY("progress-fraction", double)
  _WRAP_PROPERTY("progress-pulse-step", double)
  _WRAP_PROPERTY("primary-icon-pixbuf", Glib::RefPtr<Gdk::Pixbuf>)
  _WRAP_PROPERTY("secondary-icon-pixbuf", Glib::RefPtr<Gdk::Pixbuf>)
  _WRAP_PROPERTY("primary-icon-stock", StockID, deprecated "Use property_primary_icon_name() instead.")
  _WRAP_PROPERTY("secondary-icon-stock", StockID, deprecated "Use property_secondary_icon_name() instead.")
  _WRAP_PROPERTY("primary-icon-name", Glib::ustring)
  _WRAP_PROPERTY("secondary-icon-name", Glib::ustring)
  _WRAP_PROPERTY("primary-icon-gicon", Glib::RefPtr<Gio::Icon>)
  _WRAP_PROPERTY("secondary-icon-gicon", Glib::RefPtr<Gio::Icon>)
  _WRAP_PROPERTY("primary-icon-storage-type", ImageType)
  _WRAP_PROPERTY("secondary-icon-storage-type", ImageType)
  _WRAP_PROPERTY("primary-icon-activatable", bool)
  _WRAP_PROPERTY("secondary-icon-activatable", bool)
  _WRAP_PROPERTY("primary-icon-sensitive", bool)
  _WRAP_PROPERTY("secondary-icon-sensitive", bool)
  _WRAP_PROPERTY("primary-icon-tooltip-text", bool)
  _WRAP_PROPERTY("secondary-icon-tooltip-text", bool)
  _WRAP_PROPERTY("primary-icon-tooltip-markup", bool)
  _WRAP_PROPERTY("secondary-icon-tooltip-markup", bool)
  _WRAP_PROPERTY("im-module", Glib::ustring)
  _WRAP_PROPERTY("placeholder-text", Glib::ustring)
  _WRAP_PROPERTY("completion", Glib::RefPtr<EntryCompletion>)
  _WRAP_PROPERTY("input-purpose", InputPurpose)
  _WRAP_PROPERTY("input-hints", InputHints)
  _WRAP_PROPERTY("attributes", Pango::AttrList)
  _WRAP_PROPERTY("populate-all", bool)
  _WRAP_PROPERTY("tabs", Pango::TabArray)
};

} //namespace Gtk
