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

/* -*- Mode: vala; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
 *
 * Copyright (C) 2010-2014 Robert Ancell
 * Copyright (C) 2015-2016 Sahil Sareen
 *
 * This program is free software: you can redistribute it and/or modify it under
 * the terms of the GNU General Public License as published by the Free Software
 * Foundation, either version 3 of the License, or (at your option) any later
 * version. See http://www.gnu.org/copyleft/gpl.html the full text of the
 * license.
 */

#include "libchess.h"
#include <glib.h>
#include <glib-object.h>
#include <stdlib.h>
#include <string.h>
#include <glib/gi18n-lib.h>

#if !defined(VALA_STRICT_C)
#if !defined(__clang__) && defined(__GNUC__) && (__GNUC__ >= 14)
#pragma GCC diagnostic warning "-Wincompatible-pointer-types"
#elif defined(__clang__) && (__clang_major__ >= 16)
#pragma clang diagnostic ignored "-Wincompatible-function-pointer-types"
#pragma clang diagnostic ignored "-Wincompatible-pointer-types"
#endif
#endif

enum  {
	CHESS_GAME_0_PROPERTY,
	CHESS_GAME_IS_PAUSED_PROPERTY,
	CHESS_GAME_SHOULD_SHOW_PAUSED_OVERLAY_PROPERTY,
	CHESS_GAME_CURRENT_STATE_PROPERTY,
	CHESS_GAME_WHITE_PROPERTY,
	CHESS_GAME_BLACK_PROPERTY,
	CHESS_GAME_CURRENT_PLAYER_PROPERTY,
	CHESS_GAME_OPPONENT_PROPERTY,
	CHESS_GAME_CLOCK_PROPERTY,
	CHESS_GAME_N_MOVES_PROPERTY,
	CHESS_GAME_NUM_PROPERTIES
};
static GParamSpec* chess_game_properties[CHESS_GAME_NUM_PROPERTIES];
#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))
enum  {
	CHESS_GAME_TURN_STARTED_SIGNAL,
	CHESS_GAME_MOVED_SIGNAL,
	CHESS_GAME_PAUSED_SIGNAL,
	CHESS_GAME_UNPAUSED_SIGNAL,
	CHESS_GAME_UNDO_SIGNAL,
	CHESS_GAME_ENDED_SIGNAL,
	CHESS_GAME_NUM_SIGNALS
};
static guint chess_game_signals[CHESS_GAME_NUM_SIGNALS] = {0};
#define _vala_assert(expr, msg) if G_LIKELY (expr) ; else g_assertion_message_expr (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, msg);
#define _vala_return_if_fail(expr, msg) if G_LIKELY (expr) ; else { g_return_if_fail_warning (G_LOG_DOMAIN, G_STRFUNC, msg); return; }
#define _vala_return_val_if_fail(expr, msg, val) if G_LIKELY (expr) ; else { g_return_if_fail_warning (G_LOG_DOMAIN, G_STRFUNC, msg); return val; }
#define _vala_warn_if_fail(expr, msg) if G_LIKELY (expr) ; else g_warn_message (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, msg);

struct _ChessGamePrivate {
	gint hold_count;
	gboolean _is_paused;
	gboolean _should_show_paused_overlay;
	ChessClock* _clock;
};

static gint ChessGame_private_offset;
static gpointer chess_game_parent_class = NULL;

static void _g_object_unref0_ (gpointer var);
static inline void _g_list_free__g_object_unref0_ (GList* self);
static gboolean chess_game_do_move (ChessGame* self,
                             ChessPlayer* player,
                             const gchar* move,
                             gboolean apply);
static gboolean chess_game_move_cb (ChessGame* self,
                             ChessPlayer* player,
                             const gchar* move,
                             gboolean apply);
static gboolean _chess_game_move_cb_chess_player_do_move (ChessPlayer* _sender,
                                                   const gchar* move,
                                                   gboolean apply,
                                                   gpointer self);
static void chess_game_undo_cb (ChessGame* self,
                         ChessPlayer* player);
static void _chess_game_undo_cb_chess_player_do_undo (ChessPlayer* _sender,
                                               gpointer self);
static gboolean chess_game_resign_cb (ChessGame* self,
                               ChessPlayer* player);
static gboolean _chess_game_resign_cb_chess_player_do_resign (ChessPlayer* _sender,
                                                       gpointer self);
static void chess_game_claim_draw_cb (ChessGame* self);
static void _chess_game_claim_draw_cb_chess_player_do_claim_draw (ChessPlayer* _sender,
                                                           gpointer self);
static void chess_game_complete_move (ChessGame* self);
static gint chess_game_state_repeated_times (ChessGame* self,
                                      ChessState* s1);
static void chess_game_clock_expired_cb (ChessGame* self,
                                  ChessClock* clock);
static void _chess_game_clock_expired_cb_chess_clock_expired (ChessClock* _sender,
                                                       gpointer self);
static void chess_game_set_is_paused (ChessGame* self,
                               gboolean value);
static void chess_game_set_should_show_paused_overlay (ChessGame* self,
                                                gboolean value);
static void chess_game_finalize (GObject * obj);
static GType chess_game_get_type_once (void);
static void _vala_chess_game_get_property (GObject * object,
                                    guint property_id,
                                    GValue * value,
                                    GParamSpec * pspec);
static void _vala_chess_game_set_property (GObject * object,
                                    guint property_id,
                                    const GValue * value,
                                    GParamSpec * pspec);

static GType
chess_result_get_type_once (void)
{
	static const GEnumValue values[] = {{CHESS_RESULT_IN_PROGRESS, "CHESS_RESULT_IN_PROGRESS", "in-progress"}, {CHESS_RESULT_WHITE_WON, "CHESS_RESULT_WHITE_WON", "white-won"}, {CHESS_RESULT_BLACK_WON, "CHESS_RESULT_BLACK_WON", "black-won"}, {CHESS_RESULT_DRAW, "CHESS_RESULT_DRAW", "draw"}, {CHESS_RESULT_BUG, "CHESS_RESULT_BUG", "bug"}, {0, NULL, NULL}};
	GType chess_result_type_id;
	chess_result_type_id = g_enum_register_static ("ChessResult", values);
	return chess_result_type_id;
}

GType
chess_result_get_type (void)
{
	static volatile gsize chess_result_type_id__once = 0;
	if (g_once_init_enter (&chess_result_type_id__once)) {
		GType chess_result_type_id;
		chess_result_type_id = chess_result_get_type_once ();
		g_once_init_leave (&chess_result_type_id__once, chess_result_type_id);
	}
	return chess_result_type_id__once;
}

static GType
chess_rule_get_type_once (void)
{
	static const GEnumValue values[] = {{CHESS_RULE_UNKNOWN, "CHESS_RULE_UNKNOWN", "unknown"}, {CHESS_RULE_CHECKMATE, "CHESS_RULE_CHECKMATE", "checkmate"}, {CHESS_RULE_STALEMATE, "CHESS_RULE_STALEMATE", "stalemate"}, {CHESS_RULE_FIFTY_MOVES, "CHESS_RULE_FIFTY_MOVES", "fifty-moves"}, {CHESS_RULE_SEVENTY_FIVE_MOVES, "CHESS_RULE_SEVENTY_FIVE_MOVES", "seventy-five-moves"}, {CHESS_RULE_TIMEOUT, "CHESS_RULE_TIMEOUT", "timeout"}, {CHESS_RULE_THREE_FOLD_REPETITION, "CHESS_RULE_THREE_FOLD_REPETITION", "three-fold-repetition"}, {CHESS_RULE_FIVE_FOLD_REPETITION, "CHESS_RULE_FIVE_FOLD_REPETITION", "five-fold-repetition"}, {CHESS_RULE_INSUFFICIENT_MATERIAL, "CHESS_RULE_INSUFFICIENT_MATERIAL", "insufficient-material"}, {CHESS_RULE_RESIGN, "CHESS_RULE_RESIGN", "resign"}, {CHESS_RULE_ABANDONMENT, "CHESS_RULE_ABANDONMENT", "abandonment"}, {CHESS_RULE_DEATH, "CHESS_RULE_DEATH", "death"}, {CHESS_RULE_BUG, "CHESS_RULE_BUG", "bug"}, {0, NULL, NULL}};
	GType chess_rule_type_id;
	chess_rule_type_id = g_enum_register_static ("ChessRule", values);
	return chess_rule_type_id;
}

GType
chess_rule_get_type (void)
{
	static volatile gsize chess_rule_type_id__once = 0;
	if (g_once_init_enter (&chess_rule_type_id__once)) {
		GType chess_rule_type_id;
		chess_rule_type_id = chess_rule_get_type_once ();
		g_once_init_leave (&chess_rule_type_id__once, chess_rule_type_id);
	}
	return chess_rule_type_id__once;
}

static inline gpointer
chess_game_get_instance_private (ChessGame* self)
{
	return G_STRUCT_MEMBER_P (self, ChessGame_private_offset);
}

static void
_g_object_unref0_ (gpointer var)
{
	(var == NULL) ? NULL : (var = (g_object_unref (var), NULL));
}

static inline void
_g_list_free__g_object_unref0_ (GList* self)
{
	g_list_free_full (self, (GDestroyNotify) _g_object_unref0_);
}

static gboolean
_chess_game_move_cb_chess_player_do_move (ChessPlayer* _sender,
                                          const gchar* move,
                                          gboolean apply,
                                          gpointer self)
{
	gboolean result;
	result = chess_game_move_cb ((ChessGame*) self, _sender, move, apply);
	return result;
}

static void
_chess_game_undo_cb_chess_player_do_undo (ChessPlayer* _sender,
                                          gpointer self)
{
	chess_game_undo_cb ((ChessGame*) self, _sender);
}

static gboolean
_chess_game_resign_cb_chess_player_do_resign (ChessPlayer* _sender,
                                              gpointer self)
{
	gboolean result;
	result = chess_game_resign_cb ((ChessGame*) self, _sender);
	return result;
}

static void
_chess_game_claim_draw_cb_chess_player_do_claim_draw (ChessPlayer* _sender,
                                                      gpointer self)
{
	chess_game_claim_draw_cb ((ChessGame*) self);
}

ChessGame*
chess_game_construct (GType object_type,
                      const gchar* fen,
                      gchar** moves,
                      gint moves_length1,
                      GError** error)
{
	ChessGame * self = NULL;
	ChessState* _tmp0_;
	ChessPlayer* _tmp8_;
	ChessPlayer* _tmp9_;
	ChessPlayer* _tmp10_;
	ChessPlayer* _tmp11_;
	ChessPlayer* _tmp12_;
	ChessPlayer* _tmp13_;
	ChessPlayer* _tmp14_;
	ChessPlayer* _tmp15_;
	ChessPlayer* _tmp16_;
	ChessPlayer* _tmp17_;
	ChessPlayer* _tmp18_;
	ChessPlayer* _tmp19_;
	ChessPlayer* _tmp20_;
	ChessPlayer* _tmp21_;
	ChessPlayer* _tmp22_;
	ChessPlayer* _tmp23_;
	GError* _inner_error0_ = NULL;
	g_return_val_if_fail (fen != NULL, NULL);
	self = (ChessGame*) g_object_new (object_type, NULL);
	self->is_started = FALSE;
	_tmp0_ = chess_state_new (fen);
	self->move_stack = g_list_prepend (self->move_stack, _tmp0_);
	self->result = CHESS_RESULT_IN_PROGRESS;
	if (moves != NULL) {
		{
			gint i = 0;
			i = 0;
			{
				gboolean _tmp1_ = FALSE;
				_tmp1_ = TRUE;
				while (TRUE) {
					ChessPlayer* _tmp3_;
					ChessPlayer* _tmp4_;
					const gchar* _tmp5_;
					if (!_tmp1_) {
						gint _tmp2_;
						_tmp2_ = i;
						i = _tmp2_ + 1;
					}
					_tmp1_ = FALSE;
					if (!(i < moves_length1)) {
						break;
					}
					_tmp3_ = chess_game_get_current_player (self);
					_tmp4_ = _tmp3_;
					_tmp5_ = moves[i];
					if (!chess_game_do_move (self, _tmp4_, _tmp5_, TRUE)) {
						const gchar* _tmp6_;
						GError* _tmp7_;
						_tmp6_ = moves[i];
						_tmp7_ = g_error_new (PGN_ERROR, PGN_ERROR_LOAD_ERROR, _ ("Failed to load PGN: move %s is invalid."), _tmp6_);
						_inner_error0_ = _tmp7_;
						if (_inner_error0_->domain == PGN_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;
						}
					}
				}
			}
		}
	}
	_tmp8_ = chess_game_get_white (self);
	_tmp9_ = _tmp8_;
	g_signal_connect_object (_tmp9_, "do-move", (GCallback) _chess_game_move_cb_chess_player_do_move, self, 0);
	_tmp10_ = chess_game_get_white (self);
	_tmp11_ = _tmp10_;
	g_signal_connect_object (_tmp11_, "do-undo", (GCallback) _chess_game_undo_cb_chess_player_do_undo, self, 0);
	_tmp12_ = chess_game_get_white (self);
	_tmp13_ = _tmp12_;
	g_signal_connect_object (_tmp13_, "do-resign", (GCallback) _chess_game_resign_cb_chess_player_do_resign, self, 0);
	_tmp14_ = chess_game_get_white (self);
	_tmp15_ = _tmp14_;
	g_signal_connect_object (_tmp15_, "do-claim-draw", (GCallback) _chess_game_claim_draw_cb_chess_player_do_claim_draw, self, 0);
	_tmp16_ = chess_game_get_black (self);
	_tmp17_ = _tmp16_;
	g_signal_connect_object (_tmp17_, "do-move", (GCallback) _chess_game_move_cb_chess_player_do_move, self, 0);
	_tmp18_ = chess_game_get_black (self);
	_tmp19_ = _tmp18_;
	g_signal_connect_object (_tmp19_, "do-undo", (GCallback) _chess_game_undo_cb_chess_player_do_undo, self, 0);
	_tmp20_ = chess_game_get_black (self);
	_tmp21_ = _tmp20_;
	g_signal_connect_object (_tmp21_, "do-resign", (GCallback) _chess_game_resign_cb_chess_player_do_resign, self, 0);
	_tmp22_ = chess_game_get_black (self);
	_tmp23_ = _tmp22_;
	g_signal_connect_object (_tmp23_, "do-claim-draw", (GCallback) _chess_game_claim_draw_cb_chess_player_do_claim_draw, self, 0);
	return self;
}

ChessGame*
chess_game_new (const gchar* fen,
                gchar** moves,
                gint moves_length1,
                GError** error)
{
	return chess_game_construct (TYPE_CHESS_GAME, fen, moves, moves_length1, error);
}

static gboolean
chess_game_move_cb (ChessGame* self,
                    ChessPlayer* player,
                    const gchar* move,
                    gboolean apply)
{
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	g_return_val_if_fail (player != NULL, FALSE);
	g_return_val_if_fail (move != NULL, FALSE);
	if (!self->is_started) {
		result = FALSE;
		return result;
	}
	result = chess_game_do_move (self, player, move, apply);
	return result;
}

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

static gboolean
chess_game_do_move (ChessGame* self,
                    ChessPlayer* player,
                    const gchar* move,
                    gboolean apply)
{
	ChessPlayer* _tmp0_;
	ChessPlayer* _tmp1_;
	ChessState* state = NULL;
	ChessState* _tmp2_;
	ChessState* _tmp3_;
	ChessState* _tmp4_;
	ChessState* _tmp5_;
	gint _tmp6_;
	ChessState* _tmp7_;
	ChessState* _tmp8_;
	ChessState* _tmp9_;
	ChessState* _tmp10_;
	ChessMove* _tmp11_;
	ChessPiece* _tmp12_;
	ChessState* _tmp16_;
	ChessMove* _tmp17_;
	ChessPiece* _tmp18_;
	ChessState* _tmp19_;
	ChessMove* _tmp20_;
	ChessPiece* _tmp21_;
	ChessState* _tmp25_;
	ChessMove* _tmp26_;
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	g_return_val_if_fail (player != NULL, FALSE);
	_tmp0_ = chess_game_get_current_player (self);
	_tmp1_ = _tmp0_;
	if (player != _tmp1_) {
		result = FALSE;
		return result;
	}
	_tmp2_ = chess_game_get_current_state (self);
	_tmp3_ = _tmp2_;
	_tmp4_ = chess_state_copy (_tmp3_);
	state = _tmp4_;
	_tmp5_ = state;
	_tmp6_ = _tmp5_->number;
	_tmp5_->number = _tmp6_ + 1;
	_tmp7_ = state;
	if (!chess_state_move (_tmp7_, move, apply)) {
		result = FALSE;
		_g_object_unref0 (state);
		return result;
	}
	if (!apply) {
		result = TRUE;
		_g_object_unref0 (state);
		return result;
	}
	_tmp8_ = state;
	_tmp9_ = _g_object_ref0 (_tmp8_);
	self->move_stack = g_list_prepend (self->move_stack, _tmp9_);
	_tmp10_ = state;
	_tmp11_ = _tmp10_->last_move;
	_tmp12_ = _tmp11_->victim;
	if (_tmp12_ != NULL) {
		ChessState* _tmp13_;
		ChessMove* _tmp14_;
		ChessPiece* _tmp15_;
		_tmp13_ = state;
		_tmp14_ = _tmp13_->last_move;
		_tmp15_ = _tmp14_->victim;
		g_signal_emit_by_name (_tmp15_, "died");
	}
	_tmp16_ = state;
	_tmp17_ = _tmp16_->last_move;
	_tmp18_ = _tmp17_->piece;
	g_signal_emit_by_name (_tmp18_, "moved");
	_tmp19_ = state;
	_tmp20_ = _tmp19_->last_move;
	_tmp21_ = _tmp20_->castling_rook;
	if (_tmp21_ != NULL) {
		ChessState* _tmp22_;
		ChessMove* _tmp23_;
		ChessPiece* _tmp24_;
		_tmp22_ = state;
		_tmp23_ = _tmp22_->last_move;
		_tmp24_ = _tmp23_->castling_rook;
		g_signal_emit_by_name (_tmp24_, "moved");
	}
	_tmp25_ = state;
	_tmp26_ = _tmp25_->last_move;
	g_signal_emit (self, chess_game_signals[CHESS_GAME_MOVED_SIGNAL], 0, _tmp26_);
	chess_game_complete_move (self);
	result = TRUE;
	_g_object_unref0 (state);
	return result;
}

void
chess_game_add_hold (ChessGame* self)
{
	gint _tmp0_;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->priv->hold_count;
	self->priv->hold_count = _tmp0_ + 1;
}

void
chess_game_remove_hold (ChessGame* self)
{
	gint _tmp0_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (self->priv->hold_count > 0);
	_tmp0_ = self->priv->hold_count;
	self->priv->hold_count = _tmp0_ - 1;
	if (self->priv->hold_count == 0) {
		chess_game_complete_move (self);
	}
}

static void
chess_game_complete_move (ChessGame* self)
{
	ChessRule rule = 0;
	ChessResult _result_ = 0;
	ChessState* _tmp0_;
	ChessState* _tmp1_;
	ChessRule _tmp2_ = 0;
	ChessResult _tmp3_;
	ChessClock* _tmp4_;
	ChessPlayer* _tmp8_;
	ChessPlayer* _tmp9_;
	g_return_if_fail (self != NULL);
	if (self->priv->hold_count > 0) {
		return;
	}
	if (!self->is_started) {
		return;
	}
	_tmp0_ = chess_game_get_current_state (self);
	_tmp1_ = _tmp0_;
	_tmp3_ = chess_state_get_result (_tmp1_, &_tmp2_);
	rule = _tmp2_;
	_result_ = _tmp3_;
	if (_result_ != CHESS_RESULT_IN_PROGRESS) {
		chess_game_stop (self, _result_, rule);
		return;
	}
	if (chess_game_is_five_fold_repeat (self)) {
		chess_game_stop (self, CHESS_RESULT_DRAW, CHESS_RULE_FIVE_FOLD_REPETITION);
		return;
	}
	if (chess_game_is_seventy_five_move_rule_fulfilled (self)) {
		chess_game_stop (self, CHESS_RESULT_DRAW, CHESS_RULE_SEVENTY_FIVE_MOVES);
		return;
	}
	_tmp4_ = self->priv->_clock;
	if (_tmp4_ != NULL) {
		ChessClock* _tmp5_;
		ChessPlayer* _tmp6_;
		ChessPlayer* _tmp7_;
		_tmp5_ = self->priv->_clock;
		_tmp6_ = chess_game_get_current_player (self);
		_tmp7_ = _tmp6_;
		chess_clock_set_active_color (_tmp5_, _tmp7_->color);
	}
	_tmp8_ = chess_game_get_current_player (self);
	_tmp9_ = _tmp8_;
	g_signal_emit (self, chess_game_signals[CHESS_GAME_TURN_STARTED_SIGNAL], 0, _tmp9_);
}

static void
chess_game_undo_cb (ChessGame* self,
                    ChessPlayer* player)
{
	ChessPlayer* _tmp0_;
	ChessPlayer* _tmp1_;
	GList* _tmp4_;
	GList* _tmp5_;
	GList* _tmp6_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (player != NULL);
	_tmp0_ = chess_game_get_current_player (self);
	_tmp1_ = _tmp0_;
	if (player == _tmp1_) {
		ChessPlayer* _tmp2_;
		ChessPlayer* _tmp3_;
		_tmp2_ = chess_game_get_opponent (self);
		_tmp3_ = _tmp2_;
		chess_game_undo_cb (self, _tmp3_);
	}
	_tmp4_ = self->move_stack;
	_tmp5_ = _tmp4_->next;
	if (_tmp5_ == NULL) {
		return;
	}
	_tmp6_ = self->move_stack;
	self->move_stack = g_list_remove_link (self->move_stack, _tmp6_);
	if (self->result != CHESS_RESULT_IN_PROGRESS) {
		self->result = CHESS_RESULT_IN_PROGRESS;
		chess_game_start (self);
	}
	g_signal_emit (self, chess_game_signals[CHESS_GAME_UNDO_SIGNAL], 0);
}

static gboolean
chess_game_resign_cb (ChessGame* self,
                      ChessPlayer* player)
{
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	g_return_val_if_fail (player != NULL, FALSE);
	if (!self->is_started) {
		result = FALSE;
		return result;
	}
	if (player->color == COLOR_WHITE) {
		chess_game_stop (self, CHESS_RESULT_BLACK_WON, CHESS_RULE_RESIGN);
	} else {
		chess_game_stop (self, CHESS_RESULT_WHITE_WON, CHESS_RULE_RESIGN);
	}
	result = TRUE;
	return result;
}

static gint
chess_game_state_repeated_times (ChessGame* self,
                                 ChessState* s1)
{
	gint count = 0;
	GList* _tmp0_;
	gint result;
	g_return_val_if_fail (self != NULL, -1);
	g_return_val_if_fail (s1 != NULL, -1);
	count = 1;
	_tmp0_ = self->move_stack;
	{
		GList* s2_collection = NULL;
		GList* s2_it = NULL;
		s2_collection = _tmp0_;
		for (s2_it = s2_collection; s2_it != NULL; s2_it = s2_it->next) {
			ChessState* _tmp1_;
			ChessState* s2 = NULL;
			_tmp1_ = _g_object_ref0 ((ChessState*) s2_it->data);
			s2 = _tmp1_;
			{
				gboolean _tmp2_ = FALSE;
				ChessState* _tmp3_;
				_tmp3_ = s2;
				if (s1 != _tmp3_) {
					ChessState* _tmp4_;
					_tmp4_ = s2;
					_tmp2_ = chess_state_equals (s1, _tmp4_);
				} else {
					_tmp2_ = FALSE;
				}
				if (_tmp2_) {
					gint _tmp5_;
					_tmp5_ = count;
					count = _tmp5_ + 1;
				}
				_g_object_unref0 (s2);
			}
		}
	}
	result = count;
	return result;
}

gboolean
chess_game_is_three_fold_repeat (ChessGame* self)
{
	gint repeated = 0;
	ChessState* _tmp0_;
	ChessState* _tmp1_;
	gboolean _tmp2_ = FALSE;
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	_tmp0_ = chess_game_get_current_state (self);
	_tmp1_ = _tmp0_;
	repeated = chess_game_state_repeated_times (self, _tmp1_);
	if (repeated == 3) {
		_tmp2_ = TRUE;
	} else {
		_tmp2_ = repeated == 4;
	}
	result = _tmp2_;
	return result;
}

gboolean
chess_game_is_five_fold_repeat (ChessGame* self)
{
	ChessState* _tmp0_;
	ChessState* _tmp1_;
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	_tmp0_ = chess_game_get_current_state (self);
	_tmp1_ = _tmp0_;
	result = chess_game_state_repeated_times (self, _tmp1_) >= 5;
	return result;
}

gboolean
chess_game_is_fifty_move_rule_fulfilled (ChessGame* self)
{
	gboolean _tmp0_ = FALSE;
	ChessState* _tmp1_;
	ChessState* _tmp2_;
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	_tmp1_ = chess_game_get_current_state (self);
	_tmp2_ = _tmp1_;
	if (_tmp2_->halfmove_clock >= 100) {
		ChessState* _tmp3_;
		ChessState* _tmp4_;
		_tmp3_ = chess_game_get_current_state (self);
		_tmp4_ = _tmp3_;
		_tmp0_ = _tmp4_->halfmove_clock < 150;
	} else {
		_tmp0_ = FALSE;
	}
	result = _tmp0_;
	return result;
}

gboolean
chess_game_is_seventy_five_move_rule_fulfilled (ChessGame* self)
{
	ChessState* _tmp0_;
	ChessState* _tmp1_;
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	_tmp0_ = chess_game_get_current_state (self);
	_tmp1_ = _tmp0_;
	result = _tmp1_->halfmove_clock >= 150;
	return result;
}

gboolean
chess_game_can_claim_draw (ChessGame* self)
{
	gboolean _tmp0_ = FALSE;
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	if (chess_game_is_fifty_move_rule_fulfilled (self)) {
		_tmp0_ = TRUE;
	} else {
		_tmp0_ = chess_game_is_three_fold_repeat (self);
	}
	result = _tmp0_;
	return result;
}

static void
chess_game_claim_draw_cb (ChessGame* self)
{
	g_return_if_fail (self != NULL);
	_vala_return_if_fail (chess_game_can_claim_draw (self), "can_claim_draw ()");
	if (chess_game_is_fifty_move_rule_fulfilled (self)) {
		chess_game_stop (self, CHESS_RESULT_DRAW, CHESS_RULE_FIFTY_MOVES);
	} else {
		if (chess_game_is_three_fold_repeat (self)) {
			chess_game_stop (self, CHESS_RESULT_DRAW, CHESS_RULE_THREE_FOLD_REPETITION);
		}
	}
}

static void
_chess_game_clock_expired_cb_chess_clock_expired (ChessClock* _sender,
                                                  gpointer self)
{
	chess_game_clock_expired_cb ((ChessGame*) self, _sender);
}

void
chess_game_start (ChessGame* self)
{
	ChessClock* _tmp0_;
	ChessPlayer* _tmp5_;
	ChessPlayer* _tmp6_;
	g_return_if_fail (self != NULL);
	if (self->result != CHESS_RESULT_IN_PROGRESS) {
		return;
	}
	if (self->is_started) {
		return;
	}
	self->is_started = TRUE;
	_tmp0_ = self->priv->_clock;
	if (_tmp0_ != NULL) {
		ChessClock* _tmp1_;
		ChessClock* _tmp2_;
		ChessPlayer* _tmp3_;
		ChessPlayer* _tmp4_;
		_tmp1_ = self->priv->_clock;
		g_signal_connect_object (_tmp1_, "expired", (GCallback) _chess_game_clock_expired_cb_chess_clock_expired, self, 0);
		_tmp2_ = self->priv->_clock;
		_tmp3_ = chess_game_get_current_player (self);
		_tmp4_ = _tmp3_;
		chess_clock_set_active_color (_tmp2_, _tmp4_->color);
	}
	_tmp5_ = chess_game_get_current_player (self);
	_tmp6_ = _tmp5_;
	g_signal_emit (self, chess_game_signals[CHESS_GAME_TURN_STARTED_SIGNAL], 0, _tmp6_);
}

static void
chess_game_clock_expired_cb (ChessGame* self,
                             ChessClock* clock)
{
	gint _tmp0_;
	gint _tmp1_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (clock != NULL);
	_tmp0_ = chess_clock_get_white_remaining_seconds (clock);
	_tmp1_ = _tmp0_;
	if (_tmp1_ <= 0) {
		chess_game_stop (self, CHESS_RESULT_BLACK_WON, CHESS_RULE_TIMEOUT);
	} else {
		gint _tmp2_;
		gint _tmp3_;
		_tmp2_ = chess_clock_get_black_remaining_seconds (clock);
		_tmp3_ = _tmp2_;
		if (_tmp3_ <= 0) {
			chess_game_stop (self, CHESS_RESULT_WHITE_WON, CHESS_RULE_TIMEOUT);
		} else {
			g_assert_not_reached ();
		}
	}
}

ChessPiece*
chess_game_get_piece (ChessGame* self,
                      gint rank,
                      gint file,
                      gint move_number)
{
	ChessState* state = NULL;
	GList* _tmp1_;
	GList* _tmp2_;
	gconstpointer _tmp3_;
	ChessState* _tmp4_;
	ChessPiece* _tmp5_;
	ChessPiece* _tmp6_;
	ChessPiece* result;
	g_return_val_if_fail (self != NULL, NULL);
	if (move_number < 0) {
		GList* _tmp0_;
		_tmp0_ = self->move_stack;
		move_number = move_number + ((gint) g_list_length (_tmp0_));
	}
	_tmp1_ = self->move_stack;
	_tmp2_ = self->move_stack;
	_tmp3_ = g_list_nth_data (_tmp1_, (g_list_length (_tmp2_) - move_number) - 1);
	_tmp4_ = _g_object_ref0 ((ChessState*) _tmp3_);
	state = _tmp4_;
	_tmp5_ = state->board[chess_state_get_index (state, rank, file)];
	_tmp6_ = _g_object_ref0 (_tmp5_);
	result = _tmp6_;
	_g_object_unref0 (state);
	return result;
}

void
chess_game_pause (ChessGame* self,
                  gboolean show_overlay)
{
	gboolean _tmp0_ = FALSE;
	gboolean _tmp1_ = FALSE;
	ChessClock* _tmp2_;
	ChessClock* _tmp3_;
	g_return_if_fail (self != NULL);
	_tmp2_ = chess_game_get_clock (self);
	_tmp3_ = _tmp2_;
	if (_tmp3_ != NULL) {
		_tmp1_ = self->result == CHESS_RESULT_IN_PROGRESS;
	} else {
		_tmp1_ = FALSE;
	}
	if (_tmp1_) {
		gboolean _tmp4_;
		_tmp4_ = self->priv->_is_paused;
		_tmp0_ = !_tmp4_;
	} else {
		_tmp0_ = FALSE;
	}
	if (_tmp0_) {
		ChessClock* _tmp5_;
		ChessClock* _tmp6_;
		_tmp5_ = chess_game_get_clock (self);
		_tmp6_ = _tmp5_;
		chess_clock_pause (_tmp6_);
		chess_game_set_is_paused (self, TRUE);
		chess_game_set_should_show_paused_overlay (self, show_overlay);
		g_signal_emit (self, chess_game_signals[CHESS_GAME_PAUSED_SIGNAL], 0);
	}
}

void
chess_game_unpause (ChessGame* self)
{
	gboolean _tmp0_ = FALSE;
	gboolean _tmp1_ = FALSE;
	ChessClock* _tmp2_;
	ChessClock* _tmp3_;
	g_return_if_fail (self != NULL);
	_tmp2_ = chess_game_get_clock (self);
	_tmp3_ = _tmp2_;
	if (_tmp3_ != NULL) {
		_tmp1_ = self->result == CHESS_RESULT_IN_PROGRESS;
	} else {
		_tmp1_ = FALSE;
	}
	if (_tmp1_) {
		gboolean _tmp4_;
		_tmp4_ = self->priv->_is_paused;
		_tmp0_ = _tmp4_;
	} else {
		_tmp0_ = FALSE;
	}
	if (_tmp0_) {
		ChessClock* _tmp5_;
		ChessClock* _tmp6_;
		_tmp5_ = chess_game_get_clock (self);
		_tmp6_ = _tmp5_;
		chess_clock_unpause (_tmp6_);
		chess_game_set_is_paused (self, FALSE);
		chess_game_set_should_show_paused_overlay (self, FALSE);
		g_signal_emit (self, chess_game_signals[CHESS_GAME_UNPAUSED_SIGNAL], 0);
	}
}

void
chess_game_stop (ChessGame* self,
                 ChessResult _result_,
                 ChessRule rule)
{
	ChessClock* _tmp0_;
	g_return_if_fail (self != NULL);
	if (!self->is_started) {
		return;
	}
	self->result = _result_;
	self->rule = rule;
	self->is_started = FALSE;
	_tmp0_ = self->priv->_clock;
	if (_tmp0_ != NULL) {
		ChessClock* _tmp1_;
		_tmp1_ = self->priv->_clock;
		chess_clock_stop (_tmp1_);
	}
	g_signal_emit (self, chess_game_signals[CHESS_GAME_ENDED_SIGNAL], 0);
}

gboolean
chess_game_is_king_under_attack_at_position (ChessGame* self,
                                             gint rank,
                                             gint file)
{
	ChessState* _tmp0_;
	ChessState* _tmp1_;
	ChessPlayer* _tmp2_;
	ChessPlayer* _tmp3_;
	ChessPiece* piece = NULL;
	ChessPiece* _tmp4_;
	gboolean _tmp5_ = FALSE;
	ChessPiece* _tmp6_;
	gboolean _tmp8_ = FALSE;
	ChessPiece* _tmp9_;
	ChessPlayer* _tmp10_;
	gboolean _tmp13_ = FALSE;
	ChessPiece* _tmp14_;
	ChessPlayer* _tmp15_;
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	_tmp0_ = chess_game_get_current_state (self);
	_tmp1_ = _tmp0_;
	_tmp2_ = chess_game_get_current_player (self);
	_tmp3_ = _tmp2_;
	if (!chess_state_is_in_check (_tmp1_, _tmp3_)) {
		result = FALSE;
		return result;
	}
	_tmp4_ = chess_game_get_piece (self, rank, file, -1);
	piece = _tmp4_;
	_tmp6_ = piece;
	if (_tmp6_ == NULL) {
		_tmp5_ = TRUE;
	} else {
		ChessPiece* _tmp7_;
		_tmp7_ = piece;
		_tmp5_ = _tmp7_->type != PIECE_TYPE_KING;
	}
	if (_tmp5_) {
		result = FALSE;
		_g_object_unref0 (piece);
		return result;
	}
	_tmp9_ = piece;
	_tmp10_ = _tmp9_->player;
	if (_tmp10_->color == COLOR_WHITE) {
		ChessPlayer* _tmp11_;
		ChessPlayer* _tmp12_;
		_tmp11_ = chess_game_get_current_player (self);
		_tmp12_ = _tmp11_;
		_tmp8_ = _tmp12_->color == COLOR_WHITE;
	} else {
		_tmp8_ = FALSE;
	}
	if (_tmp8_) {
		result = TRUE;
		_g_object_unref0 (piece);
		return result;
	}
	_tmp14_ = piece;
	_tmp15_ = _tmp14_->player;
	if (_tmp15_->color == COLOR_BLACK) {
		ChessPlayer* _tmp16_;
		ChessPlayer* _tmp17_;
		_tmp16_ = chess_game_get_current_player (self);
		_tmp17_ = _tmp16_;
		_tmp13_ = _tmp17_->color == COLOR_BLACK;
	} else {
		_tmp13_ = FALSE;
	}
	if (_tmp13_) {
		result = TRUE;
		_g_object_unref0 (piece);
		return result;
	}
	result = FALSE;
	_g_object_unref0 (piece);
	return result;
}

gboolean
chess_game_is_piece_at_position_threatening_check (ChessGame* self,
                                                   gint rank,
                                                   gint file)
{
	gint* threatening_rank = NULL;
	gint threatening_rank_length1 = 0;
	gint _threatening_rank_size_ = 0;
	gint* threatening_file = NULL;
	gint threatening_file_length1 = 0;
	gint _threatening_file_size_ = 0;
	ChessState* _tmp0_;
	ChessState* _tmp1_;
	ChessPlayer* _tmp2_;
	ChessPlayer* _tmp3_;
	gint* _tmp4_ = NULL;
	gint _tmp5_ = 0;
	gint* _tmp6_ = NULL;
	gint _tmp7_ = 0;
	gboolean _tmp8_;
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	_tmp0_ = chess_game_get_current_state (self);
	_tmp1_ = _tmp0_;
	_tmp2_ = chess_game_get_current_player (self);
	_tmp3_ = _tmp2_;
	_tmp8_ = chess_state_get_positions_threatening_king (_tmp1_, _tmp3_, &_tmp4_, &_tmp5_, &_tmp6_, &_tmp7_);
	threatening_rank = (g_free (threatening_rank), NULL);
	threatening_rank = _tmp4_;
	threatening_rank_length1 = _tmp5_;
	_threatening_rank_size_ = threatening_rank_length1;
	threatening_file = (g_free (threatening_file), NULL);
	threatening_file = _tmp6_;
	threatening_file_length1 = _tmp7_;
	_threatening_file_size_ = threatening_file_length1;
	if (_tmp8_) {
		gint* _tmp9_;
		gint _tmp9__length1;
		gint* _tmp10_;
		gint _tmp10__length1;
		_tmp9_ = threatening_rank;
		_tmp9__length1 = threatening_rank_length1;
		_tmp10_ = threatening_file;
		_tmp10__length1 = threatening_file_length1;
		_vala_assert (_tmp9__length1 == _tmp10__length1, "threatening_rank.length == threatening_file.length");
		{
			gint i = 0;
			i = 0;
			{
				gboolean _tmp11_ = FALSE;
				_tmp11_ = TRUE;
				while (TRUE) {
					gint* _tmp13_;
					gint _tmp13__length1;
					gboolean _tmp14_ = FALSE;
					gint* _tmp15_;
					gint _tmp15__length1;
					gint _tmp16_;
					if (!_tmp11_) {
						gint _tmp12_;
						_tmp12_ = i;
						i = _tmp12_ + 1;
					}
					_tmp11_ = FALSE;
					_tmp13_ = threatening_rank;
					_tmp13__length1 = threatening_rank_length1;
					if (!(i < _tmp13__length1)) {
						break;
					}
					_tmp15_ = threatening_rank;
					_tmp15__length1 = threatening_rank_length1;
					_tmp16_ = _tmp15_[i];
					if (_tmp16_ == rank) {
						gint* _tmp17_;
						gint _tmp17__length1;
						gint _tmp18_;
						_tmp17_ = threatening_file;
						_tmp17__length1 = threatening_file_length1;
						_tmp18_ = _tmp17_[i];
						_tmp14_ = _tmp18_ == file;
					} else {
						_tmp14_ = FALSE;
					}
					if (_tmp14_) {
						result = TRUE;
						threatening_file = (g_free (threatening_file), NULL);
						threatening_rank = (g_free (threatening_rank), NULL);
						return result;
					}
				}
			}
		}
	}
	result = FALSE;
	threatening_file = (g_free (threatening_file), NULL);
	threatening_rank = (g_free (threatening_rank), NULL);
	return result;
}

gboolean
chess_game_get_is_paused (ChessGame* self)
{
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	result = self->priv->_is_paused;
	return result;
}

static void
chess_game_set_is_paused (ChessGame* self,
                          gboolean value)
{
	gboolean old_value;
	g_return_if_fail (self != NULL);
	old_value = chess_game_get_is_paused (self);
	if (old_value != value) {
		self->priv->_is_paused = value;
		g_object_notify_by_pspec ((GObject *) self, chess_game_properties[CHESS_GAME_IS_PAUSED_PROPERTY]);
	}
}

gboolean
chess_game_get_should_show_paused_overlay (ChessGame* self)
{
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	result = self->priv->_should_show_paused_overlay;
	return result;
}

static void
chess_game_set_should_show_paused_overlay (ChessGame* self,
                                           gboolean value)
{
	gboolean old_value;
	g_return_if_fail (self != NULL);
	old_value = chess_game_get_should_show_paused_overlay (self);
	if (old_value != value) {
		self->priv->_should_show_paused_overlay = value;
		g_object_notify_by_pspec ((GObject *) self, chess_game_properties[CHESS_GAME_SHOULD_SHOW_PAUSED_OVERLAY_PROPERTY]);
	}
}

ChessState*
chess_game_get_current_state (ChessGame* self)
{
	ChessState* result;
	GList* _tmp0_;
	gconstpointer _tmp1_;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = self->move_stack;
	_tmp1_ = _tmp0_->data;
	result = (ChessState*) _tmp1_;
	return result;
}

ChessPlayer*
chess_game_get_white (ChessGame* self)
{
	ChessPlayer* result;
	ChessState* _tmp0_;
	ChessState* _tmp1_;
	ChessPlayer* _tmp2_;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = chess_game_get_current_state (self);
	_tmp1_ = _tmp0_;
	_tmp2_ = _tmp1_->players[COLOR_WHITE];
	result = _tmp2_;
	return result;
}

ChessPlayer*
chess_game_get_black (ChessGame* self)
{
	ChessPlayer* result;
	ChessState* _tmp0_;
	ChessState* _tmp1_;
	ChessPlayer* _tmp2_;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = chess_game_get_current_state (self);
	_tmp1_ = _tmp0_;
	_tmp2_ = _tmp1_->players[COLOR_BLACK];
	result = _tmp2_;
	return result;
}

ChessPlayer*
chess_game_get_current_player (ChessGame* self)
{
	ChessPlayer* result;
	ChessState* _tmp0_;
	ChessState* _tmp1_;
	ChessPlayer* _tmp2_;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = chess_game_get_current_state (self);
	_tmp1_ = _tmp0_;
	_tmp2_ = _tmp1_->current_player;
	result = _tmp2_;
	return result;
}

ChessPlayer*
chess_game_get_opponent (ChessGame* self)
{
	ChessPlayer* result;
	ChessState* _tmp0_;
	ChessState* _tmp1_;
	ChessPlayer* _tmp2_;
	ChessPlayer* _tmp3_;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = chess_game_get_current_state (self);
	_tmp1_ = _tmp0_;
	_tmp2_ = chess_state_get_opponent (_tmp1_);
	_tmp3_ = _tmp2_;
	result = _tmp3_;
	return result;
}

ChessClock*
chess_game_get_clock (ChessGame* self)
{
	ChessClock* result;
	ChessClock* _tmp0_;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = self->priv->_clock;
	result = _tmp0_;
	return result;
}

void
chess_game_set_clock (ChessGame* self,
                      ChessClock* value)
{
	ChessClock* _tmp0_;
	g_return_if_fail (self != NULL);
	if (self->is_started) {
		return;
	}
	_tmp0_ = _g_object_ref0 (value);
	_g_object_unref0 (self->priv->_clock);
	self->priv->_clock = _tmp0_;
	g_object_notify_by_pspec ((GObject *) self, chess_game_properties[CHESS_GAME_CLOCK_PROPERTY]);
}

guint
chess_game_get_n_moves (ChessGame* self)
{
	guint result;
	GList* _tmp0_;
	g_return_val_if_fail (self != NULL, 0U);
	_tmp0_ = self->move_stack;
	result = g_list_length (_tmp0_) - 1;
	return result;
}

static void
chess_game_class_init (ChessGameClass * klass,
                       gpointer klass_data)
{
	chess_game_parent_class = g_type_class_peek_parent (klass);
	g_type_class_adjust_private_offset (klass, &ChessGame_private_offset);
	G_OBJECT_CLASS (klass)->get_property = _vala_chess_game_get_property;
	G_OBJECT_CLASS (klass)->set_property = _vala_chess_game_set_property;
	G_OBJECT_CLASS (klass)->finalize = chess_game_finalize;
	g_object_class_install_property (G_OBJECT_CLASS (klass), CHESS_GAME_IS_PAUSED_PROPERTY, chess_game_properties[CHESS_GAME_IS_PAUSED_PROPERTY] = g_param_spec_boolean ("is-paused", "is-paused", "is-paused", FALSE, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
	g_object_class_install_property (G_OBJECT_CLASS (klass), CHESS_GAME_SHOULD_SHOW_PAUSED_OVERLAY_PROPERTY, chess_game_properties[CHESS_GAME_SHOULD_SHOW_PAUSED_OVERLAY_PROPERTY] = g_param_spec_boolean ("should-show-paused-overlay", "should-show-paused-overlay", "should-show-paused-overlay", FALSE, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
	g_object_class_install_property (G_OBJECT_CLASS (klass), CHESS_GAME_CURRENT_STATE_PROPERTY, chess_game_properties[CHESS_GAME_CURRENT_STATE_PROPERTY] = g_param_spec_object ("current-state", "current-state", "current-state", TYPE_CHESS_STATE, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
	g_object_class_install_property (G_OBJECT_CLASS (klass), CHESS_GAME_WHITE_PROPERTY, chess_game_properties[CHESS_GAME_WHITE_PROPERTY] = g_param_spec_object ("white", "white", "white", TYPE_CHESS_PLAYER, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
	g_object_class_install_property (G_OBJECT_CLASS (klass), CHESS_GAME_BLACK_PROPERTY, chess_game_properties[CHESS_GAME_BLACK_PROPERTY] = g_param_spec_object ("black", "black", "black", TYPE_CHESS_PLAYER, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
	g_object_class_install_property (G_OBJECT_CLASS (klass), CHESS_GAME_CURRENT_PLAYER_PROPERTY, chess_game_properties[CHESS_GAME_CURRENT_PLAYER_PROPERTY] = g_param_spec_object ("current-player", "current-player", "current-player", TYPE_CHESS_PLAYER, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
	g_object_class_install_property (G_OBJECT_CLASS (klass), CHESS_GAME_OPPONENT_PROPERTY, chess_game_properties[CHESS_GAME_OPPONENT_PROPERTY] = g_param_spec_object ("opponent", "opponent", "opponent", TYPE_CHESS_PLAYER, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
	g_object_class_install_property (G_OBJECT_CLASS (klass), CHESS_GAME_CLOCK_PROPERTY, chess_game_properties[CHESS_GAME_CLOCK_PROPERTY] = g_param_spec_object ("clock", "clock", "clock", TYPE_CHESS_CLOCK, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE | G_PARAM_WRITABLE));
	g_object_class_install_property (G_OBJECT_CLASS (klass), CHESS_GAME_N_MOVES_PROPERTY, chess_game_properties[CHESS_GAME_N_MOVES_PROPERTY] = g_param_spec_uint ("n-moves", "n-moves", "n-moves", 0, G_MAXUINT, 0U, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
	chess_game_signals[CHESS_GAME_TURN_STARTED_SIGNAL] = g_signal_new ("turn-started", TYPE_CHESS_GAME, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__OBJECT, G_TYPE_NONE, 1, TYPE_CHESS_PLAYER);
	chess_game_signals[CHESS_GAME_MOVED_SIGNAL] = g_signal_new ("moved", TYPE_CHESS_GAME, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__OBJECT, G_TYPE_NONE, 1, TYPE_CHESS_MOVE);
	chess_game_signals[CHESS_GAME_PAUSED_SIGNAL] = g_signal_new ("paused", TYPE_CHESS_GAME, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
	chess_game_signals[CHESS_GAME_UNPAUSED_SIGNAL] = g_signal_new ("unpaused", TYPE_CHESS_GAME, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
	chess_game_signals[CHESS_GAME_UNDO_SIGNAL] = g_signal_new ("undo", TYPE_CHESS_GAME, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
	chess_game_signals[CHESS_GAME_ENDED_SIGNAL] = g_signal_new ("ended", TYPE_CHESS_GAME, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
}

static void
chess_game_instance_init (ChessGame * self,
                          gpointer klass)
{
	self->priv = chess_game_get_instance_private (self);
	self->priv->hold_count = 0;
	self->priv->_is_paused = FALSE;
	self->priv->_should_show_paused_overlay = FALSE;
}

static void
chess_game_finalize (GObject * obj)
{
	ChessGame * self;
	ChessClock* _tmp0_;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, TYPE_CHESS_GAME, ChessGame);
	_tmp0_ = self->priv->_clock;
	if (_tmp0_ != NULL) {
		ChessClock* _tmp1_;
		_tmp1_ = self->priv->_clock;
		chess_clock_stop (_tmp1_);
	}
	(self->move_stack == NULL) ? NULL : (self->move_stack = (_g_list_free__g_object_unref0_ (self->move_stack), NULL));
	_g_object_unref0 (self->priv->_clock);
	G_OBJECT_CLASS (chess_game_parent_class)->finalize (obj);
}

static GType
chess_game_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (ChessGameClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) chess_game_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (ChessGame), 0, (GInstanceInitFunc) chess_game_instance_init, NULL };
	GType chess_game_type_id;
	chess_game_type_id = g_type_register_static (G_TYPE_OBJECT, "ChessGame", &g_define_type_info, 0);
	ChessGame_private_offset = g_type_add_instance_private (chess_game_type_id, sizeof (ChessGamePrivate));
	return chess_game_type_id;
}

GType
chess_game_get_type (void)
{
	static volatile gsize chess_game_type_id__once = 0;
	if (g_once_init_enter (&chess_game_type_id__once)) {
		GType chess_game_type_id;
		chess_game_type_id = chess_game_get_type_once ();
		g_once_init_leave (&chess_game_type_id__once, chess_game_type_id);
	}
	return chess_game_type_id__once;
}

static void
_vala_chess_game_get_property (GObject * object,
                               guint property_id,
                               GValue * value,
                               GParamSpec * pspec)
{
	ChessGame * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (object, TYPE_CHESS_GAME, ChessGame);
	switch (property_id) {
		case CHESS_GAME_IS_PAUSED_PROPERTY:
		g_value_set_boolean (value, chess_game_get_is_paused (self));
		break;
		case CHESS_GAME_SHOULD_SHOW_PAUSED_OVERLAY_PROPERTY:
		g_value_set_boolean (value, chess_game_get_should_show_paused_overlay (self));
		break;
		case CHESS_GAME_CURRENT_STATE_PROPERTY:
		g_value_set_object (value, chess_game_get_current_state (self));
		break;
		case CHESS_GAME_WHITE_PROPERTY:
		g_value_set_object (value, chess_game_get_white (self));
		break;
		case CHESS_GAME_BLACK_PROPERTY:
		g_value_set_object (value, chess_game_get_black (self));
		break;
		case CHESS_GAME_CURRENT_PLAYER_PROPERTY:
		g_value_set_object (value, chess_game_get_current_player (self));
		break;
		case CHESS_GAME_OPPONENT_PROPERTY:
		g_value_set_object (value, chess_game_get_opponent (self));
		break;
		case CHESS_GAME_CLOCK_PROPERTY:
		g_value_set_object (value, chess_game_get_clock (self));
		break;
		case CHESS_GAME_N_MOVES_PROPERTY:
		g_value_set_uint (value, chess_game_get_n_moves (self));
		break;
		default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
	}
}

static void
_vala_chess_game_set_property (GObject * object,
                               guint property_id,
                               const GValue * value,
                               GParamSpec * pspec)
{
	ChessGame * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (object, TYPE_CHESS_GAME, ChessGame);
	switch (property_id) {
		case CHESS_GAME_IS_PAUSED_PROPERTY:
		chess_game_set_is_paused (self, g_value_get_boolean (value));
		break;
		case CHESS_GAME_SHOULD_SHOW_PAUSED_OVERLAY_PROPERTY:
		chess_game_set_should_show_paused_overlay (self, g_value_get_boolean (value));
		break;
		case CHESS_GAME_CLOCK_PROPERTY:
		chess_game_set_clock (self, g_value_get_object (value));
		break;
		default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
	}
}

