/* chess-scene.c generated by valac 0.56.0, the Vala compiler
 * generated from chess-scene.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 <glib-object.h>
#include "libchess.h"
#include <glib.h>
#include <float.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>

#if !defined(VALA_EXTERN)
#if defined(_MSC_VER)
#define VALA_EXTERN __declspec(dllexport) extern
#elif __GNUC__ >= 4
#define VALA_EXTERN __attribute__((visibility("default"))) extern
#else
#define VALA_EXTERN extern
#endif
#endif

#define TYPE_CHESS_MODEL (chess_model_get_type ())
#define CHESS_MODEL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_CHESS_MODEL, ChessModel))
#define CHESS_MODEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_CHESS_MODEL, ChessModelClass))
#define IS_CHESS_MODEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_CHESS_MODEL))
#define IS_CHESS_MODEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_CHESS_MODEL))
#define CHESS_MODEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_CHESS_MODEL, ChessModelClass))

typedef struct _ChessModel ChessModel;
typedef struct _ChessModelClass ChessModelClass;
typedef struct _ChessModelPrivate ChessModelPrivate;
enum  {
	CHESS_MODEL_0_PROPERTY,
	CHESS_MODEL_MOVING_PROPERTY,
	CHESS_MODEL_NUM_PROPERTIES
};
static GParamSpec* chess_model_properties[CHESS_MODEL_NUM_PROPERTIES];
#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))

#define TYPE_CHESS_SCENE (chess_scene_get_type ())
#define CHESS_SCENE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_CHESS_SCENE, ChessScene))
#define CHESS_SCENE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_CHESS_SCENE, ChessSceneClass))
#define IS_CHESS_SCENE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_CHESS_SCENE))
#define IS_CHESS_SCENE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_CHESS_SCENE))
#define CHESS_SCENE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_CHESS_SCENE, ChessSceneClass))

typedef struct _ChessScene ChessScene;
typedef struct _ChessSceneClass ChessSceneClass;
typedef struct _ChessScenePrivate ChessScenePrivate;
enum  {
	CHESS_SCENE_0_PROPERTY,
	CHESS_SCENE_GAME_PROPERTY,
	CHESS_SCENE_MOVE_NUMBER_PROPERTY,
	CHESS_SCENE_SHOW_NUMBERING_PROPERTY,
	CHESS_SCENE_SHOW_MOVE_HINTS_PROPERTY,
	CHESS_SCENE_THEME_NAME_PROPERTY,
	CHESS_SCENE_SHOW_3D_SMOOTH_PROPERTY,
	CHESS_SCENE_BOARD_SIDE_PROPERTY,
	CHESS_SCENE_BOARD_ANGLE_PROPERTY,
	CHESS_SCENE_MOVE_FORMAT_PROPERTY,
	CHESS_SCENE_NUM_PROPERTIES
};
static GParamSpec* chess_scene_properties[CHESS_SCENE_NUM_PROPERTIES];
#define _g_timer_destroy0(var) ((var == NULL) ? NULL : (var = (g_timer_destroy (var), NULL)))
#define _g_free0(var) (var = (g_free (var), NULL))
typedef struct _Block1Data Block1Data;
typedef void (*ChessScenePromotionTypeCompletionHandler) (PieceType* type, gpointer user_data);
enum  {
	CHESS_SCENE_IS_HUMAN_SIGNAL,
	CHESS_SCENE_CHANGED_SIGNAL,
	CHESS_SCENE_CHOOSE_PROMOTION_TYPE_SIGNAL,
	CHESS_SCENE_NUM_SIGNALS
};
static guint chess_scene_signals[CHESS_SCENE_NUM_SIGNALS] = {0};

struct _ChessModel {
	GObject parent_instance;
	ChessModelPrivate * priv;
	ChessPiece* piece;
	gdouble x;
	gdouble y;
	gdouble target_x;
	gdouble target_y;
	gboolean under_threat;
	gboolean is_selected;
};

struct _ChessModelClass {
	GObjectClass parent_class;
};

struct _ChessScene {
	GObject parent_instance;
	ChessScenePrivate * priv;
	GList* pieces;
	gboolean animating;
	gint selected_rank;
	gint selected_file;
};

struct _ChessSceneClass {
	GObjectClass parent_class;
};

struct _ChessScenePrivate {
	gboolean _can_move[64];
	GTimer* animation_timer;
	gdouble animation_time;
	guint animate_timeout_id;
	ChessGame* _game;
	gint _move_number;
	gboolean _show_numbering;
	gboolean _show_move_hints;
	gchar* _theme_name;
	gboolean _show_3d_smooth;
	gchar* _board_side;
	gchar* _move_format;
};

struct _Block1Data {
	int _ref_count_;
	ChessScene* self;
	gint file;
	gint rank;
};

static gpointer chess_model_parent_class = NULL;
static gint ChessScene_private_offset;
static gpointer chess_scene_parent_class = NULL;

VALA_EXTERN GType chess_model_get_type (void) G_GNUC_CONST ;
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ChessModel, g_object_unref)
VALA_EXTERN ChessModel* chess_model_new (ChessPiece* piece,
                             gdouble x,
                             gdouble y);
VALA_EXTERN ChessModel* chess_model_construct (GType object_type,
                                   ChessPiece* piece,
                                   gdouble x,
                                   gdouble y);
VALA_EXTERN gboolean chess_model_move_to (ChessModel* self,
                              gdouble x,
                              gdouble y);
VALA_EXTERN gboolean chess_model_animate (ChessModel* self,
                              gdouble timestep);
VALA_EXTERN gboolean chess_model_get_moving (ChessModel* self);
static gdouble chess_model_update_position (ChessModel* self,
                                     gdouble timestep,
                                     gdouble value,
                                     gdouble target);
static void chess_model_finalize (GObject * obj);
static GType chess_model_get_type_once (void);
static void _vala_chess_model_get_property (GObject * object,
                                     guint property_id,
                                     GValue * value,
                                     GParamSpec * pspec);
VALA_EXTERN GType chess_scene_get_type (void) G_GNUC_CONST ;
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ChessScene, g_object_unref)
static void _g_object_unref0_ (gpointer var);
static inline void _g_list_free__g_object_unref0_ (GList* self);
VALA_EXTERN ChessPiece* chess_scene_get_selected_piece (ChessScene* self);
VALA_EXTERN ChessGame* chess_scene_get_game (ChessScene* self);
VALA_EXTERN gint chess_scene_get_move_number (ChessScene* self);
VALA_EXTERN ChessScene* chess_scene_new (void);
VALA_EXTERN ChessScene* chess_scene_construct (GType object_type);
VALA_EXTERN void chess_scene_select_square (ChessScene* self,
                                gint file,
                                gint rank);
static Block1Data* block1_data_ref (Block1Data* _data1_);
static void block1_data_unref (void * _userdata_);
static void ______lambda4_ (Block1Data* _data1_,
                     PieceType* promotion_selection);
static void chess_scene_update_board (ChessScene* self);
static void _______lambda4__chess_scene_promotion_type_completion_handler (PieceType* type,
                                                                    gpointer self);
static void chess_scene_moved_cb (ChessScene* self,
                           ChessGame* game,
                           ChessMove* move);
static void chess_scene_paused_cb (ChessScene* self,
                            ChessGame* game);
static void chess_scene_unpaused_cb (ChessScene* self,
                              ChessGame* game);
static void chess_scene_undo_cb (ChessScene* self,
                          ChessGame* game);
static ChessModel* chess_scene_find_model (ChessScene* self,
                                    ChessPiece* piece);
static gboolean chess_scene_animate_cb (ChessScene* self);
static gboolean _chess_scene_animate_cb_gsource_func (gpointer self);
VALA_EXTERN gboolean chess_scene_can_move (ChessScene* self,
                               gint rank,
                               gint file);
VALA_EXTERN void chess_scene_set_game (ChessScene* self,
                           ChessGame* value);
static void _chess_scene_moved_cb_chess_game_moved (ChessGame* _sender,
                                             ChessMove* move,
                                             gpointer self);
static void _chess_scene_paused_cb_chess_game_paused (ChessGame* _sender,
                                               gpointer self);
static void _chess_scene_unpaused_cb_chess_game_unpaused (ChessGame* _sender,
                                                   gpointer self);
static void _chess_scene_undo_cb_chess_game_undo (ChessGame* _sender,
                                           gpointer self);
VALA_EXTERN void chess_scene_set_move_number (ChessScene* self,
                                  gint value);
VALA_EXTERN gboolean chess_scene_get_show_numbering (ChessScene* self);
VALA_EXTERN void chess_scene_set_show_numbering (ChessScene* self,
                                     gboolean value);
VALA_EXTERN gboolean chess_scene_get_show_move_hints (ChessScene* self);
VALA_EXTERN void chess_scene_set_show_move_hints (ChessScene* self,
                                      gboolean value);
VALA_EXTERN const gchar* chess_scene_get_theme_name (ChessScene* self);
VALA_EXTERN void chess_scene_set_theme_name (ChessScene* self,
                                 const gchar* value);
VALA_EXTERN gboolean chess_scene_get_show_3d_smooth (ChessScene* self);
VALA_EXTERN void chess_scene_set_show_3d_smooth (ChessScene* self,
                                     gboolean value);
VALA_EXTERN const gchar* chess_scene_get_board_side (ChessScene* self);
VALA_EXTERN void chess_scene_set_board_side (ChessScene* self,
                                 const gchar* value);
VALA_EXTERN gdouble chess_scene_get_board_angle (ChessScene* self);
VALA_EXTERN const gchar* chess_scene_get_move_format (ChessScene* self);
VALA_EXTERN void chess_scene_set_move_format (ChessScene* self,
                                  const gchar* value);
static void g_cclosure_user_marshal_BOOLEAN__OBJECT (GClosure * closure,
                                              GValue * return_value,
                                              guint n_param_values,
                                              const GValue * param_values,
                                              gpointer invocation_hint,
                                              gpointer marshal_data);
static void g_cclosure_user_marshal_VOID__POINTER_POINTER_POINTER (GClosure * closure,
                                                            GValue * return_value,
                                                            guint n_param_values,
                                                            const GValue * param_values,
                                                            gpointer invocation_hint,
                                                            gpointer marshal_data);
static void chess_scene_finalize (GObject * obj);
static GType chess_scene_get_type_once (void);
static void _vala_chess_scene_get_property (GObject * object,
                                     guint property_id,
                                     GValue * value,
                                     GParamSpec * pspec);
static void _vala_chess_scene_set_property (GObject * object,
                                     guint property_id,
                                     const GValue * value,
                                     GParamSpec * pspec);

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

ChessModel*
chess_model_construct (GType object_type,
                       ChessPiece* piece,
                       gdouble x,
                       gdouble y)
{
	ChessModel * self = NULL;
	ChessPiece* _tmp0_;
	g_return_val_if_fail (piece != NULL, NULL);
	self = (ChessModel*) g_object_new (object_type, NULL);
	_tmp0_ = _g_object_ref0 (piece);
	_g_object_unref0 (self->piece);
	self->piece = _tmp0_;
	self->target_x = x;
	self->x = self->target_x;
	self->target_y = y;
	self->y = self->target_y;
	return self;
}

ChessModel*
chess_model_new (ChessPiece* piece,
                 gdouble x,
                 gdouble y)
{
	return chess_model_construct (TYPE_CHESS_MODEL, piece, x, y);
}

gboolean
chess_model_move_to (ChessModel* self,
                     gdouble x,
                     gdouble y)
{
	gboolean _tmp0_ = FALSE;
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	if (self->target_x == x) {
		_tmp0_ = self->target_y == y;
	} else {
		_tmp0_ = FALSE;
	}
	if (_tmp0_) {
		result = FALSE;
		return result;
	}
	self->target_x = x;
	self->target_y = y;
	result = TRUE;
	return result;
}

gboolean
chess_model_animate (ChessModel* self,
                     gdouble timestep)
{
	gboolean _tmp0_;
	gboolean _tmp1_;
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	_tmp0_ = chess_model_get_moving (self);
	_tmp1_ = _tmp0_;
	if (!_tmp1_) {
		result = FALSE;
		return result;
	}
	self->x = chess_model_update_position (self, timestep, self->x, self->target_x);
	self->y = chess_model_update_position (self, timestep, self->y, self->target_y);
	result = TRUE;
	return result;
}

static gdouble
chess_model_update_position (ChessModel* self,
                             gdouble timestep,
                             gdouble value,
                             gdouble target)
{
	gdouble distance = 0.0;
	gdouble step = 0.0;
	gdouble result;
	g_return_val_if_fail (self != NULL, 0.0);
	distance = fabs (target - value);
	step = timestep * 4.0;
	if (step > distance) {
		step = distance;
	}
	if (target > value) {
		result = value + step;
		return result;
	} else {
		result = value - step;
		return result;
	}
}

gboolean
chess_model_get_moving (ChessModel* self)
{
	gboolean result;
	gboolean _tmp0_ = FALSE;
	g_return_val_if_fail (self != NULL, FALSE);
	if (self->x != self->target_x) {
		_tmp0_ = TRUE;
	} else {
		_tmp0_ = self->y != self->target_y;
	}
	result = _tmp0_;
	return result;
}

static void
chess_model_class_init (ChessModelClass * klass,
                        gpointer klass_data)
{
	chess_model_parent_class = g_type_class_peek_parent (klass);
	G_OBJECT_CLASS (klass)->get_property = _vala_chess_model_get_property;
	G_OBJECT_CLASS (klass)->finalize = chess_model_finalize;
	g_object_class_install_property (G_OBJECT_CLASS (klass), CHESS_MODEL_MOVING_PROPERTY, chess_model_properties[CHESS_MODEL_MOVING_PROPERTY] = g_param_spec_boolean ("moving", "moving", "moving", FALSE, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
}

static void
chess_model_instance_init (ChessModel * self,
                           gpointer klass)
{
}

static void
chess_model_finalize (GObject * obj)
{
	ChessModel * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, TYPE_CHESS_MODEL, ChessModel);
	_g_object_unref0 (self->piece);
	G_OBJECT_CLASS (chess_model_parent_class)->finalize (obj);
}

static GType
chess_model_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (ChessModelClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) chess_model_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (ChessModel), 0, (GInstanceInitFunc) chess_model_instance_init, NULL };
	GType chess_model_type_id;
	chess_model_type_id = g_type_register_static (G_TYPE_OBJECT, "ChessModel", &g_define_type_info, 0);
	return chess_model_type_id;
}

GType
chess_model_get_type (void)
{
	static volatile gsize chess_model_type_id__once = 0;
	if (g_once_init_enter (&chess_model_type_id__once)) {
		GType chess_model_type_id;
		chess_model_type_id = chess_model_get_type_once ();
		g_once_init_leave (&chess_model_type_id__once, chess_model_type_id);
	}
	return chess_model_type_id__once;
}

static void
_vala_chess_model_get_property (GObject * object,
                                guint property_id,
                                GValue * value,
                                GParamSpec * pspec)
{
	ChessModel * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (object, TYPE_CHESS_MODEL, ChessModel);
	switch (property_id) {
		case CHESS_MODEL_MOVING_PROPERTY:
		g_value_set_boolean (value, chess_model_get_moving (self));
		break;
		default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
	}
}

static inline gpointer
chess_scene_get_instance_private (ChessScene* self)
{
	return G_STRUCT_MEMBER_P (self, ChessScene_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_);
}

ChessPiece*
chess_scene_get_selected_piece (ChessScene* self)
{
	gboolean _tmp0_ = FALSE;
	ChessGame* _tmp1_;
	ChessGame* _tmp2_;
	ChessGame* _tmp3_;
	ChessGame* _tmp4_;
	gint _tmp5_;
	gint _tmp6_;
	ChessPiece* _tmp7_;
	ChessPiece* result;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp1_ = chess_scene_get_game (self);
	_tmp2_ = _tmp1_;
	if (_tmp2_ == NULL) {
		_tmp0_ = TRUE;
	} else {
		_tmp0_ = self->selected_rank < 0;
	}
	if (_tmp0_) {
		result = NULL;
		return result;
	}
	_tmp3_ = chess_scene_get_game (self);
	_tmp4_ = _tmp3_;
	_tmp5_ = chess_scene_get_move_number (self);
	_tmp6_ = _tmp5_;
	_tmp7_ = chess_game_get_piece (_tmp4_, self->selected_rank, self->selected_file, _tmp6_);
	result = _tmp7_;
	return result;
}

ChessScene*
chess_scene_construct (GType object_type)
{
	ChessScene * self = NULL;
	GTimer* _tmp0_;
	self = (ChessScene*) g_object_new (object_type, NULL);
	_tmp0_ = g_timer_new ();
	_g_timer_destroy0 (self->priv->animation_timer);
	self->priv->animation_timer = _tmp0_;
	return self;
}

ChessScene*
chess_scene_new (void)
{
	return chess_scene_construct (TYPE_CHESS_SCENE);
}

static Block1Data*
block1_data_ref (Block1Data* _data1_)
{
	g_atomic_int_inc (&_data1_->_ref_count_);
	return _data1_;
}

static void
block1_data_unref (void * _userdata_)
{
	Block1Data* _data1_;
	_data1_ = (Block1Data*) _userdata_;
	if (g_atomic_int_dec_and_test (&_data1_->_ref_count_)) {
		ChessScene* self;
		self = _data1_->self;
		_g_object_unref0 (self);
		g_slice_free (Block1Data, _data1_);
	}
}

static void
______lambda4_ (Block1Data* _data1_,
                PieceType* promotion_selection)
{
	ChessScene* self;
	self = _data1_->self;
	if (promotion_selection != NULL) {
		ChessGame* _tmp0_;
		ChessGame* _tmp1_;
		ChessPlayer* _tmp2_;
		ChessPlayer* _tmp3_;
		_tmp0_ = chess_scene_get_game (self);
		_tmp1_ = _tmp0_;
		_tmp2_ = chess_game_get_current_player (_tmp1_);
		_tmp3_ = _tmp2_;
		chess_player_move_with_coords (_tmp3_, self->selected_rank, self->selected_file, _data1_->rank, _data1_->file, TRUE, *promotion_selection);
		self->selected_file = -1;
		self->selected_rank = self->selected_file;
		chess_scene_update_board (self);
		g_signal_emit (self, chess_scene_signals[CHESS_SCENE_CHANGED_SIGNAL], 0);
	}
}

static void
_______lambda4__chess_scene_promotion_type_completion_handler (PieceType* type,
                                                               gpointer self)
{
	______lambda4_ (self, type);
}

void
chess_scene_select_square (ChessScene* self,
                           gint file,
                           gint rank)
{
	Block1Data* _data1_;
	gboolean _tmp0_ = FALSE;
	ChessGame* _tmp1_;
	ChessGame* _tmp2_;
	gint _tmp9_;
	gint _tmp10_;
	ChessPiece* piece = NULL;
	ChessGame* _tmp11_;
	ChessGame* _tmp12_;
	gint _tmp13_;
	gint _tmp14_;
	ChessPiece* _tmp15_;
	gboolean _tmp16_ = FALSE;
	g_return_if_fail (self != NULL);
	_data1_ = g_slice_new0 (Block1Data);
	_data1_->_ref_count_ = 1;
	_data1_->self = g_object_ref (self);
	_data1_->file = file;
	_data1_->rank = rank;
	_tmp1_ = chess_scene_get_game (self);
	_tmp2_ = _tmp1_;
	if (_tmp2_ == NULL) {
		_tmp0_ = TRUE;
	} else {
		ChessGame* _tmp3_;
		ChessGame* _tmp4_;
		ChessPlayer* _tmp5_;
		ChessPlayer* _tmp6_;
		gboolean _tmp7_;
		gboolean _tmp8_;
		_tmp3_ = chess_scene_get_game (self);
		_tmp4_ = _tmp3_;
		_tmp5_ = chess_game_get_current_player (_tmp4_);
		_tmp6_ = _tmp5_;
		_tmp7_ = chess_player_get_local_human (_tmp6_);
		_tmp8_ = _tmp7_;
		_tmp0_ = !_tmp8_;
	}
	if (_tmp0_) {
		block1_data_unref (_data1_);
		_data1_ = NULL;
		return;
	}
	_tmp9_ = chess_scene_get_move_number (self);
	_tmp10_ = _tmp9_;
	if (_tmp10_ != -1) {
		block1_data_unref (_data1_);
		_data1_ = NULL;
		return;
	}
	_tmp11_ = chess_scene_get_game (self);
	_tmp12_ = _tmp11_;
	_tmp13_ = chess_scene_get_move_number (self);
	_tmp14_ = _tmp13_;
	_tmp15_ = chess_game_get_piece (_tmp12_, _data1_->rank, _data1_->file, _tmp14_);
	piece = _tmp15_;
	if (_data1_->file == self->selected_file) {
		_tmp16_ = _data1_->rank == self->selected_rank;
	} else {
		_tmp16_ = FALSE;
	}
	if (_tmp16_) {
		self->selected_file = -1;
		self->selected_rank = self->selected_file;
	} else {
		gboolean _tmp17_ = FALSE;
		ChessPiece* _tmp18_;
		_tmp18_ = piece;
		if (_tmp18_ != NULL) {
			ChessPiece* _tmp19_;
			ChessPlayer* _tmp20_;
			ChessGame* _tmp21_;
			ChessGame* _tmp22_;
			ChessPlayer* _tmp23_;
			ChessPlayer* _tmp24_;
			_tmp19_ = piece;
			_tmp20_ = _tmp19_->player;
			_tmp21_ = chess_scene_get_game (self);
			_tmp22_ = _tmp21_;
			_tmp23_ = chess_game_get_current_player (_tmp22_);
			_tmp24_ = _tmp23_;
			_tmp17_ = _tmp20_ == _tmp24_;
		} else {
			_tmp17_ = FALSE;
		}
		if (_tmp17_) {
			self->selected_rank = _data1_->rank;
			self->selected_file = _data1_->file;
		} else {
			if (self->selected_file != -1) {
				gboolean can_move = FALSE;
				ChessGame* _tmp25_;
				ChessGame* _tmp26_;
				ChessPlayer* _tmp27_;
				ChessPlayer* _tmp28_;
				gboolean _tmp29_ = FALSE;
				gboolean _tmp30_ = FALSE;
				ChessGame* _tmp34_;
				ChessGame* _tmp35_;
				ChessPlayer* _tmp36_;
				ChessPlayer* _tmp37_;
				_tmp25_ = chess_scene_get_game (self);
				_tmp26_ = _tmp25_;
				_tmp27_ = chess_game_get_current_player (_tmp26_);
				_tmp28_ = _tmp27_;
				can_move = chess_player_move_with_coords (_tmp28_, self->selected_rank, self->selected_file, _data1_->rank, _data1_->file, FALSE, PIECE_TYPE_QUEEN);
				if (can_move) {
					ChessPiece* _tmp31_;
					ChessPiece* _tmp32_;
					_tmp31_ = chess_scene_get_selected_piece (self);
					_tmp32_ = _tmp31_;
					_tmp30_ = _tmp32_->type == PIECE_TYPE_PAWN;
					_g_object_unref0 (_tmp32_);
				} else {
					_tmp30_ = FALSE;
				}
				if (_tmp30_) {
					gboolean _tmp33_ = FALSE;
					if (_data1_->rank == 0) {
						_tmp33_ = TRUE;
					} else {
						_tmp33_ = _data1_->rank == 7;
					}
					_tmp29_ = _tmp33_;
				} else {
					_tmp29_ = FALSE;
				}
				if (_tmp29_) {
					g_signal_emit (self, chess_scene_signals[CHESS_SCENE_CHOOSE_PROMOTION_TYPE_SIGNAL], 0, _______lambda4__chess_scene_promotion_type_completion_handler, block1_data_ref (_data1_), block1_data_unref);
					_g_object_unref0 (piece);
					block1_data_unref (_data1_);
					_data1_ = NULL;
					return;
				}
				_tmp34_ = chess_scene_get_game (self);
				_tmp35_ = _tmp34_;
				_tmp36_ = chess_game_get_current_player (_tmp35_);
				_tmp37_ = _tmp36_;
				if (chess_player_move_with_coords (_tmp37_, self->selected_rank, self->selected_file, _data1_->rank, _data1_->file, TRUE, PIECE_TYPE_QUEEN)) {
					self->selected_file = -1;
					self->selected_rank = self->selected_file;
				}
			}
		}
	}
	chess_scene_update_board (self);
	g_signal_emit (self, chess_scene_signals[CHESS_SCENE_CHANGED_SIGNAL], 0);
	_g_object_unref0 (piece);
	block1_data_unref (_data1_);
	_data1_ = NULL;
}

static void
chess_scene_moved_cb (ChessScene* self,
                      ChessGame* game,
                      ChessMove* move)
{
	g_return_if_fail (self != NULL);
	g_return_if_fail (game != NULL);
	g_return_if_fail (move != NULL);
	chess_scene_update_board (self);
}

static void
chess_scene_paused_cb (ChessScene* self,
                       ChessGame* game)
{
	g_return_if_fail (self != NULL);
	g_return_if_fail (game != NULL);
	g_signal_emit (self, chess_scene_signals[CHESS_SCENE_CHANGED_SIGNAL], 0);
}

static void
chess_scene_unpaused_cb (ChessScene* self,
                         ChessGame* game)
{
	g_return_if_fail (self != NULL);
	g_return_if_fail (game != NULL);
	g_signal_emit (self, chess_scene_signals[CHESS_SCENE_CHANGED_SIGNAL], 0);
}

static void
chess_scene_undo_cb (ChessScene* self,
                     ChessGame* game)
{
	g_return_if_fail (self != NULL);
	g_return_if_fail (game != NULL);
	chess_scene_update_board (self);
}

static ChessModel*
chess_scene_find_model (ChessScene* self,
                        ChessPiece* piece)
{
	GList* _tmp0_;
	ChessModel* result;
	g_return_val_if_fail (self != NULL, NULL);
	g_return_val_if_fail (piece != NULL, NULL);
	_tmp0_ = self->pieces;
	{
		GList* model_collection = NULL;
		GList* model_it = NULL;
		model_collection = _tmp0_;
		for (model_it = model_collection; model_it != NULL; model_it = model_it->next) {
			ChessModel* _tmp1_;
			ChessModel* model = NULL;
			_tmp1_ = _g_object_ref0 ((ChessModel*) model_it->data);
			model = _tmp1_;
			{
				ChessModel* _tmp2_;
				ChessPiece* _tmp3_;
				_tmp2_ = model;
				_tmp3_ = _tmp2_->piece;
				if (_tmp3_ == piece) {
					result = model;
					return result;
				}
				_g_object_unref0 (model);
			}
		}
	}
	result = NULL;
	return result;
}

static gboolean
_chess_scene_animate_cb_gsource_func (gpointer self)
{
	gboolean result;
	result = chess_scene_animate_cb ((ChessScene*) self);
	return result;
}

static void
chess_scene_update_board (ChessScene* self)
{
	ChessGame* _tmp0_;
	ChessGame* _tmp1_;
	gboolean board_changed = FALSE;
	gboolean need_animation = FALSE;
	GList* new_pieces = NULL;
	GList* _tmp35_;
	GList* _tmp36_;
	GList* _tmp37_;
	gboolean _tmp41_ = FALSE;
	g_return_if_fail (self != NULL);
	_tmp0_ = chess_scene_get_game (self);
	_tmp1_ = _tmp0_;
	if (_tmp1_ == NULL) {
		return;
	}
	board_changed = FALSE;
	need_animation = FALSE;
	new_pieces = NULL;
	{
		gint rank = 0;
		rank = 0;
		{
			gboolean _tmp2_ = FALSE;
			_tmp2_ = TRUE;
			while (TRUE) {
				if (!_tmp2_) {
					gint _tmp3_;
					_tmp3_ = rank;
					rank = _tmp3_ + 1;
				}
				_tmp2_ = FALSE;
				if (!(rank < 8)) {
					break;
				}
				{
					gint file = 0;
					file = 0;
					{
						gboolean _tmp4_ = FALSE;
						_tmp4_ = TRUE;
						while (TRUE) {
							gboolean can_move = FALSE;
							gboolean _tmp6_ = FALSE;
							gboolean _tmp7_ = FALSE;
							ChessPiece* piece = NULL;
							ChessGame* _tmp14_;
							ChessGame* _tmp15_;
							gint _tmp16_;
							gint _tmp17_;
							ChessPiece* _tmp18_;
							ChessPiece* _tmp19_;
							ChessModel* model = NULL;
							ChessPiece* _tmp20_;
							ChessModel* _tmp21_;
							ChessModel* _tmp22_;
							ChessModel* _tmp25_;
							ChessModel* _tmp26_;
							gboolean _tmp27_ = FALSE;
							gboolean _tmp28_ = FALSE;
							gint _tmp29_;
							gint _tmp30_;
							ChessModel* _tmp33_;
							ChessModel* _tmp34_;
							if (!_tmp4_) {
								gint _tmp5_;
								_tmp5_ = file;
								file = _tmp5_ + 1;
							}
							_tmp4_ = FALSE;
							if (!(file < 8)) {
								break;
							}
							can_move = FALSE;
							if (self->selected_rank >= 0) {
								gint _tmp8_;
								gint _tmp9_;
								_tmp8_ = chess_scene_get_move_number (self);
								_tmp9_ = _tmp8_;
								_tmp7_ = _tmp9_ == -1;
							} else {
								_tmp7_ = FALSE;
							}
							if (_tmp7_) {
								ChessGame* _tmp10_;
								ChessGame* _tmp11_;
								ChessPlayer* _tmp12_;
								ChessPlayer* _tmp13_;
								_tmp10_ = chess_scene_get_game (self);
								_tmp11_ = _tmp10_;
								_tmp12_ = chess_game_get_current_player (_tmp11_);
								_tmp13_ = _tmp12_;
								_tmp6_ = chess_player_move_with_coords (_tmp13_, self->selected_rank, self->selected_file, rank, file, FALSE, PIECE_TYPE_QUEEN);
							} else {
								_tmp6_ = FALSE;
							}
							if (_tmp6_) {
								can_move = TRUE;
							}
							self->priv->_can_move[(rank * 8) + file] = can_move;
							_tmp14_ = chess_scene_get_game (self);
							_tmp15_ = _tmp14_;
							_tmp16_ = chess_scene_get_move_number (self);
							_tmp17_ = _tmp16_;
							_tmp18_ = chess_game_get_piece (_tmp15_, rank, file, _tmp17_);
							piece = _tmp18_;
							_tmp19_ = piece;
							if (_tmp19_ == NULL) {
								_g_object_unref0 (piece);
								continue;
							}
							_tmp20_ = piece;
							_tmp21_ = chess_scene_find_model (self, _tmp20_);
							model = _tmp21_;
							_tmp22_ = model;
							if (_tmp22_ == NULL) {
								ChessPiece* _tmp23_;
								ChessModel* _tmp24_;
								_tmp23_ = piece;
								_tmp24_ = chess_model_new (_tmp23_, (gdouble) file, (gdouble) rank);
								_g_object_unref0 (model);
								model = _tmp24_;
								board_changed = TRUE;
							}
							_tmp25_ = model;
							_tmp25_->under_threat = can_move;
							_tmp26_ = model;
							if (chess_model_move_to (_tmp26_, (gdouble) file, (gdouble) rank)) {
								board_changed = TRUE;
								need_animation = TRUE;
							}
							_tmp29_ = chess_scene_get_move_number (self);
							_tmp30_ = _tmp29_;
							if (_tmp30_ == -1) {
								_tmp28_ = rank == self->selected_rank;
							} else {
								_tmp28_ = FALSE;
							}
							if (_tmp28_) {
								_tmp27_ = file == self->selected_file;
							} else {
								_tmp27_ = FALSE;
							}
							if (_tmp27_) {
								ChessModel* _tmp31_;
								_tmp31_ = model;
								_tmp31_->is_selected = TRUE;
							} else {
								ChessModel* _tmp32_;
								_tmp32_ = model;
								_tmp32_->is_selected = FALSE;
							}
							_tmp33_ = model;
							_tmp34_ = _g_object_ref0 (_tmp33_);
							new_pieces = g_list_append (new_pieces, _tmp34_);
							_g_object_unref0 (model);
							_g_object_unref0 (piece);
						}
					}
				}
			}
		}
	}
	_tmp35_ = new_pieces;
	_tmp36_ = self->pieces;
	if (g_list_length (_tmp35_) != g_list_length (_tmp36_)) {
		board_changed = TRUE;
	}
	if (!board_changed) {
		(new_pieces == NULL) ? NULL : (new_pieces = (_g_list_free__g_object_unref0_ (new_pieces), NULL));
		return;
	}
	(self->pieces == NULL) ? NULL : (self->pieces = (_g_list_free__g_object_unref0_ (self->pieces), NULL));
	self->pieces = NULL;
	_tmp37_ = new_pieces;
	{
		GList* model_collection = NULL;
		GList* model_it = NULL;
		model_collection = _tmp37_;
		for (model_it = model_collection; model_it != NULL; model_it = model_it->next) {
			ChessModel* _tmp38_;
			ChessModel* model = NULL;
			_tmp38_ = _g_object_ref0 ((ChessModel*) model_it->data);
			model = _tmp38_;
			{
				ChessModel* _tmp39_;
				ChessModel* _tmp40_;
				_tmp39_ = model;
				_tmp40_ = _g_object_ref0 (_tmp39_);
				self->pieces = g_list_append (self->pieces, _tmp40_);
				_g_object_unref0 (model);
			}
		}
	}
	g_signal_emit (self, chess_scene_signals[CHESS_SCENE_CHANGED_SIGNAL], 0);
	if (need_animation) {
		_tmp41_ = !self->animating;
	} else {
		_tmp41_ = FALSE;
	}
	if (_tmp41_) {
		GTimer* _tmp42_;
		ChessGame* _tmp43_;
		ChessGame* _tmp44_;
		self->animating = TRUE;
		_tmp42_ = self->priv->animation_timer;
		g_timer_start (_tmp42_);
		self->priv->animation_time = (gdouble) 0;
		_tmp43_ = chess_scene_get_game (self);
		_tmp44_ = _tmp43_;
		chess_game_add_hold (_tmp44_);
		self->priv->animate_timeout_id = g_timeout_add_full (G_PRIORITY_DEFAULT_IDLE, (guint) 10, _chess_scene_animate_cb_gsource_func, g_object_ref (self), g_object_unref);
	}
	(new_pieces == NULL) ? NULL : (new_pieces = (_g_list_free__g_object_unref0_ (new_pieces), NULL));
}

gboolean
chess_scene_can_move (ChessScene* self,
                      gint rank,
                      gint file)
{
	gboolean _tmp0_;
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	_tmp0_ = self->priv->_can_move[(rank * 8) + file];
	result = _tmp0_;
	return result;
}

static gboolean
chess_scene_animate_cb (ChessScene* self)
{
	gdouble old_time = 0.0;
	GTimer* _tmp0_;
	gdouble timestep = 0.0;
	gint animate_count = 0;
	GList* _tmp1_;
	ChessGame* _tmp5_;
	ChessGame* _tmp6_;
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	old_time = self->priv->animation_time;
	_tmp0_ = self->priv->animation_timer;
	self->priv->animation_time = g_timer_elapsed (_tmp0_, NULL);
	timestep = self->priv->animation_time - old_time;
	animate_count = 0;
	_tmp1_ = self->pieces;
	{
		GList* model_collection = NULL;
		GList* model_it = NULL;
		model_collection = _tmp1_;
		for (model_it = model_collection; model_it != NULL; model_it = model_it->next) {
			ChessModel* _tmp2_;
			ChessModel* model = NULL;
			_tmp2_ = _g_object_ref0 ((ChessModel*) model_it->data);
			model = _tmp2_;
			{
				ChessModel* _tmp3_;
				_tmp3_ = model;
				if (chess_model_animate (_tmp3_, timestep)) {
					gint _tmp4_;
					_tmp4_ = animate_count;
					animate_count = _tmp4_ + 1;
				}
				_g_object_unref0 (model);
			}
		}
	}
	self->animating = animate_count > 0;
	g_signal_emit (self, chess_scene_signals[CHESS_SCENE_CHANGED_SIGNAL], 0);
	if (self->animating) {
		result = G_SOURCE_CONTINUE;
		return result;
	}
	_tmp5_ = chess_scene_get_game (self);
	_tmp6_ = _tmp5_;
	chess_game_remove_hold (_tmp6_);
	self->priv->animate_timeout_id = (guint) 0;
	result = G_SOURCE_REMOVE;
	return result;
}

ChessGame*
chess_scene_get_game (ChessScene* self)
{
	ChessGame* result;
	ChessGame* _tmp0_;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = self->priv->_game;
	result = _tmp0_;
	return result;
}

static void
_chess_scene_moved_cb_chess_game_moved (ChessGame* _sender,
                                        ChessMove* move,
                                        gpointer self)
{
	chess_scene_moved_cb ((ChessScene*) self, _sender, move);
}

static void
_chess_scene_paused_cb_chess_game_paused (ChessGame* _sender,
                                          gpointer self)
{
	chess_scene_paused_cb ((ChessScene*) self, _sender);
}

static void
_chess_scene_unpaused_cb_chess_game_unpaused (ChessGame* _sender,
                                              gpointer self)
{
	chess_scene_unpaused_cb ((ChessScene*) self, _sender);
}

static void
_chess_scene_undo_cb_chess_game_undo (ChessGame* _sender,
                                      gpointer self)
{
	chess_scene_undo_cb ((ChessScene*) self, _sender);
}

void
chess_scene_set_game (ChessScene* self,
                      ChessGame* value)
{
	ChessGame* _tmp0_;
	ChessGame* _tmp9_;
	ChessGame* _tmp10_;
	ChessGame* _tmp11_;
	ChessGame* _tmp12_;
	ChessGame* _tmp13_;
	g_return_if_fail (self != NULL);
	if (self->priv->animate_timeout_id != ((guint) 0)) {
		g_source_remove (self->priv->animate_timeout_id);
		self->priv->animate_timeout_id = (guint) 0;
		self->animating = FALSE;
	}
	_tmp0_ = self->priv->_game;
	if (_tmp0_ != NULL) {
		ChessGame* _tmp1_;
		guint _tmp2_;
		ChessGame* _tmp3_;
		guint _tmp4_;
		ChessGame* _tmp5_;
		guint _tmp6_;
		ChessGame* _tmp7_;
		guint _tmp8_;
		_tmp1_ = self->priv->_game;
		g_signal_parse_name ("moved", TYPE_CHESS_GAME, &_tmp2_, NULL, FALSE);
		g_signal_handlers_disconnect_matched (_tmp1_, G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA, _tmp2_, 0, NULL, (GCallback) _chess_scene_moved_cb_chess_game_moved, self);
		_tmp3_ = self->priv->_game;
		g_signal_parse_name ("paused", TYPE_CHESS_GAME, &_tmp4_, NULL, FALSE);
		g_signal_handlers_disconnect_matched (_tmp3_, G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA, _tmp4_, 0, NULL, (GCallback) _chess_scene_paused_cb_chess_game_paused, self);
		_tmp5_ = self->priv->_game;
		g_signal_parse_name ("unpaused", TYPE_CHESS_GAME, &_tmp6_, NULL, FALSE);
		g_signal_handlers_disconnect_matched (_tmp5_, G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA, _tmp6_, 0, NULL, (GCallback) _chess_scene_unpaused_cb_chess_game_unpaused, self);
		_tmp7_ = self->priv->_game;
		g_signal_parse_name ("undo", TYPE_CHESS_GAME, &_tmp8_, NULL, FALSE);
		g_signal_handlers_disconnect_matched (_tmp7_, G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA, _tmp8_, 0, NULL, (GCallback) _chess_scene_undo_cb_chess_game_undo, self);
	}
	_tmp9_ = _g_object_ref0 (value);
	_g_object_unref0 (self->priv->_game);
	self->priv->_game = _tmp9_;
	_tmp10_ = self->priv->_game;
	g_signal_connect_object (_tmp10_, "moved", (GCallback) _chess_scene_moved_cb_chess_game_moved, self, 0);
	_tmp11_ = self->priv->_game;
	g_signal_connect_object (_tmp11_, "paused", (GCallback) _chess_scene_paused_cb_chess_game_paused, self, 0);
	_tmp12_ = self->priv->_game;
	g_signal_connect_object (_tmp12_, "unpaused", (GCallback) _chess_scene_unpaused_cb_chess_game_unpaused, self, 0);
	_tmp13_ = self->priv->_game;
	g_signal_connect_object (_tmp13_, "undo", (GCallback) _chess_scene_undo_cb_chess_game_undo, self, 0);
	self->priv->_move_number = -1;
	self->selected_rank = -1;
	self->selected_file = -1;
	chess_scene_update_board (self);
	g_object_notify_by_pspec ((GObject *) self, chess_scene_properties[CHESS_SCENE_GAME_PROPERTY]);
}

gint
chess_scene_get_move_number (ChessScene* self)
{
	gint result;
	g_return_val_if_fail (self != NULL, 0);
	result = self->priv->_move_number;
	return result;
}

void
chess_scene_set_move_number (ChessScene* self,
                             gint value)
{
	g_return_if_fail (self != NULL);
	if (self->priv->_move_number == value) {
		return;
	}
	self->priv->_move_number = value;
	chess_scene_update_board (self);
	g_object_notify_by_pspec ((GObject *) self, chess_scene_properties[CHESS_SCENE_MOVE_NUMBER_PROPERTY]);
}

gboolean
chess_scene_get_show_numbering (ChessScene* self)
{
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	result = self->priv->_show_numbering;
	return result;
}

void
chess_scene_set_show_numbering (ChessScene* self,
                                gboolean value)
{
	g_return_if_fail (self != NULL);
	self->priv->_show_numbering = value;
	g_signal_emit (self, chess_scene_signals[CHESS_SCENE_CHANGED_SIGNAL], 0);
	g_object_notify_by_pspec ((GObject *) self, chess_scene_properties[CHESS_SCENE_SHOW_NUMBERING_PROPERTY]);
}

gboolean
chess_scene_get_show_move_hints (ChessScene* self)
{
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	result = self->priv->_show_move_hints;
	return result;
}

void
chess_scene_set_show_move_hints (ChessScene* self,
                                 gboolean value)
{
	g_return_if_fail (self != NULL);
	self->priv->_show_move_hints = value;
	g_signal_emit (self, chess_scene_signals[CHESS_SCENE_CHANGED_SIGNAL], 0);
	g_object_notify_by_pspec ((GObject *) self, chess_scene_properties[CHESS_SCENE_SHOW_MOVE_HINTS_PROPERTY]);
}

const gchar*
chess_scene_get_theme_name (ChessScene* self)
{
	const gchar* result;
	const gchar* _tmp0_;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = self->priv->_theme_name;
	result = _tmp0_;
	return result;
}

void
chess_scene_set_theme_name (ChessScene* self,
                            const gchar* value)
{
	gchar* _tmp0_;
	g_return_if_fail (self != NULL);
	_tmp0_ = g_strdup (value);
	_g_free0 (self->priv->_theme_name);
	self->priv->_theme_name = _tmp0_;
	g_signal_emit (self, chess_scene_signals[CHESS_SCENE_CHANGED_SIGNAL], 0);
	g_object_notify_by_pspec ((GObject *) self, chess_scene_properties[CHESS_SCENE_THEME_NAME_PROPERTY]);
}

gboolean
chess_scene_get_show_3d_smooth (ChessScene* self)
{
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	result = self->priv->_show_3d_smooth;
	return result;
}

void
chess_scene_set_show_3d_smooth (ChessScene* self,
                                gboolean value)
{
	g_return_if_fail (self != NULL);
	self->priv->_show_3d_smooth = value;
	g_signal_emit (self, chess_scene_signals[CHESS_SCENE_CHANGED_SIGNAL], 0);
	g_object_notify_by_pspec ((GObject *) self, chess_scene_properties[CHESS_SCENE_SHOW_3D_SMOOTH_PROPERTY]);
}

const gchar*
chess_scene_get_board_side (ChessScene* self)
{
	const gchar* result;
	const gchar* _tmp0_;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = self->priv->_board_side;
	result = _tmp0_;
	return result;
}

void
chess_scene_set_board_side (ChessScene* self,
                            const gchar* value)
{
	gchar* _tmp0_;
	g_return_if_fail (self != NULL);
	_tmp0_ = g_strdup (value);
	_g_free0 (self->priv->_board_side);
	self->priv->_board_side = _tmp0_;
	g_signal_emit (self, chess_scene_signals[CHESS_SCENE_CHANGED_SIGNAL], 0);
	g_object_notify_by_pspec ((GObject *) self, chess_scene_properties[CHESS_SCENE_BOARD_SIDE_PROPERTY]);
}

gdouble
chess_scene_get_board_angle (ChessScene* self)
{
	gdouble result;
	const gchar* _tmp0_;
	const gchar* _tmp1_;
	const gchar* _tmp2_;
	GQuark _tmp4_ = 0U;
	static GQuark _tmp3_label0 = 0;
	static GQuark _tmp3_label1 = 0;
	static GQuark _tmp3_label2 = 0;
	g_return_val_if_fail (self != NULL, 0.0);
	_tmp0_ = chess_scene_get_board_side (self);
	_tmp1_ = _tmp0_;
	_tmp2_ = _tmp1_;
	_tmp4_ = (NULL == _tmp2_) ? 0 : g_quark_from_string (_tmp2_);
	if (_tmp4_ == ((0 != _tmp3_label0) ? _tmp3_label0 : (_tmp3_label0 = g_quark_from_static_string ("black")))) {
		switch (0) {
			default:
			{
				result = 180.0;
				return result;
			}
		}
	} else if (_tmp4_ == ((0 != _tmp3_label1) ? _tmp3_label1 : (_tmp3_label1 = g_quark_from_static_string ("human")))) {
		switch (0) {
			default:
			{
				ChessGame* _tmp5_;
				ChessGame* _tmp6_;
				ChessPlayer* _tmp7_;
				ChessPlayer* _tmp8_;
				gboolean _tmp9_ = FALSE;
				_tmp5_ = chess_scene_get_game (self);
				_tmp6_ = _tmp5_;
				_tmp7_ = chess_game_get_black (_tmp6_);
				_tmp8_ = _tmp7_;
				g_signal_emit (self, chess_scene_signals[CHESS_SCENE_IS_HUMAN_SIGNAL], 0, _tmp8_, &_tmp9_);
				if (_tmp9_) {
					result = 180.0;
					return result;
				} else {
					result = 0.0;
					return result;
				}
			}
		}
	} else if (_tmp4_ == ((0 != _tmp3_label2) ? _tmp3_label2 : (_tmp3_label2 = g_quark_from_static_string ("current")))) {
		switch (0) {
			default:
			{
				gdouble _tmp10_ = 0.0;
				ChessGame* _tmp11_;
				ChessGame* _tmp12_;
				ChessPlayer* _tmp13_;
				ChessPlayer* _tmp14_;
				_tmp11_ = chess_scene_get_game (self);
				_tmp12_ = _tmp11_;
				_tmp13_ = chess_game_get_current_player (_tmp12_);
				_tmp14_ = _tmp13_;
				if (_tmp14_->color == COLOR_WHITE) {
					_tmp10_ = 0.0;
				} else {
					_tmp10_ = 180.0;
				}
				result = _tmp10_;
				return result;
			}
		}
	} else {
		switch (0) {
			default:
			{
				result = 0.0;
				return result;
			}
		}
	}
}

const gchar*
chess_scene_get_move_format (ChessScene* self)
{
	const gchar* result;
	const gchar* _tmp0_;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = self->priv->_move_format;
	result = _tmp0_;
	return result;
}

void
chess_scene_set_move_format (ChessScene* self,
                             const gchar* value)
{
	gchar* _tmp0_;
	g_return_if_fail (self != NULL);
	_tmp0_ = g_strdup (value);
	_g_free0 (self->priv->_move_format);
	self->priv->_move_format = _tmp0_;
	g_signal_emit (self, chess_scene_signals[CHESS_SCENE_CHANGED_SIGNAL], 0);
	g_object_notify_by_pspec ((GObject *) self, chess_scene_properties[CHESS_SCENE_MOVE_FORMAT_PROPERTY]);
}

static void
g_cclosure_user_marshal_BOOLEAN__OBJECT (GClosure * closure,
                                         GValue * return_value,
                                         guint n_param_values,
                                         const GValue * param_values,
                                         gpointer invocation_hint,
                                         gpointer marshal_data)
{
	typedef gboolean (*GMarshalFunc_BOOLEAN__OBJECT) (gpointer data1, gpointer arg_1, gpointer data2);
	register GMarshalFunc_BOOLEAN__OBJECT callback;
	register GCClosure * cc;
	register gpointer data1;
	register gpointer data2;
	gboolean v_return;
	cc = (GCClosure *) closure;
	g_return_if_fail (return_value != NULL);
	g_return_if_fail (n_param_values == 2);
	if (G_CCLOSURE_SWAP_DATA (closure)) {
		data1 = closure->data;
		data2 = param_values->data[0].v_pointer;
	} else {
		data1 = param_values->data[0].v_pointer;
		data2 = closure->data;
	}
	callback = (GMarshalFunc_BOOLEAN__OBJECT) (marshal_data ? marshal_data : cc->callback);
	v_return = callback (data1, g_value_get_object (param_values + 1), data2);
	g_value_set_boolean (return_value, v_return);
}

static void
g_cclosure_user_marshal_VOID__POINTER_POINTER_POINTER (GClosure * closure,
                                                       GValue * return_value,
                                                       guint n_param_values,
                                                       const GValue * param_values,
                                                       gpointer invocation_hint,
                                                       gpointer marshal_data)
{
	typedef void (*GMarshalFunc_VOID__POINTER_POINTER_POINTER) (gpointer data1, gpointer arg_1, gpointer arg_2, GDestroyNotify arg_3, gpointer data2);
	register GMarshalFunc_VOID__POINTER_POINTER_POINTER callback;
	register GCClosure * cc;
	register gpointer data1;
	register gpointer data2;
	cc = (GCClosure *) closure;
	g_return_if_fail (n_param_values == 4);
	if (G_CCLOSURE_SWAP_DATA (closure)) {
		data1 = closure->data;
		data2 = param_values->data[0].v_pointer;
	} else {
		data1 = param_values->data[0].v_pointer;
		data2 = closure->data;
	}
	callback = (GMarshalFunc_VOID__POINTER_POINTER_POINTER) (marshal_data ? marshal_data : cc->callback);
	callback (data1, g_value_get_pointer (param_values + 1), g_value_get_pointer (param_values + 2), g_value_get_pointer (param_values + 3), data2);
}

static void
chess_scene_class_init (ChessSceneClass * klass,
                        gpointer klass_data)
{
	chess_scene_parent_class = g_type_class_peek_parent (klass);
	g_type_class_adjust_private_offset (klass, &ChessScene_private_offset);
	G_OBJECT_CLASS (klass)->get_property = _vala_chess_scene_get_property;
	G_OBJECT_CLASS (klass)->set_property = _vala_chess_scene_set_property;
	G_OBJECT_CLASS (klass)->finalize = chess_scene_finalize;
	g_object_class_install_property (G_OBJECT_CLASS (klass), CHESS_SCENE_GAME_PROPERTY, chess_scene_properties[CHESS_SCENE_GAME_PROPERTY] = g_param_spec_object ("game", "game", "game", TYPE_CHESS_GAME, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE | G_PARAM_WRITABLE));
	g_object_class_install_property (G_OBJECT_CLASS (klass), CHESS_SCENE_MOVE_NUMBER_PROPERTY, chess_scene_properties[CHESS_SCENE_MOVE_NUMBER_PROPERTY] = g_param_spec_int ("move-number", "move-number", "move-number", G_MININT, G_MAXINT, 0, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE | G_PARAM_WRITABLE));
	g_object_class_install_property (G_OBJECT_CLASS (klass), CHESS_SCENE_SHOW_NUMBERING_PROPERTY, chess_scene_properties[CHESS_SCENE_SHOW_NUMBERING_PROPERTY] = g_param_spec_boolean ("show-numbering", "show-numbering", "show-numbering", FALSE, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE | G_PARAM_WRITABLE));
	g_object_class_install_property (G_OBJECT_CLASS (klass), CHESS_SCENE_SHOW_MOVE_HINTS_PROPERTY, chess_scene_properties[CHESS_SCENE_SHOW_MOVE_HINTS_PROPERTY] = g_param_spec_boolean ("show-move-hints", "show-move-hints", "show-move-hints", FALSE, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE | G_PARAM_WRITABLE));
	g_object_class_install_property (G_OBJECT_CLASS (klass), CHESS_SCENE_THEME_NAME_PROPERTY, chess_scene_properties[CHESS_SCENE_THEME_NAME_PROPERTY] = g_param_spec_string ("theme-name", "theme-name", "theme-name", NULL, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE | G_PARAM_WRITABLE));
	g_object_class_install_property (G_OBJECT_CLASS (klass), CHESS_SCENE_SHOW_3D_SMOOTH_PROPERTY, chess_scene_properties[CHESS_SCENE_SHOW_3D_SMOOTH_PROPERTY] = g_param_spec_boolean ("show-3d-smooth", "show-3d-smooth", "show-3d-smooth", FALSE, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE | G_PARAM_WRITABLE));
	g_object_class_install_property (G_OBJECT_CLASS (klass), CHESS_SCENE_BOARD_SIDE_PROPERTY, chess_scene_properties[CHESS_SCENE_BOARD_SIDE_PROPERTY] = g_param_spec_string ("board-side", "board-side", "board-side", NULL, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE | G_PARAM_WRITABLE));
	g_object_class_install_property (G_OBJECT_CLASS (klass), CHESS_SCENE_BOARD_ANGLE_PROPERTY, chess_scene_properties[CHESS_SCENE_BOARD_ANGLE_PROPERTY] = g_param_spec_double ("board-angle", "board-angle", "board-angle", -G_MAXDOUBLE, G_MAXDOUBLE, 0.0, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
	g_object_class_install_property (G_OBJECT_CLASS (klass), CHESS_SCENE_MOVE_FORMAT_PROPERTY, chess_scene_properties[CHESS_SCENE_MOVE_FORMAT_PROPERTY] = g_param_spec_string ("move-format", "move-format", "move-format", NULL, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE | G_PARAM_WRITABLE));
	chess_scene_signals[CHESS_SCENE_IS_HUMAN_SIGNAL] = g_signal_new ("is-human", TYPE_CHESS_SCENE, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_user_marshal_BOOLEAN__OBJECT, G_TYPE_BOOLEAN, 1, TYPE_CHESS_PLAYER);
	chess_scene_signals[CHESS_SCENE_CHANGED_SIGNAL] = g_signal_new ("changed", TYPE_CHESS_SCENE, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
	chess_scene_signals[CHESS_SCENE_CHOOSE_PROMOTION_TYPE_SIGNAL] = g_signal_new ("choose-promotion-type", TYPE_CHESS_SCENE, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_user_marshal_VOID__POINTER_POINTER_POINTER, G_TYPE_NONE, 3, G_TYPE_POINTER, G_TYPE_POINTER, G_TYPE_POINTER);
}

static void
chess_scene_instance_init (ChessScene * self,
                           gpointer klass)
{
	gchar* _tmp0_;
	gchar* _tmp1_;
	gchar* _tmp2_;
	self->priv = chess_scene_get_instance_private (self);
	self->pieces = NULL;
	self->animating = FALSE;
	self->selected_rank = -1;
	self->selected_file = -1;
	self->priv->animate_timeout_id = (guint) 0;
	self->priv->_game = NULL;
	self->priv->_move_number = -1;
	self->priv->_show_numbering = TRUE;
	self->priv->_show_move_hints = TRUE;
	_tmp0_ = g_strdup ("simple");
	self->priv->_theme_name = _tmp0_;
	self->priv->_show_3d_smooth = FALSE;
	_tmp1_ = g_strdup ("human");
	self->priv->_board_side = _tmp1_;
	_tmp2_ = g_strdup ("human");
	self->priv->_move_format = _tmp2_;
}

static void
chess_scene_finalize (GObject * obj)
{
	ChessScene * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, TYPE_CHESS_SCENE, ChessScene);
	(self->pieces == NULL) ? NULL : (self->pieces = (_g_list_free__g_object_unref0_ (self->pieces), NULL));
	_g_timer_destroy0 (self->priv->animation_timer);
	_g_object_unref0 (self->priv->_game);
	_g_free0 (self->priv->_theme_name);
	_g_free0 (self->priv->_board_side);
	_g_free0 (self->priv->_move_format);
	G_OBJECT_CLASS (chess_scene_parent_class)->finalize (obj);
}

static GType
chess_scene_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (ChessSceneClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) chess_scene_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (ChessScene), 0, (GInstanceInitFunc) chess_scene_instance_init, NULL };
	GType chess_scene_type_id;
	chess_scene_type_id = g_type_register_static (G_TYPE_OBJECT, "ChessScene", &g_define_type_info, 0);
	ChessScene_private_offset = g_type_add_instance_private (chess_scene_type_id, sizeof (ChessScenePrivate));
	return chess_scene_type_id;
}

GType
chess_scene_get_type (void)
{
	static volatile gsize chess_scene_type_id__once = 0;
	if (g_once_init_enter (&chess_scene_type_id__once)) {
		GType chess_scene_type_id;
		chess_scene_type_id = chess_scene_get_type_once ();
		g_once_init_leave (&chess_scene_type_id__once, chess_scene_type_id);
	}
	return chess_scene_type_id__once;
}

static void
_vala_chess_scene_get_property (GObject * object,
                                guint property_id,
                                GValue * value,
                                GParamSpec * pspec)
{
	ChessScene * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (object, TYPE_CHESS_SCENE, ChessScene);
	switch (property_id) {
		case CHESS_SCENE_GAME_PROPERTY:
		g_value_set_object (value, chess_scene_get_game (self));
		break;
		case CHESS_SCENE_MOVE_NUMBER_PROPERTY:
		g_value_set_int (value, chess_scene_get_move_number (self));
		break;
		case CHESS_SCENE_SHOW_NUMBERING_PROPERTY:
		g_value_set_boolean (value, chess_scene_get_show_numbering (self));
		break;
		case CHESS_SCENE_SHOW_MOVE_HINTS_PROPERTY:
		g_value_set_boolean (value, chess_scene_get_show_move_hints (self));
		break;
		case CHESS_SCENE_THEME_NAME_PROPERTY:
		g_value_set_string (value, chess_scene_get_theme_name (self));
		break;
		case CHESS_SCENE_SHOW_3D_SMOOTH_PROPERTY:
		g_value_set_boolean (value, chess_scene_get_show_3d_smooth (self));
		break;
		case CHESS_SCENE_BOARD_SIDE_PROPERTY:
		g_value_set_string (value, chess_scene_get_board_side (self));
		break;
		case CHESS_SCENE_BOARD_ANGLE_PROPERTY:
		g_value_set_double (value, chess_scene_get_board_angle (self));
		break;
		case CHESS_SCENE_MOVE_FORMAT_PROPERTY:
		g_value_set_string (value, chess_scene_get_move_format (self));
		break;
		default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
	}
}

static void
_vala_chess_scene_set_property (GObject * object,
                                guint property_id,
                                const GValue * value,
                                GParamSpec * pspec)
{
	ChessScene * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (object, TYPE_CHESS_SCENE, ChessScene);
	switch (property_id) {
		case CHESS_SCENE_GAME_PROPERTY:
		chess_scene_set_game (self, g_value_get_object (value));
		break;
		case CHESS_SCENE_MOVE_NUMBER_PROPERTY:
		chess_scene_set_move_number (self, g_value_get_int (value));
		break;
		case CHESS_SCENE_SHOW_NUMBERING_PROPERTY:
		chess_scene_set_show_numbering (self, g_value_get_boolean (value));
		break;
		case CHESS_SCENE_SHOW_MOVE_HINTS_PROPERTY:
		chess_scene_set_show_move_hints (self, g_value_get_boolean (value));
		break;
		case CHESS_SCENE_THEME_NAME_PROPERTY:
		chess_scene_set_theme_name (self, g_value_get_string (value));
		break;
		case CHESS_SCENE_SHOW_3D_SMOOTH_PROPERTY:
		chess_scene_set_show_3d_smooth (self, g_value_get_boolean (value));
		break;
		case CHESS_SCENE_BOARD_SIDE_PROPERTY:
		chess_scene_set_board_side (self, g_value_get_string (value));
		break;
		case CHESS_SCENE_MOVE_FORMAT_PROPERTY:
		chess_scene_set_move_format (self, g_value_get_string (value));
		break;
		default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
	}
}

