/*
 *  Copyright (C) 2004  Crispin Flowerday
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2, or (at your option)
 *  any later version.
 *
 *  This program 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 General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <glib/gi18n.h>

#include <gtk/gtkimagemenuitem.h>

#include "galeon-favicon-action.h"
#include "galeon-favicon.h"

#include "gul-gobject-misc.h"

/**
 * Private data
 */
struct _GaleonFaviconActionPrivate
{
	gchar *url;
};

enum
{
	PROP_0,
	PROP_URL,
};

static gpointer parent_class;


static void
galeon_favicon_action_sync_url (GaleonFaviconAction *action, GParamSpec *pspec,
				GtkWidget *proxy)
{
	GtkWidget *image = NULL;
  
	if (GTK_IS_IMAGE_MENU_ITEM (proxy))
	{
		image = gtk_image_menu_item_get_image (GTK_IMAGE_MENU_ITEM (proxy));
		
		if (GALEON_IS_FAVICON (image))
		{
			g_object_set (image, "url", action->priv->url, NULL);
		}
	}
}

static void
galeon_favicon_changed_cb (GaleonFavicon *icon, GaleonFaviconAction *action)
{
	if (galeon_favicon_get_is_default (icon))
	{
		gtk_widget_hide (GTK_WIDGET (icon));
	}
	else
	{
		gtk_widget_show (GTK_WIDGET (icon));
	}
}

static void
galeon_favicon_show_cb (GaleonFavicon *icon, GaleonFaviconAction *action)
{
	if (galeon_favicon_get_is_default (icon))
	{
		gtk_widget_hide (GTK_WIDGET (icon));
	}
}

static void
galeon_favicon_action_connect_proxy (GtkAction *action, GtkWidget *proxy)
{
	GtkWidget *image;
	GaleonFaviconAction *act = GALEON_FAVICON_ACTION (action);

	(* GTK_ACTION_CLASS (parent_class)->connect_proxy) (action, proxy);

	if (!GTK_IS_IMAGE_MENU_ITEM (proxy))
	{
		return;
	}

	image = gtk_image_menu_item_get_image (GTK_IMAGE_MENU_ITEM (proxy));
	if (image && !GALEON_IS_FAVICON (image))
	{
		gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (proxy), NULL);
		image = NULL;
	}

	if (!image)
	{
		image = galeon_favicon_new (act->priv->url);

		g_signal_connect_object (image, "changed",
					 G_CALLBACK (galeon_favicon_changed_cb),
					 action, 0);
		g_signal_connect_object (image, "show",
					 G_CALLBACK (galeon_favicon_show_cb),
					 action, 0);


		gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (proxy),
					       image);

		if (galeon_favicon_get_is_default (GALEON_FAVICON (image)))
		{
			gtk_widget_hide (image);
		}
		else
		{
			gtk_widget_show (image);
		}
	}
	
	g_object_set (image, "url", act->priv->url, NULL);

	g_signal_connect_object (action, "notify::url",
				 G_CALLBACK (galeon_favicon_action_sync_url),
				 proxy, 0);
}

static void
galeon_favicon_action_set_url (GaleonFaviconAction *action, const char *url)
{
	if (action->priv->url)
	{
		g_free (action->priv->url);
		action->priv->url = 0;
	}

	if (url)
	{
		action->priv->url = g_strdup (url);
	}

	g_object_notify (G_OBJECT (action), "url");
}

static void
galeon_favicon_action_set_property (GObject *object,
			      guint prop_id,
			      const GValue *value,
			      GParamSpec *pspec)
{
	GaleonFaviconAction *action = GALEON_FAVICON_ACTION (object);

	switch (prop_id)
	{
	case PROP_URL:
		{
			galeon_favicon_action_set_url
				(action, g_value_get_string (value));
		}
		break;
	default: 
		break;
	}
}

static void
galeon_favicon_action_get_property (GObject *object,
				    guint prop_id,
				    GValue *value,
				    GParamSpec *pspec)
{
	GaleonFaviconAction *action = GALEON_FAVICON_ACTION (object);
	
	switch (prop_id)
	{
	case PROP_URL:
		g_value_set_string (value, action->priv->url);
		break;
	default: 
		break;
	}
}


static void
galeon_favicon_action_finalize_impl(GObject *o)
{
	GaleonFaviconAction *action = GALEON_FAVICON_ACTION (o);
	GaleonFaviconActionPrivate *p = action->priv;

	g_free (p->url);
	g_free (p);

	G_OBJECT_CLASS(parent_class)->finalize (o);
}

static void 
galeon_favicon_action_init (GaleonFaviconAction *action)
{
	GaleonFaviconActionPrivate *p = g_new0 (GaleonFaviconActionPrivate, 1);
	action->priv = p;
}

static void
galeon_favicon_action_class_init (GaleonFaviconActionClass *klass)
{
	GObjectClass *object_class = G_OBJECT_CLASS (klass);
	GtkActionClass *action_class = GTK_ACTION_CLASS (klass);

	parent_class = g_type_class_peek_parent(klass);

	object_class->set_property = galeon_favicon_action_set_property;
	object_class->get_property = galeon_favicon_action_get_property;
	object_class->finalize     = galeon_favicon_action_finalize_impl;

	action_class->connect_proxy  = galeon_favicon_action_connect_proxy;
	action_class->menu_item_type = GTK_TYPE_IMAGE_MENU_ITEM;

	g_object_class_install_property (object_class,
                                         PROP_URL,
                                         g_param_spec_string ("url",
                                                              ("Url"),
                                                              "Url to use for looking up in the favicon cache",
							      NULL,
                                                              G_PARAM_READWRITE));
}

MAKE_GET_TYPE(galeon_favicon_action, "GaleonFaviconAction", GaleonFaviconAction,
	      galeon_favicon_action_class_init,
	      galeon_favicon_action_init, GTK_TYPE_ACTION);
