/* hypertextview.c generated by valac 0.19.0, the Vala compiler
 * generated from hypertextview.vala, do not modify */

/*
 *  Notes - panel plugin for Xfce Desktop Environment
 *  Copyright (c) 2009-2010  Mike Massonnet <mmassonnet@xfce.org>
 *
 *  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 2 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 Library General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#include <glib.h>
#include <glib-object.h>
#include <gtk/gtk.h>
#include <gdk/gdk.h>
#include <stdlib.h>
#include <string.h>
#include <pango/pango.h>
#include <gio/gio.h>


#define XNP_TYPE_HYPERTEXT_VIEW (xnp_hypertext_view_get_type ())
#define XNP_HYPERTEXT_VIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), XNP_TYPE_HYPERTEXT_VIEW, XnpHypertextView))
#define XNP_HYPERTEXT_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), XNP_TYPE_HYPERTEXT_VIEW, XnpHypertextViewClass))
#define XNP_IS_HYPERTEXT_VIEW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), XNP_TYPE_HYPERTEXT_VIEW))
#define XNP_IS_HYPERTEXT_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), XNP_TYPE_HYPERTEXT_VIEW))
#define XNP_HYPERTEXT_VIEW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), XNP_TYPE_HYPERTEXT_VIEW, XnpHypertextViewClass))

typedef struct _XnpHypertextView XnpHypertextView;
typedef struct _XnpHypertextViewClass XnpHypertextViewClass;
typedef struct _XnpHypertextViewPrivate XnpHypertextViewPrivate;
#define _gdk_cursor_unref0(var) ((var == NULL) ? NULL : (var = (gdk_cursor_unref (var), NULL)))
#define _g_free0(var) (var = (g_free (var), NULL))
#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))
#define _g_error_free0(var) ((var == NULL) ? NULL : (var = (g_error_free (var), NULL)))
#define __vala_PangoFontDescription_free0(var) ((var == NULL) ? NULL : (var = (_vala_PangoFontDescription_free (var), NULL)))
#define __vala_PangoTabArray_free0(var) ((var == NULL) ? NULL : (var = (_vala_PangoTabArray_free (var), NULL)))

struct _XnpHypertextView {
	GtkTextView parent_instance;
	XnpHypertextViewPrivate * priv;
};

struct _XnpHypertextViewClass {
	GtkTextViewClass parent_class;
};

struct _XnpHypertextViewPrivate {
	GdkCursor* hand_cursor;
	GdkCursor* regular_cursor;
	gboolean cursor_over_link;
	guint undo_timeout;
	gint undo_cursor_pos;
	gchar* undo_text;
	gchar* redo_text;
	guint tag_timeout;
	GtkTextTag* tag_link;
	gchar* _font;
};


static gpointer xnp_hypertext_view_parent_class = NULL;

GType xnp_hypertext_view_get_type (void) G_GNUC_CONST;
#define XNP_HYPERTEXT_VIEW_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), XNP_TYPE_HYPERTEXT_VIEW, XnpHypertextViewPrivate))
enum  {
	XNP_HYPERTEXT_VIEW_DUMMY_PROPERTY,
	XNP_HYPERTEXT_VIEW_FONT
};
XnpHypertextView* xnp_hypertext_view_new (void);
XnpHypertextView* xnp_hypertext_view_construct (GType object_type);
static gboolean xnp_hypertext_view_button_release_event_cb (XnpHypertextView* self, GtkWidget* hypertextview, GdkEventButton* event);
static gboolean _xnp_hypertext_view_button_release_event_cb_gtk_widget_button_release_event (GtkWidget* _sender, GdkEventButton* event, gpointer self);
static gboolean xnp_hypertext_view_motion_notify_event_cb (XnpHypertextView* self, GtkWidget* hypertextview, GdkEventMotion* event);
static gboolean _xnp_hypertext_view_motion_notify_event_cb_gtk_widget_motion_notify_event (GtkWidget* _sender, GdkEventMotion* event, gpointer self);
static void xnp_hypertext_view_move_cursor_cb (XnpHypertextView* self, GtkWidget* hypertextview, GtkMovementStep step, gint count, gboolean extend_selection);
static void _xnp_hypertext_view_move_cursor_cb_gtk_text_view_move_cursor (GtkTextView* _sender, GtkMovementStep step, gint count, gboolean extend_selection, gpointer self);
static void xnp_hypertext_view_buffer_changed_cb (XnpHypertextView* self);
static void _xnp_hypertext_view_buffer_changed_cb_gtk_text_buffer_changed (GtkTextBuffer* _sender, gpointer self);
static void xnp_hypertext_view_insert_text_cb (XnpHypertextView* self, GtkTextBuffer* buffer, GtkTextIter* location, const gchar* text, gint len);
static void _xnp_hypertext_view_insert_text_cb_gtk_text_buffer_insert_text (GtkTextBuffer* _sender, GtkTextIter* pos, const gchar* text, gint length, gpointer self);
static void xnp_hypertext_view_delete_range_cb (XnpHypertextView* self, GtkTextBuffer* buffer, GtkTextIter* start, GtkTextIter* end);
static void _xnp_hypertext_view_delete_range_cb_gtk_text_buffer_delete_range (GtkTextBuffer* _sender, GtkTextIter* start, GtkTextIter* end, gpointer self);
static gboolean xnp_hypertext_view_undo_snapshot (XnpHypertextView* self);
void xnp_hypertext_view_update_tags (XnpHypertextView* self);
static gboolean _xnp_hypertext_view_undo_snapshot_gsource_func (gpointer self);
static gboolean xnp_hypertext_view_tag_timeout_cb (XnpHypertextView* self);
static gboolean _xnp_hypertext_view_tag_timeout_cb_gsource_func (gpointer self);
static void xnp_hypertext_view_tag_timeout_init (XnpHypertextView* self);
void xnp_hypertext_view_undo (XnpHypertextView* self);
const gchar* xnp_hypertext_view_get_font (XnpHypertextView* self);
void xnp_hypertext_view_set_font (XnpHypertextView* self, const gchar* value);
static void _vala_PangoFontDescription_free (PangoFontDescription* self);
static GObject * xnp_hypertext_view_constructor (GType type, guint n_construct_properties, GObjectConstructParam * construct_properties);
static void _vala_PangoTabArray_free (PangoTabArray* self);
static void xnp_hypertext_view_finalize (GObject* obj);
static void _vala_xnp_hypertext_view_get_property (GObject * object, guint property_id, GValue * value, GParamSpec * pspec);
static void _vala_xnp_hypertext_view_set_property (GObject * object, guint property_id, const GValue * value, GParamSpec * pspec);


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


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


static void _xnp_hypertext_view_move_cursor_cb_gtk_text_view_move_cursor (GtkTextView* _sender, GtkMovementStep step, gint count, gboolean extend_selection, gpointer self) {
	xnp_hypertext_view_move_cursor_cb (self, _sender, step, count, extend_selection);
}


static void _xnp_hypertext_view_buffer_changed_cb_gtk_text_buffer_changed (GtkTextBuffer* _sender, gpointer self) {
	xnp_hypertext_view_buffer_changed_cb (self);
}


static void _xnp_hypertext_view_insert_text_cb_gtk_text_buffer_insert_text (GtkTextBuffer* _sender, GtkTextIter* pos, const gchar* text, gint length, gpointer self) {
	xnp_hypertext_view_insert_text_cb (self, _sender, pos, text, length);
}


static void _xnp_hypertext_view_delete_range_cb_gtk_text_buffer_delete_range (GtkTextBuffer* _sender, GtkTextIter* start, GtkTextIter* end, gpointer self) {
	xnp_hypertext_view_delete_range_cb (self, _sender, start, end);
}


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


XnpHypertextView* xnp_hypertext_view_construct (GType object_type) {
	XnpHypertextView * self = NULL;
	GtkTextIter iter = {0};
	GtkTextBuffer* _tmp0_;
	GtkTextBuffer* _tmp1_;
	GtkTextBuffer* _tmp2_;
	GtkTextBuffer* _tmp3_;
	GtkTextBuffer* _tmp4_;
	GtkTextBuffer* _tmp5_;
	GtkTextBuffer* _tmp6_;
	GtkTextBuffer* _tmp7_;
	GtkTextIter _tmp8_ = {0};
	GtkTextBuffer* _tmp9_;
	GtkTextBuffer* _tmp10_;
	GtkTextIter _tmp11_;
	GtkTextBuffer* _tmp12_;
	GtkTextBuffer* _tmp13_;
	GtkTextTag* _tmp14_ = NULL;
	GtkTextTag* _tmp15_;
	self = (XnpHypertextView*) g_object_new (object_type, NULL);
	g_signal_connect_object ((GtkWidget*) self, "button-release-event", (GCallback) _xnp_hypertext_view_button_release_event_cb_gtk_widget_button_release_event, self, 0);
	g_signal_connect_object ((GtkWidget*) self, "motion-notify-event", (GCallback) _xnp_hypertext_view_motion_notify_event_cb_gtk_widget_motion_notify_event, self, 0);
	g_signal_connect_object ((GtkTextView*) self, "move-cursor", (GCallback) _xnp_hypertext_view_move_cursor_cb_gtk_text_view_move_cursor, self, 0);
	_tmp0_ = gtk_text_view_get_buffer ((GtkTextView*) self);
	_tmp1_ = _tmp0_;
	g_signal_connect_object (_tmp1_, "changed", (GCallback) _xnp_hypertext_view_buffer_changed_cb_gtk_text_buffer_changed, self, 0);
	_tmp2_ = gtk_text_view_get_buffer ((GtkTextView*) self);
	_tmp3_ = _tmp2_;
	g_signal_connect_object (_tmp3_, "insert-text", (GCallback) _xnp_hypertext_view_insert_text_cb_gtk_text_buffer_insert_text, self, 0);
	_tmp4_ = gtk_text_view_get_buffer ((GtkTextView*) self);
	_tmp5_ = _tmp4_;
	g_signal_connect_object (_tmp5_, "delete-range", (GCallback) _xnp_hypertext_view_delete_range_cb_gtk_text_buffer_delete_range, self, 0);
	_tmp6_ = gtk_text_view_get_buffer ((GtkTextView*) self);
	_tmp7_ = _tmp6_;
	gtk_text_buffer_get_iter_at_offset (_tmp7_, &_tmp8_, 0);
	iter = _tmp8_;
	_tmp9_ = gtk_text_view_get_buffer ((GtkTextView*) self);
	_tmp10_ = _tmp9_;
	_tmp11_ = iter;
	gtk_text_buffer_create_mark (_tmp10_, "undo-pos", &_tmp11_, FALSE);
	_tmp12_ = gtk_text_view_get_buffer ((GtkTextView*) self);
	_tmp13_ = _tmp12_;
	_tmp14_ = gtk_text_buffer_create_tag (_tmp13_, "link", "foreground", "blue", "underline", PANGO_UNDERLINE_SINGLE, NULL, NULL);
	_tmp15_ = _g_object_ref0 (_tmp14_);
	_g_object_unref0 (self->priv->tag_link);
	self->priv->tag_link = _tmp15_;
	return self;
}


XnpHypertextView* xnp_hypertext_view_new (void) {
	return xnp_hypertext_view_construct (XNP_TYPE_HYPERTEXT_VIEW);
}


/**
 * button_release_event_cb:
 *
 * Event to open links.
 */
static gboolean xnp_hypertext_view_button_release_event_cb (XnpHypertextView* self, GtkWidget* hypertextview, GdkEventButton* event) {
	gboolean result = FALSE;
	GtkTextIter start = {0};
	GtkTextIter end = {0};
	GtkTextIter iter = {0};
	gchar* link = NULL;
	gint x = 0;
	gint y = 0;
	GdkEventButton _tmp0_;
	guint _tmp1_;
	GtkTextBuffer* _tmp2_;
	GtkTextBuffer* _tmp3_;
	GtkTextIter _tmp4_ = {0};
	GtkTextIter _tmp5_ = {0};
	gint _tmp6_ = 0;
	gint _tmp7_ = 0;
	GdkEventButton _tmp8_;
	gdouble _tmp9_;
	GdkEventButton _tmp10_;
	gdouble _tmp11_;
	gint _tmp12_ = 0;
	gint _tmp13_ = 0;
	gint _tmp14_;
	gint _tmp15_;
	GtkTextIter _tmp16_ = {0};
	GtkTextTag* _tmp17_;
	gboolean _tmp18_ = FALSE;
	GError * _inner_error_ = NULL;
	g_return_val_if_fail (self != NULL, FALSE);
	g_return_val_if_fail (hypertextview != NULL, FALSE);
	g_return_val_if_fail (event != NULL, FALSE);
	_tmp0_ = *event;
	_tmp1_ = _tmp0_.button;
	if (_tmp1_ != ((guint) 1)) {
		result = FALSE;
		_g_free0 (link);
		return result;
	}
	_tmp2_ = gtk_text_view_get_buffer ((GtkTextView*) self);
	_tmp3_ = _tmp2_;
	gtk_text_buffer_get_selection_bounds (_tmp3_, &_tmp4_, &_tmp5_);
	start = _tmp4_;
	end = _tmp5_;
	_tmp6_ = gtk_text_iter_get_offset (&start);
	_tmp7_ = gtk_text_iter_get_offset (&end);
	if (_tmp6_ != _tmp7_) {
		result = FALSE;
		_g_free0 (link);
		return result;
	}
	_tmp8_ = *event;
	_tmp9_ = _tmp8_.x;
	_tmp10_ = *event;
	_tmp11_ = _tmp10_.y;
	gtk_text_view_window_to_buffer_coords ((GtkTextView*) self, GTK_TEXT_WINDOW_WIDGET, (gint) _tmp9_, (gint) _tmp11_, &_tmp12_, &_tmp13_);
	x = _tmp12_;
	y = _tmp13_;
	_tmp14_ = x;
	_tmp15_ = y;
	gtk_text_view_get_iter_at_location ((GtkTextView*) self, &_tmp16_, _tmp14_, _tmp15_);
	iter = _tmp16_;
	_tmp17_ = self->priv->tag_link;
	_tmp18_ = gtk_text_iter_has_tag (&iter, _tmp17_);
	if (_tmp18_) {
		GtkTextIter _tmp19_;
		GtkTextIter _tmp20_;
		GtkTextTag* _tmp21_;
		gboolean _tmp22_ = FALSE;
		GtkTextTag* _tmp24_;
		GtkTextIter _tmp25_;
		const gchar* _tmp26_ = NULL;
		gchar* _tmp27_;
		_tmp19_ = iter;
		end = _tmp19_;
		_tmp20_ = end;
		start = _tmp20_;
		_tmp21_ = self->priv->tag_link;
		_tmp22_ = gtk_text_iter_begins_tag (&start, _tmp21_);
		if (!_tmp22_) {
			GtkTextTag* _tmp23_;
			_tmp23_ = self->priv->tag_link;
			gtk_text_iter_backward_to_tag_toggle (&start, _tmp23_);
		}
		_tmp24_ = self->priv->tag_link;
		gtk_text_iter_forward_to_tag_toggle (&end, _tmp24_);
		_tmp25_ = end;
		_tmp26_ = gtk_text_iter_get_text (&start, &_tmp25_);
		_tmp27_ = g_strdup (_tmp26_);
		_g_free0 (link);
		link = _tmp27_;
		{
			const gchar* _tmp28_;
			gchar* _tmp29_;
			gchar* _tmp30_;
			_tmp28_ = link;
			_tmp29_ = g_strconcat ("exo-open ", _tmp28_, NULL);
			_tmp30_ = _tmp29_;
			g_spawn_command_line_async (_tmp30_, &_inner_error_);
			_g_free0 (_tmp30_);
			if (_inner_error_ != NULL) {
				goto __catch16_g_error;
			}
			result = FALSE;
			_g_free0 (link);
			return result;
		}
		goto __finally16;
		__catch16_g_error:
		{
			GError* e = NULL;
			e = _inner_error_;
			_inner_error_ = NULL;
			_g_error_free0 (e);
		}
		__finally16:
		if (_inner_error_ != NULL) {
			_g_free0 (link);
			g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code);
			g_clear_error (&_inner_error_);
			return FALSE;
		}
		{
			const gchar* _tmp31_;
			_tmp31_ = link;
			g_app_info_launch_default_for_uri (_tmp31_, NULL, &_inner_error_);
			if (_inner_error_ != NULL) {
				goto __catch17_g_error;
			}
			result = FALSE;
			_g_free0 (link);
			return result;
		}
		goto __finally17;
		__catch17_g_error:
		{
			GError* e = NULL;
			GError* _tmp32_;
			const gchar* _tmp33_;
			e = _inner_error_;
			_inner_error_ = NULL;
			_tmp32_ = e;
			_tmp33_ = _tmp32_->message;
			g_message ("hypertextview.vala:127: Unable to open link with default handler: %s", _tmp33_);
			_g_error_free0 (e);
		}
		__finally17:
		if (_inner_error_ != NULL) {
			_g_free0 (link);
			g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code);
			g_clear_error (&_inner_error_);
			return FALSE;
		}
		{
			const gchar* _tmp34_;
			gchar* _tmp35_;
			gchar* _tmp36_;
			_tmp34_ = link;
			_tmp35_ = g_strconcat ("xdg-open ", _tmp34_, NULL);
			_tmp36_ = _tmp35_;
			g_spawn_command_line_async (_tmp36_, &_inner_error_);
			_g_free0 (_tmp36_);
			if (_inner_error_ != NULL) {
				goto __catch18_g_error;
			}
			result = FALSE;
			_g_free0 (link);
			return result;
		}
		goto __finally18;
		__catch18_g_error:
		{
			GError* e = NULL;
			e = _inner_error_;
			_inner_error_ = NULL;
			_g_error_free0 (e);
		}
		__finally18:
		if (_inner_error_ != NULL) {
			_g_free0 (link);
			g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code);
			g_clear_error (&_inner_error_);
			return FALSE;
		}
		{
			const gchar* _tmp37_;
			gchar* _tmp38_;
			gchar* _tmp39_;
			_tmp37_ = link;
			_tmp38_ = g_strconcat ("firefox ", _tmp37_, NULL);
			_tmp39_ = _tmp38_;
			g_spawn_command_line_async (_tmp39_, &_inner_error_);
			_g_free0 (_tmp39_);
			if (_inner_error_ != NULL) {
				goto __catch19_g_error;
			}
			result = FALSE;
			_g_free0 (link);
			return result;
		}
		goto __finally19;
		__catch19_g_error:
		{
			GError* e = NULL;
			e = _inner_error_;
			_inner_error_ = NULL;
			_g_error_free0 (e);
		}
		__finally19:
		if (_inner_error_ != NULL) {
			_g_free0 (link);
			g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code);
			g_clear_error (&_inner_error_);
			return FALSE;
		}
		g_message ("hypertextview.vala:142: Unable to find an appropriate fallback to open" \
" the link");
	}
	result = FALSE;
	_g_free0 (link);
	return result;
}


/**
 * motion_notify_event_cb:
 *
 * Event to update the cursor of the pointer.
 */
static gboolean xnp_hypertext_view_motion_notify_event_cb (XnpHypertextView* self, GtkWidget* hypertextview, GdkEventMotion* event) {
	gboolean result = FALSE;
	GtkTextIter iter = {0};
	GdkWindow* win = NULL;
	gboolean over_link = FALSE;
	gint x = 0;
	gint y = 0;
	GdkEventMotion _tmp0_;
	gdouble _tmp1_;
	GdkEventMotion _tmp2_;
	gdouble _tmp3_;
	gint _tmp4_ = 0;
	gint _tmp5_ = 0;
	gint _tmp6_;
	gint _tmp7_;
	GtkTextIter _tmp8_ = {0};
	GtkTextTag* _tmp9_;
	gboolean _tmp10_ = FALSE;
	gboolean _tmp11_;
	gboolean _tmp12_;
	g_return_val_if_fail (self != NULL, FALSE);
	g_return_val_if_fail (hypertextview != NULL, FALSE);
	g_return_val_if_fail (event != NULL, FALSE);
	_tmp0_ = *event;
	_tmp1_ = _tmp0_.x;
	_tmp2_ = *event;
	_tmp3_ = _tmp2_.y;
	gtk_text_view_window_to_buffer_coords ((GtkTextView*) self, GTK_TEXT_WINDOW_WIDGET, (gint) _tmp1_, (gint) _tmp3_, &_tmp4_, &_tmp5_);
	x = _tmp4_;
	y = _tmp5_;
	_tmp6_ = x;
	_tmp7_ = y;
	gtk_text_view_get_iter_at_location ((GtkTextView*) self, &_tmp8_, _tmp6_, _tmp7_);
	iter = _tmp8_;
	_tmp9_ = self->priv->tag_link;
	_tmp10_ = gtk_text_iter_has_tag (&iter, _tmp9_);
	over_link = _tmp10_;
	_tmp11_ = over_link;
	_tmp12_ = self->priv->cursor_over_link;
	if (_tmp11_ != _tmp12_) {
		gboolean _tmp13_;
		GdkWindow* _tmp14_ = NULL;
		GdkWindow* _tmp15_;
		GdkCursor* _tmp16_ = NULL;
		gboolean _tmp17_;
		GdkWindow* _tmp20_;
		GdkCursor* _tmp21_;
		_tmp13_ = over_link;
		self->priv->cursor_over_link = _tmp13_;
		_tmp14_ = gtk_text_view_get_window ((GtkTextView*) self, GTK_TEXT_WINDOW_TEXT);
		_tmp15_ = _g_object_ref0 (_tmp14_);
		_g_object_unref0 (win);
		win = _tmp15_;
		_tmp17_ = over_link;
		if (_tmp17_) {
			GdkCursor* _tmp18_;
			_tmp18_ = self->priv->hand_cursor;
			_tmp16_ = _tmp18_;
		} else {
			GdkCursor* _tmp19_;
			_tmp19_ = self->priv->regular_cursor;
			_tmp16_ = _tmp19_;
		}
		_tmp20_ = win;
		_tmp21_ = _tmp16_;
		gdk_window_set_cursor (_tmp20_, _tmp21_);
	}
	result = FALSE;
	_g_object_unref0 (win);
	return result;
}


/**
 * move_cursor_cb:
 *
 * Destroys existing timeouts and executes the actions immediately.
 */
static void xnp_hypertext_view_move_cursor_cb (XnpHypertextView* self, GtkWidget* hypertextview, GtkMovementStep step, gint count, gboolean extend_selection) {
	guint _tmp0_;
	guint _tmp6_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (hypertextview != NULL);
	_tmp0_ = self->priv->undo_timeout;
	if (_tmp0_ > ((guint) 0)) {
		guint _tmp1_;
		GtkTextBuffer* _tmp2_;
		GtkTextBuffer* _tmp3_;
		gint _tmp4_ = 0;
		gint _tmp5_;
		_tmp1_ = self->priv->undo_timeout;
		g_source_remove (_tmp1_);
		self->priv->undo_timeout = (guint) 0;
		xnp_hypertext_view_undo_snapshot (self);
		_tmp2_ = gtk_text_view_get_buffer ((GtkTextView*) self);
		_tmp3_ = _tmp2_;
		g_object_get (_tmp3_, "cursor-position", &_tmp4_, NULL);
		_tmp5_ = _tmp4_;
		self->priv->undo_cursor_pos = _tmp5_;
	}
	_tmp6_ = self->priv->tag_timeout;
	if (_tmp6_ > ((guint) 0)) {
		guint _tmp7_;
		_tmp7_ = self->priv->tag_timeout;
		g_source_remove (_tmp7_);
		self->priv->tag_timeout = (guint) 0;
		xnp_hypertext_view_update_tags (self);
	}
}


/**
 * buffer_changed_cb:
 *
 * Initializes timeouts to postpone actions.
 */
static gboolean _xnp_hypertext_view_undo_snapshot_gsource_func (gpointer self) {
	gboolean result;
	result = xnp_hypertext_view_undo_snapshot (self);
	return result;
}


static gboolean _xnp_hypertext_view_tag_timeout_cb_gsource_func (gpointer self) {
	gboolean result;
	result = xnp_hypertext_view_tag_timeout_cb (self);
	return result;
}


static void xnp_hypertext_view_buffer_changed_cb (XnpHypertextView* self) {
	guint _tmp0_;
	guint _tmp2_ = 0U;
	guint _tmp3_;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->priv->undo_timeout;
	if (_tmp0_ > ((guint) 0)) {
		guint _tmp1_;
		_tmp1_ = self->priv->undo_timeout;
		g_source_remove (_tmp1_);
		self->priv->undo_timeout = (guint) 0;
	}
	_tmp2_ = g_timeout_add_seconds_full (G_PRIORITY_DEFAULT, (guint) 2, _xnp_hypertext_view_undo_snapshot_gsource_func, g_object_ref (self), g_object_unref);
	self->priv->undo_timeout = _tmp2_;
	_tmp3_ = self->priv->tag_timeout;
	if (_tmp3_ > ((guint) 0)) {
		guint _tmp4_;
		guint _tmp5_ = 0U;
		_tmp4_ = self->priv->tag_timeout;
		g_source_remove (_tmp4_);
		self->priv->tag_timeout = (guint) 0;
		_tmp5_ = g_timeout_add_seconds_full (G_PRIORITY_DEFAULT, (guint) 2, _xnp_hypertext_view_tag_timeout_cb_gsource_func, g_object_ref (self), g_object_unref);
		self->priv->tag_timeout = _tmp5_;
	}
}


/**
 * insert_text_cb:
 *
 * Event to create and update existing tags within the buffer.
 */
static gboolean string_contains (const gchar* self, const gchar* needle) {
	gboolean result = FALSE;
	const gchar* _tmp0_;
	gchar* _tmp1_ = NULL;
	g_return_val_if_fail (self != NULL, FALSE);
	g_return_val_if_fail (needle != NULL, FALSE);
	_tmp0_ = needle;
	_tmp1_ = strstr ((gchar*) self, (gchar*) _tmp0_);
	result = _tmp1_ != NULL;
	return result;
}


static gchar string_get (const gchar* self, glong index) {
	gchar result = '\0';
	glong _tmp0_;
	gchar _tmp1_;
	g_return_val_if_fail (self != NULL, '\0');
	_tmp0_ = index;
	_tmp1_ = ((gchar*) self)[_tmp0_];
	result = _tmp1_;
	return result;
}


static void xnp_hypertext_view_insert_text_cb (XnpHypertextView* self, GtkTextBuffer* buffer, GtkTextIter* location, const gchar* text, gint len) {
	GtkTextIter start = {0};
	GtkTextIter end = {0};
	gboolean _tmp0_ = FALSE;
	GtkTextTag* _tmp1_;
	gboolean _tmp2_ = FALSE;
	gboolean _tmp5_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (buffer != NULL);
	g_return_if_fail (location != NULL);
	g_return_if_fail (text != NULL);
	_tmp1_ = self->priv->tag_link;
	_tmp2_ = gtk_text_iter_has_tag (location, _tmp1_);
	if (_tmp2_) {
		GtkTextTag* _tmp3_;
		gboolean _tmp4_ = FALSE;
		_tmp3_ = self->priv->tag_link;
		_tmp4_ = gtk_text_iter_begins_tag (location, _tmp3_);
		_tmp0_ = !_tmp4_;
	} else {
		_tmp0_ = FALSE;
	}
	_tmp5_ = _tmp0_;
	if (_tmp5_) {
		GtkTextIter _tmp6_;
		GtkTextTag* _tmp7_;
		gint _tmp8_ = 0;
		gint _tmp9_ = 0;
		_tmp6_ = *location;
		start = _tmp6_;
		_tmp7_ = self->priv->tag_link;
		gtk_text_iter_backward_to_tag_toggle (&start, _tmp7_);
		_tmp8_ = gtk_text_iter_get_offset (location);
		_tmp9_ = gtk_text_iter_get_offset (&start);
		if ((_tmp8_ - _tmp9_) < 7) {
			GtkTextIter _tmp10_;
			GtkTextTag* _tmp11_;
			GtkTextBuffer* _tmp12_;
			GtkTextBuffer* _tmp13_;
			GtkTextTag* _tmp14_;
			GtkTextIter _tmp15_;
			GtkTextIter _tmp16_;
			gboolean _tmp17_ = FALSE;
			gint _tmp18_;
			gboolean _tmp25_;
			_tmp10_ = start;
			end = _tmp10_;
			_tmp11_ = self->priv->tag_link;
			gtk_text_iter_forward_to_tag_toggle (&end, _tmp11_);
			_tmp12_ = gtk_text_view_get_buffer ((GtkTextView*) self);
			_tmp13_ = _tmp12_;
			_tmp14_ = self->priv->tag_link;
			_tmp15_ = start;
			_tmp16_ = end;
			gtk_text_buffer_remove_tag (_tmp13_, _tmp14_, &_tmp15_, &_tmp16_);
			_tmp18_ = len;
			if (_tmp18_ > 1) {
				gboolean _tmp19_ = FALSE;
				const gchar* _tmp20_;
				gboolean _tmp21_ = FALSE;
				gboolean _tmp24_;
				_tmp20_ = text;
				_tmp21_ = string_contains (_tmp20_, " ");
				if (_tmp21_) {
					_tmp19_ = TRUE;
				} else {
					const gchar* _tmp22_;
					gboolean _tmp23_ = FALSE;
					_tmp22_ = text;
					_tmp23_ = string_contains (_tmp22_, "\n");
					_tmp19_ = _tmp23_;
				}
				_tmp24_ = _tmp19_;
				_tmp17_ = _tmp24_;
			} else {
				_tmp17_ = FALSE;
			}
			_tmp25_ = _tmp17_;
			if (_tmp25_) {
				xnp_hypertext_view_tag_timeout_init (self);
			}
		} else {
			gboolean _tmp26_ = FALSE;
			const gchar* _tmp27_;
			gboolean _tmp28_ = FALSE;
			gboolean _tmp31_;
			_tmp27_ = text;
			_tmp28_ = string_contains (_tmp27_, " ");
			if (_tmp28_) {
				_tmp26_ = TRUE;
			} else {
				const gchar* _tmp29_;
				gboolean _tmp30_ = FALSE;
				_tmp29_ = text;
				_tmp30_ = string_contains (_tmp29_, "\n");
				_tmp26_ = _tmp30_;
			}
			_tmp31_ = _tmp26_;
			if (_tmp31_) {
				GtkTextIter _tmp32_;
				GtkTextTag* _tmp33_;
				GtkTextBuffer* _tmp34_;
				GtkTextBuffer* _tmp35_;
				GtkTextTag* _tmp36_;
				GtkTextIter _tmp37_;
				GtkTextIter _tmp38_;
				_tmp32_ = *location;
				end = _tmp32_;
				_tmp33_ = self->priv->tag_link;
				gtk_text_iter_forward_to_tag_toggle (&end, _tmp33_);
				_tmp34_ = gtk_text_view_get_buffer ((GtkTextView*) self);
				_tmp35_ = _tmp34_;
				_tmp36_ = self->priv->tag_link;
				_tmp37_ = start;
				_tmp38_ = end;
				gtk_text_buffer_remove_tag (_tmp35_, _tmp36_, &_tmp37_, &_tmp38_);
				xnp_hypertext_view_tag_timeout_init (self);
			}
		}
	} else {
		GtkTextTag* _tmp39_;
		gboolean _tmp40_ = FALSE;
		_tmp39_ = self->priv->tag_link;
		_tmp40_ = gtk_text_iter_ends_tag (location, _tmp39_);
		if (_tmp40_) {
			gboolean _tmp41_ = FALSE;
			gint _tmp42_;
			gboolean _tmp49_;
			_tmp42_ = len;
			if (_tmp42_ >= 1) {
				gboolean _tmp43_ = FALSE;
				const gchar* _tmp44_;
				gchar _tmp45_ = '\0';
				gboolean _tmp48_;
				_tmp44_ = text;
				_tmp45_ = string_get (_tmp44_, (glong) 0);
				if (_tmp45_ == ' ') {
					_tmp43_ = TRUE;
				} else {
					const gchar* _tmp46_;
					gchar _tmp47_ = '\0';
					_tmp46_ = text;
					_tmp47_ = string_get (_tmp46_, (glong) 0);
					_tmp43_ = _tmp47_ == '\n';
				}
				_tmp48_ = _tmp43_;
				_tmp41_ = !_tmp48_;
			} else {
				_tmp41_ = FALSE;
			}
			_tmp49_ = _tmp41_;
			if (_tmp49_) {
				GtkTextIter _tmp50_;
				GtkTextTag* _tmp51_;
				GtkTextBuffer* _tmp52_;
				GtkTextBuffer* _tmp53_;
				GtkTextTag* _tmp54_;
				GtkTextIter _tmp55_;
				GtkTextIter _tmp56_;
				_tmp50_ = *location;
				start = _tmp50_;
				_tmp51_ = self->priv->tag_link;
				gtk_text_iter_backward_to_tag_toggle (&start, _tmp51_);
				_tmp52_ = gtk_text_view_get_buffer ((GtkTextView*) self);
				_tmp53_ = _tmp52_;
				_tmp54_ = self->priv->tag_link;
				_tmp55_ = start;
				_tmp56_ = *location;
				gtk_text_buffer_remove_tag (_tmp53_, _tmp54_, &_tmp55_, &_tmp56_);
				xnp_hypertext_view_tag_timeout_init (self);
			}
		} else {
			gboolean _tmp57_ = FALSE;
			gint _tmp58_;
			gboolean _tmp61_;
			_tmp58_ = len;
			if (_tmp58_ == 1) {
				const gchar* _tmp59_;
				gchar _tmp60_ = '\0';
				_tmp59_ = text;
				_tmp60_ = string_get (_tmp59_, (glong) 0);
				_tmp57_ = _tmp60_ == '/';
			} else {
				_tmp57_ = FALSE;
			}
			_tmp61_ = _tmp57_;
			if (_tmp61_) {
				GtkTextIter _tmp62_;
				gboolean _tmp63_ = FALSE;
				gboolean _tmp64_ = FALSE;
				gboolean _tmp69_;
				_tmp62_ = *location;
				start = _tmp62_;
				_tmp64_ = gtk_text_iter_backward_chars (&start, 6);
				if (!_tmp64_) {
					_tmp63_ = TRUE;
				} else {
					GtkTextIter _tmp65_;
					const gchar* _tmp66_ = NULL;
					gchar* _tmp67_ = NULL;
					gchar* _tmp68_;
					_tmp65_ = *location;
					_tmp66_ = gtk_text_iter_get_text (&start, &_tmp65_);
					_tmp67_ = g_utf8_strdown (_tmp66_, (gssize) (-1));
					_tmp68_ = _tmp67_;
					_tmp63_ = g_strcmp0 (_tmp68_, "http:/") != 0;
					_g_free0 (_tmp68_);
				}
				_tmp69_ = _tmp63_;
				if (_tmp69_) {
					return;
				}
				xnp_hypertext_view_tag_timeout_init (self);
			} else {
				gboolean _tmp70_ = FALSE;
				gint _tmp71_;
				gboolean _tmp78_;
				_tmp71_ = len;
				if (_tmp71_ == 1) {
					gboolean _tmp72_ = FALSE;
					const gchar* _tmp73_;
					gchar _tmp74_ = '\0';
					gboolean _tmp77_;
					_tmp73_ = text;
					_tmp74_ = string_get (_tmp73_, (glong) 0);
					if (_tmp74_ == ' ') {
						_tmp72_ = TRUE;
					} else {
						const gchar* _tmp75_;
						gchar _tmp76_ = '\0';
						_tmp75_ = text;
						_tmp76_ = string_get (_tmp75_, (glong) 0);
						_tmp72_ = _tmp76_ == '\n';
					}
					_tmp77_ = _tmp72_;
					_tmp70_ = _tmp77_;
				} else {
					_tmp70_ = FALSE;
				}
				_tmp78_ = _tmp70_;
				if (_tmp78_) {
					xnp_hypertext_view_update_tags (self);
				} else {
					gboolean _tmp79_ = FALSE;
					gint _tmp80_;
					gboolean _tmp83_;
					_tmp80_ = len;
					if (_tmp80_ > 1) {
						const gchar* _tmp81_;
						gboolean _tmp82_ = FALSE;
						_tmp81_ = text;
						_tmp82_ = string_contains (_tmp81_, "http://");
						_tmp79_ = _tmp82_;
					} else {
						_tmp79_ = FALSE;
					}
					_tmp83_ = _tmp79_;
					if (_tmp83_) {
						xnp_hypertext_view_tag_timeout_init (self);
					}
				}
			}
		}
	}
}


/**
 * delete_range_cb:
 *
 * Event to delete and update existing tags within the buffer.
 */
static void xnp_hypertext_view_delete_range_cb (XnpHypertextView* self, GtkTextBuffer* buffer, GtkTextIter* start, GtkTextIter* end) {
	GtkTextIter iter = {0};
	gboolean _tmp0_ = FALSE;
	GtkTextTag* _tmp1_;
	gboolean _tmp2_ = FALSE;
	gboolean _tmp5_;
	GtkTextTag* _tmp6_;
	gboolean _tmp7_ = FALSE;
	GtkTextTag* _tmp15_;
	gboolean _tmp16_ = FALSE;
	g_return_if_fail (self != NULL);
	g_return_if_fail (buffer != NULL);
	g_return_if_fail (start != NULL);
	g_return_if_fail (end != NULL);
	_tmp1_ = self->priv->tag_link;
	_tmp2_ = gtk_text_iter_has_tag (start, _tmp1_);
	if (!_tmp2_) {
		GtkTextTag* _tmp3_;
		gboolean _tmp4_ = FALSE;
		_tmp3_ = self->priv->tag_link;
		_tmp4_ = gtk_text_iter_has_tag (end, _tmp3_);
		_tmp0_ = !_tmp4_;
	} else {
		_tmp0_ = FALSE;
	}
	_tmp5_ = _tmp0_;
	if (_tmp5_) {
		return;
	}
	_tmp6_ = self->priv->tag_link;
	_tmp7_ = gtk_text_iter_has_tag (start, _tmp6_);
	if (_tmp7_) {
		GtkTextIter _tmp8_;
		GtkTextTag* _tmp9_;
		GtkTextBuffer* _tmp10_;
		GtkTextBuffer* _tmp11_;
		GtkTextTag* _tmp12_;
		GtkTextIter _tmp13_;
		GtkTextIter _tmp14_;
		_tmp8_ = *start;
		iter = _tmp8_;
		_tmp9_ = self->priv->tag_link;
		gtk_text_iter_backward_to_tag_toggle (&iter, _tmp9_);
		_tmp10_ = gtk_text_view_get_buffer ((GtkTextView*) self);
		_tmp11_ = _tmp10_;
		_tmp12_ = self->priv->tag_link;
		_tmp13_ = iter;
		_tmp14_ = *start;
		gtk_text_buffer_remove_tag (_tmp11_, _tmp12_, &_tmp13_, &_tmp14_);
	}
	_tmp15_ = self->priv->tag_link;
	_tmp16_ = gtk_text_iter_has_tag (end, _tmp15_);
	if (_tmp16_) {
		GtkTextIter _tmp17_;
		GtkTextTag* _tmp18_;
		GtkTextBuffer* _tmp19_;
		GtkTextBuffer* _tmp20_;
		GtkTextTag* _tmp21_;
		GtkTextIter _tmp22_;
		GtkTextIter _tmp23_;
		_tmp17_ = *end;
		iter = _tmp17_;
		_tmp18_ = self->priv->tag_link;
		gtk_text_iter_forward_to_tag_toggle (&iter, _tmp18_);
		_tmp19_ = gtk_text_view_get_buffer ((GtkTextView*) self);
		_tmp20_ = _tmp19_;
		_tmp21_ = self->priv->tag_link;
		_tmp22_ = *end;
		_tmp23_ = iter;
		gtk_text_buffer_remove_tag (_tmp20_, _tmp21_, &_tmp22_, &_tmp23_);
	}
	xnp_hypertext_view_tag_timeout_init (self);
}


/**
 * undo_snapshot:
 *
 * Makes a snapshot of the current buffer and swaps undo/redo texts.
 */
static gboolean xnp_hypertext_view_undo_snapshot (XnpHypertextView* self) {
	gboolean result = FALSE;
	GtkTextIter start = {0};
	GtkTextIter end = {0};
	GtkTextBuffer* _tmp0_;
	GtkTextBuffer* _tmp1_;
	gint _tmp2_ = 0;
	gint _tmp3_;
	GtkTextBuffer* _tmp4_;
	GtkTextBuffer* _tmp5_;
	GtkTextIter _tmp6_ = {0};
	GtkTextBuffer* _tmp7_;
	GtkTextBuffer* _tmp8_;
	GtkTextIter _tmp9_ = {0};
	const gchar* _tmp10_;
	gchar* _tmp11_;
	GtkTextBuffer* _tmp12_;
	GtkTextBuffer* _tmp13_;
	GtkTextIter _tmp14_;
	GtkTextIter _tmp15_;
	gchar* _tmp16_ = NULL;
	guint _tmp17_;
	g_return_val_if_fail (self != NULL, FALSE);
	_tmp0_ = gtk_text_view_get_buffer ((GtkTextView*) self);
	_tmp1_ = _tmp0_;
	g_object_get (_tmp1_, "cursor-position", &_tmp2_, NULL);
	_tmp3_ = _tmp2_;
	self->priv->undo_cursor_pos = _tmp3_;
	_tmp4_ = gtk_text_view_get_buffer ((GtkTextView*) self);
	_tmp5_ = _tmp4_;
	gtk_text_buffer_get_iter_at_offset (_tmp5_, &_tmp6_, 0);
	start = _tmp6_;
	_tmp7_ = gtk_text_view_get_buffer ((GtkTextView*) self);
	_tmp8_ = _tmp7_;
	gtk_text_buffer_get_iter_at_offset (_tmp8_, &_tmp9_, -1);
	end = _tmp9_;
	_tmp10_ = self->priv->redo_text;
	_tmp11_ = g_strdup (_tmp10_);
	_g_free0 (self->priv->undo_text);
	self->priv->undo_text = _tmp11_;
	_tmp12_ = gtk_text_view_get_buffer ((GtkTextView*) self);
	_tmp13_ = _tmp12_;
	_tmp14_ = start;
	_tmp15_ = end;
	_tmp16_ = gtk_text_buffer_get_text (_tmp13_, &_tmp14_, &_tmp15_, FALSE);
	_g_free0 (self->priv->redo_text);
	self->priv->redo_text = _tmp16_;
	_tmp17_ = self->priv->undo_timeout;
	if (_tmp17_ > ((guint) 0)) {
		guint _tmp18_;
		_tmp18_ = self->priv->undo_timeout;
		g_source_remove (_tmp18_);
		self->priv->undo_timeout = (guint) 0;
	}
	result = FALSE;
	return result;
}


/**
 * undo:
 *
 * Revert the buffer to the undo text and swaps undo/redo texts.
 */
void xnp_hypertext_view_undo (XnpHypertextView* self) {
	GtkTextIter iter = {0};
	GtkTextMark* mark = NULL;
	gchar* tmp = NULL;
	guint _tmp0_;
	GtkTextBuffer* _tmp2_;
	GtkTextBuffer* _tmp3_;
	const gchar* _tmp4_;
	GtkTextBuffer* _tmp5_;
	GtkTextBuffer* _tmp6_;
	gint _tmp7_;
	GtkTextIter _tmp8_ = {0};
	GtkTextBuffer* _tmp9_;
	GtkTextBuffer* _tmp10_;
	GtkTextIter _tmp11_;
	GtkTextBuffer* _tmp12_;
	GtkTextBuffer* _tmp13_;
	GtkTextMark* _tmp14_ = NULL;
	GtkTextMark* _tmp15_;
	GtkTextBuffer* _tmp16_;
	GtkTextBuffer* _tmp17_;
	GtkTextMark* _tmp18_;
	GtkTextIter _tmp19_;
	GtkTextMark* _tmp20_;
	const gchar* _tmp21_;
	gchar* _tmp22_;
	const gchar* _tmp23_;
	gchar* _tmp24_;
	const gchar* _tmp25_;
	gchar* _tmp26_;
	guint _tmp27_;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->priv->undo_timeout;
	if (_tmp0_ > ((guint) 0)) {
		guint _tmp1_;
		_tmp1_ = self->priv->undo_timeout;
		g_source_remove (_tmp1_);
		self->priv->undo_timeout = (guint) 0;
		xnp_hypertext_view_undo_snapshot (self);
	}
	_tmp2_ = gtk_text_view_get_buffer ((GtkTextView*) self);
	_tmp3_ = _tmp2_;
	_tmp4_ = self->priv->undo_text;
	gtk_text_buffer_set_text (_tmp3_, _tmp4_, -1);
	_tmp5_ = gtk_text_view_get_buffer ((GtkTextView*) self);
	_tmp6_ = _tmp5_;
	_tmp7_ = self->priv->undo_cursor_pos;
	gtk_text_buffer_get_iter_at_offset (_tmp6_, &_tmp8_, _tmp7_);
	iter = _tmp8_;
	_tmp9_ = gtk_text_view_get_buffer ((GtkTextView*) self);
	_tmp10_ = _tmp9_;
	_tmp11_ = iter;
	gtk_text_buffer_place_cursor (_tmp10_, &_tmp11_);
	_tmp12_ = gtk_text_view_get_buffer ((GtkTextView*) self);
	_tmp13_ = _tmp12_;
	_tmp14_ = gtk_text_buffer_get_mark (_tmp13_, "undo-pos");
	_tmp15_ = _g_object_ref0 (_tmp14_);
	_g_object_unref0 (mark);
	mark = _tmp15_;
	_tmp16_ = gtk_text_view_get_buffer ((GtkTextView*) self);
	_tmp17_ = _tmp16_;
	_tmp18_ = mark;
	_tmp19_ = iter;
	gtk_text_buffer_move_mark (_tmp17_, _tmp18_, &_tmp19_);
	_tmp20_ = mark;
	gtk_text_view_scroll_to_mark ((GtkTextView*) self, _tmp20_, 0.0, FALSE, 0.5, 0.5);
	_tmp21_ = self->priv->undo_text;
	_tmp22_ = g_strdup (_tmp21_);
	_g_free0 (tmp);
	tmp = _tmp22_;
	_tmp23_ = self->priv->redo_text;
	_tmp24_ = g_strdup (_tmp23_);
	_g_free0 (self->priv->undo_text);
	self->priv->undo_text = _tmp24_;
	_tmp25_ = tmp;
	_tmp26_ = g_strdup (_tmp25_);
	_g_free0 (self->priv->redo_text);
	self->priv->redo_text = _tmp26_;
	_tmp27_ = self->priv->undo_timeout;
	if (_tmp27_ > ((guint) 0)) {
		guint _tmp28_;
		_tmp28_ = self->priv->undo_timeout;
		g_source_remove (_tmp28_);
		self->priv->undo_timeout = (guint) 0;
	}
	_g_free0 (tmp);
	_g_object_unref0 (mark);
}


static gboolean xnp_hypertext_view_tag_timeout_cb (XnpHypertextView* self) {
	gboolean result = FALSE;
	g_return_val_if_fail (self != NULL, FALSE);
	xnp_hypertext_view_update_tags (self);
	result = FALSE;
	return result;
}


static void xnp_hypertext_view_tag_timeout_init (XnpHypertextView* self) {
	guint _tmp0_;
	guint _tmp2_ = 0U;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->priv->tag_timeout;
	if (_tmp0_ > ((guint) 0)) {
		guint _tmp1_;
		_tmp1_ = self->priv->tag_timeout;
		g_source_remove (_tmp1_);
		self->priv->tag_timeout = (guint) 0;
	}
	_tmp2_ = g_timeout_add_seconds_full (G_PRIORITY_DEFAULT, (guint) 2, _xnp_hypertext_view_tag_timeout_cb_gsource_func, g_object_ref (self), g_object_unref);
	self->priv->tag_timeout = _tmp2_;
}


/**
 * update_tags:
 *
 * Goes through the entire document to search for untagged HTTP links and tag them.
 */
void xnp_hypertext_view_update_tags (XnpHypertextView* self) {
	GtkTextIter iter = {0};
	GtkTextIter start = {0};
	GtkTextIter end = {0};
	GtkTextIter tmp = {0};
	guint _tmp0_;
	GtkTextBuffer* _tmp2_;
	GtkTextBuffer* _tmp3_;
	GtkTextIter _tmp4_ = {0};
	g_return_if_fail (self != NULL);
	_tmp0_ = self->priv->tag_timeout;
	if (_tmp0_ > ((guint) 0)) {
		guint _tmp1_;
		_tmp1_ = self->priv->tag_timeout;
		g_source_remove (_tmp1_);
		self->priv->tag_timeout = (guint) 0;
	}
	_tmp2_ = gtk_text_view_get_buffer ((GtkTextView*) self);
	_tmp3_ = _tmp2_;
	gtk_text_buffer_get_iter_at_offset (_tmp3_, &_tmp4_, 0);
	iter = _tmp4_;
	while (TRUE) {
		GtkTextIter _tmp5_ = {0};
		GtkTextIter _tmp6_ = {0};
		gboolean _tmp7_ = FALSE;
		GtkTextIter _tmp8_;
		GtkTextTag* _tmp9_;
		gboolean _tmp10_ = FALSE;
		GtkTextIter _tmp11_ = {0};
		gboolean _tmp12_ = FALSE;
		gint _tmp23_ = 0;
		gint _tmp24_ = 0;
		_tmp7_ = gtk_text_iter_forward_search (&iter, "http://", GTK_TEXT_SEARCH_TEXT_ONLY, &_tmp5_, &_tmp6_, NULL);
		start = _tmp5_;
		end = _tmp6_;
		if (!_tmp7_) {
			break;
		}
		_tmp8_ = end;
		iter = _tmp8_;
		_tmp9_ = self->priv->tag_link;
		_tmp10_ = gtk_text_iter_begins_tag (&start, _tmp9_);
		if (_tmp10_) {
			continue;
		}
		_tmp12_ = gtk_text_iter_forward_search (&iter, " ", GTK_TEXT_SEARCH_TEXT_ONLY, &_tmp11_, NULL, NULL);
		end = _tmp11_;
		if (!_tmp12_) {
			GtkTextIter _tmp13_ = {0};
			gboolean _tmp14_ = FALSE;
			_tmp14_ = gtk_text_iter_forward_search (&iter, "\n", GTK_TEXT_SEARCH_TEXT_ONLY, &_tmp13_, NULL, NULL);
			end = _tmp13_;
			if (!_tmp14_) {
				GtkTextBuffer* _tmp15_;
				GtkTextBuffer* _tmp16_;
				GtkTextIter _tmp17_ = {0};
				_tmp15_ = gtk_text_view_get_buffer ((GtkTextView*) self);
				_tmp16_ = _tmp15_;
				gtk_text_buffer_get_iter_at_offset (_tmp16_, &_tmp17_, -1);
				end = _tmp17_;
			}
		} else {
			GtkTextIter _tmp18_ = {0};
			gboolean _tmp19_ = FALSE;
			_tmp19_ = gtk_text_iter_forward_search (&iter, "\n", GTK_TEXT_SEARCH_TEXT_ONLY, &_tmp18_, NULL, NULL);
			tmp = _tmp18_;
			if (_tmp19_) {
				gint _tmp20_ = 0;
				gint _tmp21_ = 0;
				_tmp20_ = gtk_text_iter_get_offset (&tmp);
				_tmp21_ = gtk_text_iter_get_offset (&end);
				if (_tmp20_ < _tmp21_) {
					GtkTextIter _tmp22_;
					_tmp22_ = tmp;
					end = _tmp22_;
				}
			}
		}
		_tmp23_ = gtk_text_iter_get_offset (&end);
		_tmp24_ = gtk_text_iter_get_offset (&start);
		if ((_tmp23_ - _tmp24_) >= 7) {
			GtkTextBuffer* _tmp25_;
			GtkTextBuffer* _tmp26_;
			GtkTextTag* _tmp27_;
			GtkTextIter _tmp28_;
			GtkTextIter _tmp29_;
			_tmp25_ = gtk_text_view_get_buffer ((GtkTextView*) self);
			_tmp26_ = _tmp25_;
			_tmp27_ = self->priv->tag_link;
			_tmp28_ = start;
			_tmp29_ = end;
			gtk_text_buffer_apply_tag (_tmp26_, _tmp27_, &_tmp28_, &_tmp29_);
		}
	}
}


const gchar* xnp_hypertext_view_get_font (XnpHypertextView* self) {
	const gchar* result;
	const gchar* _tmp0_;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = self->priv->_font;
	result = _tmp0_;
	return result;
}


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


void xnp_hypertext_view_set_font (XnpHypertextView* self, const gchar* value) {
	const gchar* _tmp0_;
	gchar* _tmp1_;
	const gchar* _tmp2_;
	PangoFontDescription* _tmp3_ = NULL;
	PangoFontDescription* font_descr;
	g_return_if_fail (self != NULL);
	_tmp0_ = value;
	_tmp1_ = g_strdup (_tmp0_);
	_g_free0 (self->priv->_font);
	self->priv->_font = _tmp1_;
	_tmp2_ = value;
	_tmp3_ = pango_font_description_from_string (_tmp2_);
	font_descr = _tmp3_;
	gtk_widget_modify_font ((GtkWidget*) self, font_descr);
	__vala_PangoFontDescription_free0 (font_descr);
	g_object_notify ((GObject *) self, "font");
}


static void _vala_PangoTabArray_free (PangoTabArray* self) {
	g_boxed_free (pango_tab_array_get_type (), self);
}


static GObject * xnp_hypertext_view_constructor (GType type, guint n_construct_properties, GObjectConstructParam * construct_properties) {
	GObject * obj;
	GObjectClass * parent_class;
	XnpHypertextView * self;
	PangoTabArray* _tmp0_;
	PangoTabArray* _tmp1_;
	parent_class = G_OBJECT_CLASS (xnp_hypertext_view_parent_class);
	obj = parent_class->constructor (type, n_construct_properties, construct_properties);
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, XNP_TYPE_HYPERTEXT_VIEW, XnpHypertextView);
	xnp_hypertext_view_set_font (self, "Sans 13");
	_tmp0_ = pango_tab_array_new_with_positions (1, TRUE, PANGO_TAB_LEFT, 12, NULL);
	_tmp1_ = _tmp0_;
	gtk_text_view_set_tabs ((GtkTextView*) self, _tmp1_);
	__vala_PangoTabArray_free0 (_tmp1_);
	return obj;
}


static void xnp_hypertext_view_class_init (XnpHypertextViewClass * klass) {
	xnp_hypertext_view_parent_class = g_type_class_peek_parent (klass);
	g_type_class_add_private (klass, sizeof (XnpHypertextViewPrivate));
	G_OBJECT_CLASS (klass)->get_property = _vala_xnp_hypertext_view_get_property;
	G_OBJECT_CLASS (klass)->set_property = _vala_xnp_hypertext_view_set_property;
	G_OBJECT_CLASS (klass)->constructor = xnp_hypertext_view_constructor;
	G_OBJECT_CLASS (klass)->finalize = xnp_hypertext_view_finalize;
	g_object_class_install_property (G_OBJECT_CLASS (klass), XNP_HYPERTEXT_VIEW_FONT, g_param_spec_string ("font", "font", "font", NULL, G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_READABLE | G_PARAM_WRITABLE));
}


static void xnp_hypertext_view_instance_init (XnpHypertextView * self) {
	GdkCursor* _tmp0_;
	GdkCursor* _tmp1_;
	gchar* _tmp2_;
	gchar* _tmp3_;
	self->priv = XNP_HYPERTEXT_VIEW_GET_PRIVATE (self);
	_tmp0_ = gdk_cursor_new (GDK_HAND2);
	self->priv->hand_cursor = _tmp0_;
	_tmp1_ = gdk_cursor_new (GDK_XTERM);
	self->priv->regular_cursor = _tmp1_;
	self->priv->cursor_over_link = FALSE;
	self->priv->undo_timeout = (guint) 0;
	_tmp2_ = g_strdup ("");
	self->priv->undo_text = _tmp2_;
	_tmp3_ = g_strdup ("");
	self->priv->redo_text = _tmp3_;
	self->priv->tag_timeout = (guint) 0;
}


static void xnp_hypertext_view_finalize (GObject* obj) {
	XnpHypertextView * self;
	guint _tmp0_;
	guint _tmp2_;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, XNP_TYPE_HYPERTEXT_VIEW, XnpHypertextView);
	_tmp0_ = self->priv->undo_timeout;
	if (_tmp0_ != ((guint) 0)) {
		guint _tmp1_;
		_tmp1_ = self->priv->undo_timeout;
		g_source_remove (_tmp1_);
	}
	_tmp2_ = self->priv->tag_timeout;
	if (_tmp2_ != ((guint) 0)) {
		guint _tmp3_;
		_tmp3_ = self->priv->tag_timeout;
		g_source_remove (_tmp3_);
	}
	_gdk_cursor_unref0 (self->priv->hand_cursor);
	_gdk_cursor_unref0 (self->priv->regular_cursor);
	_g_free0 (self->priv->undo_text);
	_g_free0 (self->priv->redo_text);
	_g_object_unref0 (self->priv->tag_link);
	_g_free0 (self->priv->_font);
	G_OBJECT_CLASS (xnp_hypertext_view_parent_class)->finalize (obj);
}


GType xnp_hypertext_view_get_type (void) {
	static volatile gsize xnp_hypertext_view_type_id__volatile = 0;
	if (g_once_init_enter (&xnp_hypertext_view_type_id__volatile)) {
		static const GTypeInfo g_define_type_info = { sizeof (XnpHypertextViewClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) xnp_hypertext_view_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (XnpHypertextView), 0, (GInstanceInitFunc) xnp_hypertext_view_instance_init, NULL };
		GType xnp_hypertext_view_type_id;
		xnp_hypertext_view_type_id = g_type_register_static (GTK_TYPE_TEXT_VIEW, "XnpHypertextView", &g_define_type_info, 0);
		g_once_init_leave (&xnp_hypertext_view_type_id__volatile, xnp_hypertext_view_type_id);
	}
	return xnp_hypertext_view_type_id__volatile;
}


static void _vala_xnp_hypertext_view_get_property (GObject * object, guint property_id, GValue * value, GParamSpec * pspec) {
	XnpHypertextView * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (object, XNP_TYPE_HYPERTEXT_VIEW, XnpHypertextView);
	switch (property_id) {
		case XNP_HYPERTEXT_VIEW_FONT:
		g_value_set_string (value, xnp_hypertext_view_get_font (self));
		break;
		default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
	}
}


static void _vala_xnp_hypertext_view_set_property (GObject * object, guint property_id, const GValue * value, GParamSpec * pspec) {
	XnpHypertextView * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (object, XNP_TYPE_HYPERTEXT_VIEW, XnpHypertextView);
	switch (property_id) {
		case XNP_HYPERTEXT_VIEW_FONT:
		xnp_hypertext_view_set_font (self, g_value_get_string (value));
		break;
		default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
	}
}



