/*
 * Copyright (C) 2013 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/bin.h>
#include <giomm/menumodel.h>

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

namespace Gtk
{
_WRAP_ENUM(PopoverConstraint, GtkPopoverConstraint)

/** Context dependent bubbles.
 *
 * Gtk::Popover is a bubble-like context window, primarily meant to
 * provide context-dependent information or options. Popovers are
 * attached to a widget, passed at construction time on Gtk::Popover(),
 * or updated afterwards through Gtk::Popover::set_relative_to(), by
 * default they will point to the whole widget area, although this
 * behavior can be changed through Gtk::Popover::set_pointing_to().
 *
 * The position of a popover relative to the widget it is attached to
 * can also be changed through Gtk::Popover::set_position().
 *
 * By default, Gtk::Popover performs a GTK+ grab, in order to ensure
 * input events get redirected to it while it is shown, and also so
 * the popover is dismissed in the expected situations (clicks outside
 * the popover, or the Esc key being pressed). If no such modal behavior
 * is desired on a popover, Gtk::Popover::set_modal() may be called on it
 * to tweak its behavior.
 *
 * @ingroup Widgets
 * @newin{3,12}
 */
class Popover
  : public Bin
{
  _CLASS_GTKOBJECT(Popover, GtkPopover, GTK_POPOVER, Gtk::Bin, GtkBin)
public:

  /** Creates a new popover to point to @a relative_to
   *
   * @param relative_to The Gtk::Widget the popover is related to
   */
  _WRAP_CTOR(Popover(const Widget& relative_to{?}), gtk_popover_new)

  //This is custom-implemented because the gtk_popover_new_from_model() does more
  //than just call g_object_new. MenuBar and Menu have both the same issue.
  //See https://bugzilla.gnome.org/show_bug.cgi?id=704671
  /** Creates a Popover and populates it according to
   * @a model. The popover is pointed to the @a relative_to widget.
   *
   * The created buttons are connected to actions found in the
   * ApplicationWindow to which the popover belongs - typically
   * by means of being attached to a widget that is contained within
   * the ApplicationWindow widget hierarchy.
   *
   * Actions can also be added using Widget::insert_action_group()
   * on the menu's attached widget or on any of its parent widgets.
   *
   * @param relative_to: Widget the popover is related to
   * @param model: a Gio::MenuModel
   *
   * @newin{3,12}
   */
  explicit Popover(const Widget& relative_to, const Glib::RefPtr<Gio::MenuModel>& model);

  /** Creates a Popover and populates it according to
   * @a model.
   *
   * The created buttons are connected to actions found in the
   * ApplicationWindow to which the popover belongs - typically
   * by means of being attached to a widget that is contained within
   * the ApplicationWindow widget hierarchy.
   *
   * Actions can also be added using Widget::insert_action_group()
   * on the menu's attached widget or on any of its parent widgets.
   *
   * @param model: a Gio::MenuModel
   *
   * @newin{3,12}
   */
  explicit Popover(const Glib::RefPtr<Gio::MenuModel>& model);

  _IGNORE(gtk_popover_new_from_model)


  _WRAP_METHOD(void set_relative_to(const Widget& relative_to), gtk_popover_set_relative_to)
  // transfer none
  _WRAP_METHOD(Widget* get_relative_to(), gtk_popover_get_relative_to)
  _WRAP_METHOD(const Widget* get_relative_to() const, gtk_popover_get_relative_to, constversion)

  //This cannot take NULL to mean unset.
#m4 _CONVERSION(`const GdkRectangle*',`const Gdk::Rectangle&',`Glib::wrap($3)')
  _WRAP_METHOD(void set_pointing_to(const Gdk::Rectangle& rect), gtk_popover_set_pointing_to)
#m4 _CONVERSION(`GdkRectangle*',`Gdk::Rectangle&',`Glib::wrap($3)')
  _WRAP_METHOD(bool get_pointing_to(Gdk::Rectangle& rect) const, gtk_popover_get_pointing_to)

  _WRAP_METHOD(void set_position(PositionType position = POS_TOP), gtk_popover_set_position)
  _WRAP_METHOD(PositionType get_position() const, gtk_popover_get_position)

  _WRAP_METHOD(void set_modal(bool modal = true), gtk_popover_set_modal)
  _WRAP_METHOD(bool get_modal() const, gtk_popover_get_modal)

  _WRAP_METHOD(void bind_model(const Glib::RefPtr<Gio::MenuModel>& model, const Glib::ustring& action_namespace{?}), gtk_popover_bind_model)

  _WRAP_METHOD(void set_transitions_enabled(bool transitions_enabled = true), gtk_popover_set_transitions_enabled)
  _WRAP_METHOD(bool get_transitions_enabled() const, gtk_popover_get_transitions_enabled)

  _WRAP_METHOD(void set_default_widget(Widget& widget), gtk_popover_set_default_widget)

  _WRAP_METHOD(Widget* get_default_widget(), gtk_popover_get_default_widget)
  _WRAP_METHOD(const Widget* get_default_widget() const, gtk_popover_get_default_widget, constversion)

  _WRAP_METHOD(void set_constrain_to(PopoverConstraint constraint), gtk_popover_set_constrain_to)
  _WRAP_METHOD(PopoverConstraint get_constrain_to() const, gtk_popover_get_constrain_to)

  _WRAP_PROPERTY("relative-to", Widget*)
  _WRAP_PROPERTY("pointing-to", Gdk::Rectangle)
  _WRAP_PROPERTY("position", PositionType)
  _WRAP_PROPERTY("modal", bool)
  _WRAP_PROPERTY("transitions-enabled", bool)
  _WRAP_PROPERTY("constrain-to", PopoverConstraint)

  _WRAP_SIGNAL(void closed(), "closed")
};

} // namespace Gtk
