/* io.elementary.print.c generated by valac 0.56.17, the Vala compiler
 * generated from io.elementary.print.vala, do not modify */

/**/
/*  Copyright (C) 2012 Andrea Basso*/
/*  Copyright (C) 2014 Ezequiel Lewin*/
/**/
/*  This program uses code originally written by Tarot Osuji for Leafpad http://tarot.freeshell.org/leafpad/*/
/**/
/*  This program is free software: you can redistribute it and/or modify*/
/*  it under the terms of the GNU General Public License as published by*/
/*  the Free Software Foundation, either version 3 of the License, or*/
/*  (at your option) any later version.*/
/**/
/*  This program is distributed in the hope that it will be useful,*/
/*  but WITHOUT ANY WARRANTY; without even the implied warranty of*/
/*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the*/
/*  GNU General Public License for more details.*/
/**/
/*  You should have received a copy of the GNU General Public License*/
/*  along with this program.  If not, see <http://www.gnu.org/licenses/>.*/
/**/

#include <gtk/gtk.h>
#include <glib-object.h>
#include <stdlib.h>
#include <string.h>
#include <glib.h>
#include <cairo-gobject.h>
#include <pango/pango.h>
#include <gio/gio.h>
#include <float.h>
#include <math.h>
#include <pango/pangocairo.h>

#define CUSTOM_OPERATION_FONT_SIZE 12
#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_CUSTOM_OPERATION (custom_operation_get_type ())
#define CUSTOM_OPERATION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_CUSTOM_OPERATION, CustomOperation))
#define CUSTOM_OPERATION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_CUSTOM_OPERATION, CustomOperationClass))
#define IS_CUSTOM_OPERATION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_CUSTOM_OPERATION))
#define IS_CUSTOM_OPERATION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_CUSTOM_OPERATION))
#define CUSTOM_OPERATION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_CUSTOM_OPERATION, CustomOperationClass))

typedef struct _CustomOperation CustomOperation;
typedef struct _CustomOperationClass CustomOperationClass;
typedef struct _CustomOperationPrivate CustomOperationPrivate;
enum  {
	CUSTOM_OPERATION_0_PROPERTY,
	CUSTOM_OPERATION_NUM_PROPERTIES
};
static GParamSpec* custom_operation_properties[CUSTOM_OPERATION_NUM_PROPERTIES];
#define _g_free0(var) (var = (g_free (var), NULL))
#define _cairo_destroy0(var) ((var == NULL) ? NULL : (var = (cairo_destroy (var), NULL)))
#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))
#define __vala_PangoFontDescription_free0(var) ((var == NULL) ? NULL : (var = (_vala_PangoFontDescription_free (var), NULL)))
#define _g_error_free0(var) ((var == NULL) ? NULL : (var = (g_error_free (var), NULL)))
#define _pango_layout_line_unref0(var) ((var == NULL) ? NULL : (var = (pango_layout_line_unref (var), NULL)))

struct _CustomOperation {
	GtkPrintOperation parent_instance;
	CustomOperationPrivate * priv;
};

struct _CustomOperationClass {
	GtkPrintOperationClass parent_class;
};

struct _CustomOperationPrivate {
	gchar* content;
	gint* page_breaks;
	gint page_breaks_length1;
	gint _page_breaks_size_;
	cairo_t* context;
	PangoLayout* layout;
	PangoFontDescription* desc;
	gint height;
	gint width;
	gint line_count;
};

static gint CustomOperation_private_offset;
static gpointer custom_operation_parent_class = NULL;

VALA_EXTERN GType custom_operation_get_type (void) G_GNUC_CONST ;
G_DEFINE_AUTOPTR_CLEANUP_FUNC (CustomOperation, g_object_unref)
static void _vala_PangoFontDescription_free (PangoFontDescription* self);
VALA_EXTERN CustomOperation* custom_operation_new (gchar** args,
                                       gint args_length1,
                                       GtkWindow* main_window);
VALA_EXTERN CustomOperation* custom_operation_construct (GType object_type,
                                             gchar** args,
                                             gint args_length1,
                                             GtkWindow* main_window);
static void custom_operation_beginprint (CustomOperation* self,
                                  GtkPrintContext* print_context);
static void _custom_operation_beginprint_gtk_print_operation_begin_print (GtkPrintOperation* _sender,
                                                                   GtkPrintContext* context,
                                                                   gpointer self);
static void custom_operation_drawpage (CustomOperation* self,
                                GtkPrintContext* print_context,
                                gint page_num);
static void _custom_operation_drawpage_gtk_print_operation_draw_page (GtkPrintOperation* _sender,
                                                               GtkPrintContext* context,
                                                               gint page_nr,
                                                               gpointer self);
static void _vala_array_add1 (gint* * array,
                       gint* length,
                       gint* size,
                       gint value);
static void custom_operation_finalize (GObject * obj);
static GType custom_operation_get_type_once (void);
static void _vala_main (gchar** args,
                 gint args_length1);

static inline gpointer
custom_operation_get_instance_private (CustomOperation* self)
{
	return G_STRUCT_MEMBER_P (self, CustomOperation_private_offset);
}

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

static void
_custom_operation_beginprint_gtk_print_operation_begin_print (GtkPrintOperation* _sender,
                                                              GtkPrintContext* context,
                                                              gpointer self)
{
	custom_operation_beginprint ((CustomOperation*) self, context);
}

static void
_custom_operation_drawpage_gtk_print_operation_draw_page (GtkPrintOperation* _sender,
                                                          GtkPrintContext* context,
                                                          gint page_nr,
                                                          gpointer self)
{
	custom_operation_drawpage ((CustomOperation*) self, context, page_nr);
}

CustomOperation*
custom_operation_construct (GType object_type,
                            gchar** args,
                            gint args_length1,
                            GtkWindow* main_window)
{
	CustomOperation * self = NULL;
	GFile* file = NULL;
	const gchar* _tmp0_;
	GFile* _tmp1_;
	GFile* _tmp2_;
	GtkPageSetup* setup = NULL;
	GtkPageSetup* _tmp19_;
	GError* _inner_error0_ = NULL;
	g_return_val_if_fail (main_window != NULL, NULL);
	self = (CustomOperation*) g_object_new (object_type, NULL);
	_tmp0_ = args[1];
	_tmp1_ = g_file_new_for_commandline_arg (_tmp0_);
	file = _tmp1_;
	_tmp2_ = file;
	if (g_file_query_exists (_tmp2_, NULL)) {
		{
			GFileInputStream* _tmp3_ = NULL;
			GFile* _tmp4_;
			GFileInputStream* _tmp5_;
			GDataInputStream* dis = NULL;
			GDataInputStream* _tmp6_;
			gchar* line = NULL;
			_tmp4_ = file;
			_tmp5_ = g_file_read (_tmp4_, NULL, &_inner_error0_);
			_tmp3_ = _tmp5_;
			if (G_UNLIKELY (_inner_error0_ != NULL)) {
				goto __catch0_g_error;
			}
			_tmp6_ = g_data_input_stream_new ((GInputStream*) _tmp3_);
			dis = _tmp6_;
			while (TRUE) {
				gchar* _tmp7_ = NULL;
				GDataInputStream* _tmp8_;
				gchar* _tmp9_;
				gchar* _tmp10_;
				const gchar* _tmp11_;
				const gchar* _tmp12_;
				_tmp8_ = dis;
				_tmp9_ = g_data_input_stream_read_line (_tmp8_, NULL, NULL, &_inner_error0_);
				_tmp7_ = _tmp9_;
				if (G_UNLIKELY (_inner_error0_ != NULL)) {
					_g_free0 (line);
					_g_object_unref0 (dis);
					_g_object_unref0 (_tmp3_);
					goto __catch0_g_error;
				}
				_tmp10_ = _tmp7_;
				_tmp7_ = NULL;
				_g_free0 (line);
				line = _tmp10_;
				_tmp11_ = line;
				if (!(_tmp11_ != NULL)) {
					_g_free0 (_tmp7_);
					break;
				}
				_tmp12_ = line;
				if (g_utf8_validate (_tmp12_, (gssize) -1, NULL)) {
					const gchar* _tmp13_;
					const gchar* _tmp14_;
					gchar* _tmp15_;
					gchar* _tmp16_;
					gchar* _tmp17_;
					_tmp13_ = self->priv->content;
					_tmp14_ = line;
					_tmp15_ = g_strconcat (_tmp14_, "\n", NULL);
					_tmp16_ = _tmp15_;
					_tmp17_ = g_strconcat (_tmp13_, _tmp16_, NULL);
					_g_free0 (self->priv->content);
					self->priv->content = _tmp17_;
					_g_free0 (_tmp16_);
				}
				_g_free0 (_tmp7_);
			}
			_g_free0 (line);
			_g_object_unref0 (dis);
			_g_object_unref0 (_tmp3_);
		}
		goto __finally0;
		__catch0_g_error:
		{
			GError* e = NULL;
			const gchar* _tmp18_;
			e = _inner_error0_;
			_inner_error0_ = NULL;
			_tmp18_ = e->message;
			g_error ("io.elementary.print.vala:44: %s", _tmp18_);
			_g_error_free0 (e);
		}
		__finally0:
		if (G_UNLIKELY (_inner_error0_ != NULL)) {
			_g_object_unref0 (file);
			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;
		}
	}
	_tmp19_ = gtk_page_setup_new ();
	setup = _tmp19_;
	gtk_page_setup_set_top_margin (setup, (gdouble) 15, GTK_UNIT_MM);
	gtk_page_setup_set_bottom_margin (setup, (gdouble) 15, GTK_UNIT_MM);
	gtk_page_setup_set_right_margin (setup, (gdouble) 20, GTK_UNIT_MM);
	gtk_page_setup_set_left_margin (setup, (gdouble) 20, GTK_UNIT_MM);
	gtk_print_operation_set_default_page_setup ((GtkPrintOperation*) self, setup);
	g_signal_connect_object ((GtkPrintOperation*) self, "begin-print", (GCallback) _custom_operation_beginprint_gtk_print_operation_begin_print, self, 0);
	g_signal_connect_object ((GtkPrintOperation*) self, "draw-page", (GCallback) _custom_operation_drawpage_gtk_print_operation_draw_page, self, 0);
	_g_object_unref0 (setup);
	_g_object_unref0 (file);
	return self;
}

CustomOperation*
custom_operation_new (gchar** args,
                      gint args_length1,
                      GtkWindow* main_window)
{
	return custom_operation_construct (TYPE_CUSTOM_OPERATION, args, args_length1, main_window);
}

static gpointer
_pango_layout_line_ref0 (gpointer self)
{
	return self ? pango_layout_line_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
custom_operation_beginprint (CustomOperation* self,
                             GtkPrintContext* print_context)
{
	PangoLayout* _tmp0_;
	PangoLayout* _tmp1_;
	PangoFontDescription* _tmp2_;
	PangoFontDescription* _tmp3_;
	PangoFontDescription* _tmp4_;
	PangoLayout* _tmp5_;
	PangoFontDescription* _tmp6_;
	PangoLayout* _tmp7_;
	PangoLayout* _tmp8_;
	const gchar* _tmp9_;
	PangoLayout* _tmp10_;
	PangoLayoutLine* layout_line = NULL;
	gdouble page_height = 0.0;
	gint* _tmp20_;
	gint _tmp20__length1;
	g_return_if_fail (self != NULL);
	g_return_if_fail (print_context != NULL);
	_tmp0_ = gtk_print_context_create_pango_layout (print_context);
	_g_object_unref0 (self->priv->layout);
	self->priv->layout = _tmp0_;
	_tmp1_ = self->priv->layout;
	pango_layout_set_wrap (_tmp1_, PANGO_WRAP_WORD_CHAR);
	_tmp2_ = pango_font_description_new ();
	__vala_PangoFontDescription_free0 (self->priv->desc);
	self->priv->desc = _tmp2_;
	_tmp3_ = self->priv->desc;
	pango_font_description_set_family (_tmp3_, "Open Sans");
	_tmp4_ = self->priv->desc;
	pango_font_description_set_absolute_size (_tmp4_, (gdouble) (CUSTOM_OPERATION_FONT_SIZE * PANGO_SCALE));
	_tmp5_ = self->priv->layout;
	_tmp6_ = self->priv->desc;
	pango_layout_set_font_description (_tmp5_, _tmp6_);
	self->priv->width = (gint) gtk_print_context_get_width (print_context);
	_tmp7_ = self->priv->layout;
	pango_layout_set_width (_tmp7_, PANGO_SCALE * self->priv->width);
	self->priv->height = (gint) gtk_print_context_get_height (print_context);
	_tmp8_ = self->priv->layout;
	_tmp9_ = self->priv->content;
	pango_layout_set_text (_tmp8_, _tmp9_, -1);
	_tmp10_ = self->priv->layout;
	self->priv->line_count = pango_layout_get_line_count (_tmp10_);
	page_height = (gdouble) 0;
	{
		gint line = 0;
		line = 0;
		{
			gboolean _tmp11_ = FALSE;
			_tmp11_ = TRUE;
			while (TRUE) {
				PangoRectangle ink_rect = {0};
				PangoRectangle logical_rect = {0};
				PangoLayout* _tmp13_;
				PangoLayoutLine* _tmp14_;
				PangoLayoutLine* _tmp15_;
				PangoLayoutLine* _tmp16_;
				PangoRectangle _tmp17_ = {0};
				PangoRectangle _tmp18_ = {0};
				gdouble line_height = 0.0;
				PangoRectangle _tmp19_;
				if (!_tmp11_) {
					gint _tmp12_;
					line = line + 1;
					_tmp12_ = line;
				}
				_tmp11_ = FALSE;
				if (!(line < self->priv->line_count)) {
					break;
				}
				_tmp13_ = self->priv->layout;
				_tmp14_ = pango_layout_get_line (_tmp13_, line);
				_tmp15_ = _pango_layout_line_ref0 (_tmp14_);
				_pango_layout_line_unref0 (layout_line);
				layout_line = _tmp15_;
				_tmp16_ = layout_line;
				pango_layout_line_get_extents (_tmp16_, &_tmp17_, &_tmp18_);
				ink_rect = _tmp17_;
				logical_rect = _tmp18_;
				_tmp19_ = logical_rect;
				line_height = (gdouble) (_tmp19_.height / PANGO_SCALE);
				if ((page_height + line_height) > ((gdouble) self->priv->height)) {
					_vala_array_add1 (&self->priv->page_breaks, &self->priv->page_breaks_length1, &self->priv->_page_breaks_size_, line);
					page_height = (gdouble) 0;
				}
				page_height += line_height;
			}
		}
	}
	_tmp20_ = self->priv->page_breaks;
	_tmp20__length1 = self->priv->page_breaks_length1;
	gtk_print_operation_set_n_pages ((GtkPrintOperation*) self, _tmp20__length1 + 1);
	_pango_layout_line_unref0 (layout_line);
}

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

static void
custom_operation_drawpage (CustomOperation* self,
                           GtkPrintContext* print_context,
                           gint page_num)
{
	cairo_t* _tmp0_;
	cairo_t* _tmp1_;
	cairo_t* _tmp2_;
	gint layout_width = 0;
	gint layout_height = 0;
	PangoLayout* _tmp3_;
	gint _tmp4_ = 0;
	gint _tmp5_ = 0;
	cairo_t* _tmp6_;
	cairo_t* _tmp7_;
	PangoLayout* _tmp8_;
	gint line_num = 0;
	gint line_per_page = 0;
	gint j = 0;
	g_return_if_fail (self != NULL);
	g_return_if_fail (print_context != NULL);
	_tmp0_ = gtk_print_context_get_cairo_context (print_context);
	_tmp1_ = _cairo_reference0 (_tmp0_);
	_cairo_destroy0 (self->priv->context);
	self->priv->context = _tmp1_;
	_tmp2_ = self->priv->context;
	cairo_set_source_rgb (_tmp2_, (gdouble) 0, (gdouble) 0, (gdouble) 0);
	_tmp3_ = self->priv->layout;
	pango_layout_get_size (_tmp3_, &_tmp4_, &_tmp5_);
	layout_width = _tmp4_;
	layout_height = _tmp5_;
	_tmp6_ = self->priv->context;
	cairo_move_to (_tmp6_, (gdouble) (layout_width / 2), (gdouble) ((self->priv->height - (layout_height / PANGO_SCALE)) / 2));
	_tmp7_ = self->priv->context;
	_tmp8_ = self->priv->layout;
	pango_cairo_show_layout (_tmp7_, _tmp8_);
	line_num = 0;
	line_per_page = self->priv->height / CUSTOM_OPERATION_FONT_SIZE;
	if (self->priv->line_count > (line_per_page * (page_num + 1))) {
		line_num = line_per_page * (page_num + 1);
	} else {
		line_num = self->priv->line_count;
	}
	j = 0;
	{
		gint i = 0;
		i = line_per_page * page_num;
		{
			gboolean _tmp9_ = FALSE;
			_tmp9_ = TRUE;
			while (TRUE) {
				PangoLayoutLine* line = NULL;
				PangoLayout* _tmp11_;
				PangoLayoutLine* _tmp12_;
				PangoLayoutLine* _tmp13_;
				cairo_t* _tmp14_;
				cairo_t* _tmp15_;
				PangoLayoutLine* _tmp16_;
				gint _tmp17_;
				if (!_tmp9_) {
					gint _tmp10_;
					_tmp10_ = i;
					i = _tmp10_ + 1;
				}
				_tmp9_ = FALSE;
				if (!(i < line_num)) {
					break;
				}
				_tmp11_ = self->priv->layout;
				_tmp12_ = pango_layout_get_line (_tmp11_, i);
				_tmp13_ = _pango_layout_line_ref0 (_tmp12_);
				line = _tmp13_;
				_tmp14_ = self->priv->context;
				cairo_move_to (_tmp14_, (gdouble) 0, (gdouble) (CUSTOM_OPERATION_FONT_SIZE * (j + 1)));
				_tmp15_ = self->priv->context;
				_tmp16_ = line;
				pango_cairo_show_layout_line (_tmp15_, _tmp16_);
				_tmp17_ = j;
				j = _tmp17_ + 1;
				_pango_layout_line_unref0 (line);
			}
		}
	}
}

static void
custom_operation_class_init (CustomOperationClass * klass,
                             gpointer klass_data)
{
	custom_operation_parent_class = g_type_class_peek_parent (klass);
	g_type_class_adjust_private_offset (klass, &CustomOperation_private_offset);
	G_OBJECT_CLASS (klass)->finalize = custom_operation_finalize;
}

static void
custom_operation_instance_init (CustomOperation * self,
                                gpointer klass)
{
	gchar* _tmp0_;
	self->priv = custom_operation_get_instance_private (self);
	_tmp0_ = g_strdup ("");
	self->priv->content = _tmp0_;
	self->priv->context = NULL;
	self->priv->layout = NULL;
}

static void
custom_operation_finalize (GObject * obj)
{
	CustomOperation * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, TYPE_CUSTOM_OPERATION, CustomOperation);
	_g_free0 (self->priv->content);
	self->priv->page_breaks = (g_free (self->priv->page_breaks), NULL);
	_cairo_destroy0 (self->priv->context);
	_g_object_unref0 (self->priv->layout);
	__vala_PangoFontDescription_free0 (self->priv->desc);
	G_OBJECT_CLASS (custom_operation_parent_class)->finalize (obj);
}

static GType
custom_operation_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (CustomOperationClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) custom_operation_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (CustomOperation), 0, (GInstanceInitFunc) custom_operation_instance_init, NULL };
	GType custom_operation_type_id;
	custom_operation_type_id = g_type_register_static (gtk_print_operation_get_type (), "CustomOperation", &g_define_type_info, 0);
	CustomOperation_private_offset = g_type_add_instance_private (custom_operation_type_id, sizeof (CustomOperationPrivate));
	return custom_operation_type_id;
}

GType
custom_operation_get_type (void)
{
	static volatile gsize custom_operation_type_id__once = 0;
	if (g_once_init_enter (&custom_operation_type_id__once)) {
		GType custom_operation_type_id;
		custom_operation_type_id = custom_operation_get_type_once ();
		g_once_init_leave (&custom_operation_type_id__once, custom_operation_type_id);
	}
	return custom_operation_type_id__once;
}

static void
_vala_main (gchar** args,
            gint args_length1)
{
	GtkWindow* main_window = NULL;
	GtkWindow* _tmp0_;
	CustomOperation* operation = NULL;
	CustomOperation* _tmp1_;
	GError* _inner_error0_ = NULL;
	gtk_init ((gint*) (&args_length1), &args);
	_tmp0_ = (GtkWindow*) gtk_window_new (GTK_WINDOW_TOPLEVEL);
	g_object_ref_sink (_tmp0_);
	main_window = _tmp0_;
	_tmp1_ = custom_operation_new (args, args_length1, main_window);
	operation = _tmp1_;
	gtk_print_operation_run ((GtkPrintOperation*) operation, GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG, main_window, &_inner_error0_);
	if (G_UNLIKELY (_inner_error0_ != NULL)) {
		_g_object_unref0 (operation);
		_g_object_unref0 (main_window);
		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 (operation);
	_g_object_unref0 (main_window);
}

int
main (int argc,
      char ** argv)
{
	_vala_main (argv, argc);
	return 0;
}

