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

/*
 * Copyright 2025 elementary, Inc. (https://elementary.io)
 * SPDX-License-Identifier: GPL-3.0-or-later
 *
 * Authored by: Leonhard Kargl <leo.kargl@proton.me>
 */

#include "gala.h"
#include <glib.h>
#include <clutter/clutter.h>
#include <string.h>
#include <gee.h>
#include <glib-object.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

typedef struct _Block7Data Block7Data;
#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))
#define __vala_ClutterActorBox_free0(var) ((var == NULL) ? NULL : (var = (_vala_ClutterActorBox_free (var), NULL)))
typedef struct _Block8Data Block8Data;

struct _Block7Data {
	int _ref_count_;
	GalaWidget* focus_child;
	GalaFocusDirection direction;
};

struct _Block8Data {
	int _ref_count_;
	GalaFocusDirection direction;
};

static GalaFocusDirection* _gala_focus_direction_dup (GalaFocusDirection* self);
static Block7Data* block7_data_ref (Block7Data* _data7_);
static void block7_data_unref (void * _userdata_);
static gboolean __lambda30_ (Block7Data* _data7_,
                      GalaWidget* c);
static void _vala_ClutterActorBox_free (ClutterActorBox* self);
static gboolean ___lambda30__gee_predicate (gconstpointer g,
                                     gpointer self);
static Block8Data* block8_data_ref (Block8Data* _data8_);
static void block8_data_unref (void * _userdata_);
static gint __lambda28_ (Block8Data* _data8_,
                  GalaWidget* a,
                  GalaWidget* b);
static gint ___lambda28__gcompare_data_func (gconstpointer a,
                                      gconstpointer b,
                                      gpointer self);

gboolean
gala_focus_direction_is_forward (GalaFocusDirection self)
{
	gboolean _tmp0_ = FALSE;
	gboolean result;
	if (self == GALA_FOCUS_DIRECTION_DOWN) {
		_tmp0_ = TRUE;
	} else {
		_tmp0_ = self == GALA_FOCUS_DIRECTION_RIGHT;
	}
	result = _tmp0_;
	return result;
}

static GalaFocusDirection*
_gala_focus_direction_dup (GalaFocusDirection* self)
{
	GalaFocusDirection* dup;
	dup = g_new0 (GalaFocusDirection, 1);
	memcpy (dup, self, sizeof (GalaFocusDirection));
	return dup;
}

static gpointer
__gala_focus_direction_dup0 (gpointer self)
{
	return self ? _gala_focus_direction_dup (self) : NULL;
}

GalaFocusDirection*
gala_focus_direction_get_for_event (ClutterEvent* event)
{
	GalaFocusDirection* result;
	g_return_val_if_fail (event != NULL, NULL);
	switch (clutter_event_get_key_symbol (event)) {
		case CLUTTER_KEY_Up:
		{
			GalaFocusDirection _tmp0_;
			GalaFocusDirection* _tmp1_;
			_tmp0_ = GALA_FOCUS_DIRECTION_UP;
			_tmp1_ = __gala_focus_direction_dup0 (&_tmp0_);
			result = _tmp1_;
			return result;
		}
		case CLUTTER_KEY_Down:
		{
			GalaFocusDirection _tmp2_;
			GalaFocusDirection* _tmp3_;
			_tmp2_ = GALA_FOCUS_DIRECTION_DOWN;
			_tmp3_ = __gala_focus_direction_dup0 (&_tmp2_);
			result = _tmp3_;
			return result;
		}
		case CLUTTER_KEY_Left:
		{
			GalaFocusDirection _tmp4_;
			GalaFocusDirection* _tmp5_;
			_tmp4_ = GALA_FOCUS_DIRECTION_LEFT;
			_tmp5_ = __gala_focus_direction_dup0 (&_tmp4_);
			result = _tmp5_;
			return result;
		}
		case CLUTTER_KEY_Right:
		{
			GalaFocusDirection _tmp6_;
			GalaFocusDirection* _tmp7_;
			_tmp6_ = GALA_FOCUS_DIRECTION_RIGHT;
			_tmp7_ = __gala_focus_direction_dup0 (&_tmp6_);
			result = _tmp7_;
			return result;
		}
		default:
		break;
	}
	result = NULL;
	return result;
}

 G_GNUC_NO_INLINE static GType
gala_focus_direction_get_type_once (void)
{
	static const GEnumValue values[] = {{GALA_FOCUS_DIRECTION_UP, "GALA_FOCUS_DIRECTION_UP", "up"}, {GALA_FOCUS_DIRECTION_DOWN, "GALA_FOCUS_DIRECTION_DOWN", "down"}, {GALA_FOCUS_DIRECTION_LEFT, "GALA_FOCUS_DIRECTION_LEFT", "left"}, {GALA_FOCUS_DIRECTION_RIGHT, "GALA_FOCUS_DIRECTION_RIGHT", "right"}, {0, NULL, NULL}};
	GType gala_focus_direction_type_id;
	gala_focus_direction_type_id = g_enum_register_static ("GalaFocusDirection", values);
	return gala_focus_direction_type_id;
}

GType
gala_focus_direction_get_type (void)
{
	static gsize gala_focus_direction_type_id__once = 0;
	if (g_once_init_enter (&gala_focus_direction_type_id__once)) {
		GType gala_focus_direction_type_id;
		gala_focus_direction_type_id = gala_focus_direction_get_type_once ();
		g_once_init_leave (&gala_focus_direction_type_id__once, gala_focus_direction_type_id);
	}
	return gala_focus_direction_type_id__once;
}

static Block7Data*
block7_data_ref (Block7Data* _data7_)
{
	g_atomic_int_inc (&_data7_->_ref_count_);
	return _data7_;
}

static void
block7_data_unref (void * _userdata_)
{
	Block7Data* _data7_;
	_data7_ = (Block7Data*) _userdata_;
	if (g_atomic_int_dec_and_test (&_data7_->_ref_count_)) {
		_g_object_unref0 (_data7_->focus_child);
		g_slice_free (Block7Data, _data7_);
	}
}

static gpointer
_g_object_ref0 (gpointer self)
{
	return self ? g_object_ref (self) : NULL;
}

static void
_vala_ClutterActorBox_free (ClutterActorBox* self)
{
	g_boxed_free (clutter_actor_box_get_type (), self);
}

static gboolean
__lambda30_ (Block7Data* _data7_,
             GalaWidget* c)
{
	gboolean _tmp0_ = FALSE;
	GalaWidget* _tmp1_;
	ClutterActorBox focus_alloc = {0};
	GalaWidget* _tmp3_;
	ClutterActorBox* _tmp4_;
	ClutterActorBox* _tmp5_;
	ClutterActorBox* _tmp6_;
	ClutterActorBox _tmp7_;
	ClutterActorBox alloc = {0};
	ClutterActorBox* _tmp8_;
	ClutterActorBox* _tmp9_;
	ClutterActorBox* _tmp10_;
	ClutterActorBox _tmp11_;
	gboolean _tmp12_ = FALSE;
	ClutterActorBox _tmp13_;
	ClutterActorBox _tmp14_;
	gboolean horiz_overlap = FALSE;
	gboolean _tmp17_ = FALSE;
	ClutterActorBox _tmp18_;
	ClutterActorBox _tmp19_;
	gboolean vert_overlap = FALSE;
	gboolean _tmp22_ = FALSE;
	gboolean _tmp23_ = FALSE;
	gboolean _tmp24_ = FALSE;
	gboolean _tmp27_ = FALSE;
	gboolean _tmp28_ = FALSE;
	gboolean _tmp29_ = FALSE;
	gboolean _tmp30_ = FALSE;
	gboolean result;
	g_return_val_if_fail (c != NULL, FALSE);
	_tmp1_ = _data7_->focus_child;
	if (_tmp1_ == NULL) {
		_tmp0_ = TRUE;
	} else {
		GalaWidget* _tmp2_;
		_tmp2_ = _data7_->focus_child;
		_tmp0_ = c == _tmp2_;
	}
	if (_tmp0_) {
		result = TRUE;
		return result;
	}
	_tmp3_ = _data7_->focus_child;
	g_object_get ((ClutterActor*) _tmp3_, "allocation", &_tmp4_, NULL);
	_tmp5_ = _tmp4_;
	_tmp6_ = _tmp5_;
	_tmp7_ = *_tmp6_;
	__vala_ClutterActorBox_free0 (_tmp6_);
	focus_alloc = _tmp7_;
	g_object_get ((ClutterActor*) c, "allocation", &_tmp8_, NULL);
	_tmp9_ = _tmp8_;
	_tmp10_ = _tmp9_;
	_tmp11_ = *_tmp10_;
	__vala_ClutterActorBox_free0 (_tmp10_);
	alloc = _tmp11_;
	_tmp13_ = alloc;
	_tmp14_ = focus_alloc;
	if (_tmp13_.x1 < _tmp14_.x2) {
		ClutterActorBox _tmp15_;
		ClutterActorBox _tmp16_;
		_tmp15_ = alloc;
		_tmp16_ = focus_alloc;
		_tmp12_ = _tmp15_.x2 > _tmp16_.x1;
	} else {
		_tmp12_ = FALSE;
	}
	horiz_overlap = _tmp12_;
	_tmp18_ = alloc;
	_tmp19_ = focus_alloc;
	if (_tmp18_.y1 < _tmp19_.y2) {
		ClutterActorBox _tmp20_;
		ClutterActorBox _tmp21_;
		_tmp20_ = alloc;
		_tmp21_ = focus_alloc;
		_tmp17_ = _tmp20_.y2 > _tmp21_.y1;
	} else {
		_tmp17_ = FALSE;
	}
	vert_overlap = _tmp17_;
	if (_data7_->direction == GALA_FOCUS_DIRECTION_UP) {
		_tmp24_ = TRUE;
	} else {
		_tmp24_ = _data7_->direction == GALA_FOCUS_DIRECTION_DOWN;
	}
	if (_tmp24_) {
		_tmp23_ = !horiz_overlap;
	} else {
		_tmp23_ = FALSE;
	}
	if (_tmp23_) {
		_tmp22_ = TRUE;
	} else {
		gboolean _tmp25_ = FALSE;
		gboolean _tmp26_ = FALSE;
		if (_data7_->direction == GALA_FOCUS_DIRECTION_LEFT) {
			_tmp26_ = TRUE;
		} else {
			_tmp26_ = _data7_->direction == GALA_FOCUS_DIRECTION_RIGHT;
		}
		if (_tmp26_) {
			_tmp25_ = !vert_overlap;
		} else {
			_tmp25_ = FALSE;
		}
		_tmp22_ = _tmp25_;
	}
	if (_tmp22_) {
		result = FALSE;
		return result;
	}
	if (_data7_->direction == GALA_FOCUS_DIRECTION_UP) {
		ClutterActorBox _tmp31_;
		ClutterActorBox _tmp32_;
		_tmp31_ = alloc;
		_tmp32_ = focus_alloc;
		_tmp30_ = _tmp31_.y2 <= _tmp32_.y1;
	} else {
		_tmp30_ = FALSE;
	}
	if (_tmp30_) {
		_tmp29_ = TRUE;
	} else {
		gboolean _tmp33_ = FALSE;
		if (_data7_->direction == GALA_FOCUS_DIRECTION_DOWN) {
			ClutterActorBox _tmp34_;
			ClutterActorBox _tmp35_;
			_tmp34_ = alloc;
			_tmp35_ = focus_alloc;
			_tmp33_ = _tmp34_.y1 >= _tmp35_.y2;
		} else {
			_tmp33_ = FALSE;
		}
		_tmp29_ = _tmp33_;
	}
	if (_tmp29_) {
		_tmp28_ = TRUE;
	} else {
		gboolean _tmp36_ = FALSE;
		if (_data7_->direction == GALA_FOCUS_DIRECTION_LEFT) {
			ClutterActorBox _tmp37_;
			ClutterActorBox _tmp38_;
			_tmp37_ = alloc;
			_tmp38_ = focus_alloc;
			_tmp36_ = _tmp37_.x2 <= _tmp38_.x1;
		} else {
			_tmp36_ = FALSE;
		}
		_tmp28_ = _tmp36_;
	}
	if (_tmp28_) {
		_tmp27_ = TRUE;
	} else {
		gboolean _tmp39_ = FALSE;
		if (_data7_->direction == GALA_FOCUS_DIRECTION_RIGHT) {
			ClutterActorBox _tmp40_;
			ClutterActorBox _tmp41_;
			_tmp40_ = alloc;
			_tmp41_ = focus_alloc;
			_tmp39_ = _tmp40_.x1 >= _tmp41_.x2;
		} else {
			_tmp39_ = FALSE;
		}
		_tmp27_ = _tmp39_;
	}
	result = _tmp27_;
	return result;
}

static gboolean
___lambda30__gee_predicate (gconstpointer g,
                            gpointer self)
{
	gboolean result;
	result = __lambda30_ (self, (GalaWidget*) g);
	return result;
}

void
gala_focus_utils_filter_children_for_direction (GeeList* children,
                                                ClutterActor* focus_actor,
                                                GalaFocusDirection direction)
{
	Block7Data* _data7_;
	GeeLinkedList* to_retain = NULL;
	GeeLinkedList* _tmp10_;
	GeeIterator* _tmp11_;
	GeeIterator* _tmp12_;
	g_return_if_fail (children != NULL);
	g_return_if_fail (focus_actor != NULL);
	_data7_ = g_slice_new0 (Block7Data);
	_data7_->_ref_count_ = 1;
	_data7_->direction = direction;
	_data7_->focus_child = NULL;
	{
		GeeList* _child_list = NULL;
		gint _child_size = 0;
		GeeList* _tmp0_;
		gint _tmp1_;
		gint _tmp2_;
		gint _child_index = 0;
		_child_list = children;
		_tmp0_ = _child_list;
		_tmp1_ = gee_collection_get_size ((GeeCollection*) _tmp0_);
		_tmp2_ = _tmp1_;
		_child_size = _tmp2_;
		_child_index = -1;
		while (TRUE) {
			gint _tmp3_;
			gint _tmp4_;
			GalaWidget* child = NULL;
			GeeList* _tmp5_;
			gpointer _tmp6_;
			GalaWidget* _tmp7_;
			_child_index = _child_index + 1;
			_tmp3_ = _child_index;
			_tmp4_ = _child_size;
			if (!(_tmp3_ < _tmp4_)) {
				break;
			}
			_tmp5_ = _child_list;
			_tmp6_ = gee_list_get (_tmp5_, _child_index);
			child = (GalaWidget*) _tmp6_;
			_tmp7_ = child;
			if (clutter_actor_contains ((ClutterActor*) _tmp7_, focus_actor)) {
				GalaWidget* _tmp8_;
				GalaWidget* _tmp9_;
				_tmp8_ = child;
				_tmp9_ = _g_object_ref0 (G_TYPE_CHECK_INSTANCE_CAST (_tmp8_, GALA_TYPE_WIDGET, GalaWidget));
				_g_object_unref0 (_data7_->focus_child);
				_data7_->focus_child = _tmp9_;
				_g_object_unref0 (child);
				break;
			}
			_g_object_unref0 (child);
		}
	}
	_tmp10_ = gee_linked_list_new (GALA_TYPE_WIDGET, (GBoxedCopyFunc) g_object_ref, (GDestroyNotify) g_object_unref, NULL, NULL, NULL);
	to_retain = _tmp10_;
	_tmp11_ = gee_traversable_filter ((GeeTraversable*) children, ___lambda30__gee_predicate, block7_data_ref (_data7_), block7_data_unref);
	_tmp12_ = _tmp11_;
	gee_collection_add_all_iterator ((GeeCollection*) to_retain, _tmp12_);
	_g_object_unref0 (_tmp12_);
	gee_collection_retain_all ((GeeCollection*) children, (GeeCollection*) to_retain);
	_g_object_unref0 (to_retain);
	block7_data_unref (_data7_);
	_data7_ = NULL;
}

static Block8Data*
block8_data_ref (Block8Data* _data8_)
{
	g_atomic_int_inc (&_data8_->_ref_count_);
	return _data8_;
}

static void
block8_data_unref (void * _userdata_)
{
	Block8Data* _data8_;
	_data8_ = (Block8Data*) _userdata_;
	if (g_atomic_int_dec_and_test (&_data8_->_ref_count_)) {
		g_slice_free (Block8Data, _data8_);
	}
}

static gint
__lambda28_ (Block8Data* _data8_,
             GalaWidget* a,
             GalaWidget* b)
{
	gboolean _tmp0_ = FALSE;
	gboolean _tmp1_ = FALSE;
	gboolean _tmp2_ = FALSE;
	gboolean _tmp3_ = FALSE;
	gint result;
	g_return_val_if_fail (a != NULL, -1);
	g_return_val_if_fail (b != NULL, -1);
	if (_data8_->direction == GALA_FOCUS_DIRECTION_UP) {
		gfloat _tmp4_;
		gfloat _tmp5_;
		gfloat _tmp6_;
		gfloat _tmp7_;
		gfloat _tmp8_;
		gfloat _tmp9_;
		gfloat _tmp10_;
		gfloat _tmp11_;
		_tmp4_ = clutter_actor_get_y ((ClutterActor*) a);
		_tmp5_ = _tmp4_;
		_tmp6_ = clutter_actor_get_height ((ClutterActor*) a);
		_tmp7_ = _tmp6_;
		_tmp8_ = clutter_actor_get_y ((ClutterActor*) b);
		_tmp9_ = _tmp8_;
		_tmp10_ = clutter_actor_get_height ((ClutterActor*) b);
		_tmp11_ = _tmp10_;
		_tmp3_ = (_tmp5_ + _tmp7_) > (_tmp9_ + _tmp11_);
	} else {
		_tmp3_ = FALSE;
	}
	if (_tmp3_) {
		_tmp2_ = TRUE;
	} else {
		gboolean _tmp12_ = FALSE;
		if (_data8_->direction == GALA_FOCUS_DIRECTION_DOWN) {
			gfloat _tmp13_;
			gfloat _tmp14_;
			gfloat _tmp15_;
			gfloat _tmp16_;
			_tmp13_ = clutter_actor_get_y ((ClutterActor*) a);
			_tmp14_ = _tmp13_;
			_tmp15_ = clutter_actor_get_y ((ClutterActor*) b);
			_tmp16_ = _tmp15_;
			_tmp12_ = _tmp14_ < _tmp16_;
		} else {
			_tmp12_ = FALSE;
		}
		_tmp2_ = _tmp12_;
	}
	if (_tmp2_) {
		_tmp1_ = TRUE;
	} else {
		gboolean _tmp17_ = FALSE;
		if (_data8_->direction == GALA_FOCUS_DIRECTION_LEFT) {
			gfloat _tmp18_;
			gfloat _tmp19_;
			gfloat _tmp20_;
			gfloat _tmp21_;
			gfloat _tmp22_;
			gfloat _tmp23_;
			gfloat _tmp24_;
			gfloat _tmp25_;
			_tmp18_ = clutter_actor_get_x ((ClutterActor*) a);
			_tmp19_ = _tmp18_;
			_tmp20_ = clutter_actor_get_width ((ClutterActor*) a);
			_tmp21_ = _tmp20_;
			_tmp22_ = clutter_actor_get_x ((ClutterActor*) b);
			_tmp23_ = _tmp22_;
			_tmp24_ = clutter_actor_get_width ((ClutterActor*) b);
			_tmp25_ = _tmp24_;
			_tmp17_ = (_tmp19_ + _tmp21_) > (_tmp23_ + _tmp25_);
		} else {
			_tmp17_ = FALSE;
		}
		_tmp1_ = _tmp17_;
	}
	if (_tmp1_) {
		_tmp0_ = TRUE;
	} else {
		gboolean _tmp26_ = FALSE;
		if (_data8_->direction == GALA_FOCUS_DIRECTION_RIGHT) {
			gfloat _tmp27_;
			gfloat _tmp28_;
			gfloat _tmp29_;
			gfloat _tmp30_;
			_tmp27_ = clutter_actor_get_x ((ClutterActor*) a);
			_tmp28_ = _tmp27_;
			_tmp29_ = clutter_actor_get_x ((ClutterActor*) b);
			_tmp30_ = _tmp29_;
			_tmp26_ = _tmp28_ < _tmp30_;
		} else {
			_tmp26_ = FALSE;
		}
		_tmp0_ = _tmp26_;
	}
	if (_tmp0_) {
		result = -1;
		return result;
	}
	result = 1;
	return result;
}

static gint
___lambda28__gcompare_data_func (gconstpointer a,
                                 gconstpointer b,
                                 gpointer self)
{
	gint result;
	result = __lambda28_ (self, (GalaWidget*) a, (GalaWidget*) b);
	return result;
}

void
gala_focus_utils_sort_children_for_direction (GeeList* children,
                                              GalaFocusDirection direction)
{
	Block8Data* _data8_;
	g_return_if_fail (children != NULL);
	_data8_ = g_slice_new0 (Block8Data);
	_data8_->_ref_count_ = 1;
	_data8_->direction = direction;
	gee_list_sort (children, ___lambda28__gcompare_data_func, block8_data_ref (_data8_), block8_data_unref);
	block8_data_unref (_data8_);
	_data8_ = NULL;
}

