/* util-idle-manager.c generated by valac 0.56.3, the Vala compiler
 * generated from util-idle-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_IDLE_MANAGER_0_PROPERTY,
	GEARY_IDLE_MANAGER_IS_RUNNING_PROPERTY,
	GEARY_IDLE_MANAGER_NUM_PROPERTIES
};
static GParamSpec* geary_idle_manager_properties[GEARY_IDLE_MANAGER_NUM_PROPERTIES];

#define GEARY_IDLE_MANAGER_TYPE_HANDLER_REF (geary_idle_manager_handler_ref_get_type ())
#define GEARY_IDLE_MANAGER_HANDLER_REF(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEARY_IDLE_MANAGER_TYPE_HANDLER_REF, GearyIdleManagerHandlerRef))
#define GEARY_IDLE_MANAGER_HANDLER_REF_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GEARY_IDLE_MANAGER_TYPE_HANDLER_REF, GearyIdleManagerHandlerRefClass))
#define GEARY_IDLE_MANAGER_IS_HANDLER_REF(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GEARY_IDLE_MANAGER_TYPE_HANDLER_REF))
#define GEARY_IDLE_MANAGER_IS_HANDLER_REF_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GEARY_IDLE_MANAGER_TYPE_HANDLER_REF))
#define GEARY_IDLE_MANAGER_HANDLER_REF_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GEARY_IDLE_MANAGER_TYPE_HANDLER_REF, GearyIdleManagerHandlerRefClass))

typedef struct _GearyIdleManagerHandlerRef GearyIdleManagerHandlerRef;
typedef struct _GearyIdleManagerHandlerRefClass GearyIdleManagerHandlerRefClass;
#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))
typedef struct _GearyIdleManagerHandlerRefPrivate GearyIdleManagerHandlerRefPrivate;
enum  {
	GEARY_IDLE_MANAGER_HANDLER_REF_0_PROPERTY,
	GEARY_IDLE_MANAGER_HANDLER_REF_NUM_PROPERTIES
};
static GParamSpec* geary_idle_manager_handler_ref_properties[GEARY_IDLE_MANAGER_HANDLER_REF_NUM_PROPERTIES];

struct _GearyIdleManagerPrivate {
	GearyIdleManagerIdleFunc callback;
	gpointer callback_target;
	gint64 source_id;
};

struct _GearyIdleManagerHandlerRef {
	GObject parent_instance;
	GearyIdleManagerHandlerRefPrivate * priv;
};

struct _GearyIdleManagerHandlerRefClass {
	GObjectClass parent_class;
};

struct _GearyIdleManagerHandlerRefPrivate {
	GWeakRef manager;
};

static gint GearyIdleManager_private_offset;
static gpointer geary_idle_manager_parent_class = NULL;
static gint GearyIdleManagerHandlerRef_private_offset;
static gpointer geary_idle_manager_handler_ref_parent_class = NULL;

static GType geary_idle_manager_handler_ref_get_type (void) G_GNUC_CONST  G_GNUC_UNUSED ;
static GearyIdleManagerHandlerRef* geary_idle_manager_handler_ref_new (GearyIdleManager* manager);
static GearyIdleManagerHandlerRef* geary_idle_manager_handler_ref_construct (GType object_type,
                                                                      GearyIdleManager* manager);
static gboolean geary_idle_manager_handler_ref_execute (GearyIdleManagerHandlerRef* self);
static gboolean _geary_idle_manager_handler_ref_execute_gsource_func (gpointer self);
static gboolean geary_idle_manager_execute (GearyIdleManager* self);
static void geary_idle_manager_handler_ref_finalize (GObject * obj);
static GType geary_idle_manager_handler_ref_get_type_once (void);
static void geary_idle_manager_finalize (GObject * obj);
static GType geary_idle_manager_get_type_once (void);
static void _vala_geary_idle_manager_get_property (GObject * object,
                                            guint property_id,
                                            GValue * value,
                                            GParamSpec * pspec);

static inline gpointer
geary_idle_manager_get_instance_private (GearyIdleManager* self)
{
	return G_STRUCT_MEMBER_P (self, GearyIdleManager_private_offset);
}

/** Specifies the priority the idle function should be given. */
 G_GNUC_NO_INLINE static GType
geary_idle_manager_priority_get_type_once (void)
{
	static const GEnumValue values[] = {{GEARY_IDLE_MANAGER_PRIORITY_HIGH, "GEARY_IDLE_MANAGER_PRIORITY_HIGH", "high"}, {GEARY_IDLE_MANAGER_PRIORITY_DEFAULT, "GEARY_IDLE_MANAGER_PRIORITY_DEFAULT", "default"}, {GEARY_IDLE_MANAGER_PRIORITY_HIGH_IDLE, "GEARY_IDLE_MANAGER_PRIORITY_HIGH_IDLE", "high-idle"}, {GEARY_IDLE_MANAGER_PRIORITY_DEFAULT_IDLE, "GEARY_IDLE_MANAGER_PRIORITY_DEFAULT_IDLE", "default-idle"}, {GEARY_IDLE_MANAGER_PRIORITY_LOW, "GEARY_IDLE_MANAGER_PRIORITY_LOW", "low"}, {0, NULL, NULL}};
	GType geary_idle_manager_priority_type_id;
	geary_idle_manager_priority_type_id = g_enum_register_static ("GearyIdleManagerPriority", values);
	return geary_idle_manager_priority_type_id;
}

GType
geary_idle_manager_priority_get_type (void)
{
	static gsize geary_idle_manager_priority_type_id__once = 0;
	if (g_once_init_enter (&geary_idle_manager_priority_type_id__once)) {
		GType geary_idle_manager_priority_type_id;
		geary_idle_manager_priority_type_id = geary_idle_manager_priority_get_type_once ();
		g_once_init_leave (&geary_idle_manager_priority_type_id__once, geary_idle_manager_priority_type_id);
	}
	return geary_idle_manager_priority_type_id__once;
}

/** Specifies if the idle function should run once or be continuously. */
 G_GNUC_NO_INLINE static GType
geary_idle_manager_repeat_get_type_once (void)
{
	static const GEnumValue values[] = {{GEARY_IDLE_MANAGER_REPEAT_ONCE, "GEARY_IDLE_MANAGER_REPEAT_ONCE", "once"}, {GEARY_IDLE_MANAGER_REPEAT_FOREVER, "GEARY_IDLE_MANAGER_REPEAT_FOREVER", "forever"}, {0, NULL, NULL}};
	GType geary_idle_manager_repeat_type_id;
	geary_idle_manager_repeat_type_id = g_enum_register_static ("GearyIdleManagerRepeat", values);
	return geary_idle_manager_repeat_type_id;
}

GType
geary_idle_manager_repeat_get_type (void)
{
	static gsize geary_idle_manager_repeat_type_id__once = 0;
	if (g_once_init_enter (&geary_idle_manager_repeat_type_id__once)) {
		GType geary_idle_manager_repeat_type_id;
		geary_idle_manager_repeat_type_id = geary_idle_manager_repeat_get_type_once ();
		g_once_init_leave (&geary_idle_manager_repeat_type_id__once, geary_idle_manager_repeat_type_id);
	}
	return geary_idle_manager_repeat_type_id__once;
}

gboolean
geary_idle_manager_get_is_running (GearyIdleManager* self)
{
	gboolean result;
	g_return_val_if_fail (GEARY_IS_IDLE_MANAGER (self), FALSE);
	result = self->priv->source_id >= ((gint64) 0);
	return result;
}

/**
     * Constructs a new idle manager with an interval in seconds.
     *
     * The idle function will be by default not running, and hence
     * needs to be started by a call to {@link schedule}.
     */
GearyIdleManager*
geary_idle_manager_construct (GType object_type,
                              GearyIdleManagerIdleFunc callback,
                              gpointer callback_target)
{
	GearyIdleManager * self = NULL;
	self = (GearyIdleManager*) geary_base_object_construct (object_type);
	self->priv->callback = callback;
	self->priv->callback_target = callback_target;
	return self;
}

GearyIdleManager*
geary_idle_manager_new (GearyIdleManagerIdleFunc callback,
                        gpointer callback_target)
{
	return geary_idle_manager_construct (GEARY_TYPE_IDLE_MANAGER, callback, callback_target);
}

/**
     * Schedules the idle function to run on the main loop.
     *
     * If the function is already waiting to run, it will first be reset.
     */
static gboolean
_geary_idle_manager_handler_ref_execute_gsource_func (gpointer self)
{
	gboolean result;
	result = geary_idle_manager_handler_ref_execute ((GearyIdleManagerHandlerRef*) self);
	return result;
}

void
geary_idle_manager_schedule (GearyIdleManager* self)
{
	GearyIdleManagerHandlerRef* handler = NULL;
	GearyIdleManagerHandlerRef* _tmp0_;
	g_return_if_fail (GEARY_IS_IDLE_MANAGER (self));
	geary_idle_manager_reset (self);
	_tmp0_ = geary_idle_manager_handler_ref_new (self);
	handler = _tmp0_;
	self->priv->source_id = (gint64) ((gint) g_idle_add_full ((gint) self->priority, _geary_idle_manager_handler_ref_execute_gsource_func, g_object_ref (handler), g_object_unref));
	_g_object_unref0 (handler);
}

/**
     * Prevents the idle function from being run.
     *
     * @return `true` if function was already scheduled, else `false`
     */
gboolean
geary_idle_manager_reset (GearyIdleManager* self)
{
	gboolean _tmp0_;
	gboolean _tmp1_;
	gboolean _tmp2_;
	gboolean _tmp3_;
	gboolean result;
	g_return_val_if_fail (GEARY_IS_IDLE_MANAGER (self), FALSE);
	_tmp0_ = geary_idle_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_idle_manager_get_is_running (self);
	_tmp3_ = _tmp2_;
	result = _tmp3_;
	return result;
}

static gboolean
geary_idle_manager_execute (GearyIdleManager* self)
{
	gboolean ret = FALSE;
	GearyIdleManagerIdleFunc callback = NULL;
	GearyIdleManagerIdleFunc _tmp0_;
	gpointer _tmp0__target;
	gpointer callback_target;
	GearyIdleManagerIdleFunc _tmp1_;
	gpointer _tmp1__target;
	GearyIdleManagerIdleFunc _tmp3_;
	gpointer _tmp3__target;
	gboolean result;
	g_return_val_if_fail (GEARY_IS_IDLE_MANAGER (self), FALSE);
	ret = G_SOURCE_CONTINUE;
	if (self->repetition == GEARY_IDLE_MANAGER_REPEAT_ONCE) {
		self->priv->source_id = (gint64) -1;
		ret = G_SOURCE_REMOVE;
	}
	_tmp0_ = self->priv->callback;
	_tmp0__target = self->priv->callback_target;
	callback = _tmp0_;
	callback_target = _tmp0__target;
	_tmp1_ = callback;
	_tmp1__target = callback_target;
	if (_tmp1_ != NULL) {
		GearyIdleManagerIdleFunc _tmp2_;
		gpointer _tmp2__target;
		_tmp2_ = callback;
		_tmp2__target = callback_target;
		_tmp2_ (self, _tmp2__target);
	} else {
		ret = G_SOURCE_REMOVE;
	}
	_tmp3_ = callback;
	_tmp3__target = callback_target;
	_tmp3_ (self, _tmp3__target);
	result = ret;
	return result;
}

static inline gpointer
geary_idle_manager_handler_ref_get_instance_private (GearyIdleManagerHandlerRef* self)
{
	return G_STRUCT_MEMBER_P (self, GearyIdleManagerHandlerRef_private_offset);
}

static GearyIdleManagerHandlerRef*
geary_idle_manager_handler_ref_construct (GType object_type,
                                          GearyIdleManager* manager)
{
	GearyIdleManagerHandlerRef * self = NULL;
	g_return_val_if_fail (GEARY_IS_IDLE_MANAGER (manager), NULL);
	self = (GearyIdleManagerHandlerRef*) 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 GearyIdleManagerHandlerRef*
geary_idle_manager_handler_ref_new (GearyIdleManager* manager)
{
	return geary_idle_manager_handler_ref_construct (GEARY_IDLE_MANAGER_TYPE_HANDLER_REF, manager);
}

static gboolean
geary_idle_manager_handler_ref_execute (GearyIdleManagerHandlerRef* self)
{
	gboolean ret = FALSE;
	GearyIdleManager* manager = NULL;
	GObject* _tmp0_;
	GearyIdleManager* _tmp1_;
	GearyIdleManager* _tmp2_;
	gboolean result;
	g_return_val_if_fail (GEARY_IDLE_MANAGER_IS_HANDLER_REF (self), FALSE);
	ret = G_SOURCE_REMOVE;
	_tmp0_ = g_weak_ref_get (&self->priv->manager);
	_tmp1_ = GEARY_IS_IDLE_MANAGER (_tmp0_) ? ((GearyIdleManager*) _tmp0_) : NULL;
	if (_tmp1_ == NULL) {
		_g_object_unref0 (_tmp0_);
	}
	manager = _tmp1_;
	_tmp2_ = manager;
	if (_tmp2_ != NULL) {
		GearyIdleManager* _tmp3_;
		_tmp3_ = manager;
		ret = geary_idle_manager_execute (_tmp3_);
	}
	result = ret;
	_g_object_unref0 (manager);
	return result;
}

static void
geary_idle_manager_handler_ref_class_init (GearyIdleManagerHandlerRefClass * klass,
                                           gpointer klass_data)
{
	geary_idle_manager_handler_ref_parent_class = g_type_class_peek_parent (klass);
	g_type_class_adjust_private_offset (klass, &GearyIdleManagerHandlerRef_private_offset);
	G_OBJECT_CLASS (klass)->finalize = geary_idle_manager_handler_ref_finalize;
}

static void
geary_idle_manager_handler_ref_instance_init (GearyIdleManagerHandlerRef * self,
                                              gpointer klass)
{
	self->priv = geary_idle_manager_handler_ref_get_instance_private (self);
}

static void
geary_idle_manager_handler_ref_finalize (GObject * obj)
{
	GearyIdleManagerHandlerRef * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, GEARY_IDLE_MANAGER_TYPE_HANDLER_REF, GearyIdleManagerHandlerRef);
	g_weak_ref_clear (&self->priv->manager);
	G_OBJECT_CLASS (geary_idle_manager_handler_ref_parent_class)->finalize (obj);
}

 G_GNUC_NO_INLINE static GType
geary_idle_manager_handler_ref_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (GearyIdleManagerHandlerRefClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) geary_idle_manager_handler_ref_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (GearyIdleManagerHandlerRef), 0, (GInstanceInitFunc) geary_idle_manager_handler_ref_instance_init, NULL };
	GType geary_idle_manager_handler_ref_type_id;
	geary_idle_manager_handler_ref_type_id = g_type_register_static (G_TYPE_OBJECT, "GearyIdleManagerHandlerRef", &g_define_type_info, 0);
	GearyIdleManagerHandlerRef_private_offset = g_type_add_instance_private (geary_idle_manager_handler_ref_type_id, sizeof (GearyIdleManagerHandlerRefPrivate));
	return geary_idle_manager_handler_ref_type_id;
}

static GType
geary_idle_manager_handler_ref_get_type (void)
{
	static gsize geary_idle_manager_handler_ref_type_id__once = 0;
	if (g_once_init_enter (&geary_idle_manager_handler_ref_type_id__once)) {
		GType geary_idle_manager_handler_ref_type_id;
		geary_idle_manager_handler_ref_type_id = geary_idle_manager_handler_ref_get_type_once ();
		g_once_init_leave (&geary_idle_manager_handler_ref_type_id__once, geary_idle_manager_handler_ref_type_id);
	}
	return geary_idle_manager_handler_ref_type_id__once;
}

static void
geary_idle_manager_class_init (GearyIdleManagerClass * klass,
                               gpointer klass_data)
{
	geary_idle_manager_parent_class = g_type_class_peek_parent (klass);
	g_type_class_adjust_private_offset (klass, &GearyIdleManager_private_offset);
	G_OBJECT_CLASS (klass)->get_property = _vala_geary_idle_manager_get_property;
	G_OBJECT_CLASS (klass)->finalize = geary_idle_manager_finalize;
	/** Determines if the function is waiting to fire or not. */
	g_object_class_install_property (G_OBJECT_CLASS (klass), GEARY_IDLE_MANAGER_IS_RUNNING_PROPERTY, geary_idle_manager_properties[GEARY_IDLE_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_idle_manager_instance_init (GearyIdleManager * self,
                                  gpointer klass)
{
	self->priv = geary_idle_manager_get_instance_private (self);
	self->repetition = GEARY_IDLE_MANAGER_REPEAT_ONCE;
	self->priority = GEARY_IDLE_MANAGER_PRIORITY_DEFAULT;
	self->priv->source_id = (gint64) -1;
}

static void
geary_idle_manager_finalize (GObject * obj)
{
	GearyIdleManager * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, GEARY_TYPE_IDLE_MANAGER, GearyIdleManager);
	geary_idle_manager_reset (self);
	G_OBJECT_CLASS (geary_idle_manager_parent_class)->finalize (obj);
}

/**
 * Manages execution of a function on the main loop.
 *
 * 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_idle_manager_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (GearyIdleManagerClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) geary_idle_manager_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (GearyIdleManager), 0, (GInstanceInitFunc) geary_idle_manager_instance_init, NULL };
	GType geary_idle_manager_type_id;
	geary_idle_manager_type_id = g_type_register_static (GEARY_TYPE_BASE_OBJECT, "GearyIdleManager", &g_define_type_info, 0);
	GearyIdleManager_private_offset = g_type_add_instance_private (geary_idle_manager_type_id, sizeof (GearyIdleManagerPrivate));
	return geary_idle_manager_type_id;
}

GType
geary_idle_manager_get_type (void)
{
	static gsize geary_idle_manager_type_id__once = 0;
	if (g_once_init_enter (&geary_idle_manager_type_id__once)) {
		GType geary_idle_manager_type_id;
		geary_idle_manager_type_id = geary_idle_manager_get_type_once ();
		g_once_init_leave (&geary_idle_manager_type_id__once, geary_idle_manager_type_id);
	}
	return geary_idle_manager_type_id__once;
}

static void
_vala_geary_idle_manager_get_property (GObject * object,
                                       guint property_id,
                                       GValue * value,
                                       GParamSpec * pspec)
{
	GearyIdleManager * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (object, GEARY_TYPE_IDLE_MANAGER, GearyIdleManager);
	switch (property_id) {
		case GEARY_IDLE_MANAGER_IS_RUNNING_PROPERTY:
		g_value_set_boolean (value, geary_idle_manager_get_is_running (self));
		break;
		default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
	}
}

