/* -*- 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-navigation-action.h"

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

#if GTK_CHECK_VERSION(2,6,0)
#define EGG_TYPE_DROPDOWN_TOOL_BUTTON GTK_TYPE_MENU_TOOL_BUTTON
#define EGG_DROPDOWN_TOOL_BUTTON GTK_MENU_TOOL_BUTTON
#define EGG_IS_DROPDOWN_TOOL_BUTTON GTK_IS_MENU_TOOL_BUTTON
#define EggDropdownToolButton GtkMenuToolButton
#define EGG_DROPDOWN_MENU_ACTIVATED_SIGNAL "show-menu"
#define egg_dropdown_tool_button_set_menu gtk_menu_tool_button_set_menu
#define egg_dropdown_tool_button_get_menu gtk_menu_tool_button_get_menu
#else
#include "eggdropdowntoolbutton.h"
#define EGG_DROPDOWN_MENU_ACTIVATED_SIGNAL "menu-activated"
#endif

enum {
	PROP_0,
	PROP_KZ_WINDOW
};


static void kz_navigation_action_class_init       (KzNavigationActionClass *class);
static void kz_navigation_action_init             (KzNavigationAction      *action);
static void kz_navigation_action_dispose          (GObject *obj);
static void kz_navigation_action_set_property     (GObject           *object,
						   guint              prop_id,
						   const GValue      *value,
						   GParamSpec        *pspec);
static void kz_navigation_action_get_property     (GObject           *object,
						   guint              prop_id,
						   GValue            *value,
						   GParamSpec        *pspec);
static void kz_navigation_action_connect_proxy    (GtkAction         *action,
						   GtkWidget         *proxy);
static void kz_navigation_action_activate         (GtkAction         *action);
#if 0
static void kz_navigation_action_disconnect_proxy (GtkAction         *action,
						   GtkWidget         *proxy);
#endif
static void cb_menu_activated                     (EggDropdownToolButton *b,
						   KzNavigationAction *action);
static GtkActionClass *parent_class = NULL;


KZ_OBJECT_GET_TYPE(kz_navigation_action, "KzNavigationAction", KzNavigationAction,
		   kz_navigation_action_class_init, kz_navigation_action_init,
		   GTK_TYPE_ACTION)


static void
kz_navigation_action_class_init (KzNavigationActionClass *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_navigation_action_set_property;
	object_class->get_property     = kz_navigation_action_get_property;
	object_class->dispose          = kz_navigation_action_dispose;

	action_class->toolbar_item_type = EGG_TYPE_DROPDOWN_TOOL_BUTTON;
	action_class->connect_proxy     = kz_navigation_action_connect_proxy;
	action_class->activate          = kz_navigation_action_activate;

	g_object_class_install_property
		(object_class,
		 PROP_KZ_WINDOW,
		 g_param_spec_object ("kz-window",
				      _("KzWindow"),
				      _("The KzWindow to add a navigation button"),
				      KZ_TYPE_WINDOW,
				      G_PARAM_READWRITE |
				      G_PARAM_CONSTRUCT_ONLY));
}


static void
kz_navigation_action_init (KzNavigationAction *action)
{
	action->kz = NULL;
}


static void
kz_navigation_action_dispose (GObject *obj)
{
	KzNavigationAction *action = KZ_NAVIGATION_ACTION(obj);

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

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


static void
kz_navigation_action_set_property (GObject         *object,
				   guint            prop_id,
				   const GValue    *value,
				   GParamSpec      *pspec)
{
	KzNavigationAction *action = KZ_NAVIGATION_ACTION(object);
  
	switch (prop_id)
	{
	case PROP_KZ_WINDOW:
		action->kz = g_object_ref(g_value_get_object(value));
		break;
	default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
		break;
	}
}


static void
kz_navigation_action_get_property (GObject         *object,
				   guint            prop_id,
				   GValue          *value,
				   GParamSpec      *pspec)
{
	KzNavigationAction *action = KZ_NAVIGATION_ACTION(object);

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

static void
kz_navigation_action_connect_proxy (GtkAction *action, GtkWidget *proxy)
{
	GtkWidget *menu;

	g_signal_connect (proxy, EGG_DROPDOWN_MENU_ACTIVATED_SIGNAL,
			  G_CALLBACK (cb_menu_activated), action);
	
	if (EGG_IS_DROPDOWN_TOOL_BUTTON(proxy))
	{
		menu = egg_dropdown_tool_button_get_menu(EGG_DROPDOWN_TOOL_BUTTON(proxy));
		if (!menu)
		{
			menu = gtk_menu_new();
			egg_dropdown_tool_button_set_menu(EGG_DROPDOWN_TOOL_BUTTON(proxy), menu);
		}
	}

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


#if 0
static void
kz_navigation_action_disconnect_proxy (GtkAction *action, GtkWidget *proxy)
{
	GTK_ACTION_CLASS (parent_class)->disconnect_proxy (action, proxy);
}
#endif

static void
kz_navigation_action_activate (GtkAction *action)
{
	GtkWidget *widget;

	g_return_if_fail(KZ_NAVIGATION_ACTION(action));

	widget = KZ_WINDOW_CURRENT_PAGE(KZ_NAVIGATION_ACTION(action)->kz);

	if (!widget) return;

	if (KZ_EMBED(widget))
	{
		kz_embed_go_back(KZ_EMBED(widget));
	}
}

static void
cb_menu_item_activate (GtkWidget *menu, KzNavigationAction *action)
{
	gint go_nth;

	KzEmbed *kzembed = KZ_EMBED(KZ_WINDOW_CURRENT_PAGE(action->kz));

	go_nth = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(menu), "go_nth"));

	kz_embed_go_history_index(kzembed, go_nth);
}

static void
remove_item (GtkWidget *child, gpointer data)
{
	gtk_container_remove(GTK_CONTAINER(child->parent), child);
}

static void
cb_menu_activated (EggDropdownToolButton *b, KzNavigationAction *action)
{
	int i, pos, count;
	GtkWidget *menu;
	KzEmbed *kzembed = KZ_EMBED(KZ_WINDOW_CURRENT_PAGE(action->kz));
	KzFavicon *kzfav = action->kz->kzfav;

	menu = egg_dropdown_tool_button_get_menu(b);
	if (menu)
	{
		gtk_container_foreach (GTK_CONTAINER(menu),
				       remove_item, NULL);
	}
	else
	{
		menu = gtk_menu_new();
	}

	kz_embed_shistory_get_pos(kzembed, &pos, &count);

	for (i = 0; i < pos; i++)
	{
		gchar *title = NULL, *uri = NULL;
		GtkWidget *item;
		GtkWidget *favicon = NULL;

		kz_embed_shistory_get_nth (kzembed, i, FALSE,
					   &uri, &title);
		item = gtk_image_menu_item_new_with_label(title);

		favicon	= kz_favicon_get_widget(kzfav, uri,
						KZ_ICON_SIZE_BOOKMARK_MENU);
		gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item),
					      favicon);

		gtk_menu_shell_prepend(GTK_MENU_SHELL(menu), item);
		g_object_set_data(G_OBJECT(item), "go_nth",
				  GINT_TO_POINTER(i));
		g_signal_connect(item, "activate",
                                 G_CALLBACK (cb_menu_item_activate), action);
		gtk_widget_show(item);
	
		if (title)
			g_free(title);
		if (uri)
			g_free(uri);
	}

	egg_dropdown_tool_button_set_menu(b, menu);
}

