/* puzzle-view.c generated by valac 0.56.18-dirty, the Vala compiler
 * generated from puzzle-view.vala, do not modify */

/*
   This file is part of GNOME Klotski.

   Copyright (C) 2010-2013 Robert Ancell

   GNOME Klotski is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

   GNOME Klotski is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License along
   with GNOME Klotski.  If not, see <https://www.gnu.org/licenses/>.
*/

#include <gtk/gtk.h>
#include <glib-object.h>
#include <glib.h>
#include <float.h>
#include <math.h>
#include <librsvg/rsvg.h>
#include <gio/gio.h>
#include <cairo-gobject.h>
#include <stdio.h>
#include <stdlib.h>
#include <gdk/gdk.h>
#include <string.h>

#define PUZZLE_VIEW_SPACE_OFFSET 4
#define PUZZLE_VIEW_SPACE_PADDING 5
#define PUZZLE_VIEW_THEME_OVERLAY_SIZE 8
#define PUZZLE_VIEW_THEME_TILE_SEGMENTS 27
#define PUZZLE_VIEW_THEME_TILE_CENTER 14
#define PUZZLE_VIEW_THEME_TILE_SIZE 34
#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
#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_PUZZLE_VIEW (puzzle_view_get_type ())
#define PUZZLE_VIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_PUZZLE_VIEW, PuzzleView))
#define PUZZLE_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_PUZZLE_VIEW, PuzzleViewClass))
#define IS_PUZZLE_VIEW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_PUZZLE_VIEW))
#define IS_PUZZLE_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_PUZZLE_VIEW))
#define PUZZLE_VIEW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_PUZZLE_VIEW, PuzzleViewClass))

typedef struct _PuzzleView PuzzleView;
typedef struct _PuzzleViewClass PuzzleViewClass;
typedef struct _PuzzleViewPrivate PuzzleViewPrivate;

#define TYPE_PUZZLE (puzzle_get_type ())
#define PUZZLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_PUZZLE, Puzzle))
#define PUZZLE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_PUZZLE, PuzzleClass))
#define IS_PUZZLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_PUZZLE))
#define IS_PUZZLE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_PUZZLE))
#define PUZZLE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_PUZZLE, PuzzleClass))

typedef struct _Puzzle Puzzle;
typedef struct _PuzzleClass PuzzleClass;
enum  {
	PUZZLE_VIEW_0_PROPERTY,
	PUZZLE_VIEW_PUZZLE_PROPERTY,
	PUZZLE_VIEW_NUM_PROPERTIES
};
static GParamSpec* puzzle_view_properties[PUZZLE_VIEW_NUM_PROPERTIES];
#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))
#define _cairo_surface_destroy0(var) ((var == NULL) ? NULL : (var = (cairo_surface_destroy (var), NULL)))
#define _g_error_free0(var) ((var == NULL) ? NULL : (var = (g_error_free (var), NULL)))
#define _cairo_destroy0(var) ((var == NULL) ? NULL : (var = (cairo_destroy (var), NULL)))
typedef struct _PuzzlePrivate PuzzlePrivate;

struct _PuzzleView {
	GtkDrawingArea parent_instance;
	PuzzleViewPrivate * priv;
};

struct _PuzzleViewClass {
	GtkDrawingAreaClass parent_class;
};

struct _PuzzleViewPrivate {
	gint render_size;
	guint8 piece_x;
	guint8 piece_y;
	gboolean piece_unmoved;
	gchar _piece_id;
	gchar last_piece_id;
	gdouble kx;
	gdouble ky;
	gboolean tiles_handle_init_done;
	RsvgHandle* tiles_handle;
	GFile* image_file;
	cairo_surface_t* surface;
	gboolean puzzle_init_done;
	Puzzle* _puzzle;
	GtkStyleContext* style_context;
	GtkEventControllerMotion* motion_controller;
	GtkGestureMultiPress* click_controller;
};

struct _Puzzle {
	GObject parent_instance;
	PuzzlePrivate * priv;
	gchar* map;
	gint map_length1;
	gint _map_size_;
	gchar* move_map;
	gint move_map_length1;
	gint _move_map_size_;
	gchar* orig_map;
	gint orig_map_length1;
	gint _orig_map_size_;
	gchar* lastmove_map;
	gint lastmove_map_length1;
	gint _lastmove_map_size_;
	gchar* undomove_map;
	gint undomove_map_length1;
	gint _undomove_map_size_;
};

struct _PuzzleClass {
	GObjectClass parent_class;
};

static gint PuzzleView_private_offset;
static gpointer puzzle_view_parent_class = NULL;

VALA_EXTERN GType puzzle_view_get_type (void) G_GNUC_CONST ;
G_DEFINE_AUTOPTR_CLEANUP_FUNC (PuzzleView, g_object_unref)
VALA_EXTERN GType puzzle_get_type (void) G_GNUC_CONST ;
G_DEFINE_AUTOPTR_CLEANUP_FUNC (Puzzle, g_object_unref)
static void puzzle_view_load_image (PuzzleView* self);
static gboolean puzzle_view_real_draw (GtkWidget* base,
                                cairo_t* cr);
static gint puzzle_view_get_tile_size (PuzzleView* self);
static Puzzle* puzzle_view_get_puzzle (PuzzleView* self);
VALA_EXTERN guint8 puzzle_get_width (Puzzle* self);
VALA_EXTERN guint8 puzzle_get_height (Puzzle* self);
static void puzzle_view_draw_square (PuzzleView* self,
                              cairo_t* cr,
                              guint8 x,
                              guint8 y,
                              gdouble kx,
                              gdouble ky);
static gchar puzzle_view_get_piece_id (PuzzleView* self);
VALA_EXTERN gchar puzzle_get_piece_id (Puzzle* self,
                           gchar* src,
                           gint src_length1,
                           guint8 x,
                           guint8 y);
VALA_EXTERN gint puzzle_get_piece_nr (Puzzle* self,
                          guint8 x,
                          guint8 y);
static void puzzle_view_init_mouse (PuzzleView* self);
static inline void puzzle_view_on_motion (GtkEventControllerMotion* _motion_controller,
                            gdouble event_x,
                            gdouble event_y);
static void _puzzle_view_on_motion_gtk_event_controller_motion_motion (GtkEventControllerMotion* _sender,
                                                                gdouble x,
                                                                gdouble y,
                                                                gpointer self);
static inline void puzzle_view_on_click (GtkGestureMultiPress* _click_controller,
                           gint n_press,
                           gdouble event_x,
                           gdouble event_y);
static void _puzzle_view_on_click_gtk_gesture_multi_press_pressed (GtkGestureMultiPress* _sender,
                                                            gint n_press,
                                                            gdouble x,
                                                            gdouble y,
                                                            gpointer self);
static inline void puzzle_view_on_release (GtkGestureMultiPress* _click_controller,
                             gint n_press,
                             gdouble event_x,
                             gdouble event_y);
static void _puzzle_view_on_release_gtk_gesture_multi_press_released (GtkGestureMultiPress* _sender,
                                                               gint n_press,
                                                               gdouble x,
                                                               gdouble y,
                                                               gpointer self);
VALA_EXTERN gboolean puzzle_game_over (Puzzle* self);
static void puzzle_view_set_piece_id (PuzzleView* self,
                               gchar value);
VALA_EXTERN gboolean puzzle_is_static_tile (gchar id);
static void puzzle_view_validate_move (PuzzleView* self);
VALA_EXTERN gboolean puzzle_can_be_moved (Puzzle* self,
                              gchar id);
static gchar* _vala_array_dup7 (gchar* self,
                         gssize length);
VALA_EXTERN gboolean puzzle_mapcmp (Puzzle* self,
                        gchar* m1,
                        gint m1_length1,
                        gchar* m2,
                        gint m2_length1);
static gchar* _vala_array_dup8 (gchar* self,
                         gssize length);
VALA_EXTERN guint16 puzzle_get_moves (Puzzle* self);
VALA_EXTERN void puzzle_set_moves (Puzzle* self,
                       guint16 value);
static gchar* _vala_array_dup9 (gchar* self,
                         gssize length);
VALA_EXTERN gboolean puzzle_move_piece (Puzzle* self,
                            gchar id,
                            guint8 x1,
                            guint8 y1,
                            guint8 x2,
                            guint8 y2);
VALA_EXTERN PuzzleView* puzzle_view_new (void);
VALA_EXTERN PuzzleView* puzzle_view_construct (GType object_type);
VALA_EXTERN void puzzle_view_set_puzzle (PuzzleView* self,
                             Puzzle* value);
static void _gtk_widget_queue_draw_puzzle_changed (Puzzle* _sender,
                                            gpointer self);
static GObject * puzzle_view_constructor (GType type,
                                   guint n_construct_properties,
                                   GObjectConstructParam * construct_properties);
static void puzzle_view_finalize (GObject * obj);
static GType puzzle_view_get_type_once (void);
static void _vala_puzzle_view_get_property (GObject * object,
                                     guint property_id,
                                     GValue * value,
                                     GParamSpec * pspec);
static void _vala_puzzle_view_set_property (GObject * object,
                                     guint property_id,
                                     const GValue * value,
                                     GParamSpec * pspec);
static inline gpointer _vala_memdup2 (gconstpointer mem,
                        gsize byte_size);

static inline gpointer
puzzle_view_get_instance_private (PuzzleView* self)
{
	return G_STRUCT_MEMBER_P (self, PuzzleView_private_offset);
}

static void
puzzle_view_load_image (PuzzleView* self)
{
	GFile* _tmp0_;
	GError* _inner_error0_ = NULL;
	g_return_if_fail (self != NULL);
	_tmp0_ = g_file_new_for_uri ("resource:///org/gnome/Klotski/ui/assets.svg");
	_g_object_unref0 (self->priv->image_file);
	self->priv->image_file = _tmp0_;
	{
		RsvgHandle* _tmp1_ = NULL;
		GFile* _tmp2_;
		RsvgHandle* _tmp3_;
		RsvgHandle* _tmp4_;
		_tmp2_ = self->priv->image_file;
		_tmp3_ = rsvg_handle_new_from_gfile_sync (_tmp2_, RSVG_HANDLE_FLAGS_NONE, NULL, &_inner_error0_);
		_tmp1_ = _tmp3_;
		if (G_UNLIKELY (_inner_error0_ != NULL)) {
			goto __catch0_g_error;
		}
		_tmp4_ = _tmp1_;
		_tmp1_ = NULL;
		_g_object_unref0 (self->priv->tiles_handle);
		self->priv->tiles_handle = _tmp4_;
		_g_object_unref0 (_tmp1_);
	}
	goto __finally0;
	__catch0_g_error:
	{
		GError* e = NULL;
		FILE* _tmp5_;
		GError* _tmp6_;
		const gchar* _tmp7_;
		e = _inner_error0_;
		_inner_error0_ = NULL;
		_tmp5_ = stderr;
		_tmp6_ = e;
		_tmp7_ = _tmp6_->message;
		fprintf (_tmp5_, "%s %s\n", "Error in puzzle-view.vala load image:", _tmp7_);
		exit (EXIT_FAILURE);
		_g_error_free0 (e);
	}
	__finally0:
	if (G_UNLIKELY (_inner_error0_ != NULL)) {
		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;
	}
	self->priv->tiles_handle_init_done = TRUE;
}

static gboolean
puzzle_view_real_draw (GtkWidget* base,
                       cairo_t* cr)
{
	PuzzleView * self;
	gint _tmp0_;
	gint _tmp1_;
	GtkStyleContext* _tmp15_;
	GtkStyleContext* _tmp16_;
	GdkRGBA fg = {0};
	GtkStyleContext* _tmp17_;
	GdkRGBA _tmp18_ = {0};
	GdkRGBA bg = {0};
	GtkStyleContext* _tmp19_;
	GdkRGBA _tmp20_ = {0};
	GtkStyleContext* _tmp21_;
	GdkRGBA _tmp22_;
	gint width = 0;
	gint height = 0;
	GdkRGBA _tmp23_;
	gdouble kwidth = 0.0;
	Puzzle* _tmp24_;
	Puzzle* _tmp25_;
	guint8 _tmp26_;
	guint8 _tmp27_;
	gint _tmp28_;
	gint _tmp29_;
	gdouble kheight = 0.0;
	Puzzle* _tmp30_;
	Puzzle* _tmp31_;
	guint8 _tmp32_;
	guint8 _tmp33_;
	gint _tmp34_;
	gint _tmp35_;
	gboolean result;
	self = (PuzzleView*) base;
	g_return_val_if_fail (cr != NULL, FALSE);
	_tmp0_ = puzzle_view_get_tile_size (self);
	_tmp1_ = _tmp0_;
	if (_tmp1_ != self->priv->render_size) {
		gint _tmp13_;
		gint _tmp14_;
		if (self->priv->tiles_handle_init_done) {
			gint height = 0;
			gint _tmp2_;
			gint _tmp3_;
			gint width = 0;
			gint _tmp4_;
			gint _tmp5_;
			cairo_surface_t* _tmp6_;
			cairo_surface_t* _tmp7_;
			cairo_t* c = NULL;
			cairo_surface_t* _tmp8_;
			cairo_t* _tmp9_;
			gdouble sfw = 0.0;
			gdouble sfh = 0.0;
			cairo_t* _tmp10_;
			RsvgHandle* _tmp11_;
			cairo_t* _tmp12_;
			_tmp2_ = puzzle_view_get_tile_size (self);
			_tmp3_ = _tmp2_;
			height = _tmp3_ * 2;
			_tmp4_ = puzzle_view_get_tile_size (self);
			_tmp5_ = _tmp4_;
			width = _tmp5_ * PUZZLE_VIEW_THEME_TILE_SEGMENTS;
			_tmp6_ = cairo_get_target (cr);
			_tmp7_ = cairo_surface_create_similar (_tmp6_, CAIRO_CONTENT_COLOR_ALPHA, width, height);
			_cairo_surface_destroy0 (self->priv->surface);
			self->priv->surface = _tmp7_;
			_tmp8_ = self->priv->surface;
			_tmp9_ = cairo_create (_tmp8_);
			c = _tmp9_;
			sfw = ((gdouble) width) / 918.0;
			sfh = ((gdouble) height) / 68.0;
			_tmp10_ = c;
			cairo_scale (_tmp10_, sfw, sfh);
			_tmp11_ = self->priv->tiles_handle;
			_tmp12_ = c;
			rsvg_handle_render_cairo (_tmp11_, _tmp12_);
			_cairo_destroy0 (c);
		}
		_tmp13_ = puzzle_view_get_tile_size (self);
		_tmp14_ = _tmp13_;
		self->priv->render_size = _tmp14_;
	}
	_tmp15_ = self->priv->style_context;
	gtk_style_context_save (_tmp15_);
	_tmp16_ = self->priv->style_context;
	gtk_style_context_set_state (_tmp16_, GTK_STATE_FLAG_NORMAL);
	_tmp17_ = self->priv->style_context;
	gtk_style_context_get_color (_tmp17_, GTK_STATE_FLAG_NORMAL, &_tmp18_);
	fg = _tmp18_;
	_tmp19_ = self->priv->style_context;
	gtk_style_context_get_background_color (_tmp19_, GTK_STATE_FLAG_NORMAL, &_tmp20_);
	bg = _tmp20_;
	_tmp21_ = self->priv->style_context;
	gtk_style_context_restore (_tmp21_);
	_tmp22_ = bg;
	gdk_cairo_set_source_rgba (cr, &_tmp22_);
	cairo_paint (cr);
	width = gtk_widget_get_allocated_width ((GtkWidget*) self);
	height = gtk_widget_get_allocated_height ((GtkWidget*) self);
	_tmp23_ = fg;
	gdk_cairo_set_source_rgba (cr, &_tmp23_);
	cairo_set_line_width (cr, 1.0);
	_tmp24_ = puzzle_view_get_puzzle (self);
	_tmp25_ = _tmp24_;
	_tmp26_ = puzzle_get_width (_tmp25_);
	_tmp27_ = _tmp26_;
	_tmp28_ = puzzle_view_get_tile_size (self);
	_tmp29_ = _tmp28_;
	kwidth = ((_tmp27_ * _tmp29_) + PUZZLE_VIEW_SPACE_PADDING) - 2.0;
	_tmp30_ = puzzle_view_get_puzzle (self);
	_tmp31_ = _tmp30_;
	_tmp32_ = puzzle_get_height (_tmp31_);
	_tmp33_ = _tmp32_;
	_tmp34_ = puzzle_view_get_tile_size (self);
	_tmp35_ = _tmp34_;
	kheight = ((_tmp33_ * _tmp35_) + PUZZLE_VIEW_SPACE_PADDING) - 2.0;
	self->priv->kx = (width - kwidth) / 2.0;
	self->priv->ky = (height - kheight) / 2.0;
	cairo_rectangle (cr, self->priv->kx, self->priv->ky, kwidth, kheight);
	cairo_stroke (cr);
	{
		guint8 y = 0U;
		y = (guint8) 0;
		{
			gboolean _tmp36_ = FALSE;
			_tmp36_ = TRUE;
			while (TRUE) {
				Puzzle* _tmp38_;
				Puzzle* _tmp39_;
				guint8 _tmp40_;
				guint8 _tmp41_;
				if (!_tmp36_) {
					guint8 _tmp37_;
					_tmp37_ = y;
					y = _tmp37_ + 1;
				}
				_tmp36_ = FALSE;
				_tmp38_ = puzzle_view_get_puzzle (self);
				_tmp39_ = _tmp38_;
				_tmp40_ = puzzle_get_height (_tmp39_);
				_tmp41_ = _tmp40_;
				if (!(y < _tmp41_)) {
					break;
				}
				{
					guint8 x = 0U;
					x = (guint8) 0;
					{
						gboolean _tmp42_ = FALSE;
						_tmp42_ = TRUE;
						while (TRUE) {
							Puzzle* _tmp44_;
							Puzzle* _tmp45_;
							guint8 _tmp46_;
							guint8 _tmp47_;
							gchar _tmp48_;
							gchar _tmp49_;
							Puzzle* _tmp50_;
							Puzzle* _tmp51_;
							Puzzle* _tmp52_;
							Puzzle* _tmp53_;
							gchar* _tmp54_;
							gint _tmp54__length1;
							if (!_tmp42_) {
								guint8 _tmp43_;
								_tmp43_ = x;
								x = _tmp43_ + 1;
							}
							_tmp42_ = FALSE;
							_tmp44_ = puzzle_view_get_puzzle (self);
							_tmp45_ = _tmp44_;
							_tmp46_ = puzzle_get_width (_tmp45_);
							_tmp47_ = _tmp46_;
							if (!(x < _tmp47_)) {
								break;
							}
							puzzle_view_draw_square (self, cr, x, y, self->priv->kx, self->priv->ky);
							_tmp48_ = puzzle_view_get_piece_id (self);
							_tmp49_ = _tmp48_;
							_tmp50_ = puzzle_view_get_puzzle (self);
							_tmp51_ = _tmp50_;
							_tmp52_ = puzzle_view_get_puzzle (self);
							_tmp53_ = _tmp52_;
							_tmp54_ = _tmp53_->map;
							_tmp54__length1 = _tmp53_->map_length1;
							if (_tmp49_ == puzzle_get_piece_id (_tmp51_, _tmp54_, (gint) _tmp54__length1, x, y)) {
								GdkRGBA _tmp55_ = {0};
								gint _tmp56_;
								gint _tmp57_;
								gint _tmp58_;
								gint _tmp59_;
								gint _tmp60_;
								gint _tmp61_;
								gint _tmp62_;
								gint _tmp63_;
								_tmp55_.red = 1.0;
								_tmp55_.green = 1.0;
								_tmp55_.blue = 1.0;
								_tmp55_.alpha = 0.2;
								gdk_cairo_set_source_rgba (cr, &_tmp55_);
								_tmp56_ = puzzle_view_get_tile_size (self);
								_tmp57_ = _tmp56_;
								_tmp58_ = puzzle_view_get_tile_size (self);
								_tmp59_ = _tmp58_;
								_tmp60_ = puzzle_view_get_tile_size (self);
								_tmp61_ = _tmp60_;
								_tmp62_ = puzzle_view_get_tile_size (self);
								_tmp63_ = _tmp62_;
								cairo_rectangle (cr, (x * _tmp57_) + self->priv->kx, (y * _tmp59_) + self->priv->ky, (gdouble) _tmp61_, (gdouble) _tmp63_);
								cairo_fill (cr);
							}
						}
					}
				}
			}
		}
	}
	result = FALSE;
	return result;
}

static void
puzzle_view_draw_square (PuzzleView* self,
                         cairo_t* cr,
                         guint8 x,
                         guint8 y,
                         gdouble kx,
                         gdouble ky)
{
	GdkRectangle rect = {0};
	gint _tmp0_;
	gint _tmp1_;
	gint _tmp2_;
	gint _tmp3_;
	gint _tmp4_;
	gint _tmp5_;
	gint _tmp6_;
	gint _tmp7_;
	GtkStyleContext* _tmp8_;
	GtkStyleContext* _tmp9_;
	GdkRGBA bg = {0};
	GtkStyleContext* _tmp10_;
	GdkRGBA _tmp11_ = {0};
	GtkStyleContext* _tmp12_;
	GdkRectangle _tmp13_;
	GdkRGBA _tmp14_;
	Puzzle* _tmp15_;
	Puzzle* _tmp16_;
	Puzzle* _tmp17_;
	Puzzle* _tmp18_;
	gchar* _tmp19_;
	gint _tmp19__length1;
	Puzzle* _tmp30_;
	Puzzle* _tmp31_;
	Puzzle* _tmp32_;
	Puzzle* _tmp33_;
	gchar* _tmp34_;
	gint _tmp34__length1;
	g_return_if_fail (self != NULL);
	g_return_if_fail (cr != NULL);
	memset (&rect, 0, sizeof (GdkRectangle));
	_tmp0_ = puzzle_view_get_tile_size (self);
	_tmp1_ = _tmp0_;
	rect.x = (((x * _tmp1_) + PUZZLE_VIEW_SPACE_OFFSET) + ((gint) kx)) - 1;
	_tmp2_ = puzzle_view_get_tile_size (self);
	_tmp3_ = _tmp2_;
	rect.y = (((y * _tmp3_) + PUZZLE_VIEW_SPACE_OFFSET) + ((gint) ky)) - 1;
	_tmp4_ = puzzle_view_get_tile_size (self);
	_tmp5_ = _tmp4_;
	rect.width = _tmp5_;
	_tmp6_ = puzzle_view_get_tile_size (self);
	_tmp7_ = _tmp6_;
	rect.height = _tmp7_;
	_tmp8_ = self->priv->style_context;
	gtk_style_context_save (_tmp8_);
	_tmp9_ = self->priv->style_context;
	gtk_style_context_set_state (_tmp9_, GTK_STATE_FLAG_NORMAL);
	_tmp10_ = self->priv->style_context;
	gtk_style_context_get_background_color (_tmp10_, GTK_STATE_FLAG_NORMAL, &_tmp11_);
	bg = _tmp11_;
	_tmp12_ = self->priv->style_context;
	gtk_style_context_restore (_tmp12_);
	_tmp13_ = rect;
	gdk_cairo_rectangle (cr, &_tmp13_);
	_tmp14_ = bg;
	gdk_cairo_set_source_rgba (cr, &_tmp14_);
	cairo_fill (cr);
	_tmp15_ = puzzle_view_get_puzzle (self);
	_tmp16_ = _tmp15_;
	_tmp17_ = puzzle_view_get_puzzle (self);
	_tmp18_ = _tmp17_;
	_tmp19_ = _tmp18_->map;
	_tmp19__length1 = _tmp18_->map_length1;
	if (puzzle_get_piece_id (_tmp16_, _tmp19_, (gint) _tmp19__length1, x, y) != ' ') {
		GdkRectangle _tmp20_;
		cairo_surface_t* _tmp21_;
		GdkRectangle _tmp22_;
		Puzzle* _tmp23_;
		Puzzle* _tmp24_;
		gint _tmp25_;
		gint _tmp26_;
		GdkRectangle _tmp27_;
		gint _tmp28_;
		gint _tmp29_;
		_tmp20_ = rect;
		gdk_cairo_rectangle (cr, &_tmp20_);
		_tmp21_ = self->priv->surface;
		_tmp22_ = rect;
		_tmp23_ = puzzle_view_get_puzzle (self);
		_tmp24_ = _tmp23_;
		_tmp25_ = puzzle_view_get_tile_size (self);
		_tmp26_ = _tmp25_;
		_tmp27_ = rect;
		_tmp28_ = puzzle_view_get_tile_size (self);
		_tmp29_ = _tmp28_;
		cairo_set_source_surface (cr, _tmp21_, (gdouble) (_tmp22_.x - (puzzle_get_piece_nr (_tmp24_, x, y) * _tmp26_)), (gdouble) (_tmp27_.y - (_tmp29_ / 2)));
		cairo_fill (cr);
	}
	_tmp30_ = puzzle_view_get_puzzle (self);
	_tmp31_ = _tmp30_;
	_tmp32_ = puzzle_view_get_puzzle (self);
	_tmp33_ = _tmp32_;
	_tmp34_ = _tmp33_->map;
	_tmp34__length1 = _tmp33_->map_length1;
	if (puzzle_get_piece_id (_tmp31_, _tmp34_, (gint) _tmp34__length1, x, y) == '*') {
		guint8 tile_value = 0U;
		Puzzle* _tmp35_;
		Puzzle* _tmp36_;
		Puzzle* _tmp37_;
		Puzzle* _tmp38_;
		gchar* _tmp39_;
		gint _tmp39__length1;
		gint overlay_size = 0;
		gint _tmp40_;
		gint _tmp41_;
		gint overlay_offset = 0;
		gint _tmp42_;
		gint _tmp43_;
		GdkRectangle _tmp44_;
		GdkRectangle _tmp45_;
		cairo_surface_t* _tmp46_;
		GdkRectangle _tmp47_;
		gint _tmp48_;
		gint _tmp49_;
		GdkRectangle _tmp50_;
		gint _tmp51_;
		gint _tmp52_;
		tile_value = (guint8) 22;
		_tmp35_ = puzzle_view_get_puzzle (self);
		_tmp36_ = _tmp35_;
		_tmp37_ = puzzle_view_get_puzzle (self);
		_tmp38_ = _tmp37_;
		_tmp39_ = _tmp38_->orig_map;
		_tmp39__length1 = _tmp38_->orig_map_length1;
		if (puzzle_get_piece_id (_tmp36_, _tmp39_, (gint) _tmp39__length1, x, y) == '.') {
			tile_value = (guint8) 20;
		}
		_tmp40_ = puzzle_view_get_tile_size (self);
		_tmp41_ = _tmp40_;
		overlay_size = (PUZZLE_VIEW_THEME_OVERLAY_SIZE * _tmp41_) / PUZZLE_VIEW_THEME_TILE_SIZE;
		_tmp42_ = puzzle_view_get_tile_size (self);
		_tmp43_ = _tmp42_;
		overlay_offset = ((PUZZLE_VIEW_THEME_TILE_CENTER * _tmp43_) / PUZZLE_VIEW_THEME_TILE_SIZE) - (overlay_size / 2);
		_tmp44_ = rect;
		_tmp45_ = rect;
		cairo_rectangle (cr, (gdouble) (_tmp44_.x + overlay_offset), (gdouble) (_tmp45_.y + overlay_offset), (gdouble) overlay_size, (gdouble) overlay_size);
		_tmp46_ = self->priv->surface;
		_tmp47_ = rect;
		_tmp48_ = puzzle_view_get_tile_size (self);
		_tmp49_ = _tmp48_;
		_tmp50_ = rect;
		_tmp51_ = puzzle_view_get_tile_size (self);
		_tmp52_ = _tmp51_;
		cairo_set_source_surface (cr, _tmp46_, (gdouble) (_tmp47_.x - (tile_value * _tmp49_)), (gdouble) (_tmp50_.y - (_tmp52_ / 2)));
		cairo_fill (cr);
	}
}

static void
_puzzle_view_on_motion_gtk_event_controller_motion_motion (GtkEventControllerMotion* _sender,
                                                           gdouble x,
                                                           gdouble y,
                                                           gpointer self)
{
	puzzle_view_on_motion (_sender, x, y);
}

static void
_puzzle_view_on_click_gtk_gesture_multi_press_pressed (GtkGestureMultiPress* _sender,
                                                       gint n_press,
                                                       gdouble x,
                                                       gdouble y,
                                                       gpointer self)
{
	puzzle_view_on_click (_sender, n_press, x, y);
}

static void
_puzzle_view_on_release_gtk_gesture_multi_press_released (GtkGestureMultiPress* _sender,
                                                          gint n_press,
                                                          gdouble x,
                                                          gdouble y,
                                                          gpointer self)
{
	puzzle_view_on_release (_sender, n_press, x, y);
}

static void
puzzle_view_init_mouse (PuzzleView* self)
{
	GtkEventControllerMotion* _tmp0_;
	GtkEventControllerMotion* _tmp1_;
	GtkGestureMultiPress* _tmp2_;
	GtkGestureMultiPress* _tmp3_;
	GtkGestureMultiPress* _tmp4_;
	g_return_if_fail (self != NULL);
	_tmp0_ = (GtkEventControllerMotion*) gtk_event_controller_motion_new ((GtkWidget*) self);
	_g_object_unref0 (self->priv->motion_controller);
	self->priv->motion_controller = _tmp0_;
	_tmp1_ = self->priv->motion_controller;
	g_signal_connect (_tmp1_, "motion", (GCallback) _puzzle_view_on_motion_gtk_event_controller_motion_motion, NULL);
	_tmp2_ = (GtkGestureMultiPress*) gtk_gesture_multi_press_new ((GtkWidget*) self);
	_g_object_unref0 (self->priv->click_controller);
	self->priv->click_controller = _tmp2_;
	_tmp3_ = self->priv->click_controller;
	g_signal_connect (_tmp3_, "pressed", (GCallback) _puzzle_view_on_click_gtk_gesture_multi_press_pressed, NULL);
	_tmp4_ = self->priv->click_controller;
	g_signal_connect (_tmp4_, "released", (GCallback) _puzzle_view_on_release_gtk_gesture_multi_press_released, NULL);
}

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

static gchar*
_vala_array_dup7 (gchar* self,
                  gssize length)
{
	if (length > 0) {
		return _vala_memdup2 (self, length * sizeof (gchar));
	}
	return NULL;
}

static inline void
puzzle_view_on_click (GtkGestureMultiPress* _click_controller,
                      gint n_press,
                      gdouble event_x,
                      gdouble event_y)
{
	PuzzleView* _this = NULL;
	GtkWidget* _tmp0_;
	PuzzleView* _tmp1_;
	PuzzleView* _tmp2_;
	Puzzle* _tmp3_;
	Puzzle* _tmp4_;
	gint new_piece_x = 0;
	PuzzleView* _tmp5_;
	PuzzleView* _tmp6_;
	gint _tmp7_;
	gint _tmp8_;
	gint new_piece_y = 0;
	PuzzleView* _tmp9_;
	PuzzleView* _tmp10_;
	gint _tmp11_;
	gint _tmp12_;
	gboolean _tmp13_ = FALSE;
	gboolean _tmp14_ = FALSE;
	gboolean _tmp15_ = FALSE;
	PuzzleView* _tmp26_;
	PuzzleView* _tmp27_;
	gchar new_piece_id = '\0';
	PuzzleView* _tmp28_;
	Puzzle* _tmp29_;
	Puzzle* _tmp30_;
	PuzzleView* _tmp31_;
	Puzzle* _tmp32_;
	Puzzle* _tmp33_;
	gchar* _tmp34_;
	gint _tmp34__length1;
	PuzzleView* _tmp35_;
	PuzzleView* _tmp36_;
	gboolean already_moving = FALSE;
	PuzzleView* _tmp37_;
	gchar _tmp38_;
	gchar _tmp39_;
	gboolean _tmp40_ = FALSE;
	gboolean _tmp43_ = FALSE;
	PuzzleView* _tmp51_;
	PuzzleView* _tmp52_;
	PuzzleView* _tmp53_;
	Puzzle* _tmp54_;
	Puzzle* _tmp55_;
	PuzzleView* _tmp56_;
	Puzzle* _tmp57_;
	Puzzle* _tmp58_;
	gchar* _tmp59_;
	gint _tmp59__length1;
	gchar* _tmp60_;
	gint _tmp60__length1;
	g_return_if_fail (_click_controller != NULL);
	_tmp0_ = gtk_event_controller_get_widget ((GtkEventController*) _click_controller);
	_tmp1_ = _g_object_ref0 (G_TYPE_CHECK_INSTANCE_CAST (_tmp0_, TYPE_PUZZLE_VIEW, PuzzleView));
	_this = _tmp1_;
	_tmp2_ = _this;
	_tmp3_ = puzzle_view_get_puzzle (_tmp2_);
	_tmp4_ = _tmp3_;
	if (puzzle_game_over (_tmp4_)) {
		_g_object_unref0 (_this);
		return;
	}
	_tmp5_ = _this;
	_tmp6_ = _this;
	_tmp7_ = puzzle_view_get_tile_size (_tmp6_);
	_tmp8_ = _tmp7_;
	new_piece_x = ((gint) (event_x - _tmp5_->priv->kx)) / _tmp8_;
	_tmp9_ = _this;
	_tmp10_ = _this;
	_tmp11_ = puzzle_view_get_tile_size (_tmp10_);
	_tmp12_ = _tmp11_;
	new_piece_y = ((gint) (event_y - _tmp9_->priv->ky)) / _tmp12_;
	if (new_piece_x < 0) {
		_tmp15_ = TRUE;
	} else {
		PuzzleView* _tmp16_;
		Puzzle* _tmp17_;
		Puzzle* _tmp18_;
		guint8 _tmp19_;
		guint8 _tmp20_;
		_tmp16_ = _this;
		_tmp17_ = puzzle_view_get_puzzle (_tmp16_);
		_tmp18_ = _tmp17_;
		_tmp19_ = puzzle_get_width (_tmp18_);
		_tmp20_ = _tmp19_;
		_tmp15_ = new_piece_x >= ((gint) _tmp20_);
	}
	if (_tmp15_) {
		_tmp14_ = TRUE;
	} else {
		_tmp14_ = new_piece_y < 0;
	}
	if (_tmp14_) {
		_tmp13_ = TRUE;
	} else {
		PuzzleView* _tmp21_;
		Puzzle* _tmp22_;
		Puzzle* _tmp23_;
		guint8 _tmp24_;
		guint8 _tmp25_;
		_tmp21_ = _this;
		_tmp22_ = puzzle_view_get_puzzle (_tmp21_);
		_tmp23_ = _tmp22_;
		_tmp24_ = puzzle_get_height (_tmp23_);
		_tmp25_ = _tmp24_;
		_tmp13_ = new_piece_y >= ((gint) _tmp25_);
	}
	if (_tmp13_) {
		_g_object_unref0 (_this);
		return;
	}
	_tmp26_ = _this;
	_tmp26_->priv->piece_x = (guint8) new_piece_x;
	_tmp27_ = _this;
	_tmp27_->priv->piece_y = (guint8) new_piece_y;
	_tmp28_ = _this;
	_tmp29_ = puzzle_view_get_puzzle (_tmp28_);
	_tmp30_ = _tmp29_;
	_tmp31_ = _this;
	_tmp32_ = puzzle_view_get_puzzle (_tmp31_);
	_tmp33_ = _tmp32_;
	_tmp34_ = _tmp33_->map;
	_tmp34__length1 = _tmp33_->map_length1;
	_tmp35_ = _this;
	_tmp36_ = _this;
	new_piece_id = puzzle_get_piece_id (_tmp30_, _tmp34_, (gint) _tmp34__length1, _tmp35_->priv->piece_x, _tmp36_->priv->piece_y);
	_tmp37_ = _this;
	_tmp38_ = puzzle_view_get_piece_id (_tmp37_);
	_tmp39_ = _tmp38_;
	already_moving = _tmp39_ != '\0';
	if (already_moving) {
		PuzzleView* _tmp41_;
		_tmp41_ = _this;
		_tmp40_ = _tmp41_->priv->piece_unmoved;
	} else {
		_tmp40_ = FALSE;
	}
	if (_tmp40_) {
		PuzzleView* _tmp42_;
		_tmp42_ = _this;
		puzzle_view_set_piece_id (_tmp42_, '\0');
		_g_object_unref0 (_this);
		return;
	}
	if (puzzle_is_static_tile (new_piece_id)) {
		_tmp43_ = TRUE;
	} else {
		PuzzleView* _tmp44_;
		gchar _tmp45_;
		gchar _tmp46_;
		_tmp44_ = _this;
		_tmp45_ = puzzle_view_get_piece_id (_tmp44_);
		_tmp46_ = _tmp45_;
		_tmp43_ = new_piece_id == _tmp46_;
	}
	if (_tmp43_) {
		_g_object_unref0 (_this);
		return;
	}
	if (already_moving) {
		PuzzleView* _tmp47_;
		PuzzleView* _tmp48_;
		Puzzle* _tmp49_;
		Puzzle* _tmp50_;
		_tmp47_ = _this;
		puzzle_view_validate_move (_tmp47_);
		_tmp48_ = _this;
		_tmp49_ = puzzle_view_get_puzzle (_tmp48_);
		_tmp50_ = _tmp49_;
		if (!puzzle_can_be_moved (_tmp50_, new_piece_id)) {
			_g_object_unref0 (_this);
			return;
		}
	}
	_tmp51_ = _this;
	_tmp51_->priv->piece_unmoved = TRUE;
	_tmp52_ = _this;
	puzzle_view_set_piece_id (_tmp52_, new_piece_id);
	_tmp53_ = _this;
	_tmp54_ = puzzle_view_get_puzzle (_tmp53_);
	_tmp55_ = _tmp54_;
	_tmp56_ = _this;
	_tmp57_ = puzzle_view_get_puzzle (_tmp56_);
	_tmp58_ = _tmp57_;
	_tmp59_ = _tmp58_->map;
	_tmp59__length1 = _tmp58_->map_length1;
	_tmp60_ = (_tmp59_ != NULL) ? _vala_array_dup7 (_tmp59_, _tmp59__length1) : _tmp59_;
	_tmp60__length1 = _tmp59__length1;
	_tmp55_->move_map = (g_free (_tmp55_->move_map), NULL);
	_tmp55_->move_map = _tmp60_;
	_tmp55_->move_map_length1 = _tmp60__length1;
	_tmp55_->_move_map_size_ = _tmp55_->move_map_length1;
	_g_object_unref0 (_this);
}

static inline void
puzzle_view_on_release (GtkGestureMultiPress* _click_controller,
                        gint n_press,
                        gdouble event_x,
                        gdouble event_y)
{
	PuzzleView* _this = NULL;
	GtkWidget* _tmp0_;
	PuzzleView* _tmp1_;
	PuzzleView* _tmp2_;
	gchar _tmp3_;
	gchar _tmp4_;
	g_return_if_fail (_click_controller != NULL);
	_tmp0_ = gtk_event_controller_get_widget ((GtkEventController*) _click_controller);
	_tmp1_ = _g_object_ref0 (G_TYPE_CHECK_INSTANCE_CAST (_tmp0_, TYPE_PUZZLE_VIEW, PuzzleView));
	_this = _tmp1_;
	_tmp2_ = _this;
	_tmp3_ = puzzle_view_get_piece_id (_tmp2_);
	_tmp4_ = _tmp3_;
	if (_tmp4_ != '\0') {
		PuzzleView* _tmp5_;
		_tmp5_ = _this;
		puzzle_view_validate_move (_tmp5_);
	}
	_g_object_unref0 (_this);
}

static gchar*
_vala_array_dup8 (gchar* self,
                  gssize length)
{
	if (length > 0) {
		return _vala_memdup2 (self, length * sizeof (gchar));
	}
	return NULL;
}

static gchar*
_vala_array_dup9 (gchar* self,
                  gssize length)
{
	if (length > 0) {
		return _vala_memdup2 (self, length * sizeof (gchar));
	}
	return NULL;
}

static void
puzzle_view_validate_move (PuzzleView* self)
{
	gboolean _tmp0_ = FALSE;
	gchar _tmp1_;
	gchar _tmp2_;
	g_return_if_fail (self != NULL);
	if (self->priv->piece_unmoved) {
		return;
	}
	_tmp1_ = puzzle_view_get_piece_id (self);
	_tmp2_ = _tmp1_;
	if (!puzzle_is_static_tile (_tmp2_)) {
		Puzzle* _tmp3_;
		Puzzle* _tmp4_;
		Puzzle* _tmp5_;
		Puzzle* _tmp6_;
		gchar* _tmp7_;
		gint _tmp7__length1;
		Puzzle* _tmp8_;
		Puzzle* _tmp9_;
		gchar* _tmp10_;
		gint _tmp10__length1;
		_tmp3_ = puzzle_view_get_puzzle (self);
		_tmp4_ = _tmp3_;
		_tmp5_ = puzzle_view_get_puzzle (self);
		_tmp6_ = _tmp5_;
		_tmp7_ = _tmp6_->move_map;
		_tmp7__length1 = _tmp6_->move_map_length1;
		_tmp8_ = puzzle_view_get_puzzle (self);
		_tmp9_ = _tmp8_;
		_tmp10_ = _tmp9_->map;
		_tmp10__length1 = _tmp9_->map_length1;
		_tmp0_ = puzzle_mapcmp (_tmp4_, _tmp7_, (gint) _tmp7__length1, _tmp10_, (gint) _tmp10__length1);
	} else {
		_tmp0_ = FALSE;
	}
	if (_tmp0_) {
		gboolean _tmp11_ = FALSE;
		gboolean _tmp28_ = FALSE;
		Puzzle* _tmp29_;
		Puzzle* _tmp30_;
		guint16 _tmp31_;
		guint16 _tmp32_;
		Puzzle* _tmp47_;
		Puzzle* _tmp48_;
		Puzzle* _tmp49_;
		Puzzle* _tmp50_;
		gchar* _tmp51_;
		gint _tmp51__length1;
		gchar* _tmp52_;
		gint _tmp52__length1;
		Puzzle* _tmp53_;
		Puzzle* _tmp54_;
		if (self->priv->last_piece_id == '\0') {
			_tmp11_ = TRUE;
		} else {
			gchar _tmp12_;
			gchar _tmp13_;
			_tmp12_ = puzzle_view_get_piece_id (self);
			_tmp13_ = _tmp12_;
			_tmp11_ = self->priv->last_piece_id != _tmp13_;
		}
		if (_tmp11_) {
			Puzzle* _tmp14_;
			Puzzle* _tmp15_;
			Puzzle* _tmp16_;
			Puzzle* _tmp17_;
			gchar* _tmp18_;
			gint _tmp18__length1;
			gchar* _tmp19_;
			gint _tmp19__length1;
			Puzzle* _tmp20_;
			Puzzle* _tmp21_;
			guint16 _tmp22_;
			guint16 _tmp23_;
			_tmp14_ = puzzle_view_get_puzzle (self);
			_tmp15_ = _tmp14_;
			_tmp16_ = puzzle_view_get_puzzle (self);
			_tmp17_ = _tmp16_;
			_tmp18_ = _tmp17_->lastmove_map;
			_tmp18__length1 = _tmp17_->lastmove_map_length1;
			_tmp19_ = (_tmp18_ != NULL) ? _vala_array_dup8 (_tmp18_, _tmp18__length1) : _tmp18_;
			_tmp19__length1 = _tmp18__length1;
			_tmp15_->undomove_map = (g_free (_tmp15_->undomove_map), NULL);
			_tmp15_->undomove_map = _tmp19_;
			_tmp15_->undomove_map_length1 = _tmp19__length1;
			_tmp15_->_undomove_map_size_ = _tmp15_->undomove_map_length1;
			_tmp20_ = puzzle_view_get_puzzle (self);
			_tmp21_ = _tmp20_;
			_tmp22_ = puzzle_get_moves (_tmp21_);
			_tmp23_ = _tmp22_;
			if (((gint) _tmp23_) < 10000) {
				Puzzle* _tmp24_;
				Puzzle* _tmp25_;
				guint16 _tmp26_;
				guint16 _tmp27_;
				_tmp24_ = puzzle_view_get_puzzle (self);
				_tmp25_ = _tmp24_;
				_tmp26_ = puzzle_get_moves (_tmp25_);
				_tmp27_ = _tmp26_;
				puzzle_set_moves (_tmp25_, _tmp27_ + 1);
			}
		}
		_tmp29_ = puzzle_view_get_puzzle (self);
		_tmp30_ = _tmp29_;
		_tmp31_ = puzzle_get_moves (_tmp30_);
		_tmp32_ = _tmp31_;
		if (((gint) _tmp32_) > 0) {
			Puzzle* _tmp33_;
			Puzzle* _tmp34_;
			Puzzle* _tmp35_;
			Puzzle* _tmp36_;
			gchar* _tmp37_;
			gint _tmp37__length1;
			Puzzle* _tmp38_;
			Puzzle* _tmp39_;
			gchar* _tmp40_;
			gint _tmp40__length1;
			_tmp33_ = puzzle_view_get_puzzle (self);
			_tmp34_ = _tmp33_;
			_tmp35_ = puzzle_view_get_puzzle (self);
			_tmp36_ = _tmp35_;
			_tmp37_ = _tmp36_->undomove_map;
			_tmp37__length1 = _tmp36_->undomove_map_length1;
			_tmp38_ = puzzle_view_get_puzzle (self);
			_tmp39_ = _tmp38_;
			_tmp40_ = _tmp39_->map;
			_tmp40__length1 = _tmp39_->map_length1;
			_tmp28_ = !puzzle_mapcmp (_tmp34_, _tmp37_, (gint) _tmp37__length1, _tmp40_, (gint) _tmp40__length1);
		} else {
			_tmp28_ = FALSE;
		}
		if (_tmp28_) {
			Puzzle* _tmp41_;
			Puzzle* _tmp42_;
			guint16 _tmp43_;
			guint16 _tmp44_;
			_tmp41_ = puzzle_view_get_puzzle (self);
			_tmp42_ = _tmp41_;
			_tmp43_ = puzzle_get_moves (_tmp42_);
			_tmp44_ = _tmp43_;
			puzzle_set_moves (_tmp42_, _tmp44_ - 1);
			self->priv->last_piece_id = '\0';
		} else {
			gchar _tmp45_;
			gchar _tmp46_;
			_tmp45_ = puzzle_view_get_piece_id (self);
			_tmp46_ = _tmp45_;
			self->priv->last_piece_id = _tmp46_;
		}
		_tmp47_ = puzzle_view_get_puzzle (self);
		_tmp48_ = _tmp47_;
		_tmp49_ = puzzle_view_get_puzzle (self);
		_tmp50_ = _tmp49_;
		_tmp51_ = _tmp50_->map;
		_tmp51__length1 = _tmp50_->map_length1;
		_tmp52_ = (_tmp51_ != NULL) ? _vala_array_dup9 (_tmp51_, _tmp51__length1) : _tmp51_;
		_tmp52__length1 = _tmp51__length1;
		_tmp48_->lastmove_map = (g_free (_tmp48_->lastmove_map), NULL);
		_tmp48_->lastmove_map = _tmp52_;
		_tmp48_->lastmove_map_length1 = _tmp52__length1;
		_tmp48_->_lastmove_map_size_ = _tmp48_->lastmove_map_length1;
		_tmp53_ = puzzle_view_get_puzzle (self);
		_tmp54_ = _tmp53_;
		g_signal_emit_by_name (_tmp54_, "moved");
	}
	puzzle_view_set_piece_id (self, '\0');
}

static inline void
puzzle_view_on_motion (GtkEventControllerMotion* _motion_controller,
                       gdouble event_x,
                       gdouble event_y)
{
	PuzzleView* _this = NULL;
	GtkWidget* _tmp0_;
	PuzzleView* _tmp1_;
	PuzzleView* _tmp2_;
	gchar _tmp3_;
	gchar _tmp4_;
	g_return_if_fail (_motion_controller != NULL);
	_tmp0_ = gtk_event_controller_get_widget ((GtkEventController*) _motion_controller);
	_tmp1_ = _g_object_ref0 (G_TYPE_CHECK_INSTANCE_CAST (_tmp0_, TYPE_PUZZLE_VIEW, PuzzleView));
	_this = _tmp1_;
	_tmp2_ = _this;
	_tmp3_ = puzzle_view_get_piece_id (_tmp2_);
	_tmp4_ = _tmp3_;
	if (_tmp4_ != '\0') {
		gint new_piece_x = 0;
		PuzzleView* _tmp5_;
		PuzzleView* _tmp6_;
		gint _tmp7_;
		gint _tmp8_;
		gint new_piece_y = 0;
		PuzzleView* _tmp9_;
		PuzzleView* _tmp10_;
		gint _tmp11_;
		gint _tmp12_;
		gboolean _tmp13_ = FALSE;
		gboolean _tmp14_ = FALSE;
		gboolean _tmp15_ = FALSE;
		PuzzleView* _tmp26_;
		Puzzle* _tmp27_;
		Puzzle* _tmp28_;
		PuzzleView* _tmp29_;
		gchar _tmp30_;
		gchar _tmp31_;
		PuzzleView* _tmp32_;
		PuzzleView* _tmp33_;
		_tmp5_ = _this;
		_tmp6_ = _this;
		_tmp7_ = puzzle_view_get_tile_size (_tmp6_);
		_tmp8_ = _tmp7_;
		new_piece_x = ((gint) (event_x - _tmp5_->priv->kx)) / _tmp8_;
		_tmp9_ = _this;
		_tmp10_ = _this;
		_tmp11_ = puzzle_view_get_tile_size (_tmp10_);
		_tmp12_ = _tmp11_;
		new_piece_y = ((gint) (event_y - _tmp9_->priv->ky)) / _tmp12_;
		if (event_x < ((gdouble) 0)) {
			_tmp15_ = TRUE;
		} else {
			PuzzleView* _tmp16_;
			Puzzle* _tmp17_;
			Puzzle* _tmp18_;
			guint8 _tmp19_;
			guint8 _tmp20_;
			_tmp16_ = _this;
			_tmp17_ = puzzle_view_get_puzzle (_tmp16_);
			_tmp18_ = _tmp17_;
			_tmp19_ = puzzle_get_width (_tmp18_);
			_tmp20_ = _tmp19_;
			_tmp15_ = new_piece_x > ((gint) _tmp20_);
		}
		if (_tmp15_) {
			_tmp14_ = TRUE;
		} else {
			_tmp14_ = event_y < ((gdouble) 0);
		}
		if (_tmp14_) {
			_tmp13_ = TRUE;
		} else {
			PuzzleView* _tmp21_;
			Puzzle* _tmp22_;
			Puzzle* _tmp23_;
			guint8 _tmp24_;
			guint8 _tmp25_;
			_tmp21_ = _this;
			_tmp22_ = puzzle_view_get_puzzle (_tmp21_);
			_tmp23_ = _tmp22_;
			_tmp24_ = puzzle_get_height (_tmp23_);
			_tmp25_ = _tmp24_;
			_tmp13_ = new_piece_y > ((gint) _tmp25_);
		}
		if (_tmp13_) {
			_g_object_unref0 (_this);
			return;
		}
		_tmp26_ = _this;
		_tmp27_ = puzzle_view_get_puzzle (_tmp26_);
		_tmp28_ = _tmp27_;
		_tmp29_ = _this;
		_tmp30_ = puzzle_view_get_piece_id (_tmp29_);
		_tmp31_ = _tmp30_;
		_tmp32_ = _this;
		_tmp33_ = _this;
		if (puzzle_move_piece (_tmp28_, _tmp31_, _tmp32_->priv->piece_x, _tmp33_->priv->piece_y, (guint8) new_piece_x, (guint8) new_piece_y)) {
			PuzzleView* _tmp34_;
			PuzzleView* _tmp35_;
			PuzzleView* _tmp36_;
			_tmp34_ = _this;
			_tmp34_->priv->piece_unmoved = FALSE;
			_tmp35_ = _this;
			_tmp35_->priv->piece_x = (guint8) new_piece_x;
			_tmp36_ = _this;
			_tmp36_->priv->piece_y = (guint8) new_piece_y;
		}
	}
	_g_object_unref0 (_this);
}

PuzzleView*
puzzle_view_construct (GType object_type)
{
	PuzzleView * self = NULL;
	self = (PuzzleView*) g_object_new (object_type, NULL);
	return self;
}

PuzzleView*
puzzle_view_new (void)
{
	return puzzle_view_construct (TYPE_PUZZLE_VIEW);
}

static gchar
puzzle_view_get_piece_id (PuzzleView* self)
{
	gchar result;
	g_return_val_if_fail (self != NULL, '\0');
	result = self->priv->_piece_id;
	return result;
}

static void
puzzle_view_set_piece_id (PuzzleView* self,
                          gchar value)
{
	g_return_if_fail (self != NULL);
	self->priv->_piece_id = value;
	gtk_widget_queue_draw ((GtkWidget*) self);
}

static Puzzle*
puzzle_view_get_puzzle (PuzzleView* self)
{
	Puzzle* result;
	Puzzle* _tmp0_;
	g_return_val_if_fail (self != NULL, NULL);
	if (!self->priv->puzzle_init_done) {
		g_assert_not_reached ();
	}
	_tmp0_ = self->priv->_puzzle;
	result = _tmp0_;
	return result;
}

static void
_gtk_widget_queue_draw_puzzle_changed (Puzzle* _sender,
                                       gpointer self)
{
	gtk_widget_queue_draw ((GtkWidget*) self);
}

void
puzzle_view_set_puzzle (PuzzleView* self,
                        Puzzle* value)
{
	Puzzle* _tmp1_;
	Puzzle* _tmp2_;
	g_return_if_fail (self != NULL);
	if (self->priv->puzzle_init_done) {
		Puzzle* _tmp0_;
		_tmp0_ = self->priv->_puzzle;
		g_signal_handlers_disconnect_by_func (_tmp0_, NULL, self);
	}
	_tmp1_ = _g_object_ref0 (value);
	_g_object_unref0 (self->priv->_puzzle);
	self->priv->_puzzle = _tmp1_;
	_tmp2_ = self->priv->_puzzle;
	g_signal_connect_object (_tmp2_, "changed", (GCallback) _gtk_widget_queue_draw_puzzle_changed, (GtkWidget*) self, 0);
	self->priv->puzzle_init_done = TRUE;
	self->priv->piece_x = (guint8) 0;
	self->priv->piece_y = (guint8) 0;
	self->priv->piece_unmoved = FALSE;
	puzzle_view_set_piece_id (self, '\0');
	self->priv->last_piece_id = '\0';
	gtk_widget_queue_draw ((GtkWidget*) self);
	g_object_notify_by_pspec ((GObject *) self, puzzle_view_properties[PUZZLE_VIEW_PUZZLE_PROPERTY]);
}

static gint
puzzle_view_get_tile_size (PuzzleView* self)
{
	gint result;
	gint s = 0;
	Puzzle* _tmp0_;
	Puzzle* _tmp1_;
	guint8 _tmp2_;
	guint8 _tmp3_;
	Puzzle* _tmp4_;
	Puzzle* _tmp5_;
	guint8 _tmp6_;
	guint8 _tmp7_;
	g_return_val_if_fail (self != NULL, 0);
	_tmp0_ = puzzle_view_get_puzzle (self);
	_tmp1_ = _tmp0_;
	_tmp2_ = puzzle_get_width (_tmp1_);
	_tmp3_ = _tmp2_;
	_tmp4_ = puzzle_view_get_puzzle (self);
	_tmp5_ = _tmp4_;
	_tmp6_ = puzzle_get_height (_tmp5_);
	_tmp7_ = _tmp6_;
	s = MIN ((gtk_widget_get_allocated_width ((GtkWidget*) self) - PUZZLE_VIEW_SPACE_PADDING) / _tmp3_, (gtk_widget_get_allocated_height ((GtkWidget*) self) - PUZZLE_VIEW_SPACE_PADDING) / _tmp7_);
	if ((s % 2) != 0) {
		gint _tmp8_;
		_tmp8_ = s;
		s = _tmp8_ - 1;
	}
	result = s;
	return result;
}

static GObject *
puzzle_view_constructor (GType type,
                         guint n_construct_properties,
                         GObjectConstructParam * construct_properties)
{
	GObject * obj;
	GObjectClass * parent_class;
	PuzzleView * self;
	GtkStyleContext* _tmp0_;
	GtkStyleContext* _tmp1_;
	parent_class = G_OBJECT_CLASS (puzzle_view_parent_class);
	obj = parent_class->constructor (type, n_construct_properties, construct_properties);
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, TYPE_PUZZLE_VIEW, PuzzleView);
	puzzle_view_init_mouse (self);
	_tmp0_ = gtk_widget_get_style_context ((GtkWidget*) self);
	_tmp1_ = _g_object_ref0 (_tmp0_);
	_g_object_unref0 (self->priv->style_context);
	self->priv->style_context = _tmp1_;
	gtk_widget_set_size_request ((GtkWidget*) self, 250, 250);
	gtk_widget_set_events ((GtkWidget*) self, (gint) (((GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK) | GDK_POINTER_MOTION_MASK) | GDK_BUTTON_RELEASE_MASK));
	puzzle_view_load_image (self);
	return obj;
}

static void
puzzle_view_class_init (PuzzleViewClass * klass,
                        gpointer klass_data)
{
	puzzle_view_parent_class = g_type_class_peek_parent (klass);
	g_type_class_adjust_private_offset (klass, &PuzzleView_private_offset);
	((GtkWidgetClass *) klass)->draw = (gboolean (*) (GtkWidget*, cairo_t*)) puzzle_view_real_draw;
	G_OBJECT_CLASS (klass)->get_property = _vala_puzzle_view_get_property;
	G_OBJECT_CLASS (klass)->set_property = _vala_puzzle_view_set_property;
	G_OBJECT_CLASS (klass)->constructor = puzzle_view_constructor;
	G_OBJECT_CLASS (klass)->finalize = puzzle_view_finalize;
	g_object_class_install_property (G_OBJECT_CLASS (klass), PUZZLE_VIEW_PUZZLE_PROPERTY, puzzle_view_properties[PUZZLE_VIEW_PUZZLE_PROPERTY] = g_param_spec_object ("puzzle", "puzzle", "puzzle", TYPE_PUZZLE, G_PARAM_STATIC_STRINGS | G_PARAM_WRITABLE));
}

static void
puzzle_view_instance_init (PuzzleView * self,
                           gpointer klass)
{
	self->priv = puzzle_view_get_instance_private (self);
	self->priv->render_size = 0;
	self->priv->piece_x = (guint8) 0;
	self->priv->piece_y = (guint8) 0;
	self->priv->piece_unmoved = FALSE;
	self->priv->_piece_id = '\0';
	self->priv->last_piece_id = '\0';
	self->priv->kx = (gdouble) 0;
	self->priv->ky = (gdouble) 0;
	self->priv->tiles_handle_init_done = FALSE;
	self->priv->puzzle_init_done = FALSE;
}

static void
puzzle_view_finalize (GObject * obj)
{
	PuzzleView * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, TYPE_PUZZLE_VIEW, PuzzleView);
	_g_object_unref0 (self->priv->tiles_handle);
	_g_object_unref0 (self->priv->image_file);
	_cairo_surface_destroy0 (self->priv->surface);
	_g_object_unref0 (self->priv->_puzzle);
	_g_object_unref0 (self->priv->style_context);
	_g_object_unref0 (self->priv->motion_controller);
	_g_object_unref0 (self->priv->click_controller);
	G_OBJECT_CLASS (puzzle_view_parent_class)->finalize (obj);
}

static GType
puzzle_view_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (PuzzleViewClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) puzzle_view_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (PuzzleView), 0, (GInstanceInitFunc) puzzle_view_instance_init, NULL };
	GType puzzle_view_type_id;
	puzzle_view_type_id = g_type_register_static (gtk_drawing_area_get_type (), "PuzzleView", &g_define_type_info, 0);
	PuzzleView_private_offset = g_type_add_instance_private (puzzle_view_type_id, sizeof (PuzzleViewPrivate));
	return puzzle_view_type_id;
}

GType
puzzle_view_get_type (void)
{
	static volatile gsize puzzle_view_type_id__once = 0;
	if (g_once_init_enter (&puzzle_view_type_id__once)) {
		GType puzzle_view_type_id;
		puzzle_view_type_id = puzzle_view_get_type_once ();
		g_once_init_leave (&puzzle_view_type_id__once, puzzle_view_type_id);
	}
	return puzzle_view_type_id__once;
}

static void
_vala_puzzle_view_get_property (GObject * object,
                                guint property_id,
                                GValue * value,
                                GParamSpec * pspec)
{
	PuzzleView * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (object, TYPE_PUZZLE_VIEW, PuzzleView);
	switch (property_id) {
		case PUZZLE_VIEW_PUZZLE_PROPERTY:
		g_value_set_object (value, puzzle_view_get_puzzle (self));
		break;
		default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
	}
}

static void
_vala_puzzle_view_set_property (GObject * object,
                                guint property_id,
                                const GValue * value,
                                GParamSpec * pspec)
{
	PuzzleView * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (object, TYPE_PUZZLE_VIEW, PuzzleView);
	switch (property_id) {
		case PUZZLE_VIEW_PUZZLE_PROPERTY:
		puzzle_view_set_puzzle (self, g_value_get_object (value));
		break;
		default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
	}
}

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

