/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
/*
 * incidence.c
 *
 *  Created on: 19/08/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 "../util.h"
#include "../logging.h"
#include "incidence.h"

/**
 * initialize I_incidence
 */
I_incidence*
new_i_incidence (void)
{
	I_incidence *incidence = g_new0 (I_incidence, 1);
	incidence->common = new_i_common();
	return incidence;
}

/**
 * Initialize recurrence
 */
Recurrence*
new_recurrence (void)
{
	return g_new0 (Recurrence, 1);
}

/**
 * Initialize alarm
 */
Alarm*
new_alarm (Alarm_type alarm_type)
{
	Alarm *alarm = g_new0 (Alarm, 1);
	alarm->type = alarm_type;

	if( alarm->type == I_ALARM_TYPE_PROCEDURE)
		alarm->proc_param = g_new0 (Proc_param, 1);
	else if( alarm->type == I_ALARM_TYPE_EMAIL)
		alarm->email_param = g_new0 (Email_param, 1 );

	return alarm;
}



/**
 * specific free function for I_contact objects
 */
void
free_i_incidence (I_incidence **i_incidence)
{
	if (i_incidence && *i_incidence) {
		I_incidence *ii = *i_incidence;

		free_i_common (&ii->common);

		G_STRING_FREE (ii->summary);
		G_STRING_FREE (ii->location);
		G_STRING_FREE (ii->organizer_display_name);
		G_STRING_FREE (ii->organizer_smtp_address);
		free_date_or_datetime (&ii->start_date);

		generic_g_list_free (&ii->advanced_alarm, free_alarm);
		free_recurrence (&ii->recurrence);
		generic_g_list_free (&ii->attendee, free_attendee);

		g_free(ii);

		*i_incidence = NULL;
	}
}

/**
 * specific free function for alarm objects
 */
void
free_alarm (void **data)
{
	if (data && *data) {
		Alarm *alm = (Alarm *)*data;

		/* optional !!! to check */
		if (alm->type == I_ALARM_TYPE_DISPLAY && alm->display_text!=NULL) {
			G_STRING_FREE (alm->display_text);
		} else if (alm->type == I_ALARM_TYPE_AUDIO && alm->audio_file!=NULL) {
			G_STRING_FREE (alm->audio_file);
		} else if (alm->type == I_ALARM_TYPE_PROCEDURE && alm->proc_param!=NULL) {
			free_proc_param(&alm->proc_param);
		} else if (alm->type == I_ALARM_TYPE_EMAIL && alm->email_param!=NULL) {
			free_email_param(&alm->email_param);
		}

		g_free(alm);

		*data = NULL;
	}
}

/**
 * specific free function for recurrence objects
 */
void
free_recurrence (Recurrence **recurrence)
{
	if (recurrence && *recurrence) {
		Recurrence *re = *recurrence;

		if (re->range_date!=NULL)
			g_date_free (re->range_date);
		/* g_free (re->range_date); */

		if (re->range_number!=NULL)
			g_free (re->range_number);

		/* TODO Free exclusion list. */
		/* generic_g_list_free (&re->exclusion, (void (*) (void **)) free_date_or_datetime); */

		g_free(re);
		*recurrence = NULL;
	}
}

/**
 * specific free function for attendee objects
 */
void
free_attendee (void **data)
{
	if (data && *data) {
		Attendee *att = (Attendee *)*data;

		G_STRING_FREE (att->display_name);
		G_STRING_FREE (att->smtp_address);
		g_free (att);

		*data = NULL;
	}
}

/**
 * specific free function for proc_param objects
 */
void
free_proc_param (Proc_param **proc_param)
{
	if (proc_param && *proc_param) {
		Proc_param *pp = *proc_param;

		G_STRING_FREE (pp->program);
		G_STRING_FREE (pp->arguments);

		g_free(pp);

		*proc_param = NULL;
	}
}

/**
 * specific free function for email_param objects
 */
void
free_email_param (Email_param **email_param)
{
	if (email_param && *email_param) {
		Email_param *ep = *email_param;

		generic_g_list_free (&ep->addresses, free_g_string);
		G_STRING_FREE (ep->subject);
		G_STRING_FREE (ep->mail_text);
		generic_g_list_free (&ep->attachments, free_g_string);

		g_free(ep);

		*email_param = NULL;
	}
}


#ifdef KOLABCONV_DEBUG
/**
 * print function for debugging
 */
static void
print_exclusion (const GList *exclusion)
{
	const GList *iter = exclusion;

	log_debug ("\n\tExclusion list: [ ");
	while (iter) {
		GDate *date = (GDate *) iter->data;

		if (date)
			log_debug ("%s", g_strdup_printf("%04d-%02d-%02d", date->year, date->month, date->day));

		iter = iter->next;
		if (iter)
			log_debug (", ");
	}
	log_debug (" ]");
}
#endif

#ifdef KOLABCONV_DEBUG
/**
 * print function for debugging
 */
static void
print_days_bit_field_list (gint day)
{
	if (!day)
		return;

	log_debug ("\n\tDay List: [ ");

	if (day & I_COMMON_MONDAY)
		log_debug ("monday");
	if (day & I_COMMON_TUESDAY)
		log_debug ("tuesday");
	if (day & I_COMMON_WEDNESDAY)
		log_debug ("wednesday");
	if (day & I_COMMON_THURSDAY)
		log_debug ("thursday");
	if (day & I_COMMON_FRIDAY)
		log_debug ("friday");
	if (day & I_COMMON_SATURDAY)
		log_debug ("saturday");
	if (day & I_COMMON_SUNDAY)
		log_debug ("sunday");
	log_debug (" ]");
}
#endif

#ifdef KOLABCONV_DEBUG
/**
 * only used in print recurrence... ?
 */
static gchar*
recurrence_cycle_to_string (Recurrence_cycle recurrence_cycle)
{
	switch (recurrence_cycle) {
	case I_REC_CYCLE_DAILY:
		return "daily";
	case I_REC_CYCLE_WEEKLY:
		return "weekly";
	case I_REC_CYCLE_MONTHLY_DAYNUMBER:
		return "Monthly Day_Number";
	case I_REC_CYCLE_MONTHLY_WEEKDAY:
		return "Monthly Week_Day";
	case I_REC_CYCLE_YEARLY_MONTHDAY:
		return "Yearly Month_Day";
	case I_REC_CYCLE_YEARLY_YEARDAY:
		return "Yearly Year_Day";
	case I_REC_CYCLE_YEARLY_WEEKDAY:
		return "Yearly Week_Day";
	default:
		return "undefined";
	}
}
#endif

#ifdef KOLABCONV_DEBUG
/**
 * print function for debugging
 */
static void
print_recurrence (const Recurrence *recurrence)
{
	log_debug ("\nRecurrence: ");

	if (recurrence) {
		log_debug ("\n\tCycle: %s", recurrence_cycle_to_string (recurrence->recurrence_cycle));
		if (recurrence->interval != -1)
			log_debug ("\n\tInterval %d", recurrence->interval);
		print_days_bit_field_list (recurrence->weekdays);
		if (recurrence->day_number != -1)
			log_debug ("\n\tDay Number: %d", recurrence->day_number);
		if (recurrence->month != I_COMMON_MONTH_NULL)
			log_debug ("\n\tMonth: %d", recurrence->month);
		/* log_debug ("\n\tRange: %s", convRangeTypeToString (recurrence)); */
		if (recurrence->exclusion)
			print_exclusion (recurrence->exclusion);
	} else
		log_debug ("NULL");
}
#endif

#ifdef KOLABCONV_DEBUG
/*
 * print function for debugging
 */
static void
print_attendee (const GList *attendee)
{
	const GList *iter = attendee;
	int i = 0;
	log_debug ("\nPrinting Attendee list: ");
	while (iter) {
		Attendee *attendee = ((Attendee *) iter->data);

		log_debug ("\n No.%d", (i + 1));
		log_debug ("\n\tDisplayName: %s", attendee->display_name->str);
		log_debug ("\n\tSmtpAddres: %s", attendee->smtp_address->str);
		log_debug ("\n\trequest_response: %s", (attendee->request_response == TRUE ? "true"
		                                        : "false"));
		log_debug ("\n\tinvitation_sent: %s", (attendee->invitation_sent == TRUE ? "true"
		                                       : "false"));
		log_debug ("\n\tStatus: %d", attendee->status);
		log_debug ("\n\tRole: %d\n", attendee->role);

		iter = iter->next;
		i++;
	}
}
#endif

#ifdef KOLABCONV_DEBUG
/*
 * print function for debugging
 */
static void
print_proc_param(Proc_param *proc_param)
{
	if (proc_param) {
		log_debug("\n\t\tProcedure Parameters: ");
		if (proc_param->program)
			log_debug( "\n\t\t\tProcedure: %s", proc_param->program->str);
		if (proc_param->program)
			log_debug("\n\t\t\tArguments: %s", proc_param->arguments->str);
	}
}
#endif

#ifdef KOLABCONV_DEBUG
/*
 * print function for debugging
 */
static void
print_email_param (Email_param *email_param )
{
	if (email_param) {
		log_debug("\n\t\tEmail Parameters: ");
		if( email_param->subject )
			log_debug( "\n\t\t\tSubject: %s", email_param->subject->str);
		if( email_param->mail_text )
			log_debug( "\n\t\t\tMail Text: %s", email_param->mail_text->str );
	}
}
#endif

#ifdef KOLABCONV_DEBUG
/*
 * print function for debugging
 */
static void
print_advanced_alarm_list(GList *adv_alarm_list)
{
	gint i=1;

	log_debug("\nAdvanced Alarms: ");

	while (adv_alarm_list) {
		Alarm *alarm = (Alarm *) adv_alarm_list->data;

		log_debug( "\n\tAlarm #%d:- \n\t\tType: %d", i, alarm->type);
		if (alarm->start_offset != 0)
			log_debug("\n\t\tStart offset: %d", alarm->start_offset);
		if (alarm->end_offset != 0)
			log_debug("\n\t\tEnd offset: %d", alarm->end_offset);
		if (alarm->repeat_count != 0)
			log_debug("\n\t\tRepeat Count: %d", alarm->repeat_count);
		if (alarm->repeat_interval != 0)
			log_debug("\n\t\tRepeat Interval: %d", alarm->repeat_interval);
		if (alarm->display_text)
			log_debug("\n\t\tDisplay Text: %s", alarm->display_text->str);
		if (alarm->audio_file)
			log_debug("\n\t\tAudio File: %s", alarm->audio_file->str);
		print_email_param(alarm->email_param);
		print_proc_param(alarm->proc_param);

		adv_alarm_list = adv_alarm_list->next;
	}
}
#endif

/*
 * print function for debugging
 */
void
print_incidence (const I_incidence *i_incidence)
{
#ifndef KOLABCONV_DEBUG
	(void)i_incidence;
#else
	if (i_incidence->common)
		print_i_common (i_incidence->common);
	if (i_incidence->summary)
		log_debug ("\nSummary: %s", i_incidence->summary->str);
	if (i_incidence->location)
		log_debug ("\nLocation: %s", i_incidence->location->str);
	if (i_incidence->organizer_display_name && i_incidence->organizer_smtp_address)
		log_debug ("\nOrganizer Display Name=%s, Smtp Address=%s",
		           i_incidence->organizer_display_name->str,
		           i_incidence->organizer_smtp_address->str);
	print_date_or_datetime (i_incidence->start_date, "Start Date");

	print_advanced_alarm_list( i_incidence->advanced_alarm );

	print_recurrence (i_incidence->recurrence);
	print_attendee (i_incidence->attendee);
#endif
}
