/* Widget.c generated by valac 0.56.19, the Vala compiler
 * generated from Widget.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>

#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

enum  {
	GALA_WIDGET_0_PROPERTY,
	GALA_WIDGET_CAN_FOCUS_PROPERTY,
	GALA_WIDGET_HAS_VISIBLE_FOCUS_PROPERTY,
	GALA_WIDGET_NUM_PROPERTIES
};
static GParamSpec* gala_widget_properties[GALA_WIDGET_NUM_PROPERTIES];
#define _g_free0(var) ((var == NULL) ? NULL : (var = (g_free (var), NULL)))
#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))

struct _GalaWidgetPrivate {
	gboolean _can_focus;
	gboolean _has_visible_focus;
};

static gint GalaWidget_private_offset;
static gpointer gala_widget_parent_class = NULL;

 G_GNUC_INTERNAL void gala_widget_focus_changed (GalaWidget* self);
static GalaRoot* gala_widget_get_root (GalaWidget* self);
 G_GNUC_INTERNAL gboolean gala_root_get_focus_visible (GalaRoot* self);
static gboolean* _bool_dup (gboolean* self);
static void gala_widget_set_has_visible_focus (GalaWidget* self,
                                        gboolean value);
static gboolean gala_widget_grab_focus (GalaWidget* self);
static gboolean gala_widget_real_move_focus (GalaWidget* self,
                                      GalaFocusDirection direction);
static GeeList* gala_widget_get_widget_children (GalaWidget* self);
static GObject * gala_widget_constructor (GType type,
                                   guint n_construct_properties,
                                   GObjectConstructParam * construct_properties);
static void _gala_widget_focus_changed_clutter_actor_key_focus_in (ClutterActor* _sender,
                                                            gpointer self);
static void _gala_widget_focus_changed_clutter_actor_key_focus_out (ClutterActor* _sender,
                                                             gpointer self);
static void gala_widget_finalize (GObject * obj);
static GType gala_widget_get_type_once (void);
static void _vala_gala_widget_get_property (GObject * object,
                                     guint property_id,
                                     GValue * value,
                                     GParamSpec * pspec);
static void _vala_gala_widget_set_property (GObject * object,
                                     guint property_id,
                                     const GValue * value,
                                     GParamSpec * pspec);

static inline gpointer
gala_widget_get_instance_private (GalaWidget* self)
{
	return G_STRUCT_MEMBER_P (self, GalaWidget_private_offset);
}

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

static gpointer
__bool_dup0 (gpointer self)
{
	return self ? _bool_dup (self) : NULL;
}

 G_GNUC_INTERNAL void
gala_widget_focus_changed (GalaWidget* self)
{
	gboolean _tmp0_ = FALSE;
	g_return_if_fail (self != NULL);
	if (clutter_actor_has_key_focus ((ClutterActor*) self)) {
		GalaRoot* _tmp1_ = NULL;
		GalaRoot* _tmp2_;
		gboolean* _tmp3_ = NULL;
		gboolean* _tmp7_ = NULL;
		gboolean* _tmp8_;
		_tmp2_ = gala_widget_get_root (self);
		_tmp1_ = _tmp2_;
		_tmp3_ = NULL;
		if (_tmp1_ != NULL) {
			gboolean _tmp4_;
			gboolean _tmp5_;
			gboolean* _tmp6_;
			_tmp4_ = gala_root_get_focus_visible (_tmp1_);
			_tmp5_ = _tmp4_;
			_tmp6_ = __bool_dup0 (&_tmp5_);
			_g_free0 (_tmp3_);
			_tmp3_ = _tmp6_;
		}
		_tmp8_ = __bool_dup0 (_tmp3_);
		_tmp7_ = _tmp8_;
		if (_tmp7_ == NULL) {
			gboolean _tmp9_;
			gboolean* _tmp10_;
			_tmp9_ = FALSE;
			_tmp10_ = __bool_dup0 (&_tmp9_);
			_g_free0 (_tmp7_);
			_tmp7_ = _tmp10_;
		}
		_tmp0_ = *_tmp7_;
		_g_free0 (_tmp7_);
		_g_free0 (_tmp3_);
		_g_object_unref0 (_tmp1_);
	} else {
		_tmp0_ = FALSE;
	}
	gala_widget_set_has_visible_focus (self, _tmp0_);
}

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

static GalaRoot*
gala_widget_get_root (GalaWidget* self)
{
	GalaRoot* result;
	g_return_val_if_fail (self != NULL, NULL);
	{
		ClutterActor* actor = NULL;
		ClutterActor* _tmp0_;
		_tmp0_ = _g_object_ref0 ((ClutterActor*) self);
		actor = _tmp0_;
		{
			gboolean _tmp1_ = FALSE;
			_tmp1_ = TRUE;
			while (TRUE) {
				ClutterActor* _tmp5_;
				ClutterActor* _tmp6_;
				if (!_tmp1_) {
					ClutterActor* _tmp2_;
					ClutterActor* _tmp3_;
					ClutterActor* _tmp4_;
					_tmp2_ = actor;
					_tmp3_ = clutter_actor_get_parent (_tmp2_);
					_tmp4_ = _g_object_ref0 (_tmp3_);
					_g_object_unref0 (actor);
					actor = _tmp4_;
				}
				_tmp1_ = FALSE;
				_tmp5_ = actor;
				if (!GALA_IS_WIDGET (_tmp5_)) {
					break;
				}
				_tmp6_ = actor;
				if (GALA_IS_ROOT (_tmp6_)) {
					ClutterActor* _tmp7_;
					GalaRoot* _tmp8_;
					_tmp7_ = actor;
					_tmp8_ = _g_object_ref0 (G_TYPE_CHECK_INSTANCE_CAST (_tmp7_, GALA_TYPE_ROOT, GalaRoot));
					result = _tmp8_;
					_g_object_unref0 (actor);
					return result;
				}
			}
		}
		_g_object_unref0 (actor);
	}
	result = NULL;
	return result;
}

gboolean
gala_widget_focus (GalaWidget* self,
                   GalaFocusDirection direction)
{
	ClutterActor* focus_actor = NULL;
	ClutterStage* _tmp0_;
	ClutterActor* _tmp1_;
	ClutterActor* _tmp2_;
	ClutterActor* _tmp3_;
	gboolean _tmp4_ = FALSE;
	gboolean _tmp5_ = FALSE;
	ClutterActor* _tmp6_;
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	_tmp0_ = (ClutterStage*) clutter_actor_get_stage ((ClutterActor*) self);
	_tmp1_ = clutter_stage_get_key_focus (_tmp0_);
	_tmp2_ = _g_object_ref0 (_tmp1_);
	focus_actor = _tmp2_;
	_tmp3_ = focus_actor;
	if (_tmp3_ == G_TYPE_CHECK_INSTANCE_CAST (self, clutter_actor_get_type (), ClutterActor)) {
		if (gala_focus_direction_is_forward (direction)) {
			result = gala_widget_move_focus (self, direction);
			_g_object_unref0 (focus_actor);
			return result;
		}
		result = FALSE;
		_g_object_unref0 (focus_actor);
		return result;
	}
	_tmp6_ = focus_actor;
	if (_tmp6_ != NULL) {
		ClutterActor* _tmp7_;
		_tmp7_ = focus_actor;
		_tmp5_ = GALA_IS_WIDGET (_tmp7_);
	} else {
		_tmp5_ = FALSE;
	}
	if (_tmp5_) {
		ClutterActor* _tmp8_;
		_tmp8_ = focus_actor;
		_tmp4_ = clutter_actor_contains ((ClutterActor*) self, _tmp8_);
	} else {
		_tmp4_ = FALSE;
	}
	if (_tmp4_) {
		if (gala_widget_move_focus (self, direction)) {
			result = TRUE;
			_g_object_unref0 (focus_actor);
			return result;
		}
		if (gala_focus_direction_is_forward (direction)) {
			result = FALSE;
			_g_object_unref0 (focus_actor);
			return result;
		} else {
			result = gala_widget_grab_focus (self);
			_g_object_unref0 (focus_actor);
			return result;
		}
	}
	if (gala_focus_direction_is_forward (direction)) {
		if (gala_widget_grab_focus (self)) {
			result = TRUE;
			_g_object_unref0 (focus_actor);
			return result;
		}
		result = gala_widget_move_focus (self, direction);
		_g_object_unref0 (focus_actor);
		return result;
	} else {
		if (gala_widget_move_focus (self, direction)) {
			result = TRUE;
			_g_object_unref0 (focus_actor);
			return result;
		}
		result = gala_widget_grab_focus (self);
		_g_object_unref0 (focus_actor);
		return result;
	}
}

static gboolean
gala_widget_grab_focus (GalaWidget* self)
{
	gboolean _tmp0_;
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	_tmp0_ = self->priv->_can_focus;
	if (!_tmp0_) {
		result = FALSE;
		return result;
	}
	clutter_actor_grab_key_focus ((ClutterActor*) self);
	result = TRUE;
	return result;
}

static gboolean
gala_widget_real_move_focus (GalaWidget* self,
                             GalaFocusDirection direction)
{
	GeeList* children = NULL;
	GeeList* _tmp0_;
	GeeList* _tmp1_;
	ClutterStage* _tmp2_;
	ClutterActor* _tmp3_;
	ClutterActor* _tmp4_;
	GeeList* _tmp5_;
	gboolean result;
	_tmp0_ = gala_widget_get_widget_children (self);
	children = _tmp0_;
	_tmp1_ = children;
	_tmp2_ = (ClutterStage*) clutter_actor_get_stage ((ClutterActor*) self);
	_tmp3_ = clutter_stage_get_key_focus (_tmp2_);
	_tmp4_ = _tmp3_;
	gala_focus_utils_filter_children_for_direction (_tmp1_, _tmp4_, direction);
	_tmp5_ = children;
	gala_focus_utils_sort_children_for_direction (_tmp5_, direction);
	{
		GeeList* _child_list = NULL;
		GeeList* _tmp6_;
		gint _child_size = 0;
		GeeList* _tmp7_;
		gint _tmp8_;
		gint _tmp9_;
		gint _child_index = 0;
		_tmp6_ = children;
		_child_list = _tmp6_;
		_tmp7_ = _child_list;
		_tmp8_ = gee_collection_get_size ((GeeCollection*) _tmp7_);
		_tmp9_ = _tmp8_;
		_child_size = _tmp9_;
		_child_index = -1;
		while (TRUE) {
			gint _tmp10_;
			gint _tmp11_;
			GalaWidget* child = NULL;
			GeeList* _tmp12_;
			gpointer _tmp13_;
			GalaWidget* _tmp14_;
			_child_index = _child_index + 1;
			_tmp10_ = _child_index;
			_tmp11_ = _child_size;
			if (!(_tmp10_ < _tmp11_)) {
				break;
			}
			_tmp12_ = _child_list;
			_tmp13_ = gee_list_get (_tmp12_, _child_index);
			child = (GalaWidget*) _tmp13_;
			_tmp14_ = child;
			if (gala_widget_focus (_tmp14_, direction)) {
				result = TRUE;
				_g_object_unref0 (child);
				_g_object_unref0 (children);
				return result;
			}
			_g_object_unref0 (child);
		}
	}
	result = FALSE;
	_g_object_unref0 (children);
	return result;
}

gboolean
gala_widget_move_focus (GalaWidget* self,
                        GalaFocusDirection direction)
{
	GalaWidgetClass* _klass_;
	g_return_val_if_fail (self != NULL, FALSE);
	_klass_ = GALA_WIDGET_GET_CLASS (self);
	if (_klass_->move_focus) {
		return _klass_->move_focus (self, direction);
	}
	return FALSE;
}

static GeeList*
gala_widget_get_widget_children (GalaWidget* self)
{
	GeeArrayList* widget_children = NULL;
	GeeArrayList* _tmp0_;
	GeeList* result;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = gee_array_list_new (GALA_TYPE_WIDGET, (GBoxedCopyFunc) g_object_ref, (GDestroyNotify) g_object_unref, NULL, NULL, NULL);
	widget_children = _tmp0_;
	{
		ClutterActor* child = NULL;
		ClutterActor* _tmp1_;
		ClutterActor* _tmp2_;
		_tmp1_ = clutter_actor_get_first_child ((ClutterActor*) self);
		_tmp2_ = _g_object_ref0 (_tmp1_);
		child = _tmp2_;
		{
			gboolean _tmp3_ = FALSE;
			_tmp3_ = TRUE;
			while (TRUE) {
				ClutterActor* _tmp7_;
				gboolean _tmp8_ = FALSE;
				ClutterActor* _tmp9_;
				if (!_tmp3_) {
					ClutterActor* _tmp4_;
					ClutterActor* _tmp5_;
					ClutterActor* _tmp6_;
					_tmp4_ = child;
					_tmp5_ = clutter_actor_get_next_sibling (_tmp4_);
					_tmp6_ = _g_object_ref0 (_tmp5_);
					_g_object_unref0 (child);
					child = _tmp6_;
				}
				_tmp3_ = FALSE;
				_tmp7_ = child;
				if (!(_tmp7_ != NULL)) {
					break;
				}
				_tmp9_ = child;
				if (GALA_IS_WIDGET (_tmp9_)) {
					ClutterActor* _tmp10_;
					gboolean _tmp11_;
					gboolean _tmp12_;
					_tmp10_ = child;
					g_object_get (_tmp10_, "visible", &_tmp11_, NULL);
					_tmp12_ = _tmp11_;
					_tmp8_ = _tmp12_;
				} else {
					_tmp8_ = FALSE;
				}
				if (_tmp8_) {
					GeeArrayList* _tmp13_;
					ClutterActor* _tmp14_;
					_tmp13_ = widget_children;
					_tmp14_ = child;
					gee_abstract_collection_add ((GeeAbstractCollection*) _tmp13_, G_TYPE_CHECK_INSTANCE_CAST (_tmp14_, GALA_TYPE_WIDGET, GalaWidget));
				}
			}
		}
		_g_object_unref0 (child);
	}
	result = (GeeList*) widget_children;
	return result;
}

GalaWidget*
gala_widget_construct (GType object_type)
{
	GalaWidget * self = NULL;
	self = (GalaWidget*) gala_actor_target_construct (object_type);
	return self;
}

GalaWidget*
gala_widget_new (void)
{
	return gala_widget_construct (GALA_TYPE_WIDGET);
}

gboolean
gala_widget_get_can_focus (GalaWidget* self)
{
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	result = self->priv->_can_focus;
	return result;
}

void
gala_widget_set_can_focus (GalaWidget* self,
                           gboolean value)
{
	gboolean old_value;
	g_return_if_fail (self != NULL);
	old_value = gala_widget_get_can_focus (self);
	if (old_value != value) {
		self->priv->_can_focus = value;
		g_object_notify_by_pspec ((GObject *) self, gala_widget_properties[GALA_WIDGET_CAN_FOCUS_PROPERTY]);
	}
}

gboolean
gala_widget_get_has_visible_focus (GalaWidget* self)
{
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	result = self->priv->_has_visible_focus;
	return result;
}

static void
gala_widget_set_has_visible_focus (GalaWidget* self,
                                   gboolean value)
{
	gboolean old_value;
	g_return_if_fail (self != NULL);
	old_value = gala_widget_get_has_visible_focus (self);
	if (old_value != value) {
		self->priv->_has_visible_focus = value;
		g_object_notify_by_pspec ((GObject *) self, gala_widget_properties[GALA_WIDGET_HAS_VISIBLE_FOCUS_PROPERTY]);
	}
}

static void
_gala_widget_focus_changed_clutter_actor_key_focus_in (ClutterActor* _sender,
                                                       gpointer self)
{
	gala_widget_focus_changed ((GalaWidget*) self);
}

static void
_gala_widget_focus_changed_clutter_actor_key_focus_out (ClutterActor* _sender,
                                                        gpointer self)
{
	gala_widget_focus_changed ((GalaWidget*) self);
}

static GObject *
gala_widget_constructor (GType type,
                         guint n_construct_properties,
                         GObjectConstructParam * construct_properties)
{
	GObject * obj;
	GObjectClass * parent_class;
	GalaWidget * self;
	parent_class = G_OBJECT_CLASS (gala_widget_parent_class);
	obj = parent_class->constructor (type, n_construct_properties, construct_properties);
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, GALA_TYPE_WIDGET, GalaWidget);
	g_signal_connect_object ((ClutterActor*) self, "key-focus-in", (GCallback) _gala_widget_focus_changed_clutter_actor_key_focus_in, self, 0);
	g_signal_connect_object ((ClutterActor*) self, "key-focus-out", (GCallback) _gala_widget_focus_changed_clutter_actor_key_focus_out, self, 0);
	return obj;
}

static void
gala_widget_class_init (GalaWidgetClass * klass,
                        gpointer klass_data)
{
	gala_widget_parent_class = g_type_class_peek_parent (klass);
	g_type_class_adjust_private_offset (klass, &GalaWidget_private_offset);
	((GalaWidgetClass *) klass)->move_focus = (gboolean (*) (GalaWidget*, GalaFocusDirection)) gala_widget_real_move_focus;
	G_OBJECT_CLASS (klass)->get_property = _vala_gala_widget_get_property;
	G_OBJECT_CLASS (klass)->set_property = _vala_gala_widget_set_property;
	G_OBJECT_CLASS (klass)->constructor = gala_widget_constructor;
	G_OBJECT_CLASS (klass)->finalize = gala_widget_finalize;
	g_object_class_install_property (G_OBJECT_CLASS (klass), GALA_WIDGET_CAN_FOCUS_PROPERTY, gala_widget_properties[GALA_WIDGET_CAN_FOCUS_PROPERTY] = g_param_spec_boolean ("can-focus", "can-focus", "can-focus", FALSE, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE | G_PARAM_WRITABLE));
	g_object_class_install_property (G_OBJECT_CLASS (klass), GALA_WIDGET_HAS_VISIBLE_FOCUS_PROPERTY, gala_widget_properties[GALA_WIDGET_HAS_VISIBLE_FOCUS_PROPERTY] = g_param_spec_boolean ("has-visible-focus", "has-visible-focus", "has-visible-focus", FALSE, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
}

static void
gala_widget_instance_init (GalaWidget * self,
                           gpointer klass)
{
	self->priv = gala_widget_get_instance_private (self);
	self->priv->_can_focus = FALSE;
	self->priv->_has_visible_focus = FALSE;
}

static void
gala_widget_finalize (GObject * obj)
{
	GalaWidget * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, GALA_TYPE_WIDGET, GalaWidget);
	G_OBJECT_CLASS (gala_widget_parent_class)->finalize (obj);
}

 G_GNUC_NO_INLINE static GType
gala_widget_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (GalaWidgetClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) gala_widget_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (GalaWidget), 0, (GInstanceInitFunc) gala_widget_instance_init, NULL };
	GType gala_widget_type_id;
	gala_widget_type_id = g_type_register_static (GALA_TYPE_ACTOR_TARGET, "GalaWidget", &g_define_type_info, G_TYPE_FLAG_NONE);
	GalaWidget_private_offset = g_type_add_instance_private (gala_widget_type_id, sizeof (GalaWidgetPrivate));
	return gala_widget_type_id;
}

GType
gala_widget_get_type (void)
{
	static gsize gala_widget_type_id__once = 0;
	if (g_once_init_enter (&gala_widget_type_id__once)) {
		GType gala_widget_type_id;
		gala_widget_type_id = gala_widget_get_type_once ();
		g_once_init_leave (&gala_widget_type_id__once, gala_widget_type_id);
	}
	return gala_widget_type_id__once;
}

static void
_vala_gala_widget_get_property (GObject * object,
                                guint property_id,
                                GValue * value,
                                GParamSpec * pspec)
{
	GalaWidget * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (object, GALA_TYPE_WIDGET, GalaWidget);
	switch (property_id) {
		case GALA_WIDGET_CAN_FOCUS_PROPERTY:
		g_value_set_boolean (value, gala_widget_get_can_focus (self));
		break;
		case GALA_WIDGET_HAS_VISIBLE_FOCUS_PROPERTY:
		g_value_set_boolean (value, gala_widget_get_has_visible_focus (self));
		break;
		default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
	}
}

static void
_vala_gala_widget_set_property (GObject * object,
                                guint property_id,
                                const GValue * value,
                                GParamSpec * pspec)
{
	GalaWidget * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (object, GALA_TYPE_WIDGET, GalaWidget);
	switch (property_id) {
		case GALA_WIDGET_CAN_FOCUS_PROPERTY:
		gala_widget_set_can_focus (self, g_value_get_boolean (value));
		break;
		case GALA_WIDGET_HAS_VISIBLE_FOCUS_PROPERTY:
		gala_widget_set_has_visible_focus (self, g_value_get_boolean (value));
		break;
		default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
	}
}

