/* 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 "gfileicon.h"
#include "gfile.h"
#include "gicon.h"
#include "glibintl.h"
#include "gloadableicon.h"
#include "ginputstream.h"
#include "gsimpleasyncresult.h"
#include "gioerror.h"

#include "gioalias.h"

/**
 * SECTION:gfileicon
 * @short_description: Icons pointing to an image file
 * @include: gio/gio.h
 * @see_also: #GIcon, #GLoadableIcon
 * 
 * #GFileIcon specifies an icon by pointing to an image file
 * to be used as icon.
 * 
 **/

static void g_file_icon_icon_iface_init          (GIconIface          *iface);
static void g_file_icon_loadable_icon_iface_init (GLoadableIconIface  *iface);
static void g_file_icon_load_async               (GLoadableIcon       *icon,
						  int                  size,
						  GCancellable        *cancellable,
						  GAsyncReadyCallback  callback,
						  gpointer             user_data);

struct _GFileIcon
{
  GObject parent_instance;

  GFile *file;
};

struct _GFileIconClass
{
  GObjectClass parent_class;
};

enum
{
  PROP_0,
  PROP_FILE
};

G_DEFINE_TYPE_WITH_CODE (GFileIcon, g_file_icon, G_TYPE_OBJECT,
                         G_IMPLEMENT_INTERFACE (G_TYPE_ICON,
                                                g_file_icon_icon_iface_init)
                         G_IMPLEMENT_INTERFACE (G_TYPE_LOADABLE_ICON,
                                                g_file_icon_loadable_icon_iface_init))

static void
g_file_icon_get_property (GObject    *object,
                          guint       prop_id,
                          GValue     *value,
                          GParamSpec *pspec)
{
  GFileIcon *icon = G_FILE_ICON (object);

  switch (prop_id)
    {
      case PROP_FILE:
        g_value_set_object (value, icon->file);
        break;

      default:
        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
    }
}

static void
g_file_icon_set_property (GObject      *object,
                          guint         prop_id,
                          const GValue *value,
                          GParamSpec   *pspec)
{
  GFileIcon *icon = G_FILE_ICON (object);

  switch (prop_id)
    {
      case PROP_FILE:
        icon->file = G_FILE (g_value_dup_object (value));
        break;

      default:
        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
    }
}

static void
g_file_icon_finalize (GObject *object)
{
  GFileIcon *icon;

  icon = G_FILE_ICON (object);

  g_object_unref (icon->file);

  G_OBJECT_CLASS (g_file_icon_parent_class)->finalize (object);
}

static void
g_file_icon_class_init (GFileIconClass *klass)
{
  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
  
  gobject_class->get_property = g_file_icon_get_property;
  gobject_class->set_property = g_file_icon_set_property;
  gobject_class->finalize = g_file_icon_finalize;

  /**
   * GFileIcon:file:
   *
   * The file containing the icon.
   */
  g_object_class_install_property (gobject_class, PROP_FILE,
                                   g_param_spec_object ("file",
                                                        P_("file"),
                                                        P_("The file containing the icon"),
                                                        G_TYPE_FILE,
                                                        G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_BLURB | G_PARAM_STATIC_NICK));
}

static void
g_file_icon_init (GFileIcon *file)
{
}

/**
 * g_file_icon_new:
 * @file: a #GFile.
 * 
 * Creates a new icon for a file.
 * 
 * Returns: a #GIcon for the given @file, or %NULL on error.
 **/
GIcon *
g_file_icon_new (GFile *file)
{
  g_return_val_if_fail (G_IS_FILE (file), NULL);

  return G_ICON (g_object_new (G_TYPE_FILE_ICON, "file", file, NULL));
}

/**
 * g_file_icon_get_file:
 * @icon: a #GIcon.
 * 
 * Gets the #GFile associated with the given @icon.
 * 
 * Returns: a #GFile, or %NULL.
 **/
GFile *
g_file_icon_get_file (GFileIcon *icon)
{
  g_return_val_if_fail (G_IS_FILE_ICON (icon), NULL);

  return icon->file;
}

static guint
g_file_icon_hash (GIcon *icon)
{
  GFileIcon *file_icon = G_FILE_ICON (icon);

  return g_file_hash (file_icon->file);
}

static gboolean
g_file_icon_equal (GIcon *icon1,
		   GIcon *icon2)
{
  GFileIcon *file1 = G_FILE_ICON (icon1);
  GFileIcon *file2 = G_FILE_ICON (icon2);
  
  return g_file_equal (file1->file, file2->file);
}

static gboolean
g_file_icon_to_tokens (GIcon *icon,
		       GPtrArray *tokens,
                       gint  *out_version)
{
  GFileIcon *file_icon = G_FILE_ICON (icon);

  g_return_val_if_fail (out_version != NULL, FALSE);

  *out_version = 0;

  g_ptr_array_add (tokens, g_file_get_uri (file_icon->file));
  return TRUE;
}

static GIcon *
g_file_icon_from_tokens (gchar  **tokens,
                         gint     num_tokens,
                         gint     version,
                         GError **error)
{
  GIcon *icon;
  GFile *file;

  icon = NULL;

  if (version != 0)
    {
      g_set_error (error,
                   G_IO_ERROR,
                   G_IO_ERROR_INVALID_ARGUMENT,
                   _("Can't handle version %d of GFileIcon encoding"),
                   version);
      goto out;
    }

  if (num_tokens != 1)
    {
      g_set_error_literal (error,
                           G_IO_ERROR,
                           G_IO_ERROR_INVALID_ARGUMENT,
                           _("Malformed input data for GFileIcon"));
      goto out;
    }

  file = g_file_new_for_uri (tokens[0]);
  icon = g_file_icon_new (file);
  g_object_unref (file);

 out:
  return icon;
}

static void
g_file_icon_icon_iface_init (GIconIface *iface)
{
  iface->hash = g_file_icon_hash;
  iface->equal = g_file_icon_equal;
  iface->to_tokens = g_file_icon_to_tokens;
  iface->from_tokens = g_file_icon_from_tokens;
}


static GInputStream *
g_file_icon_load (GLoadableIcon  *icon,
		  int            size,
		  char          **type,
		  GCancellable   *cancellable,
		  GError        **error)
{
  GFileInputStream *stream;
  GFileIcon *file_icon = G_FILE_ICON (icon);

  stream = g_file_read (file_icon->file,
			cancellable,
			error);
  
  return G_INPUT_STREAM (stream);
}

typedef struct {
  GLoadableIcon *icon;
  GAsyncReadyCallback callback;
  gpointer user_data;
} LoadData;

static void
load_data_free (LoadData *data)
{
  g_object_unref (data->icon);
  g_free (data);
}

static void
load_async_callback (GObject      *source_object,
		     GAsyncResult *res,
		     gpointer      user_data)
{
  GFileInputStream *stream;
  GError *error = NULL;
  GSimpleAsyncResult *simple;
  LoadData *data = user_data;

  stream = g_file_read_finish (G_FILE (source_object), res, &error);
  
  if (stream == NULL)
    {
      simple = g_simple_async_result_new_from_error (G_OBJECT (data->icon),
						     data->callback,
						     data->user_data,
						     error);
      g_error_free (error);
    }
  else
    {
      simple = g_simple_async_result_new (G_OBJECT (data->icon),
					  data->callback,
					  data->user_data,
					  g_file_icon_load_async);
      
      g_simple_async_result_set_op_res_gpointer (simple,
						 stream,
						 g_object_unref);
  }


  g_simple_async_result_complete (simple);
  
  load_data_free (data);
}

static void
g_file_icon_load_async (GLoadableIcon       *icon,
                        int                  size,
                        GCancellable        *cancellable,
                        GAsyncReadyCallback  callback,
                        gpointer             user_data)
{
  GFileIcon *file_icon = G_FILE_ICON (icon);
  LoadData *data;

  data = g_new0 (LoadData, 1);
  data->icon = g_object_ref (icon);
  data->callback = callback;
  data->user_data = user_data;
  
  g_file_read_async (file_icon->file, 0,
		     cancellable,
		     load_async_callback, data);
  
}

static GInputStream *
g_file_icon_load_finish (GLoadableIcon  *icon,
			 GAsyncResult   *res,
			 char          **type,
			 GError        **error)
{
  GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
  gpointer op;

  g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_file_icon_load_async);

  if (type)
    *type = NULL;
  
  op = g_simple_async_result_get_op_res_gpointer (simple);
  if (op)
    return g_object_ref (op);
  
  return NULL;
}

static void
g_file_icon_loadable_icon_iface_init (GLoadableIconIface *iface)
{
  iface->load = g_file_icon_load;
  iface->load_async = g_file_icon_load_async;
  iface->load_finish = g_file_icon_load_finish;
}

#define __G_FILE_ICON_C__
#include "gioaliasdef.c"
