/* util-timeout-manager.c generated by valac 0.56.3, the Vala compiler
 * generated from util-timeout-manager.vala, do not modify */

/*
 * Copyright 2017 Michael Gratton <mike@vee.net>
 *
 * This software is licensed under the GNU Lesser General Public License
 * (version 2.1 or later). See the COPYING file in this distribution.
 */

#include "geary-engine.h"
#include <glib.h>
#include <glib-object.h>

enum  {
	GEARY_TIMEOUT_MANAGER_0_PROPERTY,
	GEARY_TIMEOUT_MANAGER_IS_RUNNING_PROPERTY,
	GEARY_TIMEOUT_MANAGER_NUM_PROPERTIES
};
static GParamSpec* geary_timeout_manager_properties[GEARY_TIMEOUT_MANAGER_NUM_PROPERTIES];

#define GEARY_TIMEOUT_MANAGER_TYPE_HANDLER_REF (geary_timeout_manager_handler_ref_get_type ())
#define GEARY_TIMEOUT_MANAGER_HANDLER_REF(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEARY_TIMEOUT_MANAGER_TYPE_HANDLER_REF, GearyTimeoutManagerHandlerRef))
#define GEARY_TIMEOUT_MANAGER_HANDLER_REF_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GEARY_TIMEOUT_MANAGER_TYPE_HANDLER_REF, GearyTimeoutManagerHandlerRefClass))
#define GEARY_TIMEOUT_MANAGER_IS_HANDLER_REF(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GEARY_TIMEOUT_MANAGER_TYPE_HANDLER_REF))
#define GEARY_TIMEOUT_MANAGER_IS_HANDLER_REF_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GEARY_TIMEOUT_MANAGER_TYPE_HANDLER_REF))
#define GEARY_TIMEOUT_MANAGER_HANDLER_REF_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GEARY_TIMEOUT_MANAGER_TYPE_HANDLER_REF, GearyTimeoutManagerHandlerRefClass))

typedef struct _GearyTimeoutManagerHandlerRef GearyTimeoutManagerHandlerRef;
typedef struct _GearyTimeoutManagerHandlerRefClass GearyTimeoutManagerHandlerRefClass;
#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))
typedef struct _GearyTimeoutManagerHandlerRefPrivate GearyTimeoutManagerHandlerRefPrivate;
enum  {
	GEARY_TIMEOUT_MANAGER_HANDLER_REF_0_PROPERTY,
	GEARY_TIMEOUT_MANAGER_HANDLER_REF_NUM_PROPERTIES
};
static GParamSpec* geary_timeout_manager_handler_ref_properties[GEARY_TIMEOUT_MANAGER_HANDLER_REF_NUM_PROPERTIES];

struct _GearyTimeoutManagerPrivate {
	GearyTimeoutManagerTimeoutFunc callback;
	gpointer callback_target;
	gint64 source_id;
};

struct _GearyTimeoutManagerHandlerRef {
	GObject parent_instance;
	GearyTimeoutManagerHandlerRefPrivate * priv;
};

struct _GearyTimeoutManagerHandlerRefClass {
	GObjectClass parent_class;
};

struct _GearyTimeoutManagerHandlerRefPrivate {
	GWeakRef manager;
};

static gint GearyTimeoutManager_private_offset;
static gpointer geary_timeout_manager_parent_class = NULL;
static gint GearyTimeoutManagerHandlerRef_private_offset;
static gpointer geary_timeout_manager_handler_ref_parent_class = NULL;

static GType geary_timeout_manager_handler_ref_get_type (void) G_GNUC_CONST  G_GNUC_UNUSED ;
static GearyTimeoutManagerHandlerRef* geary_timeout_manager_handler_ref_new (GearyTimeoutManager* manager);
static GearyTimeoutManagerHandlerRef* geary_timeout_manager_handler_ref_construct (GType object_type,
                                                                            GearyTimeoutManager* manager);
static gboolean geary_timeout_manager_handler_ref_execute (GearyTimeoutManagerHandlerRef* self);
static gboolean _geary_timeout_manager_handler_ref_execute_gsource_func (gpointer self);
static gboolean geary_timeout_manager_execute (GearyTimeoutManager* self);
static void geary_timeout_manager_handler_ref_finalize (GObject * obj);
static GType geary_timeout_manager_handler_ref_get_type_once (void);
static void geary_timeout_manager_finalize (GObject * obj);
static GType geary_timeout_manager_get_type_once (void);
static void _vala_geary_timeout_manager_get_property (GObject * object,
                                               guint property_id,
                                               GValue * value,
                                               GParamSpec * pspec);

static inline gpointer
geary_timeout_manager_get_instance_private (GearyTimeoutManager* self)
{
	return G_STRUCT_MEMBER_P (self, GearyTimeoutManager_private_offset);
}

/** Specifies the priority the timeout should be given. */
 G_GNUC_NO_INLINE static GType
geary_timeout_manager_priority_get_type_once (void)
{
	static const GEnumValue values[] = {{GEARY_TIMEOUT_MANAGER_PRIORITY_HIGH, "GEARY_TIMEOUT_MANAGER_PRIORITY_HIGH", "high"}, {GEARY_TIMEOUT_MANAGER_PRIORITY_DEFAULT, "GEARY_TIMEOUT_MANAGER_PRIORITY_DEFAULT", "default"}, {GEARY_TIMEOUT_MANAGER_PRIORITY_HIGH_IDLE, "GEARY_TIMEOUT_MANAGER_PRIORITY_HIGH_IDLE", "high-idle"}, {GEARY_TIMEOUT_MANAGER_PRIORITY_DEFAULT_IDLE, "GEARY_TIMEOUT_MANAGER_PRIORITY_DEFAULT_IDLE", "default-idle"}, {GEARY_TIMEOUT_MANAGER_PRIORITY_LOW, "GEARY_TIMEOUT_MANAGER_PRIORITY_LOW", "low"}, {0, NULL, NULL}};
	GType geary_timeout_manager_priority_type_id;
	geary_timeout_manager_priority_type_id = g_enum_register_static ("GearyTimeoutManagerPriority", values);
	return geary_timeout_manager_priority_type_id;
}

GType
geary_timeout_manager_priority_get_type (void)
{
	static gsize geary_timeout_manager_priority_type_id__once = 0;
	if (g_once_init_enter (&geary_timeout_manager_priority_type_id__once)) {
		GType geary_timeout_manager_priority_type_id;
		geary_timeout_manager_priority_type_id = geary_timeout_manager_priority_get_type_once ();
		g_once_init_leave (&geary_timeout_manager_priority_type_id__once, geary_timeout_manager_priority_type_id);
	}
	return geary_timeout_manager_priority_type_id__once;
}

/** Specifies if the timeout should fire once or continuously. */
 G_GNUC_NO_INLINE static GType
geary_timeout_manager_repeat_get_type_once (void)
{
	static const GEnumValue values[] = {{GEARY_TIMEOUT_MANAGER_REPEAT_ONCE, "GEARY_TIMEOUT_MANAGER_REPEAT_ONCE", "once"}, {GEARY_TIMEOUT_MANAGER_REPEAT_FOREVER, "GEARY_TIMEOUT_MANAGER_REPEAT_FOREVER", "forever"}, {0, NULL, NULL}};
	GType geary_timeout_manager_repeat_type_id;
	geary_timeout_manager_repeat_type_id = g_enum_register_static ("GearyTimeoutManagerRepeat", values);
	return geary_timeout_manager_repeat_type_id;
}

GType
geary_timeout_manager_repeat_get_type (void)
{
	static gsize geary_timeout_manager_repeat_type_id__once = 0;
	if (g_once_init_enter (&geary_timeout_manager_repeat_type_id__once)) {
		GType geary_timeout_manager_repeat_type_id;
		geary_timeout_manager_repeat_type_id = geary_timeout_manager_repeat_get_type_once ();
		g_once_init_leave (&geary_timeout_manager_repeat_type_id__once, geary_timeout_manager_repeat_type_id);
	}
	return geary_timeout_manager_repeat_type_id__once;
}

gboolean
geary_timeout_manager_get_is_running (GearyTimeoutManager* self)
{
	gboolean result;
	g_return_val_if_fail (GEARY_IS_TIMEOUT_MANAGER (self), FALSE);
	result = self->priv->source_id >= ((gint64) 0);
	return result;
}

/**
     * Constructs a new timeout with an interval in seconds.
     *
     * The timeout will be by default not running, and hence needs to be
     * started by a call to {@link start}.
     */
GearyTimeoutManager*
geary_timeout_manager_construct_seconds (GType object_type,
                                         guint interval,
                                         GearyTimeoutManagerTimeoutFunc callback,
                                         gpointer callback_target)
{
	GearyTimeoutManager * self = NULL;
	self = (GearyTimeoutManager*) geary_base_object_construct (object_type);
	self->use_seconds = TRUE;
	self->interval = interval;
	self->priv->callback = callback;
	self->priv->callback_target = callback_target;
	return self;
}

GearyTimeoutManager*
geary_timeout_manager_new_seconds (guint interval,
                                   GearyTimeoutManagerTimeoutFunc callback,
                                   gpointer callback_target)
{
	return geary_timeout_manager_construct_seconds (GEARY_TYPE_TIMEOUT_MANAGER, interval, callback, callback_target);
}

/**
     * Constructs a new timeout with an interval in milliseconds.
     *
     * The timeout will be by default not running, and hence needs to be
     * started by a call to {@link start}.
     */
GearyTimeoutManager*
geary_timeout_manager_construct_milliseconds (GType object_type,
                                              guint interval,
                                              GearyTimeoutManagerTimeoutFunc callback,
                                              gpointer callback_target)
{
	GearyTimeoutManager * self = NULL;
	self = (GearyTimeoutManager*) geary_base_object_construct (object_type);
	self->use_seconds = FALSE;
	self->interval = interval;
	self->priv->callback = callback;
	self->priv->callback_target = callback_target;
	return self;
}

GearyTimeoutManager*
geary_timeout_manager_new_milliseconds (guint interval,
                                        GearyTimeoutManagerTimeoutFunc callback,
                                        gpointer callback_target)
{
	return geary_timeout_manager_construct_milliseconds (GEARY_TYPE_TIMEOUT_MANAGER, interval, callback, callback_target);
}

/**
     * Schedules the timeout to fire after the given interval.
     *
     * If the timeout is already running, it will first be reset.
     */
static gboolean
_geary_timeout_manager_handler_ref_execute_gsource_func (gpointer self)
{
	gboolean result;
	result = geary_timeout_manager_handler_ref_execute ((GearyTimeoutManagerHandlerRef*) self);
	return result;
}

void
geary_timeout_manager_start (GearyTimeoutManager* self)
{
	GearyTimeoutManagerHandlerRef* handler = NULL;
	GearyTimeoutManagerHandlerRef* _tmp0_;
	guint _tmp1_ = 0U;
	g_return_if_fail (GEARY_IS_TIMEOUT_MANAGER (self));
	geary_timeout_manager_reset (self);
	_tmp0_ = geary_timeout_manager_handler_ref_new (self);
	handler = _tmp0_;
	if (self->use_seconds) {
		GearyTimeoutManagerHandlerRef* _tmp2_;
		_tmp2_ = handler;
		_tmp1_ = g_timeout_add_seconds_full ((gint) self->priority, self->interval, _geary_timeout_manager_handler_ref_execute_gsource_func, g_object_ref (_tmp2_), g_object_unref);
	} else {
		GearyTimeoutManagerHandlerRef* _tmp3_;
		_tmp3_ = handler;
		_tmp1_ = g_timeout_add_full ((gint) self->priority, self->interval, _geary_timeout_manager_handler_ref_execute_gsource_func, g_object_ref (_tmp3_), g_object_unref);
	}
	self->priv->source_id = (gint64) ((gint) _tmp1_);
	_g_object_unref0 (handler);
}

/**
     * Prevents the timeout from firing.
     *
     * After a call to this timeout will not fire again, regardless of
     * the specified repetition for the timeout.
     *
     * @return `true` if the timeout was already running, else `false`
     */
gboolean
geary_timeout_manager_reset (GearyTimeoutManager* self)
{
	gboolean _tmp0_;
	gboolean _tmp1_;
	gboolean _tmp2_;
	gboolean _tmp3_;
	gboolean result;
	g_return_val_if_fail (GEARY_IS_TIMEOUT_MANAGER (self), FALSE);
	_tmp0_ = geary_timeout_manager_get_is_running (self);
	_tmp1_ = _tmp0_;
	if (_tmp1_) {
		g_source_remove ((guint) self->priv->source_id);
		self->priv->source_id = (gint64) -1;
	}
	_tmp2_ = geary_timeout_manager_get_is_running (self);
	_tmp3_ = _tmp2_;
	result = _tmp3_;
	return result;
}

static gboolean
geary_timeout_manager_execute (GearyTimeoutManager* self)
{
	gboolean ret = FALSE;
	GearyTimeoutManagerTimeoutFunc _tmp0_;
	gpointer _tmp0__target;
	gboolean result;
	g_return_val_if_fail (GEARY_IS_TIMEOUT_MANAGER (self), FALSE);
	ret = G_SOURCE_CONTINUE;
	if (self->repetition == GEARY_TIMEOUT_MANAGER_REPEAT_ONCE) {
		self->priv->source_id = (gint64) -1;
		ret = G_SOURCE_REMOVE;
	}
	_tmp0_ = self->priv->callback;
	_tmp0__target = self->priv->callback_target;
	_tmp0_ (self, _tmp0__target);
	result = ret;
	return result;
}

GearyTimeoutManager*
geary_timeout_manager_construct (GType object_type)
{
	GearyTimeoutManager * self = NULL;
	self = (GearyTimeoutManager*) geary_base_object_construct (object_type);
	return self;
}

GearyTimeoutManager*
geary_timeout_manager_new (void)
{
	return geary_timeout_manager_construct (GEARY_TYPE_TIMEOUT_MANAGER);
}

static inline gpointer
geary_timeout_manager_handler_ref_get_instance_private (GearyTimeoutManagerHandlerRef* self)
{
	return G_STRUCT_MEMBER_P (self, GearyTimeoutManagerHandlerRef_private_offset);
}

static GearyTimeoutManagerHandlerRef*
geary_timeout_manager_handler_ref_construct (GType object_type,
                                             GearyTimeoutManager* manager)
{
	GearyTimeoutManagerHandlerRef * self = NULL;
	g_return_val_if_fail (GEARY_IS_TIMEOUT_MANAGER (manager), NULL);
	self = (GearyTimeoutManagerHandlerRef*) g_object_new (object_type, NULL);
	g_weak_ref_clear (&self->priv->manager);
	g_weak_ref_init (&self->priv->manager, G_TYPE_CHECK_INSTANCE_CAST (manager, G_TYPE_OBJECT, GObject));
	return self;
}

static GearyTimeoutManagerHandlerRef*
geary_timeout_manager_handler_ref_new (GearyTimeoutManager* manager)
{
	return geary_timeout_manager_handler_ref_construct (GEARY_TIMEOUT_MANAGER_TYPE_HANDLER_REF, manager);
}

static gboolean
geary_timeout_manager_handler_ref_execute (GearyTimeoutManagerHandlerRef* self)
{
	gboolean ret = FALSE;
	GearyTimeoutManager* manager = NULL;
	GObject* _tmp0_;
	GearyTimeoutManager* _tmp1_;
	GearyTimeoutManager* _tmp2_;
	gboolean result;
	g_return_val_if_fail (GEARY_TIMEOUT_MANAGER_IS_HANDLER_REF (self), FALSE);
	ret = G_SOURCE_REMOVE;
	_tmp0_ = g_weak_ref_get (&self->priv->manager);
	_tmp1_ = GEARY_IS_TIMEOUT_MANAGER (_tmp0_) ? ((GearyTimeoutManager*) _tmp0_) : NULL;
	if (_tmp1_ == NULL) {
		_g_object_unref0 (_tmp0_);
	}
	manager = _tmp1_;
	_tmp2_ = manager;
	if (_tmp2_ != NULL) {
		GearyTimeoutManager* _tmp3_;
		_tmp3_ = manager;
		ret = geary_timeout_manager_execute (_tmp3_);
	}
	result = ret;
	_g_object_unref0 (manager);
	return result;
}

static void
geary_timeout_manager_handler_ref_class_init (GearyTimeoutManagerHandlerRefClass * klass,
                                              gpointer klass_data)
{
	geary_timeout_manager_handler_ref_parent_class = g_type_class_peek_parent (klass);
	g_type_class_adjust_private_offset (klass, &GearyTimeoutManagerHandlerRef_private_offset);
	G_OBJECT_CLASS (klass)->finalize = geary_timeout_manager_handler_ref_finalize;
}

static void
geary_timeout_manager_handler_ref_instance_init (GearyTimeoutManagerHandlerRef * self,
                                                 gpointer klass)
{
	self->priv = geary_timeout_manager_handler_ref_get_instance_private (self);
}

static void
geary_timeout_manager_handler_ref_finalize (GObject * obj)
{
	GearyTimeoutManagerHandlerRef * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, GEARY_TIMEOUT_MANAGER_TYPE_HANDLER_REF, GearyTimeoutManagerHandlerRef);
	g_weak_ref_clear (&self->priv->manager);
	G_OBJECT_CLASS (geary_timeout_manager_handler_ref_parent_class)->finalize (obj);
}

 G_GNUC_NO_INLINE static GType
geary_timeout_manager_handler_ref_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (GearyTimeoutManagerHandlerRefClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) geary_timeout_manager_handler_ref_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (GearyTimeoutManagerHandlerRef), 0, (GInstanceInitFunc) geary_timeout_manager_handler_ref_instance_init, NULL };
	GType geary_timeout_manager_handler_ref_type_id;
	geary_timeout_manager_handler_ref_type_id = g_type_register_static (G_TYPE_OBJECT, "GearyTimeoutManagerHandlerRef", &g_define_type_info, 0);
	GearyTimeoutManagerHandlerRef_private_offset = g_type_add_instance_private (geary_timeout_manager_handler_ref_type_id, sizeof (GearyTimeoutManagerHandlerRefPrivate));
	return geary_timeout_manager_handler_ref_type_id;
}

static GType
geary_timeout_manager_handler_ref_get_type (void)
{
	static gsize geary_timeout_manager_handler_ref_type_id__once = 0;
	if (g_once_init_enter (&geary_timeout_manager_handler_ref_type_id__once)) {
		GType geary_timeout_manager_handler_ref_type_id;
		geary_timeout_manager_handler_ref_type_id = geary_timeout_manager_handler_ref_get_type_once ();
		g_once_init_leave (&geary_timeout_manager_handler_ref_type_id__once, geary_timeout_manager_handler_ref_type_id);
	}
	return geary_timeout_manager_handler_ref_type_id__once;
}

static void
geary_timeout_manager_class_init (GearyTimeoutManagerClass * klass,
                                  gpointer klass_data)
{
	geary_timeout_manager_parent_class = g_type_class_peek_parent (klass);
	g_type_class_adjust_private_offset (klass, &GearyTimeoutManager_private_offset);
	G_OBJECT_CLASS (klass)->get_property = _vala_geary_timeout_manager_get_property;
	G_OBJECT_CLASS (klass)->finalize = geary_timeout_manager_finalize;
	/** Determines if the timeout is waiting to fire or not. */
	g_object_class_install_property (G_OBJECT_CLASS (klass), GEARY_TIMEOUT_MANAGER_IS_RUNNING_PROPERTY, geary_timeout_manager_properties[GEARY_TIMEOUT_MANAGER_IS_RUNNING_PROPERTY] = g_param_spec_boolean ("is-running", "is-running", "is-running", FALSE, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
}

static void
geary_timeout_manager_instance_init (GearyTimeoutManager * self,
                                     gpointer klass)
{
	self->priv = geary_timeout_manager_get_instance_private (self);
	self->repetition = GEARY_TIMEOUT_MANAGER_REPEAT_ONCE;
	self->priority = GEARY_TIMEOUT_MANAGER_PRIORITY_DEFAULT;
	self->priv->source_id = (gint64) -1;
}

static void
geary_timeout_manager_finalize (GObject * obj)
{
	GearyTimeoutManager * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, GEARY_TYPE_TIMEOUT_MANAGER, GearyTimeoutManager);
	geary_timeout_manager_reset (self);
	G_OBJECT_CLASS (geary_timeout_manager_parent_class)->finalize (obj);
}

/**
 * Executes a function after a certain period of time has elapsed.
 *
 * This class is a convenience API for the GLib main loop and source
 * infrastructure, automatically performing cleanup when destroyed.
 *
 * Note this class is not thread safe and should only be invoked from
 * the main loop.
 */
 G_GNUC_NO_INLINE static GType
geary_timeout_manager_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (GearyTimeoutManagerClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) geary_timeout_manager_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (GearyTimeoutManager), 0, (GInstanceInitFunc) geary_timeout_manager_instance_init, NULL };
	GType geary_timeout_manager_type_id;
	geary_timeout_manager_type_id = g_type_register_static (GEARY_TYPE_BASE_OBJECT, "GearyTimeoutManager", &g_define_type_info, 0);
	GearyTimeoutManager_private_offset = g_type_add_instance_private (geary_timeout_manager_type_id, sizeof (GearyTimeoutManagerPrivate));
	return geary_timeout_manager_type_id;
}

GType
geary_timeout_manager_get_type (void)
{
	static gsize geary_timeout_manager_type_id__once = 0;
	if (g_once_init_enter (&geary_timeout_manager_type_id__once)) {
		GType geary_timeout_manager_type_id;
		geary_timeout_manager_type_id = geary_timeout_manager_get_type_once ();
		g_once_init_leave (&geary_timeout_manager_type_id__once, geary_timeout_manager_type_id);
	}
	return geary_timeout_manager_type_id__once;
}

static void
_vala_geary_timeout_manager_get_property (GObject * object,
                                          guint property_id,
                                          GValue * value,
                                          GParamSpec * pspec)
{
	GearyTimeoutManager * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (object, GEARY_TYPE_TIMEOUT_MANAGER, GearyTimeoutManager);
	switch (property_id) {
		case GEARY_TIMEOUT_MANAGER_IS_RUNNING_PROPERTY:
		g_value_set_boolean (value, geary_timeout_manager_get_is_running (self));
		break;
		default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
	}
}

