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

/* -*- Mode: vala; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * Copyright © 2014 Parin Porecha
 * Copyright © 2014 Michael Catanzaro
 *
 * This file is part of GNOME Sudoku.
 *
 * GNOME Sudoku 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 Sudoku 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 Sudoku. If not, see <http://www.gnu.org/licenses/>.
 */

#include "libsudoku.h"
#include <stdlib.h>
#include <string.h>
#include <glib.h>
#include <glib-object.h>
#include <gio/gio.h>
#include <glib/gstdio.h>
#include <json-glib/json-glib.h>
#include <float.h>
#include <math.h>

enum  {
	SUDOKU_SAVER_0_PROPERTY,
	SUDOKU_SAVER_NUM_PROPERTIES
};
static GParamSpec* sudoku_saver_properties[SUDOKU_SAVER_NUM_PROPERTIES];
#define _g_free0(var) (var = (g_free (var), NULL))
#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))
#define _g_error_free0(var) ((var == NULL) ? NULL : (var = (g_error_free (var), NULL)))
#define __vala_JsonNode_free0(var) ((var == NULL) ? NULL : (var = (_vala_JsonNode_free (var), NULL)))

static gpointer sudoku_saver_parent_class = NULL;
static gchar* sudoku_saver__savegame_file;
static gchar* sudoku_saver__savegame_file = NULL;
static gchar* sudoku_saver__finishgame_dir;
static gchar* sudoku_saver__finishgame_dir = NULL;

static void sudoku_saver_set_savegame_file (const gchar* value);
static void sudoku_saver_set_finishgame_dir (const gchar* value);
static SudokuGame* sudoku_saver_parse_json_to_game (SudokuSaver* self,
                                             const gchar* file_path);
static void sudoku_saver_create_file_for_game (SudokuSaver* self,
                                        SudokuGame* game,
                                        const gchar* file_name);
static gchar* sudoku_saver_serialize_game_to_json (SudokuSaver* self,
                                            SudokuGame* game);
static void _vala_array_add1 (gint* * array,
                       gint* length,
                       gint* size,
                       gint value);
static void _vala_JsonNode_free (JsonNode* self);
static JsonNode* _vala_JsonNode_copy (JsonNode* self);
static void sudoku_saver_finalize (GObject * obj);
static GType sudoku_saver_get_type_once (void);
static void _vala_sudoku_saver_get_property (GObject * object,
                                      guint property_id,
                                      GValue * value,
                                      GParamSpec * pspec);
static void _vala_sudoku_saver_set_property (GObject * object,
                                      guint property_id,
                                      const GValue * value,
                                      GParamSpec * pspec);
static inline gpointer _vala_memdup2 (gconstpointer mem,
                        gsize byte_size);

SudokuSaver*
sudoku_saver_construct (GType object_type)
{
	SudokuSaver * self = NULL;
	GError* _inner_error0_ = NULL;
	self = (SudokuSaver*) g_object_new (object_type, NULL);
	{
		gchar* config_dir = NULL;
		const gchar* _tmp0_;
		gchar* _tmp1_;
		gchar* sudoku_data_dir = NULL;
		const gchar* _tmp2_;
		gchar* _tmp3_;
		const gchar* _tmp4_;
		gchar* _tmp5_;
		gchar* _tmp6_;
		const gchar* _tmp7_;
		gchar* _tmp8_;
		gchar* _tmp9_;
		GFile* file = NULL;
		const gchar* _tmp10_;
		GFile* _tmp11_;
		GFile* _tmp12_;
		const gchar* _tmp14_;
		const gchar* _tmp15_;
		GFile* _tmp16_;
		GFile* _tmp17_;
		_tmp0_ = g_get_user_data_dir ();
		_tmp1_ = g_strdup (_tmp0_);
		config_dir = _tmp1_;
		_tmp2_ = config_dir;
		_tmp3_ = g_build_path (G_DIR_SEPARATOR_S, _tmp2_, "gnome-sudoku", NULL);
		sudoku_data_dir = _tmp3_;
		_tmp4_ = sudoku_data_dir;
		_tmp5_ = g_build_path (G_DIR_SEPARATOR_S, _tmp4_, "savefile", NULL);
		_tmp6_ = _tmp5_;
		sudoku_saver_set_savegame_file (_tmp6_);
		_g_free0 (_tmp6_);
		_tmp7_ = sudoku_data_dir;
		_tmp8_ = g_build_path (G_DIR_SEPARATOR_S, _tmp7_, "finished", NULL);
		_tmp9_ = _tmp8_;
		sudoku_saver_set_finishgame_dir (_tmp9_);
		_g_free0 (_tmp9_);
		_tmp10_ = sudoku_data_dir;
		_tmp11_ = g_file_new_for_path (_tmp10_);
		file = _tmp11_;
		_tmp12_ = file;
		if (!g_file_query_exists (_tmp12_, NULL)) {
			GFile* _tmp13_;
			_tmp13_ = file;
			g_file_make_directory (_tmp13_, NULL, &_inner_error0_);
			if (G_UNLIKELY (_inner_error0_ != NULL)) {
				_g_object_unref0 (file);
				_g_free0 (sudoku_data_dir);
				_g_free0 (config_dir);
				goto __catch0_g_error;
			}
		}
		_tmp14_ = sudoku_saver_get_finishgame_dir ();
		_tmp15_ = _tmp14_;
		_tmp16_ = g_file_new_for_path (_tmp15_);
		_g_object_unref0 (file);
		file = _tmp16_;
		_tmp17_ = file;
		if (!g_file_query_exists (_tmp17_, NULL)) {
			GFile* _tmp18_;
			_tmp18_ = file;
			g_file_make_directory (_tmp18_, NULL, &_inner_error0_);
			if (G_UNLIKELY (_inner_error0_ != NULL)) {
				_g_object_unref0 (file);
				_g_free0 (sudoku_data_dir);
				_g_free0 (config_dir);
				goto __catch0_g_error;
			}
		}
		_g_object_unref0 (file);
		_g_free0 (sudoku_data_dir);
		_g_free0 (config_dir);
	}
	goto __finally0;
	__catch0_g_error:
	{
		GError* e = NULL;
		GError* _tmp19_;
		const gchar* _tmp20_;
		e = _inner_error0_;
		_inner_error0_ = NULL;
		_tmp19_ = e;
		_tmp20_ = _tmp19_->message;
		g_warning ("sudoku-saver.vala:48: %s", _tmp20_);
		_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 NULL;
	}
	return self;
}

SudokuSaver*
sudoku_saver_new (void)
{
	return sudoku_saver_construct (TYPE_SUDOKU_SAVER);
}

SudokuGame*
sudoku_saver_get_savedgame (SudokuSaver* self)
{
	GFile* file = NULL;
	const gchar* _tmp0_;
	const gchar* _tmp1_;
	GFile* _tmp2_;
	GFile* _tmp3_;
	const gchar* _tmp4_;
	const gchar* _tmp5_;
	SudokuGame* _tmp6_;
	SudokuGame* result;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = sudoku_saver_get_savegame_file ();
	_tmp1_ = _tmp0_;
	_tmp2_ = g_file_new_for_path (_tmp1_);
	file = _tmp2_;
	_tmp3_ = file;
	if (!g_file_query_exists (_tmp3_, NULL)) {
		result = NULL;
		_g_object_unref0 (file);
		return result;
	}
	_tmp4_ = sudoku_saver_get_savegame_file ();
	_tmp5_ = _tmp4_;
	_tmp6_ = sudoku_saver_parse_json_to_game (self, _tmp5_);
	result = _tmp6_;
	_g_object_unref0 (file);
	return result;
}

void
sudoku_saver_save_game (SudokuSaver* self,
                        SudokuGame* game)
{
	const gchar* _tmp0_;
	const gchar* _tmp1_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (game != NULL);
	_tmp0_ = sudoku_saver_get_savegame_file ();
	_tmp1_ = _tmp0_;
	sudoku_saver_create_file_for_game (self, game, _tmp1_);
}

void
sudoku_saver_add_game_to_finished (SudokuSaver* self,
                                   SudokuGame* game,
                                   gboolean delete_savegame)
{
	gchar* file_name = NULL;
	SudokuBoard* _tmp0_;
	gchar* _tmp1_;
	gchar* _tmp2_;
	gchar* _tmp3_;
	gchar* _tmp4_;
	gchar* file_path = NULL;
	const gchar* _tmp5_;
	const gchar* _tmp6_;
	const gchar* _tmp7_;
	gchar* _tmp8_;
	const gchar* _tmp9_;
	GError* _inner_error0_ = NULL;
	g_return_if_fail (self != NULL);
	g_return_if_fail (game != NULL);
	_tmp0_ = game->board;
	_tmp1_ = sudoku_board_to_string (_tmp0_, TRUE);
	_tmp2_ = _tmp1_;
	_tmp3_ = g_strconcat (_tmp2_, ".save", NULL);
	_tmp4_ = _tmp3_;
	_g_free0 (_tmp2_);
	file_name = _tmp4_;
	_tmp5_ = sudoku_saver_get_finishgame_dir ();
	_tmp6_ = _tmp5_;
	_tmp7_ = file_name;
	_tmp8_ = g_build_path (G_DIR_SEPARATOR_S, _tmp6_, _tmp7_, NULL);
	file_path = _tmp8_;
	_tmp9_ = file_path;
	sudoku_saver_create_file_for_game (self, game, _tmp9_);
	if (delete_savegame) {
		GFile* file = NULL;
		const gchar* _tmp10_;
		const gchar* _tmp11_;
		GFile* _tmp12_;
		GFile* _tmp13_;
		_tmp10_ = sudoku_saver_get_savegame_file ();
		_tmp11_ = _tmp10_;
		_tmp12_ = g_file_new_for_path (_tmp11_);
		file = _tmp12_;
		_tmp13_ = file;
		if (g_file_query_exists (_tmp13_, NULL)) {
			{
				GFile* _tmp14_;
				_tmp14_ = file;
				g_file_delete (_tmp14_, NULL, &_inner_error0_);
				if (G_UNLIKELY (_inner_error0_ != NULL)) {
					goto __catch0_g_error;
				}
			}
			goto __finally0;
			__catch0_g_error:
			{
				GError* e = NULL;
				GFile* _tmp15_;
				gchar* _tmp16_;
				gchar* _tmp17_;
				GError* _tmp18_;
				const gchar* _tmp19_;
				e = _inner_error0_;
				_inner_error0_ = NULL;
				_tmp15_ = file;
				_tmp16_ = g_file_get_uri (_tmp15_);
				_tmp17_ = _tmp16_;
				_tmp18_ = e;
				_tmp19_ = _tmp18_->message;
				g_warning ("sudoku-saver.vala:84: Failed to delete %s: %s", _tmp17_, _tmp19_);
				_g_free0 (_tmp17_);
				_g_error_free0 (e);
			}
			__finally0:
			if (G_UNLIKELY (_inner_error0_ != NULL)) {
				_g_object_unref0 (file);
				_g_free0 (file_path);
				_g_free0 (file_name);
				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;
			}
		}
		_g_object_unref0 (file);
	}
	_g_free0 (file_path);
	_g_free0 (file_name);
}

static void
sudoku_saver_create_file_for_game (SudokuSaver* self,
                                   SudokuGame* game,
                                   const gchar* file_name)
{
	gchar* json_str = NULL;
	gchar* _tmp0_;
	GError* _inner_error0_ = NULL;
	g_return_if_fail (self != NULL);
	g_return_if_fail (game != NULL);
	g_return_if_fail (file_name != NULL);
	_tmp0_ = sudoku_saver_serialize_game_to_json (self, game);
	json_str = _tmp0_;
	{
		g_file_set_contents (file_name, json_str, (gssize) -1, &_inner_error0_);
		if (G_UNLIKELY (_inner_error0_ != NULL)) {
			goto __catch0_g_error;
		}
	}
	goto __finally0;
	__catch0_g_error:
	{
		GError* e = NULL;
		GError* _tmp1_;
		const gchar* _tmp2_;
		e = _inner_error0_;
		_inner_error0_ = NULL;
		_tmp1_ = e;
		_tmp2_ = _tmp1_->message;
		g_warning ("sudoku-saver.vala:100: %s", _tmp2_);
		_g_error_free0 (e);
	}
	__finally0:
	if (G_UNLIKELY (_inner_error0_ != NULL)) {
		_g_free0 (json_str);
		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;
	}
	_g_free0 (json_str);
}

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

static void
_vala_array_add1 (gint* * array,
                  gint* length,
                  gint* size,
                  gint value)
{
	if ((*length) == (*size)) {
		*size = (*size) ? (2 * (*size)) : 4;
		*array = g_renew (gint, *array, *size);
	}
	(*array)[(*length)++] = value;
}

static void
_vala_JsonNode_free (JsonNode* self)
{
	g_boxed_free (json_node_get_type (), self);
}

static gchar*
sudoku_saver_serialize_game_to_json (SudokuSaver* self,
                                     SudokuGame* game)
{
	SudokuBoard* board = NULL;
	SudokuBoard* _tmp0_;
	SudokuBoard* _tmp1_;
	gint* board_cells = NULL;
	SudokuBoard* _tmp2_;
	gint _tmp3_ = 0;
	gint _tmp4_ = 0;
	gint* _tmp5_;
	gint board_cells_length1;
	gint board_cells_length2;
	JsonBuilder* builder = NULL;
	JsonBuilder* _tmp6_;
	JsonBuilder* _tmp7_;
	JsonBuilder* _tmp8_;
	JsonBuilder* _tmp9_;
	SudokuBoard* _tmp10_;
	DifficultyCategory _tmp11_;
	DifficultyCategory _tmp12_;
	gchar* _tmp13_;
	gchar* _tmp14_;
	JsonBuilder* _tmp15_;
	JsonBuilder* _tmp18_;
	JsonBuilder* _tmp19_;
	JsonBuilder* _tmp62_;
	JsonBuilder* _tmp63_;
	JsonGenerator* generator = NULL;
	JsonGenerator* _tmp64_;
	JsonNode* root = NULL;
	JsonBuilder* _tmp65_;
	JsonNode* _tmp66_;
	gchar* _tmp67_;
	gchar* result;
	g_return_val_if_fail (self != NULL, NULL);
	g_return_val_if_fail (game != NULL, NULL);
	_tmp0_ = game->board;
	_tmp1_ = _g_object_ref0 (_tmp0_);
	board = _tmp1_;
	_tmp2_ = board;
	_tmp5_ = sudoku_board_get_cells (_tmp2_, &_tmp3_, &_tmp4_);
	board_cells = _tmp5_;
	board_cells_length1 = _tmp3_;
	board_cells_length2 = _tmp4_;
	_tmp6_ = json_builder_new ();
	builder = _tmp6_;
	_tmp7_ = builder;
	json_builder_begin_object (_tmp7_);
	_tmp8_ = builder;
	json_builder_set_member_name (_tmp8_, "difficulty_category");
	_tmp9_ = builder;
	_tmp10_ = board;
	_tmp11_ = sudoku_board_get_difficulty_category (_tmp10_);
	_tmp12_ = _tmp11_;
	_tmp13_ = difficulty_category_to_untranslated_string (_tmp12_);
	_tmp14_ = _tmp13_;
	json_builder_add_string_value (_tmp9_, _tmp14_);
	_g_free0 (_tmp14_);
	_tmp15_ = builder;
	json_builder_set_member_name (_tmp15_, "time_elapsed");
	if (game->mode == GAME_MODE_CREATE) {
		JsonBuilder* _tmp16_;
		_tmp16_ = builder;
		json_builder_add_double_value (_tmp16_, (gdouble) 0);
	} else {
		JsonBuilder* _tmp17_;
		_tmp17_ = builder;
		json_builder_add_double_value (_tmp17_, sudoku_game_get_total_time_played (game));
	}
	_tmp18_ = builder;
	json_builder_set_member_name (_tmp18_, "cells");
	_tmp19_ = builder;
	json_builder_begin_array (_tmp19_);
	{
		gint i = 0;
		i = 0;
		{
			gboolean _tmp20_ = FALSE;
			_tmp20_ = TRUE;
			while (TRUE) {
				SudokuBoard* _tmp22_;
				gint _tmp23_;
				gint _tmp24_;
				if (!_tmp20_) {
					gint _tmp21_;
					_tmp21_ = i;
					i = _tmp21_ + 1;
				}
				_tmp20_ = FALSE;
				_tmp22_ = board;
				_tmp23_ = sudoku_board_get_rows (_tmp22_);
				_tmp24_ = _tmp23_;
				if (!(i < _tmp24_)) {
					break;
				}
				{
					gint j = 0;
					j = 0;
					{
						gboolean _tmp25_ = FALSE;
						_tmp25_ = TRUE;
						while (TRUE) {
							SudokuBoard* _tmp27_;
							gint _tmp28_;
							gint _tmp29_;
							gint* earmarks = NULL;
							gint* _tmp30_;
							gint earmarks_length1;
							gint _earmarks_size_;
							gboolean _tmp37_ = FALSE;
							gint* _tmp38_;
							gint _tmp38__length1;
							gint _tmp38__length2;
							gint _tmp39_;
							JsonBuilder* _tmp41_;
							JsonBuilder* _tmp42_;
							JsonBuilder* _tmp43_;
							JsonBuilder* _tmp44_;
							JsonBuilder* _tmp45_;
							JsonBuilder* _tmp46_;
							JsonBuilder* _tmp47_;
							JsonBuilder* _tmp48_;
							gint* _tmp49_;
							gint _tmp49__length1;
							gint _tmp49__length2;
							gint _tmp50_;
							JsonBuilder* _tmp51_;
							JsonBuilder* _tmp52_;
							SudokuBoard* _tmp53_;
							gboolean* _tmp54_;
							gint _tmp54__length1;
							gint _tmp54__length2;
							gboolean _tmp55_;
							JsonBuilder* _tmp56_;
							JsonBuilder* _tmp57_;
							gint* _tmp58_;
							gint _tmp58__length1;
							JsonBuilder* _tmp60_;
							JsonBuilder* _tmp61_;
							if (!_tmp25_) {
								gint _tmp26_;
								_tmp26_ = j;
								j = _tmp26_ + 1;
							}
							_tmp25_ = FALSE;
							_tmp27_ = board;
							_tmp28_ = sudoku_board_get_cols (_tmp27_);
							_tmp29_ = _tmp28_;
							if (!(j < _tmp29_)) {
								break;
							}
							_tmp30_ = g_new0 (gint, 0);
							earmarks = _tmp30_;
							earmarks_length1 = 0;
							_earmarks_size_ = earmarks_length1;
							{
								gint k = 0;
								k = 1;
								{
									gboolean _tmp31_ = FALSE;
									_tmp31_ = TRUE;
									while (TRUE) {
										SudokuBoard* _tmp33_;
										gint _tmp34_;
										gint _tmp35_;
										SudokuBoard* _tmp36_;
										if (!_tmp31_) {
											gint _tmp32_;
											_tmp32_ = k;
											k = _tmp32_ + 1;
										}
										_tmp31_ = FALSE;
										_tmp33_ = board;
										_tmp34_ = sudoku_board_get_max_val (_tmp33_);
										_tmp35_ = _tmp34_;
										if (!(k <= _tmp35_)) {
											break;
										}
										_tmp36_ = board;
										if (sudoku_board_is_earmark_enabled (_tmp36_, i, j, k)) {
											_vala_array_add1 (&earmarks, &earmarks_length1, &_earmarks_size_, k);
										}
									}
								}
							}
							_tmp38_ = board_cells;
							_tmp38__length1 = board_cells_length1;
							_tmp38__length2 = board_cells_length2;
							_tmp39_ = _tmp38_[(i * _tmp38__length2) + j];
							if (_tmp39_ == 0) {
								gint* _tmp40_;
								gint _tmp40__length1;
								_tmp40_ = earmarks;
								_tmp40__length1 = earmarks_length1;
								_tmp37_ = _tmp40__length1 == 0;
							} else {
								_tmp37_ = FALSE;
							}
							if (_tmp37_) {
								earmarks = (g_free (earmarks), NULL);
								continue;
							}
							_tmp41_ = builder;
							json_builder_begin_object (_tmp41_);
							_tmp42_ = builder;
							json_builder_set_member_name (_tmp42_, "position");
							_tmp43_ = builder;
							json_builder_begin_array (_tmp43_);
							_tmp44_ = builder;
							json_builder_add_int_value (_tmp44_, (gint64) i);
							_tmp45_ = builder;
							json_builder_add_int_value (_tmp45_, (gint64) j);
							_tmp46_ = builder;
							json_builder_end_array (_tmp46_);
							_tmp47_ = builder;
							json_builder_set_member_name (_tmp47_, "value");
							_tmp48_ = builder;
							_tmp49_ = board_cells;
							_tmp49__length1 = board_cells_length1;
							_tmp49__length2 = board_cells_length2;
							_tmp50_ = _tmp49_[(i * _tmp49__length2) + j];
							json_builder_add_int_value (_tmp48_, (gint64) _tmp50_);
							_tmp51_ = builder;
							json_builder_set_member_name (_tmp51_, "fixed");
							_tmp52_ = builder;
							_tmp53_ = board;
							_tmp54_ = _tmp53_->is_fixed;
							_tmp54__length1 = _tmp53_->is_fixed_length1;
							_tmp54__length2 = _tmp53_->is_fixed_length2;
							_tmp55_ = _tmp54_[(i * _tmp54__length2) + j];
							json_builder_add_boolean_value (_tmp52_, _tmp55_);
							_tmp56_ = builder;
							json_builder_set_member_name (_tmp56_, "earmarks");
							_tmp57_ = builder;
							json_builder_begin_array (_tmp57_);
							_tmp58_ = earmarks;
							_tmp58__length1 = earmarks_length1;
							{
								gint* k_collection = NULL;
								gint k_collection_length1 = 0;
								gint _k_collection_size_ = 0;
								gint k_it = 0;
								k_collection = _tmp58_;
								k_collection_length1 = _tmp58__length1;
								for (k_it = 0; k_it < k_collection_length1; k_it = k_it + 1) {
									gint k = 0;
									k = k_collection[k_it];
									{
										JsonBuilder* _tmp59_;
										_tmp59_ = builder;
										json_builder_add_int_value (_tmp59_, (gint64) k);
									}
								}
							}
							_tmp60_ = builder;
							json_builder_end_array (_tmp60_);
							_tmp61_ = builder;
							json_builder_end_object (_tmp61_);
							earmarks = (g_free (earmarks), NULL);
						}
					}
				}
			}
		}
	}
	_tmp62_ = builder;
	json_builder_end_array (_tmp62_);
	_tmp63_ = builder;
	json_builder_end_object (_tmp63_);
	_tmp64_ = json_generator_new ();
	generator = _tmp64_;
	json_generator_set_pretty (generator, TRUE);
	_tmp65_ = builder;
	_tmp66_ = json_builder_get_root (_tmp65_);
	root = _tmp66_;
	json_generator_set_root (generator, root);
	_tmp67_ = json_generator_to_data (generator, NULL);
	result = _tmp67_;
	__vala_JsonNode_free0 (root);
	_g_object_unref0 (generator);
	_g_object_unref0 (builder);
	board_cells = (g_free (board_cells), NULL);
	_g_object_unref0 (board);
	return result;
}

static JsonNode*
_vala_JsonNode_copy (JsonNode* self)
{
	return g_boxed_copy (json_node_get_type (), self);
}

static gpointer
__vala_JsonNode_copy0 (gpointer self)
{
	return self ? _vala_JsonNode_copy (self) : NULL;
}

static SudokuGame*
sudoku_saver_parse_json_to_game (SudokuSaver* self,
                                 const gchar* file_path)
{
	JsonParser* parser = NULL;
	JsonParser* _tmp0_;
	SudokuBoard* board = NULL;
	SudokuBoard* _tmp2_;
	JsonNode* node = NULL;
	JsonParser* _tmp3_;
	JsonNode* _tmp4_;
	JsonNode* _tmp5_;
	JsonReader* reader = NULL;
	JsonNode* _tmp6_;
	JsonReader* _tmp7_;
	JsonReader* _tmp8_;
	JsonReader* _tmp9_;
	JsonReader* _tmp47_;
	JsonReader* _tmp48_;
	JsonReader* _tmp49_;
	SudokuBoard* _tmp50_;
	JsonReader* _tmp51_;
	JsonReader* _tmp52_;
	JsonReader* _tmp53_;
	JsonReader* _tmp54_;
	SudokuBoard* _tmp55_;
	JsonReader* _tmp56_;
	const gchar* _tmp57_;
	JsonReader* _tmp58_;
	SudokuBoard* _tmp59_;
	SudokuGame* _tmp60_;
	GError* _inner_error0_ = NULL;
	SudokuGame* result;
	g_return_val_if_fail (self != NULL, NULL);
	g_return_val_if_fail (file_path != NULL, NULL);
	_tmp0_ = json_parser_new ();
	parser = _tmp0_;
	{
		JsonParser* _tmp1_;
		_tmp1_ = parser;
		json_parser_load_from_file (_tmp1_, file_path, &_inner_error0_);
		if (G_UNLIKELY (_inner_error0_ != NULL)) {
			goto __catch0_g_error;
		}
	}
	goto __finally0;
	__catch0_g_error:
	{
		g_clear_error (&_inner_error0_);
		result = NULL;
		_g_object_unref0 (parser);
		return result;
	}
	__finally0:
	if (G_UNLIKELY (_inner_error0_ != NULL)) {
		_g_object_unref0 (parser);
		g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error0_->message, g_quark_to_string (_inner_error0_->domain), _inner_error0_->code);
		g_clear_error (&_inner_error0_);
		return NULL;
	}
	_tmp2_ = sudoku_board_new (3, 3);
	board = _tmp2_;
	_tmp3_ = parser;
	_tmp4_ = json_parser_get_root (_tmp3_);
	_tmp5_ = __vala_JsonNode_copy0 (_tmp4_);
	node = _tmp5_;
	_tmp6_ = node;
	_tmp7_ = json_reader_new (_tmp6_);
	reader = _tmp7_;
	_tmp8_ = reader;
	json_reader_read_member (_tmp8_, "cells");
	_tmp9_ = reader;
	g_return_val_if_fail (json_reader_is_array (_tmp9_), NULL);
	{
		gint i = 0;
		i = 0;
		{
			gboolean _tmp10_ = FALSE;
			_tmp10_ = TRUE;
			while (TRUE) {
				JsonReader* _tmp12_;
				JsonReader* _tmp13_;
				JsonReader* _tmp14_;
				JsonReader* _tmp15_;
				JsonReader* _tmp16_;
				JsonReader* _tmp17_;
				JsonReader* _tmp18_;
				gint row = 0;
				JsonReader* _tmp19_;
				JsonReader* _tmp20_;
				JsonReader* _tmp21_;
				JsonReader* _tmp22_;
				gint col = 0;
				JsonReader* _tmp23_;
				JsonReader* _tmp24_;
				JsonReader* _tmp25_;
				JsonReader* _tmp26_;
				JsonReader* _tmp27_;
				gint val = 0;
				JsonReader* _tmp28_;
				JsonReader* _tmp29_;
				JsonReader* _tmp30_;
				JsonReader* _tmp31_;
				gboolean is_fixed = FALSE;
				JsonReader* _tmp32_;
				JsonReader* _tmp33_;
				JsonReader* _tmp35_;
				JsonReader* _tmp36_;
				JsonReader* _tmp45_;
				JsonReader* _tmp46_;
				if (!_tmp10_) {
					gint _tmp11_;
					_tmp11_ = i;
					i = _tmp11_ + 1;
				}
				_tmp10_ = FALSE;
				_tmp12_ = reader;
				if (!(i < json_reader_count_elements (_tmp12_))) {
					break;
				}
				_tmp13_ = reader;
				json_reader_read_element (_tmp13_, (guint) i);
				_tmp14_ = reader;
				json_reader_read_member (_tmp14_, "position");
				_tmp15_ = reader;
				g_return_val_if_fail (json_reader_is_array (_tmp15_), NULL);
				_tmp16_ = reader;
				g_return_val_if_fail (json_reader_count_elements (_tmp16_) == 2, NULL);
				_tmp17_ = reader;
				json_reader_read_element (_tmp17_, (guint) 0);
				_tmp18_ = reader;
				g_return_val_if_fail (json_reader_is_value (_tmp18_), NULL);
				_tmp19_ = reader;
				row = (gint) json_reader_get_int_value (_tmp19_);
				_tmp20_ = reader;
				json_reader_end_element (_tmp20_);
				_tmp21_ = reader;
				json_reader_read_element (_tmp21_, (guint) 1);
				_tmp22_ = reader;
				g_return_val_if_fail (json_reader_is_value (_tmp22_), NULL);
				_tmp23_ = reader;
				col = (gint) json_reader_get_int_value (_tmp23_);
				_tmp24_ = reader;
				json_reader_end_element (_tmp24_);
				_tmp25_ = reader;
				json_reader_end_member (_tmp25_);
				_tmp26_ = reader;
				json_reader_read_member (_tmp26_, "value");
				_tmp27_ = reader;
				g_return_val_if_fail (json_reader_is_value (_tmp27_), NULL);
				_tmp28_ = reader;
				val = (gint) json_reader_get_int_value (_tmp28_);
				_tmp29_ = reader;
				json_reader_end_member (_tmp29_);
				_tmp30_ = reader;
				json_reader_read_member (_tmp30_, "fixed");
				_tmp31_ = reader;
				g_return_val_if_fail (json_reader_is_value (_tmp31_), NULL);
				_tmp32_ = reader;
				is_fixed = json_reader_get_boolean_value (_tmp32_);
				_tmp33_ = reader;
				json_reader_end_member (_tmp33_);
				if (val != 0) {
					SudokuBoard* _tmp34_;
					_tmp34_ = board;
					sudoku_board_insert (_tmp34_, row, col, val, is_fixed);
				}
				_tmp35_ = reader;
				json_reader_read_member (_tmp35_, "earmarks");
				_tmp36_ = reader;
				g_return_val_if_fail (json_reader_is_array (_tmp36_), NULL);
				{
					gint k = 0;
					k = 0;
					{
						gboolean _tmp37_ = FALSE;
						_tmp37_ = TRUE;
						while (TRUE) {
							JsonReader* _tmp39_;
							JsonReader* _tmp40_;
							JsonReader* _tmp41_;
							SudokuBoard* _tmp42_;
							JsonReader* _tmp43_;
							JsonReader* _tmp44_;
							if (!_tmp37_) {
								gint _tmp38_;
								_tmp38_ = k;
								k = _tmp38_ + 1;
							}
							_tmp37_ = FALSE;
							_tmp39_ = reader;
							if (!(k < json_reader_count_elements (_tmp39_))) {
								break;
							}
							_tmp40_ = reader;
							json_reader_read_element (_tmp40_, (guint) k);
							_tmp41_ = reader;
							g_return_val_if_fail (json_reader_is_value (_tmp41_), NULL);
							_tmp42_ = board;
							_tmp43_ = reader;
							sudoku_board_enable_earmark (_tmp42_, row, col, (gint) json_reader_get_int_value (_tmp43_));
							_tmp44_ = reader;
							json_reader_end_element (_tmp44_);
						}
					}
				}
				_tmp45_ = reader;
				json_reader_end_member (_tmp45_);
				_tmp46_ = reader;
				json_reader_end_element (_tmp46_);
			}
		}
	}
	_tmp47_ = reader;
	json_reader_end_member (_tmp47_);
	_tmp48_ = reader;
	json_reader_read_member (_tmp48_, "time_elapsed");
	_tmp49_ = reader;
	g_return_val_if_fail (json_reader_is_value (_tmp49_), NULL);
	_tmp50_ = board;
	_tmp51_ = reader;
	sudoku_board_set_previous_played_time (_tmp50_, json_reader_get_double_value (_tmp51_));
	_tmp52_ = reader;
	json_reader_end_member (_tmp52_);
	_tmp53_ = reader;
	json_reader_read_member (_tmp53_, "difficulty_category");
	_tmp54_ = reader;
	g_return_val_if_fail (json_reader_is_value (_tmp54_), NULL);
	_tmp55_ = board;
	_tmp56_ = reader;
	_tmp57_ = json_reader_get_string_value (_tmp56_);
	sudoku_board_set_difficulty_category (_tmp55_, difficulty_category_from_string (_tmp57_));
	_tmp58_ = reader;
	json_reader_end_member (_tmp58_);
	_tmp59_ = board;
	_tmp60_ = sudoku_game_new (_tmp59_);
	result = _tmp60_;
	_g_object_unref0 (reader);
	__vala_JsonNode_free0 (node);
	_g_object_unref0 (board);
	_g_object_unref0 (parser);
	return result;
}

const gchar*
sudoku_saver_get_savegame_file (void)
{
	const gchar* result;
	const gchar* _tmp0_;
	_tmp0_ = sudoku_saver__savegame_file;
	result = _tmp0_;
	return result;
}

static void
sudoku_saver_set_savegame_file (const gchar* value)
{
	gchar* _tmp0_;
	_tmp0_ = g_strdup (value);
	_g_free0 (sudoku_saver__savegame_file);
	sudoku_saver__savegame_file = _tmp0_;
}

const gchar*
sudoku_saver_get_finishgame_dir (void)
{
	const gchar* result;
	const gchar* _tmp0_;
	_tmp0_ = sudoku_saver__finishgame_dir;
	result = _tmp0_;
	return result;
}

static void
sudoku_saver_set_finishgame_dir (const gchar* value)
{
	gchar* _tmp0_;
	_tmp0_ = g_strdup (value);
	_g_free0 (sudoku_saver__finishgame_dir);
	sudoku_saver__finishgame_dir = _tmp0_;
}

static void
sudoku_saver_class_init (SudokuSaverClass * klass,
                         gpointer klass_data)
{
	gchar* _tmp0_;
	gchar* _tmp1_;
	sudoku_saver_parent_class = g_type_class_peek_parent (klass);
	G_OBJECT_CLASS (klass)->get_property = _vala_sudoku_saver_get_property;
	G_OBJECT_CLASS (klass)->set_property = _vala_sudoku_saver_set_property;
	G_OBJECT_CLASS (klass)->finalize = sudoku_saver_finalize;
	_tmp0_ = g_strdup ("");
	sudoku_saver__savegame_file = _tmp0_;
	_tmp1_ = g_strdup ("");
	sudoku_saver__finishgame_dir = _tmp1_;
}

static void
sudoku_saver_instance_init (SudokuSaver * self,
                            gpointer klass)
{
}

static void
sudoku_saver_finalize (GObject * obj)
{
	SudokuSaver * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, TYPE_SUDOKU_SAVER, SudokuSaver);
	G_OBJECT_CLASS (sudoku_saver_parent_class)->finalize (obj);
}

static GType
sudoku_saver_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (SudokuSaverClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) sudoku_saver_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (SudokuSaver), 0, (GInstanceInitFunc) sudoku_saver_instance_init, NULL };
	GType sudoku_saver_type_id;
	sudoku_saver_type_id = g_type_register_static (G_TYPE_OBJECT, "SudokuSaver", &g_define_type_info, 0);
	return sudoku_saver_type_id;
}

GType
sudoku_saver_get_type (void)
{
	static volatile gsize sudoku_saver_type_id__once = 0;
	if (g_once_init_enter (&sudoku_saver_type_id__once)) {
		GType sudoku_saver_type_id;
		sudoku_saver_type_id = sudoku_saver_get_type_once ();
		g_once_init_leave (&sudoku_saver_type_id__once, sudoku_saver_type_id);
	}
	return sudoku_saver_type_id__once;
}

static void
_vala_sudoku_saver_get_property (GObject * object,
                                 guint property_id,
                                 GValue * value,
                                 GParamSpec * pspec)
{
	SudokuSaver * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (object, TYPE_SUDOKU_SAVER, SudokuSaver);
	switch (property_id) {
		default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
	}
}

static void
_vala_sudoku_saver_set_property (GObject * object,
                                 guint property_id,
                                 const GValue * value,
                                 GParamSpec * pspec)
{
	SudokuSaver * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (object, TYPE_SUDOKU_SAVER, SudokuSaver);
	switch (property_id) {
		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;
}

