/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
/***************************************************************************
 *            e-kolab-account-setup.c
 *
 *  Wed Jun 16 15:37:05 2010
 *  Copyright  2010  Christian Hilberg
 *  <hilberg@kernelconcepts.de>
 *  and Silvan Marco Fin <silvan@kernelconcepts.de> in 2011
 ****************************************************************************/

/*
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor Boston, MA 02110-1301,  USA
 */

/*----------------------------------------------------------------------------*/

#include <config.h>

#include <glib/gi18n-lib.h>

#include <addressbook/gui/widgets/eab-config.h>
#include <shell/e-shell.h>
#include <e-util/e-plugin-util.h>
#include <libecal/e-cal.h>
#include <libecal/e-cal-client.h>
#include <libedataserver/e-source.h>
#include <libedataserver/e-source-list.h>

#include <libekolab/kolab-types.h>
#include <libekolab/kolab-util-backend.h>
#include <libekolabutil/camel-system-headers.h>
#include <libekolabutil/kolab-util-camel.h>
#include <libekolabutil/kolab-util-folder.h>

#include "e-kolab-account-setup.h"

/*----------------------------------------------------------------------------*/

#define _KOLAB_CALENDAR_WIDGET "kolabcalendarwidget"
#define _KOLAB_CONTACT_WIDGET "kolabcontactwidget"
#define KOLAB_EPLUGIN_WIDGET_NAME "Evolution-Kolab EPlugin"

enum {
	NAME_COL,
	FID_COL,
	FOLDER_COL,
	NUM_COLS
};

typedef struct {
	ESource *source;
	gboolean is_new;
	GtkWidget *kolab_box;
	GtkComboBoxText *kolab_accounts_avail;
	GtkEntry *kolab_servername;
	GtkEntry *kolab_username;
	GtkComboBoxText *kolab_folders_avail;
	GtkButton *retrieve_folder_list;
	GtkEntry *kolab_foldername;
	GtkComboBoxText *kolab_conflict_strategy;
	GtkComboBoxText *encryption_method;
	GtkCheckButton *require_pkcs11_infrastructure;
	GtkEntry *pkcs11_pin;
} kolab_ui_data;

/*----------------------------------------------------------------------------*/
/* internal statics (non-UI) */

static void
ensure_kolab_sourcetype_source_group (const gchar *backendname)
{
	EShellBackend *backend = NULL;
	ESourceList *source_list = NULL;

	backend = e_shell_get_backend_by_name (e_shell_get_default (),
	                                       backendname);
	g_return_if_fail (backend != NULL);

	g_object_get (G_OBJECT (backend), "source-list", &source_list, NULL);
	g_return_if_fail (source_list != NULL);

	e_source_list_ensure_group (source_list,
	                            KOLAB_CAMEL_PROVIDER_NAME,
	                            KOLAB_CAMEL_URI_PREFIX,
	                            FALSE);

	g_object_unref (source_list);
}

/*----------------------------------------------------------------------------*/
/* internal statics (UI) */

static void
destroy_ui_data (gpointer data)
{
	kolab_ui_data *ui = (kolab_ui_data*) data;

	if (ui && ui->kolab_box)
		gtk_widget_destroy (ui->kolab_box);

	g_free (ui);
}

static void
set_ui_from_source (kolab_ui_data *uidata)
{
	ESource *source = NULL;
	gchar *kolab_uri = NULL;
	const gchar *path = NULL;
	const gchar *sync_prop = NULL;
	const gchar *enc_prop = NULL;
	const gchar *req_pkcs11_prop = NULL;
	const gchar *pin_prop = NULL;
	KolabSyncStrategyID sync_value = KOLAB_SYNC_STRATEGY_DEFAULT;
	KolabTLSVariantID enc_value = KOLAB_TLS_VARIANT_DEFAULT;
	KolabReqPkcs11 req_pkcs11_value;
	CamelURL *c_url = NULL;
	GError *tmp_error = NULL;

	g_return_if_fail ((uidata != NULL) && (uidata->source != NULL));

	source = uidata->source;

	kolab_uri = e_source_get_uri (source);
	sync_prop = e_source_get_property (source, KOLAB_SYNC_STRATEGY_PROP);
	enc_prop = e_source_get_property (source, KOLAB_TLS_VARIANT_PROP);
	sync_value = kolab_util_misc_sync_value_from_property (sync_prop);
	enc_value = kolab_util_misc_tls_variant_from_property (enc_prop);
	req_pkcs11_prop = e_source_get_property (source, KOLAB_REQ_PKCS11_PROP);
	req_pkcs11_value = kolab_util_misc_req_pkcs11_from_property (req_pkcs11_prop);
	pin_prop = e_source_get_property (source, KOLAB_PKCS11_PIN_PROP);

	c_url = camel_url_new (kolab_uri, &tmp_error);
	if (c_url == NULL) {
		g_warning ("%s()[%u] error: %s",
		           __func__, __LINE__, tmp_error->message);
		g_error_free (tmp_error);
		return;
	}

	if (c_url == NULL)
		goto cleanup;

	if ((c_url->path != NULL) && (c_url->path[0] == '/'))
		path = c_url->path+1;
	else
		path = c_url->path;

	if (c_url->host != NULL)
		gtk_entry_set_text (uidata->kolab_servername, c_url->host);
	if (path != NULL)
		gtk_entry_set_text (uidata->kolab_foldername, path);
	if (c_url->user != NULL)
		gtk_entry_set_text (uidata->kolab_username, c_url->user);
	gtk_combo_box_set_active (GTK_COMBO_BOX (uidata->encryption_method), enc_value);
	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (uidata->require_pkcs11_infrastructure), req_pkcs11_value);
	if (pin_prop != NULL)
		gtk_entry_set_text (uidata->pkcs11_pin, pin_prop);

	/* Encryption settings */
	if (uidata->is_new) {
		gtk_widget_set_sensitive (GTK_WIDGET (uidata->encryption_method), TRUE);
	}
	else {
		gtk_widget_set_sensitive (GTK_WIDGET (uidata->encryption_method), FALSE);
	}
	if (uidata->is_new && (enc_value > KOLAB_TLS_VARIANT_NONE)) {
		gtk_widget_set_sensitive (GTK_WIDGET (uidata->require_pkcs11_infrastructure), TRUE);
	}
	else {
		gtk_widget_set_sensitive (GTK_WIDGET (uidata->require_pkcs11_infrastructure), FALSE);
	}
	if (uidata->is_new
	    && (enc_value > KOLAB_TLS_VARIANT_NONE)
	    && (req_pkcs11_value == KOLAB_PKCS11_INFRASTRUCTURE_ENABLE)) {
		gtk_widget_set_sensitive (GTK_WIDGET (uidata->pkcs11_pin), TRUE);
	}
	else {
		gtk_widget_set_sensitive (GTK_WIDGET (uidata->pkcs11_pin), FALSE);
	}

	/* Options */
	gtk_combo_box_set_active (GTK_COMBO_BOX (uidata->kolab_conflict_strategy), sync_value);

 cleanup:
	g_free (kolab_uri);
	camel_url_free (c_url);
	return;
} /* set_ui_from_source () */

static void
set_source_from_ui (kolab_ui_data *uidata,
                    const gchar *authvalue)
{
	const gchar *servername = NULL;
	const gchar *foldername = NULL;
	const gchar *username = NULL;
	const gchar *auth = authvalue;
	const gchar *pin_prop = NULL;
	gchar *sync_prop = NULL;
	gchar *enc_prop = NULL;
	gchar *req_pkcs11_prop = NULL;
	gint sync_value;
	gint enc_value;
	gint req_pkcs11_value;
	gchar *kolab_uri = NULL;
	gchar *username_encoded = NULL;

	servername = gtk_entry_get_text (uidata->kolab_servername);
	foldername = gtk_entry_get_text (uidata->kolab_foldername);
	username = gtk_entry_get_text (uidata->kolab_username);
	sync_value = gtk_combo_box_get_active (GTK_COMBO_BOX (uidata->kolab_conflict_strategy));
	if (sync_value < 0) {
		/* No value set, defaulting to KOLAB_SYNC_STRATEGY_DEFAULT */
		sync_value = KOLAB_SYNC_STRATEGY_DEFAULT;
	}
	/* Treat sync_value as unsigned. */
	sync_prop = g_strdup_printf ("%u", sync_value);

	enc_value = gtk_combo_box_get_active (GTK_COMBO_BOX (uidata->encryption_method));
	if (enc_value < 0) {
		enc_value = KOLAB_TLS_VARIANT_DEFAULT;
	}
	enc_prop = g_strdup_printf ("%u", enc_value);

	req_pkcs11_value = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (uidata->require_pkcs11_infrastructure));
	if (enc_value < 0) {
		enc_value = KOLAB_PKCS11_INFRASTRUCTURE_DEFAULT;
	}
	req_pkcs11_prop = g_strdup_printf ("%u", req_pkcs11_value);
	if ((enc_value > KOLAB_TLS_VARIANT_NONE) && req_pkcs11_value) {
		pin_prop = gtk_entry_get_text (GTK_ENTRY (uidata->pkcs11_pin));
	}
	else {
		pin_prop = NULL;
	}

	/* Userinfo: Kolab acounts usually resemble the users complete email
	 * address. The URI part of an ESource requires the Userinfo, because
	 * someone might want to setup access to addressbooks/calendars of
	 * different accounts, which share the same name. E.g. the default
	 * calendar folder INBOX/calendar of account A and Account B.
	 * In the Userinfo we have to escape reserved characters.
	 */
	username_encoded = g_uri_escape_string (username, G_URI_RESERVED_CHARS_ALLOWED_IN_USERINFO, FALSE);
	kolab_uri = g_strdup_printf ("%s@%s/%s", username_encoded, servername, foldername);
	g_free (username_encoded);

	e_source_set_relative_uri (uidata->source, kolab_uri);

	e_source_set_property (uidata->source, "username", username);
	e_source_set_property (uidata->source, "auth", auth);
	e_source_set_property (uidata->source, KOLAB_SYNC_STRATEGY_PROP, sync_prop);
	e_source_set_property (uidata->source, KOLAB_TLS_VARIANT_PROP, enc_prop);
	e_source_set_property (uidata->source, KOLAB_REQ_PKCS11_PROP, req_pkcs11_prop);
	e_source_set_property (uidata->source, KOLAB_PKCS11_PIN_PROP, pin_prop);

	if (uidata->is_new && (enc_value > KOLAB_TLS_VARIANT_NONE)) {
		gtk_widget_set_sensitive (GTK_WIDGET (uidata->require_pkcs11_infrastructure), TRUE);
	}
	else {
		gtk_widget_set_sensitive (GTK_WIDGET (uidata->require_pkcs11_infrastructure), FALSE);
	}
	if (uidata->is_new
	    && (enc_value > KOLAB_TLS_VARIANT_NONE)
	    && (req_pkcs11_value == KOLAB_PKCS11_INFRASTRUCTURE_ENABLE)) {
		gtk_widget_set_sensitive (GTK_WIDGET (uidata->pkcs11_pin), TRUE);
	}
	else {
		gtk_widget_set_sensitive (GTK_WIDGET (uidata->pkcs11_pin), FALSE);
	}

	g_free (sync_prop);
	g_free (kolab_uri);
} /* set_source_from_ui () */

static void
set_contact_source_from_ui_cb (kolab_ui_data *uidata)
{
	set_source_from_ui (uidata, "plain/password");
}

static void
set_calendar_source_from_ui_cb (kolab_ui_data *uidata)
{
	set_source_from_ui (uidata, "true");
}

/*----------------------------------------------------------------------------*/
/* API functions (non-UI) */

/**
 * ensure_kolab_contacts_source_group:
 *
 * Ensures the existence of the kolab contacts source entry in Evolutions
 * source definitions.
 */
void
e_kolab_account_setup_ensure_calendar_source_groups (void)
{
	ensure_kolab_sourcetype_source_group ("calendar");
	ensure_kolab_sourcetype_source_group ("tasks");
	ensure_kolab_sourcetype_source_group ("memos");
}

void
e_kolab_account_setup_ensure_contacts_source_group (void)
{
	/* Find the original code in google-contacts-source.c. */
	ESourceList  *source_list = NULL;
	const gchar *key = NULL;

	key = "/apps/evolution/addressbook/sources";
	source_list = e_source_list_new_for_gconf_default (key);

	if (source_list == NULL)
		return;

	e_source_list_ensure_group (source_list,
	                            KOLAB_CAMEL_PROVIDER_NAME,
	                            KOLAB_CAMEL_URI_PREFIX, FALSE);
	g_object_unref (source_list);
}

/*----------------------------------------------------------------------------*/
/* API functions (UI) */

GtkWidget*
e_kolab_account_setup_backend_create (EPlugin *epl,
                                      EConfigHookItemFactoryData *data,
                                      KolabWidgetTypeID widget_type)
{
	EABConfigTargetSource *t = NULL;
	GtkWidget *parent = NULL;
	GtkWidget *real_parent = NULL;
	GtkWidget *vbox = NULL;
	GtkWidget *kolab_vbox = NULL;
	GtkWidget *hbox = NULL;
	GtkWidget *section = NULL;
	GtkWidget *spacer = NULL;
	GtkWidget *label = NULL;
	ESource *source = NULL;
	ESourceGroup *group = NULL;
	/* const gchar *base_uri = NULL; */
	kolab_ui_data *uidata = NULL;
	gchar *tmp_str = NULL;
	gint i = 0;

	g_assert (E_IS_PLUGIN (epl));
	g_assert (data != NULL);

	/* Have to check wether this is to be done for the appropriate backend... */

	t = (EABConfigTargetSource *) data->target;
	parent = data->parent;
	source = t->source;

	group = e_source_peek_group (source);
	/* base_uri = e_source_group_peek_base_uri (group); */

	g_object_set_data (G_OBJECT (epl), KOLAB_EPLUGIN_WIDGET_NAME, NULL);

	if (! e_plugin_util_is_group_proto (group, KOLAB_CAMEL_PROVIDER_PROTOCOL)) {
		/* TODO: cleanup needed */
		g_warning ("%s()[%u] Got wrong group protocol", __func__, __LINE__);
		return NULL;
	}

	uidata = g_new0 (kolab_ui_data, 1);
	uidata->source = source;
	uidata->is_new = TRUE;

	real_parent = gtk_widget_get_parent (parent);
	vbox = gtk_widget_get_ancestor (real_parent, GTK_TYPE_VBOX);

	kolab_vbox = gtk_vbox_new (FALSE, 6);
	gtk_box_pack_start (GTK_BOX (vbox), kolab_vbox, FALSE, FALSE, 0);

	/* Server section */
	section = gtk_label_new (NULL);
	tmp_str = g_strconcat ("<b>", _("Kolab Server Settings"), "</b>", NULL);
	gtk_label_set_markup (GTK_LABEL (section), tmp_str);
	g_free (tmp_str);
	gtk_misc_set_alignment (GTK_MISC (section), 0.0, 0.0);
	gtk_box_pack_start (GTK_BOX (kolab_vbox), section, FALSE, FALSE, 0);

	/* Pre-configured Kolab Mail accounts */
	hbox = gtk_hbox_new (FALSE, 10);
	gtk_box_pack_start (GTK_BOX (kolab_vbox), GTK_WIDGET (hbox), TRUE, TRUE, 0);
	spacer = gtk_label_new("   ");
	gtk_box_pack_start (GTK_BOX (hbox), spacer, FALSE, FALSE, 0);
	tmp_str = g_strconcat (_("Kolab Account"), ":", NULL);
	label = gtk_label_new_with_mnemonic (tmp_str);
	g_free (tmp_str);
	gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
	uidata->kolab_accounts_avail = GTK_COMBO_BOX_TEXT (gtk_combo_box_text_new ());
	gtk_box_pack_start (GTK_BOX (hbox), GTK_WIDGET (uidata->kolab_accounts_avail), TRUE, TRUE, 0);
	/* FIXME add Kolab accounts to GTK box */
	g_warning ("%s: FIXME add Kolab accounts to GTK box", __func__);
	gtk_combo_box_set_active (GTK_COMBO_BOX (uidata->kolab_accounts_avail), 0);

	/* Kolab server option */
	hbox = gtk_hbox_new (FALSE, 10);
	gtk_box_pack_start (GTK_BOX (kolab_vbox), GTK_WIDGET (hbox), TRUE, TRUE, 0);
	spacer = gtk_label_new("   ");
	gtk_box_pack_start (GTK_BOX (hbox), spacer, FALSE, FALSE, 0);
	tmp_str = g_strconcat (_("Kolab Server"), ":", NULL);
	label = gtk_label_new(tmp_str);
	g_free (tmp_str);
	gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
	uidata->kolab_servername = GTK_ENTRY(gtk_entry_new());
	gtk_box_pack_start (GTK_BOX (hbox), GTK_WIDGET (uidata->kolab_servername), TRUE, TRUE, 0);

	/* Kolab user name option */
	hbox = gtk_hbox_new (FALSE, 10);
	gtk_box_pack_start (GTK_BOX (kolab_vbox), GTK_WIDGET (hbox), TRUE, TRUE, 0);
	spacer = gtk_label_new("   ");
	gtk_box_pack_start (GTK_BOX (hbox), spacer, FALSE, FALSE, 0);
	tmp_str = g_strconcat (_("User ID"), ":", NULL);
	label = gtk_label_new_with_mnemonic (tmp_str);
	g_free (tmp_str);
	gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
	uidata->kolab_username = GTK_ENTRY(gtk_entry_new());
	gtk_box_pack_start (GTK_BOX (hbox), GTK_WIDGET (uidata->kolab_username), TRUE, TRUE, 0);

	/* Existing Kolab PIM type folders for selected account */
	hbox = gtk_hbox_new (FALSE, 10);
	gtk_box_pack_start (GTK_BOX (kolab_vbox), GTK_WIDGET (hbox), TRUE, TRUE, 0);
	spacer = gtk_label_new("   ");
	gtk_box_pack_start (GTK_BOX (hbox), spacer, FALSE, FALSE, 0);
	tmp_str = g_strconcat (_("Server PIM-Folders"), ":", NULL);
	label = gtk_label_new_with_mnemonic (tmp_str);
	g_free (tmp_str);
	gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
	uidata->kolab_folders_avail = GTK_COMBO_BOX_TEXT (gtk_combo_box_text_new ());
	gtk_box_pack_start (GTK_BOX (hbox), GTK_WIDGET (uidata->kolab_folders_avail), TRUE, TRUE, 0);
	/* FIXME add Kolab PIM folders to GTK box */
	g_warning ("%s: FIXME add Kolab PIM folders to GTK box", __func__);
	gtk_combo_box_set_active (GTK_COMBO_BOX (uidata->kolab_folders_avail), 0);
	uidata->retrieve_folder_list = GTK_BUTTON (gtk_button_new_with_label (_("Retrieve")));
	gtk_box_pack_start (GTK_BOX (hbox), GTK_WIDGET (uidata->retrieve_folder_list), FALSE, FALSE, 0);

	/* Kolab folder name option */
	hbox = gtk_hbox_new (FALSE, 10);
	gtk_box_pack_start (GTK_BOX (kolab_vbox), GTK_WIDGET (hbox), TRUE, TRUE, 0);
	spacer = gtk_label_new("   ");
	gtk_box_pack_start (GTK_BOX (hbox), spacer, FALSE, FALSE, 0);
	if (widget_type == KOLAB_WIDGET_TYPE_CONTACT)
		tmp_str = g_strconcat (_("Selected Contact Folder"), ":", NULL);
	else
		tmp_str = g_strconcat (_("Selected Calendar Folder"), ":", NULL);
	label = gtk_label_new_with_mnemonic (tmp_str);
	g_free (tmp_str);
	gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
	uidata->kolab_foldername = GTK_ENTRY(gtk_entry_new());
	gtk_box_pack_start (GTK_BOX (hbox), GTK_WIDGET (uidata->kolab_foldername), TRUE, TRUE, 0);

	/* Encryption setting */
	hbox = gtk_hbox_new (FALSE, 10);
	gtk_box_pack_start (GTK_BOX (kolab_vbox), GTK_WIDGET (hbox), TRUE, TRUE, 0);
	spacer = gtk_label_new("   ");
	gtk_box_pack_start (GTK_BOX (hbox), spacer, FALSE, FALSE, 0);
	tmp_str = g_strconcat (_("Encryption Method"), ":", NULL);
	label = gtk_label_new_with_mnemonic(tmp_str);
	g_free (tmp_str);
	gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
	uidata->encryption_method = GTK_COMBO_BOX_TEXT (gtk_combo_box_text_new ());
	gtk_box_pack_start (GTK_BOX (hbox), GTK_WIDGET (uidata->encryption_method), TRUE, TRUE, 0);
	for (i = KOLAB_TLS_FIRST_VARIANT; i < KOLAB_TLS_LAST_VARIANT; i++) {
		gtk_combo_box_text_append (uidata->encryption_method, NULL, kolab_util_backend_get_tls_variant_desc(i));
	}
	gtk_combo_box_set_active (GTK_COMBO_BOX (uidata->encryption_method), KOLAB_TLS_VARIANT_DEFAULT);

	/* PKCS #11 infrastructure initiation */
	hbox = gtk_hbox_new (FALSE, 10);
	gtk_box_pack_start (GTK_BOX (kolab_vbox), GTK_WIDGET (hbox), TRUE, TRUE, 0);
	spacer = gtk_label_new("   ");
	gtk_box_pack_start (GTK_BOX (hbox), spacer, FALSE, FALSE, 0);
	tmp_str = g_strconcat (_("PKCS #11 Infrastructure"), ":", NULL);
	label = gtk_label_new_with_mnemonic(tmp_str);
	g_free (tmp_str);
	gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
	uidata->require_pkcs11_infrastructure = GTK_CHECK_BUTTON (gtk_check_button_new_with_label ("PIN:"));
	gtk_box_pack_start (GTK_BOX (hbox), GTK_WIDGET (uidata->require_pkcs11_infrastructure), TRUE, TRUE, 0);
	uidata->pkcs11_pin = GTK_ENTRY (gtk_entry_new ());
	gtk_entry_set_visibility (uidata->pkcs11_pin, FALSE);
	gtk_box_pack_start (GTK_BOX (hbox), GTK_WIDGET (uidata->pkcs11_pin), TRUE, TRUE, 0);

	/* Options section */
	section = gtk_label_new (NULL);
	tmp_str = g_strconcat ("<b>", _("Kolab Folder Options"), "</b>", NULL);
	gtk_label_set_markup (GTK_LABEL (section), tmp_str);
	g_free (tmp_str);
	gtk_misc_set_alignment (GTK_MISC (section), 0.0, 0.0);
	gtk_box_pack_start (GTK_BOX (kolab_vbox), section, FALSE, FALSE, 0);

	hbox = gtk_hbox_new (FALSE, 10);
	gtk_box_pack_start (GTK_BOX (kolab_vbox), GTK_WIDGET (hbox), TRUE, TRUE, 0);
	spacer = gtk_label_new ("   ");
	gtk_box_pack_start (GTK_BOX (hbox), spacer, FALSE, FALSE, 0);
	tmp_str = g_strconcat (_("Conflict Solving Strategy"), ":", NULL);
	label = gtk_label_new_with_mnemonic (tmp_str);
	g_free (tmp_str);
	gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
	uidata->kolab_conflict_strategy = GTK_COMBO_BOX_TEXT (gtk_combo_box_text_new ());
	gtk_box_pack_start (GTK_BOX (hbox), GTK_WIDGET (uidata->kolab_conflict_strategy), TRUE, TRUE, 0);
	for (i = KOLAB_SYNC_FIRST_STRATEGY; i < KOLAB_SYNC_LAST_STRATEGY; i++) {
		gtk_combo_box_text_append (uidata->kolab_conflict_strategy, NULL, kolab_util_backend_get_sync_strategy_desc(i));
	}
	gtk_combo_box_set_active (GTK_COMBO_BOX (uidata->kolab_conflict_strategy), KOLAB_SYNC_STRATEGY_DEFAULT);

	if (e_source_get_property (source, KOLAB_SYNC_STRATEGY_PROP) != NULL) {
		uidata->is_new = FALSE;
		gtk_widget_set_sensitive (GTK_WIDGET (uidata->kolab_servername), FALSE);
		gtk_widget_set_sensitive (GTK_WIDGET (uidata->kolab_username), FALSE);
		gtk_widget_set_sensitive (GTK_WIDGET (uidata->kolab_foldername), FALSE);
	}

	set_ui_from_source (uidata);

	gtk_widget_show_all (kolab_vbox);

	uidata->kolab_box = kolab_vbox;
	g_object_set_data_full(G_OBJECT(epl), KOLAB_EPLUGIN_WIDGET_NAME, uidata, destroy_ui_data);
	g_signal_connect (uidata->kolab_box, "destroy", G_CALLBACK (gtk_widget_destroyed), &uidata->kolab_box);

	if (widget_type == KOLAB_WIDGET_TYPE_CONTACT) {
		g_signal_connect_swapped (G_OBJECT (uidata->kolab_username),
		                          "changed",
		                          G_CALLBACK (set_contact_source_from_ui_cb),
		                          uidata);
		g_signal_connect_swapped (G_OBJECT (uidata->kolab_foldername),
		                          "changed",
		                          G_CALLBACK (set_contact_source_from_ui_cb),
		                          uidata);
		g_signal_connect_swapped (G_OBJECT (uidata->kolab_servername),
		                          "changed",
		                          G_CALLBACK (set_contact_source_from_ui_cb),
		                          uidata);
		g_signal_connect_swapped (G_OBJECT (uidata->kolab_conflict_strategy),
		                          "changed",
		                          G_CALLBACK (set_contact_source_from_ui_cb),
		                          uidata);
		g_signal_connect_swapped (G_OBJECT (uidata->encryption_method),
		                          "changed",
		                          G_CALLBACK (set_contact_source_from_ui_cb),
		                          uidata);
		g_signal_connect_swapped (G_OBJECT (uidata->require_pkcs11_infrastructure),
		                          "toggled",
		                          G_CALLBACK (set_contact_source_from_ui_cb),
		                          uidata);
		g_signal_connect_swapped (G_OBJECT (uidata->pkcs11_pin),
		                          "changed",
		                          G_CALLBACK (set_contact_source_from_ui_cb),
		                          uidata);
		/* FIXME add signals for new widgets */
	} else {
		g_signal_connect_swapped (G_OBJECT (uidata->kolab_username),
		                          "changed",
		                          G_CALLBACK (set_calendar_source_from_ui_cb),
		                          uidata);
		g_signal_connect_swapped (G_OBJECT (uidata->kolab_foldername),
		                          "changed",
		                          G_CALLBACK (set_calendar_source_from_ui_cb),
		                          uidata);
		g_signal_connect_swapped (G_OBJECT (uidata->kolab_servername),
		                          "changed",
		                          G_CALLBACK (set_calendar_source_from_ui_cb),
		                          uidata);
		g_signal_connect_swapped (G_OBJECT (uidata->kolab_conflict_strategy),
		                          "changed",
		                          G_CALLBACK (set_calendar_source_from_ui_cb),
		                          uidata);
		g_signal_connect_swapped (G_OBJECT (uidata->encryption_method),
		                          "changed",
		                          G_CALLBACK (set_calendar_source_from_ui_cb),
		                          uidata);
		g_signal_connect_swapped (G_OBJECT (uidata->require_pkcs11_infrastructure),
		                          "toggled",
		                          G_CALLBACK (set_calendar_source_from_ui_cb),
		                          uidata);
		g_signal_connect_swapped (G_OBJECT (uidata->pkcs11_pin),
		                          "changed",
		                          G_CALLBACK (set_calendar_source_from_ui_cb),
		                          uidata);
		/* FIXME add signals for new widgets */
	}

	return NULL;
}

/*----------------------------------------------------------------------------*/
