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

/*
 *  Copyright (C) 2004 Hidetaka Iwai
 *
 *  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 "prefs_location_entry.h"

#include "kazehakase.h"
#include "utils/intl.h"
#include "kz-bookmark-editor.h"

#if 0
#define DATA_KEY "KzPrefsLocationEntry::info"
#define REGEX_ENTRY_WIDTH 140
#define URI_ENTRY_WIDTH 180

enum
{
	COLUMN_TERMINATOR = -1,
	COLUMN_KIND,
	COLUMN_REGEX,
	COLUMN_URI,
	COLUMN_ENCODE,
	COLUMN_EDITABLE,
	N_COLUMNS
};

typedef struct _KzPrefsLocationEntry
{
	GtkWidget     *main_vbox;
	GtkTreeView   *tree_view;
	GtkListStore  *store;
	GtkWidget     *regex_entry, *uri_entry;
	GtkWidget     *up, *down;
	GtkWidget     *new, *add, *remove;
	gboolean       changed;
	gboolean       lock_entry_handlers;
} KzPrefsLocationEntry;
#endif

static GtkWidget     *prefs_location_entry_create          (void);
static void           prefs_location_entry_response        (GtkWidget *widget,
							    gint       response);
#if 0
static void           prefs_location_entry_set_sensitive   (KzPrefsLocationEntry *prefsui);
static void           prefs_location_entry_set_entry       (KzPrefsLocationEntry *prefsui);
static void           prefs_location_entry_destroy         (gpointer data);
#endif

static KzPrefsWinPageEntry prefs_entry =
{
	path:            N_("/Location Entry"),
	priority_hint:   0,
	ui_level:        KZ_UI_LEVEL_EXPERT,
	create:          prefs_location_entry_create,
	response:        prefs_location_entry_response,
};

#if 0
static void
cb_up_button (GtkButton *button, KzPrefsLocationEntry *prefsui)
{
	GtkTreeSelection *selection;
	GtkTreeModel *model;
	GtkTreeIter iter, prev;
	GtkTreePath *treepath;

	g_return_if_fail(prefsui);

	selection = gtk_tree_view_get_selection (prefsui->tree_view);
	if (!gtk_tree_selection_get_selected (selection, &model, &iter))
		return;

	treepath = gtk_tree_model_get_path(model, &iter);
	if (!gtk_tree_path_prev(treepath)) goto ERROR;
	gtk_tree_model_get_iter(model, &prev, treepath);

	gtkutil_list_store_swap(prefsui->store, &iter, &prev);

	prefsui->changed = TRUE;

ERROR:
	gtk_tree_path_free(treepath);

	prefs_location_entry_set_sensitive (prefsui);
}


static void
cb_down_button (GtkButton *button, KzPrefsLocationEntry *prefsui)
{
	GtkTreeSelection *selection;
	GtkTreeModel *model;
	GtkTreeIter iter, next;

	g_return_if_fail(prefsui);

	selection = gtk_tree_view_get_selection (prefsui->tree_view);
	if (!gtk_tree_selection_get_selected (selection, &model, &iter))
		return;

	next = iter;
	if (!gtk_tree_model_iter_next(model, &next)) return;

	gtkutil_list_store_swap(prefsui->store, &iter, &next);

	prefsui->changed = TRUE;

	prefs_location_entry_set_sensitive (prefsui);
}


static void
cb_new_button (GtkButton *button, KzPrefsLocationEntry *prefsui)
{
	GtkTreeSelection *selection;

	g_return_if_fail(prefsui);

	selection = gtk_tree_view_get_selection(prefsui->tree_view);
	gtk_tree_selection_unselect_all(selection);

	prefs_location_entry_set_entry(prefsui);
	prefs_location_entry_set_sensitive(prefsui);
}


static void
cb_add_button (GtkButton *button, KzPrefsLocationEntry *prefsui)
{
	GtkTreeIter iter;
	GtkTreePath *treepath;
	const gchar *regex, *uri;

	g_return_if_fail(prefsui);

	regex = gtk_entry_get_text(GTK_ENTRY(prefsui->regex_entry));
	uri   = gtk_entry_get_text(GTK_ENTRY(prefsui->uri_entry));

	gtk_list_store_append(prefsui->store, &iter);
	gtk_list_store_set(prefsui->store, &iter,
			   COLUMN_REGEX,    regex,
			   COLUMN_URI,      uri,
			   COLUMN_ENCODE,   FALSE,
			   COLUMN_EDITABLE, TRUE,
			   COLUMN_TERMINATOR);

	treepath = gtk_tree_model_get_path(GTK_TREE_MODEL(prefsui->store),
					   &iter);
	gtk_tree_view_set_cursor(prefsui->tree_view,
				 treepath, NULL, FALSE);
	gtk_tree_path_free(treepath);

	prefsui->changed = TRUE;

	prefs_location_entry_set_sensitive (prefsui);
}


static void
cb_remove_button (GtkButton *button, KzPrefsLocationEntry *prefsui)
{
	GtkTreeSelection *selection;
	GtkTreeModel *model;
	GtkTreeIter iter, next;
	GtkTreePath *treepath;
	gboolean select;

	g_return_if_fail(prefsui);

	selection = gtk_tree_view_get_selection (prefsui->tree_view);
	if (!gtk_tree_selection_get_selected (selection, &model, &iter))
		return;

        /* get next row to select */
	next = iter;
	select = gtk_tree_model_iter_next(model, &next);
	if (select)
	{
		treepath = gtk_tree_model_get_path(model, &next);
	}
	else
	{
		treepath = gtk_tree_model_get_path(model, &iter);
		select = gtk_tree_path_prev(treepath);
	}
	if (select)
		gtk_tree_view_set_cursor(prefsui->tree_view,
					 treepath, NULL, FALSE);
	gtk_tree_path_free(treepath);

	/* remove the row */
	gtk_list_store_remove(prefsui->store, &iter);

	prefsui->changed = TRUE;

	prefs_location_entry_set_sensitive (prefsui);
}


static void
cb_regex_edited (GtkCellRendererText *cell,
		 const gchar *path_str,
		 const gchar *new_text,
		 KzPrefsLocationEntry *prefsui)
{
        GtkTreeIter  iter;

        gtk_tree_model_get_iter_from_string(GTK_TREE_MODEL(prefsui->store),
					    &iter, path_str);
	gtk_list_store_set(prefsui->store, &iter,
			   COLUMN_REGEX, new_text,
			   COLUMN_TERMINATOR);

	prefsui->changed = TRUE;

	prefs_location_entry_set_entry(prefsui);
	prefs_location_entry_set_sensitive(prefsui);
}


static void
cb_uri_edited (GtkCellRendererText *cell,
	       const gchar *path_str,
	       const gchar *new_text,
	       KzPrefsLocationEntry *prefsui)
{
        GtkTreeIter  iter;

        gtk_tree_model_get_iter_from_string(GTK_TREE_MODEL(prefsui->store),
					    &iter, path_str);
	gtk_list_store_set(prefsui->store, &iter,
			   COLUMN_URI, new_text,
			   COLUMN_TERMINATOR);

	prefsui->changed = TRUE;

	prefs_location_entry_set_entry(prefsui);
	prefs_location_entry_set_sensitive(prefsui);
}

static void
cb_encode_toggled (GtkCellRendererToggle *cell,
			  const gchar *path_str,
			  KzPrefsLocationEntry *prefsui)
{
        GtkTreeIter  iter;
	GValue val = { 0 };
	gboolean flag;

	gtk_tree_model_get_iter_from_string(GTK_TREE_MODEL(prefsui->store),
					    &iter, path_str);

	gtk_tree_model_get_value(GTK_TREE_MODEL(prefsui->store), &iter,
				 COLUMN_ENCODE, &val);
	flag = !(g_value_get_boolean(&val));

	gtk_list_store_set(prefsui->store, &iter,
			   COLUMN_ENCODE, flag,
			   COLUMN_TERMINATOR);

	prefsui->changed = TRUE;

	prefs_location_entry_set_entry(prefsui);
	prefs_location_entry_set_sensitive(prefsui);
}

static void
cb_cursor_changed(GtkTreeView *tree_view, KzPrefsLocationEntry *prefsui)
{
	g_return_if_fail(prefsui);

	prefsui->lock_entry_handlers = TRUE;
	prefs_location_entry_set_entry(prefsui);
	prefs_location_entry_set_sensitive (prefsui);
	prefsui->lock_entry_handlers = FALSE;
}


static void
cb_regex_entry_changed(GtkEditable *editable, KzPrefsLocationEntry *prefsui)
{
	GtkTreeSelection *selection;
	GtkTreeModel *model;
	GtkTreeIter iter;

	g_return_if_fail(prefsui);

	if (prefsui->lock_entry_handlers) return;

	selection = gtk_tree_view_get_selection (prefsui->tree_view);
	if (gtk_tree_selection_get_selected (selection, &model, &iter))
	{
		const gchar *regex;

		regex = gtk_entry_get_text(GTK_ENTRY(prefsui->regex_entry));
		gtk_list_store_set(GTK_LIST_STORE(model), &iter,
				   COLUMN_REGEX, regex,
				   COLUMN_TERMINATOR);
		prefsui->changed = TRUE;
	}

	prefs_location_entry_set_sensitive (prefsui);
}


static void
cb_uri_entry_changed(GtkEditable *editable, KzPrefsLocationEntry *prefsui)
{
	GtkTreeSelection *selection;
	GtkTreeModel *model;
	GtkTreeIter iter;

	g_return_if_fail(prefsui);

	if (prefsui->lock_entry_handlers) return;

	selection = gtk_tree_view_get_selection (prefsui->tree_view);
	if (gtk_tree_selection_get_selected (selection, &model, &iter))
	{
		const gchar *uri;

		uri = gtk_entry_get_text(GTK_ENTRY(prefsui->uri_entry));
		gtk_list_store_set(GTK_LIST_STORE(model), &iter,
				   COLUMN_URI, uri,
				   COLUMN_TERMINATOR);
		prefsui->changed = TRUE;
	}

	prefs_location_entry_set_sensitive (prefsui);
}
#endif


static void
cb_bookmark_editor_button_clicked (GtkButton *button)
{
	KzBookmark *bookmark = kz_bookmarks->smarts;
	GtkWidget *widget, *toplevel;
	GtkWindow *main_window = NULL;

	widget = kz_bookmark_editor_new(bookmark);
	toplevel = gtk_widget_get_toplevel(GTK_WIDGET(button));
	
	if (GTK_WIDGET_TOPLEVEL(toplevel))
	{
		main_window = gtk_window_get_transient_for(GTK_WINDOW(toplevel));
	}

	gtk_window_set_transient_for(GTK_WINDOW(widget), main_window);
	gtk_widget_show (widget);
	gdk_window_raise(widget->window);
}

static GtkWidget *
prefs_location_entry_create (void)
{
	GtkWidget *main_vbox, *hbox;
	GtkWidget *label;
	GtkWidget *button;

	main_vbox = gtk_vbox_new(FALSE, 0);

	label = kz_prefs_ui_utils_create_title(_("Location Entry"));
	gtk_box_pack_start(GTK_BOX(main_vbox), label,
			   FALSE, FALSE, 0);
	gtk_widget_show(label);

	/* description */
	hbox = gtk_hbox_new(FALSE, 0);
	gtk_box_pack_start(GTK_BOX(main_vbox), hbox,
			   FALSE, FALSE, 0);
	gtk_widget_show(hbox);

	label = gtk_label_new(_("The settings of behaviours of the location entry "
				"moved into the bookmark editor.\n"
				"Please use it."));
	gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
	gtk_box_pack_start(GTK_BOX(hbox), label,
			   TRUE, FALSE, 5);
	gtk_widget_show(label);

	/* button box */
	
	hbox = gtk_hbutton_box_new();
	gtk_button_box_set_layout(GTK_BUTTON_BOX(hbox), GTK_BUTTONBOX_END);
	gtk_box_pack_start(GTK_BOX(main_vbox), hbox, FALSE, FALSE, 0);
	gtk_container_set_border_width(GTK_CONTAINER(hbox), 5);
	gtk_widget_show(hbox);
	
	/* Bookmark editor button */
	
	button = gtk_button_new_with_mnemonic(_("Bookmark _Editor"));
	gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0);
	g_signal_connect(G_OBJECT(button), "clicked",
			 G_CALLBACK(cb_bookmark_editor_button_clicked), NULL);
	gtk_widget_show(button);
	
	return main_vbox;
}

#if 0
static void
prefs_location_entry_apply (KzPrefsLocationEntry *prefsui)
{
	GtkTreeModel *model = GTK_TREE_MODEL(prefsui->store);
	GtkTreeIter iter;
	GSList *new_list = NULL;
	GList *node, *list;
	gboolean exist;
	gint index;
	gchar regex_key[32], key[32];
	gboolean encode;

	if (!prefsui->changed) return;

	/* first, remove all old entries */
	list = kz_profile_enum_key(kz_global_profile, "LocationEntry", TRUE);
	for (node = list; node; node = g_list_next(node))
	{
		const gchar *key = node->data;

		if (!key_seems_sequential(key, "regex") &&
		    !key_seems_sequential(key, "uri")   &&
		    !key_seems_sequential(key, "encode")) continue;

		kz_profile_delete_key(kz_global_profile, "LocationEntry", key);
	}
	g_list_free(list);
	
	exist = gtk_tree_model_get_iter_first(model, &iter);
	for(index = 0; exist; exist = gtk_tree_model_iter_next(model, &iter), ++index)
	{
		gchar *regex = NULL, *uri = NULL;

		gtk_tree_model_get(model, &iter,
				   COLUMN_REGEX,     &regex,
				   COLUMN_URI,       &uri,
				   COLUMN_ENCODE, &encode,
				   COLUMN_TERMINATOR);

		g_snprintf(regex_key, G_N_ELEMENTS(regex_key), "regex%d", index);

		kz_profile_set_value(kz_global_profile, "LocationEntry",
				     regex_key, regex, sizeof(regex),
				     KZ_PROFILE_VALUE_TYPE_STRING);

		g_snprintf(key, G_N_ELEMENTS(key), "uri%d", index);
		kz_profile_set_value(kz_global_profile, "LocationEntry",
				     key, uri, sizeof(uri),
				     KZ_PROFILE_VALUE_TYPE_STRING);

		g_snprintf(key, G_N_ELEMENTS(key), "encode%d", index);
		kz_profile_set_value(kz_global_profile, "LocationEntry",
				     key, &encode, sizeof(encode),
				     KZ_PROFILE_VALUE_TYPE_BOOL);

		g_free(regex);
		g_free(uri);
	}

	g_slist_foreach(new_list, (GFunc) g_object_unref, NULL);
	g_slist_free(new_list);

	prefsui->changed = FALSE;

	prefs_location_entry_set_sensitive (prefsui);
}
#endif

static void
prefs_location_entry_response (GtkWidget *widget, gint response)
{
	switch (response) {
	case GTK_RESPONSE_ACCEPT:
	case GTK_RESPONSE_APPLY:
		break;
	case GTK_RESPONSE_REJECT:
		break;
	case KZ_RESPONSE_UI_LEVEL_MEDIUM:
		break;
	case KZ_RESPONSE_UI_LEVEL_EXPERT:
		break;
	case KZ_RESPONSE_UI_LEVEL_CUSTOM:
		break;
	default:
		break;
	}
}

#if 0
static void
prefs_location_entry_set_sensitive (KzPrefsLocationEntry *prefsui)
{
	GtkTreeSelection *selection;
	GtkTreeModel *model;
	GtkTreeIter iter, next;
	gboolean select;
	gboolean can_up = FALSE, can_down = FALSE;
	gboolean can_add = FALSE, can_new = TRUE;
	const gchar *regex, *uri;

	g_return_if_fail(prefsui);

	selection = gtk_tree_view_get_selection (prefsui->tree_view);
	select = gtk_tree_selection_get_selected (selection, &model, &iter);

	if (select)
	{
		GtkTreePath *treepath;

		next = iter;
		can_down = gtk_tree_model_iter_next(model, &next);

		treepath = gtk_tree_model_get_path(model, &iter);
		can_up = gtk_tree_path_prev(treepath);
		gtk_tree_path_free(treepath);
	}

	regex = gtk_entry_get_text(GTK_ENTRY(prefsui->regex_entry));
	uri   = gtk_entry_get_text(GTK_ENTRY(prefsui->uri_entry));

	if (regex && *regex && uri && *uri)
		can_add = TRUE;

	if ((!regex || !*regex) && (!uri || !*uri) && !select)
		can_new = FALSE;

	gtk_widget_set_sensitive(prefsui->up,     can_up);
	gtk_widget_set_sensitive(prefsui->down,   can_down);
	gtk_widget_set_sensitive(prefsui->new,    can_new);
	gtk_widget_set_sensitive(prefsui->add,    can_add);
	gtk_widget_set_sensitive(prefsui->remove, select);
}


static void
prefs_location_entry_set_entry (KzPrefsLocationEntry *prefsui)
{
	GtkTreeSelection *selection;
	GtkTreeModel *model;
	GtkTreeIter iter;
	gchar *regex = NULL, *uri = NULL;
	gboolean encode;

	g_return_if_fail(prefsui);

	selection = gtk_tree_view_get_selection (prefsui->tree_view);

	if (gtk_tree_selection_get_selected (selection, &model, &iter))
	{
		gtk_tree_model_get(model, &iter,
				   COLUMN_REGEX,     &regex,
				   COLUMN_URI,       &uri,
				   COLUMN_ENCODE, &encode,
				   COLUMN_TERMINATOR);

		gtk_entry_set_text(GTK_ENTRY(prefsui->regex_entry), regex);
		gtk_entry_set_text(GTK_ENTRY(prefsui->uri_entry), uri);

		g_free(regex);
		g_free(uri);
	}
	else
	{
		gtk_entry_set_text(GTK_ENTRY(prefsui->regex_entry), "");
		gtk_entry_set_text(GTK_ENTRY(prefsui->uri_entry), "");
	}
}

static void
prefs_location_entry_destroy (gpointer data)
{
	KzPrefsLocationEntry *prefsui = data;

	if (prefsui->store)
	{
		g_object_unref(prefsui->store);
		prefsui->store = NULL;
	}
	g_free(prefsui);
}
#endif


KzPrefsWinPageEntry *
prefs_location_entry_get_entry (gint idx)
{
	if (idx == 0)
		return &prefs_entry;
	else
		return NULL;
}
