/* sudoku-printer.c generated by valac 0.56.3, the Vala compiler
 * generated from sudoku-printer.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 <glib-object.h>
#include <gee.h>
#include "libsudoku.h"
#include <gtk/gtk.h>
#include <glib.h>
#include <stdlib.h>
#include <string.h>
#include <glib/gi18n-lib.h>
#include <cairo-gobject.h>
#include <float.h>
#include <math.h>
#include <pango/pango.h>
#include <pango/pangocairo.h>
#include <gdk/gdk.h>

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

#define TYPE_SUDOKU_PRINTER (sudoku_printer_get_type ())
#define SUDOKU_PRINTER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_SUDOKU_PRINTER, SudokuPrinter))
#define SUDOKU_PRINTER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_SUDOKU_PRINTER, SudokuPrinterClass))
#define IS_SUDOKU_PRINTER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_SUDOKU_PRINTER))
#define IS_SUDOKU_PRINTER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_SUDOKU_PRINTER))
#define SUDOKU_PRINTER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_SUDOKU_PRINTER, SudokuPrinterClass))

typedef struct _SudokuPrinter SudokuPrinter;
typedef struct _SudokuPrinterClass SudokuPrinterClass;
typedef struct _SudokuPrinterPrivate SudokuPrinterPrivate;
enum  {
	SUDOKU_PRINTER_0_PROPERTY,
	SUDOKU_PRINTER_NUM_PROPERTIES
};
static GParamSpec* sudoku_printer_properties[SUDOKU_PRINTER_NUM_PROPERTIES];
#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))
#define _g_free0(var) (var = (g_free (var), NULL))
#define _g_error_free0(var) ((var == NULL) ? NULL : (var = (g_error_free (var), NULL)))
#define __vala_PangoFontDescription_free0(var) ((var == NULL) ? NULL : (var = (_vala_PangoFontDescription_free (var), NULL)))
#define _cairo_destroy0(var) ((var == NULL) ? NULL : (var = (cairo_destroy (var), NULL)))

struct _SudokuPrinter {
	GObject parent_instance;
	SudokuPrinterPrivate * priv;
};

struct _SudokuPrinterClass {
	GObjectClass parent_class;
};

struct _SudokuPrinterPrivate {
	GeeList* boards;
	GtkWindow* window;
	gint margin;
	gint n_sudokus;
	gint sudokus_per_page;
	GtkPrintOperation* print_op;
};

static gint SudokuPrinter_private_offset;
static gpointer sudoku_printer_parent_class = NULL;

VALA_EXTERN GType sudoku_printer_get_type (void) G_GNUC_CONST ;
G_DEFINE_AUTOPTR_CLEANUP_FUNC (SudokuPrinter, g_object_unref)
VALA_EXTERN GtkPrintOperationResult sudoku_printer_print_sudoku (SudokuPrinter* self);
VALA_EXTERN SudokuPrinter* sudoku_printer_new (GeeList* boards,
                                   gint sudokus_per_page,
                                   GtkWindow* window);
VALA_EXTERN SudokuPrinter* sudoku_printer_construct (GType object_type,
                                         GeeList* boards,
                                         gint sudokus_per_page,
                                         GtkWindow* window);
static void sudoku_printer_begin_print_cb (SudokuPrinter* self,
                                    GtkPrintOperation* operation,
                                    GtkPrintContext* context);
static void _sudoku_printer_begin_print_cb_gtk_print_operation_begin_print (GtkPrintOperation* _sender,
                                                                     GtkPrintContext* context,
                                                                     gpointer self);
static void sudoku_printer_draw_page_cb (SudokuPrinter* self,
                                  GtkPrintOperation* operation,
                                  GtkPrintContext* context,
                                  gint page_nr);
static void _sudoku_printer_draw_page_cb_gtk_print_operation_draw_page (GtkPrintOperation* _sender,
                                                                 GtkPrintContext* context,
                                                                 gint page_nr,
                                                                 gpointer self);
static void sudoku_printer_set_label_font (SudokuPrinter* self,
                                    cairo_t* cr);
static gdouble sudoku_printer_fit_squares_in_rectangle (SudokuPrinter* self,
                                                 gdouble width,
                                                 gdouble height,
                                                 gdouble label_height,
                                                 gint margin,
                                                 guint* across,
                                                 guint* down);
static void _vala_PangoFontDescription_free (PangoFontDescription* self);
static void sudoku_printer_draw_sudoku (SudokuPrinter* self,
                                 cairo_t* cr,
                                 SudokuBoard* sudoku_board,
                                 gdouble size,
                                 gdouble offset_x,
                                 gdouble offset_y);
static void sudoku_printer_finalize (GObject * obj);
static GType sudoku_printer_get_type_once (void);

static inline gpointer
sudoku_printer_get_instance_private (SudokuPrinter* self)
{
	return G_STRUCT_MEMBER_P (self, SudokuPrinter_private_offset);
}

GtkPrintOperationResult
sudoku_printer_print_sudoku (SudokuPrinter* self)
{
	GError* _inner_error0_ = NULL;
	GtkPrintOperationResult result;
	g_return_val_if_fail (self != NULL, 0);
	{
		GtkPrintOperationResult _result_ = 0;
		GtkPrintOperation* _tmp0_;
		GtkWindow* _tmp1_;
		_tmp0_ = self->priv->print_op;
		_tmp1_ = self->priv->window;
		_result_ = gtk_print_operation_run (_tmp0_, GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG, _tmp1_, &_inner_error0_);
		if (G_UNLIKELY (_inner_error0_ != NULL)) {
			goto __catch0_g_error;
		}
		result = _result_;
		return result;
	}
	goto __finally0;
	__catch0_g_error:
	{
		GError* e = NULL;
		GtkWindow* _tmp2_;
		GError* _tmp3_;
		const gchar* _tmp4_;
		gchar* _tmp5_;
		gchar* _tmp6_;
		GtkMessageDialog* _tmp7_;
		GtkMessageDialog* _tmp8_;
		e = _inner_error0_;
		_inner_error0_ = NULL;
		_tmp2_ = self->priv->window;
		_tmp3_ = e;
		_tmp4_ = _tmp3_->message;
		_tmp5_ = g_strdup_printf ("%s\n%s", _ ("Error printing file:"), _tmp4_);
		_tmp6_ = _tmp5_;
		_tmp7_ = (GtkMessageDialog*) gtk_message_dialog_new (_tmp2_, GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, "%s", _tmp6_);
		g_object_ref_sink (_tmp7_);
		_tmp8_ = _tmp7_;
		gtk_dialog_run ((GtkDialog*) _tmp8_);
		_g_object_unref0 (_tmp8_);
		_g_free0 (_tmp6_);
		_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 0;
	}
	result = GTK_PRINT_OPERATION_RESULT_ERROR;
	return result;
}

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

static void
_sudoku_printer_begin_print_cb_gtk_print_operation_begin_print (GtkPrintOperation* _sender,
                                                                GtkPrintContext* context,
                                                                gpointer self)
{
	sudoku_printer_begin_print_cb ((SudokuPrinter*) self, _sender, context);
}

static void
_sudoku_printer_draw_page_cb_gtk_print_operation_draw_page (GtkPrintOperation* _sender,
                                                            GtkPrintContext* context,
                                                            gint page_nr,
                                                            gpointer self)
{
	sudoku_printer_draw_page_cb ((SudokuPrinter*) self, _sender, context, page_nr);
}

SudokuPrinter*
sudoku_printer_construct (GType object_type,
                          GeeList* boards,
                          gint sudokus_per_page,
                          GtkWindow* window)
{
	SudokuPrinter * self = NULL;
	GeeList* _tmp0_;
	GtkWindow* _tmp1_;
	gint _tmp2_;
	gint _tmp3_;
	GtkPrintOperation* _tmp4_;
	GtkPrintOperation* _tmp5_;
	GtkPrintOperation* _tmp6_;
	g_return_val_if_fail (boards != NULL, NULL);
	g_return_val_if_fail (window != NULL, NULL);
	self = (SudokuPrinter*) g_object_new (object_type, NULL);
	_tmp0_ = _g_object_ref0 (boards);
	_g_object_unref0 (self->priv->boards);
	self->priv->boards = _tmp0_;
	_tmp1_ = _g_object_ref0 (window);
	_g_object_unref0 (self->priv->window);
	self->priv->window = _tmp1_;
	self->priv->margin = 25;
	_tmp2_ = gee_collection_get_size ((GeeCollection*) boards);
	_tmp3_ = _tmp2_;
	self->priv->n_sudokus = _tmp3_;
	self->priv->sudokus_per_page = sudokus_per_page;
	_tmp4_ = gtk_print_operation_new ();
	_g_object_unref0 (self->priv->print_op);
	self->priv->print_op = _tmp4_;
	_tmp5_ = self->priv->print_op;
	g_signal_connect_object (_tmp5_, "begin-print", (GCallback) _sudoku_printer_begin_print_cb_gtk_print_operation_begin_print, self, 0);
	_tmp6_ = self->priv->print_op;
	g_signal_connect_object (_tmp6_, "draw-page", (GCallback) _sudoku_printer_draw_page_cb_gtk_print_operation_draw_page, self, 0);
	return self;
}

SudokuPrinter*
sudoku_printer_new (GeeList* boards,
                    gint sudokus_per_page,
                    GtkWindow* window)
{
	return sudoku_printer_construct (TYPE_SUDOKU_PRINTER, boards, sudokus_per_page, window);
}

static void
sudoku_printer_begin_print_cb (SudokuPrinter* self,
                               GtkPrintOperation* operation,
                               GtkPrintContext* context)
{
	gint pages = 0;
	g_return_if_fail (self != NULL);
	g_return_if_fail (operation != NULL);
	g_return_if_fail (context != NULL);
	pages = self->priv->n_sudokus / self->priv->sudokus_per_page;
	while (TRUE) {
		if (!((pages * self->priv->sudokus_per_page) < self->priv->n_sudokus)) {
			break;
		}
		pages += 1;
	}
	gtk_print_operation_set_n_pages (operation, pages);
}

static gpointer
_cairo_reference0 (gpointer self)
{
	return self ? cairo_reference (self) : NULL;
}

static void
_vala_PangoFontDescription_free (PangoFontDescription* self)
{
	g_boxed_free (pango_font_description_get_type (), self);
}

static void
sudoku_printer_draw_page_cb (SudokuPrinter* self,
                             GtkPrintOperation* operation,
                             GtkPrintContext* context,
                             gint page_nr)
{
	cairo_t* cr = NULL;
	cairo_t* _tmp0_;
	cairo_t* _tmp1_;
	gdouble width = 0.0;
	gdouble height = 0.0;
	cairo_t* _tmp2_;
	cairo_text_extents_t label_extents = {0};
	cairo_t* _tmp3_;
	cairo_text_extents_t _tmp4_ = {0};
	guint n_across = 0U;
	guint n_down = 0U;
	gdouble best_square_size = 0.0;
	cairo_text_extents_t _tmp5_;
	guint _tmp6_ = 0U;
	guint _tmp7_ = 0U;
	gdouble _tmp8_;
	gdouble margin_x = 0.0;
	gdouble margin_y = 0.0;
	gint start = 0;
	gint end = 0;
	GeeList* _tmp9_;
	gint _tmp10_;
	gint _tmp11_;
	GeeList* sudokus_on_page = NULL;
	GeeList* _tmp12_;
	GeeList* _tmp13_;
	guint index = 0U;
	PangoContext* pango_context = NULL;
	cairo_t* _tmp14_;
	PangoContext* _tmp15_;
	PangoContext* _tmp16_;
	GdkScreen* _tmp17_;
	cairo_font_options_t* _tmp18_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (operation != NULL);
	g_return_if_fail (context != NULL);
	_tmp0_ = gtk_print_context_get_cairo_context (context);
	_tmp1_ = _cairo_reference0 (_tmp0_);
	cr = _tmp1_;
	width = gtk_print_context_get_width (context);
	height = gtk_print_context_get_height (context);
	_tmp2_ = cr;
	sudoku_printer_set_label_font (self, _tmp2_);
	_tmp3_ = cr;
	cairo_text_extents (_tmp3_, "Ww", &_tmp4_);
	label_extents = _tmp4_;
	_tmp5_ = label_extents;
	_tmp8_ = sudoku_printer_fit_squares_in_rectangle (self, width, height, _tmp5_.height, self->priv->margin, &_tmp6_, &_tmp7_);
	n_across = _tmp6_;
	n_down = _tmp7_;
	best_square_size = _tmp8_;
	margin_x = (width - (best_square_size * n_across)) / (n_across + 1);
	margin_y = (height - (best_square_size * n_down)) / (n_down + 1);
	start = page_nr * self->priv->sudokus_per_page;
	_tmp9_ = self->priv->boards;
	_tmp10_ = gee_collection_get_size ((GeeCollection*) _tmp9_);
	_tmp11_ = _tmp10_;
	end = MIN (start + self->priv->sudokus_per_page, _tmp11_);
	_tmp12_ = self->priv->boards;
	_tmp13_ = gee_list_slice (_tmp12_, start, end);
	sudokus_on_page = _tmp13_;
	index = (guint) 0;
	_tmp14_ = cr;
	_tmp15_ = pango_cairo_create_context (_tmp14_);
	pango_context = _tmp15_;
	_tmp16_ = pango_context;
	_tmp17_ = gdk_screen_get_default ();
	_tmp18_ = gdk_screen_get_font_options (_tmp17_);
	pango_cairo_context_set_font_options (_tmp16_, _tmp18_);
	{
		GeeList* _sudoku_list = NULL;
		GeeList* _tmp19_;
		gint _sudoku_size = 0;
		GeeList* _tmp20_;
		gint _tmp21_;
		gint _tmp22_;
		gint _sudoku_index = 0;
		_tmp19_ = sudokus_on_page;
		_sudoku_list = _tmp19_;
		_tmp20_ = _sudoku_list;
		_tmp21_ = gee_collection_get_size ((GeeCollection*) _tmp20_);
		_tmp22_ = _tmp21_;
		_sudoku_size = _tmp22_;
		_sudoku_index = -1;
		while (TRUE) {
			gint _tmp23_;
			gint _tmp24_;
			SudokuBoard* sudoku = NULL;
			GeeList* _tmp25_;
			gpointer _tmp26_;
			gdouble left = 0.0;
			gdouble top = 0.0;
			cairo_text_extents_t _tmp27_;
			cairo_text_extents_t _tmp28_;
			gchar* label = NULL;
			SudokuBoard* _tmp29_;
			DifficultyCategory _tmp30_;
			DifficultyCategory _tmp31_;
			gchar* _tmp32_;
			PangoLayout* layout = NULL;
			PangoContext* _tmp33_;
			PangoLayout* _tmp34_;
			PangoLayout* _tmp35_;
			PangoFontDescription* _tmp36_;
			PangoFontDescription* _tmp37_;
			PangoLayout* _tmp38_;
			const gchar* _tmp39_;
			gint layout_width = 0;
			gint layout_height = 0;
			PangoLayout* _tmp40_;
			gint _tmp41_ = 0;
			gint _tmp42_ = 0;
			cairo_t* _tmp43_;
			cairo_t* _tmp44_;
			cairo_t* _tmp45_;
			PangoLayout* _tmp46_;
			cairo_t* _tmp47_;
			SudokuBoard* _tmp48_;
			_sudoku_index = _sudoku_index + 1;
			_tmp23_ = _sudoku_index;
			_tmp24_ = _sudoku_size;
			if (!(_tmp23_ < _tmp24_)) {
				break;
			}
			_tmp25_ = _sudoku_list;
			_tmp26_ = gee_list_get (_tmp25_, _sudoku_index);
			sudoku = (SudokuBoard*) _tmp26_;
			left = margin_x + ((index % n_across) * (best_square_size + margin_x));
			_tmp27_ = label_extents;
			_tmp28_ = label_extents;
			top = (margin_y + _tmp27_.height) + ((index / n_across) * ((best_square_size + margin_y) + _tmp28_.height));
			_tmp29_ = sudoku;
			_tmp30_ = sudoku_board_get_difficulty_category (_tmp29_);
			_tmp31_ = _tmp30_;
			_tmp32_ = difficulty_category_to_string (_tmp31_);
			label = _tmp32_;
			_tmp33_ = pango_context;
			_tmp34_ = pango_layout_new (_tmp33_);
			layout = _tmp34_;
			_tmp35_ = layout;
			_tmp36_ = pango_font_description_from_string ("Sans Bold 9");
			_tmp37_ = _tmp36_;
			pango_layout_set_font_description (_tmp35_, _tmp37_);
			__vala_PangoFontDescription_free0 (_tmp37_);
			_tmp38_ = layout;
			_tmp39_ = label;
			pango_layout_set_text (_tmp38_, _tmp39_, -1);
			_tmp40_ = layout;
			pango_layout_get_size (_tmp40_, &_tmp41_, &_tmp42_);
			layout_width = _tmp41_;
			layout_height = _tmp42_;
			layout_width /= PANGO_SCALE;
			layout_height /= PANGO_SCALE;
			_tmp43_ = cr;
			cairo_move_to (_tmp43_, left + ((best_square_size - layout_width) / 2), top - layout_height);
			_tmp44_ = cr;
			cairo_set_source_rgb (_tmp44_, (gdouble) 0, (gdouble) 0, (gdouble) 0);
			_tmp45_ = cr;
			_tmp46_ = layout;
			pango_cairo_show_layout (_tmp45_, _tmp46_);
			_tmp47_ = cr;
			_tmp48_ = sudoku;
			sudoku_printer_draw_sudoku (self, _tmp47_, _tmp48_, best_square_size, left, top);
			index += (guint) 1;
			_g_object_unref0 (layout);
			_g_free0 (label);
			_g_object_unref0 (sudoku);
		}
	}
	_g_object_unref0 (pango_context);
	_g_object_unref0 (sudokus_on_page);
	_cairo_destroy0 (cr);
}

static void
sudoku_printer_set_label_font (SudokuPrinter* self,
                               cairo_t* cr)
{
	g_return_if_fail (self != NULL);
	g_return_if_fail (cr != NULL);
	cairo_set_font_size (cr, (gdouble) 12);
	cairo_select_font_face (cr, "Sans", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD);
}

static gdouble
sudoku_printer_fit_squares_in_rectangle (SudokuPrinter* self,
                                         gdouble width,
                                         gdouble height,
                                         gdouble label_height,
                                         gint margin,
                                         guint* across,
                                         guint* down)
{
	guint _vala_across = 0U;
	guint _vala_down = 0U;
	gint n = 0;
	gdouble best_square_size = 0.0;
	gdouble square_size = 0.0;
	gdouble result;
	g_return_val_if_fail (self != NULL, 0.0);
	n = self->priv->sudokus_per_page;
	best_square_size = 0.0;
	square_size = 0.0;
	_vala_across = (guint) 1;
	_vala_down = (guint) n;
	{
		gint n_across = 0;
		n_across = 1;
		{
			gboolean _tmp0_ = FALSE;
			_tmp0_ = TRUE;
			while (TRUE) {
				gint n_down = 0;
				gdouble across_size = 0.0;
				gdouble down_size = 0.0;
				if (!_tmp0_) {
					gint _tmp1_;
					_tmp1_ = n_across;
					n_across = _tmp1_ + 1;
				}
				_tmp0_ = FALSE;
				if (!(n_across <= n)) {
					break;
				}
				n_down = ((n + n_across) - 1) / n_across;
				across_size = width - ((n_across + 1) * margin);
				across_size = across_size / n_across;
				down_size = (height - ((n_down + 1) * margin)) - (n_down * label_height);
				down_size = down_size / n_down;
				square_size = MIN (across_size, down_size);
				if (square_size > best_square_size) {
					best_square_size = square_size;
					_vala_across = (guint) n_across;
					_vala_down = (guint) n_down;
				}
			}
		}
	}
	result = best_square_size;
	if (across) {
		*across = _vala_across;
	}
	if (down) {
		*down = _vala_down;
	}
	return result;
}

static void
sudoku_printer_draw_sudoku (SudokuPrinter* self,
                            cairo_t* cr,
                            SudokuBoard* sudoku_board,
                            gdouble size,
                            gdouble offset_x,
                            gdouble offset_y)
{
	static const gint SUDOKU_SIZE = 9;
	static const gint N_BOXES = 3;
	static const gdouble PENCIL_GREY[3] = {0.3, 0.3, 0.3};
	static const gdouble BACKGROUND_COLOR[3] = {1.0, 1.0, 1.0};
	static const gdouble BORDER_COLOR[3] = {1.0, 1.0, 1.0};
	static const gdouble LINE_COLOR[3] = {0.0, 0.0, 0.0};
	gdouble THIN = 0.0;
	gdouble THICK = 0.0;
	gdouble BORDER = 0.0;
	gdouble WHITE_SPACE = 0.0;
	gdouble SQUARE_SIZE = 0.0;
	gint FONT_SIZE = 0;
	static const cairo_font_weight_t FONT_WEIGHT = CAIRO_FONT_WEIGHT_NORMAL;
	gdouble* outer = NULL;
	gdouble* _tmp0_;
	gint outer_length1;
	gint _outer_size_;
	gdouble* _tmp1_;
	gint _tmp1__length1;
	gdouble _tmp2_;
	gdouble* _tmp3_;
	gint _tmp3__length1;
	gdouble _tmp4_;
	gdouble* _tmp5_;
	gint _tmp5__length1;
	gdouble _tmp6_;
	gdouble* _tmp7_;
	gint _tmp7__length1;
	gdouble _tmp8_;
	gdouble _tmp9_;
	gdouble _tmp10_;
	gdouble _tmp11_;
	gdouble _tmp12_;
	gdouble _tmp13_;
	gdouble _tmp14_;
	gdouble* _tmp15_;
	gint _tmp15__length1;
	gdouble _tmp16_;
	gdouble* _tmp17_;
	gint _tmp17__length1;
	gdouble _tmp18_;
	gdouble _tmp19_;
	gdouble _tmp20_;
	gdouble _tmp21_;
	gdouble* pos = NULL;
	gdouble* _tmp22_;
	gint pos_length1;
	gint _pos_size_;
	gdouble position = 0.0;
	gdouble* _tmp23_;
	gint _tmp23__length1;
	gdouble last_line = 0.0;
	gchar* letter = NULL;
	gchar* _tmp27_;
	cairo_text_extents_t extents = {0};
	gint* sudoku = NULL;
	gint _tmp28_ = 0;
	gint _tmp29_ = 0;
	gint* _tmp30_;
	gint sudoku_length1;
	gint sudoku_length2;
	gboolean invert = FALSE;
	g_return_if_fail (self != NULL);
	g_return_if_fail (cr != NULL);
	g_return_if_fail (sudoku_board != NULL);
	THIN = size / 500.0;
	THICK = THIN * 5;
	BORDER = THICK;
	WHITE_SPACE = (((size - (2 * BORDER)) - (2 * THICK)) - ((N_BOXES - 1) * THICK)) - ((N_BOXES * 2) * THIN);
	SQUARE_SIZE = WHITE_SPACE / SUDOKU_SIZE;
	FONT_SIZE = ((gint) SQUARE_SIZE) / 2;
	_tmp0_ = g_new0 (gdouble, 4);
	_tmp0_[0] = offset_x;
	_tmp0_[1] = offset_x + size;
	_tmp0_[2] = offset_y;
	_tmp0_[3] = offset_y + size;
	outer = _tmp0_;
	outer_length1 = 4;
	_outer_size_ = outer_length1;
	cairo_set_source_rgb (cr, 1.0, 1.0, 1.0);
	_tmp1_ = outer;
	_tmp1__length1 = outer_length1;
	_tmp2_ = _tmp1_[0];
	_tmp3_ = outer;
	_tmp3__length1 = outer_length1;
	_tmp4_ = _tmp3_[2];
	cairo_rectangle (cr, _tmp2_, _tmp4_, size, size);
	cairo_fill (cr);
	cairo_set_line_join (cr, CAIRO_LINE_JOIN_ROUND);
	cairo_set_line_width (cr, BORDER);
	_tmp5_ = outer;
	_tmp5__length1 = outer_length1;
	_tmp6_ = _tmp5_[0];
	_tmp7_ = outer;
	_tmp7__length1 = outer_length1;
	_tmp8_ = _tmp7_[2];
	cairo_rectangle (cr, _tmp6_ + (BORDER / 2.0), _tmp8_ + (BORDER / 2.0), size - BORDER, size - BORDER);
	_tmp9_ = BACKGROUND_COLOR[0];
	_tmp10_ = BACKGROUND_COLOR[1];
	_tmp11_ = BACKGROUND_COLOR[2];
	cairo_set_source_rgb (cr, _tmp9_, _tmp10_, _tmp11_);
	cairo_fill_preserve (cr);
	_tmp12_ = BORDER_COLOR[0];
	_tmp13_ = BORDER_COLOR[1];
	_tmp14_ = BORDER_COLOR[2];
	cairo_set_source_rgb (cr, _tmp12_, _tmp13_, _tmp14_);
	cairo_stroke (cr);
	cairo_set_line_join (cr, CAIRO_LINE_JOIN_MITER);
	cairo_set_line_width (cr, THICK);
	_tmp15_ = outer;
	_tmp15__length1 = outer_length1;
	_tmp16_ = _tmp15_[0];
	_tmp17_ = outer;
	_tmp17__length1 = outer_length1;
	_tmp18_ = _tmp17_[2];
	cairo_rectangle (cr, (_tmp16_ + BORDER) + (THICK / 2.0), (_tmp18_ + BORDER) + (THICK / 2.0), (size - (BORDER * 2)) - THICK, (size - (BORDER * 2)) - THICK);
	_tmp19_ = LINE_COLOR[0];
	_tmp20_ = LINE_COLOR[1];
	_tmp21_ = LINE_COLOR[2];
	cairo_set_source_rgb (cr, _tmp19_, _tmp20_, _tmp21_);
	cairo_stroke (cr);
	_tmp22_ = g_new0 (gdouble, SUDOKU_SIZE + 1);
	pos = _tmp22_;
	pos_length1 = SUDOKU_SIZE + 1;
	_pos_size_ = pos_length1;
	position = BORDER + THICK;
	_tmp23_ = pos;
	_tmp23__length1 = pos_length1;
	_tmp23_[0] = position + (SQUARE_SIZE / 2.0);
	last_line = 0.0;
	{
		gint n = 0;
		n = 1;
		{
			gboolean _tmp24_ = FALSE;
			_tmp24_ = TRUE;
			while (TRUE) {
				gdouble* _tmp26_;
				gint _tmp26__length1;
				if (!_tmp24_) {
					gint _tmp25_;
					_tmp25_ = n;
					n = _tmp25_ + 1;
				}
				_tmp24_ = FALSE;
				if (!(n <= SUDOKU_SIZE)) {
					break;
				}
				if ((n % N_BOXES) == 0) {
					cairo_set_line_width (cr, THICK);
					position += (SQUARE_SIZE + (last_line / 2.0)) + (THICK / 2.0);
					last_line = THICK;
				} else {
					cairo_set_line_width (cr, THIN);
					position += (SQUARE_SIZE + (last_line / 2.0)) + (THIN / 2.0);
					last_line = THIN;
				}
				_tmp26_ = pos;
				_tmp26__length1 = pos_length1;
				_tmp26_[n] = (position + (last_line / 2.0)) + (SQUARE_SIZE / 2.0);
				cairo_move_to (cr, (BORDER + (THICK / 2.0)) + offset_x, position + offset_y);
				cairo_line_to (cr, ((size - BORDER) - (THICK / 2.0)) + offset_x, position + offset_y);
				cairo_move_to (cr, position + offset_x, (BORDER + (THICK / 2.0)) + offset_y);
				cairo_line_to (cr, position + offset_x, ((size - BORDER) - (THICK / 2.0)) + offset_y);
				cairo_stroke (cr);
			}
		}
	}
	cairo_set_font_size (cr, (gdouble) FONT_SIZE);
	_tmp27_ = g_strdup ("");
	letter = _tmp27_;
	_tmp30_ = sudoku_board_get_cells (sudoku_board, &_tmp28_, &_tmp29_);
	sudoku = _tmp30_;
	sudoku_length1 = _tmp28_;
	sudoku_length2 = _tmp29_;
	invert = gtk_widget_get_default_direction () == GTK_TEXT_DIR_RTL;
	{
		gint x = 0;
		x = 0;
		{
			gboolean _tmp31_ = FALSE;
			_tmp31_ = TRUE;
			while (TRUE) {
				gint _tmp33_ = 0;
				gint real_x = 0;
				if (!_tmp31_) {
					gint _tmp32_;
					_tmp32_ = x;
					x = _tmp32_ + 1;
				}
				_tmp31_ = FALSE;
				if (!(x < SUDOKU_SIZE)) {
					break;
				}
				if (invert) {
					_tmp33_ = (SUDOKU_SIZE - x) - 1;
				} else {
					_tmp33_ = x;
				}
				real_x = _tmp33_;
				{
					gint y = 0;
					y = 0;
					{
						gboolean _tmp34_ = FALSE;
						_tmp34_ = TRUE;
						while (TRUE) {
							gdouble* _tmp36_;
							gint _tmp36__length1;
							gdouble _tmp37_;
							gdouble* _tmp38_;
							gint _tmp38__length1;
							gdouble _tmp39_;
							gchar* _tmp40_;
							gint* _tmp41_;
							gint _tmp41__length1;
							gint _tmp41__length2;
							gint _tmp42_;
							if (!_tmp34_) {
								gint _tmp35_;
								_tmp35_ = y;
								y = _tmp35_ + 1;
							}
							_tmp34_ = FALSE;
							if (!(y < SUDOKU_SIZE)) {
								break;
							}
							_tmp36_ = pos;
							_tmp36__length1 = pos_length1;
							_tmp37_ = _tmp36_[x];
							_tmp38_ = pos;
							_tmp38__length1 = pos_length1;
							_tmp39_ = _tmp38_[y];
							cairo_move_to (cr, _tmp37_ + offset_x, _tmp39_ + offset_y);
							_tmp40_ = g_strdup ("");
							_g_free0 (letter);
							letter = _tmp40_;
							_tmp41_ = sudoku;
							_tmp41__length1 = sudoku_length1;
							_tmp41__length2 = sudoku_length2;
							_tmp42_ = _tmp41_[(y * _tmp41__length2) + real_x];
							if (_tmp42_ != 0) {
								gint* _tmp43_;
								gint _tmp43__length1;
								gint _tmp43__length2;
								gint _tmp44_;
								gchar* _tmp45_;
								gboolean* _tmp46_;
								gint _tmp46__length1;
								gint _tmp46__length2;
								gboolean _tmp47_;
								const gchar* _tmp51_;
								cairo_text_extents_t _tmp52_ = {0};
								gdouble* _tmp53_;
								gint _tmp53__length1;
								gdouble _tmp54_;
								cairo_text_extents_t _tmp55_;
								gdouble* _tmp56_;
								gint _tmp56__length1;
								gdouble _tmp57_;
								cairo_text_extents_t _tmp58_;
								const gchar* _tmp59_;
								_tmp43_ = sudoku;
								_tmp43__length1 = sudoku_length1;
								_tmp43__length2 = sudoku_length2;
								_tmp44_ = _tmp43_[(y * _tmp43__length2) + real_x];
								_tmp45_ = g_strdup_printf ("%i", _tmp44_);
								_g_free0 (letter);
								letter = _tmp45_;
								_tmp46_ = sudoku_board->is_fixed;
								_tmp46__length1 = sudoku_board->is_fixed_length1;
								_tmp46__length2 = sudoku_board->is_fixed_length2;
								_tmp47_ = _tmp46_[(y * _tmp46__length2) + real_x];
								if (_tmp47_) {
									cairo_select_font_face (cr, "Sans", CAIRO_FONT_SLANT_NORMAL, FONT_WEIGHT);
									cairo_set_source_rgb (cr, (gdouble) 0, (gdouble) 0, (gdouble) 0);
								} else {
									gdouble _tmp48_;
									gdouble _tmp49_;
									gdouble _tmp50_;
									cairo_select_font_face (cr, "Sans", CAIRO_FONT_SLANT_ITALIC, FONT_WEIGHT);
									_tmp48_ = PENCIL_GREY[0];
									_tmp49_ = PENCIL_GREY[1];
									_tmp50_ = PENCIL_GREY[2];
									cairo_set_source_rgb (cr, _tmp48_, _tmp49_, _tmp50_);
								}
								_tmp51_ = letter;
								cairo_text_extents (cr, _tmp51_, &_tmp52_);
								extents = _tmp52_;
								_tmp53_ = pos;
								_tmp53__length1 = pos_length1;
								_tmp54_ = _tmp53_[x];
								_tmp55_ = extents;
								_tmp56_ = pos;
								_tmp56__length1 = pos_length1;
								_tmp57_ = _tmp56_[y];
								_tmp58_ = extents;
								cairo_move_to (cr, (_tmp54_ + offset_x) - (_tmp55_.x_advance / 2.0), (_tmp57_ + offset_y) + (_tmp58_.height / 2.0));
								_tmp59_ = letter;
								cairo_show_text (cr, _tmp59_);
							}
						}
					}
				}
			}
		}
	}
	sudoku = (g_free (sudoku), NULL);
	_g_free0 (letter);
	pos = (g_free (pos), NULL);
	outer = (g_free (outer), NULL);
}

static void
sudoku_printer_class_init (SudokuPrinterClass * klass,
                           gpointer klass_data)
{
	sudoku_printer_parent_class = g_type_class_peek_parent (klass);
	g_type_class_adjust_private_offset (klass, &SudokuPrinter_private_offset);
	G_OBJECT_CLASS (klass)->finalize = sudoku_printer_finalize;
}

static void
sudoku_printer_instance_init (SudokuPrinter * self,
                              gpointer klass)
{
	self->priv = sudoku_printer_get_instance_private (self);
}

static void
sudoku_printer_finalize (GObject * obj)
{
	SudokuPrinter * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, TYPE_SUDOKU_PRINTER, SudokuPrinter);
	_g_object_unref0 (self->priv->boards);
	_g_object_unref0 (self->priv->window);
	_g_object_unref0 (self->priv->print_op);
	G_OBJECT_CLASS (sudoku_printer_parent_class)->finalize (obj);
}

static GType
sudoku_printer_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (SudokuPrinterClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) sudoku_printer_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (SudokuPrinter), 0, (GInstanceInitFunc) sudoku_printer_instance_init, NULL };
	GType sudoku_printer_type_id;
	sudoku_printer_type_id = g_type_register_static (G_TYPE_OBJECT, "SudokuPrinter", &g_define_type_info, 0);
	SudokuPrinter_private_offset = g_type_add_instance_private (sudoku_printer_type_id, sizeof (SudokuPrinterPrivate));
	return sudoku_printer_type_id;
}

GType
sudoku_printer_get_type (void)
{
	static volatile gsize sudoku_printer_type_id__once = 0;
	if (g_once_init_enter (&sudoku_printer_type_id__once)) {
		GType sudoku_printer_type_id;
		sudoku_printer_type_id = sudoku_printer_get_type_once ();
		g_once_init_leave (&sudoku_printer_type_id__once, sudoku_printer_type_id);
	}
	return sudoku_printer_type_id__once;
}

