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

/* -*- Mode: Vala; indent-tabs-mode: nil; tab-width: 4 -*-
 *
 * Copyright (C) 2011,2012 Canonical Ltd
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 3 as
 * published by the Free Software Foundation.
 *
 * 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, see <http://www.gnu.org/licenses/>.
 *
 * Authors: Robert Ancell <robert.ancell@canonical.com>
 *          Michael Terry <michael.terry@canonical.com>
 */

#include <glib-object.h>
#include <glib.h>
#include <float.h>
#include <math.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
#if !defined(VALA_EXTERN)
#if defined(_MSC_VER)
#define VALA_EXTERN __declspec(dllexport) extern
#elif __GNUC__ >= 4
#define VALA_EXTERN __attribute__((visibility("default"))) extern
#else
#define VALA_EXTERN extern
#endif
#endif

#define ANIMATION_TYPE_ANIMATE_TIMER (animation_animate_timer_get_type ())
#define ANIMATION_ANIMATE_TIMER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), ANIMATION_TYPE_ANIMATE_TIMER, AnimationAnimateTimer))
#define ANIMATION_ANIMATE_TIMER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), ANIMATION_TYPE_ANIMATE_TIMER, AnimationAnimateTimerClass))
#define ANIMATION_IS_ANIMATE_TIMER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), ANIMATION_TYPE_ANIMATE_TIMER))
#define ANIMATION_IS_ANIMATE_TIMER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), ANIMATION_TYPE_ANIMATE_TIMER))
#define ANIMATION_ANIMATE_TIMER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), ANIMATION_TYPE_ANIMATE_TIMER, AnimationAnimateTimerClass))

typedef struct _AnimationAnimateTimer AnimationAnimateTimer;
typedef struct _AnimationAnimateTimerClass AnimationAnimateTimerClass;
typedef struct _AnimationAnimateTimerPrivate AnimationAnimateTimerPrivate;
typedef gdouble (*AnimationAnimateTimerEasingFunc) (gdouble x, gpointer user_data);
enum  {
	ANIMATION_ANIMATE_TIMER_0_PROPERTY,
	ANIMATION_ANIMATE_TIMER_IS_RUNNING_PROPERTY,
	ANIMATION_ANIMATE_TIMER_PROGRESS_PROPERTY,
	ANIMATION_ANIMATE_TIMER_SPEED_PROPERTY,
	ANIMATION_ANIMATE_TIMER_NUM_PROPERTIES
};
static GParamSpec* animation_animate_timer_properties[ANIMATION_ANIMATE_TIMER_NUM_PROPERTIES];
enum  {
	ANIMATION_ANIMATE_TIMER_ANIMATE_SIGNAL,
	ANIMATION_ANIMATE_TIMER_NUM_SIGNALS
};
static guint animation_animate_timer_signals[ANIMATION_ANIMATE_TIMER_NUM_SIGNALS] = {0};

struct _AnimationAnimateTimer {
	GObject parent_instance;
	AnimationAnimateTimerPrivate * priv;
};

struct _AnimationAnimateTimerClass {
	GObjectClass parent_class;
};

struct _AnimationAnimateTimerPrivate {
	gdouble _progress;
	gint _speed;
	AnimationAnimateTimerEasingFunc _easing_func;
	gpointer _easing_func_target;
	GTimeSpan extra_time;
	GTimeSpan length;
	GTimeSpan start_time;
	gdouble extra_progress;
	guint timeout;
};

static gint AnimationAnimateTimer_private_offset;
static gpointer animation_animate_timer_parent_class = NULL;

VALA_EXTERN GType animation_animate_timer_get_type (void) G_GNUC_CONST ;
G_DEFINE_AUTOPTR_CLEANUP_FUNC (AnimationAnimateTimer, g_object_unref)
VALA_EXTERN void animation_animate_timer_stop (AnimationAnimateTimer* self);
VALA_EXTERN AnimationAnimateTimer* animation_animate_timer_new (AnimationAnimateTimerEasingFunc func,
                                                    gpointer func_target,
                                                    gint speed);
VALA_EXTERN AnimationAnimateTimer* animation_animate_timer_construct (GType object_type,
                                                          AnimationAnimateTimerEasingFunc func,
                                                          gpointer func_target,
                                                          gint speed);
static void animation_animate_timer_set_easing_func (AnimationAnimateTimer* self,
                                              AnimationAnimateTimerEasingFunc value,
                                              gpointer value_target);
VALA_EXTERN void animation_animate_timer_reset (AnimationAnimateTimer* self,
                                    gint temp_speed);
static gboolean animation_animate_timer_animate_cb (AnimationAnimateTimer* self);
static gboolean _animation_animate_timer_animate_cb_gsource_func (gpointer self);
static void animation_animate_timer_set_progress (AnimationAnimateTimer* self,
                                           gdouble value);
VALA_EXTERN gint animation_animate_timer_get_speed (AnimationAnimateTimer* self);
static gdouble animation_animate_timer_normalize_time (AnimationAnimateTimer* self,
                                                GTimeSpan now);
static gdouble animation_animate_timer_calculate_progress (AnimationAnimateTimer* self,
                                                    gdouble time_progress);
VALA_EXTERN gdouble animation_animate_timer_get_progress (AnimationAnimateTimer* self);
VALA_EXTERN AnimationAnimateTimerEasingFunc animation_animate_timer_get_easing_func (AnimationAnimateTimer* self,
                                                                         gpointer* result_target);
VALA_EXTERN gdouble animation_animate_timer_ease_in_out (gdouble x);
VALA_EXTERN gdouble animation_animate_timer_ease_in_quad (gdouble x);
VALA_EXTERN gdouble animation_animate_timer_ease_out_quad (gdouble x);
VALA_EXTERN gdouble animation_animate_timer_ease_in_quint (gdouble x);
VALA_EXTERN gdouble animation_animate_timer_ease_out_quint (gdouble x);
VALA_EXTERN gboolean animation_animate_timer_get_is_running (AnimationAnimateTimer* self);
VALA_EXTERN void animation_animate_timer_set_speed (AnimationAnimateTimer* self,
                                        gint value);
static void animation_animate_timer_finalize (GObject * obj);
static GType animation_animate_timer_get_type_once (void);
static void _vala_animation_animate_timer_get_property (GObject * object,
                                                 guint property_id,
                                                 GValue * value,
                                                 GParamSpec * pspec);
static void _vala_animation_animate_timer_set_property (GObject * object,
                                                 guint property_id,
                                                 const GValue * value,
                                                 GParamSpec * pspec);

static inline gpointer
animation_animate_timer_get_instance_private (AnimationAnimateTimer* self)
{
	return G_STRUCT_MEMBER_P (self, AnimationAnimateTimer_private_offset);
}

AnimationAnimateTimer*
animation_animate_timer_construct (GType object_type,
                                   AnimationAnimateTimerEasingFunc func,
                                   gpointer func_target,
                                   gint speed)
{
	AnimationAnimateTimer * self = NULL;
	self = (AnimationAnimateTimer*) g_object_new (object_type, "speed", speed, NULL);
	animation_animate_timer_set_easing_func (self, func, func_target);
	return self;
}

AnimationAnimateTimer*
animation_animate_timer_new (AnimationAnimateTimerEasingFunc func,
                             gpointer func_target,
                             gint speed)
{
	return animation_animate_timer_construct (ANIMATION_TYPE_ANIMATE_TIMER, func, func_target, speed);
}

static gboolean
_animation_animate_timer_animate_cb_gsource_func (gpointer self)
{
	gboolean result;
	result = animation_animate_timer_animate_cb ((AnimationAnimateTimer*) self);
	return result;
}

void
animation_animate_timer_reset (AnimationAnimateTimer* self,
                               gint temp_speed)
{
	g_return_if_fail (self != NULL);
	animation_animate_timer_stop (self);
	self->priv->timeout = g_timeout_add_full (G_PRIORITY_DEFAULT, (guint) 16, _animation_animate_timer_animate_cb_gsource_func, g_object_ref (self), g_object_unref);
	animation_animate_timer_set_progress (self, (gdouble) 0);
	self->priv->start_time = (GTimeSpan) 0;
	self->priv->extra_time = (GTimeSpan) 0;
	self->priv->extra_progress = (gdouble) 0;
	if (temp_speed == -1) {
		gint _tmp0_;
		_tmp0_ = self->priv->_speed;
		temp_speed = _tmp0_;
	}
	self->priv->length = temp_speed * G_TIME_SPAN_MILLISECOND;
}

void
animation_animate_timer_stop (AnimationAnimateTimer* self)
{
	g_return_if_fail (self != NULL);
	if (self->priv->timeout != ((guint) 0)) {
		g_source_remove (self->priv->timeout);
	}
	self->priv->timeout = (guint) 0;
}

static gboolean
animation_animate_timer_animate_cb (AnimationAnimateTimer* self)
{
	gdouble time_progress = 0.0;
	gdouble _tmp0_;
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	if (self->priv->start_time == ((GTimeSpan) 0)) {
		self->priv->start_time = (GTimeSpan) g_get_monotonic_time ();
	}
	time_progress = animation_animate_timer_normalize_time (self, (GTimeSpan) g_get_monotonic_time ());
	animation_animate_timer_set_progress (self, animation_animate_timer_calculate_progress (self, time_progress));
	_tmp0_ = self->priv->_progress;
	g_signal_emit (self, animation_animate_timer_signals[ANIMATION_ANIMATE_TIMER_ANIMATE_SIGNAL], 0, _tmp0_);
	if (time_progress >= 1.0) {
		self->priv->timeout = (guint) 0;
		result = FALSE;
		return result;
	} else {
		result = TRUE;
		return result;
	}
}

static gdouble
animation_animate_timer_normalize_time (AnimationAnimateTimer* self,
                                        GTimeSpan now)
{
	gdouble result;
	g_return_val_if_fail (self != NULL, 0.0);
	if (self->priv->length == ((GTimeSpan) 0)) {
		result = (gdouble) 1.0f;
		return result;
	}
	result = CLAMP (((gdouble) (now - self->priv->start_time)) / self->priv->length, 0.0, 1.0);
	return result;
}

static gdouble
animation_animate_timer_calculate_progress (AnimationAnimateTimer* self,
                                            gdouble time_progress)
{
	gdouble y = 0.0;
	AnimationAnimateTimerEasingFunc _tmp0_ = NULL;
	gpointer _tmp0__target = NULL;
	AnimationAnimateTimerEasingFunc _tmp1_;
	gpointer _tmp1__target;
	gdouble result;
	g_return_val_if_fail (self != NULL, 0.0);
	_tmp0_ = animation_animate_timer_get_easing_func (self, &_tmp0__target);
	_tmp1_ = _tmp0_;
	_tmp1__target = _tmp0__target;
	y = _tmp1_ (time_progress, _tmp1__target);
	result = CLAMP (y, 0.0, 1.0);
	return result;
}

gdouble
animation_animate_timer_ease_in_out (gdouble x)
{
	gdouble result;
	result = (1 - cos (G_PI * x)) / 2;
	return result;
}

gdouble
animation_animate_timer_ease_in_quad (gdouble x)
{
	gdouble result;
	result = pow (x, (gdouble) 2);
	return result;
}

gdouble
animation_animate_timer_ease_out_quad (gdouble x)
{
	gdouble result;
	result = (-1 * pow (x - 1, (gdouble) 2)) + 1;
	return result;
}

gdouble
animation_animate_timer_ease_in_quint (gdouble x)
{
	gdouble result;
	result = pow (x, (gdouble) 5);
	return result;
}

gdouble
animation_animate_timer_ease_out_quint (gdouble x)
{
	gdouble result;
	result = pow (x - 1, (gdouble) 5) + 1;
	return result;
}

gboolean
animation_animate_timer_get_is_running (AnimationAnimateTimer* self)
{
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	result = self->priv->timeout != ((guint) 0);
	return result;
}

gdouble
animation_animate_timer_get_progress (AnimationAnimateTimer* self)
{
	gdouble result;
	g_return_val_if_fail (self != NULL, 0.0);
	result = self->priv->_progress;
	return result;
}

static void
animation_animate_timer_set_progress (AnimationAnimateTimer* self,
                                      gdouble value)
{
	gdouble old_value;
	g_return_if_fail (self != NULL);
	old_value = animation_animate_timer_get_progress (self);
	if (old_value != value) {
		self->priv->_progress = value;
		g_object_notify_by_pspec ((GObject *) self, animation_animate_timer_properties[ANIMATION_ANIMATE_TIMER_PROGRESS_PROPERTY]);
	}
}

gint
animation_animate_timer_get_speed (AnimationAnimateTimer* self)
{
	gint result;
	g_return_val_if_fail (self != NULL, 0);
	result = self->priv->_speed;
	return result;
}

void
animation_animate_timer_set_speed (AnimationAnimateTimer* self,
                                   gint value)
{
	gint old_value;
	g_return_if_fail (self != NULL);
	old_value = animation_animate_timer_get_speed (self);
	if (old_value != value) {
		self->priv->_speed = value;
		g_object_notify_by_pspec ((GObject *) self, animation_animate_timer_properties[ANIMATION_ANIMATE_TIMER_SPEED_PROPERTY]);
	}
}

AnimationAnimateTimerEasingFunc
animation_animate_timer_get_easing_func (AnimationAnimateTimer* self,
                                         gpointer* result_target)
{
	AnimationAnimateTimerEasingFunc result;
	AnimationAnimateTimerEasingFunc _tmp0_;
	gpointer _tmp0__target;
	AnimationAnimateTimerEasingFunc _tmp1_;
	gpointer _tmp1__target;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = self->priv->_easing_func;
	_tmp0__target = self->priv->_easing_func_target;
	_tmp1_ = _tmp0_;
	_tmp1__target = _tmp0__target;
	*result_target = _tmp1__target;
	result = _tmp1_;
	return result;
}

static void
animation_animate_timer_set_easing_func (AnimationAnimateTimer* self,
                                         AnimationAnimateTimerEasingFunc value,
                                         gpointer value_target)
{
	g_return_if_fail (self != NULL);
	self->priv->_easing_func = value;
	self->priv->_easing_func_target = value_target;
}

static void
animation_animate_timer_class_init (AnimationAnimateTimerClass * klass,
                                    gpointer klass_data)
{
	animation_animate_timer_parent_class = g_type_class_peek_parent (klass);
	g_type_class_adjust_private_offset (klass, &AnimationAnimateTimer_private_offset);
	G_OBJECT_CLASS (klass)->get_property = _vala_animation_animate_timer_get_property;
	G_OBJECT_CLASS (klass)->set_property = _vala_animation_animate_timer_set_property;
	G_OBJECT_CLASS (klass)->finalize = animation_animate_timer_finalize;
	g_object_class_install_property (G_OBJECT_CLASS (klass), ANIMATION_ANIMATE_TIMER_IS_RUNNING_PROPERTY, animation_animate_timer_properties[ANIMATION_ANIMATE_TIMER_IS_RUNNING_PROPERTY] = g_param_spec_boolean ("is-running", "is-running", "is-running", FALSE, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
	g_object_class_install_property (G_OBJECT_CLASS (klass), ANIMATION_ANIMATE_TIMER_PROGRESS_PROPERTY, animation_animate_timer_properties[ANIMATION_ANIMATE_TIMER_PROGRESS_PROPERTY] = g_param_spec_double ("progress", "progress", "progress", -G_MAXDOUBLE, G_MAXDOUBLE, 0.0, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
	g_object_class_install_property (G_OBJECT_CLASS (klass), ANIMATION_ANIMATE_TIMER_SPEED_PROPERTY, animation_animate_timer_properties[ANIMATION_ANIMATE_TIMER_SPEED_PROPERTY] = g_param_spec_int ("speed", "speed", "speed", G_MININT, G_MAXINT, 0, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE | G_PARAM_WRITABLE));
	animation_animate_timer_signals[ANIMATION_ANIMATE_TIMER_ANIMATE_SIGNAL] = g_signal_new ("animate", ANIMATION_TYPE_ANIMATE_TIMER, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__DOUBLE, G_TYPE_NONE, 1, G_TYPE_DOUBLE);
}

static void
animation_animate_timer_instance_init (AnimationAnimateTimer * self,
                                       gpointer klass)
{
	self->priv = animation_animate_timer_get_instance_private (self);
	self->priv->extra_time = (GTimeSpan) 0;
	self->priv->length = (GTimeSpan) 0;
	self->priv->start_time = (GTimeSpan) 0;
	self->priv->extra_progress = 0.0;
	self->priv->timeout = (guint) 0;
}

static void
animation_animate_timer_finalize (GObject * obj)
{
	AnimationAnimateTimer * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, ANIMATION_TYPE_ANIMATE_TIMER, AnimationAnimateTimer);
	animation_animate_timer_stop (self);
	G_OBJECT_CLASS (animation_animate_timer_parent_class)->finalize (obj);
}

static GType
animation_animate_timer_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (AnimationAnimateTimerClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) animation_animate_timer_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (AnimationAnimateTimer), 0, (GInstanceInitFunc) animation_animate_timer_instance_init, NULL };
	GType animation_animate_timer_type_id;
	animation_animate_timer_type_id = g_type_register_static (G_TYPE_OBJECT, "AnimationAnimateTimer", &g_define_type_info, 0);
	AnimationAnimateTimer_private_offset = g_type_add_instance_private (animation_animate_timer_type_id, sizeof (AnimationAnimateTimerPrivate));
	return animation_animate_timer_type_id;
}

GType
animation_animate_timer_get_type (void)
{
	static volatile gsize animation_animate_timer_type_id__once = 0;
	if (g_once_init_enter (&animation_animate_timer_type_id__once)) {
		GType animation_animate_timer_type_id;
		animation_animate_timer_type_id = animation_animate_timer_get_type_once ();
		g_once_init_leave (&animation_animate_timer_type_id__once, animation_animate_timer_type_id);
	}
	return animation_animate_timer_type_id__once;
}

static void
_vala_animation_animate_timer_get_property (GObject * object,
                                            guint property_id,
                                            GValue * value,
                                            GParamSpec * pspec)
{
	AnimationAnimateTimer * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (object, ANIMATION_TYPE_ANIMATE_TIMER, AnimationAnimateTimer);
	switch (property_id) {
		case ANIMATION_ANIMATE_TIMER_IS_RUNNING_PROPERTY:
		g_value_set_boolean (value, animation_animate_timer_get_is_running (self));
		break;
		case ANIMATION_ANIMATE_TIMER_PROGRESS_PROPERTY:
		g_value_set_double (value, animation_animate_timer_get_progress (self));
		break;
		case ANIMATION_ANIMATE_TIMER_SPEED_PROPERTY:
		g_value_set_int (value, animation_animate_timer_get_speed (self));
		break;
		default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
	}
}

static void
_vala_animation_animate_timer_set_property (GObject * object,
                                            guint property_id,
                                            const GValue * value,
                                            GParamSpec * pspec)
{
	AnimationAnimateTimer * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (object, ANIMATION_TYPE_ANIMATE_TIMER, AnimationAnimateTimer);
	switch (property_id) {
		case ANIMATION_ANIMATE_TIMER_PROGRESS_PROPERTY:
		animation_animate_timer_set_progress (self, g_value_get_double (value));
		break;
		case ANIMATION_ANIMATE_TIMER_SPEED_PROPERTY:
		animation_animate_timer_set_speed (self, g_value_get_int (value));
		break;
		default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
	}
}

