/* -*- 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.
 *
 *  $Id: kz-actions-bookmark.c 3756 2009-02-22 11:44:12Z ikezoe $
 */

#include "kz-actions-bookmark.h"
#include <glib/gi18n.h>

#include "kz-icons.h"
#include "kz-bookmark-edit-win.h"
#include "kz-smart-bookmark.h"
#include "kz-bookmark-file.h"
#include "kz-bookmark-separator.h"
#include "utils.h"


static void
act_new_window (GtkAction *action, KzBookmarkEditor *editor)
{
	GtkWidget *widget;

	g_return_if_fail(GTK_IS_ACTION(action));
	g_return_if_fail(KZ_IS_BOOKMARK_EDITOR(editor));

	widget = kz_bookmark_editor_new(editor->root_folder);
	gtk_widget_show(widget);
}


static void
act_close_window (GtkAction *action, KzBookmarkEditor *editor)
{
	g_return_if_fail(GTK_IS_ACTION(action));
	g_return_if_fail(KZ_IS_BOOKMARK_EDITOR(editor));

	kz_bookmark_editor_store_state(editor);
	gtk_widget_destroy(GTK_WIDGET(editor));
}


static void
act_edit_bookmark (GtkAction *action, KzBookmarkEditor *editor)
{
	GList *node;

	g_return_if_fail(GTK_IS_ACTION(action));
	g_return_if_fail(KZ_IS_BOOKMARK_EDITOR(editor));

	for (node = kz_bookmark_editor_get_selected_list(editor);
	     node;
	     node = g_list_next(node))

	{
		GtkWidget *widget = kz_bookmark_edit_win_new(node->data);

		gtk_widget_show(widget);
	}
}


static void
insert_bookmark_item (KzBookmarkEditor *editor, KzBookmark *bookmark)
{
	KzBookmarkFolder *parent;
	KzBookmark *file, *sibling = NULL;
	GList *list;

	g_return_if_fail(KZ_IS_BOOKMARK_EDITOR(editor));
	g_return_if_fail(KZ_IS_BOOKMARK(bookmark));

	list = kz_bookmark_editor_get_selected_list(editor);

	if (list)
	{
		sibling = list->data;
		parent = kz_bookmark_get_parent(sibling);
	}
	else
	{
		parent = KZ_BOOKMARK_FOLDER(editor->current_folder);
		g_return_if_fail(KZ_IS_BOOKMARK(parent));
		sibling = NULL;
	}

	kz_bookmark_folder_insert_before(parent, bookmark, sibling);

	if (KZ_IS_BOOKMARK_FILE(parent))
		file = KZ_BOOKMARK(parent);
	else
		file = kz_bookmark_get_parent_file(KZ_BOOKMARK(parent));

	if (kz_bookmark_file_has_xmlrpc(KZ_BOOKMARK_FILE(file)))
	{
		kz_bookmark_file_xmlrpc_insert(KZ_BOOKMARK_FILE(file),
					       KZ_BOOKMARK(parent),
					       sibling,
					       bookmark);
	}

	g_list_free(list);
	/* focus to new bookmark item */
	kz_bookmark_editor_bookmarks_view_select(editor, bookmark);
}


static void
act_insert_bookmark (GtkAction *action, KzBookmarkEditor *editor)
{
	KzBookmark *bookmark;

	g_return_if_fail(GTK_IS_ACTION(action));
	g_return_if_fail(KZ_IS_BOOKMARK_EDITOR(editor));

	bookmark = kz_bookmark_new_with_attrs(_("New bookmark"), NULL, NULL);
	insert_bookmark_item(editor, bookmark);
	g_object_unref(bookmark);
}


static void
act_insert_folder (GtkAction *action, KzBookmarkEditor *editor)
{
	KzBookmark *folder;

	g_return_if_fail(GTK_IS_ACTION(action));
	g_return_if_fail(KZ_IS_BOOKMARK_EDITOR(editor));

	folder = kz_bookmark_folder_new(_("New folder"));
	insert_bookmark_item(editor, folder);
	g_object_unref(folder);
}


static void
act_insert_remote_bookmark (GtkAction *action, KzBookmarkEditor *editor)
{
	KzBookmark *file;

	g_return_if_fail(GTK_IS_ACTION(action));
	g_return_if_fail(KZ_IS_BOOKMARK_EDITOR(editor));

	file = KZ_BOOKMARK(kz_bookmark_file_new(NULL, NULL, NULL));
	kz_bookmark_set_title(file, _("New Remote Bookmark"));
	insert_bookmark_item(editor, file);
	g_object_unref(file);
}


static void
act_insert_smart_bookmark (GtkAction *action, KzBookmarkEditor *editor)
{
	KzBookmark *smart;

	g_return_if_fail(GTK_IS_ACTION(action));
	g_return_if_fail(KZ_IS_BOOKMARK_EDITOR(editor));

	smart = kz_smart_bookmark_new();
	kz_bookmark_set_title(KZ_BOOKMARK(smart), _("New Smart bookmark"));
	kz_smart_bookmark_append_property(KZ_SMART_BOOKMARK(smart),
					  "(.*)", "%s",
					  NULL, FALSE);
	insert_bookmark_item(editor, smart);
	g_object_unref(smart);
}

typedef enum {
	MOZILLA_BOOKMARK = 0,
	NETSCAPE_BOOKMARK,
	FIREFOX_BOOKMARK,
	GALEON_BOOKMARK,
	KONQUEROR_BOOKMARK,
	W3M_BOOKMARK
} OTHER_BROWSERS_BOOKMARK_TYPE;

static struct {
	const gchar* search_dir;
	const gchar* search_name;
	const gint search_depth;
	const gchar* description;
} other_browsers_bookmark_map[] = {
	{".mozilla/default", "bookmarks.html", 1, N_("Mozilla Bookmarks")},
	{".netscape", "bookmarks.html", 3, N_("Netscape Bookmarks")},
	{".mozilla/firefox", "bookmarks.html", 1, N_("Firefox Bookmarks")},
	{".galeon", "bookmarks.xbel", 0, N_("Galeon Bookmarks")},
	{".kde/share/apps/konqueror", "bookmarks.xml", 0, N_("Konqueror Bookmarks")},
	{".w3m" ,"bookmark.html", 0, N_("w3m Bookmarks")}
};

static void
insert_other_browsers_bookmark(KzBookmarkEditor *editor, OTHER_BROWSERS_BOOKMARK_TYPE type)
{
        /* mozilla families require recursive searching to get its bookmark */
	gchar *dir = NULL;
	GSList *list, *node;

	g_return_if_fail(KZ_IS_BOOKMARK_EDITOR(editor));

	dir = g_build_filename(g_get_home_dir(),
			       other_browsers_bookmark_map[type].search_dir,
			       NULL);
	if (!dir)
		return;

	list = find_file(dir,
			 other_browsers_bookmark_map[type].search_name,
			 other_browsers_bookmark_map[type].search_depth);
	for (node = list; node; node = g_slist_next(node))
	{
		if (g_file_test(node->data, G_FILE_TEST_IS_REGULAR))
		{
			KzBookmark *bookmark =
				KZ_BOOKMARK(kz_bookmark_file_new(node->data,
								 other_browsers_bookmark_map[type].description,
								 NULL));
			insert_bookmark_item(editor, bookmark);
			g_object_unref(bookmark);

			kz_bookmark_file_load_start(KZ_BOOKMARK_FILE(bookmark));
		}
	}
	g_slist_free(list);
	g_free(dir);
}
static void
act_insert_mozilla_bookmark (GtkAction *action, KzBookmarkEditor *editor)
{
	g_return_if_fail(GTK_IS_ACTION(action));
	g_return_if_fail(KZ_IS_BOOKMARK_EDITOR(editor));
	insert_other_browsers_bookmark(editor, MOZILLA_BOOKMARK);
}

static void
act_insert_netscape_bookmark (GtkAction *action, KzBookmarkEditor *editor)
{
	g_return_if_fail(GTK_IS_ACTION(action));
	g_return_if_fail(KZ_IS_BOOKMARK_EDITOR(editor));
	insert_other_browsers_bookmark(editor, NETSCAPE_BOOKMARK);
}

static void
act_insert_firefox_bookmark (GtkAction *action, KzBookmarkEditor *editor)
{
	g_return_if_fail(GTK_IS_ACTION(action));
	g_return_if_fail(KZ_IS_BOOKMARK_EDITOR(editor));
	insert_other_browsers_bookmark(editor, FIREFOX_BOOKMARK);
}

static void
act_insert_galeon_bookmark (GtkAction *action, KzBookmarkEditor *editor)
{
	g_return_if_fail(GTK_IS_ACTION(action));
	g_return_if_fail(KZ_IS_BOOKMARK_EDITOR(editor));
	insert_other_browsers_bookmark(editor, GALEON_BOOKMARK);
}

static void
act_insert_konqueror_bookmark (GtkAction *action, KzBookmarkEditor *editor)
{
	g_return_if_fail(GTK_IS_ACTION(action));
	g_return_if_fail(KZ_IS_BOOKMARK_EDITOR(editor));
	insert_other_browsers_bookmark(editor, KONQUEROR_BOOKMARK);
}

static void
act_insert_w3m_bookmark (GtkAction *action, KzBookmarkEditor *editor)
{
	g_return_if_fail(GTK_IS_ACTION(action));
	g_return_if_fail(KZ_IS_BOOKMARK_EDITOR(editor));
	insert_other_browsers_bookmark(editor, W3M_BOOKMARK);
}

static void
act_insert_separator (GtkAction *action, KzBookmarkEditor *editor)
{
	KzBookmark *sep;

	g_return_if_fail(GTK_IS_ACTION(action));
	g_return_if_fail(KZ_IS_BOOKMARK_EDITOR(editor));

	sep = kz_bookmark_separator_new();
	insert_bookmark_item(editor, sep);
	g_object_unref(sep);
}


static void
act_remove_selected_item (GtkAction *action, KzBookmarkEditor *editor)
{
	KzBookmark *parent, *bookmark;
	GList *list, *node;

	g_return_if_fail(GTK_IS_ACTION(action));
	g_return_if_fail(KZ_IS_BOOKMARK_EDITOR(editor));

	list = kz_bookmark_editor_get_selected_list(editor);

	parent = editor->current_folder;
	g_return_if_fail(KZ_IS_BOOKMARK(parent));

	/* FIXME!: show dialog */

	for (node = list; node; node = g_list_next(node))
	{
		KzBookmark *file;

		bookmark = node->data;
		if (!KZ_IS_BOOKMARK(bookmark)) continue;
		kz_bookmark_folder_remove(KZ_BOOKMARK_FOLDER(parent), bookmark);
		
		if (KZ_IS_BOOKMARK_FILE(parent))
			file = parent;
		else
			file = kz_bookmark_get_parent_file(parent);

		if (kz_bookmark_file_has_xmlrpc(KZ_BOOKMARK_FILE(file)))
		{
			kz_bookmark_file_xmlrpc_remove(KZ_BOOKMARK_FILE(file),
						       bookmark);
		}
	}

	g_list_free(list);
}


static void
act_show_hide_folder_view (GtkToggleAction *action, KzBookmarkEditor *editor)
{
	g_return_if_fail(GTK_IS_TOGGLE_ACTION(action));
	g_return_if_fail(KZ_IS_BOOKMARK_EDITOR(editor));
	g_return_if_fail(GTK_IS_WIDGET(editor->scrolledwin[0]));

	g_object_set(editor->scrolledwin[0],
		     "visible", gtk_toggle_action_get_active(action),
		     NULL);
}


static void
act_show_hide_content_view (GtkToggleAction *action, KzBookmarkEditor *editor)
{
	g_return_if_fail(GTK_IS_TOGGLE_ACTION(action));
	g_return_if_fail(KZ_IS_BOOKMARK_EDITOR(editor));
	g_return_if_fail(GTK_IS_WIDGET(editor->content_view));

	g_object_set(editor->content_view,
		     "visible", gtk_toggle_action_get_active(action),
		     NULL);
}


static void
act_change_list_mode (GtkRadioAction *action, GtkRadioAction *cur_action, KzBookmarkEditor *editor)
{
	gint value;

	g_return_if_fail(GTK_IS_RADIO_ACTION(action));
	g_return_if_fail(KZ_IS_BOOKMARK_EDITOR(editor));

	value = gtk_radio_action_get_current_value(action);
	switch (value) {
	case 0:
		kz_bookmark_editor_set_tree_mode(editor, FALSE);
		break;
	case 1:
		kz_bookmark_editor_set_tree_mode(editor, TRUE);
		break;
	default:
		break;
	}
}


static void
act_go_up (GtkAction *action, KzBookmarkEditor *editor)
{
	KzBookmarkFolder *parent;

	g_return_if_fail(GTK_IS_ACTION(action));
	g_return_if_fail(KZ_IS_BOOKMARK_EDITOR(editor));

	if (!editor->current_folder) return;

	parent = kz_bookmark_get_parent(editor->current_folder);
	if (!parent) return;

	kz_bookmark_editor_set_current(editor, KZ_BOOKMARK(parent));
}


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


static GtkActionEntry kz_actions_bookmark[] =
{
  {"StockFileMenu",     NULL, N_("_File"),       NULL, NULL, NULL},
  {"StockEditMenu",     NULL, N_("_Edit"),       NULL, NULL, NULL},
  {"StockViewMenu",     NULL, N_("_View"),       NULL, NULL, NULL},
  {"StockGoMenu",       NULL, N_("_Go"),         NULL, NULL, NULL},
  {"StockModeMenu",     NULL, N_("_Mode"),       NULL, NULL, NULL},
  {"NewWindow",            KZ_STOCK_NEW_WINDOW,      N_("_New Window"),             "<control>N", N_("Open a new window"), G_CALLBACK(act_new_window)},
  {"CloseWindow",          KZ_STOCK_CLOSE_WINDOW,    N_("_Close Window"),           "<control>W", N_("Close the current window"), G_CALLBACK(act_close_window)},

  {"EditBookmarkItem",     NULL,                     N_("_Edit selected item"),     NULL,         N_("Edit the selected item"), G_CALLBACK(act_edit_bookmark)},
  {"InsertBookmark",       KZ_STOCK_BOOKMARK,        N_("Insert _bookmark"),        "<control>B", N_("Insert a new bookmark"), G_CALLBACK(act_insert_bookmark)},
  {"InsertFolder",         KZ_STOCK_FOLDER,          N_("Insert _folder"),          "<control>F", N_("Insert a new folder"), G_CALLBACK(act_insert_folder)},
  {"InsertRemoteBookmark", KZ_STOCK_REMOTE_BOOKMARK, N_("Insert _remote bookmark"), "<control>R", N_("Insert a new remote bookmark"), G_CALLBACK(act_insert_remote_bookmark)},
  {"InsertSmartBookmark", KZ_STOCK_SMART_BOOKMARK, N_("Insert _smart bookmark"), "<control>S", N_("Insert a new smart bookmark"), G_CALLBACK(act_insert_smart_bookmark)},
  {"InsertMozillaBookmark", KZ_STOCK_MOZILLA, N_("Insert _Mozilla bookmark"), NULL, N_("Insert a Mozilla bookmark"), G_CALLBACK(act_insert_mozilla_bookmark)},
  {"InsertNetscapeBookmark", KZ_STOCK_NETSCAPE, N_("Insert Netscape bookmark"), NULL, N_("Insert a Netscape bookmark"), G_CALLBACK(act_insert_netscape_bookmark)},
  {"InsertFirefoxBookmark", KZ_STOCK_FIREFOX, N_("Insert Firefox bookmark"), NULL, N_("Insert a Firefox bookmark"), G_CALLBACK(act_insert_firefox_bookmark)},
  {"InsertGaleonBookmark", KZ_STOCK_GALEON, N_("Insert Galeon bookmark"), NULL, N_("Insert a Galeon bookmark"), G_CALLBACK(act_insert_galeon_bookmark)},
  {"InsertKonquerorBookmark", KZ_STOCK_KONQUEROR, N_("Insert Konqueror bookmark"), NULL, N_("Insert a Konqueror bookmark"), G_CALLBACK(act_insert_konqueror_bookmark)},
  {"InsertW3mBookmark", NULL, N_("Insert w3m bookmark"), NULL, N_("Insert a w3m bookmark"), G_CALLBACK(act_insert_w3m_bookmark)},
  {"InsertSeparator",      KZ_STOCK_SEPARATOR,       N_("Insert _separator"),       "<control>P", N_("Insert a separator"), G_CALLBACK(act_insert_separator)},
  {"RemoveBookmarkItem",   GTK_STOCK_DELETE,         N_("_Remove selected item"),   "<control>Delete",     N_("Remove the selected item"), G_CALLBACK(act_remove_selected_item)},
  {"GoUp",  GTK_STOCK_GO_UP, N_("_Up"), NULL, NULL, G_CALLBACK(act_go_up)},
};
static const gint kz_actions_bookmark_len = G_N_ELEMENTS(kz_actions_bookmark);

static GtkToggleActionEntry kz_toggle_actions_bookmark[] =
{
  {"ShowHideFolderView",  NULL, N_("Folder view"),  NULL, NULL, G_CALLBACK(act_show_hide_folder_view)},
  {"ShowHideContentView", NULL, N_("Content view"), NULL, NULL, G_CALLBACK(act_show_hide_content_view)},
};
static const gint kz_toggle_actions_bookmark_len = G_N_ELEMENTS(kz_toggle_actions_bookmark);


static GtkRadioActionEntry kz_radio_actions_bookmark[] =
{
  {"ListMode", NULL, N_("_List Mode"), NULL, NULL, 0},
  {"TreeMode", NULL, N_("_Tree Mode"), NULL, NULL, 1},
};
static const gint kz_radio_actions_bookmark_len = G_N_ELEMENTS(kz_radio_actions_bookmark);


GtkActionGroup *
kz_actions_bookmark_create_group (KzBookmarkEditor *editor, 
				  GtkAccelGroup *accel_group)
{
	GtkActionGroup *action_group;
	GList *node, *action_list;

	action_group = gtk_action_group_new("KzBookmarkEditor");

	gtk_action_group_set_translation_domain(action_group, NULL);

	gtk_action_group_add_actions (action_group,
				      kz_actions_bookmark,
				      kz_actions_bookmark_len,
				      editor);
	gtk_action_group_add_toggle_actions (action_group,
					     kz_toggle_actions_bookmark,
					     kz_toggle_actions_bookmark_len,
					     editor);
	gtk_action_group_add_radio_actions (action_group,
					    kz_radio_actions_bookmark,
					    kz_radio_actions_bookmark_len,
					    0,
					    G_CALLBACK(act_change_list_mode),
					    editor);

	action_list = gtk_action_group_list_actions(action_group);
	
	for (node = action_list; node; node = g_list_next(node))
	{
		gtk_action_set_accel_group(GTK_ACTION(node->data),
					   accel_group);
		gtk_action_connect_accelerator(GTK_ACTION(node->data));
	}
	g_list_free(action_list);

	return action_group;
}


void
kz_actions_bookmark_popup_menu_modal (KzBookmarkEditor *editor,
				      guint button, guint time)
{
	GtkWidget *popup_menu = NULL;

	popup_menu = gtk_ui_manager_get_widget(editor->menu_merge,
					       "/BookmarksViewPopup");
	if (!popup_menu) return;

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

	g_signal_handlers_disconnect_by_func(popup_menu,
					     G_CALLBACK(cb_popup_menu_hide),
					     editor);
}
