/*
 * 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 <vector>

#include <gdkmm/color.h>
#include <gdkmm/pixbuf.h>
#include <gdkmm/device.h>
#include <glibmm/object.h>
#include <cairomm/surface.h>
#include <gdk/gdk.h>
_DEFS(gdkmm,gdk)
_PINCLUDE(glibmm/private/object_p.h)

namespace Gdk
{

_WRAP_ENUM(DragAction, GdkDragAction)
_WRAP_ENUM(DragProtocol, GdkDragProtocol)

/** A Gdk::DragContext holds information about a drag in progress. It is used on both source and destination sides.
 */
class DragContext : public Glib::Object
{
  _CLASS_GOBJECT(DragContext, GdkDragContext, GDK_DRAG_CONTEXT, Glib::Object,GObject)
protected:

public:

  _WRAP_METHOD(void drag_status(DragAction action, guint32 time), gdk_drag_status)

  /** Indicate that a drop will not be accepted.
   * This function may be called by the drag destination in response to gdk_drag_motion() called by the drag source.
   * Alternatively, call drag_status() to indicate which drag action will be accepted.
   *
   * @param time The timestamp for this operation.
   */
  void drag_refuse(guint32 time);

  _IGNORE(gdk_drag_motion) //gdk_drag_motion is only used in GDK internally.

  _WRAP_METHOD(void drop_reply(bool accepted, guint32 time), gdk_drop_reply)
  _WRAP_METHOD(void drop_finish(bool success, guint32 time), gdk_drop_finish)
  _WRAP_METHOD(Glib::ustring get_selection() const, gdk_drag_get_selection)

  //For some reason this is not in our *_docs.xml file.
  /** Informs the drag source that the drop is finished, and that the data of the drag will no longer be required.
   * @param success A flag indicating whether the drop was successful.
   * @param del A flag indicating whether the source should delete the original data. (This should be true for a move.)
   * @param time The timestamp from the "drag_data_drop" signal.
   */
  _WRAP_METHOD(void drag_finish(bool success, bool del, guint32 time), gtk_drag_finish)
  //Gtk::Widget* get_source_widget() - see Gtk::Widget::drag_get_source_widget()

  // void set_icon(Gtk::Widget* widget, int hot_x, int hot_y) - see Gtk::Widget::set_as_icon().

  #m4 _CONVERSION(`const ::Cairo::RefPtr< ::Cairo::Surface>&',`cairo_surface_t*',`($3) ? const_cast<cairo_surface_t*>(($3)->cobj()) : nullptr')
  _WRAP_METHOD(void set_icon(const ::Cairo::RefPtr< ::Cairo::Surface>& surface), gtk_drag_set_icon_surface)

  _WRAP_METHOD(void set_icon(const Glib::RefPtr<Gdk::Pixbuf>& pixbuf, int hot_x, int hot_y), gtk_drag_set_icon_pixbuf)

  // The first argument was changed from StockID to ustring to avoid
  // cross-dependence between gdkmm and gtkmm.
  // See http://bugzilla.gnome.org/show_bug.cgi?id=79124 for details
  _WRAP_METHOD(void set_icon(const Glib::ustring& stock_id, int hot_x, int hot_y), gtk_drag_set_icon_stock, deprecated "Use set_icon_name() instead.")

  _WRAP_METHOD(void set_icon_name(const Glib::ustring& name, int hot_x, int hot_y), gtk_drag_set_icon_name)
  _WRAP_METHOD(void set_icon(), gtk_drag_set_icon_default)

  _WRAP_METHOD(Glib::RefPtr<Window> get_source_window(), gdk_drag_context_get_source_window, refreturn)
  _WRAP_METHOD(Glib::RefPtr<const Window> get_source_window() const, gdk_drag_context_get_source_window, refreturn, constversion)
  _WRAP_METHOD(Glib::RefPtr<Window> get_dest_window(), gdk_drag_context_get_dest_window, refreturn)
  _WRAP_METHOD(Glib::RefPtr<const Window> get_dest_window() const, gdk_drag_context_get_dest_window, refreturn, constversion)
  _WRAP_METHOD(DragProtocol get_protocol() const, gdk_drag_context_get_protocol)


  _WRAP_METHOD(void set_device(const Glib::RefPtr<Device>& device), gdk_drag_context_set_device)
  _WRAP_METHOD(Glib::RefPtr<Device> get_device(), gdk_drag_context_get_device, refreturn)
  _WRAP_METHOD(Glib::RefPtr<const Device> get_device() const, gdk_drag_context_get_device, refreturn, constversion)

  /** Get a list of targets offered by the source.
   * @result a list of targets offered by the source.
   */
  std::vector<std::string> list_targets() const;
  _IGNORE(gdk_drag_context_list_targets)

  _WRAP_METHOD(DragAction get_actions() const, gdk_drag_context_get_actions)
  _WRAP_METHOD(DragAction get_suggested_action() const, gdk_drag_context_get_suggested_action)
  _WRAP_METHOD(DragAction get_selected_action() const, gdk_drag_context_get_selected_action)

  _WRAP_METHOD_DOCS_ONLY(gdk_drag_find_window_for_screen)
  void find_window_for_screen(const Glib::RefPtr<Window>& drag_window, const Glib::RefPtr<Screen>& screen, int x_root, int y_root, Glib::RefPtr<Window>& dest_window, DragProtocol& protocol) const;
  _IGNORE(gdk_drag_find_window_for_screen)
};

} // namespace Gdk
