/* book-view.c generated by valac 0.13.1, the Vala compiler
 * generated from book-view.vala, do not modify */

/*
 * Copyright (C) 2009-2011 Canonical Ltd.
 * Author: Robert Ancell <robert.ancell@canonical.com>
 *
 * This program is free software: you can redistribute it and/or modify it under
 * the terms of the GNU General Public License as published by the Free Software
 * Foundation, either version 3 of the License, or (at your option) any later
 * version. See http://www.gnu.org/copyleft/gpl.html the full text of the
 * license.
 */
/* FIXME: When scrolling, copy existing render sideways?*/
/* FIXME: Only render pages that change and only the part that changed*/

#include <glib.h>
#include <glib-object.h>
#include <gtk/gtk.h>
#include <gdk/gdk.h>
#include <cairo.h>
#include <float.h>
#include <math.h>


#define TYPE_BOOK_VIEW (book_view_get_type ())
#define BOOK_VIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_BOOK_VIEW, BookView))
#define BOOK_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_BOOK_VIEW, BookViewClass))
#define IS_BOOK_VIEW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_BOOK_VIEW))
#define IS_BOOK_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_BOOK_VIEW))
#define BOOK_VIEW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_BOOK_VIEW, BookViewClass))

typedef struct _BookView BookView;
typedef struct _BookViewClass BookViewClass;
typedef struct _BookViewPrivate BookViewPrivate;

#define TYPE_BOOK (book_get_type ())
#define BOOK(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_BOOK, Book))
#define BOOK_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_BOOK, BookClass))
#define IS_BOOK(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_BOOK))
#define IS_BOOK_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_BOOK))
#define BOOK_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_BOOK, BookClass))

typedef struct _Book Book;
typedef struct _BookClass BookClass;

#define TYPE_PAGE (page_get_type ())
#define PAGE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_PAGE, Page))
#define PAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_PAGE, PageClass))
#define IS_PAGE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_PAGE))
#define IS_PAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_PAGE))
#define PAGE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_PAGE, PageClass))

typedef struct _Page Page;
typedef struct _PageClass PageClass;

#define TYPE_PAGE_VIEW (page_view_get_type ())
#define PAGE_VIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_PAGE_VIEW, PageView))
#define PAGE_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_PAGE_VIEW, PageViewClass))
#define IS_PAGE_VIEW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_PAGE_VIEW))
#define IS_PAGE_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_PAGE_VIEW))
#define PAGE_VIEW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_PAGE_VIEW, PageViewClass))

typedef struct _PageView PageView;
typedef struct _PageViewClass PageViewClass;
#define _book_unref0(var) ((var == NULL) ? NULL : (var = (book_unref (var), NULL)))
#define _g_hash_table_unref0(var) ((var == NULL) ? NULL : (var = (g_hash_table_unref (var), NULL)))
#define _page_view_unref0(var) ((var == NULL) ? NULL : (var = (page_view_unref (var), NULL)))
#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))
#define _page_unref0(var) ((var == NULL) ? NULL : (var = (page_unref (var), NULL)))

struct _BookView {
	GtkVBox parent_instance;
	BookViewPrivate * priv;
};

struct _BookViewClass {
	GtkVBoxClass parent_class;
};

struct _BookViewPrivate {
	Book* book;
	GHashTable* page_data;
	gboolean need_layout;
	gboolean laying_out;
	gboolean show_selected_page;
	PageView* selected_page;
	GtkWidget* drawing_area;
	GtkHScrollbar* scroll;
	GtkAdjustment* adjustment;
	GdkCursorType cursor;
};


static gpointer book_view_parent_class = NULL;

GType book_view_get_type (void) G_GNUC_CONST;
gpointer book_ref (gpointer instance);
void book_unref (gpointer instance);
GParamSpec* param_spec_book (const gchar* name, const gchar* nick, const gchar* blurb, GType object_type, GParamFlags flags);
void value_set_book (GValue* value, gpointer v_object);
void value_take_book (GValue* value, gpointer v_object);
gpointer value_get_book (const GValue* value);
GType book_get_type (void) G_GNUC_CONST;
gpointer page_ref (gpointer instance);
void page_unref (gpointer instance);
GParamSpec* param_spec_page (const gchar* name, const gchar* nick, const gchar* blurb, GType object_type, GParamFlags flags);
void value_set_page (GValue* value, gpointer v_object);
void value_take_page (GValue* value, gpointer v_object);
gpointer value_get_page (const GValue* value);
GType page_get_type (void) G_GNUC_CONST;
gpointer page_view_ref (gpointer instance);
void page_view_unref (gpointer instance);
GParamSpec* param_spec_page_view (const gchar* name, const gchar* nick, const gchar* blurb, GType object_type, GParamFlags flags);
void value_set_page_view (GValue* value, gpointer v_object);
void value_take_page_view (GValue* value, gpointer v_object);
gpointer value_get_page_view (const GValue* value);
GType page_view_get_type (void) G_GNUC_CONST;
#define BOOK_VIEW_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), TYPE_BOOK_VIEW, BookViewPrivate))
enum  {
	BOOK_VIEW_DUMMY_PROPERTY
};
BookView* book_view_new (Book* book);
BookView* book_view_construct (GType object_type, Book* book);
guint book_get_n_pages (Book* self);
Page* book_get_page (Book* self, gint page_number);
static void book_view_add_cb (BookView* self, Book* book, Page* page);
void book_view_select_page (BookView* self, Page* page);
static void _book_view_add_cb_book_page_added (Book* _sender, Page* page, gpointer self);
static void book_view_remove_cb (BookView* self, Book* book, Page* page);
static void _book_view_remove_cb_book_page_removed (Book* _sender, Page* page, gpointer self);
static void book_view_reorder_cb (BookView* self, Book* book);
static void _book_view_reorder_cb_book_reordered (Book* _sender, gpointer self);
static void book_view_clear_cb (BookView* self, Book* book);
static void _book_view_clear_cb_book_cleared (Book* _sender, gpointer self);
static void _page_unref0_ (gpointer var);
static void _page_view_unref0_ (gpointer var);
static gboolean book_view_configure_cb (BookView* self, GtkWidget* widget, GdkEventConfigure* event);
static gboolean _book_view_configure_cb_gtk_widget_configure_event (GtkWidget* _sender, GdkEventConfigure* event, gpointer self);
static gboolean book_view_draw_cb (BookView* self, GtkWidget* widget, cairo_t* context);
static gboolean _book_view_draw_cb_gtk_widget_draw (GtkWidget* _sender, cairo_t* cr, gpointer self);
static gboolean book_view_motion_cb (BookView* self, GtkWidget* widget, GdkEventMotion* event);
static gboolean _book_view_motion_cb_gtk_widget_motion_notify_event (GtkWidget* _sender, GdkEventMotion* event, gpointer self);
static gboolean book_view_key_cb (BookView* self, GtkWidget* widget, GdkEventKey* event);
static gboolean _book_view_key_cb_gtk_widget_key_press_event (GtkWidget* _sender, GdkEventKey* event, gpointer self);
static gboolean book_view_button_cb (BookView* self, GtkWidget* widget, GdkEventButton* event);
static gboolean _book_view_button_cb_gtk_widget_button_press_event (GtkWidget* _sender, GdkEventButton* event, gpointer self);
static gboolean _book_view_button_cb_gtk_widget_button_release_event (GtkWidget* _sender, GdkEventButton* event, gpointer self);
static gboolean book_view_focus_cb (BookView* self, GtkWidget* widget, GdkEventFocus* event);
static gboolean _book_view_focus_cb_gtk_widget_focus_in_event (GtkWidget* _sender, GdkEventFocus* event, gpointer self);
static gboolean _book_view_focus_cb_gtk_widget_focus_out_event (GtkWidget* _sender, GdkEventFocus* event, gpointer self);
static void book_view_scroll_cb (BookView* self, GtkAdjustment* adjustment);
static void _book_view_scroll_cb_gtk_adjustment_value_changed (GtkAdjustment* _sender, gpointer self);
static PageView* book_view_get_nth_page (BookView* self, gint n);
static PageView* book_view_get_next_page (BookView* self, PageView* page);
Page* page_view_get_page (PageView* self);
static PageView* book_view_get_prev_page (BookView* self, PageView* page);
static void book_view_page_view_changed_cb (BookView* self, PageView* page);
void book_view_redraw (BookView* self);
static void book_view_page_view_size_changed_cb (BookView* self, PageView* page);
PageView* page_view_new (Page* page);
PageView* page_view_construct (GType object_type, Page* page);
static void _book_view_page_view_changed_cb_page_view_changed (PageView* _sender, gpointer self);
static void _book_view_page_view_size_changed_cb_page_view_size_changed (PageView* _sender, gpointer self);
static void book_view_set_selected_page (BookView* self, PageView* page);
void page_view_set_selected (PageView* self, gboolean selected);
static void book_view_set_x_offset (BookView* self, gint offset);
static gint book_view_get_x_offset (BookView* self);
static void book_view_show_page_view (BookView* self, PageView* page);
gint page_view_get_x_offset (PageView* self);
gint page_view_get_width (PageView* self);
static void book_view_select_page_view (BookView* self, PageView* page);
Page* book_view_get_selected (BookView* self);
Book* book_view_get_book (BookView* self);
static void book_view_layout_into (BookView* self, gint width, gint height, gint* book_width, gint* book_height);
gint page_get_dpi (Page* self);
gint page_get_width (Page* self);
gint page_get_height (Page* self);
void page_view_set_width (PageView* self, gint width);
void page_view_set_height (PageView* self, gint height);
gint page_view_get_height (PageView* self);
void page_view_set_x_offset (PageView* self, gint offset);
void page_view_set_y_offset (PageView* self, gint offset);
static void book_view_layout (BookView* self);
void page_view_render (PageView* self, cairo_t* context);
gboolean page_view_get_selected (PageView* self);
gint page_view_get_y_offset (PageView* self);
static PageView* book_view_get_page_at (BookView* self, gint x, gint y, gint* x_, gint* y_);
void page_view_button_press (PageView* self, gint x, gint y);
void page_view_button_release (PageView* self, gint x, gint y);
static void book_view_set_cursor (BookView* self, GdkCursorType cursor);
void page_view_motion (PageView* self, gint x, gint y);
GdkCursorType page_view_get_cursor (PageView* self);
void book_view_select_next_page (BookView* self);
void book_view_select_prev_page (BookView* self);
static void g_cclosure_user_marshal_VOID__PAGE (GClosure * closure, GValue * return_value, guint n_param_values, const GValue * param_values, gpointer invocation_hint, gpointer marshal_data);
static void book_view_finalize (GObject* obj);


static gpointer _book_ref0 (gpointer self) {
	return self ? book_ref (self) : NULL;
}


static void _book_view_add_cb_book_page_added (Book* _sender, Page* page, gpointer self) {
	book_view_add_cb (self, _sender, page);
}


static void _book_view_remove_cb_book_page_removed (Book* _sender, Page* page, gpointer self) {
	book_view_remove_cb (self, _sender, page);
}


static void _book_view_reorder_cb_book_reordered (Book* _sender, gpointer self) {
	book_view_reorder_cb (self, _sender);
}


static void _book_view_clear_cb_book_cleared (Book* _sender, gpointer self) {
	book_view_clear_cb (self, _sender);
}


static void _page_unref0_ (gpointer var) {
	(var == NULL) ? NULL : (var = (page_unref (var), NULL));
}


static void _page_view_unref0_ (gpointer var) {
	(var == NULL) ? NULL : (var = (page_view_unref (var), NULL));
}


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


static gboolean _book_view_configure_cb_gtk_widget_configure_event (GtkWidget* _sender, GdkEventConfigure* event, gpointer self) {
	gboolean result;
	result = book_view_configure_cb (self, _sender, event);
	return result;
}


static gboolean _book_view_draw_cb_gtk_widget_draw (GtkWidget* _sender, cairo_t* cr, gpointer self) {
	gboolean result;
	result = book_view_draw_cb (self, _sender, cr);
	return result;
}


static gboolean _book_view_motion_cb_gtk_widget_motion_notify_event (GtkWidget* _sender, GdkEventMotion* event, gpointer self) {
	gboolean result;
	result = book_view_motion_cb (self, _sender, event);
	return result;
}


static gboolean _book_view_key_cb_gtk_widget_key_press_event (GtkWidget* _sender, GdkEventKey* event, gpointer self) {
	gboolean result;
	result = book_view_key_cb (self, _sender, event);
	return result;
}


static gboolean _book_view_button_cb_gtk_widget_button_press_event (GtkWidget* _sender, GdkEventButton* event, gpointer self) {
	gboolean result;
	result = book_view_button_cb (self, _sender, event);
	return result;
}


static gboolean _book_view_button_cb_gtk_widget_button_release_event (GtkWidget* _sender, GdkEventButton* event, gpointer self) {
	gboolean result;
	result = book_view_button_cb (self, _sender, event);
	return result;
}


static gboolean _book_view_focus_cb_gtk_widget_focus_in_event (GtkWidget* _sender, GdkEventFocus* event, gpointer self) {
	gboolean result;
	result = book_view_focus_cb (self, _sender, event);
	return result;
}


static gboolean _book_view_focus_cb_gtk_widget_focus_out_event (GtkWidget* _sender, GdkEventFocus* event, gpointer self) {
	gboolean result;
	result = book_view_focus_cb (self, _sender, event);
	return result;
}


static void _book_view_scroll_cb_gtk_adjustment_value_changed (GtkAdjustment* _sender, gpointer self) {
	book_view_scroll_cb (self, _sender);
}


BookView* book_view_construct (GType object_type, Book* book) {
	BookView * self = NULL;
	Book* _tmp0_;
	Page* _tmp4_ = NULL;
	Page* _tmp5_;
	GHashTable* _tmp6_ = NULL;
	GtkDrawingArea* _tmp7_ = NULL;
	GtkHScrollbar* _tmp8_ = NULL;
	GtkAdjustment* _tmp9_ = NULL;
	GtkAdjustment* _tmp10_;
	g_return_val_if_fail (book != NULL, NULL);
	self = (BookView*) g_object_new (object_type, NULL);
	_tmp0_ = _book_ref0 (book);
	_book_unref0 (self->priv->book);
	self->priv->book = _tmp0_;
	{
		gint i;
		i = 0;
		{
			gboolean _tmp1_;
			_tmp1_ = TRUE;
			while (TRUE) {
				guint _tmp2_;
				Page* _tmp3_ = NULL;
				Page* page;
				if (!_tmp1_) {
					i++;
				}
				_tmp1_ = FALSE;
				_tmp2_ = book_get_n_pages (book);
				if (!(((guint) i) < _tmp2_)) {
					break;
				}
				_tmp3_ = book_get_page (book, i);
				page = _tmp3_;
				book_view_add_cb (self, book, page);
				_page_unref0 (page);
			}
		}
	}
	_tmp4_ = book_get_page (book, 0);
	_tmp5_ = _tmp4_;
	book_view_select_page (self, _tmp5_);
	_page_unref0 (_tmp5_);
	g_signal_connect_object (book, "page-added", (GCallback) _book_view_add_cb_book_page_added, self, 0);
	g_signal_connect_object (book, "page-removed", (GCallback) _book_view_remove_cb_book_page_removed, self, 0);
	g_signal_connect_object (book, "reordered", (GCallback) _book_view_reorder_cb_book_reordered, self, 0);
	g_signal_connect_object (book, "cleared", (GCallback) _book_view_clear_cb_book_cleared, self, 0);
	self->priv->need_layout = TRUE;
	_tmp6_ = g_hash_table_new_full (g_direct_hash, g_direct_equal, _page_unref0_, _page_view_unref0_);
	_g_hash_table_unref0 (self->priv->page_data);
	self->priv->page_data = _tmp6_;
	self->priv->cursor = GDK_ARROW;
	_tmp7_ = (GtkDrawingArea*) gtk_drawing_area_new ();
	_g_object_unref0 (self->priv->drawing_area);
	self->priv->drawing_area = (GtkWidget*) g_object_ref_sink (_tmp7_);
	gtk_widget_set_size_request (self->priv->drawing_area, 200, 100);
	gtk_widget_set_can_focus (self->priv->drawing_area, TRUE);
	gtk_widget_set_events (self->priv->drawing_area, (gint) (((((GDK_POINTER_MOTION_MASK | GDK_BUTTON_PRESS_MASK) | GDK_BUTTON_RELEASE_MASK) | GDK_FOCUS_CHANGE_MASK) | GDK_STRUCTURE_MASK) | GDK_SCROLL_MASK));
	gtk_box_pack_start ((GtkBox*) self, self->priv->drawing_area, TRUE, TRUE, (guint) 0);
	_tmp8_ = (GtkHScrollbar*) gtk_hscrollbar_new (NULL);
	_g_object_unref0 (self->priv->scroll);
	self->priv->scroll = g_object_ref_sink (_tmp8_);
	_tmp9_ = gtk_range_get_adjustment ((GtkRange*) self->priv->scroll);
	_tmp10_ = _g_object_ref0 (_tmp9_);
	_g_object_unref0 (self->priv->adjustment);
	self->priv->adjustment = _tmp10_;
	gtk_box_pack_start ((GtkBox*) self, (GtkWidget*) self->priv->scroll, FALSE, TRUE, (guint) 0);
	g_signal_connect_object (self->priv->drawing_area, "configure-event", (GCallback) _book_view_configure_cb_gtk_widget_configure_event, self, 0);
	g_signal_connect_object (self->priv->drawing_area, "draw", (GCallback) _book_view_draw_cb_gtk_widget_draw, self, 0);
	g_signal_connect_object (self->priv->drawing_area, "motion-notify-event", (GCallback) _book_view_motion_cb_gtk_widget_motion_notify_event, self, 0);
	g_signal_connect_object (self->priv->drawing_area, "key-press-event", (GCallback) _book_view_key_cb_gtk_widget_key_press_event, self, 0);
	g_signal_connect_object (self->priv->drawing_area, "button-press-event", (GCallback) _book_view_button_cb_gtk_widget_button_press_event, self, 0);
	g_signal_connect_object (self->priv->drawing_area, "button-release-event", (GCallback) _book_view_button_cb_gtk_widget_button_release_event, self, 0);
	g_signal_connect_object (self->priv->drawing_area, "focus-in-event", (GCallback) _book_view_focus_cb_gtk_widget_focus_in_event, self, G_CONNECT_AFTER);
	g_signal_connect_object (self->priv->drawing_area, "focus-out-event", (GCallback) _book_view_focus_cb_gtk_widget_focus_out_event, self, G_CONNECT_AFTER);
	g_signal_connect_object (self->priv->adjustment, "value-changed", (GCallback) _book_view_scroll_cb_gtk_adjustment_value_changed, self, 0);
	gtk_widget_show (self->priv->drawing_area);
	return self;
}


BookView* book_view_new (Book* book) {
	return book_view_construct (TYPE_BOOK_VIEW, book);
}


static gpointer _page_view_ref0 (gpointer self) {
	return self ? page_view_ref (self) : NULL;
}


static PageView* book_view_get_nth_page (BookView* self, gint n) {
	PageView* result = NULL;
	Page* _tmp0_ = NULL;
	Page* page;
	gconstpointer _tmp1_ = NULL;
	PageView* _tmp2_;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = book_get_page (self->priv->book, n);
	page = _tmp0_;
	_tmp1_ = g_hash_table_lookup (self->priv->page_data, page);
	_tmp2_ = _page_view_ref0 ((PageView*) _tmp1_);
	result = _tmp2_;
	_page_unref0 (page);
	return result;
}


static PageView* book_view_get_next_page (BookView* self, PageView* page) {
	PageView* result = NULL;
	PageView* _tmp8_;
	g_return_val_if_fail (self != NULL, NULL);
	g_return_val_if_fail (page != NULL, NULL);
	{
		gint i;
		i = 0;
		{
			gboolean _tmp0_;
			_tmp0_ = TRUE;
			while (TRUE) {
				Page* _tmp1_ = NULL;
				Page* p;
				Page* _tmp2_ = NULL;
				Page* _tmp3_;
				gboolean _tmp4_;
				if (!_tmp0_) {
					i++;
				}
				_tmp0_ = FALSE;
				_tmp1_ = book_get_page (self->priv->book, i);
				p = _tmp1_;
				if (p == NULL) {
					_page_unref0 (p);
					break;
				}
				_tmp2_ = page_view_get_page (page);
				_tmp3_ = _tmp2_;
				_tmp4_ = p == _tmp3_;
				_page_unref0 (_tmp3_);
				if (_tmp4_) {
					Page* _tmp5_ = NULL;
					_tmp5_ = book_get_page (self->priv->book, i + 1);
					_page_unref0 (p);
					p = _tmp5_;
					if (p != NULL) {
						gconstpointer _tmp6_ = NULL;
						PageView* _tmp7_;
						_tmp6_ = g_hash_table_lookup (self->priv->page_data, p);
						_tmp7_ = _page_view_ref0 ((PageView*) _tmp6_);
						result = _tmp7_;
						_page_unref0 (p);
						return result;
					}
				}
				_page_unref0 (p);
			}
		}
	}
	_tmp8_ = _page_view_ref0 (page);
	result = _tmp8_;
	return result;
}


static PageView* book_view_get_prev_page (BookView* self, PageView* page) {
	PageView* result = NULL;
	PageView* _tmp0_;
	PageView* prev_page;
	PageView* _tmp8_;
	g_return_val_if_fail (self != NULL, NULL);
	g_return_val_if_fail (page != NULL, NULL);
	_tmp0_ = _page_view_ref0 (page);
	prev_page = _tmp0_;
	{
		gint i;
		i = 0;
		{
			gboolean _tmp1_;
			_tmp1_ = TRUE;
			while (TRUE) {
				Page* _tmp2_ = NULL;
				Page* p;
				Page* _tmp3_ = NULL;
				Page* _tmp4_;
				gboolean _tmp5_;
				gconstpointer _tmp6_ = NULL;
				PageView* _tmp7_;
				if (!_tmp1_) {
					i++;
				}
				_tmp1_ = FALSE;
				_tmp2_ = book_get_page (self->priv->book, i);
				p = _tmp2_;
				if (p == NULL) {
					_page_unref0 (p);
					break;
				}
				_tmp3_ = page_view_get_page (page);
				_tmp4_ = _tmp3_;
				_tmp5_ = p == _tmp4_;
				_page_unref0 (_tmp4_);
				if (_tmp5_) {
					result = prev_page;
					_page_unref0 (p);
					return result;
				}
				_tmp6_ = g_hash_table_lookup (self->priv->page_data, p);
				_tmp7_ = _page_view_ref0 ((PageView*) _tmp6_);
				_page_view_unref0 (prev_page);
				prev_page = _tmp7_;
				_page_unref0 (p);
			}
		}
	}
	_tmp8_ = _page_view_ref0 (page);
	result = _tmp8_;
	_page_view_unref0 (prev_page);
	return result;
}


static void book_view_page_view_changed_cb (BookView* self, PageView* page) {
	g_return_if_fail (self != NULL);
	g_return_if_fail (page != NULL);
	book_view_redraw (self);
}


static void book_view_page_view_size_changed_cb (BookView* self, PageView* page) {
	g_return_if_fail (self != NULL);
	g_return_if_fail (page != NULL);
	self->priv->need_layout = TRUE;
	book_view_redraw (self);
}


static void _book_view_page_view_changed_cb_page_view_changed (PageView* _sender, gpointer self) {
	book_view_page_view_changed_cb (self, _sender);
}


static void _book_view_page_view_size_changed_cb_page_view_size_changed (PageView* _sender, gpointer self) {
	book_view_page_view_size_changed_cb (self, _sender);
}


static gpointer _page_ref0 (gpointer self) {
	return self ? page_ref (self) : NULL;
}


static void book_view_add_cb (BookView* self, Book* book, Page* page) {
	PageView* _tmp0_ = NULL;
	PageView* page_view;
	Page* _tmp1_;
	PageView* _tmp2_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (book != NULL);
	g_return_if_fail (page != NULL);
	_tmp0_ = page_view_new (page);
	page_view = _tmp0_;
	g_signal_connect_object (page_view, "changed", (GCallback) _book_view_page_view_changed_cb_page_view_changed, self, 0);
	g_signal_connect_object (page_view, "size-changed", (GCallback) _book_view_page_view_size_changed_cb_page_view_size_changed, self, 0);
	_tmp1_ = _page_ref0 (page);
	_tmp2_ = _page_view_ref0 (page_view);
	g_hash_table_insert (self->priv->page_data, _tmp1_, _tmp2_);
	self->priv->need_layout = TRUE;
	book_view_redraw (self);
	_page_view_unref0 (page_view);
}


static void book_view_set_selected_page (BookView* self, PageView* page) {
	gboolean _tmp0_ = FALSE;
	PageView* _tmp1_;
	gboolean _tmp2_;
	g_return_if_fail (self != NULL);
	if (self->priv->selected_page != NULL) {
		_tmp0_ = page != self->priv->selected_page;
	} else {
		_tmp0_ = FALSE;
	}
	if (_tmp0_) {
		page_view_set_selected (self->priv->selected_page, FALSE);
	}
	_tmp1_ = _page_view_ref0 (page);
	_page_view_unref0 (self->priv->selected_page);
	self->priv->selected_page = _tmp1_;
	if (self->priv->selected_page == NULL) {
		return;
	}
	g_object_get (self->priv->drawing_area, "has-focus", &_tmp2_, NULL);
	if (!_tmp2_) {
		page_view_set_selected (self->priv->selected_page, FALSE);
	} else {
		page_view_set_selected (self->priv->selected_page, TRUE);
	}
}


static void book_view_set_x_offset (BookView* self, gint offset) {
	g_return_if_fail (self != NULL);
	gtk_adjustment_set_value (self->priv->adjustment, (gdouble) offset);
}


static gint book_view_get_x_offset (BookView* self) {
	gint result = 0;
	gdouble _tmp0_;
	g_return_val_if_fail (self != NULL, 0);
	_tmp0_ = gtk_adjustment_get_value (self->priv->adjustment);
	result = (gint) _tmp0_;
	return result;
}


static void book_view_show_page_view (BookView* self, PageView* page) {
	gboolean _tmp0_ = FALSE;
	GtkAllocation allocation = {0};
	GtkAllocation _tmp2_ = {0};
	gint _tmp3_;
	gint left_edge;
	gint _tmp4_;
	gint _tmp5_;
	gint right_edge;
	gint _tmp6_;
	g_return_if_fail (self != NULL);
	if (page == NULL) {
		_tmp0_ = TRUE;
	} else {
		gboolean _tmp1_;
		_tmp1_ = gtk_widget_get_visible ((GtkWidget*) self->priv->scroll);
		_tmp0_ = !_tmp1_;
	}
	if (_tmp0_) {
		return;
	}
	gtk_widget_get_allocation (self->priv->drawing_area, &_tmp2_);
	allocation = _tmp2_;
	_tmp3_ = page_view_get_x_offset (page);
	left_edge = _tmp3_;
	_tmp4_ = page_view_get_x_offset (page);
	_tmp5_ = page_view_get_width (page);
	right_edge = _tmp4_ + _tmp5_;
	_tmp6_ = book_view_get_x_offset (self);
	if ((left_edge - _tmp6_) < 0) {
		book_view_set_x_offset (self, left_edge);
	} else {
		gint _tmp7_;
		_tmp7_ = book_view_get_x_offset (self);
		if ((right_edge - _tmp7_) > allocation.width) {
			book_view_set_x_offset (self, right_edge - allocation.width);
		}
	}
}


static void book_view_select_page_view (BookView* self, PageView* page) {
	Page* p;
	g_return_if_fail (self != NULL);
	p = NULL;
	if (self->priv->selected_page == page) {
		_page_unref0 (p);
		return;
	}
	book_view_set_selected_page (self, page);
	if (self->priv->need_layout) {
		self->priv->show_selected_page = TRUE;
	} else {
		book_view_show_page_view (self, page);
	}
	if (page != NULL) {
		Page* _tmp0_ = NULL;
		_tmp0_ = page_view_get_page (page);
		_page_unref0 (p);
		p = _tmp0_;
	}
	g_signal_emit_by_name (self, "page-selected", p);
	_page_unref0 (p);
}


static void book_view_remove_cb (BookView* self, Book* book, Page* page) {
	PageView* _tmp0_;
	PageView* new_selection;
	Page* _tmp1_ = NULL;
	Page* _tmp2_;
	gboolean _tmp3_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (book != NULL);
	g_return_if_fail (page != NULL);
	_tmp0_ = _page_view_ref0 (self->priv->selected_page);
	new_selection = _tmp0_;
	_tmp1_ = book_view_get_selected (self);
	_tmp2_ = _tmp1_;
	_tmp3_ = page == _tmp2_;
	_page_unref0 (_tmp2_);
	if (_tmp3_) {
		PageView* _tmp4_ = NULL;
		_tmp4_ = book_view_get_prev_page (self, self->priv->selected_page);
		_page_view_unref0 (new_selection);
		new_selection = _tmp4_;
		if (new_selection == self->priv->selected_page) {
			PageView* _tmp5_ = NULL;
			_tmp5_ = book_view_get_next_page (self, self->priv->selected_page);
			_page_view_unref0 (new_selection);
			new_selection = _tmp5_;
		}
		_page_view_unref0 (self->priv->selected_page);
		self->priv->selected_page = NULL;
	}
	g_hash_table_remove (self->priv->page_data, page);
	book_view_select_page_view (self, new_selection);
	self->priv->need_layout = TRUE;
	book_view_redraw (self);
	_page_view_unref0 (new_selection);
}


static void book_view_reorder_cb (BookView* self, Book* book) {
	g_return_if_fail (self != NULL);
	g_return_if_fail (book != NULL);
	self->priv->need_layout = TRUE;
	book_view_redraw (self);
}


static void book_view_clear_cb (BookView* self, Book* book) {
	g_return_if_fail (self != NULL);
	g_return_if_fail (book != NULL);
	g_hash_table_remove_all (self->priv->page_data);
	_page_view_unref0 (self->priv->selected_page);
	self->priv->selected_page = NULL;
	g_signal_emit_by_name (self, "page-selected", NULL);
	self->priv->need_layout = TRUE;
	book_view_redraw (self);
}


Book* book_view_get_book (BookView* self) {
	Book* result = NULL;
	Book* _tmp0_;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = _book_ref0 (self->priv->book);
	result = _tmp0_;
	return result;
}


static gboolean book_view_configure_cb (BookView* self, GtkWidget* widget, GdkEventConfigure* event) {
	gboolean result = FALSE;
	g_return_val_if_fail (self != NULL, FALSE);
	g_return_val_if_fail (widget != NULL, FALSE);
	self->priv->need_layout = TRUE;
	result = FALSE;
	return result;
}


static void book_view_layout_into (BookView* self, gint width, gint height, gint* book_width, gint* book_height) {
	gint _book_width = 0;
	gint _book_height = 0;
	gint max_dpi;
	gint max_width;
	gint max_height;
	gdouble aspect;
	gdouble max_aspect;
	gint spacing;
	gint x_offset;
	g_return_if_fail (self != NULL);
	max_dpi = 0;
	{
		gint i;
		i = 0;
		{
			gboolean _tmp0_;
			_tmp0_ = TRUE;
			while (TRUE) {
				guint _tmp1_;
				Page* _tmp2_ = NULL;
				Page* page;
				gint _tmp3_;
				if (!_tmp0_) {
					i++;
				}
				_tmp0_ = FALSE;
				_tmp1_ = book_get_n_pages (self->priv->book);
				if (!(((guint) i) < _tmp1_)) {
					break;
				}
				_tmp2_ = book_get_page (self->priv->book, i);
				page = _tmp2_;
				_tmp3_ = page_get_dpi (page);
				if (_tmp3_ > max_dpi) {
					gint _tmp4_;
					_tmp4_ = page_get_dpi (page);
					max_dpi = _tmp4_;
				}
				_page_unref0 (page);
			}
		}
	}
	max_width = 0;
	max_height = 0;
	{
		gint i;
		i = 0;
		{
			gboolean _tmp5_;
			_tmp5_ = TRUE;
			while (TRUE) {
				guint _tmp6_;
				Page* _tmp7_ = NULL;
				Page* page;
				gint _tmp8_;
				gint w;
				gint _tmp9_;
				gint h;
				gint _tmp10_;
				gint _tmp11_;
				if (!_tmp5_) {
					i++;
				}
				_tmp5_ = FALSE;
				_tmp6_ = book_get_n_pages (self->priv->book);
				if (!(((guint) i) < _tmp6_)) {
					break;
				}
				_tmp7_ = book_get_page (self->priv->book, i);
				page = _tmp7_;
				_tmp8_ = page_get_width (page);
				w = _tmp8_;
				_tmp9_ = page_get_height (page);
				h = _tmp9_;
				_tmp10_ = page_get_dpi (page);
				w = (gint) (((((gdouble) w) * max_dpi) / _tmp10_) + 0.5);
				_tmp11_ = page_get_dpi (page);
				h = (gint) (((((gdouble) h) * max_dpi) / _tmp11_) + 0.5);
				if (w > max_width) {
					max_width = w;
				}
				if (h > max_height) {
					max_height = h;
				}
				_page_unref0 (page);
			}
		}
	}
	aspect = ((gdouble) width) / height;
	max_aspect = ((gdouble) max_width) / max_height;
	spacing = 12;
	_book_width = 0;
	_book_height = 0;
	{
		gint i;
		i = 0;
		{
			gboolean _tmp12_;
			_tmp12_ = TRUE;
			while (TRUE) {
				guint _tmp13_;
				PageView* _tmp14_ = NULL;
				PageView* page;
				Page* _tmp15_ = NULL;
				Page* p;
				gint _tmp20_;
				gint h;
				gint _tmp21_;
				if (!_tmp12_) {
					i++;
				}
				_tmp12_ = FALSE;
				_tmp13_ = book_get_n_pages (self->priv->book);
				if (!(((guint) i) < _tmp13_)) {
					break;
				}
				_tmp14_ = book_view_get_nth_page (self, i);
				page = _tmp14_;
				_tmp15_ = page_view_get_page (page);
				p = _tmp15_;
				if (max_aspect > aspect) {
					gint _tmp16_;
					gint _tmp17_;
					gint w;
					_tmp16_ = page_get_width (p);
					_tmp17_ = page_get_dpi (p);
					w = (gint) (((((gdouble) _tmp16_) * max_dpi) * width) / (_tmp17_ * max_width));
					page_view_set_width (page, w);
				} else {
					gint _tmp18_;
					gint _tmp19_;
					gint h;
					_tmp18_ = page_get_height (p);
					_tmp19_ = page_get_dpi (p);
					h = (gint) (((((gdouble) _tmp18_) * max_dpi) * height) / (_tmp19_ * max_height));
					page_view_set_height (page, h);
				}
				_tmp20_ = page_view_get_height (page);
				h = _tmp20_;
				if (h > _book_height) {
					_book_height = h;
				}
				_tmp21_ = page_view_get_width (page);
				_book_width = _book_width + _tmp21_;
				if (i != 0) {
					_book_width = _book_width + spacing;
				}
				_page_unref0 (p);
				_page_view_unref0 (page);
			}
		}
	}
	x_offset = 0;
	{
		gint i;
		i = 0;
		{
			gboolean _tmp22_;
			_tmp22_ = TRUE;
			while (TRUE) {
				guint _tmp23_;
				PageView* _tmp24_ = NULL;
				PageView* page;
				gint _tmp25_;
				gint _tmp26_;
				if (!_tmp22_) {
					i++;
				}
				_tmp22_ = FALSE;
				_tmp23_ = book_get_n_pages (self->priv->book);
				if (!(((guint) i) < _tmp23_)) {
					break;
				}
				_tmp24_ = book_view_get_nth_page (self, i);
				page = _tmp24_;
				page_view_set_x_offset (page, x_offset);
				_tmp25_ = page_view_get_width (page);
				x_offset = x_offset + (_tmp25_ + spacing);
				_tmp26_ = page_view_get_height (page);
				page_view_set_y_offset (page, (height - _tmp26_) / 2);
				_page_view_unref0 (page);
			}
		}
	}
	if (book_width) {
		*book_width = _book_width;
	}
	if (book_height) {
		*book_height = _book_height;
	}
}


static void book_view_layout (BookView* self) {
	GtkAllocation allocation = {0};
	GtkAllocation _tmp0_ = {0};
	GtkAllocation box_allocation = {0};
	GtkAllocation _tmp1_ = {0};
	gboolean right_aligned;
	gdouble _tmp2_;
	gdouble _tmp3_;
	gdouble _tmp4_;
	gint width;
	guint _tmp5_;
	gint height;
	gint book_width = 0;
	gint book_height = 0;
	gint _tmp6_;
	gint _tmp7_;
	g_return_if_fail (self != NULL);
	if (!self->priv->need_layout) {
		return;
	}
	self->priv->laying_out = TRUE;
	gtk_widget_get_allocation (self->priv->drawing_area, &_tmp0_);
	allocation = _tmp0_;
	gtk_widget_get_allocation ((GtkWidget*) self, &_tmp1_);
	box_allocation = _tmp1_;
	right_aligned = TRUE;
	_tmp2_ = gtk_adjustment_get_value (self->priv->adjustment);
	_tmp3_ = gtk_adjustment_get_upper (self->priv->adjustment);
	_tmp4_ = gtk_adjustment_get_page_size (self->priv->adjustment);
	if (_tmp2_ < (_tmp3_ - _tmp4_)) {
		right_aligned = FALSE;
	}
	width = (gint) allocation.width;
	_tmp5_ = gtk_container_get_border_width ((GtkContainer*) self);
	height = (gint) (box_allocation.height - (_tmp5_ * 2));
	book_view_layout_into (self, width, height, &_tmp6_, &_tmp7_);
	book_width = _tmp6_;
	book_height = _tmp7_;
	if (book_width > allocation.width) {
		gint _tmp8_;
		gint _tmp9_;
		gint max_offset;
		gboolean _tmp10_ = FALSE;
		height = allocation.height;
		book_view_layout_into (self, width, height, &_tmp8_, &_tmp9_);
		book_width = _tmp8_;
		book_height = _tmp9_;
		gtk_adjustment_set_lower (self->priv->adjustment, (gdouble) 0);
		gtk_adjustment_set_upper (self->priv->adjustment, (gdouble) book_width);
		gtk_adjustment_set_page_size (self->priv->adjustment, (gdouble) allocation.width);
		max_offset = book_width - allocation.width;
		if (right_aligned) {
			_tmp10_ = TRUE;
		} else {
			gint _tmp11_;
			_tmp11_ = book_view_get_x_offset (self);
			_tmp10_ = _tmp11_ > max_offset;
		}
		if (_tmp10_) {
			book_view_set_x_offset (self, max_offset);
		}
		gtk_widget_show ((GtkWidget*) self->priv->scroll);
	} else {
		gint offset;
		gtk_widget_hide ((GtkWidget*) self->priv->scroll);
		offset = (book_width - allocation.width) / 2;
		gtk_adjustment_set_lower (self->priv->adjustment, (gdouble) offset);
		gtk_adjustment_set_upper (self->priv->adjustment, (gdouble) offset);
		gtk_adjustment_set_page_size (self->priv->adjustment, (gdouble) 0);
		book_view_set_x_offset (self, offset);
	}
	if (self->priv->show_selected_page) {
		book_view_show_page_view (self, self->priv->selected_page);
	}
	self->priv->need_layout = FALSE;
	self->priv->show_selected_page = FALSE;
	self->priv->laying_out = FALSE;
}


static gboolean book_view_draw_cb (BookView* self, GtkWidget* widget, cairo_t* context) {
	gboolean result = FALSE;
	guint _tmp0_;
	gdouble left = 0.0;
	gdouble top = 0.0;
	gdouble right = 0.0;
	gdouble bottom = 0.0;
	gdouble _tmp1_;
	gdouble _tmp2_;
	gdouble _tmp3_;
	gdouble _tmp4_;
	g_return_val_if_fail (self != NULL, FALSE);
	g_return_val_if_fail (widget != NULL, FALSE);
	g_return_val_if_fail (context != NULL, FALSE);
	_tmp0_ = book_get_n_pages (self->priv->book);
	if (_tmp0_ == ((guint) 0)) {
		result = FALSE;
		return result;
	}
	book_view_layout (self);
	cairo_clip_extents (context, &_tmp1_, &_tmp2_, &_tmp3_, &_tmp4_);
	left = _tmp1_;
	top = _tmp2_;
	right = _tmp3_;
	bottom = _tmp4_;
	{
		gint i;
		i = 0;
		{
			gboolean _tmp5_;
			_tmp5_ = TRUE;
			while (TRUE) {
				guint _tmp6_;
				PageView* _tmp7_ = NULL;
				PageView* page;
				gint _tmp8_;
				gint _tmp9_;
				gint left_edge;
				gint _tmp10_;
				gint _tmp11_;
				gint _tmp12_;
				gint right_edge;
				gboolean _tmp13_ = FALSE;
				gint _tmp14_;
				gboolean _tmp15_;
				if (!_tmp5_) {
					i++;
				}
				_tmp5_ = FALSE;
				_tmp6_ = book_get_n_pages (self->priv->book);
				if (!(((guint) i) < _tmp6_)) {
					break;
				}
				_tmp7_ = book_view_get_nth_page (self, i);
				page = _tmp7_;
				_tmp8_ = page_view_get_x_offset (page);
				_tmp9_ = book_view_get_x_offset (self);
				left_edge = _tmp8_ - _tmp9_;
				_tmp10_ = page_view_get_x_offset (page);
				_tmp11_ = page_view_get_width (page);
				_tmp12_ = book_view_get_x_offset (self);
				right_edge = (_tmp10_ + _tmp11_) - _tmp12_;
				if (((gdouble) right_edge) < left) {
					_tmp13_ = TRUE;
				} else {
					_tmp13_ = ((gdouble) left_edge) > right;
				}
				if (_tmp13_) {
					_page_view_unref0 (page);
					continue;
				}
				cairo_save (context);
				_tmp14_ = book_view_get_x_offset (self);
				cairo_translate (context, (gdouble) (-_tmp14_), (gdouble) 0);
				page_view_render (page, context);
				cairo_restore (context);
				_tmp15_ = page_view_get_selected (page);
				if (_tmp15_) {
					GtkStyle* _tmp16_ = NULL;
					gint _tmp17_;
					gint _tmp18_;
					gint _tmp19_;
					gint _tmp20_;
					gint _tmp21_;
					_tmp16_ = gtk_widget_get_style (self->priv->drawing_area);
					_tmp17_ = page_view_get_x_offset (page);
					_tmp18_ = book_view_get_x_offset (self);
					_tmp19_ = page_view_get_y_offset (page);
					_tmp20_ = page_view_get_width (page);
					_tmp21_ = page_view_get_height (page);
					gtk_paint_focus (_tmp16_, context, GTK_STATE_SELECTED, NULL, NULL, _tmp17_ - _tmp18_, _tmp19_, _tmp20_, _tmp21_);
				}
				_page_view_unref0 (page);
			}
		}
	}
	result = FALSE;
	return result;
}


static PageView* book_view_get_page_at (BookView* self, gint x, gint y, gint* x_, gint* y_) {
	gint _x_ = 0;
	gint _y_ = 0;
	PageView* result = NULL;
	g_return_val_if_fail (self != NULL, NULL);
	{
		gint i;
		i = 0;
		{
			gboolean _tmp0_;
			_tmp0_ = TRUE;
			while (TRUE) {
				guint _tmp1_;
				PageView* _tmp2_ = NULL;
				PageView* page;
				gint _tmp3_;
				gint left;
				gint _tmp4_;
				gint right;
				gint _tmp5_;
				gint top;
				gint _tmp6_;
				gint bottom;
				gboolean _tmp7_ = FALSE;
				gboolean _tmp8_ = FALSE;
				gboolean _tmp9_ = FALSE;
				if (!_tmp0_) {
					i++;
				}
				_tmp0_ = FALSE;
				_tmp1_ = book_get_n_pages (self->priv->book);
				if (!(((guint) i) < _tmp1_)) {
					break;
				}
				_tmp2_ = book_view_get_nth_page (self, i);
				page = _tmp2_;
				_tmp3_ = page_view_get_x_offset (page);
				left = _tmp3_;
				_tmp4_ = page_view_get_width (page);
				right = left + _tmp4_;
				_tmp5_ = page_view_get_y_offset (page);
				top = _tmp5_;
				_tmp6_ = page_view_get_height (page);
				bottom = top + _tmp6_;
				if (x >= left) {
					_tmp9_ = x <= right;
				} else {
					_tmp9_ = FALSE;
				}
				if (_tmp9_) {
					_tmp8_ = y >= top;
				} else {
					_tmp8_ = FALSE;
				}
				if (_tmp8_) {
					_tmp7_ = y <= bottom;
				} else {
					_tmp7_ = FALSE;
				}
				if (_tmp7_) {
					_x_ = x - left;
					_y_ = y - top;
					result = page;
					if (x_) {
						*x_ = _x_;
					}
					if (y_) {
						*y_ = _y_;
					}
					return result;
				}
				_page_view_unref0 (page);
			}
		}
	}
	result = NULL;
	if (x_) {
		*x_ = _x_;
	}
	if (y_) {
		*y_ = _y_;
	}
	return result;
}


static gboolean book_view_button_cb (BookView* self, GtkWidget* widget, GdkEventButton* event) {
	gboolean result = FALSE;
	gint x;
	gint y;
	g_return_val_if_fail (self != NULL, FALSE);
	g_return_val_if_fail (widget != NULL, FALSE);
	book_view_layout (self);
	gtk_widget_grab_focus (self->priv->drawing_area);
	x = 0;
	y = 0;
	if ((*event).type == GDK_BUTTON_PRESS) {
		gint _tmp0_;
		gint _tmp1_;
		gint _tmp2_;
		PageView* _tmp3_ = NULL;
		PageView* _tmp4_;
		_tmp0_ = book_view_get_x_offset (self);
		_tmp3_ = book_view_get_page_at (self, (gint) ((*event).x + _tmp0_), (gint) (*event).y, &_tmp1_, &_tmp2_);
		x = _tmp1_;
		y = _tmp2_;
		_tmp4_ = _tmp3_;
		book_view_select_page_view (self, _tmp4_);
		_page_view_unref0 (_tmp4_);
	}
	if (self->priv->selected_page == NULL) {
		result = FALSE;
		return result;
	}
	if ((*event).button == ((guint) 1)) {
		if ((*event).type == GDK_BUTTON_PRESS) {
			page_view_button_press (self->priv->selected_page, x, y);
		} else {
			if ((*event).type == GDK_BUTTON_RELEASE) {
				page_view_button_release (self->priv->selected_page, x, y);
			} else {
				if ((*event).type == GDK_2BUTTON_PRESS) {
					Page* _tmp5_ = NULL;
					Page* _tmp6_;
					_tmp5_ = book_view_get_selected (self);
					_tmp6_ = _tmp5_;
					g_signal_emit_by_name (self, "show-page", _tmp6_);
					_page_unref0 (_tmp6_);
				}
			}
		}
	}
	if ((*event).button == ((guint) 3)) {
		g_signal_emit_by_name (self, "show-menu");
	}
	result = FALSE;
	return result;
}


static void book_view_set_cursor (BookView* self, GdkCursorType cursor) {
	GdkCursor* c = NULL;
	GdkCursor* _tmp0_ = NULL;
	GdkWindow* _tmp1_ = NULL;
	g_return_if_fail (self != NULL);
	if (self->priv->cursor == cursor) {
		_g_object_unref0 (c);
		return;
	}
	self->priv->cursor = cursor;
	_tmp0_ = gdk_cursor_new (cursor);
	_g_object_unref0 (c);
	c = _tmp0_;
	_tmp1_ = gtk_widget_get_window (self->priv->drawing_area);
	gdk_window_set_cursor (_tmp1_, c);
	_g_object_unref0 (c);
}


static gboolean book_view_motion_cb (BookView* self, GtkWidget* widget, GdkEventMotion* event) {
	gboolean result = FALSE;
	GdkCursorType cursor;
	gboolean _tmp0_ = FALSE;
	g_return_val_if_fail (self != NULL, FALSE);
	g_return_val_if_fail (widget != NULL, FALSE);
	cursor = GDK_ARROW;
	if (self->priv->selected_page != NULL) {
		_tmp0_ = ((*event).state & GDK_BUTTON1_MASK) != 0;
	} else {
		_tmp0_ = FALSE;
	}
	if (_tmp0_) {
		gint _tmp1_;
		gint _tmp2_;
		gint x;
		gint _tmp3_;
		gint y;
		GdkCursorType _tmp4_;
		_tmp1_ = book_view_get_x_offset (self);
		_tmp2_ = page_view_get_x_offset (self->priv->selected_page);
		x = (gint) (((*event).x + _tmp1_) - _tmp2_);
		_tmp3_ = page_view_get_y_offset (self->priv->selected_page);
		y = (gint) ((*event).y - _tmp3_);
		page_view_motion (self->priv->selected_page, x, y);
		_tmp4_ = page_view_get_cursor (self->priv->selected_page);
		cursor = _tmp4_;
	} else {
		gint x = 0;
		gint y = 0;
		gint _tmp5_;
		gint _tmp6_;
		gint _tmp7_;
		PageView* _tmp8_ = NULL;
		PageView* over_page;
		_tmp5_ = book_view_get_x_offset (self);
		_tmp8_ = book_view_get_page_at (self, (gint) ((*event).x + _tmp5_), (gint) (*event).y, &_tmp6_, &_tmp7_);
		x = _tmp6_;
		y = _tmp7_;
		over_page = _tmp8_;
		if (over_page != NULL) {
			GdkCursorType _tmp9_;
			page_view_motion (over_page, x, y);
			_tmp9_ = page_view_get_cursor (over_page);
			cursor = _tmp9_;
		}
		_page_view_unref0 (over_page);
	}
	book_view_set_cursor (self, cursor);
	result = FALSE;
	return result;
}


static gboolean book_view_key_cb (BookView* self, GtkWidget* widget, GdkEventKey* event) {
	gboolean result = FALSE;
	g_return_val_if_fail (self != NULL, FALSE);
	g_return_val_if_fail (widget != NULL, FALSE);
	switch ((*event).keyval) {
		case 0xff50:
		{
			Page* _tmp0_ = NULL;
			Page* _tmp1_;
			_tmp0_ = book_get_page (self->priv->book, 0);
			_tmp1_ = _tmp0_;
			book_view_select_page (self, _tmp1_);
			_page_unref0 (_tmp1_);
			result = TRUE;
			return result;
		}
		case 0xff51:
		{
			PageView* _tmp2_ = NULL;
			PageView* _tmp3_;
			_tmp2_ = book_view_get_prev_page (self, self->priv->selected_page);
			_tmp3_ = _tmp2_;
			book_view_select_page_view (self, _tmp3_);
			_page_view_unref0 (_tmp3_);
			result = TRUE;
			return result;
		}
		case 0xff53:
		{
			PageView* _tmp4_ = NULL;
			PageView* _tmp5_;
			_tmp4_ = book_view_get_next_page (self, self->priv->selected_page);
			_tmp5_ = _tmp4_;
			book_view_select_page_view (self, _tmp5_);
			_page_view_unref0 (_tmp5_);
			result = TRUE;
			return result;
		}
		case 0xFF57:
		{
			guint _tmp6_;
			Page* _tmp7_ = NULL;
			Page* _tmp8_;
			_tmp6_ = book_get_n_pages (self->priv->book);
			_tmp7_ = book_get_page (self->priv->book, ((gint) _tmp6_) - 1);
			_tmp8_ = _tmp7_;
			book_view_select_page (self, _tmp8_);
			_page_unref0 (_tmp8_);
			result = TRUE;
			return result;
		}
		default:
		{
			result = FALSE;
			return result;
		}
	}
}


static gboolean book_view_focus_cb (BookView* self, GtkWidget* widget, GdkEventFocus* event) {
	gboolean result = FALSE;
	g_return_val_if_fail (self != NULL, FALSE);
	g_return_val_if_fail (widget != NULL, FALSE);
	book_view_set_selected_page (self, self->priv->selected_page);
	result = FALSE;
	return result;
}


static void book_view_scroll_cb (BookView* self, GtkAdjustment* adjustment) {
	g_return_if_fail (self != NULL);
	g_return_if_fail (adjustment != NULL);
	if (!self->priv->laying_out) {
		book_view_redraw (self);
	}
}


void book_view_redraw (BookView* self) {
	g_return_if_fail (self != NULL);
	gtk_widget_queue_draw (self->priv->drawing_area);
}


void book_view_select_page (BookView* self, Page* page) {
	Page* _tmp0_ = NULL;
	Page* _tmp1_;
	gboolean _tmp2_;
	g_return_if_fail (self != NULL);
	_tmp0_ = book_view_get_selected (self);
	_tmp1_ = _tmp0_;
	_tmp2_ = _tmp1_ == page;
	_page_unref0 (_tmp1_);
	if (_tmp2_) {
		return;
	}
	if (page != NULL) {
		gconstpointer _tmp3_ = NULL;
		_tmp3_ = g_hash_table_lookup (self->priv->page_data, page);
		book_view_select_page_view (self, (PageView*) _tmp3_);
	} else {
		book_view_select_page_view (self, NULL);
	}
}


void book_view_select_next_page (BookView* self) {
	PageView* _tmp0_ = NULL;
	PageView* _tmp1_;
	g_return_if_fail (self != NULL);
	_tmp0_ = book_view_get_next_page (self, self->priv->selected_page);
	_tmp1_ = _tmp0_;
	book_view_select_page_view (self, _tmp1_);
	_page_view_unref0 (_tmp1_);
}


void book_view_select_prev_page (BookView* self) {
	PageView* _tmp0_ = NULL;
	PageView* _tmp1_;
	g_return_if_fail (self != NULL);
	_tmp0_ = book_view_get_prev_page (self, self->priv->selected_page);
	_tmp1_ = _tmp0_;
	book_view_select_page_view (self, _tmp1_);
	_page_view_unref0 (_tmp1_);
}


Page* book_view_get_selected (BookView* self) {
	Page* result = NULL;
	g_return_val_if_fail (self != NULL, NULL);
	if (self->priv->selected_page != NULL) {
		Page* _tmp0_ = NULL;
		_tmp0_ = page_view_get_page (self->priv->selected_page);
		result = _tmp0_;
		return result;
	} else {
		result = NULL;
		return result;
	}
}


static void g_cclosure_user_marshal_VOID__PAGE (GClosure * closure, GValue * return_value, guint n_param_values, const GValue * param_values, gpointer invocation_hint, gpointer marshal_data) {
	typedef void (*GMarshalFunc_VOID__PAGE) (gpointer data1, gpointer arg_1, gpointer data2);
	register GMarshalFunc_VOID__PAGE callback;
	register GCClosure * cc;
	register gpointer data1;
	register gpointer data2;
	cc = (GCClosure *) closure;
	g_return_if_fail (n_param_values == 2);
	if (G_CCLOSURE_SWAP_DATA (closure)) {
		data1 = closure->data;
		data2 = param_values->data[0].v_pointer;
	} else {
		data1 = param_values->data[0].v_pointer;
		data2 = closure->data;
	}
	callback = (GMarshalFunc_VOID__PAGE) (marshal_data ? marshal_data : cc->callback);
	callback (data1, value_get_page (param_values + 1), data2);
}


static void book_view_class_init (BookViewClass * klass) {
	book_view_parent_class = g_type_class_peek_parent (klass);
	g_type_class_add_private (klass, sizeof (BookViewPrivate));
	G_OBJECT_CLASS (klass)->finalize = book_view_finalize;
	g_signal_new ("page_selected", TYPE_BOOK_VIEW, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_user_marshal_VOID__PAGE, G_TYPE_NONE, 1, TYPE_PAGE);
	g_signal_new ("show_page", TYPE_BOOK_VIEW, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_user_marshal_VOID__PAGE, G_TYPE_NONE, 1, TYPE_PAGE);
	g_signal_new ("show_menu", TYPE_BOOK_VIEW, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
}


static void book_view_instance_init (BookView * self) {
	self->priv = BOOK_VIEW_GET_PRIVATE (self);
	self->priv->selected_page = NULL;
}


static void book_view_finalize (GObject* obj) {
	BookView * self;
	self = BOOK_VIEW (obj);
	_book_unref0 (self->priv->book);
	_g_hash_table_unref0 (self->priv->page_data);
	_page_view_unref0 (self->priv->selected_page);
	_g_object_unref0 (self->priv->drawing_area);
	_g_object_unref0 (self->priv->scroll);
	_g_object_unref0 (self->priv->adjustment);
	G_OBJECT_CLASS (book_view_parent_class)->finalize (obj);
}


GType book_view_get_type (void) {
	static volatile gsize book_view_type_id__volatile = 0;
	if (g_once_init_enter (&book_view_type_id__volatile)) {
		static const GTypeInfo g_define_type_info = { sizeof (BookViewClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) book_view_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (BookView), 0, (GInstanceInitFunc) book_view_instance_init, NULL };
		GType book_view_type_id;
		book_view_type_id = g_type_register_static (GTK_TYPE_VBOX, "BookView", &g_define_type_info, 0);
		g_once_init_leave (&book_view_type_id__volatile, book_view_type_id);
	}
	return book_view_type_id__volatile;
}