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

/*
 *  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-actions-tab.h"

#include <string.h>
#include "egg-toggle-action.h"
#include "egg-action.h"
#include "gtk-utils.h"
#include "intl.h"
#include "kazehakase.h"


static GQuark kztab_quark = 0;


static void
act_tab_reload (EggAction *action, KzWindow *kz)
{
	KzTabLabel *kztab;

	g_return_if_fail(KZ_IS_WINDOW(kz));

	kztab = g_object_get_qdata(G_OBJECT(kz), kztab_quark);
	g_return_if_fail(KZ_IS_TAB_LABEL(kztab));

	gtk_moz_embed_reload(GTK_MOZ_EMBED(kztab->kzembed),
			     GTK_MOZ_EMBED_FLAG_RELOADNORMAL);
}

static void
act_tab_stop (EggAction *action, KzWindow *kz)
{
	KzTabLabel *kztab;

	g_return_if_fail(KZ_IS_WINDOW(kz));

	kztab = g_object_get_qdata(G_OBJECT(kz), kztab_quark);
	g_return_if_fail(KZ_IS_TAB_LABEL(kztab));

	gtk_moz_embed_stop_load(GTK_MOZ_EMBED(kztab->kzembed));
}

static void
act_tab_close (EggAction *action, KzWindow *kz)
{
	KzTabLabel *kztab;

	g_return_if_fail(KZ_IS_WINDOW(kz));

	kztab = g_object_get_qdata(G_OBJECT(kz), kztab_quark);
	g_return_if_fail(KZ_IS_TAB_LABEL(kztab));

	kz_window_close_tab(kztab->kz, GTK_WIDGET(kztab->kzembed));
}

static void
close_all_tab (EggAction *action, KzWindow *kz, gint mode)
{
	KzTabLabel *kztab;
	GtkNotebook *notebook;
	gint num, pos;
	gint i;

	g_return_if_fail(KZ_IS_WINDOW(kz));

	kztab = g_object_get_qdata(G_OBJECT(kz), kztab_quark);

	g_return_if_fail(KZ_IS_TAB_LABEL(kztab));
	notebook = GTK_NOTEBOOK(kztab->kz->notebook);

	num = gtkutil_notebook_get_n_pages(notebook);
	pos = gtk_notebook_page_num(notebook, GTK_WIDGET(kztab->kzembed));

	if (num < 2 || pos < 0) return;

	for (i = num - 1; i >= 0; i--)
	{
		GtkWidget *widget = KZ_WINDOW_NTH_PAGE(kztab->kz, i);

		if (i == pos) continue;
		if (i > pos && mode == 1) continue;
		if (i < pos && mode == 2) continue;

		kz_window_close_tab(kztab->kz, widget);
	}
}

static void
act_tab_close_left (EggAction *action, KzWindow *kz)
{
	close_all_tab(action, kz, 1);
}

static void
act_tab_close_right (EggAction *action, KzWindow *kz)
{
	close_all_tab(action, kz, 2);
}

static void
act_tab_close_all_without_active (EggAction *action, KzWindow *kz)
{
	close_all_tab(action, kz, 0);
}


static gboolean
get_all_under_current_tab (GNode *node, gpointer data)
{
	GList **list = data;

	*list = g_list_append(*list, node->data);

	return FALSE;
}


static void
act_tab_close_all_child (EggAction *action, KzWindow *kz)
{
	KzMozEmbed *kzembed;
	KzTabLabel *kztab;
	GNode *tree, *parent;
	GList *list = NULL, *node;

	g_return_if_fail(KZ_IS_WINDOW (kz));

	kztab = g_object_get_qdata(G_OBJECT(kz), kztab_quark);

	kzembed = kztab->kzembed;
	tree = kz_window_get_tree(kz);
	parent = g_node_find(tree, G_IN_ORDER, G_TRAVERSE_ALL, kzembed);
	g_return_if_fail(parent);

	g_node_traverse(parent, G_PRE_ORDER, G_TRAVERSE_ALL, -1,
			get_all_under_current_tab, &list);
	for (node = list; node; node = g_list_next(node))
	{
		GtkWidget *widget = node->data;

		if (widget != GTK_WIDGET(kzembed))
			kz_window_close_tab(kz, widget);
	}
	g_list_free(list);
}


static void
act_tab_copy_title (EggAction *action, KzWindow *kz)
{
	KzTabLabel *kztab;

	g_return_if_fail(KZ_IS_WINDOW(kz));

	kztab = g_object_get_qdata(G_OBJECT(kz), kztab_quark);
	g_return_if_fail(KZ_IS_TAB_LABEL(kztab));

	gtkutil_copy_text(kz_moz_embed_get_title(KZ_MOZ_EMBED(kztab->kzembed)));
}

static void
act_tab_copy_location (EggAction *action, KzWindow *kz)
{
	KzTabLabel *kztab;

	g_return_if_fail(KZ_IS_WINDOW(kz));

	kztab = g_object_get_qdata(G_OBJECT(kz), kztab_quark);
	g_return_if_fail(KZ_IS_TAB_LABEL(kztab));

	gtkutil_copy_text(kz_moz_embed_get_location(KZ_MOZ_EMBED(kztab->kzembed)));
}

static void
act_tab_copy_title_and_location (EggAction *action, KzWindow *kz)
{
	KzTabLabel *kztab;
	gchar *str;

	g_return_if_fail(KZ_IS_WINDOW(kz));

	kztab = g_object_get_qdata(G_OBJECT(kz), kztab_quark);
	g_return_if_fail(KZ_IS_TAB_LABEL(kztab));

	str = g_strdup_printf("<a href=\"%s\" title=\"%s\">%s</a>",
			      kz_moz_embed_get_location(KZ_MOZ_EMBED(kztab->kzembed)),
			      kz_moz_embed_get_title(KZ_MOZ_EMBED(kztab->kzembed)),
			      kz_moz_embed_get_title(KZ_MOZ_EMBED(kztab->kzembed)));
	gtkutil_copy_text(str);
	g_free(str);
}

static void
act_tab_toggle_lock (EggAction *action, KzWindow *kz)
{
	KzTabLabel *kztab;

	g_return_if_fail(EGG_IS_TOGGLE_ACTION(action));
	g_return_if_fail(KZ_IS_WINDOW(kz));

	kztab = g_object_get_qdata(G_OBJECT(kz), kztab_quark);
	g_return_if_fail(KZ_IS_TAB_LABEL(kztab));

	if (egg_toggle_action_get_active (EGG_TOGGLE_ACTION(action)))
		kz_tab_label_set_lock(kztab, TRUE);
	else
		kz_tab_label_set_lock(kztab, FALSE);
}

static void
act_tab_copy_tab (EggAction *action, KzWindow *kz)
{
	GtkWidget *widget = KZ_WINDOW_CURRENT_PAGE(kz);
	KzMozEmbed *kzembed, *dkzembed;

	g_return_if_fail(KZ_IS_WINDOW(kz));
	g_return_if_fail(KZ_IS_MOZ_EMBED(widget));
	
	kzembed  = KZ_MOZ_EMBED(widget);	
	dkzembed = KZ_MOZ_EMBED(kz_window_open_new_tab(kz, NULL));

	kz_moz_embed_copy_page(kzembed, dkzembed);
	kz_moz_embed_shistory_copy(kzembed, dkzembed, TRUE, TRUE, TRUE);
}

EggActionGroupEntry kz_actions_tab[] =
{
        /* Toplevel */
        { "FakeToplevel", (""), NULL, NULL, NULL, NULL, NULL },

	{"TabReload",        N_("Reloa_d"),
	 GTK_STOCK_REFRESH, NULL, NULL, G_CALLBACK(act_tab_reload), NULL},

	{"TabStop",          N_("_Stop"),
	 GTK_STOCK_STOP, NULL, NULL, G_CALLBACK(act_tab_stop), NULL},

	{"TabClose",         N_("_Close"),
	 GTK_STOCK_CLOSE, NULL, NULL, G_CALLBACK(act_tab_close), NULL},

	{"TabCloseAllBackward",  N_("Close all _backward tabs"),
	 GTK_STOCK_CLOSE, NULL, NULL, G_CALLBACK(act_tab_close_left), NULL},

	{"TabCloseAllForward", N_("Close all _forward tabs"), 
	 GTK_STOCK_CLOSE, NULL, NULL, G_CALLBACK(act_tab_close_right), NULL},

	{"TabCloseAllWithoutActive", N_("Close all with_out this tab"),
	 GTK_STOCK_CLOSE, NULL, NULL, G_CALLBACK(act_tab_close_all_without_active), NULL},

	{"TabCloseAllChild", N_("Close all c_hild tab"),
	 GTK_STOCK_CLOSE, NULL, NULL, G_CALLBACK(act_tab_close_all_child), NULL},

	{"TabCopyTitle",        N_("Copy _Title"),
	 GTK_STOCK_COPY, NULL, NULL, G_CALLBACK(act_tab_copy_title), NULL},

	{"TabCopyLocation",     N_("Copy _Location"),
	 GTK_STOCK_COPY, NULL, NULL, G_CALLBACK(act_tab_copy_location), NULL},

	{"TabCopyTitleLocation",     N_("Cop_y Title&Location"),
	 GTK_STOCK_COPY, NULL, NULL, G_CALLBACK(act_tab_copy_title_and_location), NULL},

	{"TabToggleLock",     N_("Tab Loc_k"),
	 NULL, NULL, NULL, G_CALLBACK(act_tab_toggle_lock), NULL, TOGGLE_ACTION},

	{"TabCopy",     N_("Tab Co_py"),
	 NULL, NULL, NULL, G_CALLBACK(act_tab_copy_tab), NULL},
};
const gint kz_actions_tab_len = G_N_ELEMENTS(kz_actions_tab);


EggActionGroup *
kz_actions_tab_popup_create_group (KzWindow *kz, GtkAccelGroup *accel_group)
{
	EggActionGroup *action_group;
	gint i;

	action_group = egg_action_group_new("KzWindowTabPopup");
	egg_action_group_set_accel_group(action_group, accel_group);

	for (i = 0; i < kz_actions_tab_len; i++)
		kz_actions_tab[i].user_data = kz;

	egg_action_group_add_actions (action_group,
				      kz_actions_tab,
				      kz_actions_tab_len);

	for (i = 0; i < kz_actions_tab_len; i++)
		kz_actions_tab[i].user_data = NULL;

	return action_group;
}


static void
cb_popup_menu_hide (void)
{
	gtk_main_quit();
}


static void
set_popup_menu_sensitive (KzTabLabel *kztab)
{
	KzWindow *kz;
	EggAction *action;
	gint pos, num;
	gboolean lock;

	g_return_if_fail(kztab);

	kz = kztab->kz;
	g_return_if_fail(KZ_IS_WINDOW(kz));

	pos = gtk_notebook_page_num(GTK_NOTEBOOK(kztab->kz->notebook),
				    GTK_WIDGET(kztab->kzembed));
	num = gtkutil_notebook_get_n_pages(GTK_NOTEBOOK(kztab->kz->notebook));

	action = egg_action_group_get_action(kz->tabpop_actions, "TabStop");
	egg_action_set_sensitive(action, kz_moz_embed_is_loading(kztab->kzembed));

	action = egg_action_group_get_action(kz->tabpop_actions,
					     "TabCloseAllBackward");
	egg_action_set_sensitive(action, !(pos == 0));

	action = egg_action_group_get_action(kz->tabpop_actions,
					     "TabCloseAllForward");
	egg_action_set_sensitive(action, !(pos == num -1));

	action = egg_action_group_get_action(kz->tabpop_actions,
					     "TabCloseAllWithoutActive");
	egg_action_set_sensitive(action, num > 1);

	action = egg_action_group_get_action(kz->tabpop_actions,
					     "TabToggleLock");
	lock = kz_tab_label_get_lock(kztab);
	egg_toggle_action_set_active(EGG_TOGGLE_ACTION(action), lock);
}


void
kz_actions_tab_popup_menu_modal (KzTabLabel *kztab, guint button, guint time)
{
	GtkWidget *popup_menu = NULL;
	gchar path[64];

	g_return_if_fail(KZ_IS_TAB_LABEL(kztab));
	g_return_if_fail(KZ_IS_WINDOW(kztab->kz));

	if (!kztab_quark)
		kztab_quark = g_quark_from_string("KzTabAction::KzTabLabelFor");

	g_object_set_qdata(G_OBJECT(kztab->kz), kztab_quark, kztab);

	g_snprintf(path, sizeof(path), "/popups/TabPopup%s",
		   kz_ui_level_to_suffix(kz_ui_level()));
	popup_menu = egg_menu_merge_get_widget(kztab->kz->menu_merge, path);
	if (!popup_menu) return;

	set_popup_menu_sensitive(kztab);

	g_signal_connect(G_OBJECT(popup_menu), "hide",
			 G_CALLBACK(cb_popup_menu_hide), NULL);
	gtk_menu_popup(GTK_MENU(popup_menu), NULL, NULL,
		       NULL, NULL, button, time);
	gtk_main();
	g_signal_handlers_disconnect_by_func(G_OBJECT(popup_menu),
					     G_CALLBACK(cb_popup_menu_hide),
					     NULL);

	g_object_set_qdata(G_OBJECT(kztab->kz), kztab_quark, NULL);
}
