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

/* -*- Mode: vala; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
 *
 * Copyright (C) 2010-2016 Robert Ancell
 *
 * 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 <stdlib.h>
#include <string.h>
#include <glib.h>
#include <glib-object.h>

enum  {
	CHESS_MOVE_0_PROPERTY,
	CHESS_MOVE_NUM_PROPERTIES
};
static GParamSpec* chess_move_properties[CHESS_MOVE_NUM_PROPERTIES];
#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))
#define _g_string_free0(var) ((var == NULL) ? NULL : (var = (g_string_free (var, TRUE), NULL)))

static gpointer chess_move_parent_class = NULL;

static gchar* chess_move_make_san (ChessMove* self,
                            gchar** piece_names,
                            gint piece_names_length1);
static void chess_move_finalize (GObject * obj);
static GType chess_move_get_type_once (void);

gchar*
chess_move_get_lan (ChessMove* self)
{
	ChessPiece* _tmp0_;
	GString* builder = NULL;
	GString* _tmp3_;
	ChessPiece* _tmp4_;
	static const gchar promotion_symbols[6] = {' ', 'R', 'N', 'B', 'Q', 'K'};
	ChessPiece* _tmp7_;
	GString* _tmp13_;
	const gchar* _tmp14_;
	gchar* _tmp15_;
	gchar* result;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = self->castling_rook;
	if (_tmp0_ != NULL) {
		if (self->f1 > self->f0) {
			gchar* _tmp1_;
			_tmp1_ = g_strdup ("O-O");
			result = _tmp1_;
			return result;
		} else {
			gchar* _tmp2_;
			_tmp2_ = g_strdup ("O-O-O");
			result = _tmp2_;
			return result;
		}
	}
	_tmp3_ = g_string_new ("");
	builder = _tmp3_;
	_tmp4_ = self->victim;
	if (_tmp4_ != NULL) {
		GString* _tmp5_;
		_tmp5_ = builder;
		g_string_append_printf (_tmp5_, "%c%dx%c%d", 'a' + self->f0, self->r0 + 1, 'a' + self->f1, self->r1 + 1);
	} else {
		GString* _tmp6_;
		_tmp6_ = builder;
		g_string_append_printf (_tmp6_, "%c%d-%c%d", 'a' + self->f0, self->r0 + 1, 'a' + self->f1, self->r1 + 1);
	}
	_tmp7_ = self->promotion_piece;
	if (_tmp7_ != NULL) {
		GString* _tmp8_;
		ChessPiece* _tmp9_;
		gchar _tmp10_;
		_tmp8_ = builder;
		_tmp9_ = self->promotion_piece;
		_tmp10_ = promotion_symbols[_tmp9_->type];
		g_string_append_printf (_tmp8_, "=%c", (gint) _tmp10_);
	}
	switch (self->check_state) {
		case CHECK_STATE_CHECK:
		{
			GString* _tmp11_;
			_tmp11_ = builder;
			g_string_append_c (_tmp11_, '+');
			break;
		}
		case CHECK_STATE_CHECKMATE:
		{
			GString* _tmp12_;
			_tmp12_ = builder;
			g_string_append_c (_tmp12_, '#');
			break;
		}
		default:
		{
			break;
		}
	}
	_tmp13_ = builder;
	_tmp14_ = _tmp13_->str;
	_tmp15_ = g_strdup (_tmp14_);
	result = _tmp15_;
	_g_string_free0 (builder);
	return result;
}

gchar*
chess_move_get_san (ChessMove* self)
{
	static const gchar* piece_names[6] = {"", "R", "N", "B", "Q", "K"};
	gchar* _tmp0_;
	gchar* result;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = chess_move_make_san (self, (gchar**) piece_names, (gint) ((G_N_ELEMENTS (piece_names) * sizeof (const gchar*)) / sizeof (gchar*)));
	result = _tmp0_;
	return result;
}

gchar*
chess_move_get_fan (ChessMove* self)
{
	static const gchar* white_piece_names[6] = {"", "♖", "♘", "♗", "♕", "♔"};
	static const gchar* black_piece_names[6] = {"", "♜", "♞", "♝", "♛", "♚"};
	ChessPiece* _tmp0_;
	Color _tmp1_;
	Color _tmp2_;
	gchar* result;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = self->piece;
	_tmp1_ = chess_piece_get_color (_tmp0_);
	_tmp2_ = _tmp1_;
	if (_tmp2_ == COLOR_WHITE) {
		gchar* _tmp3_;
		_tmp3_ = chess_move_make_san (self, (gchar**) white_piece_names, (gint) ((G_N_ELEMENTS (white_piece_names) * sizeof (const gchar*)) / sizeof (gchar*)));
		result = _tmp3_;
		return result;
	} else {
		gchar* _tmp4_;
		_tmp4_ = chess_move_make_san (self, (gchar**) black_piece_names, (gint) ((G_N_ELEMENTS (black_piece_names) * sizeof (const gchar*)) / sizeof (gchar*)));
		result = _tmp4_;
		return result;
	}
}

static gchar*
chess_move_make_san (ChessMove* self,
                     gchar** piece_names,
                     gint piece_names_length1)
{
	ChessPiece* _tmp0_;
	GString* builder = NULL;
	GString* _tmp3_;
	GString* _tmp4_;
	ChessPiece* _tmp5_;
	const gchar* _tmp6_;
	ChessPiece* _tmp9_;
	GString* _tmp11_;
	ChessPiece* _tmp12_;
	GString* _tmp18_;
	const gchar* _tmp19_;
	gchar* _tmp20_;
	gchar* result;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = self->castling_rook;
	if (_tmp0_ != NULL) {
		if (self->f1 > self->f0) {
			gchar* _tmp1_;
			_tmp1_ = g_strdup ("O-O");
			result = _tmp1_;
			return result;
		} else {
			gchar* _tmp2_;
			_tmp2_ = g_strdup ("O-O-O");
			result = _tmp2_;
			return result;
		}
	}
	_tmp3_ = g_string_new ("");
	builder = _tmp3_;
	_tmp4_ = builder;
	_tmp5_ = self->piece;
	_tmp6_ = piece_names[_tmp5_->type];
	g_string_append (_tmp4_, _tmp6_);
	if (self->ambiguous_file) {
		GString* _tmp7_;
		_tmp7_ = builder;
		g_string_append_printf (_tmp7_, "%c", 'a' + self->f0);
	}
	if (self->ambiguous_rank) {
		GString* _tmp8_;
		_tmp8_ = builder;
		g_string_append_printf (_tmp8_, "%d", self->r0 + 1);
	}
	_tmp9_ = self->victim;
	if (_tmp9_ != NULL) {
		GString* _tmp10_;
		_tmp10_ = builder;
		g_string_append (_tmp10_, "x");
	}
	_tmp11_ = builder;
	g_string_append_printf (_tmp11_, "%c%d", 'a' + self->f1, self->r1 + 1);
	_tmp12_ = self->promotion_piece;
	if (_tmp12_ != NULL) {
		GString* _tmp13_;
		ChessPiece* _tmp14_;
		const gchar* _tmp15_;
		_tmp13_ = builder;
		_tmp14_ = self->promotion_piece;
		_tmp15_ = piece_names[_tmp14_->type];
		g_string_append_printf (_tmp13_, "=%s", _tmp15_);
	}
	switch (self->check_state) {
		case CHECK_STATE_CHECK:
		{
			GString* _tmp16_;
			_tmp16_ = builder;
			g_string_append_c (_tmp16_, '+');
			break;
		}
		case CHECK_STATE_CHECKMATE:
		{
			GString* _tmp17_;
			_tmp17_ = builder;
			g_string_append_c (_tmp17_, '#');
			break;
		}
		default:
		{
			break;
		}
	}
	_tmp18_ = builder;
	_tmp19_ = _tmp18_->str;
	_tmp20_ = g_strdup (_tmp19_);
	result = _tmp20_;
	_g_string_free0 (builder);
	return result;
}

gchar*
chess_move_get_engine (ChessMove* self)
{
	GString* builder = NULL;
	GString* _tmp0_;
	static const gchar promotion_symbols[6] = {' ', 'r', 'n', 'b', 'q', ' '};
	ChessPiece* _tmp1_;
	GString* _tmp6_;
	const gchar* _tmp7_;
	gchar* _tmp8_;
	gchar* result;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = g_string_new ("");
	builder = _tmp0_;
	_tmp1_ = self->promotion_piece;
	if (_tmp1_ != NULL) {
		GString* _tmp2_;
		ChessPiece* _tmp3_;
		gchar _tmp4_;
		_tmp2_ = builder;
		_tmp3_ = self->promotion_piece;
		_tmp4_ = promotion_symbols[_tmp3_->type];
		g_string_append_printf (_tmp2_, "%c%d%c%d%c", 'a' + self->f0, self->r0 + 1, 'a' + self->f1, self->r1 + 1, (gint) _tmp4_);
	} else {
		GString* _tmp5_;
		_tmp5_ = builder;
		g_string_append_printf (_tmp5_, "%c%d%c%d", 'a' + self->f0, self->r0 + 1, 'a' + self->f1, self->r1 + 1);
	}
	_tmp6_ = builder;
	_tmp7_ = _tmp6_->str;
	_tmp8_ = g_strdup (_tmp7_);
	result = _tmp8_;
	_g_string_free0 (builder);
	return result;
}

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

ChessMove*
chess_move_copy (ChessMove* self)
{
	ChessMove* move = NULL;
	ChessMove* _tmp0_;
	ChessPiece* _tmp1_;
	ChessPiece* _tmp2_;
	ChessPiece* _tmp3_;
	ChessPiece* _tmp4_;
	ChessPiece* _tmp5_;
	ChessPiece* _tmp6_;
	ChessPiece* _tmp7_;
	ChessPiece* _tmp8_;
	ChessMove* result;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = chess_move_new ();
	move = _tmp0_;
	move->number = self->number;
	_tmp1_ = self->piece;
	_tmp2_ = _g_object_ref0 (_tmp1_);
	_g_object_unref0 (move->piece);
	move->piece = _tmp2_;
	_tmp3_ = self->promotion_piece;
	_tmp4_ = _g_object_ref0 (_tmp3_);
	_g_object_unref0 (move->promotion_piece);
	move->promotion_piece = _tmp4_;
	_tmp5_ = self->castling_rook;
	_tmp6_ = _g_object_ref0 (_tmp5_);
	_g_object_unref0 (move->castling_rook);
	move->castling_rook = _tmp6_;
	_tmp7_ = self->victim;
	_tmp8_ = _g_object_ref0 (_tmp7_);
	_g_object_unref0 (move->victim);
	move->victim = _tmp8_;
	move->r0 = self->r0;
	move->f0 = self->f0;
	move->r1 = self->r1;
	move->f1 = self->f1;
	move->ambiguous_rank = self->ambiguous_rank;
	move->ambiguous_file = self->ambiguous_file;
	move->en_passant = self->en_passant;
	move->check_state = self->check_state;
	result = move;
	return result;
}

ChessMove*
chess_move_construct (GType object_type)
{
	ChessMove * self = NULL;
	self = (ChessMove*) g_object_new (object_type, NULL);
	return self;
}

ChessMove*
chess_move_new (void)
{
	return chess_move_construct (TYPE_CHESS_MOVE);
}

static void
chess_move_class_init (ChessMoveClass * klass,
                       gpointer klass_data)
{
	chess_move_parent_class = g_type_class_peek_parent (klass);
	G_OBJECT_CLASS (klass)->finalize = chess_move_finalize;
}

static void
chess_move_instance_init (ChessMove * self,
                          gpointer klass)
{
}

static void
chess_move_finalize (GObject * obj)
{
	ChessMove * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, TYPE_CHESS_MOVE, ChessMove);
	_g_object_unref0 (self->piece);
	_g_object_unref0 (self->promotion_piece);
	_g_object_unref0 (self->castling_rook);
	_g_object_unref0 (self->victim);
	G_OBJECT_CLASS (chess_move_parent_class)->finalize (obj);
}

static GType
chess_move_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (ChessMoveClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) chess_move_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (ChessMove), 0, (GInstanceInitFunc) chess_move_instance_init, NULL };
	GType chess_move_type_id;
	chess_move_type_id = g_type_register_static (G_TYPE_OBJECT, "ChessMove", &g_define_type_info, 0);
	return chess_move_type_id;
}

GType
chess_move_get_type (void)
{
	static volatile gsize chess_move_type_id__once = 0;
	if (g_once_init_enter (&chess_move_type_id__once)) {
		GType chess_move_type_id;
		chess_move_type_id = chess_move_get_type_once ();
		g_once_init_leave (&chess_move_type_id__once, chess_move_type_id);
	}
	return chess_move_type_id__once;
}

