/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */

/*
 *  Copyright (C) 2003-2004 Hiroyuki Ikezoe
 *  Copyright (C) 2003 Takuro Ashie
 *
 *  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.
 */

#include "kz-stop-reload-action.h"

#include <glib/gi18n.h>
#include "kazehakase.h"
#include "gobject-utils.h"

struct _KzStopReloadActionPrivate 
{
	KzWindow *kz;
	gint      state;
};

enum {
	PROP_0,
	PROP_KZ_WINDOW,
	PROP_STATE
};


static void kz_stop_reload_action_class_init       (KzStopReloadActionClass *class);
static void kz_stop_reload_action_init             (KzStopReloadAction      *action);
static void kz_stop_reload_action_dispose          (GObject *obj);
static void kz_stop_reload_action_finalize         (GObject *obj);
static void kz_stop_reload_action_set_property     (GObject           *object,
						    guint              prop_id,
						    const GValue      *value,
						    GParamSpec        *pspec);
static void kz_stop_reload_action_get_property     (GObject           *object,
						    guint              prop_id,
						    GValue            *value,
						    GParamSpec        *pspec);

static void kz_stop_reload_action_activate         (GtkAction         *action);
static void kz_stop_reload_action_connect_proxy    (GtkAction         *action,
						    GtkWidget         *proxy);
static void kz_stop_reload_action_disconnect_proxy (GtkAction         *action,
						    GtkWidget         *proxy);

static void kz_stop_reload_action_sync_state       (GtkAction  *action,
				  		    GParamSpec *pspec,
				  		    GtkWidget  *proxy);

static GtkActionClass *parent_class = NULL;

KZ_OBJECT_GET_TYPE(kz_stop_reload_action, "KzStopReloadAction", KzStopReloadAction,
		   kz_stop_reload_action_class_init, kz_stop_reload_action_init,
		   GTK_TYPE_ACTION)

KZ_OBJECT_FINALIZE(kz_stop_reload_action, KzStopReloadAction)

static void
kz_stop_reload_action_class_init (KzStopReloadActionClass *klass)
{
	GObjectClass *object_class;
	GtkActionClass *action_class;

	parent_class = g_type_class_peek_parent(klass);
	object_class = G_OBJECT_CLASS(klass);
	action_class = GTK_ACTION_CLASS(klass);

	object_class->set_property     = kz_stop_reload_action_set_property;
	object_class->get_property     = kz_stop_reload_action_get_property;
	object_class->dispose          = kz_stop_reload_action_dispose;
	object_class->finalize         = kz_stop_reload_action_finalize;

	action_class->activate         = kz_stop_reload_action_activate;
	action_class->connect_proxy    = kz_stop_reload_action_connect_proxy;
	action_class->disconnect_proxy = kz_stop_reload_action_disconnect_proxy;

	g_object_class_install_property
		(object_class,
		 PROP_KZ_WINDOW,
		 g_param_spec_object ("kz-window",
				      _("KzWindow"),
				      _("The KzWindow to add a stop_reload button"),
				      KZ_TYPE_WINDOW,
				      G_PARAM_READWRITE |
				      G_PARAM_CONSTRUCT_ONLY));
	g_object_class_install_property
		(object_class,
		 PROP_STATE,
		 g_param_spec_int ("state",
				 _("The state"),
				 _("The state of reload of stop"),
				   G_MININT,
				   G_MAXINT,
				   KZ_STOP_RELOAD_ACTION_STATE_RELOAD,
				   G_PARAM_READWRITE));
}


static void
kz_stop_reload_action_init (KzStopReloadAction *action)
{
  	action->priv = g_new0(KzStopReloadActionPrivate, 1);
  	action->priv->kz = NULL;
  	action->priv->state = KZ_STOP_RELOAD_ACTION_STATE_RELOAD;
}


static void
kz_stop_reload_action_dispose (GObject *obj)
{
	KzStopReloadAction *action = KZ_STOP_RELOAD_ACTION(obj);

	if (action->priv->kz)
		g_object_unref(action->priv->kz);
	action->priv->kz = NULL;

	if (G_OBJECT_CLASS(parent_class)->dispose)
		G_OBJECT_CLASS(parent_class)->dispose(obj);
}


static void
kz_stop_reload_action_set_property (GObject         *object,
				    guint            prop_id,
				    const GValue    *value,
				    GParamSpec      *pspec)
{
	KzStopReloadAction *action = KZ_STOP_RELOAD_ACTION(object);
  
	switch (prop_id)
	{
	case PROP_KZ_WINDOW:
		action->priv->kz = g_object_ref(g_value_get_object(value));
		break;
	case PROP_STATE:
		action->priv->state = g_value_get_int(value);
		break;
	default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
		break;
	}
}


static void
kz_stop_reload_action_get_property (GObject         *object,
				    guint            prop_id,
				    GValue          *value,
				    GParamSpec      *pspec)
{
	KzStopReloadAction *action = KZ_STOP_RELOAD_ACTION(object);

	switch (prop_id)
	{
	case PROP_KZ_WINDOW:
		g_value_set_object(value, action->priv->kz);
		break;
    	case PROP_STATE:
      		g_value_set_int (value, action->priv->state);
      		break;
	default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
		break;
	}
}


KzStopReloadAction *
kz_stop_reload_action_new(KzWindow *kz)
{
	KzStopReloadAction *action;

	action = KZ_STOP_RELOAD_ACTION(g_object_new(KZ_TYPE_STOP_RELOAD_ACTION,
						    "name",     "StopReload",
						    "label",    _("_Reload"),
			     			    "tooltip",  _("Display the latest content of the current page"),
						    "stock_id",  GTK_STOCK_REFRESH,
						    "kz-window", kz,
						    NULL));

	return action;
}


static void
kz_stop_reload_action_activate (GtkAction *action)
{
	KzWindow *kz;
	GdkModifierType state = (GdkModifierType)0;
	gint x, y;
	GtkWidget *widget;
	
	kz = KZ_STOP_RELOAD_ACTION(action)->priv->kz;
	if (!KZ_IS_WINDOW(kz)) return;

	gdk_window_get_pointer(NULL, &x, &y, &state);

	widget = KZ_WINDOW_CURRENT_PAGE(kz);

	if (KZ_IS_EMBED(widget))
	{
		KzStopReloadActionState action_state;
		action_state = KZ_STOP_RELOAD_ACTION(action)->priv->state;

		switch (action_state)
		{
		case KZ_STOP_RELOAD_ACTION_STATE_STOP:	
			kz_embed_stop_load(KZ_EMBED(widget));
			break;
		case KZ_STOP_RELOAD_ACTION_STATE_RELOAD:
			kz_embed_reload(KZ_EMBED(widget),
					(state & GDK_SHIFT_MASK) ?
					KZ_EMBED_RELOAD_BYPASS_PROXY_AND_CACHE : 
					KZ_EMBED_RELOAD_NORMAL);
			break;
		default:
			break;
		}
	}
}


static void
kz_stop_reload_action_connect_proxy (GtkAction *action, GtkWidget *proxy)
{
	g_signal_connect_object(action, "notify::state",
				G_CALLBACK(kz_stop_reload_action_sync_state),
				proxy, 0);
	(* GTK_ACTION_CLASS (parent_class)->connect_proxy) (action, proxy);
}


static void
kz_stop_reload_action_disconnect_proxy (GtkAction *action, GtkWidget *proxy)
{
	GTK_ACTION_CLASS (parent_class)->disconnect_proxy (action, proxy);

	g_signal_handlers_disconnect_by_func
			(G_OBJECT(proxy),
			 G_CALLBACK(kz_stop_reload_action_sync_state),
			 action);
}


static void
kz_stop_reload_action_sync_state (GtkAction  *action,
				  GParamSpec *pspec,
				  GtkWidget  *proxy)
{
	KzStopReloadActionState state;
	gchar *stock_id;
	
	state = KZ_STOP_RELOAD_ACTION(action)->priv->state;

	switch(state)
	{
	case KZ_STOP_RELOAD_ACTION_STATE_STOP:
		g_object_set(G_OBJECT(action),
			     "label",   _("_Stop"),
			     "tooltip", _("Stop current data transfer"),
			     "stock_id",  GTK_STOCK_STOP,
			     NULL);
		break;
	case KZ_STOP_RELOAD_ACTION_STATE_RELOAD:
	default:
		g_object_set(G_OBJECT(action),
			     "label", _("_Reload"),
			     "tooltip", _("Display the latest content of the current page"),
			     "stock_id", GTK_STOCK_REFRESH,
			     NULL);
		break;
	}

	/* 
	 * GtkAction does not redraw proxy widget 
	 * when the stock_id changes 
	 * so we redraw wproxy widget explicitly.
	 */
	g_object_get(G_OBJECT(action),
		     "stock_id", &stock_id,
		     NULL);

	if (GTK_IS_IMAGE_MENU_ITEM(proxy))
	{
		GtkWidget *image;
		image = gtk_image_new_from_stock(stock_id, GTK_ICON_SIZE_MENU);
		gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(proxy), 
					      image);
	}
	else if (GTK_IS_TOOL_BUTTON(proxy))
	{
		GtkWidget *image;
		image = gtk_image_new_from_stock(stock_id, GTK_ICON_SIZE_BUTTON);
		gtk_tool_button_set_icon_widget(GTK_TOOL_BUTTON(proxy),
						image);
		gtk_widget_show(image);
	}
	g_free(stock_id);
}


void
kz_stop_reload_action_set_state (KzStopReloadAction *action,
				 KzStopReloadActionState state)
{
	g_return_if_fail(KZ_IS_STOP_RELOAD_ACTION(action));

	g_object_set(G_OBJECT(action),
		     "state", state, NULL);
}

