/* -*- 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: prefs_remote_bookmark.c 559 2004-01-01 13:59:45Z ikezoe $
 */

#include "prefs_remote_bookmark.h"

#include <stdlib.h>
#include <string.h>

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

#define DATA_KEY "KzPrefsRemoteBookmark::info"


enum
{
	COLUMN_TERMINATOR = -1,
	COLUMN_KIND,
	COLUMN_TITLE,
	COLUMN_URI,
	COLUMN_INTERVAL,
	COLUMN_EDITABLE,
	COLUMN_RBOOKMARK,
	N_COLUMNS
};


typedef struct _KzPrefsRemoteBookmark
{
	GtkWidget     *main_vbox;
	GtkTreeView   *tree_view;
	GtkListStore  *store;
	GtkWidget     *title_entry, *uri_entry;
	GtkWidget     *interval_spin;
	GtkWidget     *up, *down;
	GtkWidget     *new, *add, *remove;
	KzBookmark    *bookmarklist;
	gboolean       changed;
	gboolean       lock_entry_handlers;
} KzPrefsRemoteBookmark;


static GtkWidget     *prefs_remote_bookmark_create          (void);
static void           prefs_remote_bookmark_response        (GtkWidget *widget,
							     gint       response);
static void           prefs_remote_bookmark_set_sensitive   (KzPrefsRemoteBookmark *prefsui);
static void           prefs_remote_bookmark_set_entry       (KzPrefsRemoteBookmark *prefsui);
static void           prefs_remote_bookmark_destroy         (gpointer data);


static KzPrefsWinPageEntry prefs_entry =
{
	path:            N_("/Remote Bookmark"),
	priority_hint:   0,
	ui_level:        KZ_UI_LEVEL_ALL,
	create:          prefs_remote_bookmark_create,
	response:        prefs_remote_bookmark_response,
};


static void
cb_up_button (GtkButton *button, KzPrefsRemoteBookmark *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_remote_bookmark_set_sensitive (prefsui);
}


static void
cb_down_button (GtkButton *button, KzPrefsRemoteBookmark *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_remote_bookmark_set_sensitive (prefsui);
}


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

	g_return_if_fail(prefsui);

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

	prefs_remote_bookmark_set_entry(prefsui);
	prefs_remote_bookmark_set_sensitive(prefsui);
}


static void
cb_add_button (GtkButton *button, KzPrefsRemoteBookmark *prefsui)
{
	GtkTreeIter iter;
	GtkTreePath *treepath;
	GtkAdjustment *adj;
	const gchar *title, *uri;
	gchar interval_str[16];
	gint interval = 0;

	g_return_if_fail(prefsui);

	title = gtk_entry_get_text(GTK_ENTRY(prefsui->title_entry));
	uri   = gtk_entry_get_text(GTK_ENTRY(prefsui->uri_entry));
	adj = gtk_spin_button_get_adjustment
			(GTK_SPIN_BUTTON(prefsui->interval_spin));
	interval = gtk_adjustment_get_value(adj);
	g_snprintf(interval_str, sizeof(interval_str), "%d", interval);

	gtk_list_store_append(prefsui->store, &iter);
	gtk_list_store_set(prefsui->store, &iter,
			   COLUMN_TITLE,    title,
			   COLUMN_URI,      uri,
			   COLUMN_INTERVAL, interval_str,
			   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_remote_bookmark_set_sensitive (prefsui);
}


static void
cb_remove_button (GtkButton *button, KzPrefsRemoteBookmark *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_remote_bookmark_set_sensitive (prefsui);
}


static void
cb_title_edited (GtkCellRendererText *cell,
		 const gchar *path_str,
		 const gchar *new_text,
		 KzPrefsRemoteBookmark *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_TITLE, new_text,
			   COLUMN_TERMINATOR);

	prefsui->changed = TRUE;

	prefs_remote_bookmark_set_entry(prefsui);
	prefs_remote_bookmark_set_sensitive(prefsui);
}


static void
cb_uri_edited (GtkCellRendererText *cell,
	       const gchar *path_str,
	       const gchar *new_text,
	       KzPrefsRemoteBookmark *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_remote_bookmark_set_entry(prefsui);
	prefs_remote_bookmark_set_sensitive(prefsui);
}


static void
cb_interval_edited (GtkCellRendererText *cell,
		    const gchar *path_str,
		    const gchar *new_text,
		    KzPrefsRemoteBookmark *prefsui)
{
        GtkTreeIter  iter;
	gint i;

	for (i = 0; i < strlen(new_text); i++)
	{
		if (!g_ascii_isdigit(new_text[i]))
		{
			new_text = "0";
			break;
		}
	}

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

	prefsui->changed = TRUE;

	prefs_remote_bookmark_set_entry(prefsui);
	prefs_remote_bookmark_set_sensitive(prefsui);
}


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

	prefsui->lock_entry_handlers = TRUE;
	prefs_remote_bookmark_set_entry(prefsui);
	prefs_remote_bookmark_set_sensitive (prefsui);
	prefsui->lock_entry_handlers = FALSE;
}


static void
cb_title_entry_changed(GtkEditable *editable, KzPrefsRemoteBookmark *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 *title;

		title = gtk_entry_get_text(GTK_ENTRY(prefsui->title_entry));
		gtk_list_store_set(GTK_LIST_STORE(model), &iter,
				   COLUMN_TITLE, title,
				   COLUMN_TERMINATOR);
		prefsui->changed = TRUE;
	}

	prefs_remote_bookmark_set_sensitive (prefsui);
}


static void
cb_uri_entry_changed(GtkEditable *editable, KzPrefsRemoteBookmark *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_remote_bookmark_set_sensitive (prefsui);
}


static void
cb_interval_value_changed (GtkSpinButton *button, KzPrefsRemoteBookmark *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))
	{
		GtkAdjustment *adj;
		gchar interval_str[16];
		gint interval;

		adj = gtk_spin_button_get_adjustment
				(GTK_SPIN_BUTTON(prefsui->interval_spin));
		interval = gtk_adjustment_get_value(adj);
		g_snprintf(interval_str, sizeof(interval_str), "%d", interval);
		gtk_list_store_set(GTK_LIST_STORE(model), &iter,
				   COLUMN_INTERVAL, interval_str,
				   COLUMN_TERMINATOR);
		prefsui->changed = TRUE;
	}

	prefs_remote_bookmark_set_sensitive (prefsui);
}


static GtkWidget *
prefs_remote_bookmark_create (void)
{
	KzPrefsRemoteBookmark *prefsui = g_new0(KzPrefsRemoteBookmark, 1);
	GtkWidget *main_vbox, *list_hbox, *hbox, *vbox1, *vbox2;
	GtkWidget *label, *scrwin, *tree_view;
	GtkWidget *button, *arrow, *entry, *spin;
	GtkListStore *store;
	GtkCellRenderer *cell;
	GtkTreeViewColumn *column;
	GList *children, *node;

	prefsui->changed = FALSE;
	prefsui->lock_entry_handlers = FALSE;

	main_vbox = gtk_vbox_new(FALSE, 0);
	prefsui->main_vbox = main_vbox;
	g_object_set_data_full(G_OBJECT(main_vbox), DATA_KEY,
			       prefsui, prefs_remote_bookmark_destroy);

	label = kz_prefs_ui_utils_create_title(_("Remote Bookmark"));
	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(_("Kazehakase can fetch RSS/RDF, LIRS, hina-di files. "
				"File formats will be detected automatically."));
	gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
	gtk_box_pack_start(GTK_BOX(hbox), label,
			   FALSE, FALSE, 10);
	gtk_widget_show(label);

	/* hbox for list and up/down buttons */
	list_hbox = gtk_hbox_new(FALSE, 0);
	gtk_box_pack_start(GTK_BOX(main_vbox), list_hbox,
			   TRUE, TRUE, 0);
	gtk_widget_show(list_hbox);

	/* scrolled window */
	scrwin = gtk_scrolled_window_new(NULL, NULL);
	gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrwin),
				       GTK_POLICY_AUTOMATIC,
				       GTK_POLICY_AUTOMATIC);
        gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrwin),
					    GTK_SHADOW_IN);
	gtk_container_set_border_width(GTK_CONTAINER(scrwin), 5);
	gtk_box_pack_start(GTK_BOX(list_hbox), scrwin, TRUE, TRUE, 0);
	gtk_widget_show(scrwin);

	/* tree view */
	store = gtk_list_store_new(N_COLUMNS,
				   G_TYPE_STRING,
				   G_TYPE_STRING,
				   G_TYPE_STRING,
				   G_TYPE_STRING,
				   G_TYPE_BOOLEAN,
				   KZ_TYPE_BOOKMARK);
	prefsui->store = store;

	tree_view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store));
	prefsui->tree_view = GTK_TREE_VIEW(tree_view);
	gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (tree_view), TRUE);

	/* Title column */
	cell = gtk_cell_renderer_text_new();
	g_signal_connect(G_OBJECT(cell), "edited",
			 G_CALLBACK(cb_title_edited), prefsui);
	column = gtk_tree_view_column_new_with_attributes
			(_("Title"), cell,
			 "text",     COLUMN_TITLE,
			 "editable", COLUMN_EDITABLE,
			 NULL);
	gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
	gtk_tree_view_column_set_fixed_width (column, 100);
	gtk_tree_view_column_set_resizable(column, TRUE);
	gtk_tree_view_append_column(prefsui->tree_view, column);

	/* URI column */
	cell = gtk_cell_renderer_text_new();
	g_signal_connect(G_OBJECT(cell), "edited",
			 G_CALLBACK(cb_uri_edited), prefsui);
	column = gtk_tree_view_column_new_with_attributes
			(_("URI"), cell,
			 "text",     COLUMN_URI,
			 "editable", COLUMN_EDITABLE,
			 NULL);
	gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
	gtk_tree_view_column_set_fixed_width (column, 250);
	gtk_tree_view_column_set_resizable(column, TRUE);
	gtk_tree_view_append_column(prefsui->tree_view, column);

	/* Interval column */
	cell = gtk_cell_renderer_text_new();
	g_object_set(G_OBJECT(cell), "xalign", 0.8, NULL);
	g_signal_connect(G_OBJECT(cell), "edited",
			 G_CALLBACK(cb_interval_edited), prefsui);
	column = gtk_tree_view_column_new_with_attributes
			(_("Interval (min)"), cell,
			 "text",     COLUMN_INTERVAL,
			 "editable", COLUMN_EDITABLE,
			 NULL);
	g_object_set(G_OBJECT(column), "alignment", 0.5, NULL);
	gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
	gtk_tree_view_column_set_fixed_width (column, 30);
	gtk_tree_view_column_set_resizable(column, TRUE);
	gtk_tree_view_append_column(prefsui->tree_view, column);

	/* set default value */
	prefsui->bookmarklist = kz_bookmark_list_get_instance();

	children = kz_bookmark_get_children(prefsui->bookmarklist);
	for (node = children; node; node = g_list_next(node))
	{
		KzBookmark *bookmark = node->data;
		GtkTreeIter iter;
		gchar buf[32];
		const gchar *title, *location;
		guint interval;

		interval = kz_bookmark_get_interval(bookmark);
		g_snprintf(buf, sizeof(buf) / sizeof(gchar), "%d",
			   interval);

		title    = kz_bookmark_get_title(KZ_BOOKMARK(bookmark));
		location = kz_bookmark_get_location(KZ_BOOKMARK(bookmark));
		gtk_list_store_append(store, &iter);
		gtk_list_store_set(store, &iter,
				   COLUMN_TITLE,     title,
				   COLUMN_URI,       location,
				   COLUMN_INTERVAL,  buf,
				   COLUMN_EDITABLE,  TRUE,
				   COLUMN_RBOOKMARK, bookmark,
				   COLUMN_TERMINATOR);
	}
	g_list_free(children);

	gtk_container_add(GTK_CONTAINER(scrwin), tree_view);
	gtk_widget_show(tree_view);

	/* button box */
	vbox1 = gtk_vbox_new(TRUE, 0);
	gtk_box_pack_start(GTK_BOX(list_hbox), vbox1, FALSE, FALSE, 0);
	gtk_container_set_border_width(GTK_CONTAINER(vbox1), 0);
	gtk_widget_show(vbox1);

	vbox2 = gtk_vbox_new(FALSE, 0);
	gtk_box_pack_start(GTK_BOX(vbox1), vbox2, FALSE, FALSE, 0);
	gtk_container_set_border_width(GTK_CONTAINER(vbox2), 0);
	gtk_widget_show(vbox2);

	/* up button */
	button = gtk_button_new();
	prefsui->up = button;
	arrow = gtk_arrow_new(GTK_ARROW_UP, GTK_SHADOW_NONE);
	gtk_container_add(GTK_CONTAINER(button), arrow);
	gtk_widget_show(arrow);
	gtk_box_pack_start(GTK_BOX(vbox2), button, FALSE, FALSE, 5);
	g_signal_connect(G_OBJECT(button), "clicked",
			 G_CALLBACK(cb_up_button), prefsui);
	gtk_widget_show(button);

	/* down button */
	button = gtk_button_new();
	prefsui->down = button;
	arrow = gtk_arrow_new(GTK_ARROW_DOWN, GTK_SHADOW_NONE);
	gtk_container_add(GTK_CONTAINER(button), arrow);
	gtk_widget_show(arrow);
	gtk_box_pack_start(GTK_BOX(vbox2), button, FALSE, FALSE, 5);
	g_signal_connect(G_OBJECT(button), "clicked",
			 G_CALLBACK(cb_down_button), prefsui);
	gtk_widget_show(button);

	/* entry box */
	hbox = gtk_hbox_new(FALSE, 0);
	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);

	prefsui->title_entry = entry = gtk_entry_new();
	gtk_box_pack_start(GTK_BOX(hbox), entry, TRUE, TRUE, 0);
	gtk_widget_set_size_request(entry, 100, -1);
	g_signal_connect(G_OBJECT(entry), "changed",
			 G_CALLBACK(cb_title_entry_changed), prefsui);
	gtk_widget_show(entry);

	prefsui->uri_entry = entry = gtk_entry_new();
	gtk_box_pack_start(GTK_BOX(hbox), entry, TRUE, TRUE, 0);
	gtk_widget_set_size_request(entry, 250, -1);
	g_signal_connect(G_OBJECT(entry), "changed",
			 G_CALLBACK(cb_uri_entry_changed), prefsui);
	gtk_widget_show(entry);

	prefsui->interval_spin = spin
		= gtk_spin_button_new_with_range(0, 60 * 24 * 7, 1);
	gtk_box_pack_start(GTK_BOX(hbox), spin, TRUE, TRUE, 0);
	g_signal_connect(G_OBJECT(spin), "value-changed",
			 G_CALLBACK(cb_interval_value_changed), prefsui);
	gtk_widget_show(spin);

	/* 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);

	/* clear button */
	button = gtk_button_new_from_stock(GTK_STOCK_NEW);
	prefsui->new = button;
	gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0);
	g_signal_connect(G_OBJECT(button), "clicked",
			 G_CALLBACK(cb_new_button), prefsui);
	gtk_widget_show(button);

	/* add button */
	button = gtk_button_new_from_stock(GTK_STOCK_ADD);
	prefsui->add = button;
	gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0);
	g_signal_connect(G_OBJECT(button), "clicked",
			 G_CALLBACK(cb_add_button), prefsui);
	gtk_widget_show(button);

	/* remove button */
	button = gtk_button_new_from_stock(GTK_STOCK_REMOVE);
	prefsui->remove = button;
	gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0);
	g_signal_connect(G_OBJECT(button), "clicked",
			 G_CALLBACK(cb_remove_button), prefsui);
	gtk_widget_show(button);

	/* signal handler for GtkTreeView */
	g_signal_connect(G_OBJECT(tree_view), "cursor-changed",
			 G_CALLBACK(cb_cursor_changed), prefsui);

	prefs_remote_bookmark_set_sensitive (prefsui);

	return main_vbox;
}



static void
prefs_remote_bookmark_apply (KzPrefsRemoteBookmark *prefsui)
{
	GtkTreeModel *model = GTK_TREE_MODEL(prefsui->store);
	GtkTreeIter iter;
	GSList *new_list = NULL;
	gboolean exist;

	if (!prefsui->changed) return;

	exist = gtk_tree_model_get_iter_first(model, &iter);
	while (exist)
	{
		KzBookmark *bookmark = NULL;
		gchar *title = NULL, *uri = NULL, *interval_str = NULL;
		gint interval = 0;

		gtk_tree_model_get(model, &iter,
				   COLUMN_TITLE,     &title,
				   COLUMN_URI,       &uri,
				   COLUMN_INTERVAL,  &interval_str,
				   COLUMN_RBOOKMARK, &bookmark,
				   COLUMN_TERMINATOR);
		if (interval_str)
			interval = atoi(interval_str);

		if (bookmark)
		{
			g_object_ref(bookmark);
		        g_object_set(G_OBJECT(bookmark),
				     "title",    title,
				     "location", uri,
				     "interval", interval,
				     NULL);
		}
		else
		{
			bookmark = kz_bookmark_file_new(uri, title, NULL);
			kz_bookmark_set_interval(bookmark, interval);
		}

		new_list = g_slist_append(new_list, bookmark);

		g_free(title);
		g_free(uri);
		g_free(interval_str);

		exist = gtk_tree_model_iter_next(model, &iter);
	}

	kz_bookmark_list_set_list(prefsui->bookmarklist, new_list);
	kz_bookmark_save(prefsui->bookmarklist);

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

	prefsui->changed = FALSE;

	prefs_remote_bookmark_set_sensitive (prefsui);
}


static void
prefs_remote_bookmark_response (GtkWidget *widget, gint response)
{
	KzPrefsRemoteBookmark *prefsui = g_object_get_data(G_OBJECT(widget), DATA_KEY);

	g_return_if_fail(prefsui);

	switch (response) {
	case GTK_RESPONSE_ACCEPT:
	case GTK_RESPONSE_APPLY:
		prefs_remote_bookmark_apply(prefsui);
		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;
	}
}


static void
prefs_remote_bookmark_set_sensitive (KzPrefsRemoteBookmark *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 *title, *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);
	}

	title = gtk_entry_get_text(GTK_ENTRY(prefsui->title_entry));
	uri   = gtk_entry_get_text(GTK_ENTRY(prefsui->uri_entry));
	if (title && *title && uri && *uri)
		can_add = TRUE;

	if ((!title || !*title) && (!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_remote_bookmark_set_entry (KzPrefsRemoteBookmark *prefsui)
{
	GtkTreeSelection *selection;
	GtkTreeModel *model;
	GtkTreeIter iter;
	GtkAdjustment *adj;
	gchar *title = NULL, *uri = NULL, *interval_str = NULL;
	gint interval = 0;

	g_return_if_fail(prefsui);

	adj = gtk_spin_button_get_adjustment
			(GTK_SPIN_BUTTON(prefsui->interval_spin));

	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_TITLE,     &title,
				   COLUMN_URI,       &uri,
				   COLUMN_INTERVAL,  &interval_str,
				   COLUMN_TERMINATOR);

		interval = atoi(interval_str);

		gtk_entry_set_text(GTK_ENTRY(prefsui->title_entry), title);
		gtk_entry_set_text(GTK_ENTRY(prefsui->uri_entry), uri);
		gtk_adjustment_set_value(GTK_ADJUSTMENT(adj), interval);

		g_free(title);
		g_free(uri);
		g_free(interval_str);
	}
	else
	{
		gtk_entry_set_text(GTK_ENTRY(prefsui->title_entry), "");
		gtk_entry_set_text(GTK_ENTRY(prefsui->uri_entry), "");
		gtk_adjustment_set_value(GTK_ADJUSTMENT(adj), 0);
	}
}


static void
prefs_remote_bookmark_destroy (gpointer data)
{
	KzPrefsRemoteBookmark *prefsui = data;

	if (prefsui->bookmarklist)
	{
		g_object_unref(prefsui->bookmarklist);
		prefsui->bookmarklist = NULL;
	}

	g_free(prefsui);
}


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