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

/* -*- Mode: vala; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * Copyright © 2014 Parin Porecha
 * Copyright © 2014 Michael Catanzaro
 *
 * 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 "libsudoku.h"
#include <glib.h>
#include <gee.h>
#include <glib-object.h>
#include <gio/gio.h>
#include <float.h>
#include <math.h>
#include <gobject/gvaluecollector.h>
#include <string.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

#define SUDOKU_GAME_TYPE_STACK_ITEM (sudoku_game_stack_item_get_type ())
#define SUDOKU_GAME_STACK_ITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SUDOKU_GAME_TYPE_STACK_ITEM, SudokuGamestack_item))
#define SUDOKU_GAME_STACK_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SUDOKU_GAME_TYPE_STACK_ITEM, SudokuGamestack_itemClass))
#define SUDOKU_GAME_IS_STACK_ITEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SUDOKU_GAME_TYPE_STACK_ITEM))
#define SUDOKU_GAME_IS_STACK_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SUDOKU_GAME_TYPE_STACK_ITEM))
#define SUDOKU_GAME_STACK_ITEM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SUDOKU_GAME_TYPE_STACK_ITEM, SudokuGamestack_itemClass))

typedef struct _SudokuGamestack_item SudokuGamestack_item;
typedef struct _SudokuGamestack_itemClass SudokuGamestack_itemClass;
enum  {
	SUDOKU_GAME_0_PROPERTY,
	SUDOKU_GAME_BOARD_PROPERTY,
	SUDOKU_GAME_PAUSED_PROPERTY,
	SUDOKU_GAME_NUM_PROPERTIES
};
static GParamSpec* sudoku_game_properties[SUDOKU_GAME_NUM_PROPERTIES];
#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))
#define _g_timer_destroy0(var) ((var == NULL) ? NULL : (var = (g_timer_destroy (var), NULL)))
typedef struct _SudokuGamestack_itemPrivate SudokuGamestack_itemPrivate;

#define SUDOKU_GAME_TYPE_EARMARK_CHANGE (sudoku_game_earmark_change_get_type ())
typedef struct _SudokuGameearmark_change SudokuGameearmark_change;

#define SUDOKU_GAME_TYPE_VALUE_CHANGE (sudoku_game_value_change_get_type ())
typedef struct _SudokuGamevalue_change SudokuGamevalue_change;
#define _sudoku_game_stack_item_unref0(var) ((var == NULL) ? NULL : (var = (sudoku_game_stack_item_unref (var), NULL)))
#define _sudoku_game_value_change_free0(var) ((var == NULL) ? NULL : (var = (sudoku_game_value_change_free (var), NULL)))
#define _sudoku_game_earmark_change_free0(var) ((var == NULL) ? NULL : (var = (sudoku_game_earmark_change_free (var), NULL)))
typedef struct _Block2Data Block2Data;
typedef struct _SudokuGameParamSpecstack_item SudokuGameParamSpecstack_item;
enum  {
	SUDOKU_GAME_TICK_SIGNAL,
	SUDOKU_GAME_ACTION_COMPLETED_SIGNAL,
	SUDOKU_GAME_NUM_SIGNALS
};
static guint sudoku_game_signals[SUDOKU_GAME_NUM_SIGNALS] = {0};

struct _SudokuGamePrivate {
	SudokuBoard* _board;
	gboolean _paused;
	GTimer* timer;
	guint clock_tick_timeout;
	GeeArrayList* stack;
	gint stack_head_index;
};

struct _SudokuGameearmark_change {
	gint row;
	gint col;
	gint number;
	gboolean enabled;
};

struct _SudokuGamevalue_change {
	gint row;
	gint col;
	gint old_val;
	gint new_val;
};

struct _SudokuGamestack_item {
	GTypeInstance parent_instance;
	volatile int ref_count;
	SudokuGamestack_itemPrivate * priv;
	GeeArrayList* earmarks;
	GeeArrayList* values;
	StackAction action;
};

struct _SudokuGamestack_itemClass {
	GTypeClass parent_class;
	void (*finalize) (SudokuGamestack_item *self);
};

struct _Block2Data {
	int _ref_count_;
	SudokuGame* weak_this;
};

struct _SudokuGameParamSpecstack_item {
	GParamSpec parent_instance;
};

static gint SudokuGame_private_offset;
static gpointer sudoku_game_parent_class = NULL;
static gpointer sudoku_game_stack_item_parent_class = NULL;

static gpointer sudoku_game_stack_item_ref (gpointer instance);
static void sudoku_game_stack_item_unref (gpointer instance);
static GParamSpec* sudoku_game_param_spec_stack_item (const gchar* name,
                                               const gchar* nick,
                                               const gchar* blurb,
                                               GType object_type,
                                               GParamFlags flags) G_GNUC_UNUSED ;
static void sudoku_game_value_set_stack_item (GValue* value,
                                       gpointer v_object) G_GNUC_UNUSED ;
static void sudoku_game_value_take_stack_item (GValue* value,
                                        gpointer v_object) G_GNUC_UNUSED ;
static gpointer sudoku_game_value_get_stack_item (const GValue* value) G_GNUC_UNUSED ;
static GType sudoku_game_stack_item_get_type (void) G_GNUC_CONST  G_GNUC_UNUSED ;
static void sudoku_game_set_board (SudokuGame* self,
                            SudokuBoard* value);
static SudokuGamestack_item* sudoku_game_stack_item_new (StackAction _action);
static SudokuGamestack_item* sudoku_game_stack_item_construct (GType object_type,
                                                        StackAction _action);
static void sudoku_game_add_to_stack (SudokuGame* self,
                               SudokuGamestack_item* item);
static void sudoku_game_add_earmark_step (SudokuGame* self,
                                   SudokuGamestack_item* item,
                                   gint row,
                                   gint col,
                                   gint number,
                                   gboolean enabled);
static GType sudoku_game_earmark_change_get_type (void) G_GNUC_CONST  G_GNUC_UNUSED ;
static SudokuGameearmark_change* sudoku_game_earmark_change_dup (const SudokuGameearmark_change* self);
static void sudoku_game_earmark_change_free (SudokuGameearmark_change* self);
static GType sudoku_game_value_change_get_type (void) G_GNUC_CONST  G_GNUC_UNUSED ;
static SudokuGamevalue_change* sudoku_game_value_change_dup (const SudokuGamevalue_change* self);
static void sudoku_game_value_change_free (SudokuGamevalue_change* self);
static void sudoku_game_add_disable_earmarks_step (SudokuGame* self,
                                            SudokuGamestack_item* item,
                                            gint row,
                                            gint col);
static void sudoku_game_add_value_step (SudokuGame* self,
                                 SudokuGamestack_item* item,
                                 gint row,
                                 gint col,
                                 gint old_val,
                                 gint val);
static void sudoku_game_start_clock_tick (SudokuGame* _this);
static Block2Data* block2_data_ref (Block2Data* _data2_);
static void block2_data_unref (void * _userdata_);
static gboolean __lambda4_ (Block2Data* _data2_);
static gboolean ___lambda4__gsource_func (gpointer self);
static void sudoku_game_real_dispose (GObject* base);
static void sudoku_game_stack_item_finalize (SudokuGamestack_item * obj);
static GType sudoku_game_stack_item_get_type_once (void);
static void sudoku_game_finalize (GObject * obj);
static GType sudoku_game_get_type_once (void);
static void _vala_sudoku_game_get_property (GObject * object,
                                     guint property_id,
                                     GValue * value,
                                     GParamSpec * pspec);
static void _vala_sudoku_game_set_property (GObject * object,
                                     guint property_id,
                                     const GValue * value,
                                     GParamSpec * pspec);
static inline gpointer _vala_memdup2 (gconstpointer mem,
                        gsize byte_size);

static inline gpointer
sudoku_game_get_instance_private (SudokuGame* self)
{
	return G_STRUCT_MEMBER_P (self, SudokuGame_private_offset);
}

gboolean
sudoku_game_is_undostack_null (SudokuGame* self)
{
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	result = self->priv->stack_head_index == -1;
	return result;
}

gboolean
sudoku_game_is_redostack_null (SudokuGame* self)
{
	GeeArrayList* _tmp0_;
	gint _tmp1_;
	gint _tmp2_;
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	_tmp0_ = self->priv->stack;
	_tmp1_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) _tmp0_);
	_tmp2_ = _tmp1_;
	result = self->priv->stack_head_index == (_tmp2_ - 1);
	return result;
}

SudokuGame*
sudoku_game_construct (GType object_type,
                       SudokuBoard* board,
                       GError** error)
{
	SudokuGame * self = NULL;
	GeeArrayList* _tmp1_;
	GError* _inner_error0_ = NULL;
	g_return_val_if_fail (board != NULL, NULL);
	self = (SudokuGame*) g_object_new (object_type, NULL);
	sudoku_game_set_board (self, board);
	sudoku_board_solve (board);
	if (!sudoku_board_solved (board)) {
		GError* _tmp0_;
		_tmp0_ = g_error_new_literal (G_IO_ERROR, G_IO_ERROR_INVALID_DATA, "The puzzle has more than one solution");
		_inner_error0_ = _tmp0_;
		if (_inner_error0_->domain == G_IO_ERROR) {
			g_propagate_error (error, _inner_error0_);
			_g_object_unref0 (self);
			return NULL;
		} else {
			g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error0_->message, g_quark_to_string (_inner_error0_->domain), _inner_error0_->code);
			g_clear_error (&_inner_error0_);
			return NULL;
		}
	}
	sudoku_game_start_clock (self);
	_tmp1_ = gee_array_list_new (SUDOKU_GAME_TYPE_STACK_ITEM, (GBoxedCopyFunc) sudoku_game_stack_item_ref, (GDestroyNotify) sudoku_game_stack_item_unref, NULL, NULL, NULL);
	_g_object_unref0 (self->priv->stack);
	self->priv->stack = _tmp1_;
	return self;
}

SudokuGame*
sudoku_game_new (SudokuBoard* board,
                 GError** error)
{
	return sudoku_game_construct (TYPE_SUDOKU_GAME, board, error);
}

void
sudoku_game_enable_earmark (SudokuGame* self,
                            gint row,
                            gint col,
                            gint num)
{
	SudokuGamestack_item* new_stack_item = NULL;
	SudokuGamestack_item* _tmp0_;
	SudokuBoard* _tmp1_;
	g_return_if_fail (self != NULL);
	_tmp0_ = sudoku_game_stack_item_new (STACK_ACTION_ENABLE_EARMARK);
	new_stack_item = _tmp0_;
	sudoku_game_add_to_stack (self, new_stack_item);
	sudoku_game_add_earmark_step (self, new_stack_item, row, col, num, TRUE);
	_tmp1_ = self->priv->_board;
	sudoku_board_enable_earmark (_tmp1_, row, col, num);
	g_signal_emit (self, sudoku_game_signals[SUDOKU_GAME_ACTION_COMPLETED_SIGNAL], 0, new_stack_item->action);
	_sudoku_game_stack_item_unref0 (new_stack_item);
}

void
sudoku_game_disable_earmark (SudokuGame* self,
                             gint row,
                             gint col,
                             gint num)
{
	SudokuGamestack_item* new_stack_item = NULL;
	SudokuGamestack_item* _tmp0_;
	SudokuBoard* _tmp1_;
	g_return_if_fail (self != NULL);
	_tmp0_ = sudoku_game_stack_item_new (STACK_ACTION_DISABLE_EARMARK);
	new_stack_item = _tmp0_;
	sudoku_game_add_to_stack (self, new_stack_item);
	sudoku_game_add_earmark_step (self, new_stack_item, row, col, num, FALSE);
	_tmp1_ = self->priv->_board;
	sudoku_board_disable_earmark (_tmp1_, row, col, num);
	g_signal_emit (self, sudoku_game_signals[SUDOKU_GAME_ACTION_COMPLETED_SIGNAL], 0, new_stack_item->action);
	_sudoku_game_stack_item_unref0 (new_stack_item);
}

void
sudoku_game_disable_all_earmarks (SudokuGame* self,
                                  gint row,
                                  gint col)
{
	SudokuGamestack_item* new_stack_item = NULL;
	SudokuGamestack_item* _tmp0_;
	SudokuBoard* _tmp1_;
	g_return_if_fail (self != NULL);
	_tmp0_ = sudoku_game_stack_item_new (STACK_ACTION_DISABLE_ALL_EARMARKS);
	new_stack_item = _tmp0_;
	sudoku_game_add_to_stack (self, new_stack_item);
	sudoku_game_add_disable_earmarks_step (self, new_stack_item, row, col);
	_tmp1_ = self->priv->_board;
	sudoku_board_disable_all_earmarks (_tmp1_, row, col);
	g_signal_emit (self, sudoku_game_signals[SUDOKU_GAME_ACTION_COMPLETED_SIGNAL], 0, new_stack_item->action);
	_sudoku_game_stack_item_unref0 (new_stack_item);
}

void
sudoku_game_insert (SudokuGame* self,
                    gint row,
                    gint col,
                    gint val)
{
	gint old_val = 0;
	SudokuBoard* _tmp0_;
	SudokuGamestack_item* new_stack_item = NULL;
	SudokuGamestack_item* _tmp1_;
	SudokuGamestack_item* _tmp2_;
	SudokuBoard* _tmp3_;
	SudokuGamestack_item* _tmp6_;
	SudokuBoard* _tmp7_;
	SudokuGamestack_item* _tmp8_;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->priv->_board;
	old_val = sudoku_board_get (_tmp0_, row, col);
	_tmp1_ = sudoku_game_stack_item_new (STACK_ACTION_INSERT);
	new_stack_item = _tmp1_;
	_tmp2_ = new_stack_item;
	sudoku_game_add_to_stack (self, _tmp2_);
	_tmp3_ = self->priv->_board;
	if (sudoku_board_has_earmarks (_tmp3_, row, col)) {
		SudokuGamestack_item* _tmp4_;
		SudokuBoard* _tmp5_;
		_tmp4_ = new_stack_item;
		sudoku_game_add_disable_earmarks_step (self, _tmp4_, row, col);
		_tmp5_ = self->priv->_board;
		sudoku_board_disable_all_earmarks (_tmp5_, row, col);
	}
	_tmp6_ = new_stack_item;
	sudoku_game_add_value_step (self, _tmp6_, row, col, old_val, val);
	_tmp7_ = self->priv->_board;
	sudoku_board_insert (_tmp7_, row, col, val, FALSE);
	_tmp8_ = new_stack_item;
	g_signal_emit (self, sudoku_game_signals[SUDOKU_GAME_ACTION_COMPLETED_SIGNAL], 0, _tmp8_->action);
	_sudoku_game_stack_item_unref0 (new_stack_item);
}

void
sudoku_game_remove (SudokuGame* self,
                    gint row,
                    gint col)
{
	gint old_val = 0;
	SudokuBoard* _tmp0_;
	SudokuGamestack_item* new_stack_item = NULL;
	SudokuGamestack_item* _tmp1_;
	SudokuBoard* _tmp2_;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->priv->_board;
	old_val = sudoku_board_get (_tmp0_, row, col);
	_tmp1_ = sudoku_game_stack_item_new (STACK_ACTION_REMOVE);
	new_stack_item = _tmp1_;
	sudoku_game_add_to_stack (self, new_stack_item);
	sudoku_game_add_value_step (self, new_stack_item, row, col, old_val, 0);
	_tmp2_ = self->priv->_board;
	sudoku_board_remove (_tmp2_, row, col);
	g_signal_emit (self, sudoku_game_signals[SUDOKU_GAME_ACTION_COMPLETED_SIGNAL], 0, new_stack_item->action);
	_sudoku_game_stack_item_unref0 (new_stack_item);
}

void
sudoku_game_insert_and_disable_related_earmarks (SudokuGame* self,
                                                 gint row,
                                                 gint col,
                                                 gint val)
{
	gint old_val = 0;
	SudokuBoard* _tmp0_;
	SudokuGamestack_item* new_stack_item = NULL;
	SudokuGamestack_item* _tmp1_;
	SudokuGamestack_item* _tmp2_;
	SudokuGamestack_item* _tmp33_;
	GeeArrayList* _tmp34_;
	gint _tmp35_;
	gint _tmp36_;
	SudokuBoard* _tmp38_;
	SudokuGamestack_item* _tmp41_;
	SudokuBoard* _tmp42_;
	SudokuGamestack_item* _tmp43_;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->priv->_board;
	old_val = sudoku_board_get (_tmp0_, row, col);
	_tmp1_ = sudoku_game_stack_item_new (STACK_ACTION_INSERT_AND_DISABLE_RELATED_EARMARKS);
	new_stack_item = _tmp1_;
	_tmp2_ = new_stack_item;
	sudoku_game_add_to_stack (self, _tmp2_);
	{
		gint col_tmp = 0;
		col_tmp = 0;
		{
			gboolean _tmp3_ = FALSE;
			_tmp3_ = TRUE;
			while (TRUE) {
				SudokuBoard* _tmp5_;
				gint _tmp6_;
				gint _tmp7_;
				if (!_tmp3_) {
					gint _tmp4_;
					_tmp4_ = col_tmp;
					col_tmp = _tmp4_ + 1;
				}
				_tmp3_ = FALSE;
				_tmp5_ = self->priv->_board;
				_tmp6_ = sudoku_board_get_cols (_tmp5_);
				_tmp7_ = _tmp6_;
				if (!(col_tmp < _tmp7_)) {
					break;
				}
				{
					gint row_tmp = 0;
					row_tmp = 0;
					{
						gboolean _tmp8_ = FALSE;
						_tmp8_ = TRUE;
						while (TRUE) {
							SudokuBoard* _tmp10_;
							gint _tmp11_;
							gint _tmp12_;
							gboolean _tmp13_ = FALSE;
							gboolean _tmp14_ = FALSE;
							gboolean _tmp15_ = FALSE;
							gboolean _tmp16_ = FALSE;
							if (!_tmp8_) {
								gint _tmp9_;
								_tmp9_ = row_tmp;
								row_tmp = _tmp9_ + 1;
							}
							_tmp8_ = FALSE;
							_tmp10_ = self->priv->_board;
							_tmp11_ = sudoku_board_get_rows (_tmp10_);
							_tmp12_ = _tmp11_;
							if (!(row_tmp < _tmp12_)) {
								break;
							}
							if (row_tmp == row) {
								_tmp13_ = col_tmp == col;
							} else {
								_tmp13_ = FALSE;
							}
							if (_tmp13_) {
								continue;
							}
							if (row_tmp == row) {
								_tmp16_ = TRUE;
							} else {
								_tmp16_ = col_tmp == col;
							}
							if (_tmp16_) {
								_tmp15_ = TRUE;
							} else {
								gboolean _tmp17_ = FALSE;
								SudokuBoard* _tmp18_;
								gint _tmp19_;
								gint _tmp20_;
								SudokuBoard* _tmp21_;
								gint _tmp22_;
								gint _tmp23_;
								_tmp18_ = self->priv->_board;
								_tmp19_ = sudoku_board_get_block_cols (_tmp18_);
								_tmp20_ = _tmp19_;
								_tmp21_ = self->priv->_board;
								_tmp22_ = sudoku_board_get_block_cols (_tmp21_);
								_tmp23_ = _tmp22_;
								if ((row_tmp / _tmp20_) == (row / _tmp23_)) {
									SudokuBoard* _tmp24_;
									gint _tmp25_;
									gint _tmp26_;
									SudokuBoard* _tmp27_;
									gint _tmp28_;
									gint _tmp29_;
									_tmp24_ = self->priv->_board;
									_tmp25_ = sudoku_board_get_block_rows (_tmp24_);
									_tmp26_ = _tmp25_;
									_tmp27_ = self->priv->_board;
									_tmp28_ = sudoku_board_get_block_rows (_tmp27_);
									_tmp29_ = _tmp28_;
									_tmp17_ = (col_tmp / _tmp26_) == (col / _tmp29_);
								} else {
									_tmp17_ = FALSE;
								}
								_tmp15_ = _tmp17_;
							}
							if (_tmp15_) {
								SudokuBoard* _tmp30_;
								_tmp30_ = self->priv->_board;
								_tmp14_ = sudoku_board_is_earmark_enabled (_tmp30_, row_tmp, col_tmp, val);
							} else {
								_tmp14_ = FALSE;
							}
							if (_tmp14_) {
								SudokuGamestack_item* _tmp31_;
								SudokuBoard* _tmp32_;
								_tmp31_ = new_stack_item;
								sudoku_game_add_earmark_step (self, _tmp31_, row_tmp, col_tmp, val, FALSE);
								_tmp32_ = self->priv->_board;
								sudoku_board_disable_earmark (_tmp32_, row_tmp, col_tmp, val);
							}
						}
					}
				}
			}
		}
	}
	_tmp33_ = new_stack_item;
	_tmp34_ = _tmp33_->earmarks;
	_tmp35_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) _tmp34_);
	_tmp36_ = _tmp35_;
	if (_tmp36_ == 0) {
		SudokuGamestack_item* _tmp37_;
		_tmp37_ = new_stack_item;
		_tmp37_->action = STACK_ACTION_INSERT;
	}
	_tmp38_ = self->priv->_board;
	if (sudoku_board_has_earmarks (_tmp38_, row, col)) {
		SudokuGamestack_item* _tmp39_;
		SudokuBoard* _tmp40_;
		_tmp39_ = new_stack_item;
		sudoku_game_add_disable_earmarks_step (self, _tmp39_, row, col);
		_tmp40_ = self->priv->_board;
		sudoku_board_disable_all_earmarks (_tmp40_, row, col);
	}
	_tmp41_ = new_stack_item;
	sudoku_game_add_value_step (self, _tmp41_, row, col, old_val, val);
	_tmp42_ = self->priv->_board;
	sudoku_board_insert (_tmp42_, row, col, val, FALSE);
	_tmp43_ = new_stack_item;
	g_signal_emit (self, sudoku_game_signals[SUDOKU_GAME_ACTION_COMPLETED_SIGNAL], 0, _tmp43_->action);
	_sudoku_game_stack_item_unref0 (new_stack_item);
}

StackAction
sudoku_game_get_current_stack_action (SudokuGame* self)
{
	StackAction _tmp0_ = 0;
	StackAction result;
	g_return_val_if_fail (self != NULL, 0);
	if (self->priv->stack_head_index == -1) {
		_tmp0_ = STACK_ACTION_NONE;
	} else {
		GeeArrayList* _tmp1_;
		gpointer _tmp2_;
		SudokuGamestack_item* _tmp3_;
		_tmp1_ = self->priv->stack;
		_tmp2_ = gee_abstract_list_get ((GeeAbstractList*) _tmp1_, self->priv->stack_head_index);
		_tmp3_ = (SudokuGamestack_item*) _tmp2_;
		_tmp0_ = _tmp3_->action;
		_sudoku_game_stack_item_unref0 (_tmp3_);
	}
	result = _tmp0_;
	return result;
}

static void
sudoku_game_add_to_stack (SudokuGame* self,
                          SudokuGamestack_item* item)
{
	GeeArrayList* _tmp0_;
	GeeArrayList* _tmp1_;
	gint _tmp2_;
	gint _tmp3_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (item != NULL);
	sudoku_game_stack_slice (self);
	_tmp0_ = self->priv->stack;
	gee_abstract_collection_add ((GeeAbstractCollection*) _tmp0_, item);
	_tmp1_ = self->priv->stack;
	_tmp2_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) _tmp1_);
	_tmp3_ = _tmp2_;
	self->priv->stack_head_index = _tmp3_ - 1;
}

void
sudoku_game_toggle_pause (SudokuGame* self)
{
	gboolean _tmp0_;
	gboolean _tmp1_;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->priv->_paused;
	sudoku_game_set_paused (self, !_tmp0_);
	_tmp1_ = self->priv->_paused;
	if (_tmp1_) {
		sudoku_game_stop_clock (self);
	} else {
		sudoku_game_resume_clock (self);
	}
}

gboolean
sudoku_game_is_empty (SudokuGame* self)
{
	SudokuBoard* _tmp0_;
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	_tmp0_ = self->priv->_board;
	result = sudoku_board_is_empty (_tmp0_);
	return result;
}

void
sudoku_game_reset (SudokuGame* self)
{
	gint* cells = NULL;
	SudokuBoard* _tmp0_;
	gint _tmp1_ = 0;
	gint _tmp2_ = 0;
	gint* _tmp3_;
	gint cells_length1;
	gint cells_length2;
	SudokuGamestack_item* new_stack_item = NULL;
	SudokuGamestack_item* _tmp4_;
	SudokuGamestack_item* _tmp5_;
	SudokuGamestack_item* _tmp25_;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->priv->_board;
	_tmp3_ = sudoku_board_get_cells (_tmp0_, &_tmp1_, &_tmp2_);
	cells = _tmp3_;
	cells_length1 = _tmp1_;
	cells_length2 = _tmp2_;
	_tmp4_ = sudoku_game_stack_item_new (STACK_ACTION_CLEAR_BOARD);
	new_stack_item = _tmp4_;
	_tmp5_ = new_stack_item;
	sudoku_game_add_to_stack (self, _tmp5_);
	{
		gint row = 0;
		row = 0;
		{
			gboolean _tmp6_ = FALSE;
			_tmp6_ = TRUE;
			while (TRUE) {
				SudokuBoard* _tmp8_;
				gint _tmp9_;
				gint _tmp10_;
				if (!_tmp6_) {
					gint _tmp7_;
					_tmp7_ = row;
					row = _tmp7_ + 1;
				}
				_tmp6_ = FALSE;
				_tmp8_ = self->priv->_board;
				_tmp9_ = sudoku_board_get_rows (_tmp8_);
				_tmp10_ = _tmp9_;
				if (!(row < _tmp10_)) {
					break;
				}
				{
					gint col = 0;
					col = 0;
					{
						gboolean _tmp11_ = FALSE;
						_tmp11_ = TRUE;
						while (TRUE) {
							SudokuBoard* _tmp13_;
							gint _tmp14_;
							gint _tmp15_;
							SudokuBoard* _tmp16_;
							gint* _tmp17_;
							gint _tmp17__length1;
							gint _tmp17__length2;
							gint _tmp18_;
							SudokuBoard* _tmp24_;
							if (!_tmp11_) {
								gint _tmp12_;
								_tmp12_ = col;
								col = _tmp12_ + 1;
							}
							_tmp11_ = FALSE;
							_tmp13_ = self->priv->_board;
							_tmp14_ = sudoku_board_get_cols (_tmp13_);
							_tmp15_ = _tmp14_;
							if (!(col < _tmp15_)) {
								break;
							}
							_tmp16_ = self->priv->_board;
							if (sudoku_board_get_is_fixed (_tmp16_, row, col)) {
								continue;
							}
							_tmp17_ = cells;
							_tmp17__length1 = cells_length1;
							_tmp17__length2 = cells_length2;
							_tmp18_ = _tmp17_[(row * _tmp17__length2) + col];
							if (_tmp18_ > 0) {
								SudokuGamestack_item* _tmp19_;
								gint* _tmp20_;
								gint _tmp20__length1;
								gint _tmp20__length2;
								gint _tmp21_;
								_tmp19_ = new_stack_item;
								_tmp20_ = cells;
								_tmp20__length1 = cells_length1;
								_tmp20__length2 = cells_length2;
								_tmp21_ = _tmp20_[(row * _tmp20__length2) + col];
								sudoku_game_add_value_step (self, _tmp19_, row, col, _tmp21_, 0);
							} else {
								SudokuBoard* _tmp22_;
								_tmp22_ = self->priv->_board;
								if (sudoku_board_has_earmarks (_tmp22_, row, col)) {
									SudokuGamestack_item* _tmp23_;
									_tmp23_ = new_stack_item;
									sudoku_game_add_disable_earmarks_step (self, _tmp23_, row, col);
								}
							}
							_tmp24_ = self->priv->_board;
							sudoku_board_set (_tmp24_, row, col, 0);
						}
					}
				}
			}
		}
	}
	_tmp25_ = new_stack_item;
	g_signal_emit (self, sudoku_game_signals[SUDOKU_GAME_ACTION_COMPLETED_SIGNAL], 0, _tmp25_->action);
	_sudoku_game_stack_item_unref0 (new_stack_item);
	cells = (g_free (cells), NULL);
}

static void
sudoku_game_add_earmark_step (SudokuGame* self,
                              SudokuGamestack_item* item,
                              gint row,
                              gint col,
                              gint number,
                              gboolean enabled)
{
	SudokuGameearmark_change step = {0};
	SudokuGameearmark_change _tmp0_ = {0};
	GeeArrayList* _tmp1_;
	SudokuGameearmark_change _tmp2_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (item != NULL);
	_tmp0_.row = row;
	_tmp0_.col = col;
	_tmp0_.number = number;
	_tmp0_.enabled = enabled;
	step = _tmp0_;
	_tmp1_ = item->earmarks;
	_tmp2_ = step;
	gee_abstract_collection_add ((GeeAbstractCollection*) _tmp1_, &_tmp2_);
}

static void
sudoku_game_add_disable_earmarks_step (SudokuGame* self,
                                       SudokuGamestack_item* item,
                                       gint row,
                                       gint col)
{
	gboolean* marks = NULL;
	SudokuBoard* _tmp0_;
	gint _tmp1_ = 0;
	gboolean* _tmp2_;
	gint marks_length1;
	gint _marks_size_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (item != NULL);
	_tmp0_ = self->priv->_board;
	_tmp2_ = sudoku_board_get_earmarks (_tmp0_, row, col, &_tmp1_);
	marks = _tmp2_;
	marks_length1 = _tmp1_;
	_marks_size_ = marks_length1;
	{
		gint num = 0;
		num = 1;
		{
			gboolean _tmp3_ = FALSE;
			_tmp3_ = TRUE;
			while (TRUE) {
				gboolean* _tmp5_;
				gint _tmp5__length1;
				gboolean _tmp6_;
				if (!_tmp3_) {
					gint _tmp4_;
					_tmp4_ = num;
					num = _tmp4_ + 1;
				}
				_tmp3_ = FALSE;
				if (!(num <= 9)) {
					break;
				}
				_tmp5_ = marks;
				_tmp5__length1 = marks_length1;
				_tmp6_ = _tmp5_[num - 1];
				if (_tmp6_) {
					SudokuGameearmark_change step = {0};
					SudokuGameearmark_change _tmp7_ = {0};
					GeeArrayList* _tmp8_;
					SudokuGameearmark_change _tmp9_;
					_tmp7_.row = row;
					_tmp7_.col = col;
					_tmp7_.number = num;
					_tmp7_.enabled = FALSE;
					step = _tmp7_;
					_tmp8_ = item->earmarks;
					_tmp9_ = step;
					gee_abstract_collection_add ((GeeAbstractCollection*) _tmp8_, &_tmp9_);
				}
			}
		}
	}
	marks = (g_free (marks), NULL);
}

static void
sudoku_game_add_value_step (SudokuGame* self,
                            SudokuGamestack_item* item,
                            gint row,
                            gint col,
                            gint old_val,
                            gint val)
{
	SudokuGamevalue_change step = {0};
	SudokuGamevalue_change _tmp0_ = {0};
	GeeArrayList* _tmp1_;
	SudokuGamevalue_change _tmp2_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (item != NULL);
	_tmp0_.row = row;
	_tmp0_.col = col;
	_tmp0_.old_val = old_val;
	_tmp0_.new_val = val;
	step = _tmp0_;
	_tmp1_ = item->values;
	_tmp2_ = step;
	gee_abstract_collection_add ((GeeAbstractCollection*) _tmp1_, &_tmp2_);
}

void
sudoku_game_undo (SudokuGame* self)
{
	SudokuGamestack_item* changes = NULL;
	GeeArrayList* _tmp0_;
	gpointer _tmp1_;
	GeeListIterator* value_iterator = NULL;
	SudokuGamestack_item* _tmp2_;
	GeeArrayList* _tmp3_;
	GeeListIterator* _tmp4_;
	GeeListIterator* earmark_iterator = NULL;
	SudokuGamestack_item* _tmp14_;
	GeeArrayList* _tmp15_;
	GeeListIterator* _tmp16_;
	gint _tmp31_;
	GeeArrayList* _tmp32_;
	gpointer _tmp33_;
	SudokuGamestack_item* _tmp34_;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->priv->stack;
	_tmp1_ = gee_abstract_list_get ((GeeAbstractList*) _tmp0_, self->priv->stack_head_index);
	changes = (SudokuGamestack_item*) _tmp1_;
	_tmp2_ = changes;
	_tmp3_ = _tmp2_->values;
	_tmp4_ = gee_abstract_list_list_iterator ((GeeAbstractList*) _tmp3_);
	value_iterator = _tmp4_;
	{
		gboolean has_next = FALSE;
		GeeListIterator* _tmp5_;
		_tmp5_ = value_iterator;
		has_next = gee_iterator_next ((GeeIterator*) _tmp5_);
		{
			gboolean _tmp6_ = FALSE;
			_tmp6_ = TRUE;
			while (TRUE) {
				SudokuGamevalue_change* val = NULL;
				GeeListIterator* _tmp8_;
				gpointer _tmp9_;
				SudokuBoard* _tmp10_;
				SudokuGamevalue_change* _tmp11_;
				SudokuGamevalue_change* _tmp12_;
				SudokuGamevalue_change* _tmp13_;
				if (!_tmp6_) {
					GeeListIterator* _tmp7_;
					_tmp7_ = value_iterator;
					has_next = gee_iterator_next ((GeeIterator*) _tmp7_);
				}
				_tmp6_ = FALSE;
				if (!has_next) {
					break;
				}
				_tmp8_ = value_iterator;
				_tmp9_ = gee_iterator_get ((GeeIterator*) _tmp8_);
				val = (SudokuGamevalue_change*) _tmp9_;
				_tmp10_ = self->priv->_board;
				_tmp11_ = val;
				_tmp12_ = val;
				_tmp13_ = val;
				sudoku_board_set (_tmp10_, (*_tmp11_).row, (*_tmp12_).col, (*_tmp13_).old_val);
				_sudoku_game_value_change_free0 (val);
			}
		}
	}
	_tmp14_ = changes;
	_tmp15_ = _tmp14_->earmarks;
	_tmp16_ = gee_abstract_list_list_iterator ((GeeAbstractList*) _tmp15_);
	earmark_iterator = _tmp16_;
	{
		gboolean has_next = FALSE;
		GeeListIterator* _tmp17_;
		_tmp17_ = earmark_iterator;
		has_next = gee_iterator_next ((GeeIterator*) _tmp17_);
		{
			gboolean _tmp18_ = FALSE;
			_tmp18_ = TRUE;
			while (TRUE) {
				SudokuGameearmark_change* earmark = NULL;
				GeeListIterator* _tmp20_;
				gpointer _tmp21_;
				SudokuGameearmark_change* _tmp22_;
				if (!_tmp18_) {
					GeeListIterator* _tmp19_;
					_tmp19_ = earmark_iterator;
					has_next = gee_iterator_next ((GeeIterator*) _tmp19_);
				}
				_tmp18_ = FALSE;
				if (!has_next) {
					break;
				}
				_tmp20_ = earmark_iterator;
				_tmp21_ = gee_iterator_get ((GeeIterator*) _tmp20_);
				earmark = (SudokuGameearmark_change*) _tmp21_;
				_tmp22_ = earmark;
				if ((*_tmp22_).enabled) {
					SudokuBoard* _tmp23_;
					SudokuGameearmark_change* _tmp24_;
					SudokuGameearmark_change* _tmp25_;
					SudokuGameearmark_change* _tmp26_;
					_tmp23_ = self->priv->_board;
					_tmp24_ = earmark;
					_tmp25_ = earmark;
					_tmp26_ = earmark;
					sudoku_board_disable_earmark (_tmp23_, (*_tmp24_).row, (*_tmp25_).col, (*_tmp26_).number);
				} else {
					SudokuBoard* _tmp27_;
					SudokuGameearmark_change* _tmp28_;
					SudokuGameearmark_change* _tmp29_;
					SudokuGameearmark_change* _tmp30_;
					_tmp27_ = self->priv->_board;
					_tmp28_ = earmark;
					_tmp29_ = earmark;
					_tmp30_ = earmark;
					sudoku_board_enable_earmark (_tmp27_, (*_tmp28_).row, (*_tmp29_).col, (*_tmp30_).number);
				}
				_sudoku_game_earmark_change_free0 (earmark);
			}
		}
	}
	_tmp31_ = self->priv->stack_head_index;
	self->priv->stack_head_index = _tmp31_ - 1;
	_tmp32_ = self->priv->stack;
	_tmp33_ = gee_abstract_list_get ((GeeAbstractList*) _tmp32_, self->priv->stack_head_index + 1);
	_tmp34_ = (SudokuGamestack_item*) _tmp33_;
	g_signal_emit (self, sudoku_game_signals[SUDOKU_GAME_ACTION_COMPLETED_SIGNAL], 0, _tmp34_->action);
	_sudoku_game_stack_item_unref0 (_tmp34_);
	_g_object_unref0 (earmark_iterator);
	_g_object_unref0 (value_iterator);
	_sudoku_game_stack_item_unref0 (changes);
}

void
sudoku_game_redo (SudokuGame* self)
{
	gint _tmp0_;
	SudokuGamestack_item* changes = NULL;
	GeeArrayList* _tmp1_;
	gpointer _tmp2_;
	GeeListIterator* earmark_iterator = NULL;
	SudokuGamestack_item* _tmp3_;
	GeeArrayList* _tmp4_;
	GeeListIterator* _tmp5_;
	GeeListIterator* value_iterator = NULL;
	SudokuGamestack_item* _tmp20_;
	GeeArrayList* _tmp21_;
	GeeListIterator* _tmp22_;
	GeeArrayList* _tmp32_;
	gpointer _tmp33_;
	SudokuGamestack_item* _tmp34_;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->priv->stack_head_index;
	self->priv->stack_head_index = _tmp0_ + 1;
	_tmp1_ = self->priv->stack;
	_tmp2_ = gee_abstract_list_get ((GeeAbstractList*) _tmp1_, self->priv->stack_head_index);
	changes = (SudokuGamestack_item*) _tmp2_;
	_tmp3_ = changes;
	_tmp4_ = _tmp3_->earmarks;
	_tmp5_ = gee_abstract_list_list_iterator ((GeeAbstractList*) _tmp4_);
	earmark_iterator = _tmp5_;
	{
		gboolean has_next = FALSE;
		GeeListIterator* _tmp6_;
		_tmp6_ = earmark_iterator;
		has_next = gee_iterator_next ((GeeIterator*) _tmp6_);
		{
			gboolean _tmp7_ = FALSE;
			_tmp7_ = TRUE;
			while (TRUE) {
				SudokuGameearmark_change* earmark = NULL;
				GeeListIterator* _tmp9_;
				gpointer _tmp10_;
				SudokuGameearmark_change* _tmp11_;
				if (!_tmp7_) {
					GeeListIterator* _tmp8_;
					_tmp8_ = earmark_iterator;
					has_next = gee_iterator_next ((GeeIterator*) _tmp8_);
				}
				_tmp7_ = FALSE;
				if (!has_next) {
					break;
				}
				_tmp9_ = earmark_iterator;
				_tmp10_ = gee_iterator_get ((GeeIterator*) _tmp9_);
				earmark = (SudokuGameearmark_change*) _tmp10_;
				_tmp11_ = earmark;
				if ((*_tmp11_).enabled) {
					SudokuBoard* _tmp12_;
					SudokuGameearmark_change* _tmp13_;
					SudokuGameearmark_change* _tmp14_;
					SudokuGameearmark_change* _tmp15_;
					_tmp12_ = self->priv->_board;
					_tmp13_ = earmark;
					_tmp14_ = earmark;
					_tmp15_ = earmark;
					sudoku_board_enable_earmark (_tmp12_, (*_tmp13_).row, (*_tmp14_).col, (*_tmp15_).number);
				} else {
					SudokuBoard* _tmp16_;
					SudokuGameearmark_change* _tmp17_;
					SudokuGameearmark_change* _tmp18_;
					SudokuGameearmark_change* _tmp19_;
					_tmp16_ = self->priv->_board;
					_tmp17_ = earmark;
					_tmp18_ = earmark;
					_tmp19_ = earmark;
					sudoku_board_disable_earmark (_tmp16_, (*_tmp17_).row, (*_tmp18_).col, (*_tmp19_).number);
				}
				_sudoku_game_earmark_change_free0 (earmark);
			}
		}
	}
	_tmp20_ = changes;
	_tmp21_ = _tmp20_->values;
	_tmp22_ = gee_abstract_list_list_iterator ((GeeAbstractList*) _tmp21_);
	value_iterator = _tmp22_;
	{
		gboolean has_next = FALSE;
		GeeListIterator* _tmp23_;
		_tmp23_ = value_iterator;
		has_next = gee_iterator_next ((GeeIterator*) _tmp23_);
		{
			gboolean _tmp24_ = FALSE;
			_tmp24_ = TRUE;
			while (TRUE) {
				SudokuGamevalue_change* val = NULL;
				GeeListIterator* _tmp26_;
				gpointer _tmp27_;
				SudokuBoard* _tmp28_;
				SudokuGamevalue_change* _tmp29_;
				SudokuGamevalue_change* _tmp30_;
				SudokuGamevalue_change* _tmp31_;
				if (!_tmp24_) {
					GeeListIterator* _tmp25_;
					_tmp25_ = value_iterator;
					has_next = gee_iterator_next ((GeeIterator*) _tmp25_);
				}
				_tmp24_ = FALSE;
				if (!has_next) {
					break;
				}
				_tmp26_ = value_iterator;
				_tmp27_ = gee_iterator_get ((GeeIterator*) _tmp26_);
				val = (SudokuGamevalue_change*) _tmp27_;
				_tmp28_ = self->priv->_board;
				_tmp29_ = val;
				_tmp30_ = val;
				_tmp31_ = val;
				sudoku_board_set (_tmp28_, (*_tmp29_).row, (*_tmp30_).col, (*_tmp31_).new_val);
				_sudoku_game_value_change_free0 (val);
			}
		}
	}
	_tmp32_ = self->priv->stack;
	_tmp33_ = gee_abstract_list_get ((GeeAbstractList*) _tmp32_, self->priv->stack_head_index);
	_tmp34_ = (SudokuGamestack_item*) _tmp33_;
	g_signal_emit (self, sudoku_game_signals[SUDOKU_GAME_ACTION_COMPLETED_SIGNAL], 0, _tmp34_->action);
	_sudoku_game_stack_item_unref0 (_tmp34_);
	_g_object_unref0 (value_iterator);
	_g_object_unref0 (earmark_iterator);
	_sudoku_game_stack_item_unref0 (changes);
}

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

void
sudoku_game_enable_all_earmark_possibilities (SudokuGame* self)
{
	gint* cells = NULL;
	SudokuBoard* _tmp0_;
	gint _tmp1_ = 0;
	gint _tmp2_ = 0;
	gint* _tmp3_;
	gint cells_length1;
	gint cells_length2;
	SudokuGamestack_item* new_stack_item = NULL;
	SudokuGamestack_item* _tmp4_;
	gint head_backup = 0;
	GeeArrayList* stack_backup = NULL;
	GeeArrayList* _tmp5_;
	GeeArrayList* _tmp6_;
	SudokuGamestack_item* _tmp7_;
	SudokuGamestack_item* _tmp31_;
	GeeArrayList* _tmp32_;
	gint _tmp33_;
	gint _tmp34_;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->priv->_board;
	_tmp3_ = sudoku_board_get_cells (_tmp0_, &_tmp1_, &_tmp2_);
	cells = _tmp3_;
	cells_length1 = _tmp1_;
	cells_length2 = _tmp2_;
	_tmp4_ = sudoku_game_stack_item_new (STACK_ACTION_ENABLE_ALL_EARMARK_POSSIBILITIES);
	new_stack_item = _tmp4_;
	head_backup = self->priv->stack_head_index;
	_tmp5_ = self->priv->stack;
	_tmp6_ = _g_object_ref0 (_tmp5_);
	stack_backup = _tmp6_;
	_tmp7_ = new_stack_item;
	sudoku_game_add_to_stack (self, _tmp7_);
	{
		gint row = 0;
		row = 0;
		{
			gboolean _tmp8_ = FALSE;
			_tmp8_ = TRUE;
			while (TRUE) {
				SudokuBoard* _tmp10_;
				gint _tmp11_;
				gint _tmp12_;
				if (!_tmp8_) {
					gint _tmp9_;
					_tmp9_ = row;
					row = _tmp9_ + 1;
				}
				_tmp8_ = FALSE;
				_tmp10_ = self->priv->_board;
				_tmp11_ = sudoku_board_get_rows (_tmp10_);
				_tmp12_ = _tmp11_;
				if (!(row < _tmp12_)) {
					break;
				}
				{
					gint col = 0;
					col = 0;
					{
						gboolean _tmp13_ = FALSE;
						_tmp13_ = TRUE;
						while (TRUE) {
							SudokuBoard* _tmp15_;
							gint _tmp16_;
							gint _tmp17_;
							gint* _tmp18_;
							gint _tmp18__length1;
							gint _tmp18__length2;
							gint _tmp19_;
							gboolean* marks = NULL;
							SudokuBoard* _tmp20_;
							gint _tmp21_ = 0;
							gboolean* _tmp22_;
							gint marks_length1;
							gint _marks_size_;
							if (!_tmp13_) {
								gint _tmp14_;
								_tmp14_ = col;
								col = _tmp14_ + 1;
							}
							_tmp13_ = FALSE;
							_tmp15_ = self->priv->_board;
							_tmp16_ = sudoku_board_get_cols (_tmp15_);
							_tmp17_ = _tmp16_;
							if (!(col < _tmp17_)) {
								break;
							}
							_tmp18_ = cells;
							_tmp18__length1 = cells_length1;
							_tmp18__length2 = cells_length2;
							_tmp19_ = _tmp18_[(row * _tmp18__length2) + col];
							if (_tmp19_ != 0) {
								continue;
							}
							_tmp20_ = self->priv->_board;
							_tmp22_ = sudoku_board_get_possibilities_as_bool_array (_tmp20_, row, col, &_tmp21_);
							marks = _tmp22_;
							marks_length1 = _tmp21_;
							_marks_size_ = marks_length1;
							{
								gint num = 0;
								num = 1;
								{
									gboolean _tmp23_ = FALSE;
									_tmp23_ = TRUE;
									while (TRUE) {
										gboolean _tmp25_ = FALSE;
										gboolean* _tmp26_;
										gint _tmp26__length1;
										gboolean _tmp27_;
										if (!_tmp23_) {
											gint _tmp24_;
											_tmp24_ = num;
											num = _tmp24_ + 1;
										}
										_tmp23_ = FALSE;
										if (!(num <= 9)) {
											break;
										}
										_tmp26_ = marks;
										_tmp26__length1 = marks_length1;
										_tmp27_ = _tmp26_[num - 1];
										if (_tmp27_) {
											SudokuBoard* _tmp28_;
											_tmp28_ = self->priv->_board;
											_tmp25_ = !sudoku_board_is_earmark_enabled (_tmp28_, row, col, num);
										} else {
											_tmp25_ = FALSE;
										}
										if (_tmp25_) {
											SudokuGamestack_item* _tmp29_;
											SudokuBoard* _tmp30_;
											_tmp29_ = new_stack_item;
											sudoku_game_add_earmark_step (self, _tmp29_, row, col, num, TRUE);
											_tmp30_ = self->priv->_board;
											sudoku_board_enable_earmark (_tmp30_, row, col, num);
										}
									}
								}
							}
							marks = (g_free (marks), NULL);
						}
					}
				}
			}
		}
	}
	_tmp31_ = new_stack_item;
	_tmp32_ = _tmp31_->earmarks;
	_tmp33_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) _tmp32_);
	_tmp34_ = _tmp33_;
	if (_tmp34_ == 0) {
		GeeArrayList* _tmp35_;
		GeeArrayList* _tmp36_;
		_tmp35_ = stack_backup;
		_tmp36_ = _g_object_ref0 (_tmp35_);
		_g_object_unref0 (self->priv->stack);
		self->priv->stack = _tmp36_;
		self->priv->stack_head_index = head_backup;
	} else {
		SudokuGamestack_item* _tmp37_;
		_tmp37_ = new_stack_item;
		g_signal_emit (self, sudoku_game_signals[SUDOKU_GAME_ACTION_COMPLETED_SIGNAL], 0, _tmp37_->action);
	}
	_g_object_unref0 (stack_backup);
	_sudoku_game_stack_item_unref0 (new_stack_item);
	cells = (g_free (cells), NULL);
}

void
sudoku_game_stack_slice (SudokuGame* self)
{
	GeeArrayList* _tmp0_;
	gint _tmp1_;
	gint _tmp2_;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->priv->stack;
	_tmp1_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) _tmp0_);
	_tmp2_ = _tmp1_;
	if (self->priv->stack_head_index == (_tmp2_ - 1)) {
		return;
	}
	if (self->priv->stack_head_index == -1) {
		GeeArrayList* _tmp3_;
		_tmp3_ = self->priv->stack;
		gee_abstract_collection_clear ((GeeAbstractCollection*) _tmp3_);
	} else {
		GeeArrayList* _tmp4_;
		GeeList* _tmp5_;
		_tmp4_ = self->priv->stack;
		_tmp5_ = gee_abstract_list_slice ((GeeAbstractList*) _tmp4_, 0, self->priv->stack_head_index + 1);
		_g_object_unref0 (self->priv->stack);
		self->priv->stack = G_TYPE_CHECK_INSTANCE_CAST (_tmp5_, GEE_TYPE_ARRAY_LIST, GeeArrayList);
	}
}

gdouble
sudoku_game_get_total_time_played (SudokuGame* self)
{
	SudokuBoard* _tmp0_;
	gdouble _tmp1_;
	gdouble _tmp2_;
	GTimer* _tmp3_;
	gdouble result;
	g_return_val_if_fail (self != NULL, -1.0);
	_tmp0_ = self->priv->_board;
	_tmp1_ = sudoku_board_get_previous_played_time (_tmp0_);
	_tmp2_ = _tmp1_;
	_tmp3_ = self->priv->timer;
	result = _tmp2_ + g_timer_elapsed (_tmp3_, NULL);
	return result;
}

gdouble
sudoku_game_get_elapsed_time (SudokuGame* self)
{
	GTimer* _tmp0_;
	gdouble result;
	g_return_val_if_fail (self != NULL, -1.0);
	_tmp0_ = self->priv->timer;
	result = g_timer_elapsed (_tmp0_, NULL);
	return result;
}

void
sudoku_game_start_clock (SudokuGame* self)
{
	GTimer* _tmp0_;
	GTimer* _tmp2_;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->priv->timer;
	if (_tmp0_ == NULL) {
		GTimer* _tmp1_;
		_tmp1_ = g_timer_new ();
		_g_timer_destroy0 (self->priv->timer);
		self->priv->timer = _tmp1_;
	} else {
		sudoku_game_stop_clock (self);
	}
	_tmp2_ = self->priv->timer;
	g_timer_start (_tmp2_);
	sudoku_game_start_clock_tick (self);
}

void
sudoku_game_stop_clock (SudokuGame* self)
{
	gboolean _tmp0_ = FALSE;
	GTimer* _tmp1_;
	GTimer* _tmp2_;
	g_return_if_fail (self != NULL);
	_tmp1_ = self->priv->timer;
	if (_tmp1_ == NULL) {
		_tmp0_ = TRUE;
	} else {
		_tmp0_ = self->priv->clock_tick_timeout == ((guint) 0);
	}
	if (_tmp0_) {
		return;
	}
	_tmp2_ = self->priv->timer;
	g_timer_stop (_tmp2_);
	g_source_remove (self->priv->clock_tick_timeout);
	self->priv->clock_tick_timeout = (guint) 0;
	g_signal_emit (self, sudoku_game_signals[SUDOKU_GAME_TICK_SIGNAL], 0);
}

void
sudoku_game_resume_clock (SudokuGame* self)
{
	gboolean _tmp0_ = FALSE;
	GTimer* _tmp1_;
	GTimer* _tmp2_;
	g_return_if_fail (self != NULL);
	_tmp1_ = self->priv->timer;
	if (_tmp1_ == NULL) {
		_tmp0_ = TRUE;
	} else {
		_tmp0_ = self->priv->clock_tick_timeout != ((guint) 0);
	}
	if (_tmp0_) {
		return;
	}
	_tmp2_ = self->priv->timer;
	g_timer_continue (_tmp2_);
	sudoku_game_start_clock_tick (self);
}

static Block2Data*
block2_data_ref (Block2Data* _data2_)
{
	g_atomic_int_inc (&_data2_->_ref_count_);
	return _data2_;
}

static void
block2_data_unref (void * _userdata_)
{
	Block2Data* _data2_;
	_data2_ = (Block2Data*) _userdata_;
	if (g_atomic_int_dec_and_test (&_data2_->_ref_count_)) {
		g_slice_free (Block2Data, _data2_);
	}
}

static gboolean
__lambda4_ (Block2Data* _data2_)
{
	gboolean result;
	g_signal_emit (_data2_->weak_this, sudoku_game_signals[SUDOKU_GAME_TICK_SIGNAL], 0);
	result = G_SOURCE_CONTINUE;
	return result;
}

static gboolean
___lambda4__gsource_func (gpointer self)
{
	gboolean result;
	result = __lambda4_ (self);
	return result;
}

static void
sudoku_game_start_clock_tick (SudokuGame* _this)
{
	Block2Data* _data2_;
	g_return_if_fail (_this != NULL);
	_data2_ = g_slice_new0 (Block2Data);
	_data2_->_ref_count_ = 1;
	_data2_->weak_this = _this;
	_data2_->weak_this->priv->clock_tick_timeout = g_timeout_add_seconds_full (G_PRIORITY_DEFAULT, (guint) 1, ___lambda4__gsource_func, block2_data_ref (_data2_), block2_data_unref);
	g_source_set_name_by_id (_data2_->weak_this->priv->clock_tick_timeout, "[gnome-sudoku] clock_tick");
	block2_data_unref (_data2_);
	_data2_ = NULL;
}

void
sudoku_game_auto_complete (SudokuGame* self)
{
	gint* cells = NULL;
	SudokuBoard* _tmp0_;
	gint _tmp1_ = 0;
	gint _tmp2_ = 0;
	gint* _tmp3_;
	gint cells_length1;
	gint cells_length2;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->priv->_board;
	_tmp3_ = sudoku_board_get_cells (_tmp0_, &_tmp1_, &_tmp2_);
	cells = _tmp3_;
	cells_length1 = _tmp1_;
	cells_length2 = _tmp2_;
	{
		gint row = 0;
		row = 0;
		{
			gboolean _tmp4_ = FALSE;
			_tmp4_ = TRUE;
			while (TRUE) {
				if (!_tmp4_) {
					gint _tmp5_;
					_tmp5_ = row;
					row = _tmp5_ + 1;
				}
				_tmp4_ = FALSE;
				if (!(row < 9)) {
					break;
				}
				{
					gint col = 0;
					col = 0;
					{
						gboolean _tmp6_ = FALSE;
						_tmp6_ = TRUE;
						while (TRUE) {
							gint solution = 0;
							SudokuBoard* _tmp8_;
							gint* _tmp9_;
							gint _tmp9__length1;
							gint _tmp9__length2;
							gint _tmp10_;
							if (!_tmp6_) {
								gint _tmp7_;
								_tmp7_ = col;
								col = _tmp7_ + 1;
							}
							_tmp6_ = FALSE;
							if (!(col < 9)) {
								break;
							}
							_tmp8_ = self->priv->_board;
							solution = sudoku_board_get_solution (_tmp8_, row, col);
							_tmp9_ = cells;
							_tmp9__length1 = cells_length1;
							_tmp9__length2 = cells_length2;
							_tmp10_ = _tmp9_[(row * _tmp9__length2) + col];
							if (_tmp10_ != solution) {
								sudoku_game_insert (self, row, col, solution);
							}
						}
					}
				}
			}
		}
	}
	cells = (g_free (cells), NULL);
}

static void
sudoku_game_real_dispose (GObject* base)
{
	SudokuGame * self;
	self = (SudokuGame*) base;
	G_OBJECT_CLASS (sudoku_game_parent_class)->dispose (G_TYPE_CHECK_INSTANCE_CAST (self, G_TYPE_OBJECT, GObject));
	sudoku_game_stop_clock (self);
}

SudokuBoard*
sudoku_game_get_board (SudokuGame* self)
{
	SudokuBoard* result;
	SudokuBoard* _tmp0_;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = self->priv->_board;
	result = _tmp0_;
	return result;
}

static void
sudoku_game_set_board (SudokuGame* self,
                       SudokuBoard* value)
{
	SudokuBoard* old_value;
	g_return_if_fail (self != NULL);
	old_value = sudoku_game_get_board (self);
	if (old_value != value) {
		SudokuBoard* _tmp0_;
		_tmp0_ = _g_object_ref0 (value);
		_g_object_unref0 (self->priv->_board);
		self->priv->_board = _tmp0_;
		g_object_notify_by_pspec ((GObject *) self, sudoku_game_properties[SUDOKU_GAME_BOARD_PROPERTY]);
	}
}

gboolean
sudoku_game_get_paused (SudokuGame* self)
{
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	result = self->priv->_paused;
	return result;
}

void
sudoku_game_set_paused (SudokuGame* self,
                        gboolean value)
{
	gboolean old_value;
	g_return_if_fail (self != NULL);
	old_value = sudoku_game_get_paused (self);
	if (old_value != value) {
		self->priv->_paused = value;
		g_object_notify_by_pspec ((GObject *) self, sudoku_game_properties[SUDOKU_GAME_PAUSED_PROPERTY]);
	}
}

static SudokuGamestack_item*
sudoku_game_stack_item_construct (GType object_type,
                                  StackAction _action)
{
	SudokuGamestack_item* self = NULL;
	GeeArrayList* _tmp0_;
	GeeArrayList* _tmp1_;
	self = (SudokuGamestack_item*) g_type_create_instance (object_type);
	self->action = _action;
	_tmp0_ = gee_array_list_new (SUDOKU_GAME_TYPE_EARMARK_CHANGE, (GBoxedCopyFunc) sudoku_game_earmark_change_dup, (GDestroyNotify) sudoku_game_earmark_change_free, NULL, NULL, NULL);
	_g_object_unref0 (self->earmarks);
	self->earmarks = _tmp0_;
	_tmp1_ = gee_array_list_new (SUDOKU_GAME_TYPE_VALUE_CHANGE, (GBoxedCopyFunc) sudoku_game_value_change_dup, (GDestroyNotify) sudoku_game_value_change_free, NULL, NULL, NULL);
	_g_object_unref0 (self->values);
	self->values = _tmp1_;
	return self;
}

static SudokuGamestack_item*
sudoku_game_stack_item_new (StackAction _action)
{
	return sudoku_game_stack_item_construct (SUDOKU_GAME_TYPE_STACK_ITEM, _action);
}

static void
sudoku_game_value_stack_item_init (GValue* value)
{
	value->data[0].v_pointer = NULL;
}

static void
sudoku_game_value_stack_item_free_value (GValue* value)
{
	if (value->data[0].v_pointer) {
		sudoku_game_stack_item_unref (value->data[0].v_pointer);
	}
}

static void
sudoku_game_value_stack_item_copy_value (const GValue* src_value,
                                         GValue* dest_value)
{
	if (src_value->data[0].v_pointer) {
		dest_value->data[0].v_pointer = sudoku_game_stack_item_ref (src_value->data[0].v_pointer);
	} else {
		dest_value->data[0].v_pointer = NULL;
	}
}

static gpointer
sudoku_game_value_stack_item_peek_pointer (const GValue* value)
{
	return value->data[0].v_pointer;
}

static gchar*
sudoku_game_value_stack_item_collect_value (GValue* value,
                                            guint n_collect_values,
                                            GTypeCValue* collect_values,
                                            guint collect_flags)
{
	if (collect_values[0].v_pointer) {
		SudokuGamestack_item * object;
		object = collect_values[0].v_pointer;
		if (object->parent_instance.g_class == NULL) {
			return g_strconcat ("invalid unclassed object pointer for value type `", G_VALUE_TYPE_NAME (value), "'", NULL);
		} else if (!g_value_type_compatible (G_TYPE_FROM_INSTANCE (object), G_VALUE_TYPE (value))) {
			return g_strconcat ("invalid object type `", g_type_name (G_TYPE_FROM_INSTANCE (object)), "' for value type `", G_VALUE_TYPE_NAME (value), "'", NULL);
		}
		value->data[0].v_pointer = sudoku_game_stack_item_ref (object);
	} else {
		value->data[0].v_pointer = NULL;
	}
	return NULL;
}

static gchar*
sudoku_game_value_stack_item_lcopy_value (const GValue* value,
                                          guint n_collect_values,
                                          GTypeCValue* collect_values,
                                          guint collect_flags)
{
	SudokuGamestack_item ** object_p;
	object_p = collect_values[0].v_pointer;
	if (!object_p) {
		return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value));
	}
	if (!value->data[0].v_pointer) {
		*object_p = NULL;
	} else if (collect_flags & G_VALUE_NOCOPY_CONTENTS) {
		*object_p = value->data[0].v_pointer;
	} else {
		*object_p = sudoku_game_stack_item_ref (value->data[0].v_pointer);
	}
	return NULL;
}

static GParamSpec*
sudoku_game_param_spec_stack_item (const gchar* name,
                                   const gchar* nick,
                                   const gchar* blurb,
                                   GType object_type,
                                   GParamFlags flags)
{
	SudokuGameParamSpecstack_item* spec;
	g_return_val_if_fail (g_type_is_a (object_type, SUDOKU_GAME_TYPE_STACK_ITEM), NULL);
	spec = g_param_spec_internal (G_TYPE_PARAM_OBJECT, name, nick, blurb, flags);
	G_PARAM_SPEC (spec)->value_type = object_type;
	return G_PARAM_SPEC (spec);
}

static gpointer
sudoku_game_value_get_stack_item (const GValue* value)
{
	g_return_val_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, SUDOKU_GAME_TYPE_STACK_ITEM), NULL);
	return value->data[0].v_pointer;
}

static void
sudoku_game_value_set_stack_item (GValue* value,
                                  gpointer v_object)
{
	SudokuGamestack_item * old;
	g_return_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, SUDOKU_GAME_TYPE_STACK_ITEM));
	old = value->data[0].v_pointer;
	if (v_object) {
		g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (v_object, SUDOKU_GAME_TYPE_STACK_ITEM));
		g_return_if_fail (g_value_type_compatible (G_TYPE_FROM_INSTANCE (v_object), G_VALUE_TYPE (value)));
		value->data[0].v_pointer = v_object;
		sudoku_game_stack_item_ref (value->data[0].v_pointer);
	} else {
		value->data[0].v_pointer = NULL;
	}
	if (old) {
		sudoku_game_stack_item_unref (old);
	}
}

static void
sudoku_game_value_take_stack_item (GValue* value,
                                   gpointer v_object)
{
	SudokuGamestack_item * old;
	g_return_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, SUDOKU_GAME_TYPE_STACK_ITEM));
	old = value->data[0].v_pointer;
	if (v_object) {
		g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (v_object, SUDOKU_GAME_TYPE_STACK_ITEM));
		g_return_if_fail (g_value_type_compatible (G_TYPE_FROM_INSTANCE (v_object), G_VALUE_TYPE (value)));
		value->data[0].v_pointer = v_object;
	} else {
		value->data[0].v_pointer = NULL;
	}
	if (old) {
		sudoku_game_stack_item_unref (old);
	}
}

static void
sudoku_game_stack_item_class_init (SudokuGamestack_itemClass * klass,
                                   gpointer klass_data)
{
	sudoku_game_stack_item_parent_class = g_type_class_peek_parent (klass);
	((SudokuGamestack_itemClass *) klass)->finalize = sudoku_game_stack_item_finalize;
}

static void
sudoku_game_stack_item_instance_init (SudokuGamestack_item * self,
                                      gpointer klass)
{
	self->ref_count = 1;
}

static void
sudoku_game_stack_item_finalize (SudokuGamestack_item * obj)
{
	SudokuGamestack_item * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, SUDOKU_GAME_TYPE_STACK_ITEM, SudokuGamestack_item);
	g_signal_handlers_destroy (self);
	_g_object_unref0 (self->earmarks);
	_g_object_unref0 (self->values);
}

static GType
sudoku_game_stack_item_get_type_once (void)
{
	static const GTypeValueTable g_define_type_value_table = { sudoku_game_value_stack_item_init, sudoku_game_value_stack_item_free_value, sudoku_game_value_stack_item_copy_value, sudoku_game_value_stack_item_peek_pointer, "p", sudoku_game_value_stack_item_collect_value, "p", sudoku_game_value_stack_item_lcopy_value };
	static const GTypeInfo g_define_type_info = { sizeof (SudokuGamestack_itemClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) sudoku_game_stack_item_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (SudokuGamestack_item), 0, (GInstanceInitFunc) sudoku_game_stack_item_instance_init, &g_define_type_value_table };
	static const GTypeFundamentalInfo g_define_type_fundamental_info = { (G_TYPE_FLAG_CLASSED | G_TYPE_FLAG_INSTANTIATABLE | G_TYPE_FLAG_DERIVABLE | G_TYPE_FLAG_DEEP_DERIVABLE) };
	GType sudoku_game_stack_item_type_id;
	sudoku_game_stack_item_type_id = g_type_register_fundamental (g_type_fundamental_next (), "SudokuGamestack_item", &g_define_type_info, &g_define_type_fundamental_info, 0);
	return sudoku_game_stack_item_type_id;
}

static GType
sudoku_game_stack_item_get_type (void)
{
	static volatile gsize sudoku_game_stack_item_type_id__once = 0;
	if (g_once_init_enter (&sudoku_game_stack_item_type_id__once)) {
		GType sudoku_game_stack_item_type_id;
		sudoku_game_stack_item_type_id = sudoku_game_stack_item_get_type_once ();
		g_once_init_leave (&sudoku_game_stack_item_type_id__once, sudoku_game_stack_item_type_id);
	}
	return sudoku_game_stack_item_type_id__once;
}

static gpointer
sudoku_game_stack_item_ref (gpointer instance)
{
	SudokuGamestack_item * self;
	self = instance;
	g_atomic_int_inc (&self->ref_count);
	return instance;
}

static void
sudoku_game_stack_item_unref (gpointer instance)
{
	SudokuGamestack_item * self;
	self = instance;
	if (g_atomic_int_dec_and_test (&self->ref_count)) {
		SUDOKU_GAME_STACK_ITEM_GET_CLASS (self)->finalize (self);
		g_type_free_instance ((GTypeInstance *) self);
	}
}

static SudokuGameearmark_change*
sudoku_game_earmark_change_dup (const SudokuGameearmark_change* self)
{
	SudokuGameearmark_change* dup;
	dup = g_new0 (SudokuGameearmark_change, 1);
	memcpy (dup, self, sizeof (SudokuGameearmark_change));
	return dup;
}

static void
sudoku_game_earmark_change_free (SudokuGameearmark_change* self)
{
	g_free (self);
}

static GType
sudoku_game_earmark_change_get_type_once (void)
{
	GType sudoku_game_earmark_change_type_id;
	sudoku_game_earmark_change_type_id = g_boxed_type_register_static ("SudokuGameearmark_change", (GBoxedCopyFunc) sudoku_game_earmark_change_dup, (GBoxedFreeFunc) sudoku_game_earmark_change_free);
	return sudoku_game_earmark_change_type_id;
}

static GType
sudoku_game_earmark_change_get_type (void)
{
	static volatile gsize sudoku_game_earmark_change_type_id__once = 0;
	if (g_once_init_enter (&sudoku_game_earmark_change_type_id__once)) {
		GType sudoku_game_earmark_change_type_id;
		sudoku_game_earmark_change_type_id = sudoku_game_earmark_change_get_type_once ();
		g_once_init_leave (&sudoku_game_earmark_change_type_id__once, sudoku_game_earmark_change_type_id);
	}
	return sudoku_game_earmark_change_type_id__once;
}

static SudokuGamevalue_change*
sudoku_game_value_change_dup (const SudokuGamevalue_change* self)
{
	SudokuGamevalue_change* dup;
	dup = g_new0 (SudokuGamevalue_change, 1);
	memcpy (dup, self, sizeof (SudokuGamevalue_change));
	return dup;
}

static void
sudoku_game_value_change_free (SudokuGamevalue_change* self)
{
	g_free (self);
}

static GType
sudoku_game_value_change_get_type_once (void)
{
	GType sudoku_game_value_change_type_id;
	sudoku_game_value_change_type_id = g_boxed_type_register_static ("SudokuGamevalue_change", (GBoxedCopyFunc) sudoku_game_value_change_dup, (GBoxedFreeFunc) sudoku_game_value_change_free);
	return sudoku_game_value_change_type_id;
}

static GType
sudoku_game_value_change_get_type (void)
{
	static volatile gsize sudoku_game_value_change_type_id__once = 0;
	if (g_once_init_enter (&sudoku_game_value_change_type_id__once)) {
		GType sudoku_game_value_change_type_id;
		sudoku_game_value_change_type_id = sudoku_game_value_change_get_type_once ();
		g_once_init_leave (&sudoku_game_value_change_type_id__once, sudoku_game_value_change_type_id);
	}
	return sudoku_game_value_change_type_id__once;
}

static void
sudoku_game_class_init (SudokuGameClass * klass,
                        gpointer klass_data)
{
	sudoku_game_parent_class = g_type_class_peek_parent (klass);
	g_type_class_adjust_private_offset (klass, &SudokuGame_private_offset);
	((GObjectClass *) klass)->dispose = (void (*) (GObject*)) sudoku_game_real_dispose;
	G_OBJECT_CLASS (klass)->get_property = _vala_sudoku_game_get_property;
	G_OBJECT_CLASS (klass)->set_property = _vala_sudoku_game_set_property;
	G_OBJECT_CLASS (klass)->finalize = sudoku_game_finalize;
	g_object_class_install_property (G_OBJECT_CLASS (klass), SUDOKU_GAME_BOARD_PROPERTY, sudoku_game_properties[SUDOKU_GAME_BOARD_PROPERTY] = g_param_spec_object ("board", "board", "board", TYPE_SUDOKU_BOARD, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
	g_object_class_install_property (G_OBJECT_CLASS (klass), SUDOKU_GAME_PAUSED_PROPERTY, sudoku_game_properties[SUDOKU_GAME_PAUSED_PROPERTY] = g_param_spec_boolean ("paused", "paused", "paused", FALSE, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE | G_PARAM_WRITABLE));
	sudoku_game_signals[SUDOKU_GAME_TICK_SIGNAL] = g_signal_new ("tick", TYPE_SUDOKU_GAME, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
	sudoku_game_signals[SUDOKU_GAME_ACTION_COMPLETED_SIGNAL] = g_signal_new ("action-completed", TYPE_SUDOKU_GAME, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__ENUM, G_TYPE_NONE, 1, TYPE_STACK_ACTION);
}

static void
sudoku_game_instance_init (SudokuGame * self,
                           gpointer klass)
{
	self->priv = sudoku_game_get_instance_private (self);
	self->priv->_paused = FALSE;
	self->priv->stack_head_index = -1;
}

static void
sudoku_game_finalize (GObject * obj)
{
	SudokuGame * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, TYPE_SUDOKU_GAME, SudokuGame);
	_g_object_unref0 (self->priv->_board);
	_g_timer_destroy0 (self->priv->timer);
	_g_object_unref0 (self->priv->stack);
	G_OBJECT_CLASS (sudoku_game_parent_class)->finalize (obj);
}

static GType
sudoku_game_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (SudokuGameClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) sudoku_game_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (SudokuGame), 0, (GInstanceInitFunc) sudoku_game_instance_init, NULL };
	GType sudoku_game_type_id;
	sudoku_game_type_id = g_type_register_static (G_TYPE_OBJECT, "SudokuGame", &g_define_type_info, 0);
	SudokuGame_private_offset = g_type_add_instance_private (sudoku_game_type_id, sizeof (SudokuGamePrivate));
	return sudoku_game_type_id;
}

GType
sudoku_game_get_type (void)
{
	static volatile gsize sudoku_game_type_id__once = 0;
	if (g_once_init_enter (&sudoku_game_type_id__once)) {
		GType sudoku_game_type_id;
		sudoku_game_type_id = sudoku_game_get_type_once ();
		g_once_init_leave (&sudoku_game_type_id__once, sudoku_game_type_id);
	}
	return sudoku_game_type_id__once;
}

static void
_vala_sudoku_game_get_property (GObject * object,
                                guint property_id,
                                GValue * value,
                                GParamSpec * pspec)
{
	SudokuGame * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (object, TYPE_SUDOKU_GAME, SudokuGame);
	switch (property_id) {
		case SUDOKU_GAME_BOARD_PROPERTY:
		g_value_set_object (value, sudoku_game_get_board (self));
		break;
		case SUDOKU_GAME_PAUSED_PROPERTY:
		g_value_set_boolean (value, sudoku_game_get_paused (self));
		break;
		default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
	}
}

static void
_vala_sudoku_game_set_property (GObject * object,
                                guint property_id,
                                const GValue * value,
                                GParamSpec * pspec)
{
	SudokuGame * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (object, TYPE_SUDOKU_GAME, SudokuGame);
	switch (property_id) {
		case SUDOKU_GAME_BOARD_PROPERTY:
		sudoku_game_set_board (self, g_value_get_object (value));
		break;
		case SUDOKU_GAME_PAUSED_PROPERTY:
		sudoku_game_set_paused (self, g_value_get_boolean (value));
		break;
		default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
	}
}

gboolean
stack_action_is_single_value_change (StackAction self)
{
	gboolean result;
	switch (self) {
		case STACK_ACTION_INSERT:
		case STACK_ACTION_REMOVE:
		case STACK_ACTION_INSERT_AND_DISABLE_RELATED_EARMARKS:
		{
			result = TRUE;
			return result;
		}
		default:
		{
			result = FALSE;
			return result;
		}
	}
}

gboolean
stack_action_is_single_earmarks_change (StackAction self)
{
	gboolean result;
	switch (self) {
		case STACK_ACTION_ENABLE_EARMARK:
		case STACK_ACTION_DISABLE_EARMARK:
		case STACK_ACTION_DISABLE_ALL_EARMARKS:
		{
			result = TRUE;
			return result;
		}
		default:
		{
			result = FALSE;
			return result;
		}
	}
}

static GType
stack_action_get_type_once (void)
{
	static const GEnumValue values[] = {{STACK_ACTION_NONE, "STACK_ACTION_NONE", "none"}, {STACK_ACTION_INSERT, "STACK_ACTION_INSERT", "insert"}, {STACK_ACTION_REMOVE, "STACK_ACTION_REMOVE", "remove"}, {STACK_ACTION_ENABLE_EARMARK, "STACK_ACTION_ENABLE_EARMARK", "enable-earmark"}, {STACK_ACTION_DISABLE_EARMARK, "STACK_ACTION_DISABLE_EARMARK", "disable-earmark"}, {STACK_ACTION_DISABLE_ALL_EARMARKS, "STACK_ACTION_DISABLE_ALL_EARMARKS", "disable-all-earmarks"}, {STACK_ACTION_INSERT_AND_DISABLE_RELATED_EARMARKS, "STACK_ACTION_INSERT_AND_DISABLE_RELATED_EARMARKS", "insert-and-disable-related-earmarks"}, {STACK_ACTION_ENABLE_ALL_EARMARK_POSSIBILITIES, "STACK_ACTION_ENABLE_ALL_EARMARK_POSSIBILITIES", "enable-all-earmark-possibilities"}, {STACK_ACTION_CLEAR_BOARD, "STACK_ACTION_CLEAR_BOARD", "clear-board"}, {0, NULL, NULL}};
	GType stack_action_type_id;
	stack_action_type_id = g_enum_register_static ("StackAction", values);
	return stack_action_type_id;
}

GType
stack_action_get_type (void)
{
	static volatile gsize stack_action_type_id__once = 0;
	if (g_once_init_enter (&stack_action_type_id__once)) {
		GType stack_action_type_id;
		stack_action_type_id = stack_action_get_type_once ();
		g_once_init_leave (&stack_action_type_id__once, stack_action_type_id);
	}
	return stack_action_type_id__once;
}

static inline gpointer
_vala_memdup2 (gconstpointer mem,
               gsize byte_size)
{
	gpointer new_mem;
	if (mem && byte_size != 0) {
		new_mem = g_malloc (byte_size);
		memcpy (new_mem, mem, byte_size);
	} else {
		new_mem = NULL;
	}
	return new_mem;
}

