/* ICalComponent.c generated by valac 0.56.19, the Vala compiler
 * generated from ICalComponent.vala, do not modify */

/*
 * Copyright 2011-2020 elementary, Inc. (https://elementary.io)
 *
 * 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., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301 USA.
 */

#include "elementary-calendar.h"
#include <libical-glib/libical-glib.h>
#include <glib.h>

#if !defined(VALA_STRICT_C)
#if !defined(__clang__) && defined(__GNUC__) && (__GNUC__ >= 14)
#pragma GCC diagnostic warning "-Wincompatible-pointer-types"
#elif defined(__clang__) && (__clang_major__ >= 16)
#pragma clang diagnostic ignored "-Wincompatible-function-pointer-types"
#pragma clang diagnostic ignored "-Wincompatible-pointer-types"
#endif
#endif

#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))
#define _g_date_time_unref0(var) ((var == NULL) ? NULL : (var = (g_date_time_unref (var), NULL)))

/** Gets the start and end times of @component as {@link ICal.Time} objects.
     * 
     * This accounts for implicit end times by calculating its value from a
     * duration, if necessary.
     */
static gpointer
_g_object_ref0 (gpointer self)
{
	return self ? g_object_ref (self) : NULL;
}

void
calendar_util_icalcomponent_get_icaltimes (ICalComponent* component,
                                           ICalTime** dt_start,
                                           ICalTime** dt_end)
{
	ICalTime* _vala_dt_start = NULL;
	ICalTime* _vala_dt_end = NULL;
	ICalTime* _tmp0_;
	ICalTime* _tmp1_;
	ICalTime* _tmp2_;
	g_return_if_fail (component != NULL);
	_tmp0_ = i_cal_component_get_dtstart (component);
	_g_object_unref0 (_vala_dt_start);
	_vala_dt_start = _tmp0_;
	_tmp1_ = i_cal_component_get_dtend (component);
	_g_object_unref0 (_vala_dt_end);
	_vala_dt_end = _tmp1_;
	_tmp2_ = _vala_dt_end;
	if (i_cal_time_is_null_time (_tmp2_)) {
		ICalDuration* _tmp3_;
		ICalDuration* _tmp4_;
		gboolean _tmp5_;
		_tmp3_ = i_cal_component_get_duration (component);
		_tmp4_ = _tmp3_;
		_tmp5_ = !i_cal_duration_is_null_duration (_tmp4_);
		_g_object_unref0 (_tmp4_);
		if (_tmp5_) {
			ICalTime* _tmp6_;
			ICalDuration* _tmp7_;
			ICalDuration* _tmp8_;
			ICalTime* _tmp9_;
			_tmp6_ = _vala_dt_start;
			_tmp7_ = i_cal_component_get_duration (component);
			_tmp8_ = _tmp7_;
			_tmp9_ = i_cal_duration_extend (_tmp6_, _tmp8_);
			_g_object_unref0 (_vala_dt_end);
			_vala_dt_end = _tmp9_;
			_g_object_unref0 (_tmp8_);
		} else {
			ICalTime* _tmp10_;
			_tmp10_ = _vala_dt_start;
			if (i_cal_time_is_date (_tmp10_)) {
				ICalTime* _tmp11_;
				ICalTime* _tmp12_;
				ICalTime* _tmp13_;
				_tmp11_ = _vala_dt_start;
				_tmp12_ = i_cal_time_clone (_tmp11_);
				_g_object_unref0 (_vala_dt_end);
				_vala_dt_end = _tmp12_;
				_tmp13_ = _vala_dt_end;
				i_cal_time_adjust (_tmp13_, 1, 0, 0, 0);
			} else {
				ICalTime* _tmp14_;
				ICalTime* _tmp15_;
				_tmp14_ = _vala_dt_start;
				_tmp15_ = _g_object_ref0 (_tmp14_);
				_g_object_unref0 (_vala_dt_end);
				_vala_dt_end = _tmp15_;
			}
		}
	}
	if (dt_start) {
		*dt_start = _vala_dt_start;
	} else {
		_g_object_unref0 (_vala_dt_start);
	}
	if (dt_end) {
		*dt_end = _vala_dt_end;
	} else {
		_g_object_unref0 (_vala_dt_end);
	}
}

/** Gets a pair of {@link GLib.DateTime} objects representing the start and
     *  end of the given component, represented in the system time zone.
     *
     * The conversion behavior differs based on the type of {@link ICal.Time}.
     * DATE type times (which contain no time information) are represented as
     * midnight on the given date in the local timezone
     * (see {@link Calendar.Util.datetime_is_all_day}).
     * DATE-TIME type times are converted to the local timezone if they have
     * a time zone, and are represented at the given time in the local timezone
     * if they are floating.
     *
     * Note that unlike {@link icalcomponent_get_datetimes}, the
     * {@link GLib.TimeZone} contained in @start_date and @end_date is
     * guaranteed to be correct, since there is a well-defined local timezone
     * between both libical and GLib. For
     * more details, see {@link Calendar.Util.icaltime_to_local_datetime}.
     *
     * @see icalcomponent_get_datetimes
     */
void
calendar_util_icalcomponent_get_local_datetimes (ICalComponent* component,
                                                 GDateTime** start_date,
                                                 GDateTime** end_date)
{
	GDateTime* _vala_start_date = NULL;
	GDateTime* _vala_end_date = NULL;
	ICalTime* dt_start = NULL;
	ICalTime* dt_end = NULL;
	ICalTime* _tmp0_ = NULL;
	ICalTime* _tmp1_ = NULL;
	GDateTime* _tmp2_;
	GDateTime* _tmp3_;
	g_return_if_fail (component != NULL);
	calendar_util_icalcomponent_get_icaltimes (component, &_tmp0_, &_tmp1_);
	_g_object_unref0 (dt_start);
	dt_start = _tmp0_;
	_g_object_unref0 (dt_end);
	dt_end = _tmp1_;
	_tmp2_ = calendar_util_icaltime_to_local_datetime (dt_start);
	_g_date_time_unref0 (_vala_start_date);
	_vala_start_date = _tmp2_;
	_tmp3_ = calendar_util_icaltime_to_local_datetime (dt_end);
	_g_date_time_unref0 (_vala_end_date);
	_vala_end_date = _tmp3_;
	_g_object_unref0 (dt_end);
	_g_object_unref0 (dt_start);
	if (start_date) {
		*start_date = _vala_start_date;
	} else {
		_g_date_time_unref0 (_vala_start_date);
	}
	if (end_date) {
		*end_date = _vala_end_date;
	} else {
		_g_date_time_unref0 (_vala_end_date);
	}
}

/** Gets a pair of {@link GLib.DateTime} objects representing the start and
     *  end of the given component, represented in the time zone of @component.
     *
     * **Note:** the {@link GLib.TimeZone} data of @start_date and @end_date
     * is not guaranteed to be correct. You should never assume that the time
     * zone data contained in the resulting objects is correct. The intention
     * is that all time zone calculations should be done in libical directly,
     * where time zone data should be correct. This is because it's not
     * always possible to map a libical timezone to a GLib timezone. For
     * more details, see {@link Calendar.Util.icaltime_to_datetime}.
     *
     * @see icalcomponent_get_local_datetimes
     */
void
calendar_util_icalcomponent_get_datetimes (ICalComponent* component,
                                           GDateTime** start_date,
                                           GDateTime** end_date)
{
	GDateTime* _vala_start_date = NULL;
	GDateTime* _vala_end_date = NULL;
	ICalTime* dt_start = NULL;
	ICalTime* dt_end = NULL;
	ICalTime* _tmp0_ = NULL;
	ICalTime* _tmp1_ = NULL;
	GDateTime* _tmp2_;
	GDateTime* _tmp3_;
	g_return_if_fail (component != NULL);
	calendar_util_icalcomponent_get_icaltimes (component, &_tmp0_, &_tmp1_);
	_g_object_unref0 (dt_start);
	dt_start = _tmp0_;
	_g_object_unref0 (dt_end);
	dt_end = _tmp1_;
	_tmp2_ = calendar_util_icaltime_to_datetime (dt_start);
	_g_date_time_unref0 (_vala_start_date);
	_vala_start_date = _tmp2_;
	_tmp3_ = calendar_util_icaltime_to_datetime (dt_end);
	_g_date_time_unref0 (_vala_end_date);
	_vala_end_date = _tmp3_;
	_g_object_unref0 (dt_end);
	_g_object_unref0 (dt_start);
	if (start_date) {
		*start_date = _vala_start_date;
	} else {
		_g_date_time_unref0 (_vala_start_date);
	}
	if (end_date) {
		*end_date = _vala_end_date;
	} else {
		_g_date_time_unref0 (_vala_end_date);
	}
}

/** Wraps {@link icalcomponent_get_local_datetimes()}, including date
     *  adjustments for all-day events.
     *
     * Like {@link icalcomponent_get_local_datetimes()}, this gets a pair of
     * {@link GLib.DateTime} objects representing the start and end of the
     * given component.
     *
     * It differs in its handling of all-day events. According to
     * RFC 5545, their end time is exclusive, representing the day after the
     * last day the event occurs. To handle this, we must "fake" an earlier
     * date to replicate the expected experience of an inclusive end date.
     * It substracts a single day from the end time of all-day events. It leaves
     * other events unchanged.
     *
     * This should be used for user-facing display only. It breaks from spec to
     * make the display of all-day events more intuitive, and doesn't reflect
     * the actual times the events occur.
     *
     * This converts the resulting times to the local timezone. If you want to keep
     * the result in @component's timezone, use {@link icalcmponent_get_datetimes_for_display}.
     */
void
calendar_util_icalcomponent_get_local_datetimes_for_display (ICalComponent* component,
                                                             GDateTime** start_date,
                                                             GDateTime** end_date)
{
	GDateTime* _vala_start_date = NULL;
	GDateTime* _vala_end_date = NULL;
	GDateTime* _tmp0_ = NULL;
	GDateTime* _tmp1_ = NULL;
	GDateTime* _tmp2_;
	GDateTime* _tmp3_;
	g_return_if_fail (component != NULL);
	calendar_util_icalcomponent_get_local_datetimes (component, &_tmp0_, &_tmp1_);
	_g_date_time_unref0 (_vala_start_date);
	_vala_start_date = _tmp0_;
	_g_date_time_unref0 (_vala_end_date);
	_vala_end_date = _tmp1_;
	_tmp2_ = _vala_start_date;
	_tmp3_ = _vala_end_date;
	if (calendar_util_datetime_is_all_day (_tmp2_, _tmp3_)) {
		GDateTime* _tmp4_;
		GDateTime* _tmp5_;
		_tmp4_ = _vala_end_date;
		_tmp5_ = g_date_time_add_days (_tmp4_, -1);
		_g_date_time_unref0 (_vala_end_date);
		_vala_end_date = _tmp5_;
	}
	if (start_date) {
		*start_date = _vala_start_date;
	} else {
		_g_date_time_unref0 (_vala_start_date);
	}
	if (end_date) {
		*end_date = _vala_end_date;
	} else {
		_g_date_time_unref0 (_vala_end_date);
	}
}

/** Wraps {@link icalcomponent_get_datetimes()}, including date
     *  adjustments for all-day events.
     *
     * Like {@link icalcomponent_get_datetimes()}, this gets a pair of
     * {@link GLib.DateTime} objects representing the start and end of the
     * given component.
     *
     * It differs in its handling of all-day events. According to
     * RFC 5545, their end time is exclusive, representing the day after the
     * last day the event occurs. To handle this, we must "fake" an earlier
     * date to replicate the expected experience of an inclusive end date.
     * It substracts a single day from the end time of all-day events. It leaves
     * other events unchanged.
     *
     * This should be used for user-facing display only. It breaks from spec to
     * make the display of all-day events more intuitive, and doesn't reflect
     * the actual times the events occur.
     *
     * This keeps the resulting times in @component's timezone. If you want to convert
     * the result to local time, use {@link icalcmponent_get_local_datetimes_for_display}.
     */
void
calendar_util_icalcomponent_get_datetimes_for_display (ICalComponent* component,
                                                       GDateTime** start_date,
                                                       GDateTime** end_date)
{
	GDateTime* _vala_start_date = NULL;
	GDateTime* _vala_end_date = NULL;
	GDateTime* _tmp0_ = NULL;
	GDateTime* _tmp1_ = NULL;
	GDateTime* _tmp2_;
	GDateTime* _tmp3_;
	g_return_if_fail (component != NULL);
	calendar_util_icalcomponent_get_datetimes (component, &_tmp0_, &_tmp1_);
	_g_date_time_unref0 (_vala_start_date);
	_vala_start_date = _tmp0_;
	_g_date_time_unref0 (_vala_end_date);
	_vala_end_date = _tmp1_;
	_tmp2_ = _vala_start_date;
	_tmp3_ = _vala_end_date;
	if (calendar_util_datetime_is_all_day (_tmp2_, _tmp3_)) {
		GDateTime* _tmp4_;
		GDateTime* _tmp5_;
		_tmp4_ = _vala_end_date;
		_tmp5_ = g_date_time_add_days (_tmp4_, -1);
		_g_date_time_unref0 (_vala_end_date);
		_vala_end_date = _tmp5_;
	}
	if (start_date) {
		*start_date = _vala_start_date;
	} else {
		_g_date_time_unref0 (_vala_start_date);
	}
	if (end_date) {
		*end_date = _vala_end_date;
	} else {
		_g_date_time_unref0 (_vala_end_date);
	}
}

/** Returns whether the given icalcomponent overlaps with the time range.
     *
     * This is true if the icalcomponent either starts or ends within the range, even
     * if the entire icalcomponent doesn't happen within the range.
     */
gboolean
calendar_util_icalcomponent_is_in_range (ICalComponent* component,
                                         CalendarUtilDateRange* range)
{
	GDateTime* start = NULL;
	GDateTime* end = NULL;
	GDateTime* _tmp0_ = NULL;
	GDateTime* _tmp1_ = NULL;
	gint c1 = 0;
	GDateTime* _tmp2_;
	GDateTime* _tmp3_;
	GDateTime* _tmp4_;
	gint c2 = 0;
	GDateTime* _tmp5_;
	GDateTime* _tmp6_;
	GDateTime* _tmp7_;
	gint c3 = 0;
	GDateTime* _tmp8_;
	GDateTime* _tmp9_;
	GDateTime* _tmp10_;
	gint c4 = 0;
	GDateTime* _tmp11_;
	GDateTime* _tmp12_;
	GDateTime* _tmp13_;
	gboolean _tmp14_ = FALSE;
	gboolean _tmp15_ = FALSE;
	gboolean _tmp16_ = FALSE;
	gboolean _tmp17_ = FALSE;
	gboolean result;
	g_return_val_if_fail (component != NULL, FALSE);
	g_return_val_if_fail (range != NULL, FALSE);
	calendar_util_icalcomponent_get_local_datetimes (component, &_tmp0_, &_tmp1_);
	_g_date_time_unref0 (start);
	start = _tmp0_;
	_g_date_time_unref0 (end);
	end = _tmp1_;
	_tmp2_ = start;
	_tmp3_ = calendar_util_date_range_get_first_dt (range);
	_tmp4_ = _tmp3_;
	c1 = g_date_time_compare (_tmp2_, _tmp4_);
	_tmp5_ = start;
	_tmp6_ = calendar_util_date_range_get_last_dt (range);
	_tmp7_ = _tmp6_;
	c2 = g_date_time_compare (_tmp5_, _tmp7_);
	_tmp8_ = end;
	_tmp9_ = calendar_util_date_range_get_first_dt (range);
	_tmp10_ = _tmp9_;
	c3 = g_date_time_compare (_tmp8_, _tmp10_);
	_tmp11_ = end;
	_tmp12_ = calendar_util_date_range_get_last_dt (range);
	_tmp13_ = _tmp12_;
	c4 = g_date_time_compare (_tmp11_, _tmp13_);
	if (c1 <= 0) {
		_tmp14_ = c3 > 0;
	} else {
		_tmp14_ = FALSE;
	}
	if (_tmp14_) {
		result = TRUE;
		_g_date_time_unref0 (end);
		_g_date_time_unref0 (start);
		return result;
	}
	if (c2 < 0) {
		_tmp15_ = c4 > 0;
	} else {
		_tmp15_ = FALSE;
	}
	if (_tmp15_) {
		result = TRUE;
		_g_date_time_unref0 (end);
		_g_date_time_unref0 (start);
		return result;
	}
	if (c1 >= 0) {
		_tmp16_ = c2 < 0;
	} else {
		_tmp16_ = FALSE;
	}
	if (_tmp16_) {
		result = TRUE;
		_g_date_time_unref0 (end);
		_g_date_time_unref0 (start);
		return result;
	}
	if (c3 > 0) {
		_tmp17_ = c4 < 0;
	} else {
		_tmp17_ = FALSE;
	}
	if (_tmp17_) {
		result = TRUE;
		_g_date_time_unref0 (end);
		_g_date_time_unref0 (start);
		return result;
	}
	result = FALSE;
	_g_date_time_unref0 (end);
	_g_date_time_unref0 (start);
	return result;
}

gboolean
calendar_util_icalcomponent_is_multiday (ICalComponent* component)
{
	GDateTime* start = NULL;
	GDateTime* end = NULL;
	GDateTime* _tmp0_ = NULL;
	GDateTime* _tmp1_ = NULL;
	gboolean _tmp2_ = FALSE;
	GDateTime* _tmp3_;
	GDateTime* _tmp4_;
	gboolean result;
	g_return_val_if_fail (component != NULL, FALSE);
	calendar_util_icalcomponent_get_local_datetimes_for_display (component, &_tmp0_, &_tmp1_);
	_g_date_time_unref0 (start);
	start = _tmp0_;
	_g_date_time_unref0 (end);
	end = _tmp1_;
	_tmp3_ = start;
	_tmp4_ = end;
	if (g_date_time_get_year (_tmp3_) != g_date_time_get_year (_tmp4_)) {
		_tmp2_ = TRUE;
	} else {
		GDateTime* _tmp5_;
		GDateTime* _tmp6_;
		_tmp5_ = start;
		_tmp6_ = end;
		_tmp2_ = g_date_time_get_day_of_year (_tmp5_) != g_date_time_get_day_of_year (_tmp6_);
	}
	if (_tmp2_) {
		result = TRUE;
		_g_date_time_unref0 (end);
		_g_date_time_unref0 (start);
		return result;
	}
	result = FALSE;
	_g_date_time_unref0 (end);
	_g_date_time_unref0 (start);
	return result;
}

