/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
/*
 * contact-i-to-e.c
 *
 *  Created on: 21.12.2010
 *      Author: Umer Kayani <u.kayani@tarent.de>,
 *              Hendrik Helwich <h.helwich@tarent.de>,
 *              Peter Neuhaus <p.neuhaus@tarent.de>,
 *      		Andreas Grau <a.grau@tarent.de>
 */

/*
 * 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 <libical/ical.h>

#include "priv-evolution.h"
#include "evolution.h"
#include "evolution-util.h"

#include "../kolab/priv-kolab.h"
#include "../kolab/kolab-constants.h"
#include "../kolab/kolab-util.h"

#include "../logging.h"
#include "../util.h"

/*
 * prototypes for static functions
 */
static void process_contact_i_to_e (EContact* e_contact, I_contact **i_contact);

static void add_binary_field_base64 (EContact *e_contact, Kolab_conv_mail_part *mpart);
static void add_hidden_field_base64 (EContact *e_contact, gchar* field_name, gchar *field_value, gint id);

static gint kolab_store_get_sub_id(GList **k_store_sublist, gpointer ptr);
static void kolab_store_add_id(I_contact *i_contact, gpointer ptr, GList **k_store_sublist,
                               EVCardAttribute *attr);
static void kolab_store_add_id_to_field(EContact *e_contact, EContactField ecf, I_contact *i_contact,
                                        gpointer ptr, GList **k_store_sublist);

static GList* phone_type_i_to_v(Icontact_phone_type i_phone_type);
static EContactField address_type_i_to_e(Icontact_address_type i_addr_type);

/**
 * Convert libekolabconv I_contact to Evolution EContact.
 */
EContact*
conv_I_contact_to_EContact (I_contact **icontact_ptr, GError** error)
{
	I_contact *icontact = NULL;
	EContact* eContact = NULL;

	g_return_val_if_fail (error == NULL || *error == NULL, NULL);

	log_debug ("\nconv_I_contact_to_EContact(): convert I_contact to EContact.");

	icontact = *icontact_ptr;
	/* error = NULL; */ /* what's that?! */

	if (icontact != NULL) {

		eContact = e_contact_new ();
		process_contact_i_to_e (eContact, icontact_ptr);

		return eContact;
	} else {
		log_debug ("\nError: Can't generate EContact from I_contact, iContact is NULL\n");
		return NULL;
	}
}

/**
 * Process neccessary steps for conversion
 */
static void
process_contact_i_to_e (EContact* e_contact, I_contact **i_contact)
{
	I_contact *icontact = *i_contact;
	/* This method assumes contact object is initialized */
	/* printContact( *i_contact ); */

	/**
	 * holds pointers of kolab_store (I_contact) elements which hold kolab
	 * xml sub notes (like an unknown xml element below the second phone
	 * element). The list index of the pointer defines the id of the written
	 * kolab store element.
	 */
	GList *k_store_sublist = NULL;

	EContactDate date;
	GList* list = NULL;
	Custom* custom_field = NULL;
	/* char paramName[20], intStr[5]; for adding hidden field for kolab_store */
	gint i = 0;
	gint max_evolution_im = 4; /* maximum instant messenger fields that can be handled by evolution, rest in kolab store */

	/* *****************************************************************SET NAME******************************************* */
	EContactName *name = g_new0(EContactName, 1);
	if (icontact->given_name != NULL)
		name->given = icontact->given_name->str;
	if (icontact->middle_names != NULL)
		name->additional = icontact->middle_names->str;
	if (icontact->last_name != NULL)
		name->family = icontact->last_name->str;
	if (icontact->suffix != NULL)
		name->suffixes = icontact->suffix->str;
	if (icontact->prefix != NULL)
		name->prefixes = icontact->prefix->str;
	e_contact_set (e_contact, E_CONTACT_NAME, name);
	g_free(name);

	if (icontact->full_name != NULL)
		e_contact_set (e_contact, E_CONTACT_FULL_NAME, icontact->full_name->str);
	if (icontact->nick_name != NULL)
		e_contact_set (e_contact, E_CONTACT_NICKNAME, icontact->nick_name->str);
	if (icontact->spouse_name != NULL)
		e_contact_set (e_contact, E_CONTACT_SPOUSE, icontact->spouse_name->str);

	/* following command is not possible because the id cannot be read later
	 * from the multivalue field "N":
	 */
	/* kolab_store_add_id_to_field(e_contact, E_CONTACT_NAME, icontact, (gpointer) KOLAB_STORE_PTR_CONTACT_NAME, &k_store_sublist); */

	/* *****************************************************************SET WEB FIELDS************************************* */
	if (icontact->web_page != NULL)
		e_contact_set (e_contact, E_CONTACT_HOMEPAGE_URL, icontact->web_page->str);
	if (icontact->free_busy_url != NULL)
		e_contact_set (e_contact, E_CONTACT_FREEBUSY_URL, icontact->free_busy_url->str);

	/* *****************************************************************SET ORGANIZATIONAL FIELDS************************** */
	if (icontact->organization != NULL)
		e_contact_set (e_contact, E_CONTACT_ORG, icontact->organization->str);
	if (icontact->department != NULL)
		e_contact_set (e_contact, E_CONTACT_ORG_UNIT, icontact->department->str);
	if (icontact->profession != NULL)
		e_contact_set (e_contact, E_CONTACT_ROLE, icontact->profession->str);
	if (icontact->job_title != NULL)
		e_contact_set (e_contact, E_CONTACT_TITLE, icontact->job_title->str);
	if (icontact->manager_name != NULL)
		e_contact_set (e_contact, E_CONTACT_MANAGER, icontact->manager_name->str);
	if (icontact->assistant != NULL)
		e_contact_set (e_contact, E_CONTACT_ASSISTANT, icontact->assistant->str);
	if (icontact->office_location != NULL)
		e_contact_set (e_contact, E_CONTACT_OFFICE, icontact->office_location->str);

	/* *****************************************************************SET BIRTHDAY*************************************** */
	if (icontact->birthday != NULL) {
		date.day = icontact->birthday->day;
		date.month = icontact->birthday->month;
		date.year = icontact->birthday->year;

		e_contact_set (e_contact, E_CONTACT_BIRTH_DATE, &date);
	}

	/* *****************************************************************SET ANNIVERSARY************************************ */
	if (icontact->anniversary != NULL) {
		date.day = icontact->anniversary->day;
		date.month = icontact->anniversary->month;
		date.year = icontact->anniversary->year;

		e_contact_set (e_contact, E_CONTACT_ANNIVERSARY, &date);
	}

	/* *****************************************************************SET PICTURE FIELDS********************************* */
	if (icontact->photo) {
		/* log_debug("\nPicture is set in eContact\n"); */

		EContactPhoto e_contact_photo;
		e_contact_photo.type = E_CONTACT_PHOTO_TYPE_INLINED;

		e_contact_photo.data.inlined.data = g_new0(guchar, icontact->photo->length);
		e_contact_photo.data.inlined.mime_type = g_new0(gchar, 100);

		memcpy (e_contact_photo.data.inlined.data, icontact->photo->data,
		        icontact->photo->length);
		e_contact_photo.data.inlined.length = icontact->photo->length;
		e_contact_photo.data.inlined.mime_type = g_strdup (icontact->photo->mime_type);
		e_contact_photo.data.uri = NULL;

		e_contact_set (e_contact, E_CONTACT_PHOTO, &e_contact_photo);
		g_free(e_contact_photo.data.inlined.mime_type);
		g_free(e_contact_photo.data.inlined.data);
		g_free(e_contact_photo.data.uri);
	}

	/* *****************************************************************SET PHONE****************************************** */
	for (list = g_list_first (icontact->phone_numbers); list != NULL; list = list->next) {
		Phone_number *phone = (Phone_number *)list->data;
		GList *vcard_types = phone_type_i_to_v(phone->type);

		EVCardAttribute *ph_number = e_vcard_attribute_new (NULL, EVC_TEL);
		EVCardAttributeParam* ph_param = e_vcard_attribute_param_new (EVC_TYPE);
		e_vcard_attribute_add_param(ph_number, ph_param);

		while (vcard_types != NULL) {
			e_vcard_attribute_param_add_value(ph_param, vcard_types->data);			/* set type */
			vcard_types = vcard_types->next;
		}

		e_vcard_attribute_add_value (ph_number, phone->number);					/* set number */
		kolab_store_add_id(icontact, (gpointer)phone, &k_store_sublist, ph_number);		/* set kolab store attributes */
		e_vcard_add_attribute(&e_contact->parent, ph_number);

		g_list_free(vcard_types);
	}

	/* *****************************************************************SET EMAIL****************************************** */
	list = NULL;
	list = g_list_first (icontact->emails);

	while (list != NULL && i < 4) {

		Email *email = (Email *)list->data;
		EContactField email_slot;

		if (i == 0)
			email_slot = E_CONTACT_EMAIL_1;
		else if (i == 1)
			email_slot = E_CONTACT_EMAIL_2;
		else if (i == 2)
			email_slot = E_CONTACT_EMAIL_3;
		else if (i == 3)
			email_slot = E_CONTACT_EMAIL_4;

		if (email->smtp_address && email->smtp_address->str) {
			e_contact_set (e_contact, email_slot, email->smtp_address->str);

			kolab_store_add_id_to_field(e_contact, email_slot, icontact, (gpointer) email, &k_store_sublist);
		}

		/* TODO: handle display-name properly (kolab-store?) */
#if 0
		if (((Email*) list->data)->display_name)
			addHiddenParamToExistingFieldInEcontact (eContact,
			                                         email_slot, "display-name",
			                                         ((Email*) list->data)->display_name->str);
#endif
		/* log_debug("\nEmail %d \n\tdisplay_name: %s, smtp_address: %s", (i), ((Email*)list->data)->display_name->str, ((Email*)list->data)->smtp_address->str); */

		i++;
		list = list->next;
	}

	/* *****************************************************************SET ADDRESSES************************************** */
	list = g_list_first (icontact->addresses);
	i = 0;

	while (list != NULL) {

		Address *i_address = ((Address*) list->data);

		EContactAddress *e_address = g_new0(EContactAddress, 1);

		e_address->street = NULL; e_address->po = NULL; e_address->locality = NULL;
		e_address->region = NULL; e_address->code = NULL; e_address->country = NULL;
		e_address->ext = NULL; e_address->address_format = NULL;

		if (i_address->street)
			e_address->street = g_strdup(i_address->street->str);
		if (i_address->pobox)
			e_address->po = g_strdup(i_address->pobox->str);
		if (i_address->locality)
			e_address->locality = g_strdup(i_address->locality->str);
		if (i_address->region)
			e_address->region = g_strdup(i_address->region->str);
		if (i_address->postal_code)
			e_address->code = g_strdup(i_address->postal_code->str);
		if (i_address->country)
			e_address->country = g_strdup(i_address->country->str);
		if (i_address->type) {
			EContactField ecf = address_type_i_to_e(i_address->type);
			e_contact_set (e_contact, ecf, e_address);
			/* put address-fields unknown by evolution into kolab-store */
			kolab_store_add_id_to_field(e_contact, ecf, icontact, (gpointer) i_address, &k_store_sublist);
		}

		e_contact_address_free(e_address);

		list = list->next;
	}

	/* print_addresses_from_econtact (eContact, "populateEContactFromIContact"); */

	/* *****************************************************************GEO************************************************ */
	if (icontact->latitude >= -90.0 && icontact->latitude <= 90.0
	    && icontact->longitude >= -180.0 && icontact->longitude <= 180.0) {
		/* if both degrees are set and their values are valid coordinate values, then set geo */
		EContactGeo geo;
		geo.latitude = icontact->latitude;
		geo.longitude = icontact->longitude;
		e_contact_set(e_contact, E_CONTACT_GEO, &geo);
	}


	/* *****************************************************************SET COMMON FIELDS************************************ */
	if (icontact->common != NULL) {
		if (icontact->common->uid != NULL)
			e_contact_set (e_contact, E_CONTACT_UID, icontact->common->uid->str);

		if (icontact->common->body != NULL)
			e_contact_set (e_contact, E_CONTACT_NOTE, icontact->common->body->str);

		if (icontact->common->categories != NULL)
			e_contact_set (e_contact, E_CONTACT_CATEGORIES, icontact->common->categories->str);


		if (icontact->common->creation_datetime != NULL
		    && icontact->common->creation_datetime->date_time != NULL) {

			EVCardAttribute *createdAttribute = NULL;
			struct tm *ts =	gmtime (icontact->common->creation_datetime->date_time);
			gchar *buf = g_new0(gchar, 21);
			strftime (buf, 21, "%Y-%m-%dT%H:%M:%SZ", ts);

			/* Create a new vcard attribute */
			createdAttribute = e_vcard_attribute_new (NULL, ICONTACT_KOLAB_CREATED);

			/* Add the vcard attribute to eContact */
			e_vcard_add_attribute_with_value ((EVCard *) e_contact, createdAttribute, buf);

			g_debug ("**** populateEContactFromIContact() X-KOLAB-CREATED: %s", buf);
			g_free (buf);
		}

		if (icontact->common->last_modified_datetime != NULL
		    && icontact->common->last_modified_datetime->date_time != NULL) {
			struct tm *ts = gmtime(icontact->common->last_modified_datetime->date_time);
			gchar *buf = g_new0(gchar, 21);
			strftime(buf, 21, "%Y-%m-%dT%H:%M:%SZ", ts);
			e_contact_set (e_contact, E_CONTACT_REV, buf);
			g_free(buf);
			g_debug ("**** populateEContactFromIContact() E_CONTACT_REV: %s", (gchar*) e_contact_get (e_contact, E_CONTACT_REV));
		}
	}

	/* *****************************************************************SET BINARY BASE 64 ENCODED FIELDS****************** */
	/* We add one binary base 64 encoded field for each element of extraAttachments GList in icontact */

	list = g_list_first (icontact->common->kolab_attachment_store);

	while (list != NULL) {
		/* log_debug("\nBinary Attachment No. %d is attached. \n", ++i); */

		Kolab_conv_mail_part *bin_att = ((Kolab_conv_mail_part *) list->data);
		add_binary_field_base64 (e_contact, bin_att);

		kolabconv_free_kmail_part((void **) &bin_att);

		list = list->next;
	}

	/* **************************************SET X-CUSTOM FIELDS (ALL IM fields and BlogFeed URL)*************************** */
	list = NULL;
	list = g_list_first (icontact->custom_list);
	i = 0;					/* count for written messenger fields */

	while (list != NULL) {
		custom_field = (Custom *) list->data;

		if (strcmp (custom_field->name->str, KLBX_CNT_X_CUSTOM_NAME_BLOGFEED) == 0) {		/* x-custom blogfeed */
			e_contact_set (e_contact, E_CONTACT_BLOG_URL, custom_field->value->str);
		}
		else if (strcmp (custom_field->name->str, KLBX_CNT_X_CUSTOM_NAME_ALL) == 0		/* x-custom im */
		         && i < max_evolution_im) {
			EVCardAttribute *im_field = NULL; /* attribute to write */

			/* save just elements that are available in evolution, put other in kolab store */
			if (strcmp (custom_field->app->str, KLBX_CNT_X_CUSTOM_APP_AIM) == 0) {		/* aim */
				im_field = e_vcard_attribute_new(NULL, EVC_X_AIM);
			}
			else if (strcmp (custom_field->app->str, KLBX_CNT_X_CUSTOM_APP_XMPP) == 0) {	/* jabber */
				im_field = e_vcard_attribute_new(NULL, EVC_X_JABBER);
			}
			else if (strcmp (custom_field->app->str, KLBX_CNT_X_CUSTOM_APP_YAHOO) == 0) {	/* yahoo */
				im_field = e_vcard_attribute_new(NULL, EVC_X_YAHOO);
			}
			else if (strcmp (custom_field->app->str, KLBX_CNT_X_CUSTOM_APP_GADUGADU) == 0) {/* gadu-gadu */
				im_field = e_vcard_attribute_new(NULL, EVC_X_GADUGADU);
			}
			else if (strcmp (custom_field->app->str, KLBX_CNT_X_CUSTOM_APP_MSN) == 0) {	/* msn */
				im_field = e_vcard_attribute_new(NULL, EVC_X_MSN);
			}
			else if (strcmp (custom_field->app->str, KLBX_CNT_X_CUSTOM_APP_ICQ) == 0) {	/* icq */
				im_field = e_vcard_attribute_new(NULL, EVC_X_ICQ);
			}
			else if (strcmp (custom_field->app->str, KLBX_CNT_X_CUSTOM_APP_GROUPWISE) == 0) {/* groupwise */
				im_field = e_vcard_attribute_new(NULL, EVC_X_GROUPWISE);
			}
			else if (strcmp (custom_field->app->str, KLBX_CNT_X_CUSTOM_APP_SKYPE) == 0) {	/* skype */
				im_field = e_vcard_attribute_new(NULL, EVC_X_SKYPE);
			} else {
				/* type not found */
				xmlNodePtr store_node = NULL;
				store_node = xmlNewNode(NULL, BAD_CAST KLBX_CNT_X_CUSTOM_LIST);
				add_property (store_node, "value", custom_field->value->str);
				add_property (store_node, "app", custom_field->app->str);
				add_property (store_node, "name", custom_field->name->str);
				i_kolab_store_add_xml_element((*i_contact)->common, (*i_contact)->common, store_node);
				xmlFree(store_node);
			}

			/* If there will be a mappable IRC field in Evolution some time, the value of one field has to be split
			 * in Adress and Network by delimiter sign  (\356\204\240).
			 * Kontact saves both in value field.
			 * Example:<x-custom value="IRC-AddressIRC-Network" app="messaging/irc" name="All" />
			 */

			if (im_field != NULL) {		/* if attribute not set mappable type found */
				EVCardAttributeParam* im_param = e_vcard_attribute_param_new (EVC_TYPE);
				e_vcard_attribute_add_param(im_field, im_param);
				e_vcard_attribute_param_add_value(im_param, "HOME");
				e_vcard_attribute_add_value(im_field, custom_field->value->str);
				e_vcard_add_attribute(&e_contact->parent, im_field);
				i++;
			}
		} else {
			xmlNodePtr store_node = NULL;
			store_node = xmlNewNode(NULL, BAD_CAST KLBX_CNT_X_CUSTOM_LIST);
			add_property (store_node, "value", custom_field->value->str);
			add_property (store_node, "app", custom_field->app->str);
			add_property (store_node, "name", custom_field->name->str);
			i_kolab_store_add_xml_element((*i_contact)->common, (*i_contact)->common, store_node);
			log_debug ("\nCustom field (%s) saved in kolab store, not available in Evolution. \n",	custom_field->app->str);
			xmlFree(store_node);
		}

		/* log_debug("\nApp=%s, Value=%s, Name=%s\n", custom_field->app->str, custom_field->value->str, custom_field->name->str); */

		list = list->next;
	}

	i_evo_store_get_all_contact(icontact->common, e_contact);

	/* *************************************SET KOLAB STORE AS A HIDDEN FIELD IN EVOLUTION********************************* */
	list = NULL;
	if (icontact->common->kolab_store) {
		/* Add a param in kolab_store for each element in the list icontact->kolab_store */
		list = kolab_store_get_element_list(icontact->common, icontact->common);
		for (list = g_list_last (list); list != NULL; list = list->prev)
			add_hidden_field_base64 (e_contact,
			                         ICONTACT_KOLAB_STORE,
			                         ((gchar *) list->data), -1);

		/* add kolab store elements with a constant id (name) */

		list = kolab_store_get_element_list(icontact->common, (gpointer) KOLAB_STORE_PTR_CONTACT_NAME);
		for (list = g_list_last (list); list != NULL; list = list->prev)
			add_hidden_field_base64 (e_contact,
			                         ICONTACT_KOLAB_STORE,
			                         ((gchar *) list->data), KOLAB_STORE_PTR_CONTACT_NAME);

		/* add kolab store elements which are referred by id */

		i = 0;
		for (; k_store_sublist != NULL; k_store_sublist = k_store_sublist->next) {

			list = kolab_store_get_element_list(icontact->common, k_store_sublist->data);
			for (; list != NULL; list = list->next)
				add_hidden_field_base64 (e_contact,
				                         ICONTACT_KOLAB_STORE,
				                         ((gchar *) list->data), i);
			i++;
		}
	}
	free_i_contact(i_contact);
}

/**
 * Add the given mail part as hidden custom attribute to the vCard which is
 * wrapped in the given EContact.
 *
 * @param  e_contact
 *         an Evolution contact object which wraps a vCard.
 * @param  mpart
 *         a Kolab XML mail part which will be added to the vCard
 */
static void
add_binary_field_base64 (EContact *e_contact, Kolab_conv_mail_part *mpart)
{
	/* Create a new vcard attribute */
	EVCardAttribute *bin_attr = e_vcard_attribute_new (NULL, ICONTACT_KOLAB_STORE_ATTACHMENT);

	/* Add a encoding parameter to vcard attribute to make it base 64 encoded */
	e_vcard_attribute_add_param_with_value (bin_attr, e_vcard_attribute_param_new (
		         EVC_ENCODING), "BASE64");

	/* Add a mime_type parameter to vcard attribute. */
	if (mpart->mime_type)
		e_vcard_attribute_add_param_with_value (bin_attr, e_vcard_attribute_param_new (
			         ICONTACT_KOLAB_STORE_ATTACHMENT_MTYPE), mpart->mime_type);

	/* Add a mime_type parameter to vcard attribute. */
	if (mpart->name)
		e_vcard_attribute_add_param_with_value (bin_attr, e_vcard_attribute_param_new (
			         ICONTACT_KOLAB_STORE_ATTACHMENT_NAME), mpart->name);

	/* Add binary data to the attribute */
	e_vcard_attribute_add_value_decoded (bin_attr, mpart->data, (gint)mpart->length);

	/* Add the vcard attribute to eContact */
	e_vcard_add_attribute ((EVCard *) e_contact, bin_attr);
}

/**
 * Add a hidden filed to the vCard which is wrapped in the given EContact.
 */
static void
add_hidden_field_base64 (EContact *e_contact, gchar* field_name, gchar *field_value, gint id)
{
	EVCardAttribute *attrib = e_vcard_attribute_new (NULL, field_name);

	if (id >= 0) {
		EVCardAttributeParam *param = e_vcard_attribute_param_new (ICONTACT_KOLAB_STORE_ID);
		gchar id_str[5];
		sprintf (id_str, "%i", id);
		e_vcard_attribute_param_add_value(param, id_str);
		e_vcard_attribute_add_param(attrib, param);
	}

	e_vcard_attribute_add_param_with_value  (attrib, e_vcard_attribute_param_new (EVC_ENCODING), "BASE64");
	e_vcard_attribute_add_value_decoded ( attrib, field_value, (gint) strlen( field_value ));
	e_vcard_add_attribute ( (EVCard *)e_contact, attrib);
}

/**
 * Returns the position of the given pointer in the given list. If the pointer
 * is not part of the list it will be added to it.
 */
static gint
kolab_store_get_sub_id(GList **k_store_sublist, gpointer ptr)
{
	gint idx = g_list_index(*k_store_sublist, ptr);
	if (idx == -1) { /* element is not found */
		idx = (gint) g_list_length(*k_store_sublist);
		*k_store_sublist = g_list_append(*k_store_sublist, ptr);
	}
	return idx;
}

/**
 * Adds an id pointer to the given vcard attribute to indicate that it should
 * hold the kolab store element with the same id.
 */
static void
kolab_store_add_id(I_contact *i_contact, gpointer ptr, GList **k_store_sublist,
                   EVCardAttribute *attr)
{
	GList *list = kolab_store_get_element_list(i_contact->common, ptr);
	if (list != NULL) {
		gint id = kolab_store_get_sub_id(k_store_sublist, ptr);
		EVCardAttributeParam *param = e_vcard_attribute_param_new (ICONTACT_KOLAB_STORE_ID);
		gchar id_str[5];
		sprintf (id_str, "%i", id);
		e_vcard_attribute_param_add_value(param, id_str);
		e_vcard_attribute_add_param(attr, param);
	}
}


/**
 * Adds a kolab store id parameter to the vcard attribute which is represented
 * by the given EContact field identifier.
 */
static void
kolab_store_add_id_to_field(EContact *e_contact, EContactField ecf, I_contact *i_contact, gpointer ptr, GList **k_store_sublist)
{
	GList *attrs = e_contact_get_attributes (e_contact, ecf);
	EVCardAttribute *attr =  attrs->data;
	kolab_store_add_id(i_contact, ptr, k_store_sublist, attr);
	e_contact_set_attributes (e_contact, ecf, attrs);
	g_list_free(attrs);
}


/**
 * map icontact phone type to vcard phone type
 */
static GList*
phone_type_i_to_v(Icontact_phone_type i_phone_type)
{
	GList *vcard_types = NULL;

	if (i_phone_type == ICONTACT_PHONE_PRIMARY) {	/* one param value */
		vcard_types = g_list_append(vcard_types, (gchar*)"PREF");
	}
	else if (i_phone_type == ICONTACT_PHONE_ASSISTANT) {
		vcard_types = g_list_append(vcard_types, EVC_X_ASSISTANT);
	}
	else if (i_phone_type == ICONTACT_PHONE_CALLBACK) {
		vcard_types = g_list_append(vcard_types, EVC_X_CALLBACK);
	}
	else if (i_phone_type == ICONTACT_PHONE_CAR) {
		vcard_types = g_list_append(vcard_types, (gchar*)"CAR");
	}
	else if (i_phone_type == ICONTACT_PHONE_COMPANY) {
		vcard_types = g_list_append(vcard_types, (gchar*)"X-EVOLUTION-COMPANY");
	}
	else if (i_phone_type == ICONTACT_PHONE_ISDN) {
		vcard_types = g_list_append(vcard_types, (gchar*)"ISDN");
	}
	else if (i_phone_type == ICONTACT_PHONE_MOBILE) {
		vcard_types = g_list_append(vcard_types, (gchar*)"CELL");
	}
	else if (i_phone_type == ICONTACT_PHONE_PAGER) {
		vcard_types = g_list_append(vcard_types, (gchar*)"PAGER");
	}
	else if (i_phone_type == ICONTACT_PHONE_RADIO) {
		vcard_types = g_list_append(vcard_types, EVC_X_RADIO);
	}
	else if (i_phone_type == ICONTACT_PHONE_TELEX) {
		vcard_types = g_list_append(vcard_types, EVC_X_TELEX);
	}
	else if (i_phone_type == ICONTACT_PHONE_TTYTDD) {
		vcard_types = g_list_append(vcard_types, EVC_X_TTYTDD);
	}
	else if (i_phone_type == ICONTACT_PHONE_OTHER) {
		vcard_types = g_list_append(vcard_types, (gchar*)"VOICE");
	}
	else if (i_phone_type == ICONTACT_PHONE_HOME_1) { /* two param values */
		vcard_types = g_list_append(vcard_types, (gchar*)"HOME");
		vcard_types = g_list_append(vcard_types, (gchar*)"VOICE");
	}
	else if (i_phone_type == ICONTACT_PHONE_HOME_FAX) {
		vcard_types = g_list_append(vcard_types, (gchar*)"HOME");
		vcard_types = g_list_append(vcard_types, (gchar*)"FAX");
	}
	else if (i_phone_type == ICONTACT_PHONE_BUSINESS_1) {
		vcard_types = g_list_append(vcard_types, (gchar*)"WORK");
		vcard_types = g_list_append(vcard_types, (gchar*)"VOICE");
	}
	else if (i_phone_type == ICONTACT_PHONE_BUSINESS_FAX) {
		vcard_types = g_list_append(vcard_types, (gchar*)"WORK");
		vcard_types = g_list_append(vcard_types, (gchar*)"FAX");
	} else	{ /* default */
		vcard_types = g_list_append(vcard_types, (gchar*)"PREF");
	}

	return vcard_types;
}

/**
 * convert I_contact address type to EContact address type
 */
static EContactField
address_type_i_to_e(Icontact_address_type i_addr_type)
{
	switch (i_addr_type) {
	case ICONTACT_ADDR_TYPE_HOME:
		return E_CONTACT_ADDRESS_HOME;
	case ICONTACT_ADDR_TYPE_BUSINESS:
		return E_CONTACT_ADDRESS_WORK;
	case ICONTACT_ADDR_TYPE_OTHER:
	default:
		return E_CONTACT_ADDRESS_OTHER;
	}
}
