/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
/*
 * contact.c
 *
 *  Created on: 01.07.2010
 *      Author: Umer Kayani <u.kayani@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 <ctype.h>
#include <glib.h>
#include "common.h"
#include "contact.h"
#include "../util.h"
#include "../logging.h"

/**
 * initalize Address
 */
Address*
new_address (void)
{
	return (Address *) g_new0(Address, 1);
}

/**
 * initialize I_contact
 */
I_contact*
new_i_contact (void)
{
	I_contact* i_contact = g_new0(I_contact, 1);

	i_contact->common = g_new0(I_common, 1);

	i_contact->latitude = DEGREE_NOT_SET;
	i_contact->longitude = DEGREE_NOT_SET;

	return i_contact;
}


/**
 * specific free function for Address objects
 */
void
free_address (void **data)
{
	if (data && *data) {
		Address *add = (Address *)*data;

		G_STRING_FREE (add->street);
		G_STRING_FREE (add->pobox);
		G_STRING_FREE (add->locality);
		G_STRING_FREE (add->region);
		G_STRING_FREE (add->postal_code);
		G_STRING_FREE (add->country);

		g_free (add);
		*data = NULL;
	}
}


/**
 * specific free function for Custom objects
 */
void
free_custom (void **data)
{
	if (data && *data) {
		Custom *cust = (Custom *)*data;

		G_STRING_FREE (cust->app);
		G_STRING_FREE (cust->name);
		G_STRING_FREE (cust->value);

		g_free (cust);
		*data = NULL;
	}
}

/**
 * specific free function for Email objects
 */
void
free_email (void **data)
{
	if (data && *data) {
		Email *email = (Email *)*data;

		G_STRING_FREE (email->display_name);
		G_STRING_FREE (email->smtp_address);

		g_free(email);
		*data = NULL;
	}
}

/**
 * specific free function for Phone_number objects
 */
void
free_phone_number (void **data)
{
	if (data && *data) {
		Phone_number *phone = (Phone_number *)*data;

		if (phone->number != NULL)
			g_free(phone->number);

		g_free (phone);
		*data = NULL;
	}
}

/**
 * specific free function for I_contact objects
 */
void
free_i_contact (I_contact **i_contact)
{
	if (i_contact && *i_contact) {
		I_contact *ic = *i_contact;
		free_i_common (&ic->common);

		G_STRING_FREE (ic->given_name);
		G_STRING_FREE (ic->middle_names);
		G_STRING_FREE (ic->last_name);
		G_STRING_FREE (ic->full_name);
		G_STRING_FREE (ic->prefix);
		G_STRING_FREE (ic->suffix);

		G_STRING_FREE (ic->free_busy_url);
		G_STRING_FREE (ic->organization);
		G_STRING_FREE (ic->web_page);
		G_STRING_FREE (ic->department);
		G_STRING_FREE (ic->office_location);
		G_STRING_FREE (ic->profession);
		G_STRING_FREE (ic->job_title);
		G_STRING_FREE (ic->manager_name);
		G_STRING_FREE (ic->assistant);

		G_STRING_FREE (ic->nick_name);
		G_STRING_FREE (ic->spouse_name);
		G_DATE_FREE (ic->birthday);
		G_DATE_FREE (ic->anniversary);

		/* G_STRING_FREE (ic->picture_name); */

		kolabconv_free_kmail_part((void **) &ic->photo);

		generic_g_list_free (&ic->phone_numbers, free_phone_number);
		generic_g_list_free (&ic->emails, free_email);
		generic_g_list_free (&ic->addresses, free_address);

		generic_g_list_free (&ic->custom_list, free_custom);

		g_free(ic);
		*i_contact = NULL;
	}
}



/* --------------------------- functions for debugging ------------------------------ */

/**
 * print data structure (for debugging)
 */
static void
print_addresses (I_contact *c)
{
#ifndef KOLABCONV_DEBUG
	(void)c;
#else
	GList* list = NULL;
	list = g_list_first (c->addresses);
	int i = 0;

	log_debug ("\n\nAddresses:");
	while (list != NULL) {
		log_debug ("\nAddress #: %d", ++i);

		if (((Address*) list->data)->type != ICONTACT_ADDR_TYPE_NULL)
			log_debug ("\n\ttype: %d", ((Address*) list->data)->type);
		if (((Address*) list->data)->street != NULL)
			log_debug ("\n\tstreet: %s", ((Address*) list->data)->street->str);
		if (((Address*) list->data)->pobox != NULL)
			log_debug ("\n\tpobox: %s", ((Address*) list->data)->pobox->str);
		if (((Address*) list->data)->locality != NULL)
			log_debug ("\n\tlocality: %s", ((Address*) list->data)->locality->str);
		if (((Address*) list->data)->region != NULL)
			log_debug ("\n\tregion: %s", ((Address*) list->data)->region->str);
		if (((Address*) list->data)->postal_code != NULL)
			log_debug ("\n\tpostal-code: %s", ((Address*) list->data)->postal_code->str);
		if (((Address*) list->data)->country != NULL)
			log_debug ("\n\tcountry: %s", ((Address*) list->data)->country->str);

		list = list->next;
	}
#endif
}

/**
 * print data structure (for debugging)
 */
static void
print_custom_fields (I_contact *c)
{
#ifndef KOLABCONV_DEBUG
	(void)c;
#else
	GList* list = NULL;
	list = g_list_first (c->custom_list);
	int i = 0;

	log_debug ("\n\nCustom Fields:");
	while (list != NULL) {
		log_debug ("\nCustom Field: %d \tValue=%s, App=%s, Name=%s", (++i),
		           ((Custom*) list->data)->value->str,
		           ((Custom*) list->data)->app->str,
		           ((Custom*) list->data)->name->str);
		list = list->next;
	}
#endif
}

/**
 * print data structure (for debugging)
 */
static void
print_phone_numbers (I_contact *c)
{
#ifndef KOLABCONV_DEBUG
	(void)c;
#else
	GList* list = NULL;
	list = g_list_first (c->phone_numbers);
	int i = 0;

	log_debug ("\n\nPhone_numbers:");
	while (list != NULL) {
		log_debug ("\nPhone %d \tType: %d, Phone: %s", (++i),
		           ((Phone_number*) list->data)->type,
		           ((Phone_number*) list->data)->number);
		list = list->next;
	}
#endif
}

/**
 * get gchar portion of GString, catch NULL pointer
 */
static gchar*
gstring_to_gchar(GString *gstring)
{
	return gstring ? gstring->str : "NULL";
}

/**
 * convenience function
 */
static void
append_str(GString *out, const gchar* name, GString *value)
{
	g_string_append_printf(out, "%s: %s\n", name, gstring_to_gchar(value));
}

/**
 * convenience function
 */
static void
append_emails(gpointer element_ptr, gpointer data)
{
	Email *email = element_ptr;
	GString *out = data;
	g_string_append(out, "email:\n");
	/* append_str(out, "  display_name", email->display_name); */
	append_str(out, "  smtp_address", email->smtp_address);
}


/**
 * print data structure (for debugging)
 */
void
print_contact (I_contact *c)
{
	/* log_debug ("\nPrinting contact object: \n"); */

	GString *out = g_string_sized_new(50);

	print_i_common (c->common);

	append_str(out, "given name", c->given_name);
	append_str(out, "middle_names", c->middle_names);
	append_str(out, "lastName", c->last_name);
	append_str(out, "fullName", c->full_name);

	if (c->middle_names != NULL)
		log_debug ("\nMiddle_names: %s", (c->middle_names)->str);
	if (c->last_name != NULL)
		log_debug ("\nLastName: %s", (c->last_name)->str);
	if (c->full_name != NULL)
		log_debug ("\nFullName: %s", (c->full_name)->str);
	if (c->prefix != NULL)
		log_debug ("\nPrefix: %s", (c->prefix)->str);
	if (c->suffix != NULL)
		log_debug ("\nSuffix: %s", (c->suffix)->str);
	if (c->free_busy_url != NULL)
		log_debug ("\nFreeBusyUrl: %s", (c->free_busy_url)->str);
	if (c->organization != NULL)
		log_debug ("\nOrganization: %s", (c->organization)->str);
	if (c->web_page != NULL)
		log_debug ("\nWebPage: %s", (c->web_page)->str);
	if (c->department != NULL)
		log_debug ("\nDepartment: %s", (c->department)->str);
	if (c->office_location != NULL)
		log_debug ("\nOfficeLocation: %s", (c->office_location)->str);
	if (c->profession != NULL)
		log_debug ("\nProfession: %s", (c->profession)->str);
	if (c->job_title != NULL)
		log_debug ("\nJob_title: %s", (c->job_title)->str);
	if (c->manager_name != NULL)
		log_debug ("\nManager_name: %s", (c->manager_name)->str);
	if (c->assistant != NULL)
		log_debug ("\nAssistant: %s", (c->assistant)->str);
	if (c->nick_name != NULL)
		log_debug ("\nNick_name: %s", (c->nick_name)->str);
	if (c->spouse_name != NULL)
		log_debug ("\nSpouse_name: %s", (c->spouse_name)->str);
	if (c->birthday != NULL)
		log_debug ("\nBirthday: %d-%d-%d", (c->birthday)->year, (c->birthday)->month, (c->birthday)->day);
	if (c->anniversary != NULL)
		log_debug ("\nAnniversary: %d-%d-%d", (c->anniversary)->year, (c->anniversary)->month, (c->anniversary)->day);
	if (c->photo->name != NULL)
		log_debug ("\nPictureAttachmentName: %s", c->photo->name);

	print_phone_numbers (c);

	g_list_foreach(c->emails, append_emails, out);
	g_debug("%s", out->str);

	print_addresses (c);
	print_custom_fields (c);

	if (c->photo->name) {
		log_debug ("\nPicture is set.");
	}
	if (c->common->kolab_attachment_store) {
		log_debug ("\nOther attachments are set.");
	}
}
