/* boni.c generated by valac 0.35.2.5-825d5, the Vala compiler
 * generated from boni.vala, do not modify */

/* -*- Mode: vala; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
 * Gnome Nibbles: Gnome Worm Game
 * Copyright (C) 2015 Iulian-Gabriel Radu <iulian.radu67@gmail.com>
 *
 * 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.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
/* This is a fairly literal translation of the GPLv2+ original by*/
/* Sean MacIsaac, Ian Peters, Guillaume Béland.*/

#include <glib.h>
#include <glib-object.h>
#include <gee.h>


#define TYPE_BONUS_TYPE (bonus_type_get_type ())

#define TYPE_BONUS (bonus_get_type ())
#define BONUS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_BONUS, Bonus))
#define BONUS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_BONUS, BonusClass))
#define IS_BONUS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_BONUS))
#define IS_BONUS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_BONUS))
#define BONUS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_BONUS, BonusClass))

typedef struct _Bonus Bonus;
typedef struct _BonusClass BonusClass;
typedef struct _BonusPrivate BonusPrivate;

#define TYPE_BONI (boni_get_type ())
#define BONI(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_BONI, Boni))
#define BONI_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_BONI, BoniClass))
#define IS_BONI(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_BONI))
#define IS_BONI_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_BONI))
#define BONI_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_BONI, BoniClass))

typedef struct _Boni Boni;
typedef struct _BoniClass BoniClass;
typedef struct _BoniPrivate BoniPrivate;
#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))
enum  {
	BONI_BONUS_ADDED_SIGNAL,
	BONI_BONUS_REMOVED_SIGNAL,
	BONI_LAST_SIGNAL
};
static guint boni_signals[BONI_LAST_SIGNAL] = {0};

typedef enum  {
	BONUS_TYPE_REGULAR,
	BONUS_TYPE_HALF,
	BONUS_TYPE_DOUBLE,
	BONUS_TYPE_LIFE,
	BONUS_TYPE_REVERSE,
	BONUS_TYPE_WARP
} BonusType;

struct _Bonus {
	GObject parent_instance;
	BonusPrivate * priv;
	gint x;
	gint y;
	BonusType type;
	gboolean fake;
	gint countdown;
};

struct _BonusClass {
	GObjectClass parent_class;
};

struct _Boni {
	GObject parent_instance;
	BoniPrivate * priv;
	GeeLinkedList* bonuses;
	gint missed;
	gint numleft;
	gint numboni;
	gint numbonuses;
};

struct _BoniClass {
	GObjectClass parent_class;
};


static gpointer bonus_parent_class = NULL;
static gpointer boni_parent_class = NULL;

GType bonus_type_get_type (void) G_GNUC_CONST;
GType bonus_get_type (void) G_GNUC_CONST;
enum  {
	BONUS_DUMMY_PROPERTY
};
Bonus* bonus_new (gint x, gint y, BonusType type, gboolean fake, gint countdown);
Bonus* bonus_construct (GType object_type, gint x, gint y, BonusType type, gboolean fake, gint countdown);
static void bonus_finalize (GObject * obj);
GType boni_get_type (void) G_GNUC_CONST;
enum  {
	BONI_DUMMY_PROPERTY
};
#define BONI_MAX_BONUSES 100
#define BONI_MAX_MISSED 2
Boni* boni_new (gint numworms);
Boni* boni_construct (GType object_type, gint numworms);
void boni_add_bonus (Boni* self, gint* board, int board_length1, int board_length2, gint x, gint y, BonusType type, gboolean fake, gint countdown);
void boni_remove_bonus (Boni* self, gint* board, int board_length1, int board_length2, Bonus* bonus);
#define NIBBLES_GAME_EMPTYCHAR 'a'
void boni_reset (Boni* self, gint numworms);
Bonus* boni_get_bonus (Boni* self, gint* board, int board_length1, int board_length2, gint x, gint y);
static void boni_finalize (GObject * obj);


GType bonus_type_get_type (void) {
	static volatile gsize bonus_type_type_id__volatile = 0;
	if (g_once_init_enter (&bonus_type_type_id__volatile)) {
		static const GEnumValue values[] = {{BONUS_TYPE_REGULAR, "BONUS_TYPE_REGULAR", "regular"}, {BONUS_TYPE_HALF, "BONUS_TYPE_HALF", "half"}, {BONUS_TYPE_DOUBLE, "BONUS_TYPE_DOUBLE", "double"}, {BONUS_TYPE_LIFE, "BONUS_TYPE_LIFE", "life"}, {BONUS_TYPE_REVERSE, "BONUS_TYPE_REVERSE", "reverse"}, {BONUS_TYPE_WARP, "BONUS_TYPE_WARP", "warp"}, {0, NULL, NULL}};
		GType bonus_type_type_id;
		bonus_type_type_id = g_enum_register_static ("BonusType", values);
		g_once_init_leave (&bonus_type_type_id__volatile, bonus_type_type_id);
	}
	return bonus_type_type_id__volatile;
}


Bonus* bonus_construct (GType object_type, gint x, gint y, BonusType type, gboolean fake, gint countdown) {
	Bonus * self = NULL;
	gint _tmp0_;
	gint _tmp1_;
	BonusType _tmp2_;
	gboolean _tmp3_;
	gint _tmp4_;
	self = (Bonus*) g_object_new (object_type, NULL);
	_tmp0_ = x;
	self->x = _tmp0_;
	_tmp1_ = y;
	self->y = _tmp1_;
	_tmp2_ = type;
	self->type = _tmp2_;
	_tmp3_ = fake;
	self->fake = _tmp3_;
	_tmp4_ = countdown;
	self->countdown = _tmp4_;
	return self;
}


Bonus* bonus_new (gint x, gint y, BonusType type, gboolean fake, gint countdown) {
	return bonus_construct (TYPE_BONUS, x, y, type, fake, countdown);
}


static void bonus_class_init (BonusClass * klass) {
	bonus_parent_class = g_type_class_peek_parent (klass);
	G_OBJECT_CLASS (klass)->finalize = bonus_finalize;
}


static void bonus_instance_init (Bonus * self) {
}


static void bonus_finalize (GObject * obj) {
	Bonus * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, TYPE_BONUS, Bonus);
	G_OBJECT_CLASS (bonus_parent_class)->finalize (obj);
}


GType bonus_get_type (void) {
	static volatile gsize bonus_type_id__volatile = 0;
	if (g_once_init_enter (&bonus_type_id__volatile)) {
		static const GTypeInfo g_define_type_info = { sizeof (BonusClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) bonus_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (Bonus), 0, (GInstanceInitFunc) bonus_instance_init, NULL };
		GType bonus_type_id;
		bonus_type_id = g_type_register_static (G_TYPE_OBJECT, "Bonus", &g_define_type_info, 0);
		g_once_init_leave (&bonus_type_id__volatile, bonus_type_id);
	}
	return bonus_type_id__volatile;
}


Boni* boni_construct (GType object_type, gint numworms) {
	Boni * self = NULL;
	GeeLinkedList* _tmp0_;
	gint _tmp1_;
	gint _tmp2_;
	self = (Boni*) g_object_new (object_type, NULL);
	_tmp0_ = gee_linked_list_new (TYPE_BONUS, (GBoxedCopyFunc) g_object_ref, g_object_unref, NULL, NULL, NULL);
	_g_object_unref0 (self->bonuses);
	self->bonuses = _tmp0_;
	self->missed = 0;
	_tmp1_ = numworms;
	self->numboni = 8 + _tmp1_;
	self->numbonuses = 0;
	_tmp2_ = self->numboni;
	self->numleft = _tmp2_;
	return self;
}


Boni* boni_new (gint numworms) {
	return boni_construct (TYPE_BONI, numworms);
}


void boni_add_bonus (Boni* self, gint* board, int board_length1, int board_length2, gint x, gint y, BonusType type, gboolean fake, gint countdown) {
	gint _tmp0_;
	Bonus* bonus;
	gint _tmp1_;
	gint _tmp2_;
	BonusType _tmp3_;
	gboolean _tmp4_;
	gint _tmp5_;
	Bonus* _tmp6_;
	GeeLinkedList* _tmp7_;
	Bonus* _tmp8_;
	gint* _tmp9_;
	gint _tmp9__length1;
	gint _tmp9__length2;
	gint _tmp10_;
	gint _tmp11_;
	BonusType _tmp12_;
	gint _tmp13_;
	gint* _tmp14_;
	gint _tmp14__length1;
	gint _tmp14__length2;
	gint _tmp15_;
	gint _tmp16_;
	BonusType _tmp17_;
	gint _tmp18_;
	gint* _tmp19_;
	gint _tmp19__length1;
	gint _tmp19__length2;
	gint _tmp20_;
	gint _tmp21_;
	BonusType _tmp22_;
	gint _tmp23_;
	gint* _tmp24_;
	gint _tmp24__length1;
	gint _tmp24__length2;
	gint _tmp25_;
	gint _tmp26_;
	BonusType _tmp27_;
	gint _tmp28_;
	gint _tmp29_;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->numbonuses;
	if (_tmp0_ == BONI_MAX_BONUSES) {
		return;
	}
	_tmp1_ = x;
	_tmp2_ = y;
	_tmp3_ = type;
	_tmp4_ = fake;
	_tmp5_ = countdown;
	_tmp6_ = bonus_new (_tmp1_, _tmp2_, _tmp3_, _tmp4_, _tmp5_);
	bonus = _tmp6_;
	_tmp7_ = self->bonuses;
	_tmp8_ = bonus;
	gee_abstract_collection_add ((GeeAbstractCollection*) _tmp7_, _tmp8_);
	_tmp9_ = board;
	_tmp9__length1 = board_length1;
	_tmp9__length2 = board_length2;
	_tmp10_ = x;
	_tmp11_ = y;
	_tmp12_ = type;
	_tmp9_[(_tmp10_ * _tmp9__length2) + _tmp11_] = (gint) (_tmp12_ + 'A');
	_tmp13_ = _tmp9_[(_tmp10_ * _tmp9__length2) + _tmp11_];
	_tmp14_ = board;
	_tmp14__length1 = board_length1;
	_tmp14__length2 = board_length2;
	_tmp15_ = x;
	_tmp16_ = y;
	_tmp17_ = type;
	_tmp14_[((_tmp15_ + 1) * _tmp14__length2) + _tmp16_] = (gint) (_tmp17_ + 'A');
	_tmp18_ = _tmp14_[((_tmp15_ + 1) * _tmp14__length2) + _tmp16_];
	_tmp19_ = board;
	_tmp19__length1 = board_length1;
	_tmp19__length2 = board_length2;
	_tmp20_ = x;
	_tmp21_ = y;
	_tmp22_ = type;
	_tmp19_[(_tmp20_ * _tmp19__length2) + (_tmp21_ + 1)] = (gint) (_tmp22_ + 'A');
	_tmp23_ = _tmp19_[(_tmp20_ * _tmp19__length2) + (_tmp21_ + 1)];
	_tmp24_ = board;
	_tmp24__length1 = board_length1;
	_tmp24__length2 = board_length2;
	_tmp25_ = x;
	_tmp26_ = y;
	_tmp27_ = type;
	_tmp24_[((_tmp25_ + 1) * _tmp24__length2) + (_tmp26_ + 1)] = (gint) (_tmp27_ + 'A');
	_tmp28_ = _tmp24_[((_tmp25_ + 1) * _tmp24__length2) + (_tmp26_ + 1)];
	g_signal_emit (self, boni_signals[BONI_BONUS_ADDED_SIGNAL], 0);
	_tmp29_ = self->numbonuses;
	self->numbonuses = _tmp29_ + 1;
	_g_object_unref0 (bonus);
}


void boni_remove_bonus (Boni* self, gint* board, int board_length1, int board_length2, Bonus* bonus) {
	gint* _tmp0_;
	gint _tmp0__length1;
	gint _tmp0__length2;
	Bonus* _tmp1_;
	gint _tmp2_;
	Bonus* _tmp3_;
	gint _tmp4_;
	gint _tmp5_;
	gint* _tmp6_;
	gint _tmp6__length1;
	gint _tmp6__length2;
	Bonus* _tmp7_;
	gint _tmp8_;
	Bonus* _tmp9_;
	gint _tmp10_;
	gint _tmp11_;
	gint* _tmp12_;
	gint _tmp12__length1;
	gint _tmp12__length2;
	Bonus* _tmp13_;
	gint _tmp14_;
	Bonus* _tmp15_;
	gint _tmp16_;
	gint _tmp17_;
	gint* _tmp18_;
	gint _tmp18__length1;
	gint _tmp18__length2;
	Bonus* _tmp19_;
	gint _tmp20_;
	Bonus* _tmp21_;
	gint _tmp22_;
	gint _tmp23_;
	Bonus* _tmp24_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (bonus != NULL);
	_tmp0_ = board;
	_tmp0__length1 = board_length1;
	_tmp0__length2 = board_length2;
	_tmp1_ = bonus;
	_tmp2_ = _tmp1_->x;
	_tmp3_ = bonus;
	_tmp4_ = _tmp3_->y;
	_tmp0_[(_tmp2_ * _tmp0__length2) + _tmp4_] = (gint) NIBBLES_GAME_EMPTYCHAR;
	_tmp5_ = _tmp0_[(_tmp2_ * _tmp0__length2) + _tmp4_];
	_tmp6_ = board;
	_tmp6__length1 = board_length1;
	_tmp6__length2 = board_length2;
	_tmp7_ = bonus;
	_tmp8_ = _tmp7_->x;
	_tmp9_ = bonus;
	_tmp10_ = _tmp9_->y;
	_tmp6_[((_tmp8_ + 1) * _tmp6__length2) + _tmp10_] = (gint) NIBBLES_GAME_EMPTYCHAR;
	_tmp11_ = _tmp6_[((_tmp8_ + 1) * _tmp6__length2) + _tmp10_];
	_tmp12_ = board;
	_tmp12__length1 = board_length1;
	_tmp12__length2 = board_length2;
	_tmp13_ = bonus;
	_tmp14_ = _tmp13_->x;
	_tmp15_ = bonus;
	_tmp16_ = _tmp15_->y;
	_tmp12_[(_tmp14_ * _tmp12__length2) + (_tmp16_ + 1)] = (gint) NIBBLES_GAME_EMPTYCHAR;
	_tmp17_ = _tmp12_[(_tmp14_ * _tmp12__length2) + (_tmp16_ + 1)];
	_tmp18_ = board;
	_tmp18__length1 = board_length1;
	_tmp18__length2 = board_length2;
	_tmp19_ = bonus;
	_tmp20_ = _tmp19_->x;
	_tmp21_ = bonus;
	_tmp22_ = _tmp21_->y;
	_tmp18_[((_tmp20_ + 1) * _tmp18__length2) + (_tmp22_ + 1)] = (gint) NIBBLES_GAME_EMPTYCHAR;
	_tmp23_ = _tmp18_[((_tmp20_ + 1) * _tmp18__length2) + (_tmp22_ + 1)];
	_tmp24_ = bonus;
	g_signal_emit (self, boni_signals[BONI_BONUS_REMOVED_SIGNAL], 0, _tmp24_);
}


void boni_reset (Boni* self, gint numworms) {
	GeeLinkedList* _tmp0_;
	gint _tmp1_;
	gint _tmp2_;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->bonuses;
	gee_abstract_collection_clear ((GeeAbstractCollection*) _tmp0_);
	self->missed = 0;
	_tmp1_ = numworms;
	self->numboni = 8 + _tmp1_;
	self->numbonuses = 0;
	_tmp2_ = self->numboni;
	self->numleft = _tmp2_;
}


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


Bonus* boni_get_bonus (Boni* self, gint* board, int board_length1, int board_length2, gint x, gint y) {
	Bonus* result = NULL;
	g_return_val_if_fail (self != NULL, NULL);
	{
		GeeLinkedList* _bonus_list;
		GeeLinkedList* _tmp0_;
		GeeLinkedList* _tmp1_;
		gint _bonus_size;
		GeeLinkedList* _tmp2_;
		gint _tmp3_;
		gint _tmp4_;
		gint _bonus_index;
		_tmp0_ = self->bonuses;
		_tmp1_ = _g_object_ref0 (_tmp0_);
		_bonus_list = _tmp1_;
		_tmp2_ = _bonus_list;
		_tmp3_ = gee_abstract_collection_get_size ((GeeCollection*) _tmp2_);
		_tmp4_ = _tmp3_;
		_bonus_size = _tmp4_;
		_bonus_index = -1;
		while (TRUE) {
			gint _tmp5_;
			gint _tmp6_;
			gint _tmp7_;
			Bonus* bonus;
			GeeLinkedList* _tmp8_;
			gint _tmp9_;
			gpointer _tmp10_;
			gboolean _tmp11_ = FALSE;
			gboolean _tmp12_ = FALSE;
			gboolean _tmp13_ = FALSE;
			gboolean _tmp14_ = FALSE;
			gint _tmp15_;
			Bonus* _tmp16_;
			gint _tmp17_;
			_tmp5_ = _bonus_index;
			_bonus_index = _tmp5_ + 1;
			_tmp6_ = _bonus_index;
			_tmp7_ = _bonus_size;
			if (!(_tmp6_ < _tmp7_)) {
				break;
			}
			_tmp8_ = _bonus_list;
			_tmp9_ = _bonus_index;
			_tmp10_ = gee_abstract_list_get ((GeeAbstractList*) _tmp8_, _tmp9_);
			bonus = (Bonus*) _tmp10_;
			_tmp15_ = x;
			_tmp16_ = bonus;
			_tmp17_ = _tmp16_->x;
			if (_tmp15_ == _tmp17_) {
				gint _tmp18_;
				Bonus* _tmp19_;
				gint _tmp20_;
				_tmp18_ = y;
				_tmp19_ = bonus;
				_tmp20_ = _tmp19_->y;
				_tmp14_ = _tmp18_ == _tmp20_;
			} else {
				_tmp14_ = FALSE;
			}
			if (_tmp14_) {
				_tmp13_ = TRUE;
			} else {
				gboolean _tmp21_ = FALSE;
				gint _tmp22_;
				Bonus* _tmp23_;
				gint _tmp24_;
				_tmp22_ = x;
				_tmp23_ = bonus;
				_tmp24_ = _tmp23_->x;
				if (_tmp22_ == (_tmp24_ + 1)) {
					gint _tmp25_;
					Bonus* _tmp26_;
					gint _tmp27_;
					_tmp25_ = y;
					_tmp26_ = bonus;
					_tmp27_ = _tmp26_->y;
					_tmp21_ = _tmp25_ == _tmp27_;
				} else {
					_tmp21_ = FALSE;
				}
				_tmp13_ = _tmp21_;
			}
			if (_tmp13_) {
				_tmp12_ = TRUE;
			} else {
				gboolean _tmp28_ = FALSE;
				gint _tmp29_;
				Bonus* _tmp30_;
				gint _tmp31_;
				_tmp29_ = x;
				_tmp30_ = bonus;
				_tmp31_ = _tmp30_->x;
				if (_tmp29_ == _tmp31_) {
					gint _tmp32_;
					Bonus* _tmp33_;
					gint _tmp34_;
					_tmp32_ = y;
					_tmp33_ = bonus;
					_tmp34_ = _tmp33_->y;
					_tmp28_ = _tmp32_ == (_tmp34_ + 1);
				} else {
					_tmp28_ = FALSE;
				}
				_tmp12_ = _tmp28_;
			}
			if (_tmp12_) {
				_tmp11_ = TRUE;
			} else {
				gboolean _tmp35_ = FALSE;
				gint _tmp36_;
				Bonus* _tmp37_;
				gint _tmp38_;
				_tmp36_ = x;
				_tmp37_ = bonus;
				_tmp38_ = _tmp37_->x;
				if (_tmp36_ == (_tmp38_ + 1)) {
					gint _tmp39_;
					Bonus* _tmp40_;
					gint _tmp41_;
					_tmp39_ = y;
					_tmp40_ = bonus;
					_tmp41_ = _tmp40_->y;
					_tmp35_ = _tmp39_ == (_tmp41_ + 1);
				} else {
					_tmp35_ = FALSE;
				}
				_tmp11_ = _tmp35_;
			}
			if (_tmp11_) {
				result = bonus;
				_g_object_unref0 (_bonus_list);
				return result;
			}
			_g_object_unref0 (bonus);
		}
		_g_object_unref0 (_bonus_list);
	}
	result = NULL;
	return result;
}


static void boni_class_init (BoniClass * klass) {
	boni_parent_class = g_type_class_peek_parent (klass);
	G_OBJECT_CLASS (klass)->finalize = boni_finalize;
	boni_signals[BONI_BONUS_ADDED_SIGNAL] = g_signal_new ("bonus_added", TYPE_BONI, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
	boni_signals[BONI_BONUS_REMOVED_SIGNAL] = g_signal_new ("bonus_removed", TYPE_BONI, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__OBJECT, G_TYPE_NONE, 1, TYPE_BONUS);
}


static void boni_instance_init (Boni * self) {
}


static void boni_finalize (GObject * obj) {
	Boni * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, TYPE_BONI, Boni);
	_g_object_unref0 (self->bonuses);
	G_OBJECT_CLASS (boni_parent_class)->finalize (obj);
}


GType boni_get_type (void) {
	static volatile gsize boni_type_id__volatile = 0;
	if (g_once_init_enter (&boni_type_id__volatile)) {
		static const GTypeInfo g_define_type_info = { sizeof (BoniClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) boni_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (Boni), 0, (GInstanceInitFunc) boni_instance_init, NULL };
		GType boni_type_id;
		boni_type_id = g_type_register_static (G_TYPE_OBJECT, "Boni", &g_define_type_info, 0);
		g_once_init_leave (&boni_type_id__volatile, boni_type_id);
	}
	return boni_type_id__volatile;
}



