/* Copyright (C) 2003 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 <gtkmm/stylecontext.h>
#include <gdkmm/rectangle.h>
#include <gdkmm/pixbuf.h>
#include <gdkmm/rgba.h>
#include <gdkmm/types.h>
#include <giomm/asyncresult.h>
#include <giomm/cancellable.h>

//#include <gtk/gtkicontheme.h>

_DEFS(gtkmm,gtk)

namespace Gtk
{

class IconTheme;

class IconInfo
{
  _CLASS_BOXEDTYPE(IconInfo, GtkIconInfo, NONE, gtk_icon_info_ref, g_object_unref)
  _IGNORE(gtk_icon_info_get_attach_points, g_object_ref, g_object_unref, gtk_icon_info_copy, gtk_icon_info_free)
public:

  IconInfo(const Glib::RefPtr<IconTheme>& icon_theme, const Glib::RefPtr<Gdk::Pixbuf>& pixbuf);
  _IGNORE(gtk_icon_info_new_for_pixbuf)

  /** This typedef is just to make it more obvious that
   * our operator const void* should be used like operator bool().
   */
  typedef const void* BoolExpr;

  /** Tests whether the IconInfo is valid.
   * For instance,
   * @code
   * if(iconinfo)
   *   do_something()
   * @endcode
   */
  operator BoolExpr() const;

  _WRAP_METHOD(int get_base_size() const, gtk_icon_info_get_base_size)
  _WRAP_METHOD(int get_base_scale() const, gtk_icon_info_get_base_scale)

  _WRAP_METHOD(Glib::ustring get_filename() const, gtk_icon_info_get_filename)
  _WRAP_METHOD(Glib::RefPtr<Gdk::Pixbuf> get_builtin_pixbuf(), gtk_icon_info_get_builtin_pixbuf, refreturn)
  _WRAP_METHOD(Glib::RefPtr<const Gdk::Pixbuf> get_builtin_pixbuf() const, gtk_icon_info_get_builtin_pixbuf, refreturn, constversion)
  _WRAP_METHOD(Glib::RefPtr<Gdk::Pixbuf> load_icon() const, gtk_icon_info_load_icon, errthrow)

 #m4 _CONVERSION(`cairo_surface_t*',`::Cairo::RefPtr< ::Cairo::Surface>',`::Cairo::RefPtr< ::Cairo::Surface>(new Cairo::Surface($3, true /* do not take reference */))')
  _WRAP_METHOD(::Cairo::RefPtr< ::Cairo::Surface> load_surface(const Glib::RefPtr<Gdk::Window>& for_window), gtk_icon_info_load_surface, errthrow)

  //TODO: Documentation
  Glib::RefPtr<Gdk::Pixbuf> load_symbolic(const Gdk::RGBA& fg, const Gdk::RGBA& success_color, const Gdk::RGBA& warning_color, const Gdk::RGBA& error_color, bool& was_symbolic) const;
  _IGNORE(gtk_icon_info_load_symbolic)

  _IGNORE(gtk_icon_info_load_symbolic_for_style) //deprecated

  /** Asynchronously load, render and scale an icon previously looked up from the icon theme using Gtk::IconTheme::lookup_icon().
   *
   * @param slot A callback slot to call when the request is satisfied.
   * @param cancellable A Cancellable object which can be used to cancel the operation.
   *
   * @newin{3,8}
   */
  void load_icon_async(const Gio::SlotAsyncReady& slot, const Glib::RefPtr<Gio::Cancellable>& cancellable);

  /** Asynchronously load, render and scale an icon previously looked up from the icon theme using Gtk::IconTheme::lookup_icon().
   *
   * @param slot A callback slot to call when the request is satisfied.
   *
   * @newin{3,8}
   */
  void load_icon_async(const Gio::SlotAsyncReady& slot);
  _IGNORE(gtk_icon_info_load_icon_async)

 _WRAP_METHOD(Glib::RefPtr<Gdk::Pixbuf> load_icon_finish(const Glib::RefPtr<Gio::AsyncResult>& result), gtk_icon_info_load_icon_finish, errthrow)



  /** Loads an icon, modifying it to match the system colors for the foreground, success, warning and error colors provided.
   * If the icon is not a symbolic one, this method will return the result from load_icon().
   * This method uses the regular foreground color and the symbolic colors with the names "success_color",
   * "warning_color" and "error_color" from the context.
   *
   * This allows loading symbolic icons that will match the system theme.
   *
   * @param A StyleContext.
   * @param was_symbolic Whether the loaded icon was a symbolic one and whether the fg color was applied to it. 
   */
  Glib::RefPtr<Gdk::Pixbuf> load_symbolic(const Glib::RefPtr<StyleContext>& style, bool& was_symbolic);
  _IGNORE(gtk_icon_info_load_symbolic_for_context)

  //TODO: When we can break ABI: Rename these to load_symbolic_async(), or rename load_symbolic(context) to load_symbolic_for_context() for consistency.  
  /** Asynchronously load, render and scale a symbolic icon previously looked up from the icon theme using Gtk::IconTheme::lookup_icon().
   * For more details, see load_symbolic() which is the synchronous version of this call.
   *
   * @param context A StyleContext.
   * @param slot A callback slot to call when the request is satisfied.
   * @param cancellable A Cancellable object which can be used to cancel the operation.
   *
   * @newin{3,8}
   */
  void load_symbolic_for_context_async(const Glib::RefPtr<StyleContext>& context, const Gio::SlotAsyncReady& slot, const Glib::RefPtr<Gio::Cancellable>& cancellable);

  /** Asynchronously load, render and scale a symbolic icon previously looked up from the icon theme using Gtk::IconTheme::lookup_icon().
   * For more details, see load_symbolic() which is the synchronous version of this call.
   *
   * @param context A StyleContext.
   * @param slot A callback slot to call when the request is satisfied.
   *
   * @newin{3,8}
   */
  void load_symbolic_for_context_async(const Glib::RefPtr<StyleContext>& context, const Gio::SlotAsyncReady& slot);
  _IGNORE(gtk_icon_info_load_symbolic_for_context_async)

 _WRAP_METHOD(Glib::RefPtr<Gdk::Pixbuf> load_symbolic_for_context_finish(const Glib::RefPtr<Gio::AsyncResult>& result, bool& was_symbolic), gtk_icon_info_load_symbolic_for_context_finish, errthrow)


  //TODO: In gtk_icon_info_load_symbolic_async(), each GdkRGBA* can be NULL, but we do not want that many method overloads.
  //TODO: Documentation.
  void load_symbolic_async(const Gdk::RGBA& fg, const Gdk::RGBA& success_color, const Gdk::RGBA& warning_color, const Gdk::RGBA& error_color, const Gio::SlotAsyncReady& slot, const Glib::RefPtr<Gio::Cancellable>& cancellable);
  void load_symbolic_async(const Gdk::RGBA& fg, const Gdk::RGBA& success_color, const Gdk::RGBA& warning_color, const Gdk::RGBA& error_color, const Gio::SlotAsyncReady& slot);
  _IGNORE(gtk_icon_info_load_symbolic_async)

 _WRAP_METHOD(Glib::RefPtr<Gdk::Pixbuf> load_symbolic_finish(const Glib::RefPtr<Gio::AsyncResult>& result, bool& was_symbolic), gtk_icon_info_load_symbolic_finish, errthrow)




  _WRAP_METHOD(void set_raw_coordinates(bool raw_coordinates = true), gtk_icon_info_set_raw_coordinates)
  _WRAP_METHOD(bool get_embedded_rect(Gdk::Rectangle& rectangle) const, gtk_icon_info_get_embedded_rect)

  //TODO: Documentation.
  std::vector<Gdk::Point> get_attach_points() const;

  _WRAP_METHOD(Glib::ustring get_display_name() const, gtk_icon_info_get_display_name)

  _WRAP_METHOD(bool is_symbolic() const, gtk_icon_info_is_symbolic)
};

} // namespace Gtk
