/* 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 <stdlib.h>
#include <string.h>

#include "gicon.h"
#include "gthemedicon.h"
#include "gfileicon.h"
#include "gemblemedicon.h"
#include "gfile.h"
#include "gioerror.h"

#include "glibintl.h"


/* There versioning of this is implicit, version 1 would be ".1 " */
#define G_ICON_SERIALIZATION_MAGIC0 ". "

/**
 * SECTION:gicon
 * @short_description: Interface for icons
 * @include: gio/gio.h
 *
 * #GIcon is a very minimal interface for icons. It provides functions
 * for checking the equality of two icons, hashing of icons and
 * serializing an icon to and from strings.
 *
 * #GIcon does not provide the actual pixmap for the icon as this is out 
 * of GIO's scope, however implementations of #GIcon may contain the name 
 * of an icon (see #GThemedIcon), or the path to an icon (see #GLoadableIcon). 
 * 
 * To obtain a hash of a #GIcon, see g_icon_hash().
 * 
 * To check if two #GIcons are equal, see g_icon_equal().
 *
 * For serializing a #GIcon, use g_icon_to_string() and
 * g_icon_new_for_string().
 *
 * If your application or library provides one or more #GIcon
 * implementations you need to ensure that each #GType is registered
 * with the type system prior to calling g_icon_new_for_string().
 **/

typedef GIconIface GIconInterface;
G_DEFINE_INTERFACE(GIcon, g_icon, G_TYPE_OBJECT)

static void
g_icon_default_init (GIconInterface *iface)
{
}

/**
 * g_icon_hash:
 * @icon: #gconstpointer to an icon object.
 * 
 * Gets a hash for an icon.
 *
 * Virtual: hash
 * Returns: a #guint containing a hash for the @icon, suitable for 
 * use in a #GHashTable or similar data structure.
 **/
guint
g_icon_hash (gconstpointer icon)
{
  GIconIface *iface;

  g_return_val_if_fail (G_IS_ICON (icon), 0);

  iface = G_ICON_GET_IFACE (icon);

  return (* iface->hash) ((GIcon *)icon);
}

/**
 * g_icon_equal:
 * @icon1: (allow-none): pointer to the first #GIcon.
 * @icon2: (allow-none): pointer to the second #GIcon.
 * 
 * Checks if two icons are equal.
 * 
 * Returns: %TRUE if @icon1 is equal to @icon2. %FALSE otherwise.
 **/
gboolean
g_icon_equal (GIcon *icon1,
	      GIcon *icon2)
{
  GIconIface *iface;

  if (icon1 == NULL && icon2 == NULL)
    return TRUE;

  if (icon1 == NULL || icon2 == NULL)
    return FALSE;
  
  if (G_TYPE_FROM_INSTANCE (icon1) != G_TYPE_FROM_INSTANCE (icon2))
    return FALSE;

  iface = G_ICON_GET_IFACE (icon1);
  
  return (* iface->equal) (icon1, icon2);
}

static gboolean
g_icon_to_string_tokenized (GIcon *icon, GString *s)
{
  GPtrArray *tokens;
  gint version;
  GIconIface *icon_iface;
  int i;

  g_return_val_if_fail (icon != NULL, FALSE);
  g_return_val_if_fail (G_IS_ICON (icon), FALSE);

  icon_iface = G_ICON_GET_IFACE (icon);
  if (icon_iface->to_tokens == NULL)
    return FALSE;

  tokens = g_ptr_array_new ();
  if (!icon_iface->to_tokens (icon, tokens, &version))
    {
      g_ptr_array_free (tokens, TRUE);
      return FALSE;
    }

  /* format: TypeName[.Version] <token_0> .. <token_N-1>
     version 0 is implicit and can be omitted
     all the tokens are url escaped to ensure they have no spaces in them */
  
  g_string_append (s, g_type_name_from_instance ((GTypeInstance *)icon));
  if (version != 0)
    g_string_append_printf (s, ".%d", version);
  
  for (i = 0; i < tokens->len; i++)
    {
      char *token;

      token = g_ptr_array_index (tokens, i);

      g_string_append_c (s, ' ');
      /* We really only need to escape spaces here, so allow lots of otherwise reserved chars */
      g_string_append_uri_escaped (s, token,
				   G_URI_RESERVED_CHARS_ALLOWED_IN_PATH, TRUE);

      g_free (token);
    }
  
  g_ptr_array_free (tokens, TRUE);
  
  return TRUE;
}

/**
 * g_icon_to_string:
 * @icon: a #GIcon.
 *
 * Generates a textual representation of @icon that can be used for
 * serialization such as when passing @icon to a different process or
 * saving it to persistent storage. Use g_icon_new_for_string() to
 * get @icon back from the returned string.
 *
 * The encoding of the returned string is proprietary to #GIcon except
 * in the following two cases
 *
 * <itemizedlist>
 * <listitem><para>
 *     If @icon is a #GFileIcon, the returned string is a native path
 *     (such as <literal>/path/to/my icon.png</literal>) without escaping
 *     if the #GFile for @icon is a native file.  If the file is not
 *     native, the returned string is the result of g_file_get_uri()
 *     (such as <literal>sftp://path/to/my&percnt;20icon.png</literal>).
 * </para></listitem>
 * <listitem><para>
 *    If @icon is a #GThemedIcon with exactly one name, the encoding is
 *    simply the name (such as <literal>network-server</literal>).
 * </para></listitem>
 * </itemizedlist>
 *
 * Virtual: to_tokens
 * Returns: An allocated NUL-terminated UTF8 string or %NULL if @icon can't
 * be serialized. Use g_free() to free.
 *
 * Since: 2.20
 */
gchar *
g_icon_to_string (GIcon *icon)
{
  gchar *ret;

  g_return_val_if_fail (icon != NULL, NULL);
  g_return_val_if_fail (G_IS_ICON (icon), NULL);

  ret = NULL;

  if (G_IS_FILE_ICON (icon))
    {
      GFile *file;

      file = g_file_icon_get_file (G_FILE_ICON (icon));
      if (g_file_is_native (file))
	{
	  ret = g_file_get_path (file);
	  if (!g_utf8_validate (ret, -1, NULL))
	    {
	      g_free (ret);
	      ret = NULL;
	    }
	}
      else
        ret = g_file_get_uri (file);
    }
  else if (G_IS_THEMED_ICON (icon))
    {
      const char * const *names;

      names = g_themed_icon_get_names (G_THEMED_ICON (icon));
      if (names != NULL &&
	  names[0] != NULL &&
	  names[0][0] != '.' && /* Allowing icons starting with dot would break G_ICON_SERIALIZATION_MAGIC0 */
	  g_utf8_validate (names[0], -1, NULL) && /* Only return utf8 strings */
	  names[1] == NULL)
	ret = g_strdup (names[0]);
    }

  if (ret == NULL)
    {
      GString *s;

      s = g_string_new (G_ICON_SERIALIZATION_MAGIC0);

      if (g_icon_to_string_tokenized (icon, s))
	ret = g_string_free (s, FALSE);
      else
	g_string_free (s, TRUE);
    }

  return ret;
}

static GIcon *
g_icon_new_from_tokens (char   **tokens,
			GError **error)
{
  GIcon *icon;
  char *typename, *version_str;
  GType type;
  gpointer klass;
  GIconIface *icon_iface;
  gint version;
  char *endp;
  int num_tokens;
  int i;

  icon = NULL;
  klass = NULL;

  num_tokens = g_strv_length (tokens);

  if (num_tokens < 1)
    {
      g_set_error (error,
                   G_IO_ERROR,
                   G_IO_ERROR_INVALID_ARGUMENT,
                   _("Wrong number of tokens (%d)"),
                   num_tokens);
      goto out;
    }
  
  typename = tokens[0];
  version_str = strchr (typename, '.');
  if (version_str)
    {
      *version_str = 0;
      version_str += 1;
    }
  
  
  type = g_type_from_name (tokens[0]);
  if (type == 0)
    {
      g_set_error (error,
                   G_IO_ERROR,
                   G_IO_ERROR_INVALID_ARGUMENT,
                   _("No type for class name %s"),
                   tokens[0]);
      goto out;
    }

  if (!g_type_is_a (type, G_TYPE_ICON))
    {
      g_set_error (error,
                   G_IO_ERROR,
                   G_IO_ERROR_INVALID_ARGUMENT,
                   _("Type %s does not implement the GIcon interface"),
                   tokens[0]);
      goto out;
    }

  klass = g_type_class_ref (type);
  if (klass == NULL)
    {
      g_set_error (error,
                   G_IO_ERROR,
                   G_IO_ERROR_INVALID_ARGUMENT,
                   _("Type %s is not classed"),
                   tokens[0]);
      goto out;
    }

  version = 0;
  if (version_str)
    {
      version = strtol (version_str, &endp, 10);
      if (endp == NULL || *endp != '\0')
	{
	  g_set_error (error,
		       G_IO_ERROR,
		       G_IO_ERROR_INVALID_ARGUMENT,
		       _("Malformed version number: %s"),
		       version_str);
	  goto out;
	}
    }

  icon_iface = g_type_interface_peek (klass, G_TYPE_ICON);
  g_assert (icon_iface != NULL);

  if (icon_iface->from_tokens == NULL)
    {
      g_set_error (error,
                   G_IO_ERROR,
                   G_IO_ERROR_INVALID_ARGUMENT,
                   _("Type %s does not implement from_tokens() on the GIcon interface"),
                   tokens[0]);
      goto out;
    }

  for (i = 1;  i < num_tokens; i++)
    {
      char *escaped;

      escaped = tokens[i];
      tokens[i] = g_uri_unescape_string (escaped, NULL);
      g_free (escaped);
    }
  
  icon = icon_iface->from_tokens (tokens + 1, num_tokens - 1, version, error);

 out:
  if (klass != NULL)
    g_type_class_unref (klass);
  return icon;
}

static void
ensure_builtin_icon_types (void)
{
  g_type_ensure (G_TYPE_THEMED_ICON);
  g_type_ensure (G_TYPE_FILE_ICON);
  g_type_ensure (G_TYPE_EMBLEMED_ICON);
  g_type_ensure (G_TYPE_EMBLEM);
}

/**
 * g_icon_new_for_string:
 * @str: A string obtained via g_icon_to_string().
 * @error: Return location for error.
 *
 * Generate a #GIcon instance from @str. This function can fail if
 * @str is not valid - see g_icon_to_string() for discussion.
 *
 * If your application or library provides one or more #GIcon
 * implementations you need to ensure that each #GType is registered
 * with the type system prior to calling g_icon_new_for_string().
 *
 * Returns: (transfer full): An object implementing the #GIcon
 *          interface or %NULL if @error is set.
 *
 * Since: 2.20
 **/
GIcon *
g_icon_new_for_string (const gchar   *str,
                       GError       **error)
{
  GIcon *icon;

  g_return_val_if_fail (str != NULL, NULL);

  ensure_builtin_icon_types ();

  icon = NULL;

  if (*str == '.')
    {
      if (g_str_has_prefix (str, G_ICON_SERIALIZATION_MAGIC0))
	{
	  gchar **tokens;
	  
	  /* handle tokenized encoding */
	  tokens = g_strsplit (str + sizeof (G_ICON_SERIALIZATION_MAGIC0) - 1, " ", 0);
	  icon = g_icon_new_from_tokens (tokens, error);
	  g_strfreev (tokens);
	}
      else
	g_set_error_literal (error,
			     G_IO_ERROR,
			     G_IO_ERROR_INVALID_ARGUMENT,
			     _("Can't handle the supplied version of the icon encoding"));
    }
  else
    {
      gchar *scheme;

      /* handle special GFileIcon and GThemedIcon cases */
      scheme = g_uri_parse_scheme (str);
      if (scheme != NULL || str[0] == '/' || str[0] == G_DIR_SEPARATOR)
        {
          GFile *location;
          location = g_file_new_for_commandline_arg (str);
          icon = g_file_icon_new (location);
          g_object_unref (location);
        }
      else
	icon = g_themed_icon_new (str);
      g_free (scheme);
    }

  return icon;
}
