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

/* grid.vala
 *
 * Copyright 2022 Vojtěch Perník
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * 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/>.
 */

#include <adwaita.h>
#include <glib-object.h>
#include <glib.h>
#include <gtk/gtk.h>
#include <stdlib.h>
#include <string.h>
#include <glib/gi18n-lib.h>
#include <gtk/gtkimmodule.h>
#include <gdk/gdk.h>
#include <float.h>
#include <math.h>

#define WG_GRID_COLS 5
#define WG_GRID_ROWS 6
#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 WG_TYPE_GRID (wg_grid_get_type ())
#define WG_GRID(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), WG_TYPE_GRID, WGGrid))
#define WG_GRID_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), WG_TYPE_GRID, WGGridClass))
#define WG_IS_GRID(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), WG_TYPE_GRID))
#define WG_IS_GRID_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), WG_TYPE_GRID))
#define WG_GRID_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), WG_TYPE_GRID, WGGridClass))

typedef struct _WGGrid WGGrid;
typedef struct _WGGridClass WGGridClass;
typedef struct _WGGridPrivate WGGridPrivate;
enum  {
	WG_GRID_0_PROPERTY,
	WG_GRID_NUM_PROPERTIES
};
static GParamSpec* wg_grid_properties[WG_GRID_NUM_PROPERTIES];
#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))

#define WG_TYPE_CELL (wg_cell_get_type ())
#define WG_CELL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), WG_TYPE_CELL, WGCell))
#define WG_CELL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), WG_TYPE_CELL, WGCellClass))
#define WG_IS_CELL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), WG_TYPE_CELL))
#define WG_IS_CELL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), WG_TYPE_CELL))
#define WG_CELL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), WG_TYPE_CELL, WGCellClass))

typedef struct _WGCell WGCell;
typedef struct _WGCellClass WGCellClass;
#define _g_free0(var) (var = (g_free (var), NULL))
typedef enum  {
	WG_CELL_STATE_CORRECT,
	WG_CELL_STATE_WRONG,
	WG_CELL_STATE_WRONG_POSITION,
	WG_CELL_STATE_UNKNOWN,
	WG_CELL_STATE_NONE
} WGCellState;

#define WG_TYPE_CELL_STATE (wg_cell_state_get_type ())
enum  {
	WG_GRID_CONFIRMED_SIGNAL,
	WG_GRID_GAME_OVER_SIGNAL,
	WG_GRID_NUM_SIGNALS
};
static guint wg_grid_signals[WG_GRID_NUM_SIGNALS] = {0};

struct _WGGrid {
	AdwBin parent_instance;
	WGGridPrivate * priv;
};

struct _WGGridClass {
	AdwBinClass parent_class;
	void (*game_over) (WGGrid* self, gboolean win);
};

struct _WGGridPrivate {
	gint active_x;
	gint active_y;
	GtkGrid* grid;
	GtkEventControllerKey* controller;
};

static gint WGGrid_private_offset;
static gpointer wg_grid_parent_class = NULL;

VALA_EXTERN GType wg_grid_get_type (void) G_GNUC_CONST ;
G_DEFINE_AUTOPTR_CLEANUP_FUNC (WGGrid, g_object_unref)
VALA_EXTERN void wg_grid_new_game (WGGrid* self);
static void wg_grid_clear (WGGrid* self);
VALA_EXTERN void wg_grid_insert (WGGrid* self,
                     const gchar* text);
static void wg_grid_reset_row_state (WGGrid* self);
VALA_EXTERN GType wg_cell_get_type (void) G_GNUC_CONST ;
G_DEFINE_AUTOPTR_CLEANUP_FUNC (WGCell, g_object_unref)
static WGCell* wg_grid_active_cell (WGGrid* self);
VALA_EXTERN void wg_cell_set_content (WGCell* self,
                          const gchar* value);
static WGCell* wg_grid_activate_next (WGGrid* self);
static void wg_grid_update_properties (WGGrid* self);
VALA_EXTERN void wg_grid_backspace (WGGrid* self);
static WGCell* wg_grid_activate_prev (WGGrid* self);
VALA_EXTERN void wg_grid_confirm (WGGrid* self);
VALA_EXTERN gboolean wg_grid_is_row_filled (WGGrid* self);
VALA_EXTERN GType wg_cell_state_get_type (void) G_GNUC_CONST ;
VALA_EXTERN gchar** wg_grid_get_current_content (WGGrid* self,
                                     gint* result_length1);
static void wg_grid_set_cell_state (WGGrid* self,
                             gint x,
                             gint y,
                             WGCellState state);
static WGCell* wg_grid_activate_next_row (WGGrid* self);
static WGCell* wg_grid_get_cell (WGGrid* self,
                          gint x,
                          gint y);
static WGCell* wg_grid_set_active_cell (WGGrid* self,
                                 gint x,
                                 gint y);
VALA_EXTERN void wg_cell_set_focused (WGCell* self,
                          gboolean value);
static void _vala_array_add1 (gchar** * array,
                       gint* length,
                       gint* size,
                       gchar* value);
VALA_EXTERN const gchar* wg_cell_get_content (WGCell* self);
static void _vala_array_add2 (gchar** * array,
                       gint* length,
                       gint* size,
                       gchar* value);
VALA_EXTERN void wg_cell_set_state (WGCell* self,
                        WGCellState value);
VALA_EXTERN WGGrid* wg_grid_new (void);
VALA_EXTERN WGGrid* wg_grid_construct (GType object_type);
static void g_cclosure_user_marshal_POINTER__BOXED_INT (GClosure * closure,
                                                 GValue * return_value,
                                                 guint n_param_values,
                                                 const GValue * param_values,
                                                 gpointer invocation_hint,
                                                 gpointer marshal_data);
static void wg_grid_real_game_over (WGGrid* self,
                             gboolean win);
static GObject * wg_grid_constructor (GType type,
                               guint n_construct_properties,
                               GObjectConstructParam * construct_properties);
VALA_EXTERN WGCell* wg_cell_new (void);
VALA_EXTERN WGCell* wg_cell_construct (GType object_type);
static void _wg_grid___lambda6_ (WGGrid* self,
                          const gchar* str);
VALA_EXTERN gchar* wg_data_parser_replace (const gchar* original);
VALA_EXTERN gchar** wg_data_parser_get_available_letters (gint* result_length1);
static gboolean _vala_string_array_contains (gchar* * stack,
                                      gssize stack_length,
                                      const gchar* needle);
static void __wg_grid___lambda6__gtk_im_context_commit (GtkIMContext* _sender,
                                                 const gchar* str,
                                                 gpointer self);
static gboolean _wg_grid___lambda7_ (WGGrid* self,
                              guint val,
                              guint code,
                              GdkModifierType state);
static gboolean __wg_grid___lambda7__gtk_event_controller_key_key_pressed (GtkEventControllerKey* _sender,
                                                                    guint keyval,
                                                                    guint keycode,
                                                                    GdkModifierType state,
                                                                    gpointer self);
static void _wg_grid___lambda8_ (WGGrid* self);
static void __wg_grid___lambda8__gtk_gesture_click_released (GtkGestureClick* _sender,
                                                      gint n_press,
                                                      gdouble x,
                                                      gdouble y,
                                                      gpointer self);
static void wg_grid_finalize (GObject * obj);
static GType wg_grid_get_type_once (void);
static void _vala_array_destroy (gpointer array,
                          gssize array_length,
                          GDestroyNotify destroy_func);
static void _vala_array_free (gpointer array,
                       gssize array_length,
                       GDestroyNotify destroy_func);

static inline gpointer
wg_grid_get_instance_private (WGGrid* self)
{
	return G_STRUCT_MEMBER_P (self, WGGrid_private_offset);
}

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

void
wg_grid_new_game (WGGrid* self)
{
	GtkEventControllerKey* _tmp0_;
	GtkEventController* _tmp1_;
	g_return_if_fail (self != NULL);
	wg_grid_clear (self);
	_tmp0_ = self->priv->controller;
	_tmp1_ = _g_object_ref0 ((GtkEventController*) _tmp0_);
	gtk_widget_add_controller ((GtkWidget*) self, _tmp1_);
}

/**
     * Insert into active cell and move the cursor.
     */
void
wg_grid_insert (WGGrid* self,
                const gchar* text)
{
	WGCell* cell = NULL;
	WGCell* _tmp0_;
	WGCell* _tmp1_;
	WGCell* _tmp2_;
	gchar* _tmp3_;
	gchar* _tmp4_;
	WGCell* _tmp5_;
	WGCell* _tmp6_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (text != NULL);
	wg_grid_reset_row_state (self);
	_tmp0_ = wg_grid_active_cell (self);
	cell = _tmp0_;
	_tmp1_ = cell;
	if (_tmp1_ == NULL) {
		_g_object_unref0 (cell);
		return;
	}
	_tmp2_ = cell;
	_tmp3_ = g_utf8_strup (text, (gssize) -1);
	_tmp4_ = _tmp3_;
	wg_cell_set_content (_tmp2_, _tmp4_);
	_g_free0 (_tmp4_);
	_tmp5_ = wg_grid_activate_next (self);
	_tmp6_ = _tmp5_;
	_g_object_unref0 (_tmp6_);
	wg_grid_update_properties (self);
	_g_object_unref0 (cell);
}

/**
     * Delete from the last cell and move cursor back.
     */
void
wg_grid_backspace (WGGrid* self)
{
	WGCell* cell = NULL;
	WGCell* _tmp0_;
	g_return_if_fail (self != NULL);
	wg_grid_reset_row_state (self);
	_tmp0_ = wg_grid_activate_prev (self);
	cell = _tmp0_;
	wg_cell_set_content (cell, "");
	wg_grid_update_properties (self);
	_g_object_unref0 (cell);
}

/**
     * Confirm the current row content.
     *
     * If the confirmation is possible, emits the confirmed() signal.
     */
void
wg_grid_confirm (WGGrid* self)
{
	GList* res = NULL;
	gint _tmp0_ = 0;
	gchar** _tmp1_;
	gchar** _tmp2_;
	gint _tmp2__length1;
	GList* _tmp3_ = NULL;
	GList* _tmp4_;
	gboolean _tmp5_ = FALSE;
	GList* _tmp6_;
	gboolean win = FALSE;
	gint x = 0;
	WGCell* _tmp15_;
	WGCell* _tmp16_;
	g_return_if_fail (self != NULL);
	if (!wg_grid_is_row_filled (self)) {
		return;
	}
	_tmp1_ = wg_grid_get_current_content (self, &_tmp0_);
	_tmp2_ = _tmp1_;
	_tmp2__length1 = _tmp0_;
	g_signal_emit (self, wg_grid_signals[WG_GRID_CONFIRMED_SIGNAL], 0, _tmp2_, (gint) _tmp0_, &_tmp3_);
	_tmp4_ = _tmp3_;
	_tmp2_ = (_vala_array_free (_tmp2_, _tmp2__length1, (GDestroyNotify) g_free), NULL);
	res = _tmp4_;
	_tmp6_ = res;
	if (_tmp6_ == NULL) {
		_tmp5_ = TRUE;
	} else {
		GList* _tmp7_;
		_tmp7_ = res;
		_tmp5_ = g_list_length (_tmp7_) <= ((guint) 0);
	}
	if (_tmp5_) {
		{
			gint x = 0;
			x = 0;
			{
				gboolean _tmp8_ = FALSE;
				_tmp8_ = TRUE;
				while (TRUE) {
					if (!_tmp8_) {
						gint _tmp9_;
						_tmp9_ = x;
						x = _tmp9_ + 1;
					}
					_tmp8_ = FALSE;
					if (!(x < WG_GRID_COLS)) {
						break;
					}
					wg_grid_set_cell_state (self, x, self->priv->active_y, WG_CELL_STATE_UNKNOWN);
				}
			}
		}
		(res == NULL) ? NULL : (res = (g_list_free (res), NULL));
		return;
	}
	win = TRUE;
	x = 0;
	while (TRUE) {
		gboolean _tmp10_ = FALSE;
		WGCellState current_state = 0;
		GList* _tmp12_;
		gconstpointer _tmp13_;
		gint _tmp14_;
		if (x < WG_GRID_COLS) {
			GList* _tmp11_;
			_tmp11_ = res;
			_tmp10_ = ((guint) x) < g_list_length (_tmp11_);
		} else {
			_tmp10_ = FALSE;
		}
		if (!_tmp10_) {
			break;
		}
		_tmp12_ = res;
		_tmp13_ = g_list_nth_data (_tmp12_, (guint) x);
		current_state = (WGCellState) ((gintptr) _tmp13_);
		wg_grid_set_cell_state (self, x, self->priv->active_y, current_state);
		if (current_state != WG_CELL_STATE_CORRECT) {
			win = FALSE;
		}
		_tmp14_ = x;
		x = _tmp14_ + 1;
	}
	if (win) {
		g_signal_emit (self, wg_grid_signals[WG_GRID_GAME_OVER_SIGNAL], 0, TRUE);
		(res == NULL) ? NULL : (res = (g_list_free (res), NULL));
		return;
	}
	_tmp15_ = wg_grid_activate_next_row (self);
	_tmp16_ = _tmp15_;
	_g_object_unref0 (_tmp16_);
	wg_grid_update_properties (self);
	if (self->priv->active_y >= WG_GRID_ROWS) {
		g_signal_emit (self, wg_grid_signals[WG_GRID_GAME_OVER_SIGNAL], 0, FALSE);
	}
	(res == NULL) ? NULL : (res = (g_list_free (res), NULL));
}

static gchar*
_vala_g_strjoinv (const gchar* separator,
                  gchar** str_array,
                  gint str_array_length1)
{
	gboolean _tmp0_ = FALSE;
	gchar* result;
	if (separator == NULL) {
		separator = "";
	}
	if (str_array != NULL) {
		gboolean _tmp1_ = FALSE;
		if (str_array_length1 > 0) {
			_tmp1_ = TRUE;
		} else {
			gboolean _tmp2_ = FALSE;
			if (str_array_length1 == -1) {
				const gchar* _tmp3_;
				_tmp3_ = str_array[0];
				_tmp2_ = _tmp3_ != NULL;
			} else {
				_tmp2_ = FALSE;
			}
			_tmp1_ = _tmp2_;
		}
		_tmp0_ = _tmp1_;
	} else {
		_tmp0_ = FALSE;
	}
	if (_tmp0_) {
		gint i = 0;
		gsize len = 0UL;
		gint _tmp16_;
		gint _tmp17_;
		const gchar* res = NULL;
		void* _tmp18_;
		const gchar* _tmp19_ = NULL;
		const gchar* _tmp20_;
		void* ptr = NULL;
		const gchar* _tmp22_;
		void* _tmp23_;
		const gchar* _tmp33_;
		len = (gsize) 1;
		{
			gboolean _tmp4_ = FALSE;
			i = 0;
			_tmp4_ = TRUE;
			while (TRUE) {
				gboolean _tmp6_ = FALSE;
				gboolean _tmp7_ = FALSE;
				gint _tmp10_ = 0;
				const gchar* _tmp11_;
				if (!_tmp4_) {
					gint _tmp5_;
					_tmp5_ = i;
					i = _tmp5_ + 1;
				}
				_tmp4_ = FALSE;
				if (str_array_length1 != -1) {
					_tmp7_ = i < str_array_length1;
				} else {
					_tmp7_ = FALSE;
				}
				if (_tmp7_) {
					_tmp6_ = TRUE;
				} else {
					gboolean _tmp8_ = FALSE;
					if (str_array_length1 == -1) {
						const gchar* _tmp9_;
						_tmp9_ = str_array[i];
						_tmp8_ = _tmp9_ != NULL;
					} else {
						_tmp8_ = FALSE;
					}
					_tmp6_ = _tmp8_;
				}
				if (!_tmp6_) {
					break;
				}
				_tmp11_ = str_array[i];
				if (_tmp11_ != NULL) {
					const gchar* _tmp12_;
					gint _tmp13_;
					gint _tmp14_;
					_tmp12_ = str_array[i];
					_tmp13_ = strlen ((const gchar*) _tmp12_);
					_tmp14_ = _tmp13_;
					_tmp10_ = _tmp14_;
				} else {
					_tmp10_ = 0;
				}
				len += (gsize) _tmp10_;
			}
		}
		if (i == 0) {
			gchar* _tmp15_;
			_tmp15_ = g_strdup ("");
			result = _tmp15_;
			return result;
		}
		str_array_length1 = i;
		_tmp16_ = strlen ((const gchar*) separator);
		_tmp17_ = _tmp16_;
		len += (gsize) (_tmp17_ * (i - 1));
		_tmp18_ = g_malloc (len);
		res = _tmp18_;
		_tmp20_ = str_array[0];
		if (_tmp20_ != NULL) {
			const gchar* _tmp21_;
			_tmp21_ = str_array[0];
			_tmp19_ = (const gchar*) _tmp21_;
		} else {
			_tmp19_ = "";
		}
		_tmp22_ = res;
		_tmp23_ = g_stpcpy ((void*) _tmp22_, _tmp19_);
		ptr = _tmp23_;
		{
			gboolean _tmp24_ = FALSE;
			i = 1;
			_tmp24_ = TRUE;
			while (TRUE) {
				void* _tmp26_;
				void* _tmp27_;
				const gchar* _tmp28_ = NULL;
				const gchar* _tmp29_;
				void* _tmp31_;
				void* _tmp32_;
				if (!_tmp24_) {
					gint _tmp25_;
					_tmp25_ = i;
					i = _tmp25_ + 1;
				}
				_tmp24_ = FALSE;
				if (!(i < str_array_length1)) {
					break;
				}
				_tmp26_ = ptr;
				_tmp27_ = g_stpcpy (_tmp26_, (const gchar*) separator);
				ptr = _tmp27_;
				_tmp29_ = str_array[i];
				if (_tmp29_ != NULL) {
					const gchar* _tmp30_;
					_tmp30_ = str_array[i];
					_tmp28_ = (const gchar*) _tmp30_;
				} else {
					_tmp28_ = "";
				}
				_tmp31_ = ptr;
				_tmp32_ = g_stpcpy (_tmp31_, _tmp28_);
				ptr = _tmp32_;
			}
		}
		_tmp33_ = res;
		res = NULL;
		result = (gchar*) _tmp33_;
		return result;
	} else {
		gchar* _tmp34_;
		_tmp34_ = g_strdup ("");
		result = _tmp34_;
		return result;
	}
}

static void
wg_grid_update_properties (WGGrid* self)
{
	gint _tmp0_ = 0;
	gchar** _tmp1_;
	gchar** _tmp2_;
	gint _tmp2__length1;
	gchar* _tmp3_;
	gchar* _tmp4_;
	g_return_if_fail (self != NULL);
	_tmp1_ = wg_grid_get_current_content (self, &_tmp0_);
	_tmp2_ = _tmp1_;
	_tmp2__length1 = _tmp0_;
	_tmp3_ = _vala_g_strjoinv ("", _tmp2_, (gint) _tmp0_);
	_tmp4_ = _tmp3_;
	gtk_accessible_update_property ((GtkAccessible*) self, GTK_ACCESSIBLE_PROPERTY_VALUE_TEXT, _tmp4_, -1, -1);
	_g_free0 (_tmp4_);
	_tmp2_ = (_vala_array_free (_tmp2_, _tmp2__length1, (GDestroyNotify) g_free), NULL);
}

static WGCell*
wg_grid_get_cell (WGGrid* self,
                  gint x,
                  gint y)
{
	GtkGrid* _tmp0_;
	GtkWidget* _tmp1_;
	WGCell* _tmp2_;
	WGCell* result;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = self->priv->grid;
	_tmp1_ = gtk_grid_get_child_at (_tmp0_, x, y);
	_tmp2_ = _g_object_ref0 (G_TYPE_CHECK_INSTANCE_CAST (_tmp1_, WG_TYPE_CELL, WGCell));
	result = _tmp2_;
	return result;
}

static WGCell*
wg_grid_active_cell (WGGrid* self)
{
	WGCell* _tmp0_;
	WGCell* result;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = wg_grid_get_cell (self, self->priv->active_x, self->priv->active_y);
	result = _tmp0_;
	return result;
}

static WGCell*
wg_grid_set_active_cell (WGGrid* self,
                         gint x,
                         gint y)
{
	WGCell* cell = NULL;
	WGCell* _tmp0_;
	WGCell* _tmp1_;
	WGCell* _tmp3_;
	WGCell* _tmp4_;
	WGCell* result;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = wg_grid_active_cell (self);
	cell = _tmp0_;
	_tmp1_ = cell;
	if (_tmp1_ != NULL) {
		WGCell* _tmp2_;
		_tmp2_ = cell;
		wg_cell_set_focused (_tmp2_, FALSE);
	}
	self->priv->active_x = x;
	self->priv->active_y = y;
	_tmp3_ = wg_grid_active_cell (self);
	_g_object_unref0 (cell);
	cell = _tmp3_;
	_tmp4_ = cell;
	if (_tmp4_ != NULL) {
		WGCell* _tmp5_;
		_tmp5_ = cell;
		wg_cell_set_focused (_tmp5_, TRUE);
	}
	result = cell;
	return result;
}

static WGCell*
wg_grid_activate_next (WGGrid* self)
{
	WGCell* _tmp1_;
	WGCell* result;
	g_return_val_if_fail (self != NULL, NULL);
	if (self->priv->active_x == WG_GRID_COLS) {
		WGCell* _tmp0_;
		_tmp0_ = wg_grid_active_cell (self);
		result = _tmp0_;
		return result;
	}
	_tmp1_ = wg_grid_set_active_cell (self, self->priv->active_x + 1, self->priv->active_y);
	result = _tmp1_;
	return result;
}

static WGCell*
wg_grid_activate_prev (WGGrid* self)
{
	WGCell* _tmp1_;
	WGCell* result;
	g_return_val_if_fail (self != NULL, NULL);
	if (self->priv->active_x == 0) {
		WGCell* _tmp0_;
		_tmp0_ = wg_grid_active_cell (self);
		result = _tmp0_;
		return result;
	}
	_tmp1_ = wg_grid_set_active_cell (self, self->priv->active_x - 1, self->priv->active_y);
	result = _tmp1_;
	return result;
}

static WGCell*
wg_grid_activate_next_row (WGGrid* self)
{
	WGCell* _tmp1_;
	WGCell* result;
	g_return_val_if_fail (self != NULL, NULL);
	if (self->priv->active_y >= WG_GRID_ROWS) {
		WGCell* _tmp0_;
		_tmp0_ = wg_grid_active_cell (self);
		result = _tmp0_;
		return result;
	}
	_tmp1_ = wg_grid_set_active_cell (self, 0, self->priv->active_y + 1);
	result = _tmp1_;
	return result;
}

static void
_vala_array_add1 (gchar** * array,
                  gint* length,
                  gint* size,
                  gchar* value)
{
	if ((*length) == (*size)) {
		*size = (*size) ? (2 * (*size)) : 4;
		*array = g_renew (gchar*, *array, (*size) + 1);
	}
	(*array)[(*length)++] = value;
	(*array)[*length] = NULL;
}

static void
_vala_array_add2 (gchar** * array,
                  gint* length,
                  gint* size,
                  gchar* value)
{
	if ((*length) == (*size)) {
		*size = (*size) ? (2 * (*size)) : 4;
		*array = g_renew (gchar*, *array, (*size) + 1);
	}
	(*array)[(*length)++] = value;
	(*array)[*length] = NULL;
}

gchar**
wg_grid_get_current_content (WGGrid* self,
                             gint* result_length1)
{
	gchar** row = NULL;
	gchar** _tmp0_;
	gint row_length1;
	gint _row_size_;
	gchar** _tmp10_;
	gint _tmp10__length1;
	gchar** result;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = g_new0 (gchar*, 0 + 1);
	row = _tmp0_;
	row_length1 = 0;
	_row_size_ = row_length1;
	{
		gint x = 0;
		x = 0;
		{
			gboolean _tmp1_ = FALSE;
			_tmp1_ = TRUE;
			while (TRUE) {
				WGCell* cell = NULL;
				WGCell* _tmp3_;
				WGCell* _tmp4_;
				WGCell* _tmp6_;
				const gchar* _tmp7_;
				const gchar* _tmp8_;
				gchar* _tmp9_;
				if (!_tmp1_) {
					gint _tmp2_;
					_tmp2_ = x;
					x = _tmp2_ + 1;
				}
				_tmp1_ = FALSE;
				if (!(x < WG_GRID_COLS)) {
					break;
				}
				_tmp3_ = wg_grid_get_cell (self, x, self->priv->active_y);
				cell = _tmp3_;
				_tmp4_ = cell;
				if (_tmp4_ == NULL) {
					gchar* _tmp5_;
					_tmp5_ = g_strdup ("");
					_vala_array_add1 (&row, &row_length1, &_row_size_, _tmp5_);
					_g_object_unref0 (cell);
					continue;
				}
				_tmp6_ = cell;
				_tmp7_ = wg_cell_get_content (_tmp6_);
				_tmp8_ = _tmp7_;
				_tmp9_ = g_utf8_strdown (_tmp8_, (gssize) -1);
				_vala_array_add2 (&row, &row_length1, &_row_size_, _tmp9_);
				_g_object_unref0 (cell);
			}
		}
	}
	_tmp10_ = row;
	_tmp10__length1 = row_length1;
	if (result_length1) {
		*result_length1 = _tmp10__length1;
	}
	result = _tmp10_;
	return result;
}

gboolean
wg_grid_is_row_filled (WGGrid* self)
{
	gint _tmp0_ = 0;
	gchar** _tmp1_;
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	_tmp1_ = wg_grid_get_current_content (self, &_tmp0_);
	{
		gchar** cell_collection = NULL;
		gint cell_collection_length1 = 0;
		gint _cell_collection_size_ = 0;
		gint cell_it = 0;
		cell_collection = _tmp1_;
		cell_collection_length1 = _tmp0_;
		for (cell_it = 0; cell_it < cell_collection_length1; cell_it = cell_it + 1) {
			gchar* _tmp2_;
			gchar* cell = NULL;
			_tmp2_ = g_strdup (cell_collection[cell_it]);
			cell = _tmp2_;
			{
				const gchar* _tmp3_;
				gint _tmp4_;
				gint _tmp5_;
				_tmp3_ = cell;
				_tmp4_ = strlen (_tmp3_);
				_tmp5_ = _tmp4_;
				if (_tmp5_ == 0) {
					result = FALSE;
					_g_free0 (cell);
					cell_collection = (_vala_array_free (cell_collection, cell_collection_length1, (GDestroyNotify) g_free), NULL);
					return result;
				}
				_g_free0 (cell);
			}
		}
		cell_collection = (_vala_array_free (cell_collection, cell_collection_length1, (GDestroyNotify) g_free), NULL);
	}
	result = TRUE;
	return result;
}

static void
wg_grid_set_cell_state (WGGrid* self,
                        gint x,
                        gint y,
                        WGCellState state)
{
	WGCell* _tmp0_;
	WGCell* _tmp1_;
	g_return_if_fail (self != NULL);
	_tmp0_ = wg_grid_get_cell (self, x, y);
	_tmp1_ = _tmp0_;
	wg_cell_set_state (_tmp1_, state);
	_g_object_unref0 (_tmp1_);
}

static void
wg_grid_reset_row_state (WGGrid* self)
{
	g_return_if_fail (self != NULL);
	{
		gint x = 0;
		x = 0;
		{
			gboolean _tmp0_ = FALSE;
			_tmp0_ = TRUE;
			while (TRUE) {
				if (!_tmp0_) {
					gint _tmp1_;
					_tmp1_ = x;
					x = _tmp1_ + 1;
				}
				_tmp0_ = FALSE;
				if (!(x < WG_GRID_COLS)) {
					break;
				}
				wg_grid_set_cell_state (self, x, self->priv->active_y, WG_CELL_STATE_NONE);
			}
		}
	}
}

static void
wg_grid_clear (WGGrid* self)
{
	WGCell* _tmp7_;
	WGCell* _tmp8_;
	g_return_if_fail (self != NULL);
	{
		gint y = 0;
		y = 0;
		{
			gboolean _tmp0_ = FALSE;
			_tmp0_ = TRUE;
			while (TRUE) {
				if (!_tmp0_) {
					gint _tmp1_;
					_tmp1_ = y;
					y = _tmp1_ + 1;
				}
				_tmp0_ = FALSE;
				if (!(y < WG_GRID_ROWS)) {
					break;
				}
				{
					gint x = 0;
					x = 0;
					{
						gboolean _tmp2_ = FALSE;
						_tmp2_ = TRUE;
						while (TRUE) {
							WGCell* cell = NULL;
							WGCell* _tmp4_;
							WGCell* _tmp5_;
							WGCell* _tmp6_;
							if (!_tmp2_) {
								gint _tmp3_;
								_tmp3_ = x;
								x = _tmp3_ + 1;
							}
							_tmp2_ = FALSE;
							if (!(x < WG_GRID_COLS)) {
								break;
							}
							_tmp4_ = wg_grid_get_cell (self, x, y);
							cell = _tmp4_;
							_tmp5_ = cell;
							wg_cell_set_content (_tmp5_, "");
							_tmp6_ = cell;
							wg_cell_set_state (_tmp6_, WG_CELL_STATE_NONE);
							_g_object_unref0 (cell);
						}
					}
				}
			}
		}
	}
	_tmp7_ = wg_grid_set_active_cell (self, 0, 0);
	_tmp8_ = _tmp7_;
	_g_object_unref0 (_tmp8_);
}

WGGrid*
wg_grid_construct (GType object_type)
{
	WGGrid * self = NULL;
	self = (WGGrid*) g_object_new (object_type, NULL);
	return self;
}

WGGrid*
wg_grid_new (void)
{
	return wg_grid_construct (WG_TYPE_GRID);
}

static void
g_cclosure_user_marshal_POINTER__BOXED_INT (GClosure * closure,
                                            GValue * return_value,
                                            guint n_param_values,
                                            const GValue * param_values,
                                            gpointer invocation_hint,
                                            gpointer marshal_data)
{
	typedef gpointer (*GMarshalFunc_POINTER__BOXED_INT) (gpointer data1, gpointer arg_1, gint arg_2, gpointer data2);
	register GMarshalFunc_POINTER__BOXED_INT callback;
	register GCClosure * cc;
	register gpointer data1;
	register gpointer data2;
	gpointer v_return;
	cc = (GCClosure *) closure;
	g_return_if_fail (return_value != NULL);
	g_return_if_fail (n_param_values == 3);
	if (G_CCLOSURE_SWAP_DATA (closure)) {
		data1 = closure->data;
		data2 = param_values->data[0].v_pointer;
	} else {
		data1 = param_values->data[0].v_pointer;
		data2 = closure->data;
	}
	callback = (GMarshalFunc_POINTER__BOXED_INT) (marshal_data ? marshal_data : cc->callback);
	v_return = callback (data1, g_value_get_boxed (param_values + 1), g_value_get_int (param_values + 2), data2);
	g_value_set_pointer (return_value, v_return);
}

static void
wg_grid_real_game_over (WGGrid* self,
                        gboolean win)
{
	GtkEventControllerKey* _tmp0_;
	_tmp0_ = self->priv->controller;
	gtk_widget_remove_controller ((GtkWidget*) self, (GtkEventController*) _tmp0_);
}

static gboolean
_vala_string_array_contains (gchar* * stack,
                             gssize stack_length,
                             const gchar* needle)
{
	gssize i;
	for (i = 0; i < stack_length; i++) {
		if (g_strcmp0 (stack[i], needle) == 0) {
			return TRUE;
		}
	}
	return FALSE;
}

static void
_wg_grid___lambda6_ (WGGrid* self,
                     const gchar* str)
{
	gchar* key = NULL;
	gchar* _tmp0_;
	gchar* _tmp1_;
	gchar* _tmp2_;
	gchar* _tmp3_;
	const gchar* _tmp4_;
	gint _tmp5_ = 0;
	gchar** _tmp6_;
	gchar** _tmp7_;
	gint _tmp7__length1;
	gboolean _tmp8_;
	const gchar* _tmp9_;
	g_return_if_fail (str != NULL);
	_tmp0_ = g_utf8_strdown (str, (gssize) -1);
	_tmp1_ = _tmp0_;
	_tmp2_ = wg_data_parser_replace (_tmp1_);
	_tmp3_ = _tmp2_;
	_g_free0 (_tmp1_);
	key = _tmp3_;
	_tmp4_ = key;
	_tmp6_ = wg_data_parser_get_available_letters (&_tmp5_);
	_tmp7_ = _tmp6_;
	_tmp7__length1 = _tmp5_;
	_tmp8_ = !_vala_string_array_contains (_tmp7_, _tmp5_, _tmp4_);
	_tmp7_ = (_vala_array_free (_tmp7_, _tmp7__length1, (GDestroyNotify) g_free), NULL);
	if (_tmp8_) {
		_g_free0 (key);
		return;
	}
	_tmp9_ = key;
	wg_grid_insert (self, _tmp9_);
	_g_free0 (key);
}

static void
__wg_grid___lambda6__gtk_im_context_commit (GtkIMContext* _sender,
                                            const gchar* str,
                                            gpointer self)
{
	_wg_grid___lambda6_ ((WGGrid*) self, str);
}

static gboolean
_wg_grid___lambda7_ (WGGrid* self,
                     guint val,
                     guint code,
                     GdkModifierType state)
{
	gboolean _tmp0_ = FALSE;
	gboolean _tmp1_ = FALSE;
	gboolean _tmp2_ = FALSE;
	gboolean _tmp3_ = FALSE;
	gboolean result;
	if (val == GDK_KEY_BackSpace) {
		_tmp1_ = TRUE;
	} else {
		_tmp1_ = val == GDK_KEY_Delete;
	}
	if (_tmp1_) {
		_tmp0_ = TRUE;
	} else {
		_tmp0_ = val == GDK_KEY_KP_Delete;
	}
	if (_tmp0_) {
		wg_grid_backspace (self);
		result = TRUE;
		return result;
	}
	if (val == GDK_KEY_Return) {
		_tmp3_ = TRUE;
	} else {
		_tmp3_ = val == GDK_KEY_KP_Enter;
	}
	if (_tmp3_) {
		_tmp2_ = TRUE;
	} else {
		_tmp2_ = val == GDK_KEY_ISO_Enter;
	}
	if (_tmp2_) {
		wg_grid_confirm (self);
		result = TRUE;
		return result;
	}
	result = FALSE;
	return result;
}

static gboolean
__wg_grid___lambda7__gtk_event_controller_key_key_pressed (GtkEventControllerKey* _sender,
                                                           guint keyval,
                                                           guint keycode,
                                                           GdkModifierType state,
                                                           gpointer self)
{
	gboolean result;
	result = _wg_grid___lambda7_ ((WGGrid*) self, keyval, keycode, state);
	return result;
}

static void
_wg_grid___lambda8_ (WGGrid* self)
{
	gtk_widget_grab_focus ((GtkWidget*) self);
}

static void
__wg_grid___lambda8__gtk_gesture_click_released (GtkGestureClick* _sender,
                                                 gint n_press,
                                                 gdouble x,
                                                 gdouble y,
                                                 gpointer self)
{
	_wg_grid___lambda8_ ((WGGrid*) self);
}

static GObject *
wg_grid_constructor (GType type,
                     guint n_construct_properties,
                     GObjectConstructParam * construct_properties)
{
	GObject * obj;
	GObjectClass * parent_class;
	WGGrid * self;
	GtkGrid* _tmp0_;
	GtkGrid* _tmp1_;
	GtkGrid* _tmp2_;
	GtkGrid* _tmp3_;
	GtkGrid* _tmp4_;
	WGCell* _tmp12_;
	WGCell* _tmp13_;
	GtkIMMulticontext* context = NULL;
	GtkIMMulticontext* _tmp14_;
	GtkEventControllerKey* _tmp15_;
	GtkIMMulticontext* _tmp16_;
	GtkIMMulticontext* _tmp17_;
	GtkEventControllerKey* _tmp18_;
	GtkGestureClick* click_controller = NULL;
	GtkGestureClick* _tmp19_;
	GtkGestureClick* _tmp20_;
	GtkEventController* _tmp21_;
	GtkGestureClick* _tmp22_;
	parent_class = G_OBJECT_CLASS (wg_grid_parent_class);
	obj = parent_class->constructor (type, n_construct_properties, construct_properties);
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, WG_TYPE_GRID, WGGrid);
	gtk_widget_set_focusable ((GtkWidget*) self, TRUE);
	gtk_widget_set_can_focus ((GtkWidget*) self, TRUE);
	g_object_set ((GtkAccessible*) self, "accessible-role", GTK_ACCESSIBLE_ROLE_TEXT_BOX, NULL);
	gtk_accessible_update_property ((GtkAccessible*) self, GTK_ACCESSIBLE_PROPERTY_LABEL, _ ("the letter grid"), -1, -1);
	gtk_widget_add_css_class ((GtkWidget*) self, "letter-grid");
	gtk_widget_set_margin_top ((GtkWidget*) self, 10);
	gtk_widget_set_margin_bottom ((GtkWidget*) self, 10);
	gtk_widget_set_margin_start ((GtkWidget*) self, 10);
	gtk_widget_set_margin_end ((GtkWidget*) self, 10);
	gtk_widget_set_halign ((GtkWidget*) self, GTK_ALIGN_CENTER);
	gtk_widget_set_hexpand ((GtkWidget*) self, TRUE);
	gtk_widget_set_valign ((GtkWidget*) self, GTK_ALIGN_CENTER);
	gtk_widget_set_vexpand ((GtkWidget*) self, TRUE);
	_tmp0_ = self->priv->grid;
	adw_bin_set_child ((AdwBin*) self, (GtkWidget*) _tmp0_);
	_tmp1_ = self->priv->grid;
	gtk_grid_set_column_homogeneous (_tmp1_, TRUE);
	_tmp2_ = self->priv->grid;
	gtk_grid_set_row_homogeneous (_tmp2_, TRUE);
	_tmp3_ = self->priv->grid;
	gtk_grid_set_column_spacing (_tmp3_, 6);
	_tmp4_ = self->priv->grid;
	gtk_grid_set_row_spacing (_tmp4_, 6);
	{
		gint y = 0;
		y = 0;
		{
			gboolean _tmp5_ = FALSE;
			_tmp5_ = TRUE;
			while (TRUE) {
				if (!_tmp5_) {
					gint _tmp6_;
					_tmp6_ = y;
					y = _tmp6_ + 1;
				}
				_tmp5_ = FALSE;
				if (!(y < WG_GRID_ROWS)) {
					break;
				}
				{
					gint x = 0;
					x = 0;
					{
						gboolean _tmp7_ = FALSE;
						_tmp7_ = TRUE;
						while (TRUE) {
							GtkGrid* _tmp9_;
							WGCell* _tmp10_;
							WGCell* _tmp11_;
							if (!_tmp7_) {
								gint _tmp8_;
								_tmp8_ = x;
								x = _tmp8_ + 1;
							}
							_tmp7_ = FALSE;
							if (!(x < WG_GRID_COLS)) {
								break;
							}
							_tmp9_ = self->priv->grid;
							_tmp10_ = wg_cell_new ();
							g_object_ref_sink (_tmp10_);
							_tmp11_ = _tmp10_;
							gtk_grid_attach (_tmp9_, (GtkWidget*) _tmp11_, x, y, 1, 1);
							_g_object_unref0 (_tmp11_);
						}
					}
				}
			}
		}
	}
	_tmp12_ = wg_grid_active_cell (self);
	_tmp13_ = _tmp12_;
	wg_cell_set_focused (_tmp13_, TRUE);
	_g_object_unref0 (_tmp13_);
	_tmp14_ = (GtkIMMulticontext*) gtk_im_multicontext_new ();
	context = _tmp14_;
	_tmp15_ = self->priv->controller;
	_tmp16_ = context;
	gtk_event_controller_key_set_im_context (_tmp15_, (GtkIMContext*) _tmp16_);
	_tmp17_ = context;
	g_signal_connect_object ((GtkIMContext*) _tmp17_, "commit", (GCallback) __wg_grid___lambda6__gtk_im_context_commit, self, 0);
	_tmp18_ = self->priv->controller;
	g_signal_connect_object (_tmp18_, "key-pressed", (GCallback) __wg_grid___lambda7__gtk_event_controller_key_key_pressed, self, 0);
	_tmp19_ = (GtkGestureClick*) gtk_gesture_click_new ();
	click_controller = _tmp19_;
	_tmp20_ = click_controller;
	_tmp21_ = _g_object_ref0 ((GtkEventController*) _tmp20_);
	gtk_widget_add_controller ((GtkWidget*) self, _tmp21_);
	_tmp22_ = click_controller;
	g_signal_connect_object (_tmp22_, "released", (GCallback) __wg_grid___lambda8__gtk_gesture_click_released, self, 0);
	_g_object_unref0 (click_controller);
	_g_object_unref0 (context);
	return obj;
}

static void
wg_grid_class_init (WGGridClass * klass,
                    gpointer klass_data)
{
	wg_grid_parent_class = g_type_class_peek_parent (klass);
	g_type_class_adjust_private_offset (klass, &WGGrid_private_offset);
	((WGGridClass *) klass)->game_over = wg_grid_real_game_over;
	G_OBJECT_CLASS (klass)->constructor = wg_grid_constructor;
	G_OBJECT_CLASS (klass)->finalize = wg_grid_finalize;
	/**
	     * Emitted when the current word is confirmed.
	     *
	     * Gets the current row content as the first argument.
	     * The second argument is a bool, true if the current row is the last one.
	     *
	     * Returns List of CellStates.
	     * If the word is unknown, it's expected to be an empty list.
	     */
	wg_grid_signals[WG_GRID_CONFIRMED_SIGNAL] = g_signal_new ("confirmed", WG_TYPE_GRID, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_user_marshal_POINTER__BOXED_INT, G_TYPE_POINTER, 2, G_TYPE_STRV, G_TYPE_INT);
	/**
	     * Emitted when the game ends.
	     * (the grid is filled up or the word is guessed)
	     *
	     * If the game was won is given as a bool argument.
	     */
	wg_grid_signals[WG_GRID_GAME_OVER_SIGNAL] = g_signal_new ("game-over", WG_TYPE_GRID, G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (WGGridClass, game_over), NULL, NULL, g_cclosure_marshal_VOID__BOOLEAN, G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
}

static void
wg_grid_instance_init (WGGrid * self,
                       gpointer klass)
{
	GtkGrid* _tmp0_;
	GtkEventControllerKey* _tmp1_;
	self->priv = wg_grid_get_instance_private (self);
	self->priv->active_x = 0;
	self->priv->active_y = 0;
	_tmp0_ = (GtkGrid*) gtk_grid_new ();
	g_object_ref_sink (_tmp0_);
	self->priv->grid = _tmp0_;
	_tmp1_ = (GtkEventControllerKey*) gtk_event_controller_key_new ();
	self->priv->controller = _tmp1_;
}

static void
wg_grid_finalize (GObject * obj)
{
	WGGrid * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, WG_TYPE_GRID, WGGrid);
	_g_object_unref0 (self->priv->grid);
	_g_object_unref0 (self->priv->controller);
	G_OBJECT_CLASS (wg_grid_parent_class)->finalize (obj);
}

static GType
wg_grid_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (WGGridClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) wg_grid_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (WGGrid), 0, (GInstanceInitFunc) wg_grid_instance_init, NULL };
	GType wg_grid_type_id;
	wg_grid_type_id = g_type_register_static (adw_bin_get_type (), "WGGrid", &g_define_type_info, 0);
	WGGrid_private_offset = g_type_add_instance_private (wg_grid_type_id, sizeof (WGGridPrivate));
	return wg_grid_type_id;
}

GType
wg_grid_get_type (void)
{
	static volatile gsize wg_grid_type_id__once = 0;
	if (g_once_init_enter (&wg_grid_type_id__once)) {
		GType wg_grid_type_id;
		wg_grid_type_id = wg_grid_get_type_once ();
		g_once_init_leave (&wg_grid_type_id__once, wg_grid_type_id);
	}
	return wg_grid_type_id__once;
}

static void
_vala_array_destroy (gpointer array,
                     gssize array_length,
                     GDestroyNotify destroy_func)
{
	if ((array != NULL) && (destroy_func != NULL)) {
		gssize i;
		for (i = 0; i < array_length; i = i + 1) {
			if (((gpointer*) array)[i] != NULL) {
				destroy_func (((gpointer*) array)[i]);
			}
		}
	}
}

static void
_vala_array_free (gpointer array,
                  gssize array_length,
                  GDestroyNotify destroy_func)
{
	_vala_array_destroy (array, array_length, destroy_func);
	g_free (array);
}

