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

/*
 * Copyright © 2025 Alain M. (https://github.com/alainm23/planify)
 *
 * 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 3 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
 *
 * Authored by: Alain M. <alainmh23@gmail.com>
 */

#include "chrono.h"
#include <glib.h>
#include <glib-object.h>
#include <stdlib.h>
#include <string.h>
#include <float.h>
#include <math.h>
#include <gee.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

enum  {
	CHRONO_EN_RECURRENCE_PARSER_0_PROPERTY,
	CHRONO_EN_RECURRENCE_PARSER_NUM_PROPERTIES
};
static GParamSpec* chrono_en_recurrence_parser_properties[CHRONO_EN_RECURRENCE_PARSER_NUM_PROPERTIES];
#define _g_regex_unref0(var) ((var == NULL) ? NULL : (var = (g_regex_unref (var), NULL)))
#define _g_error_free0(var) ((var == NULL) ? NULL : (var = (g_error_free (var), NULL)))
#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))
#define _g_match_info_unref0(var) ((var == NULL) ? NULL : (var = (g_match_info_unref (var), NULL)))
#define _g_free0(var) (var = (g_free (var), NULL))
#define _g_date_time_unref0(var) ((var == NULL) ? NULL : (var = (g_date_time_unref (var), NULL)))

struct _ChronoENRecurrenceParserPrivate {
	GRegex* basic_regex;
	GRegex* alias_regex;
	GRegex* time_of_day_regex;
	GRegex* weekday_regex;
	GRegex* ordinal_day_regex;
	GRegex* specific_date_regex;
	GRegex* hour_regex;
};

static gint ChronoENRecurrenceParser_private_offset;
static gpointer chrono_en_recurrence_parser_parent_class = NULL;

static ChronoParseResult* chrono_en_recurrence_parser_parse_hour (ChronoENRecurrenceParser* self,
                                                           const gchar* text,
                                                           GDateTime* reference_date);
static ChronoParseResult* chrono_en_recurrence_parser_parse_specific_date (ChronoENRecurrenceParser* self,
                                                                    const gchar* text,
                                                                    GDateTime* reference_date);
static ChronoParseResult* chrono_en_recurrence_parser_parse_ordinal_day (ChronoENRecurrenceParser* self,
                                                                  const gchar* text,
                                                                  GDateTime* reference_date);
static ChronoParseResult* chrono_en_recurrence_parser_parse_time_of_day (ChronoENRecurrenceParser* self,
                                                                  const gchar* text,
                                                                  GDateTime* reference_date);
static ChronoParseResult* chrono_en_recurrence_parser_parse_weekday (ChronoENRecurrenceParser* self,
                                                              const gchar* text,
                                                              GDateTime* reference_date);
static ChronoParseResult* chrono_en_recurrence_parser_parse_alias (ChronoENRecurrenceParser* self,
                                                            const gchar* text,
                                                            GDateTime* reference_date);
static ChronoParseResult* chrono_en_recurrence_parser_parse_basic (ChronoENRecurrenceParser* self,
                                                            const gchar* text,
                                                            GDateTime* reference_date);
static ChronoParseResult* chrono_en_recurrence_parser_create_result (ChronoENRecurrenceParser* self,
                                                              GMatchInfo* match_info,
                                                              GDateTime* reference_date,
                                                              ChronoRecurrenceType type,
                                                              gint interval);
static void chrono_en_recurrence_parser_finalize (GObject * obj);
static GType chrono_en_recurrence_parser_get_type_once (void);

static inline gpointer
chrono_en_recurrence_parser_get_instance_private (ChronoENRecurrenceParser* self)
{
	return G_STRUCT_MEMBER_P (self, ChronoENRecurrenceParser_private_offset);
}

ChronoENRecurrenceParser*
chrono_en_recurrence_parser_construct (GType object_type)
{
	ChronoENRecurrenceParser * self = NULL;
	GError* _inner_error0_ = NULL;
	self = (ChronoENRecurrenceParser*) g_object_new (object_type, NULL);
	{
		GRegex* _tmp0_ = NULL;
		GRegex* _tmp1_;
		GRegex* _tmp2_;
		GRegex* _tmp3_ = NULL;
		GRegex* _tmp4_;
		GRegex* _tmp5_;
		GRegex* _tmp6_ = NULL;
		GRegex* _tmp7_;
		GRegex* _tmp8_;
		GRegex* _tmp9_ = NULL;
		GRegex* _tmp10_;
		GRegex* _tmp11_;
		GRegex* _tmp12_ = NULL;
		GRegex* _tmp13_;
		GRegex* _tmp14_;
		GRegex* _tmp15_ = NULL;
		GRegex* _tmp16_;
		GRegex* _tmp17_;
		GRegex* _tmp18_ = NULL;
		GRegex* _tmp19_;
		GRegex* _tmp20_;
		_tmp1_ = g_regex_new ("\\bevery\\s+(?:(\\d+)\\s+)?(day|week|month|year)s?\\b", G_REGEX_CASELESS, 0, &_inner_error0_);
		_tmp0_ = _tmp1_;
		if (G_UNLIKELY (_inner_error0_ != NULL)) {
			goto __catch0_g_error;
		}
		_tmp2_ = _tmp0_;
		_tmp0_ = NULL;
		_g_regex_unref0 (self->priv->basic_regex);
		self->priv->basic_regex = _tmp2_;
		_tmp4_ = g_regex_new ("\\b(daily|weekly|monthly|yearly)\\b", G_REGEX_CASELESS, 0, &_inner_error0_);
		_tmp3_ = _tmp4_;
		if (G_UNLIKELY (_inner_error0_ != NULL)) {
			_g_regex_unref0 (_tmp0_);
			goto __catch0_g_error;
		}
		_tmp5_ = _tmp3_;
		_tmp3_ = NULL;
		_g_regex_unref0 (self->priv->alias_regex);
		self->priv->alias_regex = _tmp5_;
		_tmp7_ = g_regex_new ("\\bevery\\s+(morning|afternoon|evening|night)\\b", G_REGEX_CASELESS, 0, &_inner_error0_);
		_tmp6_ = _tmp7_;
		if (G_UNLIKELY (_inner_error0_ != NULL)) {
			_g_regex_unref0 (_tmp3_);
			_g_regex_unref0 (_tmp0_);
			goto __catch0_g_error;
		}
		_tmp8_ = _tmp6_;
		_tmp6_ = NULL;
		_g_regex_unref0 (self->priv->time_of_day_regex);
		self->priv->time_of_day_regex = _tmp8_;
		_tmp10_ = g_regex_new ("\\bevery\\s+(weekday|workday|weekend)\\b", G_REGEX_CASELESS, 0, &_inner_error0_);
		_tmp9_ = _tmp10_;
		if (G_UNLIKELY (_inner_error0_ != NULL)) {
			_g_regex_unref0 (_tmp6_);
			_g_regex_unref0 (_tmp3_);
			_g_regex_unref0 (_tmp0_);
			goto __catch0_g_error;
		}
		_tmp11_ = _tmp9_;
		_tmp9_ = NULL;
		_g_regex_unref0 (self->priv->weekday_regex);
		self->priv->weekday_regex = _tmp11_;
		_tmp13_ = g_regex_new ("\\bevery\\s+(?:(\\d+)(?:st|nd|rd|th)|last\\s+day)\\b", G_REGEX_CASELESS, 0, &_inner_error0_);
		_tmp12_ = _tmp13_;
		if (G_UNLIKELY (_inner_error0_ != NULL)) {
			_g_regex_unref0 (_tmp9_);
			_g_regex_unref0 (_tmp6_);
			_g_regex_unref0 (_tmp3_);
			_g_regex_unref0 (_tmp0_);
			goto __catch0_g_error;
		}
		_tmp14_ = _tmp12_;
		_tmp12_ = NULL;
		_g_regex_unref0 (self->priv->ordinal_day_regex);
		self->priv->ordinal_day_regex = _tmp14_;
		_tmp16_ = g_regex_new ("\\bevery\\s+(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)(?:uary|r" \
"uary|ch|il|e|y|ust|tember|ober|ember)?\\s+(\\d+)(?:st|nd|rd|th)?\\b", G_REGEX_CASELESS, 0, &_inner_error0_);
		_tmp15_ = _tmp16_;
		if (G_UNLIKELY (_inner_error0_ != NULL)) {
			_g_regex_unref0 (_tmp12_);
			_g_regex_unref0 (_tmp9_);
			_g_regex_unref0 (_tmp6_);
			_g_regex_unref0 (_tmp3_);
			_g_regex_unref0 (_tmp0_);
			goto __catch0_g_error;
		}
		_tmp17_ = _tmp15_;
		_tmp15_ = NULL;
		_g_regex_unref0 (self->priv->specific_date_regex);
		self->priv->specific_date_regex = _tmp17_;
		_tmp19_ = g_regex_new ("\\bevery\\s+hour\\b", G_REGEX_CASELESS, 0, &_inner_error0_);
		_tmp18_ = _tmp19_;
		if (G_UNLIKELY (_inner_error0_ != NULL)) {
			_g_regex_unref0 (_tmp15_);
			_g_regex_unref0 (_tmp12_);
			_g_regex_unref0 (_tmp9_);
			_g_regex_unref0 (_tmp6_);
			_g_regex_unref0 (_tmp3_);
			_g_regex_unref0 (_tmp0_);
			goto __catch0_g_error;
		}
		_tmp20_ = _tmp18_;
		_tmp18_ = NULL;
		_g_regex_unref0 (self->priv->hour_regex);
		self->priv->hour_regex = _tmp20_;
		_g_regex_unref0 (_tmp18_);
		_g_regex_unref0 (_tmp15_);
		_g_regex_unref0 (_tmp12_);
		_g_regex_unref0 (_tmp9_);
		_g_regex_unref0 (_tmp6_);
		_g_regex_unref0 (_tmp3_);
		_g_regex_unref0 (_tmp0_);
	}
	goto __finally0;
	__catch0_g_error:
	{
		GError* e = NULL;
		GError* _tmp21_;
		const gchar* _tmp22_;
		e = _inner_error0_;
		_inner_error0_ = NULL;
		_tmp21_ = e;
		_tmp22_ = _tmp21_->message;
		g_warning ("ENRecurrenceParser.vala:42: Error compiling regex: %s", _tmp22_);
		_g_error_free0 (e);
	}
	__finally0:
	if (G_UNLIKELY (_inner_error0_ != NULL)) {
		g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error0_->message, g_quark_to_string (_inner_error0_->domain), _inner_error0_->code);
		g_clear_error (&_inner_error0_);
		return NULL;
	}
	return self;
}

ChronoENRecurrenceParser*
chrono_en_recurrence_parser_new (void)
{
	return chrono_en_recurrence_parser_construct (CHRONO_TYPE_EN_RECURRENCE_PARSER);
}

ChronoParseResult*
chrono_en_recurrence_parser_parse (ChronoENRecurrenceParser* self,
                                   const gchar* text,
                                   GDateTime* reference_date)
{
	ChronoParseResult* _result_ = NULL;
	ChronoParseResult* _tmp0_;
	ChronoParseResult* _tmp1_;
	ChronoParseResult* _tmp2_;
	ChronoParseResult* _tmp3_;
	ChronoParseResult* _tmp4_;
	ChronoParseResult* _tmp5_;
	ChronoParseResult* _tmp6_;
	ChronoParseResult* _tmp7_;
	ChronoParseResult* _tmp8_;
	ChronoParseResult* _tmp9_;
	ChronoParseResult* _tmp10_;
	ChronoParseResult* _tmp11_;
	ChronoParseResult* _tmp12_;
	ChronoParseResult* result;
	g_return_val_if_fail (self != NULL, NULL);
	g_return_val_if_fail (text != NULL, NULL);
	g_return_val_if_fail (reference_date != NULL, NULL);
	_tmp0_ = chrono_en_recurrence_parser_parse_hour (self, text, reference_date);
	_result_ = _tmp0_;
	_tmp1_ = _result_;
	if (_tmp1_ != NULL) {
		result = _result_;
		return result;
	}
	_tmp2_ = chrono_en_recurrence_parser_parse_specific_date (self, text, reference_date);
	_g_object_unref0 (_result_);
	_result_ = _tmp2_;
	_tmp3_ = _result_;
	if (_tmp3_ != NULL) {
		result = _result_;
		return result;
	}
	_tmp4_ = chrono_en_recurrence_parser_parse_ordinal_day (self, text, reference_date);
	_g_object_unref0 (_result_);
	_result_ = _tmp4_;
	_tmp5_ = _result_;
	if (_tmp5_ != NULL) {
		result = _result_;
		return result;
	}
	_tmp6_ = chrono_en_recurrence_parser_parse_time_of_day (self, text, reference_date);
	_g_object_unref0 (_result_);
	_result_ = _tmp6_;
	_tmp7_ = _result_;
	if (_tmp7_ != NULL) {
		result = _result_;
		return result;
	}
	_tmp8_ = chrono_en_recurrence_parser_parse_weekday (self, text, reference_date);
	_g_object_unref0 (_result_);
	_result_ = _tmp8_;
	_tmp9_ = _result_;
	if (_tmp9_ != NULL) {
		result = _result_;
		return result;
	}
	_tmp10_ = chrono_en_recurrence_parser_parse_alias (self, text, reference_date);
	_g_object_unref0 (_result_);
	_result_ = _tmp10_;
	_tmp11_ = _result_;
	if (_tmp11_ != NULL) {
		result = _result_;
		return result;
	}
	_tmp12_ = chrono_en_recurrence_parser_parse_basic (self, text, reference_date);
	_g_object_unref0 (_result_);
	_result_ = _tmp12_;
	result = _result_;
	return result;
}

static ChronoParseResult*
chrono_en_recurrence_parser_parse_basic (ChronoENRecurrenceParser* self,
                                         const gchar* text,
                                         GDateTime* reference_date)
{
	GMatchInfo* match_info = NULL;
	GRegex* _tmp0_;
	GMatchInfo* _tmp1_ = NULL;
	gboolean _tmp2_;
	gchar* interval_str = NULL;
	GMatchInfo* _tmp3_;
	gchar* _tmp4_;
	gchar* unit = NULL;
	GMatchInfo* _tmp5_;
	gchar* _tmp6_;
	gchar* _tmp7_;
	gchar* _tmp8_;
	gchar* _tmp9_;
	gint _tmp10_ = 0;
	gboolean _tmp11_ = FALSE;
	const gchar* _tmp12_;
	gint interval = 0;
	ChronoRecurrenceType type = 0;
	const gchar* _tmp17_;
	const gchar* _tmp18_;
	GQuark _tmp20_ = 0U;
	static GQuark _tmp19_label0 = 0;
	static GQuark _tmp19_label1 = 0;
	static GQuark _tmp19_label2 = 0;
	static GQuark _tmp19_label3 = 0;
	GMatchInfo* _tmp21_;
	ChronoParseResult* _tmp22_;
	ChronoParseResult* result;
	g_return_val_if_fail (self != NULL, NULL);
	g_return_val_if_fail (text != NULL, NULL);
	g_return_val_if_fail (reference_date != NULL, NULL);
	_tmp0_ = self->priv->basic_regex;
	_tmp2_ = g_regex_match (_tmp0_, text, 0, &_tmp1_);
	_g_match_info_unref0 (match_info);
	match_info = _tmp1_;
	if (!_tmp2_) {
		result = NULL;
		_g_match_info_unref0 (match_info);
		return result;
	}
	_tmp3_ = match_info;
	_tmp4_ = g_match_info_fetch (_tmp3_, 1);
	interval_str = _tmp4_;
	_tmp5_ = match_info;
	_tmp6_ = g_match_info_fetch (_tmp5_, 2);
	_tmp7_ = _tmp6_;
	_tmp8_ = g_utf8_strdown (_tmp7_, (gssize) -1);
	_tmp9_ = _tmp8_;
	_g_free0 (_tmp7_);
	unit = _tmp9_;
	_tmp12_ = interval_str;
	if (_tmp12_ != NULL) {
		const gchar* _tmp13_;
		gint _tmp14_;
		gint _tmp15_;
		_tmp13_ = interval_str;
		_tmp14_ = strlen (_tmp13_);
		_tmp15_ = _tmp14_;
		_tmp11_ = _tmp15_ > 0;
	} else {
		_tmp11_ = FALSE;
	}
	if (_tmp11_) {
		const gchar* _tmp16_;
		_tmp16_ = interval_str;
		_tmp10_ = atoi (_tmp16_);
	} else {
		_tmp10_ = 1;
	}
	interval = _tmp10_;
	type = CHRONO_RECURRENCE_TYPE_DAILY;
	_tmp17_ = unit;
	_tmp18_ = _tmp17_;
	_tmp20_ = (NULL == _tmp18_) ? 0 : g_quark_from_string (_tmp18_);
	if (_tmp20_ == ((0 != _tmp19_label0) ? _tmp19_label0 : (_tmp19_label0 = g_quark_from_static_string ("day")))) {
		switch (0) {
			default:
			{
				type = CHRONO_RECURRENCE_TYPE_DAILY;
				break;
			}
		}
	} else if (_tmp20_ == ((0 != _tmp19_label1) ? _tmp19_label1 : (_tmp19_label1 = g_quark_from_static_string ("week")))) {
		switch (0) {
			default:
			{
				type = CHRONO_RECURRENCE_TYPE_WEEKLY;
				break;
			}
		}
	} else if (_tmp20_ == ((0 != _tmp19_label2) ? _tmp19_label2 : (_tmp19_label2 = g_quark_from_static_string ("month")))) {
		switch (0) {
			default:
			{
				type = CHRONO_RECURRENCE_TYPE_MONTHLY;
				break;
			}
		}
	} else if (_tmp20_ == ((0 != _tmp19_label3) ? _tmp19_label3 : (_tmp19_label3 = g_quark_from_static_string ("year")))) {
		switch (0) {
			default:
			{
				type = CHRONO_RECURRENCE_TYPE_YEARLY;
				break;
			}
		}
	}
	_tmp21_ = match_info;
	_tmp22_ = chrono_en_recurrence_parser_create_result (self, _tmp21_, reference_date, type, interval);
	result = _tmp22_;
	_g_free0 (unit);
	_g_free0 (interval_str);
	_g_match_info_unref0 (match_info);
	return result;
}

static ChronoParseResult*
chrono_en_recurrence_parser_parse_alias (ChronoENRecurrenceParser* self,
                                         const gchar* text,
                                         GDateTime* reference_date)
{
	GMatchInfo* match_info = NULL;
	GRegex* _tmp0_;
	GMatchInfo* _tmp1_ = NULL;
	gboolean _tmp2_;
	gchar* alias = NULL;
	GMatchInfo* _tmp3_;
	gchar* _tmp4_;
	gchar* _tmp5_;
	gchar* _tmp6_;
	gchar* _tmp7_;
	ChronoRecurrenceType type = 0;
	const gchar* _tmp8_;
	const gchar* _tmp9_;
	GQuark _tmp11_ = 0U;
	static GQuark _tmp10_label0 = 0;
	static GQuark _tmp10_label1 = 0;
	static GQuark _tmp10_label2 = 0;
	static GQuark _tmp10_label3 = 0;
	GMatchInfo* _tmp12_;
	ChronoParseResult* _tmp13_;
	ChronoParseResult* result;
	g_return_val_if_fail (self != NULL, NULL);
	g_return_val_if_fail (text != NULL, NULL);
	g_return_val_if_fail (reference_date != NULL, NULL);
	_tmp0_ = self->priv->alias_regex;
	_tmp2_ = g_regex_match (_tmp0_, text, 0, &_tmp1_);
	_g_match_info_unref0 (match_info);
	match_info = _tmp1_;
	if (!_tmp2_) {
		result = NULL;
		_g_match_info_unref0 (match_info);
		return result;
	}
	_tmp3_ = match_info;
	_tmp4_ = g_match_info_fetch (_tmp3_, 1);
	_tmp5_ = _tmp4_;
	_tmp6_ = g_utf8_strdown (_tmp5_, (gssize) -1);
	_tmp7_ = _tmp6_;
	_g_free0 (_tmp5_);
	alias = _tmp7_;
	type = CHRONO_RECURRENCE_TYPE_DAILY;
	_tmp8_ = alias;
	_tmp9_ = _tmp8_;
	_tmp11_ = (NULL == _tmp9_) ? 0 : g_quark_from_string (_tmp9_);
	if (_tmp11_ == ((0 != _tmp10_label0) ? _tmp10_label0 : (_tmp10_label0 = g_quark_from_static_string ("daily")))) {
		switch (0) {
			default:
			{
				type = CHRONO_RECURRENCE_TYPE_DAILY;
				break;
			}
		}
	} else if (_tmp11_ == ((0 != _tmp10_label1) ? _tmp10_label1 : (_tmp10_label1 = g_quark_from_static_string ("weekly")))) {
		switch (0) {
			default:
			{
				type = CHRONO_RECURRENCE_TYPE_WEEKLY;
				break;
			}
		}
	} else if (_tmp11_ == ((0 != _tmp10_label2) ? _tmp10_label2 : (_tmp10_label2 = g_quark_from_static_string ("monthly")))) {
		switch (0) {
			default:
			{
				type = CHRONO_RECURRENCE_TYPE_MONTHLY;
				break;
			}
		}
	} else if (_tmp11_ == ((0 != _tmp10_label3) ? _tmp10_label3 : (_tmp10_label3 = g_quark_from_static_string ("yearly")))) {
		switch (0) {
			default:
			{
				type = CHRONO_RECURRENCE_TYPE_YEARLY;
				break;
			}
		}
	}
	_tmp12_ = match_info;
	_tmp13_ = chrono_en_recurrence_parser_create_result (self, _tmp12_, reference_date, type, 1);
	result = _tmp13_;
	_g_free0 (alias);
	_g_match_info_unref0 (match_info);
	return result;
}

static ChronoParseResult*
chrono_en_recurrence_parser_parse_time_of_day (ChronoENRecurrenceParser* self,
                                               const gchar* text,
                                               GDateTime* reference_date)
{
	GMatchInfo* match_info = NULL;
	GRegex* _tmp0_;
	GMatchInfo* _tmp1_ = NULL;
	gboolean _tmp2_;
	gchar* time = NULL;
	GMatchInfo* _tmp3_;
	gchar* _tmp4_;
	gchar* _tmp5_;
	gchar* _tmp6_;
	gchar* _tmp7_;
	gint hour = 0;
	const gchar* _tmp8_;
	const gchar* _tmp9_;
	GQuark _tmp11_ = 0U;
	static GQuark _tmp10_label0 = 0;
	static GQuark _tmp10_label1 = 0;
	static GQuark _tmp10_label2 = 0;
	static GQuark _tmp10_label3 = 0;
	ChronoParseResult* _result_ = NULL;
	GMatchInfo* _tmp12_;
	ChronoParseResult* _tmp13_;
	ChronoParseResult* _tmp14_;
	ChronoRecurrenceRule* _tmp15_;
	ChronoRecurrenceRule* _tmp16_;
	ChronoParseResult* _tmp17_;
	GDateTime* _tmp18_;
	GDateTime* _tmp19_;
	ChronoParseResult* result;
	g_return_val_if_fail (self != NULL, NULL);
	g_return_val_if_fail (text != NULL, NULL);
	g_return_val_if_fail (reference_date != NULL, NULL);
	_tmp0_ = self->priv->time_of_day_regex;
	_tmp2_ = g_regex_match (_tmp0_, text, 0, &_tmp1_);
	_g_match_info_unref0 (match_info);
	match_info = _tmp1_;
	if (!_tmp2_) {
		result = NULL;
		_g_match_info_unref0 (match_info);
		return result;
	}
	_tmp3_ = match_info;
	_tmp4_ = g_match_info_fetch (_tmp3_, 1);
	_tmp5_ = _tmp4_;
	_tmp6_ = g_utf8_strdown (_tmp5_, (gssize) -1);
	_tmp7_ = _tmp6_;
	_g_free0 (_tmp5_);
	time = _tmp7_;
	hour = 9;
	_tmp8_ = time;
	_tmp9_ = _tmp8_;
	_tmp11_ = (NULL == _tmp9_) ? 0 : g_quark_from_string (_tmp9_);
	if (_tmp11_ == ((0 != _tmp10_label0) ? _tmp10_label0 : (_tmp10_label0 = g_quark_from_static_string ("morning")))) {
		switch (0) {
			default:
			{
				hour = 9;
				break;
			}
		}
	} else if (_tmp11_ == ((0 != _tmp10_label1) ? _tmp10_label1 : (_tmp10_label1 = g_quark_from_static_string ("afternoon")))) {
		switch (0) {
			default:
			{
				hour = 12;
				break;
			}
		}
	} else if (_tmp11_ == ((0 != _tmp10_label2) ? _tmp10_label2 : (_tmp10_label2 = g_quark_from_static_string ("evening")))) {
		switch (0) {
			default:
			{
				hour = 19;
				break;
			}
		}
	} else if (_tmp11_ == ((0 != _tmp10_label3) ? _tmp10_label3 : (_tmp10_label3 = g_quark_from_static_string ("night")))) {
		switch (0) {
			default:
			{
				hour = 22;
				break;
			}
		}
	}
	_tmp12_ = match_info;
	_tmp13_ = chrono_en_recurrence_parser_create_result (self, _tmp12_, reference_date, CHRONO_RECURRENCE_TYPE_DAILY, 1);
	_result_ = _tmp13_;
	_tmp14_ = _result_;
	_tmp15_ = chrono_parse_result_get_recurrence (_tmp14_);
	_tmp16_ = _tmp15_;
	chrono_recurrence_rule_set_hour (_tmp16_, hour);
	_tmp17_ = _result_;
	_tmp18_ = g_date_time_new_local (g_date_time_get_year (reference_date), g_date_time_get_month (reference_date), g_date_time_get_day_of_month (reference_date), hour, 0, (gdouble) 0);
	_tmp19_ = _tmp18_;
	chrono_parse_result_set_date (_tmp17_, _tmp19_);
	_g_date_time_unref0 (_tmp19_);
	result = _result_;
	_g_free0 (time);
	_g_match_info_unref0 (match_info);
	return result;
}

static ChronoParseResult*
chrono_en_recurrence_parser_parse_weekday (ChronoENRecurrenceParser* self,
                                           const gchar* text,
                                           GDateTime* reference_date)
{
	GMatchInfo* match_info = NULL;
	GRegex* _tmp0_;
	GMatchInfo* _tmp1_ = NULL;
	gboolean _tmp2_;
	gchar* type = NULL;
	GMatchInfo* _tmp3_;
	gchar* _tmp4_;
	gchar* _tmp5_;
	gchar* _tmp6_;
	gchar* _tmp7_;
	ChronoParseResult* _result_ = NULL;
	GMatchInfo* _tmp8_;
	ChronoParseResult* _tmp9_;
	ChronoParseResult* _tmp10_;
	ChronoRecurrenceRule* _tmp11_;
	ChronoRecurrenceRule* _tmp12_;
	GeeArrayList* _tmp13_;
	GeeArrayList* _tmp14_;
	gboolean _tmp15_ = FALSE;
	const gchar* _tmp16_;
	ChronoParseResult* result;
	g_return_val_if_fail (self != NULL, NULL);
	g_return_val_if_fail (text != NULL, NULL);
	g_return_val_if_fail (reference_date != NULL, NULL);
	_tmp0_ = self->priv->weekday_regex;
	_tmp2_ = g_regex_match (_tmp0_, text, 0, &_tmp1_);
	_g_match_info_unref0 (match_info);
	match_info = _tmp1_;
	if (!_tmp2_) {
		result = NULL;
		_g_match_info_unref0 (match_info);
		return result;
	}
	_tmp3_ = match_info;
	_tmp4_ = g_match_info_fetch (_tmp3_, 1);
	_tmp5_ = _tmp4_;
	_tmp6_ = g_utf8_strdown (_tmp5_, (gssize) -1);
	_tmp7_ = _tmp6_;
	_g_free0 (_tmp5_);
	type = _tmp7_;
	_tmp8_ = match_info;
	_tmp9_ = chrono_en_recurrence_parser_create_result (self, _tmp8_, reference_date, CHRONO_RECURRENCE_TYPE_WEEKLY, 1);
	_result_ = _tmp9_;
	_tmp10_ = _result_;
	_tmp11_ = chrono_parse_result_get_recurrence (_tmp10_);
	_tmp12_ = _tmp11_;
	_tmp13_ = gee_array_list_new (G_TYPE_INT, NULL, NULL, NULL, NULL, NULL);
	_tmp14_ = _tmp13_;
	chrono_recurrence_rule_set_days_of_week (_tmp12_, _tmp14_);
	_g_object_unref0 (_tmp14_);
	_tmp16_ = type;
	if (g_strcmp0 (_tmp16_, "weekday") == 0) {
		_tmp15_ = TRUE;
	} else {
		const gchar* _tmp17_;
		_tmp17_ = type;
		_tmp15_ = g_strcmp0 (_tmp17_, "workday") == 0;
	}
	if (_tmp15_) {
		ChronoParseResult* _tmp18_;
		ChronoRecurrenceRule* _tmp19_;
		ChronoRecurrenceRule* _tmp20_;
		GeeArrayList* _tmp21_;
		GeeArrayList* _tmp22_;
		gint* _tmp23_;
		gint* _tmp24_;
		gint _tmp24__length1;
		_tmp18_ = _result_;
		_tmp19_ = chrono_parse_result_get_recurrence (_tmp18_);
		_tmp20_ = _tmp19_;
		_tmp21_ = chrono_recurrence_rule_get_days_of_week (_tmp20_);
		_tmp22_ = _tmp21_;
		_tmp23_ = g_new0 (gint, 5);
		_tmp23_[0] = 1;
		_tmp23_[1] = 2;
		_tmp23_[2] = 3;
		_tmp23_[3] = 4;
		_tmp23_[4] = 5;
		_tmp24_ = _tmp23_;
		_tmp24__length1 = 5;
		gee_collection_add_all_array ((GeeCollection*) _tmp22_, _tmp24_, (gint) 5);
		_tmp24_ = (g_free (_tmp24_), NULL);
	} else {
		ChronoParseResult* _tmp25_;
		ChronoRecurrenceRule* _tmp26_;
		ChronoRecurrenceRule* _tmp27_;
		GeeArrayList* _tmp28_;
		GeeArrayList* _tmp29_;
		_tmp25_ = _result_;
		_tmp26_ = chrono_parse_result_get_recurrence (_tmp25_);
		_tmp27_ = _tmp26_;
		_tmp28_ = chrono_recurrence_rule_get_days_of_week (_tmp27_);
		_tmp29_ = _tmp28_;
		gee_abstract_collection_add ((GeeAbstractCollection*) _tmp29_, (gpointer) ((gintptr) 6));
	}
	result = _result_;
	_g_free0 (type);
	_g_match_info_unref0 (match_info);
	return result;
}

static gboolean
string_contains (const gchar* self,
                 const gchar* needle)
{
	gchar* _tmp0_;
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	g_return_val_if_fail (needle != NULL, FALSE);
	_tmp0_ = strstr ((gchar*) self, (gchar*) needle);
	result = _tmp0_ != NULL;
	return result;
}

static ChronoParseResult*
chrono_en_recurrence_parser_parse_ordinal_day (ChronoENRecurrenceParser* self,
                                               const gchar* text,
                                               GDateTime* reference_date)
{
	GMatchInfo* match_info = NULL;
	GRegex* _tmp0_;
	GMatchInfo* _tmp1_ = NULL;
	gboolean _tmp2_;
	gchar* day_str = NULL;
	GMatchInfo* _tmp3_;
	gchar* _tmp4_;
	ChronoParseResult* _result_ = NULL;
	GMatchInfo* _tmp5_;
	ChronoParseResult* _tmp6_;
	ChronoParseResult* result;
	g_return_val_if_fail (self != NULL, NULL);
	g_return_val_if_fail (text != NULL, NULL);
	g_return_val_if_fail (reference_date != NULL, NULL);
	_tmp0_ = self->priv->ordinal_day_regex;
	_tmp2_ = g_regex_match (_tmp0_, text, 0, &_tmp1_);
	_g_match_info_unref0 (match_info);
	match_info = _tmp1_;
	if (!_tmp2_) {
		result = NULL;
		_g_match_info_unref0 (match_info);
		return result;
	}
	_tmp3_ = match_info;
	_tmp4_ = g_match_info_fetch (_tmp3_, 1);
	day_str = _tmp4_;
	_tmp5_ = match_info;
	_tmp6_ = chrono_en_recurrence_parser_create_result (self, _tmp5_, reference_date, CHRONO_RECURRENCE_TYPE_MONTHLY, 1);
	_result_ = _tmp6_;
	if (string_contains (text, "last day")) {
		ChronoParseResult* _tmp7_;
		ChronoRecurrenceRule* _tmp8_;
		ChronoRecurrenceRule* _tmp9_;
		_tmp7_ = _result_;
		_tmp8_ = chrono_parse_result_get_recurrence (_tmp7_);
		_tmp9_ = _tmp8_;
		chrono_recurrence_rule_set_last_day (_tmp9_, TRUE);
	} else {
		gboolean _tmp10_ = FALSE;
		const gchar* _tmp11_;
		_tmp11_ = day_str;
		if (_tmp11_ != NULL) {
			const gchar* _tmp12_;
			gint _tmp13_;
			gint _tmp14_;
			_tmp12_ = day_str;
			_tmp13_ = strlen (_tmp12_);
			_tmp14_ = _tmp13_;
			_tmp10_ = _tmp14_ > 0;
		} else {
			_tmp10_ = FALSE;
		}
		if (_tmp10_) {
			ChronoParseResult* _tmp15_;
			ChronoRecurrenceRule* _tmp16_;
			ChronoRecurrenceRule* _tmp17_;
			const gchar* _tmp18_;
			_tmp15_ = _result_;
			_tmp16_ = chrono_parse_result_get_recurrence (_tmp15_);
			_tmp17_ = _tmp16_;
			_tmp18_ = day_str;
			chrono_recurrence_rule_set_day_of_month (_tmp17_, atoi (_tmp18_));
		}
	}
	result = _result_;
	_g_free0 (day_str);
	_g_match_info_unref0 (match_info);
	return result;
}

static ChronoParseResult*
chrono_en_recurrence_parser_parse_specific_date (ChronoENRecurrenceParser* self,
                                                 const gchar* text,
                                                 GDateTime* reference_date)
{
	GMatchInfo* match_info = NULL;
	GRegex* _tmp0_;
	GMatchInfo* _tmp1_ = NULL;
	gboolean _tmp2_;
	gchar* month_str = NULL;
	GMatchInfo* _tmp3_;
	gchar* _tmp4_;
	gchar* _tmp5_;
	gchar* _tmp6_;
	gchar* _tmp7_;
	gchar* day_str = NULL;
	GMatchInfo* _tmp8_;
	gchar* _tmp9_;
	gint month = 0;
	const gchar* _tmp10_;
	const gchar* _tmp11_;
	GQuark _tmp13_ = 0U;
	static GQuark _tmp12_label0 = 0;
	static GQuark _tmp12_label1 = 0;
	static GQuark _tmp12_label2 = 0;
	static GQuark _tmp12_label3 = 0;
	static GQuark _tmp12_label4 = 0;
	static GQuark _tmp12_label5 = 0;
	static GQuark _tmp12_label6 = 0;
	static GQuark _tmp12_label7 = 0;
	static GQuark _tmp12_label8 = 0;
	static GQuark _tmp12_label9 = 0;
	static GQuark _tmp12_label10 = 0;
	static GQuark _tmp12_label11 = 0;
	ChronoParseResult* _result_ = NULL;
	GMatchInfo* _tmp14_;
	ChronoParseResult* _tmp15_;
	ChronoParseResult* _tmp16_;
	ChronoRecurrenceRule* _tmp17_;
	ChronoRecurrenceRule* _tmp18_;
	ChronoParseResult* _tmp19_;
	ChronoRecurrenceRule* _tmp20_;
	ChronoRecurrenceRule* _tmp21_;
	const gchar* _tmp22_;
	ChronoParseResult* result;
	g_return_val_if_fail (self != NULL, NULL);
	g_return_val_if_fail (text != NULL, NULL);
	g_return_val_if_fail (reference_date != NULL, NULL);
	_tmp0_ = self->priv->specific_date_regex;
	_tmp2_ = g_regex_match (_tmp0_, text, 0, &_tmp1_);
	_g_match_info_unref0 (match_info);
	match_info = _tmp1_;
	if (!_tmp2_) {
		result = NULL;
		_g_match_info_unref0 (match_info);
		return result;
	}
	_tmp3_ = match_info;
	_tmp4_ = g_match_info_fetch (_tmp3_, 1);
	_tmp5_ = _tmp4_;
	_tmp6_ = g_utf8_strdown (_tmp5_, (gssize) -1);
	_tmp7_ = _tmp6_;
	_g_free0 (_tmp5_);
	month_str = _tmp7_;
	_tmp8_ = match_info;
	_tmp9_ = g_match_info_fetch (_tmp8_, 2);
	day_str = _tmp9_;
	month = 1;
	_tmp10_ = month_str;
	_tmp11_ = _tmp10_;
	_tmp13_ = (NULL == _tmp11_) ? 0 : g_quark_from_string (_tmp11_);
	if (_tmp13_ == ((0 != _tmp12_label0) ? _tmp12_label0 : (_tmp12_label0 = g_quark_from_static_string ("jan")))) {
		switch (0) {
			default:
			{
				month = 1;
				break;
			}
		}
	} else if (_tmp13_ == ((0 != _tmp12_label1) ? _tmp12_label1 : (_tmp12_label1 = g_quark_from_static_string ("feb")))) {
		switch (0) {
			default:
			{
				month = 2;
				break;
			}
		}
	} else if (_tmp13_ == ((0 != _tmp12_label2) ? _tmp12_label2 : (_tmp12_label2 = g_quark_from_static_string ("mar")))) {
		switch (0) {
			default:
			{
				month = 3;
				break;
			}
		}
	} else if (_tmp13_ == ((0 != _tmp12_label3) ? _tmp12_label3 : (_tmp12_label3 = g_quark_from_static_string ("apr")))) {
		switch (0) {
			default:
			{
				month = 4;
				break;
			}
		}
	} else if (_tmp13_ == ((0 != _tmp12_label4) ? _tmp12_label4 : (_tmp12_label4 = g_quark_from_static_string ("may")))) {
		switch (0) {
			default:
			{
				month = 5;
				break;
			}
		}
	} else if (_tmp13_ == ((0 != _tmp12_label5) ? _tmp12_label5 : (_tmp12_label5 = g_quark_from_static_string ("jun")))) {
		switch (0) {
			default:
			{
				month = 6;
				break;
			}
		}
	} else if (_tmp13_ == ((0 != _tmp12_label6) ? _tmp12_label6 : (_tmp12_label6 = g_quark_from_static_string ("jul")))) {
		switch (0) {
			default:
			{
				month = 7;
				break;
			}
		}
	} else if (_tmp13_ == ((0 != _tmp12_label7) ? _tmp12_label7 : (_tmp12_label7 = g_quark_from_static_string ("aug")))) {
		switch (0) {
			default:
			{
				month = 8;
				break;
			}
		}
	} else if (_tmp13_ == ((0 != _tmp12_label8) ? _tmp12_label8 : (_tmp12_label8 = g_quark_from_static_string ("sep")))) {
		switch (0) {
			default:
			{
				month = 9;
				break;
			}
		}
	} else if (_tmp13_ == ((0 != _tmp12_label9) ? _tmp12_label9 : (_tmp12_label9 = g_quark_from_static_string ("oct")))) {
		switch (0) {
			default:
			{
				month = 10;
				break;
			}
		}
	} else if (_tmp13_ == ((0 != _tmp12_label10) ? _tmp12_label10 : (_tmp12_label10 = g_quark_from_static_string ("nov")))) {
		switch (0) {
			default:
			{
				month = 11;
				break;
			}
		}
	} else if (_tmp13_ == ((0 != _tmp12_label11) ? _tmp12_label11 : (_tmp12_label11 = g_quark_from_static_string ("dec")))) {
		switch (0) {
			default:
			{
				month = 12;
				break;
			}
		}
	}
	_tmp14_ = match_info;
	_tmp15_ = chrono_en_recurrence_parser_create_result (self, _tmp14_, reference_date, CHRONO_RECURRENCE_TYPE_YEARLY, 1);
	_result_ = _tmp15_;
	_tmp16_ = _result_;
	_tmp17_ = chrono_parse_result_get_recurrence (_tmp16_);
	_tmp18_ = _tmp17_;
	chrono_recurrence_rule_set_month_of_year (_tmp18_, month);
	_tmp19_ = _result_;
	_tmp20_ = chrono_parse_result_get_recurrence (_tmp19_);
	_tmp21_ = _tmp20_;
	_tmp22_ = day_str;
	chrono_recurrence_rule_set_day_of_month (_tmp21_, atoi (_tmp22_));
	result = _result_;
	_g_free0 (day_str);
	_g_free0 (month_str);
	_g_match_info_unref0 (match_info);
	return result;
}

static ChronoParseResult*
chrono_en_recurrence_parser_parse_hour (ChronoENRecurrenceParser* self,
                                        const gchar* text,
                                        GDateTime* reference_date)
{
	GMatchInfo* match_info = NULL;
	GRegex* _tmp0_;
	GMatchInfo* _tmp1_ = NULL;
	gboolean _tmp2_;
	GMatchInfo* _tmp3_;
	ChronoParseResult* _tmp4_;
	ChronoParseResult* result;
	g_return_val_if_fail (self != NULL, NULL);
	g_return_val_if_fail (text != NULL, NULL);
	g_return_val_if_fail (reference_date != NULL, NULL);
	_tmp0_ = self->priv->hour_regex;
	_tmp2_ = g_regex_match (_tmp0_, text, 0, &_tmp1_);
	_g_match_info_unref0 (match_info);
	match_info = _tmp1_;
	if (!_tmp2_) {
		result = NULL;
		_g_match_info_unref0 (match_info);
		return result;
	}
	_tmp3_ = match_info;
	_tmp4_ = chrono_en_recurrence_parser_create_result (self, _tmp3_, reference_date, CHRONO_RECURRENCE_TYPE_DAILY, 1);
	result = _tmp4_;
	_g_match_info_unref0 (match_info);
	return result;
}

static ChronoParseResult*
chrono_en_recurrence_parser_create_result (ChronoENRecurrenceParser* self,
                                           GMatchInfo* match_info,
                                           GDateTime* reference_date,
                                           ChronoRecurrenceType type,
                                           gint interval)
{
	gint start = 0;
	gint end = 0;
	gint _tmp0_ = 0;
	gint _tmp1_ = 0;
	ChronoRecurrenceRule* rule = NULL;
	ChronoRecurrenceRule* _tmp2_;
	ChronoParseResult* _result_ = NULL;
	ChronoParseResult* _tmp3_;
	gchar* _tmp4_;
	gchar* _tmp5_;
	ChronoParseResult* result;
	g_return_val_if_fail (self != NULL, NULL);
	g_return_val_if_fail (match_info != NULL, NULL);
	g_return_val_if_fail (reference_date != NULL, NULL);
	g_match_info_fetch_pos (match_info, 0, &_tmp0_, &_tmp1_);
	start = _tmp0_;
	end = _tmp1_;
	_tmp2_ = chrono_recurrence_rule_new (type);
	rule = _tmp2_;
	chrono_recurrence_rule_set_interval (rule, interval);
	_tmp3_ = chrono_parse_result_new ();
	_result_ = _tmp3_;
	chrono_parse_result_set_date (_result_, reference_date);
	chrono_parse_result_set_recurrence (_result_, rule);
	chrono_parse_result_set_start_index (_result_, start);
	chrono_parse_result_set_end_index (_result_, end);
	_tmp4_ = g_match_info_fetch (match_info, 0);
	_tmp5_ = _tmp4_;
	chrono_parse_result_set_matched_text (_result_, _tmp5_);
	_g_free0 (_tmp5_);
	result = _result_;
	_g_object_unref0 (rule);
	return result;
}

static void
chrono_en_recurrence_parser_class_init (ChronoENRecurrenceParserClass * klass,
                                        gpointer klass_data)
{
	chrono_en_recurrence_parser_parent_class = g_type_class_peek_parent (klass);
	g_type_class_adjust_private_offset (klass, &ChronoENRecurrenceParser_private_offset);
	G_OBJECT_CLASS (klass)->finalize = chrono_en_recurrence_parser_finalize;
}

static void
chrono_en_recurrence_parser_instance_init (ChronoENRecurrenceParser * self,
                                           gpointer klass)
{
	self->priv = chrono_en_recurrence_parser_get_instance_private (self);
}

static void
chrono_en_recurrence_parser_finalize (GObject * obj)
{
	ChronoENRecurrenceParser * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, CHRONO_TYPE_EN_RECURRENCE_PARSER, ChronoENRecurrenceParser);
	_g_regex_unref0 (self->priv->basic_regex);
	_g_regex_unref0 (self->priv->alias_regex);
	_g_regex_unref0 (self->priv->time_of_day_regex);
	_g_regex_unref0 (self->priv->weekday_regex);
	_g_regex_unref0 (self->priv->ordinal_day_regex);
	_g_regex_unref0 (self->priv->specific_date_regex);
	_g_regex_unref0 (self->priv->hour_regex);
	G_OBJECT_CLASS (chrono_en_recurrence_parser_parent_class)->finalize (obj);
}

 G_GNUC_NO_INLINE static GType
chrono_en_recurrence_parser_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (ChronoENRecurrenceParserClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) chrono_en_recurrence_parser_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (ChronoENRecurrenceParser), 0, (GInstanceInitFunc) chrono_en_recurrence_parser_instance_init, NULL };
	GType chrono_en_recurrence_parser_type_id;
	chrono_en_recurrence_parser_type_id = g_type_register_static (G_TYPE_OBJECT, "ChronoENRecurrenceParser", &g_define_type_info, 0);
	ChronoENRecurrenceParser_private_offset = g_type_add_instance_private (chrono_en_recurrence_parser_type_id, sizeof (ChronoENRecurrenceParserPrivate));
	return chrono_en_recurrence_parser_type_id;
}

GType
chrono_en_recurrence_parser_get_type (void)
{
	static gsize chrono_en_recurrence_parser_type_id__once = 0;
	if (g_once_init_enter (&chrono_en_recurrence_parser_type_id__once)) {
		GType chrono_en_recurrence_parser_type_id;
		chrono_en_recurrence_parser_type_id = chrono_en_recurrence_parser_get_type_once ();
		g_once_init_leave (&chrono_en_recurrence_parser_type_id__once, chrono_en_recurrence_parser_type_id);
	}
	return chrono_en_recurrence_parser_type_id__once;
}

