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

/*
 *  Copyright (C) 2005 Ryo SHIMIZU
 *
 *  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-copy-format-dialog.h"

#include <stdio.h>
#include <gdk/gdkkeysyms.h>
#include <glib/gi18n.h>
#include <glib/gprintf.h>

#include "utils.h"
#include "kz-icons.h"

enum {
	PROP_0,
	PROP_KZ_WINDOW
};

enum {
	TERMINATOR = -1,
	COLUMN_TITLE,
	COLUMN_FORMAT,
	COLUMN_EDITABLE,
	N_COLUMNS
};

static GObject *constructor        (GType           type,
				    guint           n_props,
				    GObjectConstructParam *props);
static void     dispose            (GObject        *object);
static void     set_property       (GObject       *object,
				    guint          prop_id,
				    const GValue  *value,
				    GParamSpec    *pspec);
static void     get_property       (GObject       *object,
				    guint          prop_id,
				    GValue        *value,
				    GParamSpec    *pspec);
static void     response           (GtkDialog      *dialog,
				    gint            arg);

static void     cb_add_button_clicked           	(GtkWidget      *widget,
						    	 KzCopyFormatDialog  *copy_format);

static void     cb_remove_button_clicked           	(GtkWidget      *widget,
							 KzCopyFormatDialog  *copy_format);

static void	cb_title_edited				(GtkWidget *widget,
							 const gchar *path_str,
							 const gchar *new_text,
							 KzCopyFormatDialog *copy_format);

static void	cb_format_edited			(GtkWidget *widget,
							 const gchar *path_str,
							 const gchar *new_text,
							 KzCopyFormatDialog *copy_format);

static void	set_copy_format_prefs(KzCopyFormatDialog *copy_format);

static GList*	get_copy_format_prefs(void);

G_DEFINE_TYPE(KzCopyFormatDialog, kz_copy_format_dialog, GTK_TYPE_DIALOG)

static void
kz_copy_format_dialog_class_init (KzCopyFormatDialogClass *klass)
{
	GObjectClass *gobject_class;
	GtkDialogClass *dialog_class;

	gobject_class = (GObjectClass *) klass;
	dialog_class  = (GtkDialogClass *) klass;

	gobject_class->constructor  = constructor;
	gobject_class->dispose      = dispose;
	gobject_class->set_property = set_property;
	gobject_class->get_property = get_property;

	/* GtkDialog signals */
	dialog_class->response = response;

	g_object_class_install_property
		(gobject_class,
		 PROP_KZ_WINDOW,
		 g_param_spec_object("kz-window",
				      _("KzWindow"),
				     _("The parent kazehakase window"),
				     KZ_TYPE_WINDOW,
				     G_PARAM_READWRITE |
				     G_PARAM_CONSTRUCT_ONLY));
}


static void
kz_copy_format_dialog_init (KzCopyFormatDialog *copy_format)
{
	GtkWidget *main_vbox, *scrwin, *tree_view, *hbox, *add_button, *remove_button, *label;
	GtkListStore *store;
	GtkCellRenderer *cell;
	GtkTreeViewColumn *col;
	GtkTreeSelection *selection;

	copy_format->kz            = NULL;

	main_vbox = GTK_DIALOG(copy_format)->vbox;
	gtk_box_set_spacing(GTK_BOX(main_vbox), 4);
	gtk_window_set_default_size(GTK_WINDOW(copy_format), 600, 450);
	gtk_window_set_icon(GTK_WINDOW(copy_format), kz_icon);
	gtk_window_set_destroy_with_parent(GTK_WINDOW(copy_format), TRUE);

	gtk_dialog_add_buttons(GTK_DIALOG(copy_format),
			       GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT,
			       GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
			       NULL);

	/* label */
	label = gtk_label_new(_("You can specify the format of copied title, URI and Selected text. \n"
				"%t% -> Title, %u% -> URI, %s% -> Selected text, \\n -> NewLine"));
	gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
	gtk_box_pack_start(GTK_BOX(main_vbox), label, FALSE, FALSE, 0);
	gtk_widget_show(label);

	/* 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_box_pack_start(GTK_BOX(main_vbox), 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_BOOLEAN
					 );
	tree_view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store));
	gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (tree_view), TRUE);
	selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view));
	gtk_tree_selection_set_mode (selection, GTK_SELECTION_MULTIPLE);

	/* title column */
	cell = gtk_cell_renderer_text_new();
	g_signal_connect(cell, "edited", G_CALLBACK(cb_title_edited), copy_format);
	col = gtk_tree_view_column_new_with_attributes
			(_("Title"), cell, "text", COLUMN_TITLE, "editable", COLUMN_EDITABLE, NULL);
	gtk_tree_view_column_set_sizing(col, GTK_TREE_VIEW_COLUMN_FIXED);
	gtk_tree_view_column_set_fixed_width (col, 200);
	gtk_tree_view_column_set_resizable(col, TRUE);
	gtk_tree_view_append_column(GTK_TREE_VIEW(tree_view), col);

	/* format column */
	cell = gtk_cell_renderer_text_new();
	g_signal_connect(cell, "edited", G_CALLBACK(cb_format_edited), copy_format);
	col = gtk_tree_view_column_new_with_attributes
			(_("Format"), cell, "text", COLUMN_FORMAT, "editable", COLUMN_EDITABLE,  NULL);
	gtk_tree_view_column_set_sizing(col, GTK_TREE_VIEW_COLUMN_FIXED);
	gtk_tree_view_column_set_fixed_width (col, 360);
	gtk_tree_view_column_set_resizable(col, TRUE);
	gtk_tree_view_append_column(GTK_TREE_VIEW(tree_view), col);

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

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

	/* add button */
	add_button = gtk_button_new_from_stock(GTK_STOCK_ADD);
	gtk_box_pack_start(GTK_BOX(hbox), add_button, FALSE, FALSE, 0);
	g_signal_connect(add_button, "clicked",
			 G_CALLBACK(cb_add_button_clicked), copy_format);
	g_signal_connect(add_button, "clicked",
			 G_CALLBACK(set_copy_format_prefs), copy_format);
	gtk_widget_show(add_button);

	/* remove button */
	remove_button = gtk_button_new_from_stock(GTK_STOCK_REMOVE);
	gtk_box_pack_start(GTK_BOX(hbox), remove_button, FALSE, FALSE, 0);
	g_signal_connect(remove_button, "clicked",
			 G_CALLBACK(cb_remove_button_clicked), copy_format);
	gtk_widget_show(remove_button);

	copy_format->scrolled_window = scrwin;
	copy_format->tree_view       = GTK_TREE_VIEW(tree_view);
	copy_format->list_store      = store;
}


static GObject*
constructor (GType                  type,
	     guint                  n_props,
	     GObjectConstructParam *props)
{
	GtkWidget *widget;
	KzCopyFormatDialog *copy_format;
	GObject *object;
	GObjectClass *klass = G_OBJECT_CLASS(kz_copy_format_dialog_parent_class);
	GList *list = NULL, *node;

	object = klass->constructor(type, n_props, props);

	copy_format = KZ_COPY_FORMAT_DIALOG(object);
	widget = GTK_WIDGET(copy_format);

	gtk_window_set_title(GTK_WINDOW(copy_format), _("Copy Format Editor"));
	gtk_window_set_transient_for(GTK_WINDOW(copy_format),
	    			     GTK_WINDOW(copy_format->kz));

	list = get_copy_format_prefs();

	if (!list) return object;

	for (node = list; node; node = g_list_next(node))
	{
		CopyFormat *link = node->data;
		GtkTreeIter iter;
		const gchar *title = link->title;
		const gchar *format = link->format;

		if (!title || !*title) continue;

		gtk_list_store_append(copy_format->list_store, &iter);
		gtk_list_store_set(copy_format->list_store, &iter,
				   COLUMN_TITLE, title,
				   COLUMN_FORMAT, format,
					 COLUMN_EDITABLE, TRUE,
				   TERMINATOR);
	}

	g_list_free(list);

	return object;
}


static void
dispose (GObject *object)
{
	KzCopyFormatDialog *copy_format = KZ_COPY_FORMAT_DIALOG(object);

	if (copy_format->kz)
	{
		g_object_unref(copy_format->kz);
		copy_format->kz = NULL;
	}

	if (copy_format->list_store)
	{
		g_object_unref(copy_format->list_store);
		copy_format->list_store = NULL;
	}

	if (G_OBJECT_CLASS (kz_copy_format_dialog_parent_class)->dispose)
		G_OBJECT_CLASS (kz_copy_format_dialog_parent_class)->dispose(object);
}


static void
set_property (GObject         *object,
	      guint            prop_id,
	      const GValue    *value,
	      GParamSpec      *pspec)
{
	KzCopyFormatDialog *copy_format = KZ_COPY_FORMAT_DIALOG(object);
  
	switch (prop_id)
	{
	case PROP_KZ_WINDOW:
		copy_format->kz = g_object_ref(g_value_get_object(value));
		break;
	default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
		break;
	}
}


static void
get_property (GObject         *object,
	      guint            prop_id,
	      GValue          *value,
	      GParamSpec      *pspec)
{
	KzCopyFormatDialog *copy_format = KZ_COPY_FORMAT_DIALOG(object);

	switch (prop_id)
	{
	case PROP_KZ_WINDOW:
		g_value_set_object(value, copy_format->kz);
		break;
	default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
		break;
	}
}


GtkWidget *
kz_copy_format_dialog_new (KzWindow *kz)
{
	GtkWidget *widget;

	widget = GTK_WIDGET(g_object_new(KZ_TYPE_COPY_FORMAT_DIALOG,
					 "kz-window",     kz,
					 NULL));

	return widget;
}


static void
response (GtkDialog *dialog, gint arg)
{
	KzCopyFormatDialog *copy_format;

	g_return_if_fail (KZ_IS_COPY_FORMAT_DIALOG(dialog));

	copy_format = KZ_COPY_FORMAT_DIALOG(dialog);
	if (!copy_format->kz) return;

	switch (arg) {
	case GTK_RESPONSE_ACCEPT:
		set_copy_format_prefs(copy_format);
		gtk_widget_destroy(GTK_WIDGET(dialog));
		break;
	case GTK_RESPONSE_REJECT:
		gtk_widget_destroy(GTK_WIDGET(dialog));
		break;
	default:
		break;
	}
}


static void
cb_add_button_clicked (GtkWidget *widget,
		       KzCopyFormatDialog *copy_format)
{
	CopyFormat copy_format_data;
  GtkTreeIter iter;
  GtkTreeModel *model = NULL;

	g_return_if_fail(KZ_IS_COPY_FORMAT_DIALOG(copy_format));

  model = gtk_tree_view_get_model(copy_format->tree_view);
	copy_format_data.title = g_strdup(_("Title"));
	copy_format_data.format = g_strdup(_("Define format here"));

	gtk_list_store_append (GTK_LIST_STORE (model), &iter);
	gtk_list_store_set (GTK_LIST_STORE (model), &iter,
		COLUMN_TITLE, copy_format_data.title,
		COLUMN_FORMAT, copy_format_data.format,
		COLUMN_EDITABLE, TRUE,
		TERMINATOR);
}

static void
cb_remove_button_clicked (GtkWidget *widget,
			  KzCopyFormatDialog *copy_format)
{
	GtkTreeSelection *selection;
	GtkTreeModel *model = NULL;
	GList *list, *node, *pass = NULL;

	g_return_if_fail(KZ_IS_COPY_FORMAT_DIALOG(copy_format));

	selection = gtk_tree_view_get_selection(copy_format->tree_view);
	
	list = gtk_tree_selection_get_selected_rows(selection,
						    &model);
	for (node = list; node; node = g_list_next(node))
	{
		gchar *title, *format;
		CopyFormat *p;
		GtkTreeIter iter;
		GtkTreePath *path = node->data;
		
		gtk_tree_model_get_iter(model, &iter, path);
	
		gtk_tree_model_get(model,
				   &iter, 
				   COLUMN_TITLE, &title,
				   COLUMN_FORMAT, &format,
				   TERMINATOR);
		p = g_new0(CopyFormat, 1);
		p->title = g_strdup(title);
		p->format = g_strdup(format);
		g_free(title);
		g_free(format);
		pass = g_list_append(pass, p);
		gtk_list_store_remove(GTK_LIST_STORE(model), &iter);
		gtk_tree_path_free(path);
	}

	g_list_free(list);
	g_list_free(pass);
}

static void
cb_title_edited (GtkWidget *widget,
		 const gchar *path_str,
		 const gchar *new_text,
		 KzCopyFormatDialog *copy_format)
{
	GtkTreeIter iter;
	GtkListStore *store;

	store = copy_format->list_store;
	gtk_tree_model_get_iter_from_string(GTK_TREE_MODEL(store),
			    &iter, path_str);
	gtk_list_store_set (store, &iter,
		COLUMN_TITLE, new_text,
		COLUMN_EDITABLE, TRUE,
		TERMINATOR);
}

static void
cb_format_edited (GtkWidget *widget,
		  const gchar *path_str,
		  const gchar *new_text,
		  KzCopyFormatDialog *copy_format)
{
	GtkTreeIter iter;
	GtkListStore *store;

	store = copy_format->list_store;
	gtk_tree_model_get_iter_from_string(GTK_TREE_MODEL(store),
			    &iter, path_str);
	gtk_list_store_set (store, &iter,
		COLUMN_FORMAT, new_text,
		COLUMN_EDITABLE, TRUE,
		TERMINATOR);
}

static GList*
get_copy_format_prefs(void)
{
	GList *list = NULL;
	CopyFormat *copy_format_data;
	guint i;
	gchar format_directive[] = "copy_document_formatXX";
	gchar title_directive[] = "copy_document_format_titleXX";

	for(i = 1;i < 100;i++)
	{
		gchar *title;
		gchar *format;
		copy_format_data = g_new0(CopyFormat, 1);

		g_sprintf(title_directive, "copy_document_format_title%d", i);
		g_sprintf(format_directive,  "copy_document_format%d", i);

		title = KZ_CONF_GET_STR("Global", title_directive);
		format = KZ_CONF_GET_STR("Global", format_directive);

		if(!format)
			break;

		copy_format_data->title = title;
		copy_format_data->format = format;

		list = g_list_append(list, copy_format_data);
	}
	return list;
}

static void
set_copy_format_prefs(KzCopyFormatDialog *copy_format)
{
	GtkTreeModel *model = NULL;
	GtkTreeIter iter;
	GList *list = NULL, *node = NULL;
	guint i = 1;
	gboolean exist;
	gchar format_directive[] = "copy_document_formatXX";
	gchar title_directive[] = "copy_document_format_titleXX";

	g_return_if_fail(KZ_IS_COPY_FORMAT_DIALOG(copy_format));

	list = kz_profile_enum_key(KZ_GET_GLOBAL_PROFILE, "Global", TRUE);
	for (node = list; node; node = g_list_next(node))
	{
		const gchar *key = node->data;
		if(key && *key && key_seems_sequential(key,
				"copy_document_format_title"))
			kz_profile_delete_key(KZ_GET_GLOBAL_PROFILE, "Global", key);
		if(key && *key && key_seems_sequential(key,
				"copy_document_format"))
			kz_profile_delete_key(KZ_GET_GLOBAL_PROFILE, "Global", key);
	}
	g_list_free(list);

	model = gtk_tree_view_get_model(copy_format->tree_view);
	exist = gtk_tree_model_get_iter_first(model, &iter);

	for(; exist; exist = gtk_tree_model_iter_next(model, &iter))
	{
		gchar *title = NULL, *format = NULL;
		gtk_tree_model_get(model, &iter,
				COLUMN_TITLE, &title,
				COLUMN_FORMAT, &format,
				TERMINATOR);

		g_sprintf(title_directive, "copy_document_format_title%d", i);
		g_sprintf(format_directive,  "copy_document_format%d", i);

		KZ_CONF_SET_STR("Global", title_directive, title);
		KZ_CONF_SET_STR("Global", format_directive, format);
		
		i++;
	}
}
