/* GIO - GLib Input, Output and Streaming Library
 * 
 * Copyright (C) 2006-2007 Red Hat, Inc.
 *
 * 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 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., 59 Temple Place, Suite 330,
 * Boston, MA 02111-1307, USA.
 *
 * Author: Alexander Larsson <alexl@redhat.com>
 */

#include "config.h"
#include "gasyncresult.h"
#include "gsimpleasyncresult.h"
#include "gicon.h"
#include "gloadableicon.h"
#include "glibintl.h"


/**
 * SECTION:gloadableicon
 * @short_description: Loadable Icons
 * @include: gio/gio.h
 * @see_also: #GIcon, #GThemedIcon
 * 
 * Extends the #GIcon interface and adds the ability to 
 * load icons from streams.
 **/

static void          g_loadable_icon_real_load_async  (GLoadableIcon        *icon,
						       int                   size,
						       GCancellable         *cancellable,
						       GAsyncReadyCallback   callback,
						       gpointer              user_data);
static GInputStream *g_loadable_icon_real_load_finish (GLoadableIcon        *icon,
						       GAsyncResult         *res,
						       char                **type,
						       GError              **error);

typedef GLoadableIconIface GLoadableIconInterface;
G_DEFINE_INTERFACE(GLoadableIcon, g_loadable_icon, G_TYPE_ICON)

static void
g_loadable_icon_default_init (GLoadableIconIface *iface)
{
  iface->load_async = g_loadable_icon_real_load_async;
  iface->load_finish = g_loadable_icon_real_load_finish;
}

/**
 * g_loadable_icon_load:
 * @icon: a #GLoadableIcon.
 * @size: an integer.
 * @type: (out) (allow-none): a location to store the type of the
 *        loaded icon, %NULL to ignore.
 * @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore. 
 * @error: a #GError location to store the error occuring, or %NULL to 
 * ignore.
 * 
 * Loads a loadable icon. For the asynchronous version of this function, 
 * see g_loadable_icon_load_async().
 * 
 * Returns: (transfer full): a #GInputStream to read the icon from.
 **/
GInputStream *
g_loadable_icon_load (GLoadableIcon  *icon,
		      int             size,
		      char          **type,
		      GCancellable   *cancellable,
		      GError        **error)
{
  GLoadableIconIface *iface;

  g_return_val_if_fail (G_IS_LOADABLE_ICON (icon), NULL);

  iface = G_LOADABLE_ICON_GET_IFACE (icon);

  return (* iface->load) (icon, size, type, cancellable, error);
}

/**
 * g_loadable_icon_load_async:
 * @icon: a #GLoadableIcon.
 * @size: an integer.
 * @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore. 
 * @callback: (scope async): a #GAsyncReadyCallback to call when the
 *            request is satisfied
 * @user_data: (closure): the data to pass to callback function
 * 
 * Loads an icon asynchronously. To finish this function, see 
 * g_loadable_icon_load_finish(). For the synchronous, blocking 
 * version of this function, see g_loadable_icon_load().
 **/
void
g_loadable_icon_load_async (GLoadableIcon       *icon,
                            int                  size,
                            GCancellable        *cancellable,
                            GAsyncReadyCallback  callback,
                            gpointer             user_data)
{
  GLoadableIconIface *iface;
  
  g_return_if_fail (G_IS_LOADABLE_ICON (icon));

  iface = G_LOADABLE_ICON_GET_IFACE (icon);

  (* iface->load_async) (icon, size, cancellable, callback, user_data);
}

/**
 * g_loadable_icon_load_finish:
 * @icon: a #GLoadableIcon.
 * @res: a #GAsyncResult.
 * @type: a location to store the type of the loaded icon, %NULL to ignore.
 * @error: a #GError location to store the error occuring, or %NULL to 
 * ignore.
 * 
 * Finishes an asynchronous icon load started in g_loadable_icon_load_async().
 * 
 * Returns: (transfer full): a #GInputStream to read the icon from.
 **/
GInputStream *
g_loadable_icon_load_finish (GLoadableIcon  *icon,
			     GAsyncResult   *res,
			     char          **type,
			     GError        **error)
{
  GLoadableIconIface *iface;
  
  g_return_val_if_fail (G_IS_LOADABLE_ICON (icon), NULL);
  g_return_val_if_fail (G_IS_ASYNC_RESULT (res), NULL);

  if (G_IS_SIMPLE_ASYNC_RESULT (res))
    {
      GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
      if (g_simple_async_result_propagate_error (simple, error))
	return NULL;
    }
  
  iface = G_LOADABLE_ICON_GET_IFACE (icon);

  return (* iface->load_finish) (icon, res, type, error);
}

/********************************************
 *   Default implementation of async load   *
 ********************************************/

typedef struct {
  int size;
  char *type;
  GInputStream *stream;
} LoadData;

static void
load_data_free (LoadData *data)
{
  if (data->stream)
    g_object_unref (data->stream);
  g_free (data->type);
  g_free (data);
}

static void
load_async_thread (GSimpleAsyncResult *res,
		   GObject            *object,
		   GCancellable       *cancellable)
{
  GLoadableIconIface *iface;
  GInputStream *stream;
  LoadData *data;
  GError *error = NULL;
  char *type = NULL;

  data = g_simple_async_result_get_op_res_gpointer (res);
  
  iface = G_LOADABLE_ICON_GET_IFACE (object);
  stream = iface->load (G_LOADABLE_ICON (object), data->size, &type, cancellable, &error);

  if (stream == NULL)
    {
      g_simple_async_result_take_error (res, error);
    }
  else
    {
      data->stream = stream;
      data->type = type;
    }
}



static void
g_loadable_icon_real_load_async (GLoadableIcon       *icon,
				 int                  size,
				 GCancellable        *cancellable,
				 GAsyncReadyCallback  callback,
				 gpointer             user_data)
{
  GSimpleAsyncResult *res;
  LoadData *data;
  
  res = g_simple_async_result_new (G_OBJECT (icon), callback, user_data, g_loadable_icon_real_load_async);
  data = g_new0 (LoadData, 1);
  g_simple_async_result_set_op_res_gpointer (res, data, (GDestroyNotify) load_data_free);
  g_simple_async_result_run_in_thread (res, load_async_thread, 0, cancellable);
  g_object_unref (res);
}

static GInputStream *
g_loadable_icon_real_load_finish (GLoadableIcon        *icon,
				  GAsyncResult         *res,
				  char                **type,
				  GError              **error)
{
  GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
  LoadData *data;

  g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_loadable_icon_real_load_async);

  data = g_simple_async_result_get_op_res_gpointer (simple);

  if (type)
    {
      *type = data->type;
      data->type = NULL;
    }

  return g_object_ref (data->stream);
}
