/* -*- 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-smart-bookmark-button-action.h"

#include "kazehakase.h"
#include "intl.h"
#include "gobject-utils.h"
#include "gtk24backports.h"

#include <time.h>

enum {
	PROP_0,
	PROP_BOOKMARK,
	PROP_KZ_WINDOW
};


static void kz_smart_bookmark_button_action_class_init (KzSmartBookmarkButtonActionClass *class);
static void kz_smart_bookmark_button_action_init       (KzSmartBookmarkButtonAction      *action);

static void       dispose          (GObject      *obj);
static void       set_property     (GObject      *object,
			            guint         prop_id,
			            const GValue *value,
			            GParamSpec   *pspec);
static void       get_property     (GObject      *object,
			            guint         prop_id,
			            GValue       *value,
			            GParamSpec   *pspec);
static GtkWidget *create_tool_item (GtkAction    *action);
static void       activate         (GtkAction    *action);
static void       connect_proxy    (GtkAction    *action,
			            GtkWidget    *proxy);
static void       disconnect_proxy (GtkAction    *action,
			            GtkWidget    *proxy);

static const gchar *get_entry_text   (GtkAction    *action,
		  		      GtkWidget    *widget);

/* callbacks */
static gboolean kz_smart_bookmark_button_press_cb (GtkWidget      *widget,
						   GdkEventButton *event,
						   KzSmartBookmarkButtonAction   *action);

static GtkActionClass *parent_class = NULL;


KZ_OBJECT_GET_TYPE(kz_smart_bookmark_button_action, 
		   "KzSmartBookmarkButtonAction",
		   KzSmartBookmarkButtonAction,
 		   kz_smart_bookmark_button_action_class_init,
		   kz_smart_bookmark_button_action_init,
		   GTK_TYPE_ACTION)

static void
kz_smart_bookmark_button_action_class_init (KzSmartBookmarkButtonActionClass *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     = set_property;
	object_class->get_property     = get_property;
	object_class->dispose          = dispose;

	action_class->activate         = activate;
	action_class->connect_proxy    = connect_proxy;
	action_class->disconnect_proxy = disconnect_proxy;
	action_class->create_tool_item = create_tool_item;

	g_object_class_install_property
		(object_class,
		 PROP_BOOKMARK,
		 g_param_spec_object ("kz-bookmark",
				      _("Bookmark Object"),
				      _("Bookmark Object for smart bookmark"),
				      KZ_TYPE_BOOKMARK,
				      G_PARAM_READWRITE |
				      G_PARAM_CONSTRUCT_ONLY));

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


static void
kz_smart_bookmark_button_action_init (KzSmartBookmarkButtonAction *action)
{
	action->bookmark   = NULL;
	action->kz         = NULL;
}


static void
dispose (GObject *obj)
{
	KzSmartBookmarkButtonAction *action = KZ_SMART_BOOKMARK_BUTTON_ACTION(obj);

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

	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
set_property (GObject         *object,
	      guint            prop_id,
	      const GValue    *value,
	      GParamSpec      *pspec)
{
	KzSmartBookmarkButtonAction *action = KZ_SMART_BOOKMARK_BUTTON_ACTION(object);
  
	switch (prop_id)
	{
	case PROP_BOOKMARK:
		action->bookmark = g_object_ref(g_value_get_object(value));
		break;
	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
get_property (GObject         *object,
	      guint            prop_id,
	      GValue          *value,
	      GParamSpec      *pspec)
{
	KzSmartBookmarkButtonAction *action = KZ_SMART_BOOKMARK_BUTTON_ACTION(object);

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


KzSmartBookmarkButtonAction *
kz_smart_bookmark_button_action_new(KzWindow *kz, KzBookmark *bookmark)
{
	KzSmartBookmarkButtonAction *action;

	action = KZ_SMART_BOOKMARK_BUTTON_ACTION(g_object_new(KZ_TYPE_SMART_BOOKMARK_BUTTON_ACTION,
						 "name",      "SmartBookmarkButton",
						 "label",     _("_SmartBookmarkButton"),
						 "tooltip",   _("Search"),
						 "stock_id",    KZ_STOCK_SEARCH,
						 "kz-bookmark", bookmark,
						 "kz-window",   kz,
						 NULL));

	return action;
}


static void
activate (GtkAction *action)
{
	KzBookmark *bookmark;
	KzWindow *kz;
	const gchar *text;
	gchar *smart_uri;

	bookmark = KZ_SMART_BOOKMARK_BUTTON_ACTION(action)->bookmark;
	g_return_if_fail(KZ_IS_BOOKMARK(bookmark));

	kz = KZ_SMART_BOOKMARK_BUTTON_ACTION(action)->kz;
	if (!KZ_IS_WINDOW(kz)) return;

	text = get_entry_text(action, NULL);

	smart_uri = kz_bookmark_get_smart_uri(bookmark, text);
	kz_window_load_url(kz, smart_uri);

	g_free(smart_uri);
}


static void
connect_proxy (GtkAction *action, GtkWidget *proxy)
{
	g_signal_connect(proxy,
			 "button-press-event",
			 G_CALLBACK(kz_smart_bookmark_button_press_cb),
			 action);
	(* GTK_ACTION_CLASS (parent_class)->connect_proxy) (action, proxy);
}


static void
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_smart_bookmark_button_press_cb),
			 action);
}

static GtkWidget *
create_tool_item (GtkAction *action)
{
	GtkWidget *button;
	GtkWidget *item;

	item =  (* GTK_ACTION_CLASS (parent_class)->create_tool_item) (action);

	button = gtk_bin_get_child(GTK_BIN(item));

	g_signal_connect(button,
			 "button-press-event",
			 G_CALLBACK(kz_smart_bookmark_button_press_cb),
			 action);
	gtk_widget_show(button);
	
	return item;
}


static gboolean
kz_smart_bookmark_button_press_cb (GtkWidget *widget,
				   GdkEventButton *event,
				   KzSmartBookmarkButtonAction *action)
{
	KzBookmark *bookmark = action->bookmark;
	KzWindow *kz = action->kz;
	const gchar *text;
	gchar *smart_uri;
	
	if (!KZ_IS_WINDOW(kz)) return FALSE;

	text = get_entry_text(GTK_ACTION(action), widget);
	smart_uri = kz_bookmark_get_smart_uri(bookmark, text);

	switch (event->button)
	{
	case 1: /* open in the current tab */
		kz_window_load_url(kz, smart_uri);
		g_free(smart_uri);
		return TRUE;
		break;
	case 2: /* open in new tab */
		kz_window_open_new_tab(kz, smart_uri);
		g_free(smart_uri);
		return TRUE;
		break;
	case 3:
	default:
		break;
	}

	return FALSE;
}

static const gchar *
get_entry_text (GtkAction *action, GtkWidget *widget)
{
	const gchar *text = NULL;
	GtkEntry *entry = NULL;
	GSList *widgets;
	GtkWidget *toolbar, *toolitem;
	gint position;
	
	widgets = gtk_ui_manager_get_toplevels(KZ_SMART_BOOKMARK_BUTTON_ACTION(action)->kz->menu_merge,
					       GTK_UI_MANAGER_TOOLBAR);
	toolbar = widgets->data;
	
	toolitem = gtk_widget_get_ancestor(widget, GTK_TYPE_TOOL_ITEM);
	if (!toolitem)
		return NULL;

	position = gtk24_toolbar_get_item_index(GTK24_TOOLBAR(toolbar),
						GTK_TOOL_ITEM(toolitem));
	position--;
	while (position >= 0)
	{
		GtkToolItem *proxy;
		proxy = gtk24_toolbar_get_nth_item(GTK24_TOOLBAR(toolbar),
						   position);
		if (GTK_IS_BIN(proxy))
		{
			if (GTK_IS_ENTRY(GTK_BIN(proxy)->child))
			{
				entry = GTK_ENTRY(GTK_BIN(proxy)->child);
				break;
			}
			else if (GTK_IS_COMBO(GTK_BIN(proxy)->child))
			{
				entry = GTK_ENTRY(GTK_COMBO(GTK_BIN(proxy)->child)->entry);
				break;
			}
		}
		position--;
	}
	
	if (entry)
	{
		text = gtk_entry_get_text(GTK_ENTRY(entry));
	}

	return text;
}

