/*
 * Osmo - a handy personal organizer
 *
 * Copyright (C) 2007-2009 Tomasz Maka <pasp@users.sourceforge.net>
 *               2007-2009 Piotr Maka <silloz@users.sourceforge.net>
 *
 * 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 of the License, 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 "contacts.h"
#include "contacts_preferences_gui.h"
#include "i18n.h"
#include "options_prefs.h"
#include "stock_icons.h"
#include "utils_gui.h"

#ifdef CONTACTS_ENABLED

/* ========================================================================== */
struct visible_column {
    gchar *checked_state;
    GUI *appGUI;
};

/* ========================================================================== */

static void
contacts_photo_size_changed_cb (GtkComboBox *widget, GUI *appGUI)
{
	gint sizes[] = { PHOTO_SMALL, PHOTO_MEDIUM, PHOTO_LARGE };
	gint i;

	i = gtk_combo_box_get_active (widget);
	config.photo_width = sizes[i % 3];
	g_signal_emit_by_name (appGUI->cnt->contacts_list_selection, "changed");
}

/* ========================================================================== */

static void
contact_link_color_changed_cb (GtkColorChooser *widget, GUI *appGUI)
{
	GdkRGBA color;

	gtk_color_chooser_get_rgba (widget, &color);
        utl_gui_convert_color_to_string(&color, config.contact_link_color);
	g_object_set (G_OBJECT (appGUI->gui_url_tag), "foreground-gdk", &color, NULL);
	g_signal_emit_by_name (G_OBJECT (appGUI->cnt->contacts_list_selection), "changed");
}

/* ========================================================================== */

static void
contact_tag_color_changed_cb (GtkColorChooser *widget, GUI *appGUI)
{
	GdkRGBA color;

	gtk_color_chooser_get_rgba (widget, &color);
	utl_gui_convert_color_to_string (&color, config.contact_tag_color);
	g_signal_emit_by_name (appGUI->cnt->contacts_list_selection, "changed");
}

/* ========================================================================== */

static void
cn_font_size_changed_cb (GtkSpinButton *spinbutton, GUI *appGUI)
{
	config.contact_name_font_size = (gint) gtk_spin_button_get_value (spinbutton);
	g_signal_emit_by_name (G_OBJECT (appGUI->cnt->contacts_list_selection), "changed");
}

static void
ci_font_size_changed_cb (GtkSpinButton *spinbutton, GUI *appGUI)
{
	config.contact_item_font_size = (gint) gtk_spin_button_get_value (spinbutton);
#ifdef HAVE_LIBWEBKIT
        webkit_settings_set_default_font_size (webkit_web_view_get_settings(appGUI->cnt->html_webkitview), config.contact_item_font_size);
#endif  /* LIBWEBKIT */
	g_signal_emit_by_name (G_OBJECT (appGUI->cnt->contacts_list_selection), "changed");
}

/* ========================================================================== */

static void
create_appearance_section (GtkWidget *appearance_vbox, GUI *appGUI)
{
	GtkWidget *table, *colors_hbox, *fonts_hbox, *photo_hbox, *spinbutton;
	GtkWidget *label, *color_button, *combobox;
	GtkAdjustment *adjustment;
	GdkRGBA color;
	gint i = 0;

	table = gtk_grid_new ();
	gtk_box_pack_start (GTK_BOX (appearance_vbox), table, FALSE, FALSE, 0);
	gtk_grid_set_column_spacing (GTK_GRID (table), 4);
	gtk_grid_set_row_spacing (GTK_GRID (table), 8);

	label = utl_gui_create_label ("%s:", _("Colors"));
	gtk_grid_attach (GTK_GRID (table), label, 0, i, 1, 1);

	colors_hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 8);
	gtk_grid_attach (GTK_GRID (table), colors_hbox, 1, i, 3, 1);

	color_button = gtk_color_button_new ();
	if (config.enable_tooltips)
		gtk_widget_set_tooltip_text (color_button, _("Color of contact tags"));
	gdk_rgba_parse (&color, config.contact_tag_color);
	gtk_color_chooser_set_rgba (GTK_COLOR_CHOOSER (color_button), &color);
	gtk_box_pack_start (GTK_BOX (colors_hbox), color_button, FALSE, FALSE, 0);
	g_signal_connect (G_OBJECT (color_button), "color-set", G_CALLBACK (contact_tag_color_changed_cb), appGUI);
	appGUI->opt->contact_tag_color_picker = color_button;

	color_button = gtk_color_button_new ();
	if (config.enable_tooltips)
		gtk_widget_set_tooltip_text (color_button, _("Color of links"));
	gdk_rgba_parse (&color, config.contact_link_color);
	gtk_color_chooser_set_rgba (GTK_COLOR_CHOOSER (color_button), &color);
	gtk_box_pack_start (GTK_BOX (colors_hbox), color_button, FALSE, FALSE, 0);
	g_signal_connect (G_OBJECT (color_button), "color-set", G_CALLBACK (contact_link_color_changed_cb), appGUI);
	appGUI->opt->contact_link_color_picker = color_button;

	i++;
	label = utl_gui_create_label ("%s:", _("Font size"));
	gtk_grid_attach (GTK_GRID (table), label, 0, i, 1, 1);

	fonts_hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 8);
	gtk_grid_attach (GTK_GRID (table), fonts_hbox, 1, i, 3, 1);

	adjustment = gtk_adjustment_new (0, 8, 48, 1, 10, 0);
	spinbutton = gtk_spin_button_new (GTK_ADJUSTMENT (adjustment), 1, 0);
	if (config.enable_tooltips)
		gtk_widget_set_tooltip_text (spinbutton, _("Name font size"));
	gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (spinbutton), TRUE);
	gtk_spin_button_set_value (GTK_SPIN_BUTTON (spinbutton), config.contact_name_font_size);
	gtk_box_pack_start (GTK_BOX (fonts_hbox), spinbutton, FALSE, FALSE, 0);
	g_signal_connect (G_OBJECT (spinbutton), "value-changed", G_CALLBACK (cn_font_size_changed_cb), appGUI);
	appGUI->opt->cn_font_size_spinbutton = spinbutton;

	adjustment = gtk_adjustment_new (0, 8, 48, 1, 10, 0);
	spinbutton = gtk_spin_button_new (GTK_ADJUSTMENT (adjustment), 1, 0);
	if (config.enable_tooltips)
		gtk_widget_set_tooltip_text (spinbutton, _("Item font size"));
	gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (spinbutton), TRUE);
	gtk_spin_button_set_value (GTK_SPIN_BUTTON (spinbutton), config.contact_item_font_size);
	gtk_box_pack_start (GTK_BOX (fonts_hbox), spinbutton, FALSE, FALSE, 0);
	g_signal_connect (G_OBJECT (spinbutton), "value-changed", G_CALLBACK (ci_font_size_changed_cb), appGUI);
	appGUI->opt->ci_font_size_spinbutton = spinbutton;

	i++;
	label = utl_gui_create_label ("%s:", _("Photo size"));
	gtk_grid_attach (GTK_GRID (table), label, 0, i, 1, 1);

	photo_hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 8);
	gtk_grid_attach (GTK_GRID (table), photo_hbox, 1, i, 3, 1);

	combobox = gtk_combo_box_text_new ();
	gtk_box_pack_start (GTK_BOX (photo_hbox), combobox, FALSE, FALSE, 0);
	gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combobox), NULL, _("Small"));
	gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combobox), NULL, _("Medium"));
	gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combobox), NULL, _("Large"));
	appGUI->opt->contacts_photo_size_combobox = combobox;
	g_signal_connect (G_OBJECT (combobox), "changed", G_CALLBACK (contacts_photo_size_changed_cb), appGUI);

	if (config.photo_width == PHOTO_LARGE) {
		gtk_combo_box_set_active (GTK_COMBO_BOX (combobox), 2);
	} else if (config.photo_width == PHOTO_MEDIUM) {
		gtk_combo_box_set_active (GTK_COMBO_BOX (combobox), 1);
	} else {
		gtk_combo_box_set_active (GTK_COMBO_BOX (combobox), 0);
	}
}

/* ========================================================================== */

static void
maps_provider_changed_cb (GtkComboBox *widget, GUI *appGUI)
{
    config.maps_provider = gtk_combo_box_get_active (widget);
}

/* ========================================================================== */

static void
create_miscellaneous_section (GtkWidget *miscellaneous_vbox, GUI *appGUI)
{
	GtkWidget *maps_hbox;
	GtkWidget *label;
	GtkWidget *combobox;

	maps_hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 8);
	gtk_box_pack_start (GTK_BOX (miscellaneous_vbox), maps_hbox, TRUE, TRUE, 4);

    label = utl_gui_create_label ("%s:", _("Maps provider"));
	gtk_box_pack_start (GTK_BOX (maps_hbox), label, FALSE, FALSE, 0);

	combobox = gtk_combo_box_text_new ();
	gtk_box_pack_start (GTK_BOX (maps_hbox), combobox, FALSE, FALSE, 0);
	gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combobox), NULL, "Google");
	gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combobox), NULL, "Bing");
	gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combobox), NULL, "OpenStreetMap");
	g_signal_connect (G_OBJECT (combobox), "changed", G_CALLBACK (maps_provider_changed_cb), appGUI);
	gtk_combo_box_set_active (GTK_COMBO_BOX (combobox), config.maps_provider);
}

/* ========================================================================== */

static void
contacts_group_remove_cb (GtkWidget *widget, GUI *appGUI)
{
	GtkTreePath *path;
	GtkTreeIter iter;

	gtk_tree_view_get_cursor (GTK_TREE_VIEW (appGUI->opt->contacts_group_treeview), &path, NULL);

	if (path != NULL) {
		gtk_tree_model_get_iter (GTK_TREE_MODEL (appGUI->opt->contacts_group_store), &iter, path);
		gtk_list_store_remove (appGUI->opt->contacts_group_store, &iter);
		gtk_tree_path_free (path);
	}
}

/* ========================================================================== */

static void
contacts_group_cell_edited_cb (GtkCellRendererText *renderer, gchar *path, gchar *new_text, GUI *appGUI)
{
	GtkTreeModel *model;
	GtkTreeIter iter;

	if (g_ascii_strcasecmp (new_text, "") != 0) {
		model = gtk_tree_view_get_model (GTK_TREE_VIEW (appGUI->opt->contacts_group_treeview));
		if (gtk_tree_model_get_iter_from_string (model, &iter, path))
			gtk_list_store_set (appGUI->opt->contacts_group_store, &iter, 0, new_text, -1);
	}
}

/* ========================================================================== */

static void
contacts_group_add_cb (GtkWidget *widget, GUI *appGUI)
{
	GtkTreeIter iter;
	const gchar *category_name;
	gchar *item;
	gboolean has_next;

	category_name = gtk_entry_get_text (GTK_ENTRY (appGUI->opt->contacts_group_entry));
	if (!strlen (category_name)) return;

        has_next = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (appGUI->opt->contacts_group_store), &iter);
	while (has_next) {
		gtk_tree_model_get (GTK_TREE_MODEL (appGUI->opt->contacts_group_store), &iter, 0, &item, -1);
		if (!strcmp (category_name, item)) {
			g_free (item);
			return;
		}
		g_free (item);
                has_next = gtk_tree_model_iter_next (GTK_TREE_MODEL (appGUI->opt->contacts_group_store), &iter);
	}

	gtk_list_store_append (appGUI->opt->contacts_group_store, &iter);
	gtk_list_store_set (appGUI->opt->contacts_group_store, &iter, 0, category_name, -1);
	gtk_entry_set_text (GTK_ENTRY (appGUI->opt->contacts_group_entry), "");
	gtk_widget_set_sensitive (appGUI->opt->contacts_group_add_button, FALSE);
}

/* ========================================================================== */

static void
contacts_group_selected_cb (GtkTreeSelection *selection, GUI *appGUI)
{
	GtkTreeModel *model;
	GtkTreeIter iter;

	if (gtk_tree_selection_get_selected (selection, &model, &iter))
		gtk_widget_set_sensitive (appGUI->opt->contacts_group_remove_button, TRUE);
	else
		gtk_widget_set_sensitive (appGUI->opt->contacts_group_remove_button, FALSE);
}

/* ========================================================================== */

static gint
contacts_group_entry_key_release_cb (GtkEntry *widget, GdkEventKey *event, GUI *appGUI)
{
	gboolean state = FALSE;

	if (strlen (gtk_entry_get_text (widget)))
		state = TRUE;

	gtk_widget_set_sensitive (appGUI->opt->contacts_group_add_button, state);

	if (event->keyval == GDK_KEY_Return) {
		if (state) contacts_group_add_cb (NULL, appGUI);
		return TRUE;
	}

	return FALSE;
}

/* ========================================================================== */

static void
create_groups_section (GtkWidget *groups_vbox, GUI *appGUI)
{
	GtkTreeViewColumn *column;
	GtkCellRenderer *renderer;
	GtkWidget *table, *scrolledwindow, *treeview;

	table = gtk_grid_new ();
	gtk_box_pack_start (GTK_BOX (groups_vbox), table, TRUE, TRUE, 0);
	gtk_container_set_border_width (GTK_CONTAINER (table), 8);
	gtk_grid_set_row_spacing (GTK_GRID (table), 8);
	gtk_grid_set_column_spacing (GTK_GRID (table), 4);

	appGUI->opt->contacts_group_entry = gtk_entry_new ();
	gtk_widget_set_hexpand(appGUI->opt->contacts_group_entry, TRUE);
	gtk_grid_attach (GTK_GRID (table), appGUI->opt->contacts_group_entry, 0, 3, 1, 1);
	g_signal_connect (G_OBJECT (appGUI->opt->contacts_group_entry), "key_release_event",
	                  G_CALLBACK (contacts_group_entry_key_release_cb), appGUI);

	scrolledwindow = gtk_scrolled_window_new (NULL, NULL);
	gtk_widget_set_hexpand(scrolledwindow, TRUE);
	gtk_scrolled_window_set_min_content_height(GTK_SCROLLED_WINDOW (scrolledwindow), 80);
	gtk_grid_attach (GTK_GRID (table), scrolledwindow, 0, 0, 3, 3);
	gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
	gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolledwindow), GTK_SHADOW_IN);

	treeview = gtk_tree_view_new_with_model (GTK_TREE_MODEL (appGUI->opt->contacts_group_store));
	gtk_container_add (GTK_CONTAINER (scrolledwindow), treeview);
	gtk_container_set_border_width (GTK_CONTAINER (treeview), 4);
	gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (treeview), FALSE);
	gtk_tree_view_set_reorderable (GTK_TREE_VIEW (treeview), TRUE);
	gtk_tree_view_set_enable_search (GTK_TREE_VIEW (treeview), FALSE);
	appGUI->opt->contacts_group_treeview = treeview;

	appGUI->opt->contacts_group_select = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview));
	g_signal_connect (G_OBJECT (appGUI->opt->contacts_group_select), "changed", G_CALLBACK (contacts_group_selected_cb), appGUI);

	renderer = gtk_cell_renderer_text_new ();
	g_object_set (renderer, "editable", TRUE, "editable-set", TRUE, NULL);
	g_signal_connect (G_OBJECT (renderer), "edited", G_CALLBACK (contacts_group_cell_edited_cb), appGUI);

	column = gtk_tree_view_column_new_with_attributes (NULL, renderer, "text", 0, NULL);
	gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column);

	appGUI->opt->contacts_group_add_button = gtk_button_new_from_icon_name ("list-add", GTK_ICON_SIZE_BUTTON);
	gtk_widget_set_sensitive (appGUI->opt->contacts_group_add_button, FALSE);
	gtk_grid_attach (GTK_GRID (table), appGUI->opt->contacts_group_add_button, 1, 3, 1, 1);
	g_signal_connect (appGUI->opt->contacts_group_add_button, "clicked", G_CALLBACK (contacts_group_add_cb), appGUI);

	appGUI->opt->contacts_group_remove_button = gtk_button_new_from_icon_name ("list-remove", GTK_ICON_SIZE_BUTTON);
	gtk_widget_set_sensitive (appGUI->opt->contacts_group_remove_button, FALSE);
	gtk_grid_attach (GTK_GRID (table), appGUI->opt->contacts_group_remove_button, 2, 3, 1, 1);
	g_signal_connect (appGUI->opt->contacts_group_remove_button, "clicked", G_CALLBACK (contacts_group_remove_cb), appGUI);
}

/* ========================================================================== */
void
free_data(gpointer data, GClosure *closure) {
    g_free(data);
}

/* ========================================================================== */
static void
visible_column_toggled(GtkToggleButton *togglebutton, struct visible_column *data) {
    *(data->checked_state) = gtk_toggle_button_get_active(togglebutton) ? '+' : '-';
    refresh_contacts_visible_columns(data->appGUI);
}

/* ========================================================================== */
static GtkWidget *
create_visible_columns_checkbutton(const gchar *label, gchar *checked_state, GUI *appGUI) {
    struct visible_column *data;
    GtkWidget *checkbutton = gtk_check_button_new_with_mnemonic(label);

    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkbutton), *checked_state == '+');
    data = g_new(struct visible_column, 1);
    data->appGUI = appGUI;
    data->checked_state = checked_state;
    g_signal_connect_data(G_OBJECT(checkbutton), "toggled", G_CALLBACK(visible_column_toggled), data, free_data, (GConnectFlags) 0);
    return checkbutton;
}

/* ========================================================================== */
static void
create_visible_columns_section(GtkWidget *visible_columns_vbox, GUI *appGUI) {
    GtkWidget *table, *checkbutton;

    table = gtk_grid_new();
    gtk_box_pack_start(GTK_BOX(visible_columns_vbox), table, FALSE, FALSE, 0);
    gtk_grid_set_row_spacing(GTK_GRID(table), 4);
    gtk_grid_set_column_spacing(GTK_GRID(table), 8);

    checkbutton = create_visible_columns_checkbutton(_("Group"), &(config.contacts_visible_columns[COLUMN_GROUP]), appGUI);
    gtk_widget_set_hexpand(checkbutton, TRUE);
    gtk_grid_attach(GTK_GRID(table), checkbutton, 0, 0, 1, 1);

    checkbutton = create_visible_columns_checkbutton(_("Organization"), &(config.contacts_visible_columns[COLUMN_WORK_ORGANIZATION]), appGUI);
    gtk_widget_set_hexpand(checkbutton, TRUE);
    gtk_grid_attach(GTK_GRID(table), checkbutton, 1, 0, 1, 1);
}

/* ========================================================================== */
static void
birthday_browser_visible_column_toggled(GtkToggleButton *togglebutton, gint *option) {
    *option = gtk_toggle_button_get_active(togglebutton);
}

/* ========================================================================== */
static GtkWidget *
create_birthday_browser_visible_columns_checkbutton(const gchar *label, gboolean *checked_state) {
    GtkWidget *checkbutton = gtk_check_button_new_with_mnemonic(label);
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkbutton), *checked_state);
    g_signal_connect(G_OBJECT(checkbutton), "toggled", G_CALLBACK(birthday_browser_visible_column_toggled), checked_state);
    return checkbutton;
}

/* ========================================================================== */
static void
create_birthday_browser_visible_columns_section(GtkWidget *visible_columns_vbox, GUI *appGUI) {
    GtkWidget *table, *checkbutton;

    table = gtk_grid_new();
    gtk_box_pack_start(GTK_BOX(visible_columns_vbox), table, FALSE, FALSE, 0);
    gtk_grid_set_row_spacing(GTK_GRID(table), 4);
    gtk_grid_set_column_spacing(GTK_GRID(table), 8);

    checkbutton = create_birthday_browser_visible_columns_checkbutton(_("Age"), &(config.cnt_visible_age_column));
    gtk_widget_set_hexpand(checkbutton, TRUE);
    gtk_grid_attach(GTK_GRID(table), checkbutton, 0, 0, 1, 1);
    appGUI->opt->vc_age_checkbutton = checkbutton;

    checkbutton = create_birthday_browser_visible_columns_checkbutton(_("Birthday date"), &(config.cnt_visible_birthday_date_column));
    gtk_widget_set_hexpand(checkbutton, TRUE);
    gtk_grid_attach(GTK_GRID(table), checkbutton, 1, 0, 1, 1);
    appGUI->opt->vc_birthday_date_checkbutton = checkbutton;

    checkbutton = create_birthday_browser_visible_columns_checkbutton(_("Zodiac sign"), &(config.cnt_visible_zodiac_sign_column));
    gtk_widget_set_hexpand(checkbutton, TRUE);
    gtk_grid_attach(GTK_GRID(table), checkbutton, 2, 0, 1, 1);
    appGUI->opt->vc_zodiac_sign_checkbutton = checkbutton;
}

/* ========================================================================== */

GtkWidget *
cnt_create_preferences_page (GtkWidget *notebook, GUI *appGUI)
{
	GtkWidget *vbox_top, *vbox_icon, *vbox, *scrolledwindow;

	vbox_top = gtk_box_new (GTK_ORIENTATION_VERTICAL, VBOX_SPACING);
	gtk_container_set_border_width (GTK_CONTAINER (vbox_top), BORDER_WIDTH);
	scrolledwindow = utl_gui_insert_in_scrolled_window (vbox_top, GTK_SHADOW_ETCHED_IN);
	gtk_container_set_border_width (GTK_CONTAINER (scrolledwindow), 2);
	vbox_icon = utl_gui_create_icon_with_label (OSMO_STOCK_CONTACTS, _("Contacts"));

	vbox = utl_gui_create_vbox_in_frame (vbox_top, _("Appearance"));
	create_appearance_section (vbox, appGUI);

	vbox = utl_gui_create_vbox_in_frame (vbox_top, _("Visible columns"));
	create_visible_columns_section (vbox, appGUI);
        
	vbox = utl_gui_create_vbox_in_frame (vbox_top, _("Miscellaneous"));
	create_miscellaneous_section (vbox, appGUI);

	vbox = utl_gui_create_vbox_in_frame (vbox_top, _("Groups"));
	create_groups_section (vbox, appGUI);

	vbox = utl_gui_create_vbox_in_frame (vbox_top, _("Visible columns in birthday browser"));
	create_birthday_browser_visible_columns_section (vbox, appGUI);

	gtk_notebook_append_page (GTK_NOTEBOOK (notebook), scrolledwindow, vbox_icon);
	gtk_widget_show_all (scrolledwindow);

	return scrolledwindow;
}

/* ========================================================================== */

#endif /* CONTACTS_ENABLED */

