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

/* -*- Mode: vala; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * Copyright © 2025 Johan Gay
 *
 * This file is part of GNOME Sudoku.
 *
 * GNOME Sudoku 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.
 *
 * GNOME Sudoku 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 GNOME Sudoku. If not, see <http://www.gnu.org/licenses/>.
 */

#include <gtk/gtk.h>
#include <glib-object.h>
#include "libsudoku.h"
#include <glib.h>
#include <float.h>
#include <math.h>
#include <gio/gio.h>
#include <stdlib.h>
#include <string.h>
#include <adwaita.h>
#include <gee.h>
#include <gdk/gdk.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 TYPE_SUDOKU_GRID (sudoku_grid_get_type ())
#define SUDOKU_GRID(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_SUDOKU_GRID, SudokuGrid))
#define SUDOKU_GRID_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_SUDOKU_GRID, SudokuGridClass))
#define IS_SUDOKU_GRID(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_SUDOKU_GRID))
#define IS_SUDOKU_GRID_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_SUDOKU_GRID))
#define SUDOKU_GRID_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_SUDOKU_GRID, SudokuGridClass))

typedef struct _SudokuGrid SudokuGrid;
typedef struct _SudokuGridClass SudokuGridClass;
typedef struct _SudokuGridPrivate SudokuGridPrivate;

#define TYPE_SUDOKU_NUMBER_PICKER (sudoku_number_picker_get_type ())
#define SUDOKU_NUMBER_PICKER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_SUDOKU_NUMBER_PICKER, SudokuNumberPicker))
#define SUDOKU_NUMBER_PICKER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_SUDOKU_NUMBER_PICKER, SudokuNumberPickerClass))
#define IS_SUDOKU_NUMBER_PICKER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_SUDOKU_NUMBER_PICKER))
#define IS_SUDOKU_NUMBER_PICKER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_SUDOKU_NUMBER_PICKER))
#define SUDOKU_NUMBER_PICKER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_SUDOKU_NUMBER_PICKER, SudokuNumberPickerClass))

typedef struct _SudokuNumberPicker SudokuNumberPicker;
typedef struct _SudokuNumberPickerClass SudokuNumberPickerClass;

#define TYPE_SUDOKU_CELL (sudoku_cell_get_type ())
#define SUDOKU_CELL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_SUDOKU_CELL, SudokuCell))
#define SUDOKU_CELL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_SUDOKU_CELL, SudokuCellClass))
#define IS_SUDOKU_CELL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_SUDOKU_CELL))
#define IS_SUDOKU_CELL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_SUDOKU_CELL))
#define SUDOKU_CELL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_SUDOKU_CELL, SudokuCellClass))

typedef struct _SudokuCell SudokuCell;
typedef struct _SudokuCellClass SudokuCellClass;
enum  {
	SUDOKU_GRID_0_PROPERTY,
	SUDOKU_GRID_SELECTED_ROW_PROPERTY,
	SUDOKU_GRID_SELECTED_COL_PROPERTY,
	SUDOKU_GRID_SELECTED_CELL_PROPERTY,
	SUDOKU_GRID_NUM_PROPERTIES
};
static GParamSpec* sudoku_grid_properties[SUDOKU_GRID_NUM_PROPERTIES];
#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))

#define TYPE_SUDOKU (sudoku_get_type ())
#define SUDOKU(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_SUDOKU, Sudoku))
#define SUDOKU_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_SUDOKU, SudokuClass))
#define IS_SUDOKU(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_SUDOKU))
#define IS_SUDOKU_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_SUDOKU))
#define SUDOKU_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_SUDOKU, SudokuClass))

typedef struct _Sudoku Sudoku;
typedef struct _SudokuClass SudokuClass;
typedef enum  {
	ZOOM_LEVEL_NONE = 0,
	ZOOM_LEVEL_SMALL = 1,
	ZOOM_LEVEL_MEDIUM = 2,
	ZOOM_LEVEL_LARGE = 3
} ZoomLevel;

#define TYPE_ZOOM_LEVEL (zoom_level_get_type ())
#define _g_free0(var) ((var == NULL) ? NULL : (var = (g_free (var), NULL)))

#define TYPE_SUDOKU_WINDOW (sudoku_window_get_type ())
#define SUDOKU_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_SUDOKU_WINDOW, SudokuWindow))
#define SUDOKU_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_SUDOKU_WINDOW, SudokuWindowClass))
#define IS_SUDOKU_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_SUDOKU_WINDOW))
#define IS_SUDOKU_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_SUDOKU_WINDOW))
#define SUDOKU_WINDOW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_SUDOKU_WINDOW, SudokuWindowClass))

typedef struct _SudokuWindow SudokuWindow;
typedef struct _SudokuWindowClass SudokuWindowClass;

struct _SudokuGrid {
	GtkGrid parent_instance;
	SudokuGridPrivate * priv;
	SudokuNumberPicker* number_picker;
};

struct _SudokuGridClass {
	GtkGridClass parent_class;
};

struct _SudokuGridPrivate {
	SudokuGame* game;
	SudokuCell** cells;
	gint cells_length1;
	gint cells_length2;
	gint _selected_row;
	gint _selected_col;
	gdouble zoom_value_multiplier;
	gdouble zoom_earmark_multiplier;
	GtkGestureClick* button_controller;
	GtkEventControllerFocus* focus_controller;
	GSimpleActionGroup* action_group;
	GSimpleAction* move_up_action;
	GSimpleAction* move_down_action;
	GSimpleAction* move_left_action;
	GSimpleAction* move_right_action;
	GSimpleAction* escape_action;
};

static gint SudokuGrid_private_offset;
static gpointer sudoku_grid_parent_class = NULL;
VALA_EXTERN Sudoku* sudoku_app;

VALA_EXTERN GType sudoku_grid_get_type (void) G_GNUC_CONST ;
G_DEFINE_AUTOPTR_CLEANUP_FUNC (SudokuGrid, g_object_unref)
VALA_EXTERN GType sudoku_number_picker_get_type (void) G_GNUC_CONST ;
G_DEFINE_AUTOPTR_CLEANUP_FUNC (SudokuNumberPicker, g_object_unref)
VALA_EXTERN GType sudoku_cell_get_type (void) G_GNUC_CONST ;
G_DEFINE_AUTOPTR_CLEANUP_FUNC (SudokuCell, g_object_unref)
static void sudoku_grid_new_move_shortcut (SudokuGridClass* klass,
                                    const gchar* name,
                                    const gchar* accelerator,
                                    GtkDirectionType dir);
VALA_EXTERN SudokuGrid* sudoku_grid_new (SudokuGame* game);
VALA_EXTERN SudokuGrid* sudoku_grid_construct (GType object_type,
                                   SudokuGame* game);
static void sudoku_grid_button_released_cb (SudokuGrid* self,
                                     GtkGestureClick* gesture,
                                     gint n_press,
                                     gdouble x,
                                     gdouble y);
static void _sudoku_grid_button_released_cb_gtk_gesture_click_released (GtkGestureClick* _sender,
                                                                 gint n_press,
                                                                 gdouble x,
                                                                 gdouble y,
                                                                 gpointer self);
VALA_EXTERN SudokuNumberPicker* sudoku_number_picker_new (SudokuGame* game);
VALA_EXTERN SudokuNumberPicker* sudoku_number_picker_construct (GType object_type,
                                                    SudokuGame* game);
VALA_EXTERN void sudoku_grid_update_zoom (SudokuGrid* self);
VALA_EXTERN SudokuCell* sudoku_cell_new (SudokuGame* game,
                             SudokuGrid* grid,
                             gdouble* zoom_value_multiplier,
                             gdouble* zoom_earmark_multiplier,
                             gint row,
                             gint col);
VALA_EXTERN SudokuCell* sudoku_cell_construct (GType object_type,
                                   SudokuGame* game,
                                   SudokuGrid* grid,
                                   gdouble* zoom_value_multiplier,
                                   gdouble* zoom_earmark_multiplier,
                                   gint row,
                                   gint col);
VALA_EXTERN void sudoku_grid_update_selected (SudokuGrid* self,
                                  SudokuCell* cell);
static void _sudoku_grid_update_selected_sudoku_cell_select (SudokuCell* _sender,
                                                      gpointer self);
static void __lambda18_ (SudokuGrid* self);
VALA_EXTERN void sudoku_grid_unselect (SudokuGrid* self);
static void ___lambda18__gtk_event_controller_focus_leave (GtkEventControllerFocus* _sender,
                                                    gpointer self);
static void sudoku_grid_add_game_hooks (SudokuGrid* self);
VALA_EXTERN void sudoku_grid_update_warnings (SudokuGrid* self);
static void sudoku_grid_new_move_action (SudokuGrid* self,
                                  const gchar* name,
                                  GSimpleAction** action);
static void _gtk_popover_popdown_g_simple_action_activate (GSimpleAction* _sender,
                                                    GVariant* parameter,
                                                    gpointer self);
static void sudoku_grid_move (SudokuGrid* self,
                       GVariant* variant);
static void _sudoku_grid_move_g_simple_action_activate (GSimpleAction* _sender,
                                                 GVariant* parameter,
                                                 gpointer self);
VALA_EXTERN void sudoku_grid_change_game (SudokuGrid* self,
                              SudokuGame* new_game);
VALA_EXTERN void sudoku_number_picker_change_game (SudokuNumberPicker* self,
                                       SudokuGame* new_game);
static void sudoku_grid_set_selected_row (SudokuGrid* self,
                                   gint value);
static void sudoku_grid_set_selected_col (SudokuGrid* self,
                                   gint value);
VALA_EXTERN void sudoku_cell_change_game (SudokuCell* self,
                              SudokuGame* new_game);
VALA_EXTERN void sudoku_cell_update_content_visibility (SudokuCell* self);
VALA_EXTERN void sudoku_cell_update_fixed (SudokuCell* self);
static void sudoku_grid_paused_cb (SudokuGrid* self);
static void _sudoku_grid_paused_cb_g_object_notify (GObject* _sender,
                                             GParamSpec* pspec,
                                             gpointer self);
static void sudoku_grid_value_changed_cb (SudokuGrid* self,
                                   gint row,
                                   gint col,
                                   gint old_val,
                                   gint new_val);
static void _sudoku_grid_value_changed_cb_sudoku_board_value_changed (SudokuBoard* _sender,
                                                               gint row,
                                                               gint col,
                                                               gint old_val,
                                                               gint new_val,
                                                               gpointer self);
static void sudoku_grid_earmark_changed_cb (SudokuGrid* self,
                                     gint row,
                                     gint col,
                                     gint num,
                                     gboolean enabled);
static void _sudoku_grid_earmark_changed_cb_sudoku_board_earmark_changed (SudokuBoard* _sender,
                                                                   gint row,
                                                                   gint col,
                                                                   gint num,
                                                                   gboolean enabled,
                                                                   gpointer self);
static void sudoku_grid_update_highlighter (SudokuGrid* self,
                                     gint old_row,
                                     gint old_col);
static void sudoku_grid_set_cell_highlighter (SudokuGrid* self,
                                       gint row,
                                       gint col,
                                       gboolean enabled);
VALA_EXTERN gint sudoku_grid_get_selected_row (SudokuGrid* self);
VALA_EXTERN gint sudoku_grid_get_selected_col (SudokuGrid* self);
static void sudoku_grid_update_value_highlighter (SudokuGrid* self,
                                           gint row,
                                           gint col,
                                           gint old_val,
                                           gint new_val);
VALA_EXTERN GType sudoku_get_type (void) G_GNUC_CONST ;
G_DEFINE_AUTOPTR_CLEANUP_FUNC (Sudoku, g_object_unref)
VALA_EXTERN gboolean sudoku_get_highlight_numbers (Sudoku* self);
VALA_EXTERN SudokuCell* sudoku_grid_get_selected_cell (SudokuGrid* self);
VALA_EXTERN gint sudoku_cell_get_value (SudokuCell* self);
VALA_EXTERN void sudoku_cell_set_highlight_number (SudokuCell* self,
                                       gboolean value);
VALA_EXTERN void sudoku_cell_set_earmark_highlight (SudokuCell* self,
                                        gint num,
                                        gboolean enabled);
VALA_EXTERN gboolean sudoku_cell_get_is_fixed (SudokuCell* self);
VALA_EXTERN gboolean sudoku_get_highlight_row_column (Sudoku* self);
VALA_EXTERN gint sudoku_cell_get_row (SudokuCell* self);
VALA_EXTERN gint sudoku_cell_get_col (SudokuCell* self);
VALA_EXTERN gboolean sudoku_get_highlight_block (Sudoku* self);
VALA_EXTERN void sudoku_cell_set_highlight_coord (SudokuCell* self,
                                      gboolean value);
VALA_EXTERN GType zoom_level_get_type (void) G_GNUC_CONST ;
VALA_EXTERN ZoomLevel sudoku_get_zoom_level (Sudoku* self);
VALA_EXTERN void sudoku_grid_toggle_highlighter (SudokuGrid* self);
VALA_EXTERN void sudoku_cell_update_value_warnings (SudokuCell* self);
VALA_EXTERN void sudoku_cell_update_all_earmark_warnings (SudokuCell* self);
VALA_EXTERN void sudoku_grid_update_cell_warnings (SudokuGrid* self,
                                       gint row,
                                       gint col);
VALA_EXTERN gboolean sudoku_cell_get_selected (SudokuCell* self);
VALA_EXTERN void sudoku_cell_set_selected (SudokuCell* self,
                               gboolean value);
VALA_EXTERN gboolean sudoku_cell_grab_selection (SudokuCell* self);
VALA_EXTERN void sudoku_cell_update_earmark_visibility (SudokuCell* self,
                                            gint num);
VALA_EXTERN void sudoku_cell_animate_earmark_removal (SudokuCell* self,
                                          gint num);
VALA_EXTERN void sudoku_cell_update_earmark_warning (SudokuCell* self,
                                         gint num);
static gboolean sudoku_grid_real_grab_focus (GtkWidget* base);
VALA_EXTERN GType sudoku_window_get_type (void) G_GNUC_CONST ;
G_DEFINE_AUTOPTR_CLEANUP_FUNC (SudokuWindow, g_object_unref)
VALA_EXTERN gboolean sudoku_window_get_keyboard_pressed_recently (SudokuWindow* self);
static gboolean sudoku_grid_real_focus (GtkWidget* base,
                                 GtkDirectionType direction);
static void sudoku_grid_real_dispose (GObject* base);
static void sudoku_grid_finalize (GObject * obj);
static GType sudoku_grid_get_type_once (void);
static void _vala_sudoku_grid_get_property (GObject * object,
                                     guint property_id,
                                     GValue * value,
                                     GParamSpec * pspec);
static void _vala_sudoku_grid_set_property (GObject * object,
                                     guint property_id,
                                     const GValue * value,
                                     GParamSpec * pspec);
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 const Coord SUDOKU_GRID_START = {4, 4};

static inline gpointer
sudoku_grid_get_instance_private (SudokuGrid* self)
{
	return G_STRUCT_MEMBER_P (self, SudokuGrid_private_offset);
}

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

static void
sudoku_grid_new_move_shortcut (SudokuGridClass* klass,
                               const gchar* name,
                               const gchar* accelerator,
                               GtkDirectionType dir)
{
	GtkNamedAction* action = NULL;
	GtkNamedAction* _tmp0_;
	GtkShortcutTrigger* trigger = NULL;
	GtkShortcutTrigger* _tmp1_;
	GtkShortcut* shortcut = NULL;
	GtkShortcutTrigger* _tmp2_;
	GtkShortcutAction* _tmp3_;
	GtkShortcut* _tmp4_;
	g_return_if_fail (name != NULL);
	g_return_if_fail (accelerator != NULL);
	_tmp0_ = (GtkNamedAction*) gtk_named_action_new (name);
	action = _tmp0_;
	_tmp1_ = gtk_shortcut_trigger_parse_string (accelerator);
	trigger = _tmp1_;
	_tmp2_ = _g_object_ref0 (trigger);
	_tmp3_ = _g_object_ref0 ((GtkShortcutAction*) action);
	_tmp4_ = gtk_shortcut_new_with_arguments (_tmp2_, _tmp3_, "i", dir, NULL);
	shortcut = _tmp4_;
	gtk_widget_class_add_shortcut (GTK_WIDGET_CLASS (klass), shortcut);
	_g_object_unref0 (shortcut);
	_g_object_unref0 (trigger);
	_g_object_unref0 (action);
}

static void
_sudoku_grid_button_released_cb_gtk_gesture_click_released (GtkGestureClick* _sender,
                                                            gint n_press,
                                                            gdouble x,
                                                            gdouble y,
                                                            gpointer self)
{
	sudoku_grid_button_released_cb ((SudokuGrid*) self, _sender, n_press, x, y);
}

static void
_sudoku_grid_update_selected_sudoku_cell_select (SudokuCell* _sender,
                                                 gpointer self)
{
	sudoku_grid_update_selected ((SudokuGrid*) self, _sender);
}

static void
__lambda18_ (SudokuGrid* self)
{
	GtkWindow* window = NULL;
	GtkRoot* _tmp0_;
	GtkWindow* _tmp1_;
	GtkWindow* _tmp2_;
	gboolean _tmp3_;
	gboolean _tmp4_;
	_tmp0_ = gtk_widget_get_root ((GtkWidget*) self);
	_tmp1_ = _g_object_ref0 (G_TYPE_CHECK_INSTANCE_TYPE (_tmp0_, gtk_window_get_type ()) ? ((GtkWindow*) _tmp0_) : NULL);
	window = _tmp1_;
	_tmp2_ = window;
	g_object_get (_tmp2_, "is-active", &_tmp3_, NULL);
	_tmp4_ = _tmp3_;
	if (_tmp4_) {
		sudoku_grid_unselect (self);
	}
	_g_object_unref0 (window);
}

static void
___lambda18__gtk_event_controller_focus_leave (GtkEventControllerFocus* _sender,
                                               gpointer self)
{
	__lambda18_ ((SudokuGrid*) self);
}

static void
_gtk_popover_popdown_g_simple_action_activate (GSimpleAction* _sender,
                                               GVariant* parameter,
                                               gpointer self)
{
	gtk_popover_popdown ((GtkPopover*) self);
}

SudokuGrid*
sudoku_grid_construct (GType object_type,
                       SudokuGame* game)
{
	SudokuGrid * self = NULL;
	SudokuGame* _tmp0_;
	GtkGestureClick* _tmp1_;
	GtkGestureClick* _tmp2_;
	GtkGestureClick* _tmp3_;
	GtkGestureClick* _tmp4_;
	GtkEventController* _tmp5_;
	SudokuNumberPicker* _tmp6_;
	GtkGrid** blocks = NULL;
	SudokuBoard* _tmp7_;
	SudokuBoard* _tmp8_;
	gint _tmp9_;
	gint _tmp10_;
	SudokuBoard* _tmp11_;
	SudokuBoard* _tmp12_;
	gint _tmp13_;
	gint _tmp14_;
	GtkGrid** _tmp15_;
	gint blocks_length1;
	gint blocks_length2;
	SudokuBoard* _tmp39_;
	SudokuBoard* _tmp40_;
	gint _tmp41_;
	gint _tmp42_;
	SudokuBoard* _tmp43_;
	SudokuBoard* _tmp44_;
	gint _tmp45_;
	gint _tmp46_;
	SudokuCell** _tmp47_;
	GtkEventControllerFocus* _tmp85_;
	GtkEventControllerFocus* _tmp86_;
	GtkEventControllerFocus* _tmp87_;
	GtkEventController* _tmp88_;
	GSimpleActionGroup* _tmp89_;
	GSimpleAction* _tmp90_ = NULL;
	GSimpleAction* _tmp91_ = NULL;
	GSimpleAction* _tmp92_ = NULL;
	GSimpleAction* _tmp93_ = NULL;
	GSimpleAction* _tmp94_;
	GSimpleAction* _tmp95_;
	GSimpleAction* _tmp96_;
	SudokuNumberPicker* _tmp97_;
	GSimpleActionGroup* _tmp98_;
	GSimpleAction* _tmp99_;
	GSimpleActionGroup* _tmp100_;
	g_return_val_if_fail (game != NULL, NULL);
	self = (SudokuGrid*) g_object_new (object_type, NULL);
	_tmp0_ = _g_object_ref0 (game);
	_g_object_unref0 (self->priv->game);
	self->priv->game = _tmp0_;
	gtk_grid_set_row_spacing ((GtkGrid*) self, 2);
	gtk_grid_set_column_spacing ((GtkGrid*) self, 2);
	gtk_grid_set_column_homogeneous ((GtkGrid*) self, TRUE);
	gtk_grid_set_row_homogeneous ((GtkGrid*) self, TRUE);
	gtk_widget_set_direction ((GtkWidget*) self, GTK_TEXT_DIR_LTR);
	gtk_widget_add_css_class ((GtkWidget*) self, "board");
	_tmp1_ = (GtkGestureClick*) gtk_gesture_click_new ();
	_g_object_unref0 (self->priv->button_controller);
	self->priv->button_controller = _tmp1_;
	_tmp2_ = self->priv->button_controller;
	gtk_gesture_single_set_button ((GtkGestureSingle*) _tmp2_, (guint) 0);
	_tmp3_ = self->priv->button_controller;
	g_signal_connect_object (_tmp3_, "released", (GCallback) _sudoku_grid_button_released_cb_gtk_gesture_click_released, self, 0);
	_tmp4_ = self->priv->button_controller;
	_tmp5_ = _g_object_ref0 ((GtkEventController*) _tmp4_);
	gtk_widget_add_controller ((GtkWidget*) self, _tmp5_);
	_tmp6_ = sudoku_number_picker_new (game);
	g_object_ref_sink (_tmp6_);
	_g_object_unref0 (self->number_picker);
	self->number_picker = _tmp6_;
	sudoku_grid_update_zoom (self);
	_tmp7_ = sudoku_game_get_board (game);
	_tmp8_ = _tmp7_;
	_tmp9_ = sudoku_board_get_block_rows (_tmp8_);
	_tmp10_ = _tmp9_;
	_tmp11_ = sudoku_game_get_board (game);
	_tmp12_ = _tmp11_;
	_tmp13_ = sudoku_board_get_block_cols (_tmp12_);
	_tmp14_ = _tmp13_;
	_tmp15_ = g_new0 (GtkGrid*, (_tmp10_ * _tmp14_) + 1);
	blocks = _tmp15_;
	blocks_length1 = _tmp10_;
	blocks_length2 = _tmp14_;
	{
		gint block_row = 0;
		block_row = 0;
		{
			gboolean _tmp16_ = FALSE;
			_tmp16_ = TRUE;
			while (TRUE) {
				SudokuBoard* _tmp18_;
				SudokuBoard* _tmp19_;
				gint _tmp20_;
				gint _tmp21_;
				if (!_tmp16_) {
					gint _tmp17_;
					_tmp17_ = block_row;
					block_row = _tmp17_ + 1;
				}
				_tmp16_ = FALSE;
				_tmp18_ = sudoku_game_get_board (game);
				_tmp19_ = _tmp18_;
				_tmp20_ = sudoku_board_get_block_rows (_tmp19_);
				_tmp21_ = _tmp20_;
				if (!(block_row < _tmp21_)) {
					break;
				}
				{
					gint block_col = 0;
					block_col = 0;
					{
						gboolean _tmp22_ = FALSE;
						_tmp22_ = TRUE;
						while (TRUE) {
							SudokuBoard* _tmp24_;
							SudokuBoard* _tmp25_;
							gint _tmp26_;
							gint _tmp27_;
							GtkGrid* block_grid = NULL;
							GtkGrid* _tmp28_;
							GtkGrid* _tmp29_;
							GtkGrid* _tmp30_;
							GtkGrid* _tmp31_;
							GtkGrid* _tmp32_;
							GtkGrid* _tmp33_;
							GtkGrid* _tmp34_;
							GtkGrid* _tmp35_;
							GtkGrid** _tmp36_;
							gint _tmp36__length1;
							gint _tmp36__length2;
							GtkGrid* _tmp37_;
							GtkGrid* _tmp38_;
							if (!_tmp22_) {
								gint _tmp23_;
								_tmp23_ = block_col;
								block_col = _tmp23_ + 1;
							}
							_tmp22_ = FALSE;
							_tmp24_ = sudoku_game_get_board (game);
							_tmp25_ = _tmp24_;
							_tmp26_ = sudoku_board_get_block_cols (_tmp25_);
							_tmp27_ = _tmp26_;
							if (!(block_col < _tmp27_)) {
								break;
							}
							_tmp28_ = (GtkGrid*) gtk_grid_new ();
							g_object_ref_sink (_tmp28_);
							block_grid = _tmp28_;
							_tmp29_ = block_grid;
							gtk_widget_set_direction ((GtkWidget*) _tmp29_, GTK_TEXT_DIR_LTR);
							_tmp30_ = block_grid;
							gtk_grid_set_row_spacing (_tmp30_, 1);
							_tmp31_ = block_grid;
							gtk_grid_set_column_spacing (_tmp31_, 1);
							_tmp32_ = block_grid;
							gtk_grid_set_column_homogeneous (_tmp32_, TRUE);
							_tmp33_ = block_grid;
							gtk_grid_set_row_homogeneous (_tmp33_, TRUE);
							_tmp34_ = block_grid;
							gtk_widget_add_css_class ((GtkWidget*) _tmp34_, "block");
							_tmp35_ = block_grid;
							gtk_grid_attach ((GtkGrid*) self, (GtkWidget*) _tmp35_, block_col, block_row, 1, 1);
							_tmp36_ = blocks;
							_tmp36__length1 = blocks_length1;
							_tmp36__length2 = blocks_length2;
							_tmp37_ = block_grid;
							_tmp38_ = _g_object_ref0 (_tmp37_);
							_g_object_unref0 (_tmp36_[(block_row * _tmp36__length2) + block_col]);
							_tmp36_[(block_row * _tmp36__length2) + block_col] = _tmp38_;
							_g_object_unref0 (block_grid);
						}
					}
				}
			}
		}
	}
	_tmp39_ = sudoku_game_get_board (game);
	_tmp40_ = _tmp39_;
	_tmp41_ = sudoku_board_get_rows (_tmp40_);
	_tmp42_ = _tmp41_;
	_tmp43_ = sudoku_game_get_board (game);
	_tmp44_ = _tmp43_;
	_tmp45_ = sudoku_board_get_cols (_tmp44_);
	_tmp46_ = _tmp45_;
	_tmp47_ = g_new0 (SudokuCell*, (_tmp42_ * _tmp46_) + 1);
	self->priv->cells = (_vala_array_free (self->priv->cells, self->priv->cells_length1 * self->priv->cells_length2, (GDestroyNotify) g_object_unref), NULL);
	self->priv->cells = _tmp47_;
	self->priv->cells_length1 = _tmp42_;
	self->priv->cells_length2 = _tmp46_;
	{
		gint row = 0;
		row = 0;
		{
			gboolean _tmp48_ = FALSE;
			_tmp48_ = TRUE;
			while (TRUE) {
				SudokuBoard* _tmp50_;
				SudokuBoard* _tmp51_;
				gint _tmp52_;
				gint _tmp53_;
				if (!_tmp48_) {
					gint _tmp49_;
					_tmp49_ = row;
					row = _tmp49_ + 1;
				}
				_tmp48_ = FALSE;
				_tmp50_ = sudoku_game_get_board (game);
				_tmp51_ = _tmp50_;
				_tmp52_ = sudoku_board_get_rows (_tmp51_);
				_tmp53_ = _tmp52_;
				if (!(row < _tmp53_)) {
					break;
				}
				{
					gint col = 0;
					col = 0;
					{
						gboolean _tmp54_ = FALSE;
						_tmp54_ = TRUE;
						while (TRUE) {
							SudokuBoard* _tmp56_;
							SudokuBoard* _tmp57_;
							gint _tmp58_;
							gint _tmp59_;
							SudokuCell* cell = NULL;
							SudokuCell* _tmp60_;
							GtkGrid** _tmp61_;
							gint _tmp61__length1;
							gint _tmp61__length2;
							SudokuBoard* _tmp62_;
							SudokuBoard* _tmp63_;
							gint _tmp64_;
							gint _tmp65_;
							SudokuBoard* _tmp66_;
							SudokuBoard* _tmp67_;
							gint _tmp68_;
							gint _tmp69_;
							GtkGrid* _tmp70_;
							SudokuCell* _tmp71_;
							SudokuBoard* _tmp72_;
							SudokuBoard* _tmp73_;
							gint _tmp74_;
							gint _tmp75_;
							SudokuBoard* _tmp76_;
							SudokuBoard* _tmp77_;
							gint _tmp78_;
							gint _tmp79_;
							SudokuCell** _tmp80_;
							gint _tmp80__length1;
							gint _tmp80__length2;
							SudokuCell* _tmp81_;
							SudokuCell* _tmp82_;
							SudokuCell** _tmp83_;
							gint _tmp83__length1;
							gint _tmp83__length2;
							SudokuCell* _tmp84_;
							if (!_tmp54_) {
								gint _tmp55_;
								_tmp55_ = col;
								col = _tmp55_ + 1;
							}
							_tmp54_ = FALSE;
							_tmp56_ = sudoku_game_get_board (game);
							_tmp57_ = _tmp56_;
							_tmp58_ = sudoku_board_get_cols (_tmp57_);
							_tmp59_ = _tmp58_;
							if (!(col < _tmp59_)) {
								break;
							}
							_tmp60_ = sudoku_cell_new (game, self, &self->priv->zoom_value_multiplier, &self->priv->zoom_earmark_multiplier, row, col);
							g_object_ref_sink (_tmp60_);
							cell = _tmp60_;
							_tmp61_ = blocks;
							_tmp61__length1 = blocks_length1;
							_tmp61__length2 = blocks_length2;
							_tmp62_ = sudoku_game_get_board (game);
							_tmp63_ = _tmp62_;
							_tmp64_ = sudoku_board_get_block_rows (_tmp63_);
							_tmp65_ = _tmp64_;
							_tmp66_ = sudoku_game_get_board (game);
							_tmp67_ = _tmp66_;
							_tmp68_ = sudoku_board_get_block_cols (_tmp67_);
							_tmp69_ = _tmp68_;
							_tmp70_ = _tmp61_[((row / _tmp65_) * _tmp61__length2) + (col / _tmp69_)];
							_tmp71_ = cell;
							_tmp72_ = sudoku_game_get_board (game);
							_tmp73_ = _tmp72_;
							_tmp74_ = sudoku_board_get_block_cols (_tmp73_);
							_tmp75_ = _tmp74_;
							_tmp76_ = sudoku_game_get_board (game);
							_tmp77_ = _tmp76_;
							_tmp78_ = sudoku_board_get_block_rows (_tmp77_);
							_tmp79_ = _tmp78_;
							gtk_grid_attach (_tmp70_, (GtkWidget*) _tmp71_, col % _tmp75_, row % _tmp79_, 1, 1);
							_tmp80_ = self->priv->cells;
							_tmp80__length1 = self->priv->cells_length1;
							_tmp80__length2 = self->priv->cells_length2;
							_tmp81_ = cell;
							_tmp82_ = _g_object_ref0 (_tmp81_);
							_g_object_unref0 (_tmp80_[(row * _tmp80__length2) + col]);
							_tmp80_[(row * _tmp80__length2) + col] = _tmp82_;
							_tmp83_ = self->priv->cells;
							_tmp83__length1 = self->priv->cells_length1;
							_tmp83__length2 = self->priv->cells_length2;
							_tmp84_ = _tmp83_[(row * _tmp83__length2) + col];
							g_signal_connect_object (_tmp84_, "select", (GCallback) _sudoku_grid_update_selected_sudoku_cell_select, self, 0);
							_g_object_unref0 (cell);
						}
					}
				}
			}
		}
	}
	_tmp85_ = (GtkEventControllerFocus*) gtk_event_controller_focus_new ();
	_g_object_unref0 (self->priv->focus_controller);
	self->priv->focus_controller = _tmp85_;
	_tmp86_ = self->priv->focus_controller;
	g_signal_connect_object (_tmp86_, "leave", (GCallback) ___lambda18__gtk_event_controller_focus_leave, self, 0);
	_tmp87_ = self->priv->focus_controller;
	_tmp88_ = _g_object_ref0 ((GtkEventController*) _tmp87_);
	gtk_widget_add_controller ((GtkWidget*) self, _tmp88_);
	sudoku_grid_add_game_hooks (self);
	sudoku_grid_update_warnings (self);
	_tmp89_ = g_simple_action_group_new ();
	_g_object_unref0 (self->priv->action_group);
	self->priv->action_group = _tmp89_;
	sudoku_grid_new_move_action (self, "move-up", &_tmp90_);
	_g_object_unref0 (self->priv->move_up_action);
	self->priv->move_up_action = _tmp90_;
	sudoku_grid_new_move_action (self, "move-down", &_tmp91_);
	_g_object_unref0 (self->priv->move_down_action);
	self->priv->move_down_action = _tmp91_;
	sudoku_grid_new_move_action (self, "move-right", &_tmp92_);
	_g_object_unref0 (self->priv->move_right_action);
	self->priv->move_right_action = _tmp92_;
	sudoku_grid_new_move_action (self, "move-left", &_tmp93_);
	_g_object_unref0 (self->priv->move_left_action);
	self->priv->move_left_action = _tmp93_;
	_tmp94_ = g_simple_action_new ("escape", NULL);
	_g_object_unref0 (self->priv->escape_action);
	self->priv->escape_action = _tmp94_;
	_tmp95_ = self->priv->escape_action;
	g_simple_action_set_enabled (_tmp95_, TRUE);
	_tmp96_ = self->priv->escape_action;
	_tmp97_ = self->number_picker;
	g_signal_connect_object (_tmp96_, "activate", (GCallback) _gtk_popover_popdown_g_simple_action_activate, (GtkPopover*) _tmp97_, 0);
	_tmp98_ = self->priv->action_group;
	_tmp99_ = self->priv->escape_action;
	g_action_map_add_action ((GActionMap*) _tmp98_, (GAction*) _tmp99_);
	_tmp100_ = self->priv->action_group;
	gtk_widget_insert_action_group ((GtkWidget*) self, "grid", (GActionGroup*) _tmp100_);
	blocks = (_vala_array_free (blocks, blocks_length1 * blocks_length2, (GDestroyNotify) g_object_unref), NULL);
	return self;
}

SudokuGrid*
sudoku_grid_new (SudokuGame* game)
{
	return sudoku_grid_construct (TYPE_SUDOKU_GRID, game);
}

static void
_sudoku_grid_move_g_simple_action_activate (GSimpleAction* _sender,
                                            GVariant* parameter,
                                            gpointer self)
{
	sudoku_grid_move ((SudokuGrid*) self, parameter);
}

static void
sudoku_grid_new_move_action (SudokuGrid* self,
                             const gchar* name,
                             GSimpleAction** action)
{
	GSimpleAction* _vala_action = NULL;
	const GVariantType* _tmp0_;
	GSimpleAction* _tmp1_;
	GSimpleActionGroup* _tmp2_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (name != NULL);
	_tmp0_ = G_VARIANT_TYPE_INT32;
	_tmp1_ = g_simple_action_new (name, _tmp0_);
	_g_object_unref0 (_vala_action);
	_vala_action = _tmp1_;
	g_signal_connect_object (_vala_action, "activate", (GCallback) _sudoku_grid_move_g_simple_action_activate, self, 0);
	_tmp2_ = self->priv->action_group;
	g_action_map_add_action ((GActionMap*) _tmp2_, (GAction*) _vala_action);
	if (action) {
		*action = _vala_action;
	} else {
		_g_object_unref0 (_vala_action);
	}
}

void
sudoku_grid_change_game (SudokuGrid* self,
                         SudokuGame* new_game)
{
	SudokuNumberPicker* _tmp0_;
	SudokuGame* _tmp1_;
	SudokuCell** _tmp2_;
	gint _tmp2__length1;
	gint _tmp2__length2;
	g_return_if_fail (self != NULL);
	g_return_if_fail (new_game != NULL);
	_tmp0_ = self->number_picker;
	sudoku_number_picker_change_game (_tmp0_, new_game);
	_tmp1_ = _g_object_ref0 (new_game);
	_g_object_unref0 (self->priv->game);
	self->priv->game = _tmp1_;
	sudoku_grid_set_selected_row (self, SUDOKU_GRID_START.row);
	sudoku_grid_set_selected_col (self, SUDOKU_GRID_START.col);
	_tmp2_ = self->priv->cells;
	_tmp2__length1 = self->priv->cells_length1;
	_tmp2__length2 = self->priv->cells_length2;
	{
		SudokuCell** cell_collection = NULL;
		gint cell_collection_length1 = 0;
		gint cell_collection_length2 = 0;
		gint cell_it = 0;
		cell_collection = _tmp2_;
		cell_collection_length1 = _tmp2__length1 * _tmp2__length2;
		for (cell_it = 0; cell_it < cell_collection_length1; cell_it = cell_it + 1) {
			SudokuCell* _tmp3_;
			SudokuCell* cell = NULL;
			_tmp3_ = _g_object_ref0 (cell_collection[cell_it]);
			cell = _tmp3_;
			{
				SudokuCell* _tmp4_;
				SudokuCell* _tmp5_;
				SudokuCell* _tmp6_;
				_tmp4_ = cell;
				sudoku_cell_change_game (_tmp4_, new_game);
				_tmp5_ = cell;
				sudoku_cell_update_content_visibility (_tmp5_);
				_tmp6_ = cell;
				sudoku_cell_update_fixed (_tmp6_);
				_g_object_unref0 (cell);
			}
		}
	}
	sudoku_grid_update_warnings (self);
	sudoku_grid_add_game_hooks (self);
}

static void
_sudoku_grid_paused_cb_g_object_notify (GObject* _sender,
                                        GParamSpec* pspec,
                                        gpointer self)
{
	sudoku_grid_paused_cb ((SudokuGrid*) self);
}

static void
_sudoku_grid_value_changed_cb_sudoku_board_value_changed (SudokuBoard* _sender,
                                                          gint row,
                                                          gint col,
                                                          gint old_val,
                                                          gint new_val,
                                                          gpointer self)
{
	sudoku_grid_value_changed_cb ((SudokuGrid*) self, row, col, old_val, new_val);
}

static void
_sudoku_grid_earmark_changed_cb_sudoku_board_earmark_changed (SudokuBoard* _sender,
                                                              gint row,
                                                              gint col,
                                                              gint num,
                                                              gboolean enabled,
                                                              gpointer self)
{
	sudoku_grid_earmark_changed_cb ((SudokuGrid*) self, row, col, num, enabled);
}

static void
sudoku_grid_add_game_hooks (SudokuGrid* self)
{
	SudokuGame* _tmp0_;
	SudokuGame* _tmp1_;
	SudokuBoard* _tmp2_;
	SudokuBoard* _tmp3_;
	SudokuGame* _tmp4_;
	SudokuBoard* _tmp5_;
	SudokuBoard* _tmp6_;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->priv->game;
	g_signal_connect_object ((GObject*) _tmp0_, "notify::paused", (GCallback) _sudoku_grid_paused_cb_g_object_notify, self, 0);
	_tmp1_ = self->priv->game;
	_tmp2_ = sudoku_game_get_board (_tmp1_);
	_tmp3_ = _tmp2_;
	g_signal_connect_object (_tmp3_, "value-changed", (GCallback) _sudoku_grid_value_changed_cb_sudoku_board_value_changed, self, 0);
	_tmp4_ = self->priv->game;
	_tmp5_ = sudoku_game_get_board (_tmp4_);
	_tmp6_ = _tmp5_;
	g_signal_connect_object (_tmp6_, "earmark-changed", (GCallback) _sudoku_grid_earmark_changed_cb_sudoku_board_earmark_changed, self, 0);
}

static void
sudoku_grid_update_highlighter (SudokuGrid* self,
                                gint old_row,
                                gint old_col)
{
	gint _tmp0_;
	gint _tmp1_;
	g_return_if_fail (self != NULL);
	sudoku_grid_set_cell_highlighter (self, old_row, old_col, FALSE);
	_tmp0_ = self->priv->_selected_row;
	_tmp1_ = self->priv->_selected_col;
	sudoku_grid_set_cell_highlighter (self, _tmp0_, _tmp1_, TRUE);
}

static void
sudoku_grid_update_value_highlighter (SudokuGrid* self,
                                      gint row,
                                      gint col,
                                      gint old_val,
                                      gint new_val)
{
	Sudoku* _tmp0_;
	gboolean _tmp1_;
	gboolean _tmp2_;
	gboolean _tmp3_ = FALSE;
	gint _tmp4_;
	g_return_if_fail (self != NULL);
	_tmp0_ = sudoku_app;
	_tmp1_ = sudoku_get_highlight_numbers (_tmp0_);
	_tmp2_ = _tmp1_;
	if (!_tmp2_) {
		return;
	}
	_tmp4_ = self->priv->_selected_row;
	if (row != _tmp4_) {
		_tmp3_ = TRUE;
	} else {
		gint _tmp5_;
		_tmp5_ = self->priv->_selected_col;
		_tmp3_ = col != _tmp5_;
	}
	if (_tmp3_) {
		SudokuCell* _tmp6_;
		SudokuCell* _tmp7_;
		gint _tmp8_;
		gint _tmp9_;
		_tmp6_ = sudoku_grid_get_selected_cell (self);
		_tmp7_ = _tmp6_;
		_tmp8_ = sudoku_cell_get_value (_tmp7_);
		_tmp9_ = _tmp8_;
		if (old_val == _tmp9_) {
			SudokuCell** _tmp10_;
			gint _tmp10__length1;
			gint _tmp10__length2;
			SudokuCell* _tmp11_;
			_tmp10_ = self->priv->cells;
			_tmp10__length1 = self->priv->cells_length1;
			_tmp10__length2 = self->priv->cells_length2;
			_tmp11_ = _tmp10_[(row * _tmp10__length2) + col];
			sudoku_cell_set_highlight_number (_tmp11_, FALSE);
		} else {
			gboolean _tmp12_ = FALSE;
			SudokuCell* _tmp13_;
			SudokuCell* _tmp14_;
			gint _tmp15_;
			gint _tmp16_;
			_tmp13_ = sudoku_grid_get_selected_cell (self);
			_tmp14_ = _tmp13_;
			_tmp15_ = sudoku_cell_get_value (_tmp14_);
			_tmp16_ = _tmp15_;
			if (new_val == _tmp16_) {
				_tmp12_ = new_val != 0;
			} else {
				_tmp12_ = FALSE;
			}
			if (_tmp12_) {
				SudokuCell** _tmp17_;
				gint _tmp17__length1;
				gint _tmp17__length2;
				SudokuCell* _tmp18_;
				_tmp17_ = self->priv->cells;
				_tmp17__length1 = self->priv->cells_length1;
				_tmp17__length2 = self->priv->cells_length2;
				_tmp18_ = _tmp17_[(row * _tmp17__length2) + col];
				sudoku_cell_set_highlight_number (_tmp18_, TRUE);
			}
		}
		return;
	}
	{
		gint col_tmp = 0;
		col_tmp = 0;
		{
			gboolean _tmp19_ = FALSE;
			_tmp19_ = TRUE;
			while (TRUE) {
				SudokuGame* _tmp21_;
				SudokuBoard* _tmp22_;
				SudokuBoard* _tmp23_;
				gint _tmp24_;
				gint _tmp25_;
				if (!_tmp19_) {
					gint _tmp20_;
					_tmp20_ = col_tmp;
					col_tmp = _tmp20_ + 1;
				}
				_tmp19_ = FALSE;
				_tmp21_ = self->priv->game;
				_tmp22_ = sudoku_game_get_board (_tmp21_);
				_tmp23_ = _tmp22_;
				_tmp24_ = sudoku_board_get_cols (_tmp23_);
				_tmp25_ = _tmp24_;
				if (!(col_tmp < _tmp25_)) {
					break;
				}
				{
					gint row_tmp = 0;
					row_tmp = 0;
					{
						gboolean _tmp26_ = FALSE;
						_tmp26_ = TRUE;
						while (TRUE) {
							SudokuGame* _tmp28_;
							SudokuBoard* _tmp29_;
							SudokuBoard* _tmp30_;
							gint _tmp31_;
							gint _tmp32_;
							SudokuCell* cell_tmp = NULL;
							SudokuCell** _tmp33_;
							gint _tmp33__length1;
							gint _tmp33__length2;
							SudokuCell* _tmp34_;
							SudokuCell* _tmp35_;
							SudokuCell* _tmp36_;
							SudokuCell* _tmp37_;
							SudokuCell* _tmp38_;
							SudokuCell* _tmp39_;
							gint _tmp40_;
							gint _tmp41_;
							if (!_tmp26_) {
								gint _tmp27_;
								_tmp27_ = row_tmp;
								row_tmp = _tmp27_ + 1;
							}
							_tmp26_ = FALSE;
							_tmp28_ = self->priv->game;
							_tmp29_ = sudoku_game_get_board (_tmp28_);
							_tmp30_ = _tmp29_;
							_tmp31_ = sudoku_board_get_rows (_tmp30_);
							_tmp32_ = _tmp31_;
							if (!(row_tmp < _tmp32_)) {
								break;
							}
							_tmp33_ = self->priv->cells;
							_tmp33__length1 = self->priv->cells_length1;
							_tmp33__length2 = self->priv->cells_length2;
							_tmp34_ = _tmp33_[(row_tmp * _tmp33__length2) + col_tmp];
							_tmp35_ = _g_object_ref0 (_tmp34_);
							cell_tmp = _tmp35_;
							_tmp36_ = sudoku_grid_get_selected_cell (self);
							_tmp37_ = _tmp36_;
							_tmp38_ = cell_tmp;
							if (_tmp37_ == _tmp38_) {
								_g_object_unref0 (cell_tmp);
								continue;
							}
							_tmp39_ = cell_tmp;
							_tmp40_ = sudoku_cell_get_value (_tmp39_);
							_tmp41_ = _tmp40_;
							if (_tmp41_ == 0) {
								if (old_val > 0) {
									SudokuCell* _tmp42_;
									_tmp42_ = cell_tmp;
									sudoku_cell_set_earmark_highlight (_tmp42_, old_val, FALSE);
								}
								if (new_val > 0) {
									SudokuCell* _tmp43_;
									_tmp43_ = cell_tmp;
									sudoku_cell_set_earmark_highlight (_tmp43_, new_val, TRUE);
								}
							} else {
								SudokuCell* _tmp44_;
								gint _tmp45_;
								gint _tmp46_;
								_tmp44_ = cell_tmp;
								_tmp45_ = sudoku_cell_get_value (_tmp44_);
								_tmp46_ = _tmp45_;
								if (new_val == _tmp46_) {
									SudokuCell* _tmp47_;
									_tmp47_ = cell_tmp;
									sudoku_cell_set_highlight_number (_tmp47_, TRUE);
								} else {
									SudokuCell* _tmp48_;
									gint _tmp49_;
									gint _tmp50_;
									_tmp48_ = cell_tmp;
									_tmp49_ = sudoku_cell_get_value (_tmp48_);
									_tmp50_ = _tmp49_;
									if (old_val == _tmp50_) {
										SudokuCell* _tmp51_;
										_tmp51_ = cell_tmp;
										sudoku_cell_set_highlight_number (_tmp51_, FALSE);
									}
								}
							}
							_g_object_unref0 (cell_tmp);
						}
					}
				}
			}
		}
	}
}

static void
sudoku_grid_set_cell_highlighter (SudokuGrid* self,
                                  gint row,
                                  gint col,
                                  gboolean enabled)
{
	SudokuCell* target_cell = NULL;
	SudokuCell** _tmp0_;
	gint _tmp0__length1;
	gint _tmp0__length2;
	SudokuCell* _tmp1_;
	SudokuCell* _tmp2_;
	SudokuCell** _tmp3_;
	gint _tmp3__length1;
	gint _tmp3__length2;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->priv->cells;
	_tmp0__length1 = self->priv->cells_length1;
	_tmp0__length2 = self->priv->cells_length2;
	_tmp1_ = _tmp0_[(row * _tmp0__length2) + col];
	_tmp2_ = _g_object_ref0 (_tmp1_);
	target_cell = _tmp2_;
	_tmp3_ = self->priv->cells;
	_tmp3__length1 = self->priv->cells_length1;
	_tmp3__length2 = self->priv->cells_length2;
	{
		SudokuCell** cell_collection = NULL;
		gint cell_collection_length1 = 0;
		gint cell_collection_length2 = 0;
		gint cell_it = 0;
		cell_collection = _tmp3_;
		cell_collection_length1 = _tmp3__length1 * _tmp3__length2;
		for (cell_it = 0; cell_it < cell_collection_length1; cell_it = cell_it + 1) {
			SudokuCell* _tmp4_;
			SudokuCell* cell = NULL;
			_tmp4_ = _g_object_ref0 (cell_collection[cell_it]);
			cell = _tmp4_;
			{
				SudokuCell* _tmp5_;
				SudokuCell* _tmp6_;
				gboolean _tmp7_ = FALSE;
				SudokuCell* _tmp8_;
				gint _tmp9_;
				gint _tmp10_;
				gboolean _tmp28_ = FALSE;
				SudokuCell* _tmp29_;
				gboolean _tmp30_;
				gboolean _tmp31_;
				_tmp5_ = cell;
				_tmp6_ = target_cell;
				if (_tmp5_ == _tmp6_) {
					_g_object_unref0 (cell);
					continue;
				}
				_tmp8_ = target_cell;
				_tmp9_ = sudoku_cell_get_value (_tmp8_);
				_tmp10_ = _tmp9_;
				if (_tmp10_ > 0) {
					Sudoku* _tmp11_;
					gboolean _tmp12_;
					gboolean _tmp13_;
					_tmp11_ = sudoku_app;
					_tmp12_ = sudoku_get_highlight_numbers (_tmp11_);
					_tmp13_ = _tmp12_;
					_tmp7_ = _tmp13_;
				} else {
					_tmp7_ = FALSE;
				}
				if (_tmp7_) {
					SudokuCell* _tmp14_;
					gint _tmp15_;
					gint _tmp16_;
					SudokuCell* _tmp17_;
					gint _tmp18_;
					gint _tmp19_;
					_tmp14_ = target_cell;
					_tmp15_ = sudoku_cell_get_value (_tmp14_);
					_tmp16_ = _tmp15_;
					_tmp17_ = cell;
					_tmp18_ = sudoku_cell_get_value (_tmp17_);
					_tmp19_ = _tmp18_;
					if (_tmp16_ == _tmp19_) {
						SudokuCell* _tmp20_;
						_tmp20_ = cell;
						sudoku_cell_set_highlight_number (_tmp20_, enabled);
					} else {
						SudokuCell* _tmp21_;
						gint _tmp22_;
						gint _tmp23_;
						_tmp21_ = cell;
						_tmp22_ = sudoku_cell_get_value (_tmp21_);
						_tmp23_ = _tmp22_;
						if (_tmp23_ == 0) {
							SudokuCell* _tmp24_;
							SudokuCell* _tmp25_;
							gint _tmp26_;
							gint _tmp27_;
							_tmp24_ = cell;
							_tmp25_ = target_cell;
							_tmp26_ = sudoku_cell_get_value (_tmp25_);
							_tmp27_ = _tmp26_;
							sudoku_cell_set_earmark_highlight (_tmp24_, _tmp27_, enabled);
						}
					}
				}
				_tmp29_ = cell;
				_tmp30_ = sudoku_cell_get_is_fixed (_tmp29_);
				_tmp31_ = _tmp30_;
				if (!_tmp31_) {
					gboolean _tmp32_ = FALSE;
					gboolean _tmp33_ = FALSE;
					Sudoku* _tmp34_;
					gboolean _tmp35_;
					gboolean _tmp36_;
					_tmp34_ = sudoku_app;
					_tmp35_ = sudoku_get_highlight_row_column (_tmp34_);
					_tmp36_ = _tmp35_;
					if (_tmp36_) {
						gboolean _tmp37_ = FALSE;
						SudokuCell* _tmp38_;
						gint _tmp39_;
						gint _tmp40_;
						_tmp38_ = cell;
						_tmp39_ = sudoku_cell_get_row (_tmp38_);
						_tmp40_ = _tmp39_;
						if (_tmp40_ == row) {
							_tmp37_ = TRUE;
						} else {
							SudokuCell* _tmp41_;
							gint _tmp42_;
							gint _tmp43_;
							_tmp41_ = cell;
							_tmp42_ = sudoku_cell_get_col (_tmp41_);
							_tmp43_ = _tmp42_;
							_tmp37_ = _tmp43_ == col;
						}
						_tmp33_ = _tmp37_;
					} else {
						_tmp33_ = FALSE;
					}
					if (_tmp33_) {
						_tmp32_ = TRUE;
					} else {
						gboolean _tmp44_ = FALSE;
						gboolean _tmp45_ = FALSE;
						Sudoku* _tmp46_;
						gboolean _tmp47_;
						gboolean _tmp48_;
						_tmp46_ = sudoku_app;
						_tmp47_ = sudoku_get_highlight_block (_tmp46_);
						_tmp48_ = _tmp47_;
						if (_tmp48_) {
							SudokuCell* _tmp49_;
							gint _tmp50_;
							gint _tmp51_;
							SudokuGame* _tmp52_;
							SudokuBoard* _tmp53_;
							SudokuBoard* _tmp54_;
							gint _tmp55_;
							gint _tmp56_;
							SudokuGame* _tmp57_;
							SudokuBoard* _tmp58_;
							SudokuBoard* _tmp59_;
							gint _tmp60_;
							gint _tmp61_;
							_tmp49_ = cell;
							_tmp50_ = sudoku_cell_get_row (_tmp49_);
							_tmp51_ = _tmp50_;
							_tmp52_ = self->priv->game;
							_tmp53_ = sudoku_game_get_board (_tmp52_);
							_tmp54_ = _tmp53_;
							_tmp55_ = sudoku_board_get_block_cols (_tmp54_);
							_tmp56_ = _tmp55_;
							_tmp57_ = self->priv->game;
							_tmp58_ = sudoku_game_get_board (_tmp57_);
							_tmp59_ = _tmp58_;
							_tmp60_ = sudoku_board_get_block_cols (_tmp59_);
							_tmp61_ = _tmp60_;
							_tmp45_ = (_tmp51_ / _tmp56_) == (row / _tmp61_);
						} else {
							_tmp45_ = FALSE;
						}
						if (_tmp45_) {
							SudokuCell* _tmp62_;
							gint _tmp63_;
							gint _tmp64_;
							SudokuGame* _tmp65_;
							SudokuBoard* _tmp66_;
							SudokuBoard* _tmp67_;
							gint _tmp68_;
							gint _tmp69_;
							SudokuGame* _tmp70_;
							SudokuBoard* _tmp71_;
							SudokuBoard* _tmp72_;
							gint _tmp73_;
							gint _tmp74_;
							_tmp62_ = cell;
							_tmp63_ = sudoku_cell_get_col (_tmp62_);
							_tmp64_ = _tmp63_;
							_tmp65_ = self->priv->game;
							_tmp66_ = sudoku_game_get_board (_tmp65_);
							_tmp67_ = _tmp66_;
							_tmp68_ = sudoku_board_get_block_rows (_tmp67_);
							_tmp69_ = _tmp68_;
							_tmp70_ = self->priv->game;
							_tmp71_ = sudoku_game_get_board (_tmp70_);
							_tmp72_ = _tmp71_;
							_tmp73_ = sudoku_board_get_block_rows (_tmp72_);
							_tmp74_ = _tmp73_;
							_tmp44_ = (_tmp64_ / _tmp69_) == (col / _tmp74_);
						} else {
							_tmp44_ = FALSE;
						}
						_tmp32_ = _tmp44_;
					}
					_tmp28_ = _tmp32_;
				} else {
					_tmp28_ = FALSE;
				}
				if (_tmp28_) {
					SudokuCell* _tmp75_;
					_tmp75_ = cell;
					sudoku_cell_set_highlight_coord (_tmp75_, enabled);
				}
				_g_object_unref0 (cell);
			}
		}
	}
	_g_object_unref0 (target_cell);
}

void
sudoku_grid_update_zoom (SudokuGrid* self)
{
	Sudoku* _tmp0_;
	ZoomLevel _tmp1_;
	ZoomLevel _tmp2_;
	SudokuCell** _tmp3_;
	gint _tmp3__length1;
	gint _tmp3__length2;
	g_return_if_fail (self != NULL);
	_tmp0_ = sudoku_app;
	_tmp1_ = sudoku_get_zoom_level (_tmp0_);
	_tmp2_ = _tmp1_;
	switch (_tmp2_) {
		case ZOOM_LEVEL_SMALL:
		{
			self->priv->zoom_value_multiplier = 0.4;
			self->priv->zoom_earmark_multiplier = 0.25;
			break;
		}
		case ZOOM_LEVEL_MEDIUM:
		{
			self->priv->zoom_value_multiplier = 0.5;
			self->priv->zoom_earmark_multiplier = 0.25;
			break;
		}
		case ZOOM_LEVEL_LARGE:
		{
			self->priv->zoom_value_multiplier = 0.6;
			self->priv->zoom_earmark_multiplier = 0.3;
			break;
		}
		default:
		{
			g_assert_not_reached ();
		}
	}
	_tmp3_ = self->priv->cells;
	_tmp3__length1 = self->priv->cells_length1;
	_tmp3__length2 = self->priv->cells_length2;
	{
		SudokuCell** cell_collection = NULL;
		gint cell_collection_length1 = 0;
		gint cell_collection_length2 = 0;
		gint cell_it = 0;
		cell_collection = _tmp3_;
		cell_collection_length1 = _tmp3__length1 * _tmp3__length2;
		for (cell_it = 0; cell_it < cell_collection_length1; cell_it = cell_it + 1) {
			SudokuCell* _tmp4_;
			SudokuCell* cell = NULL;
			_tmp4_ = _g_object_ref0 (cell_collection[cell_it]);
			cell = _tmp4_;
			{
				SudokuCell* _tmp5_;
				_tmp5_ = cell;
				gtk_widget_queue_allocate ((GtkWidget*) _tmp5_);
				_g_object_unref0 (cell);
			}
		}
	}
}

void
sudoku_grid_toggle_highlighter (SudokuGrid* self)
{
	GtkEventControllerFocus* _tmp0_;
	gboolean _tmp1_;
	gboolean _tmp2_;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->priv->focus_controller;
	g_object_get (_tmp0_, "contains-focus", &_tmp1_, NULL);
	_tmp2_ = _tmp1_;
	if (_tmp2_) {
		gint _tmp3_;
		gint _tmp4_;
		_tmp3_ = self->priv->_selected_row;
		_tmp4_ = self->priv->_selected_col;
		sudoku_grid_set_cell_highlighter (self, _tmp3_, _tmp4_, TRUE);
	}
}

void
sudoku_grid_update_warnings (SudokuGrid* self)
{
	SudokuCell** _tmp0_;
	gint _tmp0__length1;
	gint _tmp0__length2;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->priv->cells;
	_tmp0__length1 = self->priv->cells_length1;
	_tmp0__length2 = self->priv->cells_length2;
	{
		SudokuCell** cell_collection = NULL;
		gint cell_collection_length1 = 0;
		gint cell_collection_length2 = 0;
		gint cell_it = 0;
		cell_collection = _tmp0_;
		cell_collection_length1 = _tmp0__length1 * _tmp0__length2;
		for (cell_it = 0; cell_it < cell_collection_length1; cell_it = cell_it + 1) {
			SudokuCell* _tmp1_;
			SudokuCell* cell = NULL;
			_tmp1_ = _g_object_ref0 (cell_collection[cell_it]);
			cell = _tmp1_;
			{
				SudokuCell* _tmp2_;
				SudokuCell* _tmp3_;
				_tmp2_ = cell;
				sudoku_cell_update_value_warnings (_tmp2_);
				_tmp3_ = cell;
				sudoku_cell_update_all_earmark_warnings (_tmp3_);
				_g_object_unref0 (cell);
			}
		}
	}
}

void
sudoku_grid_update_cell_warnings (SudokuGrid* self,
                                  gint row,
                                  gint col)
{
	g_return_if_fail (self != NULL);
	{
		GeeIterator* _coord_it = NULL;
		SudokuGame* _tmp0_;
		SudokuBoard* _tmp1_;
		SudokuBoard* _tmp2_;
		GeeSet** _tmp3_;
		gint _tmp3__length1;
		gint _tmp3__length2;
		GeeSet* _tmp4_;
		GeeIterator* _tmp5_;
		_tmp0_ = self->priv->game;
		_tmp1_ = sudoku_game_get_board (_tmp0_);
		_tmp2_ = _tmp1_;
		_tmp3_ = _tmp2_->aligned_coords_for_cell;
		_tmp3__length1 = _tmp2_->aligned_coords_for_cell_length1;
		_tmp3__length2 = _tmp2_->aligned_coords_for_cell_length2;
		_tmp4_ = _tmp3_[(row * _tmp3__length2) + col];
		_tmp5_ = gee_iterable_iterator ((GeeIterable*) _tmp4_);
		_coord_it = _tmp5_;
		while (TRUE) {
			GeeIterator* _tmp6_;
			Coord* coord = NULL;
			GeeIterator* _tmp7_;
			gpointer _tmp8_;
			SudokuCell** _tmp9_;
			gint _tmp9__length1;
			gint _tmp9__length2;
			Coord* _tmp10_;
			Coord* _tmp11_;
			SudokuCell* _tmp12_;
			SudokuCell** _tmp13_;
			gint _tmp13__length1;
			gint _tmp13__length2;
			Coord* _tmp14_;
			Coord* _tmp15_;
			SudokuCell* _tmp16_;
			_tmp6_ = _coord_it;
			if (!gee_iterator_next (_tmp6_)) {
				break;
			}
			_tmp7_ = _coord_it;
			_tmp8_ = gee_iterator_get (_tmp7_);
			coord = (Coord*) _tmp8_;
			_tmp9_ = self->priv->cells;
			_tmp9__length1 = self->priv->cells_length1;
			_tmp9__length2 = self->priv->cells_length2;
			_tmp10_ = coord;
			_tmp11_ = coord;
			_tmp12_ = _tmp9_[((*_tmp10_).row * _tmp9__length2) + (*_tmp11_).col];
			sudoku_cell_update_value_warnings (_tmp12_);
			_tmp13_ = self->priv->cells;
			_tmp13__length1 = self->priv->cells_length1;
			_tmp13__length2 = self->priv->cells_length2;
			_tmp14_ = coord;
			_tmp15_ = coord;
			_tmp16_ = _tmp13_[((*_tmp14_).row * _tmp13__length2) + (*_tmp15_).col];
			sudoku_cell_update_all_earmark_warnings (_tmp16_);
			_g_free0 (coord);
		}
		_g_object_unref0 (_coord_it);
	}
}

void
sudoku_grid_update_selected (SudokuGrid* self,
                             SudokuCell* cell)
{
	gboolean _tmp0_;
	gboolean _tmp1_;
	gint old_row = 0;
	gint _tmp2_;
	gint old_col = 0;
	gint _tmp3_;
	SudokuCell* _tmp4_;
	SudokuCell* _tmp5_;
	gint _tmp6_;
	gint _tmp7_;
	gint _tmp8_;
	gint _tmp9_;
	SudokuCell* _tmp10_;
	SudokuCell* _tmp11_;
	SudokuNumberPicker* _tmp12_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (cell != NULL);
	_tmp0_ = sudoku_cell_get_selected (cell);
	_tmp1_ = _tmp0_;
	if (_tmp1_) {
		return;
	}
	_tmp2_ = self->priv->_selected_row;
	old_row = _tmp2_;
	_tmp3_ = self->priv->_selected_col;
	old_col = _tmp3_;
	_tmp4_ = sudoku_grid_get_selected_cell (self);
	_tmp5_ = _tmp4_;
	sudoku_cell_set_selected (_tmp5_, FALSE);
	_tmp6_ = sudoku_cell_get_row (cell);
	_tmp7_ = _tmp6_;
	sudoku_grid_set_selected_row (self, _tmp7_);
	_tmp8_ = sudoku_cell_get_col (cell);
	_tmp9_ = _tmp8_;
	sudoku_grid_set_selected_col (self, _tmp9_);
	_tmp10_ = sudoku_grid_get_selected_cell (self);
	_tmp11_ = _tmp10_;
	sudoku_cell_set_selected (_tmp11_, TRUE);
	_tmp12_ = self->number_picker;
	gtk_popover_popdown ((GtkPopover*) _tmp12_);
	sudoku_grid_update_highlighter (self, old_row, old_col);
}

void
sudoku_grid_unselect (SudokuGrid* self)
{
	SudokuNumberPicker* _tmp0_;
	SudokuCell* _tmp1_;
	SudokuCell* _tmp2_;
	gint _tmp3_;
	gint _tmp4_;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->number_picker;
	gtk_popover_popdown ((GtkPopover*) _tmp0_);
	_tmp1_ = sudoku_grid_get_selected_cell (self);
	_tmp2_ = _tmp1_;
	sudoku_cell_set_selected (_tmp2_, FALSE);
	_tmp3_ = self->priv->_selected_row;
	_tmp4_ = self->priv->_selected_col;
	sudoku_grid_set_cell_highlighter (self, _tmp3_, _tmp4_, FALSE);
}

static void
sudoku_grid_move (SudokuGrid* self,
                  GVariant* variant)
{
	GtkDirectionType dir = 0;
	g_return_if_fail (self != NULL);
	dir = (GtkDirectionType) g_variant_get_int32 (variant);
	G_TYPE_INSTANCE_GET_CLASS ((GtkWidget*) self, gtk_widget_get_type (), GtkWidgetClass)->focus ((GtkWidget*) self, dir);
}

static void
sudoku_grid_button_released_cb (SudokuGrid* self,
                                GtkGestureClick* gesture,
                                gint n_press,
                                gdouble x,
                                gdouble y)
{
	gboolean _tmp0_ = FALSE;
	SudokuNumberPicker* _tmp1_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (gesture != NULL);
	if (gtk_gesture_single_get_current_button ((GtkGestureSingle*) gesture) != ((guint) GDK_BUTTON_PRIMARY)) {
		_tmp0_ = gtk_gesture_single_get_current_button ((GtkGestureSingle*) gesture) != ((guint) GDK_BUTTON_SECONDARY);
	} else {
		_tmp0_ = FALSE;
	}
	if (_tmp0_) {
		return;
	}
	_tmp1_ = self->number_picker;
	gtk_popover_popdown ((GtkPopover*) _tmp1_);
	gtk_gesture_set_state ((GtkGesture*) gesture, GTK_EVENT_SEQUENCE_CLAIMED);
}

static void
sudoku_grid_value_changed_cb (SudokuGrid* self,
                              gint row,
                              gint col,
                              gint old_val,
                              gint new_val)
{
	StackAction action = 0;
	SudokuGame* _tmp0_;
	SudokuCell** _tmp3_;
	gint _tmp3__length1;
	gint _tmp3__length2;
	SudokuCell* _tmp4_;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->priv->game;
	action = sudoku_game_get_current_stack_action (_tmp0_);
	if (stack_action_is_single_value_change (action)) {
		SudokuCell** _tmp1_;
		gint _tmp1__length1;
		gint _tmp1__length2;
		SudokuCell* _tmp2_;
		_tmp1_ = self->priv->cells;
		_tmp1__length1 = self->priv->cells_length1;
		_tmp1__length2 = self->priv->cells_length2;
		_tmp2_ = _tmp1_[(row * _tmp1__length2) + col];
		sudoku_cell_grab_selection (_tmp2_);
	}
	_tmp3_ = self->priv->cells;
	_tmp3__length1 = self->priv->cells_length1;
	_tmp3__length2 = self->priv->cells_length2;
	_tmp4_ = _tmp3_[(row * _tmp3__length2) + col];
	sudoku_cell_update_content_visibility (_tmp4_);
	sudoku_grid_update_cell_warnings (self, row, col);
	sudoku_grid_update_value_highlighter (self, row, col, old_val, new_val);
}

static void
sudoku_grid_earmark_changed_cb (SudokuGrid* self,
                                gint row,
                                gint col,
                                gint num,
                                gboolean enabled)
{
	StackAction action = 0;
	SudokuGame* _tmp0_;
	SudokuCell** _tmp10_;
	gint _tmp10__length1;
	gint _tmp10__length2;
	SudokuCell* _tmp11_;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->priv->game;
	action = sudoku_game_get_current_stack_action (_tmp0_);
	if (stack_action_is_single_earmarks_change (action)) {
		SudokuCell** _tmp1_;
		gint _tmp1__length1;
		gint _tmp1__length2;
		SudokuCell* _tmp2_;
		SudokuCell** _tmp3_;
		gint _tmp3__length1;
		gint _tmp3__length2;
		SudokuCell* _tmp4_;
		_tmp1_ = self->priv->cells;
		_tmp1__length1 = self->priv->cells_length1;
		_tmp1__length2 = self->priv->cells_length2;
		_tmp2_ = _tmp1_[(row * _tmp1__length2) + col];
		sudoku_cell_grab_selection (_tmp2_);
		_tmp3_ = self->priv->cells;
		_tmp3__length1 = self->priv->cells_length1;
		_tmp3__length2 = self->priv->cells_length2;
		_tmp4_ = _tmp3_[(row * _tmp3__length2) + col];
		sudoku_cell_update_earmark_visibility (_tmp4_, num);
	} else {
		gboolean _tmp5_ = FALSE;
		if (!enabled) {
			_tmp5_ = action == STACK_ACTION_INSERT_AND_DISABLE_RELATED_EARMARKS;
		} else {
			_tmp5_ = FALSE;
		}
		if (_tmp5_) {
			SudokuCell** _tmp6_;
			gint _tmp6__length1;
			gint _tmp6__length2;
			SudokuCell* _tmp7_;
			_tmp6_ = self->priv->cells;
			_tmp6__length1 = self->priv->cells_length1;
			_tmp6__length2 = self->priv->cells_length2;
			_tmp7_ = _tmp6_[(row * _tmp6__length2) + col];
			sudoku_cell_animate_earmark_removal (_tmp7_, num);
		} else {
			SudokuCell** _tmp8_;
			gint _tmp8__length1;
			gint _tmp8__length2;
			SudokuCell* _tmp9_;
			_tmp8_ = self->priv->cells;
			_tmp8__length1 = self->priv->cells_length1;
			_tmp8__length2 = self->priv->cells_length2;
			_tmp9_ = _tmp8_[(row * _tmp8__length2) + col];
			sudoku_cell_update_earmark_visibility (_tmp9_, num);
		}
	}
	_tmp10_ = self->priv->cells;
	_tmp10__length1 = self->priv->cells_length1;
	_tmp10__length2 = self->priv->cells_length2;
	_tmp11_ = _tmp10_[(row * _tmp10__length2) + col];
	sudoku_cell_update_earmark_warning (_tmp11_, num);
}

static void
sudoku_grid_paused_cb (SudokuGrid* self)
{
	SudokuGame* _tmp0_;
	gboolean _tmp1_;
	gboolean _tmp2_;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->priv->game;
	_tmp1_ = sudoku_game_get_paused (_tmp0_);
	_tmp2_ = _tmp1_;
	if (_tmp2_) {
		sudoku_grid_unselect (self);
	} else {
		gtk_widget_grab_focus ((GtkWidget*) self);
	}
}

static gboolean
sudoku_grid_real_grab_focus (GtkWidget* base)
{
	SudokuGrid * self;
	SudokuWindow* window = NULL;
	GtkRoot* _tmp0_;
	GtkRoot* _tmp1_;
	SudokuWindow* _tmp2_;
	SudokuWindow* _tmp3_;
	gboolean _tmp4_;
	gboolean _tmp5_;
	gboolean result;
	self = (SudokuGrid*) base;
	_tmp0_ = gtk_widget_get_root ((GtkWidget*) self);
	_tmp1_ = _tmp0_;
	_tmp2_ = _g_object_ref0 (IS_SUDOKU_WINDOW (_tmp1_) ? ((SudokuWindow*) _tmp1_) : NULL);
	window = _tmp2_;
	_tmp3_ = window;
	_tmp4_ = sudoku_window_get_keyboard_pressed_recently (_tmp3_);
	_tmp5_ = _tmp4_;
	if (_tmp5_) {
		SudokuCell* _tmp6_;
		SudokuCell* _tmp7_;
		_tmp6_ = sudoku_grid_get_selected_cell (self);
		_tmp7_ = _tmp6_;
		result = sudoku_cell_grab_selection (_tmp7_);
		_g_object_unref0 (window);
		return result;
	} else {
		SudokuCell* _tmp8_;
		SudokuCell* _tmp9_;
		_tmp8_ = sudoku_grid_get_selected_cell (self);
		_tmp9_ = _tmp8_;
		result = gtk_widget_grab_focus ((GtkWidget*) _tmp9_);
		_g_object_unref0 (window);
		return result;
	}
}

static gboolean
sudoku_grid_real_focus (GtkWidget* base,
                        GtkDirectionType direction)
{
	SudokuGrid * self;
	gboolean result;
	self = (SudokuGrid*) base;
	switch (direction) {
		case GTK_DIR_TAB_FORWARD:
		{
			GtkEventControllerFocus* _tmp0_;
			gboolean _tmp1_;
			gboolean _tmp2_;
			_tmp0_ = self->priv->focus_controller;
			g_object_get (_tmp0_, "contains-focus", &_tmp1_, NULL);
			_tmp2_ = _tmp1_;
			if (!_tmp2_) {
				result = gtk_widget_grab_focus ((GtkWidget*) self);
				return result;
			} else {
				result = GDK_EVENT_PROPAGATE;
				return result;
			}
		}
		case GTK_DIR_TAB_BACKWARD:
		{
			GtkEventControllerFocus* _tmp3_;
			gboolean _tmp4_;
			gboolean _tmp5_;
			_tmp3_ = self->priv->focus_controller;
			g_object_get (_tmp3_, "contains-focus", &_tmp4_, NULL);
			_tmp5_ = _tmp4_;
			if (!_tmp5_) {
				result = gtk_widget_grab_focus ((GtkWidget*) self);
				return result;
			} else {
				result = GDK_EVENT_PROPAGATE;
				return result;
			}
		}
		case GTK_DIR_UP:
		{
			gint _tmp6_;
			_tmp6_ = self->priv->_selected_row;
			if (_tmp6_ == 0) {
				SudokuCell** _tmp7_;
				gint _tmp7__length1;
				gint _tmp7__length2;
				gint _tmp8_;
				SudokuCell* _tmp9_;
				_tmp7_ = self->priv->cells;
				_tmp7__length1 = self->priv->cells_length1;
				_tmp7__length2 = self->priv->cells_length2;
				_tmp8_ = self->priv->_selected_col;
				_tmp9_ = _tmp7_[(8 * _tmp7__length2) + _tmp8_];
				result = G_TYPE_INSTANCE_GET_CLASS ((GtkWidget*) _tmp9_, gtk_widget_get_type (), GtkWidgetClass)->focus ((GtkWidget*) _tmp9_, direction);
				return result;
			} else {
				SudokuCell** _tmp10_;
				gint _tmp10__length1;
				gint _tmp10__length2;
				gint _tmp11_;
				gint _tmp12_;
				SudokuCell* _tmp13_;
				_tmp10_ = self->priv->cells;
				_tmp10__length1 = self->priv->cells_length1;
				_tmp10__length2 = self->priv->cells_length2;
				_tmp11_ = self->priv->_selected_row;
				_tmp12_ = self->priv->_selected_col;
				_tmp13_ = _tmp10_[((_tmp11_ - 1) * _tmp10__length2) + _tmp12_];
				result = G_TYPE_INSTANCE_GET_CLASS ((GtkWidget*) _tmp13_, gtk_widget_get_type (), GtkWidgetClass)->focus ((GtkWidget*) _tmp13_, direction);
				return result;
			}
		}
		case GTK_DIR_DOWN:
		{
			gint _tmp14_;
			_tmp14_ = self->priv->_selected_row;
			if (_tmp14_ == 8) {
				SudokuCell** _tmp15_;
				gint _tmp15__length1;
				gint _tmp15__length2;
				gint _tmp16_;
				SudokuCell* _tmp17_;
				_tmp15_ = self->priv->cells;
				_tmp15__length1 = self->priv->cells_length1;
				_tmp15__length2 = self->priv->cells_length2;
				_tmp16_ = self->priv->_selected_col;
				_tmp17_ = _tmp15_[(0 * _tmp15__length2) + _tmp16_];
				result = G_TYPE_INSTANCE_GET_CLASS ((GtkWidget*) _tmp17_, gtk_widget_get_type (), GtkWidgetClass)->focus ((GtkWidget*) _tmp17_, direction);
				return result;
			} else {
				SudokuCell** _tmp18_;
				gint _tmp18__length1;
				gint _tmp18__length2;
				gint _tmp19_;
				gint _tmp20_;
				SudokuCell* _tmp21_;
				_tmp18_ = self->priv->cells;
				_tmp18__length1 = self->priv->cells_length1;
				_tmp18__length2 = self->priv->cells_length2;
				_tmp19_ = self->priv->_selected_row;
				_tmp20_ = self->priv->_selected_col;
				_tmp21_ = _tmp18_[((_tmp19_ + 1) * _tmp18__length2) + _tmp20_];
				result = G_TYPE_INSTANCE_GET_CLASS ((GtkWidget*) _tmp21_, gtk_widget_get_type (), GtkWidgetClass)->focus ((GtkWidget*) _tmp21_, direction);
				return result;
			}
		}
		case GTK_DIR_LEFT:
		{
			gint _tmp22_;
			_tmp22_ = self->priv->_selected_col;
			if (_tmp22_ == 0) {
				SudokuCell** _tmp23_;
				gint _tmp23__length1;
				gint _tmp23__length2;
				gint _tmp24_;
				SudokuCell* _tmp25_;
				_tmp23_ = self->priv->cells;
				_tmp23__length1 = self->priv->cells_length1;
				_tmp23__length2 = self->priv->cells_length2;
				_tmp24_ = self->priv->_selected_row;
				_tmp25_ = _tmp23_[(_tmp24_ * _tmp23__length2) + 8];
				result = G_TYPE_INSTANCE_GET_CLASS ((GtkWidget*) _tmp25_, gtk_widget_get_type (), GtkWidgetClass)->focus ((GtkWidget*) _tmp25_, direction);
				return result;
			} else {
				SudokuCell** _tmp26_;
				gint _tmp26__length1;
				gint _tmp26__length2;
				gint _tmp27_;
				gint _tmp28_;
				SudokuCell* _tmp29_;
				_tmp26_ = self->priv->cells;
				_tmp26__length1 = self->priv->cells_length1;
				_tmp26__length2 = self->priv->cells_length2;
				_tmp27_ = self->priv->_selected_row;
				_tmp28_ = self->priv->_selected_col;
				_tmp29_ = _tmp26_[(_tmp27_ * _tmp26__length2) + (_tmp28_ - 1)];
				result = G_TYPE_INSTANCE_GET_CLASS ((GtkWidget*) _tmp29_, gtk_widget_get_type (), GtkWidgetClass)->focus ((GtkWidget*) _tmp29_, direction);
				return result;
			}
		}
		case GTK_DIR_RIGHT:
		{
			gint _tmp30_;
			_tmp30_ = self->priv->_selected_col;
			if (_tmp30_ == 8) {
				SudokuCell** _tmp31_;
				gint _tmp31__length1;
				gint _tmp31__length2;
				gint _tmp32_;
				SudokuCell* _tmp33_;
				_tmp31_ = self->priv->cells;
				_tmp31__length1 = self->priv->cells_length1;
				_tmp31__length2 = self->priv->cells_length2;
				_tmp32_ = self->priv->_selected_row;
				_tmp33_ = _tmp31_[(_tmp32_ * _tmp31__length2) + 0];
				result = G_TYPE_INSTANCE_GET_CLASS ((GtkWidget*) _tmp33_, gtk_widget_get_type (), GtkWidgetClass)->focus ((GtkWidget*) _tmp33_, direction);
				return result;
			} else {
				SudokuCell** _tmp34_;
				gint _tmp34__length1;
				gint _tmp34__length2;
				gint _tmp35_;
				gint _tmp36_;
				SudokuCell* _tmp37_;
				_tmp34_ = self->priv->cells;
				_tmp34__length1 = self->priv->cells_length1;
				_tmp34__length2 = self->priv->cells_length2;
				_tmp35_ = self->priv->_selected_row;
				_tmp36_ = self->priv->_selected_col;
				_tmp37_ = _tmp34_[(_tmp35_ * _tmp34__length2) + (_tmp36_ + 1)];
				result = G_TYPE_INSTANCE_GET_CLASS ((GtkWidget*) _tmp37_, gtk_widget_get_type (), GtkWidgetClass)->focus ((GtkWidget*) _tmp37_, direction);
				return result;
			}
		}
		default:
		{
			g_assert_not_reached ();
		}
	}
}

static void
sudoku_grid_real_dispose (GObject* base)
{
	SudokuGrid * self;
	SudokuNumberPicker* _tmp0_;
	self = (SudokuGrid*) base;
	_tmp0_ = self->number_picker;
	gtk_widget_unparent ((GtkWidget*) _tmp0_);
	G_OBJECT_CLASS (sudoku_grid_parent_class)->dispose ((GObject*) G_TYPE_CHECK_INSTANCE_CAST (self, gtk_grid_get_type (), GtkGrid));
}

gint
sudoku_grid_get_selected_row (SudokuGrid* self)
{
	gint result;
	g_return_val_if_fail (self != NULL, -1);
	result = self->priv->_selected_row;
	return result;
}

static void
sudoku_grid_set_selected_row (SudokuGrid* self,
                              gint value)
{
	gint old_value;
	g_return_if_fail (self != NULL);
	old_value = sudoku_grid_get_selected_row (self);
	if (old_value != value) {
		self->priv->_selected_row = value;
		g_object_notify_by_pspec ((GObject *) self, sudoku_grid_properties[SUDOKU_GRID_SELECTED_ROW_PROPERTY]);
	}
}

gint
sudoku_grid_get_selected_col (SudokuGrid* self)
{
	gint result;
	g_return_val_if_fail (self != NULL, -1);
	result = self->priv->_selected_col;
	return result;
}

static void
sudoku_grid_set_selected_col (SudokuGrid* self,
                              gint value)
{
	gint old_value;
	g_return_if_fail (self != NULL);
	old_value = sudoku_grid_get_selected_col (self);
	if (old_value != value) {
		self->priv->_selected_col = value;
		g_object_notify_by_pspec ((GObject *) self, sudoku_grid_properties[SUDOKU_GRID_SELECTED_COL_PROPERTY]);
	}
}

SudokuCell*
sudoku_grid_get_selected_cell (SudokuGrid* self)
{
	SudokuCell* result;
	SudokuCell** _tmp0_;
	gint _tmp0__length1;
	gint _tmp0__length2;
	gint _tmp1_;
	gint _tmp2_;
	SudokuCell* _tmp3_;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = self->priv->cells;
	_tmp0__length1 = self->priv->cells_length1;
	_tmp0__length2 = self->priv->cells_length2;
	_tmp1_ = self->priv->_selected_row;
	_tmp2_ = self->priv->_selected_col;
	_tmp3_ = _tmp0_[(_tmp1_ * _tmp0__length2) + _tmp2_];
	result = _tmp3_;
	return result;
}

static void
sudoku_grid_class_init (SudokuGridClass * klass,
                        gpointer klass_data)
{
	GtkNamedAction* action = NULL;
	GtkNamedAction* _tmp0_;
	GtkShortcutTrigger* trigger = NULL;
	GtkShortcutTrigger* _tmp1_;
	GtkShortcut* shortcut = NULL;
	GtkShortcutTrigger* _tmp2_;
	GtkShortcutTrigger* _tmp3_;
	GtkNamedAction* _tmp4_;
	GtkShortcutAction* _tmp5_;
	GtkShortcut* _tmp6_;
	GtkShortcut* _tmp7_;
	sudoku_grid_parent_class = g_type_class_peek_parent (klass);
	g_type_class_adjust_private_offset (klass, &SudokuGrid_private_offset);
	((GtkWidgetClass *) klass)->grab_focus = (gboolean (*) (GtkWidget*)) sudoku_grid_real_grab_focus;
	((GtkWidgetClass *) klass)->focus = (gboolean (*) (GtkWidget*, GtkDirectionType)) sudoku_grid_real_focus;
	((GObjectClass *) klass)->dispose = (void (*) (GObject*)) sudoku_grid_real_dispose;
	G_OBJECT_CLASS (klass)->get_property = _vala_sudoku_grid_get_property;
	G_OBJECT_CLASS (klass)->set_property = _vala_sudoku_grid_set_property;
	G_OBJECT_CLASS (klass)->finalize = sudoku_grid_finalize;
	g_object_class_install_property (G_OBJECT_CLASS (klass), SUDOKU_GRID_SELECTED_ROW_PROPERTY, sudoku_grid_properties[SUDOKU_GRID_SELECTED_ROW_PROPERTY] = g_param_spec_int ("selected-row", "selected-row", "selected-row", G_MININT, G_MAXINT, SUDOKU_GRID_START.row, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
	g_object_class_install_property (G_OBJECT_CLASS (klass), SUDOKU_GRID_SELECTED_COL_PROPERTY, sudoku_grid_properties[SUDOKU_GRID_SELECTED_COL_PROPERTY] = g_param_spec_int ("selected-col", "selected-col", "selected-col", G_MININT, G_MAXINT, SUDOKU_GRID_START.col, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
	g_object_class_install_property (G_OBJECT_CLASS (klass), SUDOKU_GRID_SELECTED_CELL_PROPERTY, sudoku_grid_properties[SUDOKU_GRID_SELECTED_CELL_PROPERTY] = g_param_spec_object ("selected-cell", "selected-cell", "selected-cell", TYPE_SUDOKU_CELL, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
	sudoku_grid_new_move_shortcut (klass, "grid.move-up", "w", GTK_DIR_UP);
	sudoku_grid_new_move_shortcut (klass, "grid.move-left", "a", GTK_DIR_LEFT);
	sudoku_grid_new_move_shortcut (klass, "grid.move-down", "s", GTK_DIR_DOWN);
	sudoku_grid_new_move_shortcut (klass, "grid.move-right", "d", GTK_DIR_RIGHT);
	_tmp0_ = (GtkNamedAction*) gtk_named_action_new ("grid.escape");
	action = _tmp0_;
	_tmp1_ = gtk_shortcut_trigger_parse_string ("Escape");
	trigger = _tmp1_;
	_tmp2_ = trigger;
	_tmp3_ = _g_object_ref0 (_tmp2_);
	_tmp4_ = action;
	_tmp5_ = _g_object_ref0 ((GtkShortcutAction*) _tmp4_);
	_tmp6_ = gtk_shortcut_new (_tmp3_, _tmp5_);
	shortcut = _tmp6_;
	_tmp7_ = shortcut;
	gtk_widget_class_add_shortcut (GTK_WIDGET_CLASS (klass), _tmp7_);
	_g_object_unref0 (shortcut);
	_g_object_unref0 (trigger);
	_g_object_unref0 (action);
}

static void
sudoku_grid_instance_init (SudokuGrid * self,
                           gpointer klass)
{
	self->priv = sudoku_grid_get_instance_private (self);
	self->priv->_selected_row = SUDOKU_GRID_START.row;
	self->priv->_selected_col = SUDOKU_GRID_START.col;
}

static void
sudoku_grid_finalize (GObject * obj)
{
	SudokuGrid * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, TYPE_SUDOKU_GRID, SudokuGrid);
	_g_object_unref0 (self->priv->game);
	self->priv->cells = (_vala_array_free (self->priv->cells, self->priv->cells_length1 * self->priv->cells_length2, (GDestroyNotify) g_object_unref), NULL);
	_g_object_unref0 (self->priv->button_controller);
	_g_object_unref0 (self->priv->focus_controller);
	_g_object_unref0 (self->number_picker);
	_g_object_unref0 (self->priv->action_group);
	_g_object_unref0 (self->priv->move_up_action);
	_g_object_unref0 (self->priv->move_down_action);
	_g_object_unref0 (self->priv->move_left_action);
	_g_object_unref0 (self->priv->move_right_action);
	_g_object_unref0 (self->priv->escape_action);
	G_OBJECT_CLASS (sudoku_grid_parent_class)->finalize (obj);
}

static GType
sudoku_grid_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (SudokuGridClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) sudoku_grid_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (SudokuGrid), 0, (GInstanceInitFunc) sudoku_grid_instance_init, NULL };
	GType sudoku_grid_type_id;
	sudoku_grid_type_id = g_type_register_static (gtk_grid_get_type (), "SudokuGrid", &g_define_type_info, 0);
	SudokuGrid_private_offset = g_type_add_instance_private (sudoku_grid_type_id, sizeof (SudokuGridPrivate));
	return sudoku_grid_type_id;
}

GType
sudoku_grid_get_type (void)
{
	static volatile gsize sudoku_grid_type_id__once = 0;
	if (g_once_init_enter (&sudoku_grid_type_id__once)) {
		GType sudoku_grid_type_id;
		sudoku_grid_type_id = sudoku_grid_get_type_once ();
		g_once_init_leave (&sudoku_grid_type_id__once, sudoku_grid_type_id);
	}
	return sudoku_grid_type_id__once;
}

static void
_vala_sudoku_grid_get_property (GObject * object,
                                guint property_id,
                                GValue * value,
                                GParamSpec * pspec)
{
	SudokuGrid * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (object, TYPE_SUDOKU_GRID, SudokuGrid);
	switch (property_id) {
		case SUDOKU_GRID_SELECTED_ROW_PROPERTY:
		g_value_set_int (value, sudoku_grid_get_selected_row (self));
		break;
		case SUDOKU_GRID_SELECTED_COL_PROPERTY:
		g_value_set_int (value, sudoku_grid_get_selected_col (self));
		break;
		case SUDOKU_GRID_SELECTED_CELL_PROPERTY:
		g_value_set_object (value, sudoku_grid_get_selected_cell (self));
		break;
		default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
	}
}

static void
_vala_sudoku_grid_set_property (GObject * object,
                                guint property_id,
                                const GValue * value,
                                GParamSpec * pspec)
{
	SudokuGrid * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (object, TYPE_SUDOKU_GRID, SudokuGrid);
	switch (property_id) {
		case SUDOKU_GRID_SELECTED_ROW_PROPERTY:
		sudoku_grid_set_selected_row (self, g_value_get_int (value));
		break;
		case SUDOKU_GRID_SELECTED_COL_PROPERTY:
		sudoku_grid_set_selected_col (self, g_value_get_int (value));
		break;
		default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
	}
}

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);
}

