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

#include "string.h"

#include "egg-toggle-action.h"
#include "egg-entry-action.h"
#include "gtk-utils.h"
#include "intl.h"
#include "kazehakase.h"
#include "kz-window.h"
#include "kz-actions-download.h"


typedef enum {
	LOCATION_LINK,
	LOCATION_IMAGE,
	LOCATION_FRAME		
} LocationType;

typedef enum {
	CURRENT_TAB,
	NEW_TAB,
	NEW_WINDOW
} WindowType;

static void
open_location (EggAction *action, KzWindow *kz, LocationType location, WindowType window)
{
	const KzEmbedEventMouse *event;
	const gchar *uri = NULL;

	g_return_if_fail(KZ_IS_WINDOW(kz));

	event = kz_window_get_mouse_event_info(kz);
	g_return_if_fail(event);

	switch (location) {
	case LOCATION_LINK:
		uri = event->cinfo.link;
		break;
	case LOCATION_IMAGE:
		uri = event->cinfo.img;
		break;
	case LOCATION_FRAME:
		uri = event->cinfo.frame_src;
		break;
	default:
		g_return_if_reached();
		break;
	}

	if (!uri) return;

	switch (window) {
	case CURRENT_TAB:
		kz_window_load_url(kz, uri);
		break;
	case NEW_TAB:
		kz_window_open_new_tab_with_parent (kz, uri,
						    KZ_WINDOW_CURRENT_PAGE(kz));
		break;
	case NEW_WINDOW:
	{
		GtkWidget *widget = kz_window_new(uri);
		gtk_widget_show(widget);
		break;
	}
	default:
		g_return_if_reached();
		break;
	}
}

static void
act_popup_open (EggAction *action, KzWindow *kz)
{
	open_location(action, kz, LOCATION_LINK, CURRENT_TAB);
}

static void
act_popup_open_in_new_tab (EggAction *action, KzWindow *kz)
{
	open_location(action, kz, LOCATION_LINK, NEW_TAB);
}

static void
act_popup_open_in_new_win (EggAction *action, KzWindow *kz)
{
	open_location(action, kz, LOCATION_LINK, NEW_WINDOW);
}

static void
act_popup_copy_link_location (EggAction *action, KzWindow *kz)
{
	const KzEmbedEventMouse *event;

	g_return_if_fail(KZ_IS_WINDOW(kz));

	event = kz_window_get_mouse_event_info(kz);
	g_return_if_fail(event);

	gtkutil_copy_text(event->cinfo.link);
}

static void
act_popup_open_image (EggAction *action, KzWindow *kz)
{
	open_location(action, kz, LOCATION_IMAGE, CURRENT_TAB);
}

static void
act_popup_open_image_in_new_tab (EggAction *action, KzWindow *kz)
{
	open_location(action, kz, LOCATION_IMAGE, NEW_TAB);
}

static void
act_popup_open_image_in_new_win (EggAction *action, KzWindow *kz)
{
	open_location(action, kz, LOCATION_IMAGE, NEW_WINDOW);
}

static void
act_popup_save_link (EggAction *action, KzWindow *kz)
{
	const KzEmbedEventMouse *event;
	const gchar *uri = NULL;

	g_return_if_fail(KZ_IS_WINDOW(kz));

	event = kz_window_get_mouse_event_info(kz);
	g_return_if_fail(event);

	uri = event->cinfo.link;
	kz_actions_download_open_save_dialog(uri);
}

static void
act_popup_save_image (EggAction *action, KzWindow *kz)
{
	const KzEmbedEventMouse *event;
	const gchar *uri = NULL;

	g_return_if_fail(KZ_IS_WINDOW(kz));

	event = kz_window_get_mouse_event_info(kz);
	g_return_if_fail(event);

	uri = event->cinfo.img;
	kz_actions_download_open_save_dialog(uri);
}

static void
act_popup_copy_image_location (EggAction *action, KzWindow *kz)
{
	const KzEmbedEventMouse *event;

	g_return_if_fail(KZ_IS_WINDOW(kz));

	event = kz_window_get_mouse_event_info(kz);
	g_return_if_fail(event);

	gtkutil_copy_text(event->cinfo.img);
}

static void
act_popup_open_frame (EggAction *action, KzWindow *kz)
{
	open_location(action, kz, LOCATION_FRAME, CURRENT_TAB);
}

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

	{"OpenLink",            N_("_Open"),
	 GTK_STOCK_OPEN, NULL, NULL, G_CALLBACK(act_popup_open), NULL},
	{"OpenLinkInNewTab",    N_("Open in new _tab"),
	 GTK_STOCK_OPEN, NULL, NULL, G_CALLBACK(act_popup_open_in_new_tab), NULL},
	{"OpenLinkInNewWindow", N_("Open in new _window"),
	 GTK_STOCK_OPEN, NULL, NULL, G_CALLBACK(act_popup_open_in_new_win), NULL},
	{"CopyLinkLocation",    N_("Copy _link location"),
	 GTK_STOCK_COPY, NULL, NULL, G_CALLBACK(act_popup_copy_link_location), NULL},
	{"SaveLink",            N_("Save lin_k to disk"),
	 GTK_STOCK_SAVE, NULL, NULL, G_CALLBACK(act_popup_save_link), NULL},

	{"OpenImage",           N_("Open _image"),
	 GTK_STOCK_OPEN, NULL, NULL, G_CALLBACK(act_popup_open_image), NULL},
	{"OpenImageInNewTab",   N_("Open image in new ta_b"),
	 GTK_STOCK_OPEN, NULL, NULL, G_CALLBACK(act_popup_open_image_in_new_tab), NULL},
	{"OpenImageInNewWindow",N_("Open image in _new window"),
	 GTK_STOCK_OPEN, NULL, NULL, G_CALLBACK(act_popup_open_image_in_new_win), NULL},
	{"CopyImageLocation",   N_("Copy image l_ocation"),
	 GTK_STOCK_COPY, NULL, NULL, G_CALLBACK(act_popup_copy_image_location), NULL},
	{"SaveImage",           N_("Sa_ve image as"),
	 GTK_STOCK_SAVE, NULL, NULL, G_CALLBACK(act_popup_save_image), NULL},

	{"OpenThisFrame",       N_("Open this _frame"),
	 GTK_STOCK_OPEN, NULL, NULL, G_CALLBACK(act_popup_open_frame), NULL},
};
const gint kz_actions_popup_len = G_N_ELEMENTS(kz_actions_popup);


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

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

	for (i = 0; i < kz_actions_popup_len; i++)
		kz_actions_popup[i].user_data = kz;

	egg_action_group_add_actions (action_group,
				      kz_actions_popup,
				      kz_actions_popup_len);

	for (i = 0; i < kz_actions_popup_len; i++)
		kz_actions_popup[i].user_data = NULL;

	return action_group;
}


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


#define GET_MENU(kz, path) \
	(egg_menu_merge_get_widget(kz->menu_merge, path))

void
kz_actions_popup_menu_modal (KzWindow *kz, guint button, guint time)
{
	GtkWidget *popup_menu = NULL;
	const KzEmbedEventMouse *event;
	gboolean is_selection, is_doc, is_link, is_image, is_input, is_frame;
	gchar path[64] = {0};

	event = kz_window_get_mouse_event_info(kz);
	if (!event) return;

	is_selection = event->cinfo.context & KZ_CONTEXT_SELECTION;
	is_doc       = event->cinfo.context & KZ_CONTEXT_DOCUMENT;
	is_link      = event->cinfo.context & KZ_CONTEXT_LINK;
	is_image     = event->cinfo.context & KZ_CONTEXT_IMAGE;
	is_input     = event->cinfo.context & KZ_CONTEXT_INPUT;
	is_frame     = event->cinfo.context & KZ_CONTEXT_FRAME;

#if 0
	if (is_selection)
		/*
		 * FIXME!! We should merge this menu items to other context's
		 * menu.
		 */
		popup_menu = GET_MENU(kz, "/popups/SelectionPopup");
	else
#endif
	if (is_doc)
	{
		if (is_frame)
			g_snprintf(path, sizeof(path), "/popups/DocumentPopupinFrame%s",
				   kz_ui_level_to_suffix(kz_ui_level()));
		else
			g_snprintf(path, sizeof(path), "/popups/DocumentPopup%s",
				   kz_ui_level_to_suffix(kz_ui_level()));
	}
	if (is_link && is_image)
		g_snprintf(path, sizeof(path), "/popups/LinkImagePopup%s",
			   kz_ui_level_to_suffix(kz_ui_level()));
	else if (is_link)
		g_snprintf(path, sizeof(path), "/popups/LinkPopup%s",
			   kz_ui_level_to_suffix(kz_ui_level()));
	else if (is_image)
		g_snprintf(path, sizeof(path), "/popups/ImagePopup%s",
			   kz_ui_level_to_suffix(kz_ui_level()));
	else if (is_input)
		g_snprintf(path, sizeof(path), "/popups/InputPopup%s",
			   kz_ui_level_to_suffix(kz_ui_level()));

	if (!*path) return;

	popup_menu = GET_MENU(kz, path);
	if (!popup_menu) return;

	if (is_input)
		gtkutil_append_im_menuitem(GTK_MENU_SHELL(popup_menu));

	g_signal_connect(G_OBJECT(popup_menu), "hide",
			 G_CALLBACK(cb_popup_menu_hide), kz);
	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), kz);
}
