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

/*
 * This file is part of budgie-desktop
 *
 * Copyright © 2015-2022 Budgie Desktop Developers
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 */
/**<Target value for end of animation */

#include "budgie-private.h"
#include <stdlib.h>
#include <string.h>
#include <glib.h>
#include <glib-object.h>
#include <gtk/gtk.h>
#include <gdk/gdk.h>
#include <float.h>
#include <math.h>

#define _g_free0(var) (var = (g_free (var), NULL))
enum  {
	BUDGIE_ANIMATION_0_PROPERTY,
	BUDGIE_ANIMATION_NUM_PROPERTIES
};
static GParamSpec* budgie_animation_properties[BUDGIE_ANIMATION_NUM_PROPERTIES];
#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))

struct _BudgieAnimationPrivate {
	BudgieAnimCompletionFunc compl;
	gpointer compl_target;
};

static gint BudgieAnimation_private_offset;
static gpointer budgie_animation_parent_class = NULL;

static void _vala_BudgiePropChange_array_free (BudgiePropChange * array,
                                        gssize array_length);
static gboolean budgie_animation_tick_callback (BudgieAnimation* self,
                                         GtkWidget* widget,
                                         GdkFrameClock* frame);
static gboolean _budgie_animation_tick_callback_gtk_tick_callback (GtkWidget* widget,
                                                            GdkFrameClock* frame_clock,
                                                            gpointer self);
static void budgie_animation_finalize (GObject * obj);
static GType budgie_animation_get_type_once (void);

void
budgie_prop_change_copy (const BudgiePropChange* self,
                         BudgiePropChange* dest)
{
	const gchar* _tmp0_;
	gchar* _tmp1_;
	GValue _tmp2_;
	GValue _tmp3_;
	GValue _tmp4_ = {0};
	GValue _tmp5_;
	GValue _tmp6_;
	GValue _tmp7_ = {0};
	_tmp0_ = (*self).property;
	_tmp1_ = g_strdup (_tmp0_);
	_g_free0 ((*dest).property);
	(*dest).property = _tmp1_;
	_tmp2_ = (*self).old;
	_tmp3_ = _tmp2_;
	if (G_IS_VALUE (&_tmp3_)) {
		g_value_init (&_tmp4_, G_VALUE_TYPE (&_tmp3_));
		g_value_copy (&_tmp3_, &_tmp4_);
	} else {
		_tmp4_ = _tmp3_;
	}
	G_IS_VALUE (&(*dest).old) ? (g_value_unset (&(*dest).old), NULL) : NULL;
	(*dest).old = _tmp4_;
	_tmp5_ = (*self).new;
	_tmp6_ = _tmp5_;
	if (G_IS_VALUE (&_tmp6_)) {
		g_value_init (&_tmp7_, G_VALUE_TYPE (&_tmp6_));
		g_value_copy (&_tmp6_, &_tmp7_);
	} else {
		_tmp7_ = _tmp6_;
	}
	G_IS_VALUE (&(*dest).new) ? (g_value_unset (&(*dest).new), NULL) : NULL;
	(*dest).new = _tmp7_;
}

void
budgie_prop_change_destroy (BudgiePropChange* self)
{
	_g_free0 ((*self).property);
	G_IS_VALUE (&(*self).old) ? (g_value_unset (&(*self).old), NULL) : NULL;
	G_IS_VALUE (&(*self).new) ? (g_value_unset (&(*self).new), NULL) : NULL;
}

BudgiePropChange*
budgie_prop_change_dup (const BudgiePropChange* self)
{
	BudgiePropChange* dup;
	dup = g_new0 (BudgiePropChange, 1);
	budgie_prop_change_copy (self, dup);
	return dup;
}

void
budgie_prop_change_free (BudgiePropChange* self)
{
	budgie_prop_change_destroy (self);
	g_free (self);
}

static GType
budgie_prop_change_get_type_once (void)
{
	GType budgie_prop_change_type_id;
	budgie_prop_change_type_id = g_boxed_type_register_static ("BudgiePropChange", (GBoxedCopyFunc) budgie_prop_change_dup, (GBoxedFreeFunc) budgie_prop_change_free);
	return budgie_prop_change_type_id;
}

GType
budgie_prop_change_get_type (void)
{
	static volatile gsize budgie_prop_change_type_id__once = 0;
	if (g_once_init_enter (&budgie_prop_change_type_id__once)) {
		GType budgie_prop_change_type_id;
		budgie_prop_change_type_id = budgie_prop_change_get_type_once ();
		g_once_init_leave (&budgie_prop_change_type_id__once, budgie_prop_change_type_id);
	}
	return budgie_prop_change_type_id__once;
}

static inline gpointer
budgie_animation_get_instance_private (BudgieAnimation* self)
{
	return G_STRUCT_MEMBER_P (self, BudgieAnimation_private_offset);
}

static void
_vala_BudgiePropChange_array_free (BudgiePropChange * array,
                                   gssize array_length)
{
	if (array != NULL) {
		gssize i;
		for (i = 0; i < array_length; i = i + 1) {
			budgie_prop_change_destroy (&array[i]);
		}
	}
	g_free (array);
}

static gboolean
budgie_animation_tick_callback (BudgieAnimation* self,
                                GtkWidget* widget,
                                GdkFrameClock* frame)
{
	gint64 time = 0LL;
	gfloat factor = 0.0F;
	gint64 elapsed = 0LL;
	gboolean _tmp0_ = FALSE;
	gboolean _tmp1_ = FALSE;
	BudgiePropChange* _tmp17_;
	gint _tmp17__length1;
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	g_return_val_if_fail (widget != NULL, FALSE);
	g_return_val_if_fail (frame != NULL, FALSE);
	time = gdk_frame_clock_get_frame_time (frame);
	factor = 0.0f;
	elapsed = time - self->start_time;
	if (elapsed >= self->length) {
		_tmp1_ = TRUE;
	} else {
		_tmp1_ = self->id == ((guint) 0);
	}
	if (_tmp1_) {
		_tmp0_ = TRUE;
	} else {
		_tmp0_ = !self->can_anim;
	}
	if (_tmp0_) {
		if (self->id > ((guint) 0)) {
			BudgiePropChange* _tmp2_;
			gint _tmp2__length1;
			_tmp2_ = self->changes;
			_tmp2__length1 = self->changes_length1;
			{
				BudgiePropChange* p_collection = NULL;
				gint p_collection_length1 = 0;
				gint _p_collection_size_ = 0;
				gint p_it = 0;
				p_collection = _tmp2_;
				p_collection_length1 = _tmp2__length1;
				for (p_it = 0; p_it < p_collection_length1; p_it = p_it + 1) {
					BudgiePropChange _tmp3_;
					BudgiePropChange _tmp4_ = {0};
					BudgiePropChange p = {0};
					_tmp3_ = p_collection[p_it];
					budgie_prop_change_copy (&_tmp3_, &_tmp4_);
					p = _tmp4_;
					{
						GObject* _tmp5_;
						_tmp5_ = self->object;
						if (_tmp5_ == NULL) {
							BudgiePropChange _tmp6_;
							const gchar* _tmp7_;
							BudgiePropChange _tmp8_;
							GValue _tmp9_;
							_tmp6_ = p;
							_tmp7_ = _tmp6_.property;
							_tmp8_ = p;
							_tmp9_ = _tmp8_.new;
							g_object_set_property ((GObject*) widget, _tmp7_, &_tmp9_);
						} else {
							GObject* _tmp10_;
							BudgiePropChange _tmp11_;
							const gchar* _tmp12_;
							BudgiePropChange _tmp13_;
							GValue _tmp14_;
							_tmp10_ = self->object;
							_tmp11_ = p;
							_tmp12_ = _tmp11_.property;
							_tmp13_ = p;
							_tmp14_ = _tmp13_.new;
							g_object_set_property (_tmp10_, _tmp12_, &_tmp14_);
						}
						budgie_prop_change_destroy (&p);
					}
				}
			}
		}
		self->id = (guint) 0;
		if (self->can_anim) {
			BudgieAnimCompletionFunc _tmp15_;
			gpointer _tmp15__target;
			self->can_anim = FALSE;
			_tmp15_ = self->priv->compl;
			_tmp15__target = self->priv->compl_target;
			if (_tmp15_ != NULL) {
				BudgieAnimCompletionFunc _tmp16_;
				gpointer _tmp16__target;
				_tmp16_ = self->priv->compl;
				_tmp16__target = self->priv->compl_target;
				_tmp16_ (self, _tmp16__target);
			}
		}
		gtk_widget_queue_draw (widget);
		result = FALSE;
		return result;
	}
	factor = CLAMP (((gfloat) elapsed) / self->length, (gfloat) 0, 1.0f);
	_tmp17_ = self->changes;
	_tmp17__length1 = self->changes_length1;
	{
		BudgiePropChange* c_collection = NULL;
		gint c_collection_length1 = 0;
		gint _c_collection_size_ = 0;
		gint c_it = 0;
		c_collection = _tmp17_;
		c_collection_length1 = _tmp17__length1;
		for (c_it = 0; c_it < c_collection_length1; c_it = c_it + 1) {
			BudgiePropChange _tmp18_;
			BudgiePropChange _tmp19_ = {0};
			BudgiePropChange c = {0};
			_tmp18_ = c_collection[c_it];
			budgie_prop_change_copy (&_tmp18_, &_tmp19_);
			c = _tmp19_;
			{
				gdouble old = 0.0;
				gdouble new = 0.0;
				BudgieTweenFunc _tmp20_;
				gpointer _tmp20__target;
				gdouble delta = 0.0;
				gdouble nprop = 0.0;
				GObject* _tmp22_;
				old = g_value_get_double (&c.old);
				new = g_value_get_double (&c.new);
				_tmp20_ = self->tween;
				_tmp20__target = self->tween_target;
				if (_tmp20_ != NULL) {
					BudgieTweenFunc _tmp21_;
					gpointer _tmp21__target;
					_tmp21_ = self->tween;
					_tmp21__target = self->tween_target;
					factor = (gfloat) _tmp21_ ((gdouble) factor, _tmp21__target);
				}
				delta = (new - old) * factor;
				nprop = (gdouble) (old + delta);
				_tmp22_ = self->object;
				if (_tmp22_ == NULL) {
					BudgiePropChange _tmp23_;
					const gchar* _tmp24_;
					GValue _tmp25_ = {0};
					_tmp23_ = c;
					_tmp24_ = _tmp23_.property;
					g_value_init (&_tmp25_, G_TYPE_DOUBLE);
					g_value_set_double (&_tmp25_, nprop);
					g_object_set_property ((GObject*) widget, _tmp24_, &_tmp25_);
					G_IS_VALUE (&_tmp25_) ? (g_value_unset (&_tmp25_), NULL) : NULL;
				} else {
					GObject* _tmp26_;
					BudgiePropChange _tmp27_;
					const gchar* _tmp28_;
					GValue _tmp29_ = {0};
					_tmp26_ = self->object;
					_tmp27_ = c;
					_tmp28_ = _tmp27_.property;
					g_value_init (&_tmp29_, G_TYPE_DOUBLE);
					g_value_set_double (&_tmp29_, nprop);
					g_object_set_property (_tmp26_, _tmp28_, &_tmp29_);
					G_IS_VALUE (&_tmp29_) ? (g_value_unset (&_tmp29_), NULL) : NULL;
				}
				budgie_prop_change_destroy (&c);
			}
		}
	}
	gtk_widget_queue_draw (widget);
	result = self->can_anim;
	return result;
}

/**
* Start this animation by attaching ourselves to the GdkFrameClock
*
* @param compl A completion callback to execute when this animation completes
*/
static gboolean
_budgie_animation_tick_callback_gtk_tick_callback (GtkWidget* widget,
                                                   GdkFrameClock* frame_clock,
                                                   gpointer self)
{
	gboolean result;
	result = budgie_animation_tick_callback ((BudgieAnimation*) self, widget, frame_clock);
	return result;
}

void
budgie_animation_start (BudgieAnimation* self,
                        BudgieAnimCompletionFunc compl,
                        gpointer compl_target)
{
	GtkWidget* _tmp0_;
	GdkFrameClock* _tmp1_;
	GtkWidget* _tmp4_;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->widget;
	_tmp1_ = gtk_widget_get_frame_clock (_tmp0_);
	if (_tmp1_ == NULL) {
		return;
	}
	if (!self->no_reset) {
		GtkWidget* _tmp2_;
		GdkFrameClock* _tmp3_;
		_tmp2_ = self->widget;
		_tmp3_ = gtk_widget_get_frame_clock (_tmp2_);
		self->start_time = gdk_frame_clock_get_frame_time (_tmp3_);
	}
	self->priv->compl = compl;
	self->priv->compl_target = compl_target;
	self->can_anim = TRUE;
	_tmp4_ = self->widget;
	self->id = gtk_widget_add_tick_callback (_tmp4_, _budgie_animation_tick_callback_gtk_tick_callback, g_object_ref (self), g_object_unref);
}

/**
* Stop a running animation
*/
void
budgie_animation_stop (BudgieAnimation* self)
{
	g_return_if_fail (self != NULL);
	self->can_anim = FALSE;
	if (self->id != ((guint) 0)) {
		GtkWidget* _tmp0_;
		_tmp0_ = self->widget;
		gtk_widget_remove_tick_callback (_tmp0_, self->id);
	}
	self->id = (guint) 0;
}

BudgieAnimation*
budgie_animation_construct (GType object_type)
{
	BudgieAnimation * self = NULL;
	self = (BudgieAnimation*) g_object_new (object_type, NULL);
	return self;
}

BudgieAnimation*
budgie_animation_new (void)
{
	return budgie_animation_construct (BUDGIE_TYPE_ANIMATION);
}

static void
budgie_animation_class_init (BudgieAnimationClass * klass,
                             gpointer klass_data)
{
	budgie_animation_parent_class = g_type_class_peek_parent (klass);
	g_type_class_adjust_private_offset (klass, &BudgieAnimation_private_offset);
	G_OBJECT_CLASS (klass)->finalize = budgie_animation_finalize;
}

static void
budgie_animation_instance_init (BudgieAnimation * self,
                                gpointer klass)
{
	self->priv = budgie_animation_get_instance_private (self);
}

static void
budgie_animation_finalize (GObject * obj)
{
	BudgieAnimation * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, BUDGIE_TYPE_ANIMATION, BudgieAnimation);
	self->changes = (_vala_BudgiePropChange_array_free (self->changes, self->changes_length1), NULL);
	_g_object_unref0 (self->object);
	G_OBJECT_CLASS (budgie_animation_parent_class)->finalize (obj);
}

/**
* Utility to struct to enable easier animations
* Inspired by Clutter.
*/
static GType
budgie_animation_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (BudgieAnimationClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) budgie_animation_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (BudgieAnimation), 0, (GInstanceInitFunc) budgie_animation_instance_init, NULL };
	GType budgie_animation_type_id;
	budgie_animation_type_id = g_type_register_static (G_TYPE_OBJECT, "BudgieAnimation", &g_define_type_info, 0);
	BudgieAnimation_private_offset = g_type_add_instance_private (budgie_animation_type_id, sizeof (BudgieAnimationPrivate));
	return budgie_animation_type_id;
}

GType
budgie_animation_get_type (void)
{
	static volatile gsize budgie_animation_type_id__once = 0;
	if (g_once_init_enter (&budgie_animation_type_id__once)) {
		GType budgie_animation_type_id;
		budgie_animation_type_id = budgie_animation_get_type_once ();
		g_once_init_leave (&budgie_animation_type_id__once, budgie_animation_type_id);
	}
	return budgie_animation_type_id__once;
}

gdouble
budgie_sine_ease_in_out (gdouble p)
{
	gdouble result;
	result = 0.5 * (1 - cos (p * G_PI));
	return result;
}

gdouble
budgie_sine_ease_in (gdouble p)
{
	gdouble result;
	result = sin ((p - 1) * G_PI_2) + 1;
	return result;
}

gdouble
budgie_sine_ease_out (gdouble p)
{
	gdouble result;
	result = sin (p * G_PI_2);
	return result;
}

gdouble
budgie_elastic_ease_in (gdouble p)
{
	gdouble result;
	result = sin ((13 * G_PI_2) * p) * pow ((gdouble) 2, 10 * (p - 1));
	return result;
}

gdouble
budgie_elastic_ease_out (gdouble p)
{
	gdouble result;
	result = (sin ((-13 * G_PI_2) * (p + 1)) * pow ((gdouble) 2, -10 * p)) + 1;
	return result;
}

gdouble
budgie_back_ease_in (gdouble p)
{
	gdouble result;
	result = ((p * p) * p) - (p * sin (p * G_PI));
	return result;
}

gdouble
budgie_back_ease_out (gdouble p)
{
	gdouble f = 0.0;
	gdouble result;
	f = 1 - p;
	result = 1 - (((f * f) * f) - (f * sin (f * G_PI)));
	return result;
}

gdouble
budgie_expo_ease_in (gdouble p)
{
	gdouble _tmp0_ = 0.0;
	gdouble result;
	if (p == 0.0) {
		_tmp0_ = p;
	} else {
		_tmp0_ = pow ((gdouble) 2, 10 * (p - 1));
	}
	result = _tmp0_;
	return result;
}

gdouble
budgie_expo_ease_out (gdouble p)
{
	gdouble _tmp0_ = 0.0;
	gdouble result;
	if (p == 1.0) {
		_tmp0_ = p;
	} else {
		_tmp0_ = 1 - pow ((gdouble) 2, -10 * p);
	}
	result = _tmp0_;
	return result;
}

gdouble
budgie_quad_ease_in (gdouble p)
{
	gdouble result;
	result = p * p;
	return result;
}

gdouble
budgie_quad_ease_out (gdouble p)
{
	gdouble result;
	result = -(p * (p - 2));
	return result;
}

gdouble
budgie_quad_ease_in_out (gdouble p)
{
	gdouble _tmp0_ = 0.0;
	gdouble result;
	if (p < 0.5) {
		_tmp0_ = (2 * p) * p;
	} else {
		_tmp0_ = (((-2 * p) * p) + (4 * p)) - 1;
	}
	result = _tmp0_;
	return result;
}

gdouble
budgie_circ_ease_in (gdouble p)
{
	gdouble result;
	result = 1 - sqrt (1 - (p * p));
	return result;
}

gdouble
budgie_circ_ease_out (gdouble p)
{
	gdouble result;
	result = sqrt ((2 - p) * p);
	return result;
}

