/*
 *  Copyright (C) 2003 Ricardo Fernández Pascual
 *
 *  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 <gtk/gtktoolitem.h>
#include <gtk/gtkalignment.h>

#include "galeon-action-spinner.h"
#include "gul-gobject-misc.h"
#include "galeon-spinner.h"
#include "galeon-shell.h"
#include "pixbuf-cache.h"
#include "galeon-config.h"
#include <glib/gi18n.h>
#include <string.h>

static void		galeon_action_spinner_init			(GaleonAction *action);
static void		galeon_action_spinner_class_init		(GaleonActionClass *class);
static void		galeon_action_spinner_finalize			(GObject *object);
static void		galeon_action_spinner_update			(GaleonAction *action);
static void		galeon_action_spinner_current_embed_changed	(GaleonAction *action, 
									 GaleonEmbed *old_embed, GaleonEmbed *new_embed);
static GtkWidget *	galeon_action_spinner_create_toolitem		(GtkAction *action);

static GtkActionClass *parent_class = NULL;

MAKE_GET_TYPE (galeon_action_spinner, "GaleonActionSpinner", GaleonActionSpinner, galeon_action_spinner_class_init, 
	       galeon_action_spinner_init, GALEON_TYPE_ACTION);


static void
galeon_action_spinner_class_init (GaleonActionClass *class)
{
	GObjectClass *object_class = G_OBJECT_CLASS (class);
	GtkActionClass *action_class = GTK_ACTION_CLASS (class);
	GaleonActionClass *galeon_action_class = GALEON_ACTION_CLASS (class);

	object_class->finalize = galeon_action_spinner_finalize;

	action_class->create_tool_item = galeon_action_spinner_create_toolitem;

	galeon_action_class->update = galeon_action_spinner_update;
	galeon_action_class->current_embed_changed = galeon_action_spinner_current_embed_changed;

	parent_class = g_type_class_peek_parent (class);
}

static void
galeon_action_spinner_init (GaleonAction *action)
{
	g_object_set (G_OBJECT (action), "tooltip", _("Go to Galeon homepage"), NULL);	
	g_object_set (G_OBJECT (action), "label", _("Spinner"), NULL);	
	g_object_set (G_OBJECT (action), "stock_id", STOCK_SPINNER_REST, NULL);
}

static void
galeon_action_spinner_finalize (GObject *object)
{
	G_OBJECT_CLASS (parent_class)->finalize (object);
}

static void
galeon_action_spinner_update (GaleonAction *action)
{
	GSList *sli;
	gboolean spin = FALSE;
	GaleonWindow *window = galeon_action_get_window (action);

	if (window)
	{
		GList *tabs = galeon_window_get_tabs (window);
		GList *l;
		
		for (l = tabs; l; l = l->next)
		{
			GaleonTab *tab = l->data;
			g_return_if_fail (IS_GALEON_TAB (tab));
			
			if (galeon_tab_get_load_status (tab) & TAB_LOAD_STARTED)
			{
				spin = TRUE;
				break;
			}
		}
		g_list_free (tabs);
	}
	
	for (sli = gtk_action_get_proxies (GTK_ACTION (action)); sli; sli = sli->next)
	{
		GtkWidget *alignment = GTK_BIN (sli->data)->child;
		GaleonSpinner *spinner = GALEON_SPINNER (GTK_BIN (alignment)->child);
		if (spin)
		{
			galeon_spinner_start (spinner);
		}
		else
		{
			galeon_spinner_stop (spinner);
		}
	}
}

static void
galeon_action_spinner_current_embed_changed (GaleonAction *action, 
					      GaleonEmbed *old_embed, GaleonEmbed *new_embed)
{
	if (old_embed)
	{
		g_signal_handlers_disconnect_matched (old_embed, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, action);
	}

	if (new_embed)
	{
	}

	galeon_action_spinner_update (action);
}

static gboolean
galeon_action_spinner_button_release_event_cb (GtkWidget *w, GdkEventButton *ev, GaleonAction *action)
{
	GaleonWindow *window = galeon_action_get_window (action);
        if (ev->button == 1)
        {
                galeon_window_load_url (window, GALEON_HOMEPAGE_URL);
        }
        else if (ev->button == 2)
        {
                galeon_shell_new_tab (galeon_shell, window, NULL,
                                      GALEON_HOMEPAGE_URL, 0);
        }
	return FALSE;
}

static gboolean
toolitem_create_menu_proxy_cb (GtkToolItem *toolitem, gpointer dummy)
{
	/* Don't show item in overflow menu */
	gtk_tool_item_set_proxy_menu_item (toolitem, "dummy", NULL);
	return TRUE;
}


/*
 * Check to see whether the toolitem should have 'expand' set, it should
 * if there are no other items with that flag set, this ensures that the
 * spinner is always on the right hand side of the screen 
 */
static void
toolitem_toolbar_size_allocate_cb (GtkToolbar *toolbar, GtkAllocation *allocation,
				   GtkToolItem *toolitem)
{
	int i, n_items;
	gboolean expand = TRUE;

	g_return_if_fail (GTK_IS_TOOLBAR (toolbar));

	n_items = gtk_toolbar_get_n_items (toolbar);
	for (i = 0 ; i < n_items ; i++)
	{
		GtkToolItem *  item;

		item = gtk_toolbar_get_nth_item (toolbar, i);
		if (gtk_tool_item_get_expand (item) &&
		    item != toolitem )
		{
			expand = FALSE;
			break;
		}
	}
	gtk_tool_item_set_expand (toolitem, expand);
}

static void
toolitem_parent_set_cb (GtkToolItem *toolitem, GtkObject *old_parent, gpointer dummy)
{
	GtkWidget *parent;

	if (old_parent)
	{
		g_signal_handlers_disconnect_matched (old_parent, G_SIGNAL_MATCH_DATA, 0, 0,
						      NULL, NULL, toolitem);
	}
	
	parent = GTK_WIDGET (toolitem)->parent;
	if (parent)
	{
		g_signal_connect_object (parent, "size_allocate",
			      G_CALLBACK (toolitem_toolbar_size_allocate_cb), toolitem, 0);
	}
}


static GtkWidget *
galeon_action_spinner_create_toolitem (GtkAction *action)
{
	GtkToolItem *ti = gtk_tool_item_new ();
	GtkWidget *ali = gtk_alignment_new (1, 0.5, 0, 0);
	GtkWidget *gs = galeon_spinner_new ();
	galeon_spinner_set_small_mode (GALEON_SPINNER (gs), TRUE);
	gtk_container_add (GTK_CONTAINER (ali), gs);
	gtk_container_add (GTK_CONTAINER (ti), ali);
	
	gtk_widget_show (ali);
	gtk_widget_show (gs);

	g_signal_connect (gs, "button-release-event",
			  G_CALLBACK (galeon_action_spinner_button_release_event_cb), action);
	g_signal_connect (ti, "create-menu-proxy",
			  G_CALLBACK (toolitem_create_menu_proxy_cb), NULL);
	g_signal_connect (ti, "parent-set",
			  G_CALLBACK (toolitem_parent_set_cb), NULL);

	return GTK_WIDGET (ti);
}
