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

/*
* Copyright (c) 2017 Felipe Escoto (https://github.com/Philip-Scott/Notes-up)
*
* 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
* 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., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*
* Authored by: Natan Streppel <streppels at gmail.com>
*/

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

#if !defined(VALA_STRICT_C)
#if !defined(__clang__) && defined(__GNUC__) && (__GNUC__ >= 14)
#pragma GCC diagnostic warning "-Wincompatible-pointer-types"
#elif defined(__clang__) && (__clang_major__ >= 16)
#pragma clang diagnostic ignored "-Wincompatible-function-pointer-types"
#pragma clang diagnostic ignored "-Wincompatible-pointer-types"
#endif
#endif
#if !defined(VALA_EXTERN)
#if defined(_MSC_VER)
#define VALA_EXTERN __declspec(dllexport) extern
#elif __GNUC__ >= 4
#define VALA_EXTERN __attribute__((visibility("default"))) extern
#else
#define VALA_EXTERN extern
#endif
#endif

#define TYPE_WORD_WRAPPER (word_wrapper_get_type ())
#define WORD_WRAPPER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_WORD_WRAPPER, WordWrapper))
#define WORD_WRAPPER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_WORD_WRAPPER, WordWrapperClass))
#define IS_WORD_WRAPPER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_WORD_WRAPPER))
#define IS_WORD_WRAPPER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_WORD_WRAPPER))
#define WORD_WRAPPER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_WORD_WRAPPER, WordWrapperClass))

typedef struct _WordWrapper WordWrapper;
typedef struct _WordWrapperClass WordWrapperClass;
typedef struct _WordWrapperPrivate WordWrapperPrivate;
enum  {
	WORD_WRAPPER_0_PROPERTY,
	WORD_WRAPPER_NUM_PROPERTIES
};
static GParamSpec* word_wrapper_properties[WORD_WRAPPER_NUM_PROPERTIES];
#define _g_free0(var) (var = (g_free (var), NULL))
#define _g_match_info_unref0(var) ((var == NULL) ? NULL : (var = (g_match_info_unref (var), NULL)))
#define _g_regex_unref0(var) ((var == NULL) ? NULL : (var = (g_regex_unref (var), NULL)))

struct _WordWrapper {
	GObject parent_instance;
	WordWrapperPrivate * priv;
};

struct _WordWrapperClass {
	GObjectClass parent_class;
};

static gpointer word_wrapper_parent_class = NULL;
static GRegex* word_wrapper_starting_whitespaces_regex;
static GRegex* word_wrapper_starting_whitespaces_regex = NULL;
static GRegex* word_wrapper_ending_whitespaces_regex;
static GRegex* word_wrapper_ending_whitespaces_regex = NULL;

VALA_EXTERN GType word_wrapper_get_type (void) G_GNUC_CONST ;
G_DEFINE_AUTOPTR_CLEANUP_FUNC (WordWrapper, g_object_unref)
VALA_EXTERN gchar* word_wrapper_identify_word (GtkTextIter* start,
                                   GtkTextIter* end,
                                   const gchar* first_half,
                                   const gchar* second_half);
static void word_wrapper_detect_edges (GtkTextIter* start,
                                GtkTextIter* end,
                                const gchar* first_half,
                                const gchar* second_half);
VALA_EXTERN gchar* word_wrapper_wrap_string (const gchar* original_text,
                                 const gchar* first_half,
                                 const gchar* second_half);
static void word_wrapper_save_surrouding_spaces (const gchar* text,
                                          gchar** leading_spaces,
                                          gchar** trailing_spaces);
static gboolean word_wrapper_already_wrapped (const gchar* text,
                                       const gchar* first_half,
                                       const gchar* second_half);
static gchar* word_wrapper_get_return_string (const gchar* text,
                                       const gchar* leading_spaces,
                                       const gchar* trailing_spaces);
static gboolean word_wrapper_no_edges (GtkTextIter* iter);
static void word_wrapper_detects_wrapping (GtkTextIter* start,
                                    GtkTextIter* end,
                                    const gchar* first_half,
                                    const gchar* second_half);
static gboolean word_wrapper_opens_wrapping (GtkTextIter* iter,
                                      const gchar* first_half,
                                      const gchar* second_half);
static void word_wrapper_forwards_iter_until_whitespace (GtkTextIter* iter,
                                                  gint n);
static gboolean word_wrapper_closes_wrapping (GtkTextIter* iter,
                                       const gchar* first_half,
                                       const gchar* second_half);
static void word_wrapper_forwards_iter_to_whitespace (GtkTextIter* iter,
                                               gint n);
static gboolean word_wrapper_iter_is_followed_by (GtkTextIter* iter,
                                           const gchar* text);
static gboolean word_wrapper_word_ends_with (GtkTextIter* iter,
                                      const gchar* tag);
static gboolean word_wrapper_iter_starts_after (GtkTextIter* iter,
                                         const gchar* text);
static gboolean word_wrapper_word_starts_with (GtkTextIter* iter,
                                        const gchar* tag);
static gboolean __lambda11_ (gunichar c);
static gboolean ___lambda11__gtk_text_char_predicate (gunichar ch,
                                               gpointer self);
static gboolean __lambda12_ (gunichar c);
static gboolean ___lambda12__gtk_text_char_predicate (gunichar ch,
                                               gpointer self);
VALA_EXTERN WordWrapper* word_wrapper_new (void);
VALA_EXTERN WordWrapper* word_wrapper_construct (GType object_type);
static void word_wrapper_finalize (GObject * obj);
static GType word_wrapper_get_type_once (void);
static inline gpointer _vala_memdup2 (gconstpointer mem,
                        gsize byte_size);

/**
     * Moves start and end iterators to the beggining and end of an word, respectively, additionaly
     * with its wrappers, if present.
     * Retuns the found string.
     */
gchar*
word_wrapper_identify_word (GtkTextIter* start,
                            GtkTextIter* end,
                            const gchar* first_half,
                            const gchar* second_half)
{
	GtkTextIter _tmp0_;
	gchar* _tmp1_;
	gchar* result;
	g_return_val_if_fail (start != NULL, NULL);
	g_return_val_if_fail (end != NULL, NULL);
	g_return_val_if_fail (first_half != NULL, NULL);
	g_return_val_if_fail (second_half != NULL, NULL);
	word_wrapper_detect_edges (start, end, first_half, second_half);
	_tmp0_ = *end;
	_tmp1_ = gtk_text_iter_get_text (start, &_tmp0_);
	result = _tmp1_;
	return result;
}

/**
     * Wraps this instance's text with first and second halves.
     * Unwraps this instance's text element if already wrapped with first and second halves.
     */
static gchar*
string_strip (const gchar* self)
{
	gchar* _result_ = NULL;
	gchar* _tmp0_;
	gchar* result;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = g_strdup (self);
	_result_ = _tmp0_;
	g_strstrip (_result_);
	result = _result_;
	return result;
}

static gint
string_last_index_of (const gchar* self,
                      const gchar* needle,
                      gint start_index)
{
	gchar* _result_ = NULL;
	gchar* _tmp0_;
	gchar* _tmp1_;
	gint result;
	g_return_val_if_fail (self != NULL, -1);
	g_return_val_if_fail (needle != NULL, -1);
	_tmp0_ = g_strrstr (((gchar*) self) + start_index, (gchar*) needle);
	_result_ = _tmp0_;
	_tmp1_ = _result_;
	if (_tmp1_ != NULL) {
		gchar* _tmp2_;
		_tmp2_ = _result_;
		result = (gint) (_tmp2_ - ((gchar*) self));
		return result;
	} else {
		result = -1;
		return result;
	}
}

static glong
string_strnlen (gchar* str,
                glong maxlen)
{
	gchar* end = NULL;
	gchar* _tmp0_;
	gchar* _tmp1_;
	glong result;
	_tmp0_ = memchr (str, 0, (gsize) maxlen);
	end = _tmp0_;
	_tmp1_ = end;
	if (_tmp1_ == NULL) {
		result = maxlen;
		return result;
	} else {
		gchar* _tmp2_;
		_tmp2_ = end;
		result = (glong) (_tmp2_ - str);
		return result;
	}
}

static gchar*
string_substring (const gchar* self,
                  glong offset,
                  glong len)
{
	glong string_length = 0L;
	gboolean _tmp0_ = FALSE;
	gchar* _tmp3_;
	gchar* result;
	g_return_val_if_fail (self != NULL, NULL);
	if (offset >= ((glong) 0)) {
		_tmp0_ = len >= ((glong) 0);
	} else {
		_tmp0_ = FALSE;
	}
	if (_tmp0_) {
		string_length = string_strnlen ((gchar*) self, offset + len);
	} else {
		gint _tmp1_;
		gint _tmp2_;
		_tmp1_ = strlen (self);
		_tmp2_ = _tmp1_;
		string_length = (glong) _tmp2_;
	}
	if (offset < ((glong) 0)) {
		offset = string_length + offset;
		g_return_val_if_fail (offset >= ((glong) 0), NULL);
	} else {
		g_return_val_if_fail (offset <= string_length, NULL);
	}
	if (len < ((glong) 0)) {
		len = string_length - offset;
	}
	g_return_val_if_fail ((offset + len) <= string_length, NULL);
	_tmp3_ = g_strndup (((gchar*) self) + offset, (gsize) len);
	result = _tmp3_;
	return result;
}

gchar*
word_wrapper_wrap_string (const gchar* original_text,
                          const gchar* first_half,
                          const gchar* second_half)
{
	gchar* leading_spaces = NULL;
	gchar* _tmp0_;
	gchar* trailing_spaces = NULL;
	gchar* _tmp1_;
	gchar* text = NULL;
	gchar* _tmp2_;
	const gchar* _tmp3_;
	gchar* result;
	g_return_val_if_fail (original_text != NULL, NULL);
	g_return_val_if_fail (first_half != NULL, NULL);
	g_return_val_if_fail (second_half != NULL, NULL);
	_tmp0_ = g_strdup ("");
	leading_spaces = _tmp0_;
	_tmp1_ = g_strdup ("");
	trailing_spaces = _tmp1_;
	word_wrapper_save_surrouding_spaces (original_text, &leading_spaces, &trailing_spaces);
	_tmp2_ = string_strip (original_text);
	text = _tmp2_;
	_tmp3_ = text;
	if (word_wrapper_already_wrapped (_tmp3_, first_half, second_half)) {
		gint head = 0;
		gint tail = 0;
		const gchar* _tmp4_;
		const gchar* _tmp5_;
		gint _tmp6_;
		gint _tmp7_;
		gint _tmp8_;
		gint _tmp9_;
		const gchar* _tmp10_;
		gchar* _tmp11_;
		gchar* _tmp12_;
		const gchar* _tmp13_;
		const gchar* _tmp14_;
		gchar* _tmp15_;
		gchar* _tmp16_;
		head = g_utf8_strlen (first_half, (gssize) -1);
		_tmp4_ = text;
		_tmp5_ = text;
		_tmp6_ = strlen (_tmp5_);
		_tmp7_ = _tmp6_;
		_tmp8_ = strlen (second_half);
		_tmp9_ = _tmp8_;
		tail = string_last_index_of (_tmp4_, second_half, _tmp7_ - _tmp9_);
		_tmp10_ = text;
		_tmp11_ = string_substring (_tmp10_, (glong) head, (glong) (tail - head));
		_tmp12_ = _tmp11_;
		_tmp13_ = leading_spaces;
		_tmp14_ = trailing_spaces;
		_tmp15_ = word_wrapper_get_return_string (_tmp12_, _tmp13_, _tmp14_);
		_tmp16_ = _tmp15_;
		_g_free0 (_tmp12_);
		result = _tmp16_;
		_g_free0 (text);
		_g_free0 (trailing_spaces);
		_g_free0 (leading_spaces);
		return result;
	} else {
		const gchar* _tmp17_;
		gchar* _tmp18_;
		gchar* _tmp19_;
		gchar* _tmp20_;
		gchar* _tmp21_;
		const gchar* _tmp22_;
		const gchar* _tmp23_;
		gchar* _tmp24_;
		gchar* _tmp25_;
		_tmp17_ = text;
		_tmp18_ = g_strconcat (first_half, _tmp17_, NULL);
		_tmp19_ = _tmp18_;
		_tmp20_ = g_strconcat (_tmp19_, second_half, NULL);
		_tmp21_ = _tmp20_;
		_tmp22_ = leading_spaces;
		_tmp23_ = trailing_spaces;
		_tmp24_ = word_wrapper_get_return_string (_tmp21_, _tmp22_, _tmp23_);
		_tmp25_ = _tmp24_;
		_g_free0 (_tmp21_);
		_g_free0 (_tmp19_);
		result = _tmp25_;
		_g_free0 (text);
		_g_free0 (trailing_spaces);
		_g_free0 (leading_spaces);
		return result;
	}
}

/**
     * Returns the given stripped string with its leading and trailing whitespaces back on
     */
static gchar*
word_wrapper_get_return_string (const gchar* text,
                                const gchar* leading_spaces,
                                const gchar* trailing_spaces)
{
	gchar* _tmp0_;
	gchar* _tmp1_;
	gchar* _tmp2_;
	gchar* _tmp3_;
	gchar* result;
	g_return_val_if_fail (text != NULL, NULL);
	g_return_val_if_fail (leading_spaces != NULL, NULL);
	g_return_val_if_fail (trailing_spaces != NULL, NULL);
	_tmp0_ = g_strconcat (leading_spaces, text, NULL);
	_tmp1_ = _tmp0_;
	_tmp2_ = g_strconcat (_tmp1_, trailing_spaces, NULL);
	_tmp3_ = _tmp2_;
	_g_free0 (_tmp1_);
	result = _tmp3_;
	return result;
}

/**
     * Counts the number of whitespace characters to the left and right of a given text
     */
static void
word_wrapper_save_surrouding_spaces (const gchar* text,
                                     gchar** leading_spaces,
                                     gchar** trailing_spaces)
{
	GMatchInfo* match_info = NULL;
	GRegex* _tmp0_;
	GMatchInfo* _tmp1_ = NULL;
	GMatchInfo* _tmp2_;
	GRegex* _tmp5_;
	GMatchInfo* _tmp6_ = NULL;
	GMatchInfo* _tmp7_;
	g_return_if_fail (text != NULL);
	g_return_if_fail (*leading_spaces != NULL);
	g_return_if_fail (*trailing_spaces != NULL);
	_tmp0_ = word_wrapper_starting_whitespaces_regex;
	g_regex_match (_tmp0_, text, 0, &_tmp1_);
	_g_match_info_unref0 (match_info);
	match_info = _tmp1_;
	_tmp2_ = match_info;
	if (g_match_info_matches (_tmp2_)) {
		GMatchInfo* _tmp3_;
		gchar* _tmp4_;
		_tmp3_ = match_info;
		_tmp4_ = g_match_info_fetch (_tmp3_, 0);
		_g_free0 (*leading_spaces);
		*leading_spaces = _tmp4_;
	}
	_tmp5_ = word_wrapper_ending_whitespaces_regex;
	g_regex_match (_tmp5_, text, 0, &_tmp6_);
	_g_match_info_unref0 (match_info);
	match_info = _tmp6_;
	_tmp7_ = match_info;
	if (g_match_info_matches (_tmp7_)) {
		GMatchInfo* _tmp8_;
		gchar* _tmp9_;
		_tmp8_ = match_info;
		_tmp9_ = g_match_info_fetch (_tmp8_, 0);
		_g_free0 (*trailing_spaces);
		*trailing_spaces = _tmp9_;
	}
	_g_match_info_unref0 (match_info);
}

/**
     * Adjusts iterators to surround a word or its wrappers if present
     */
static void
word_wrapper_detect_edges (GtkTextIter* start,
                           GtkTextIter* end,
                           const gchar* first_half,
                           const gchar* second_half)
{
	GtkTextIter _tmp0_;
	gboolean _tmp1_ = FALSE;
	gboolean _tmp2_ = FALSE;
	g_return_if_fail (start != NULL);
	g_return_if_fail (end != NULL);
	g_return_if_fail (first_half != NULL);
	g_return_if_fail (second_half != NULL);
	_tmp0_ = *end;
	if (word_wrapper_no_edges (&_tmp0_)) {
		return;
	}
	if (g_unichar_isalnum (gtk_text_iter_get_char (start))) {
		_tmp2_ = TRUE;
	} else {
		_tmp2_ = g_unichar_isspace (gtk_text_iter_get_char (end));
	}
	if (_tmp2_) {
		_tmp1_ = TRUE;
	} else {
		_tmp1_ = gtk_text_iter_ends_line (end);
	}
	if (_tmp1_) {
		if (!gtk_text_iter_starts_word (start)) {
			gtk_text_iter_backward_word_start (start);
		}
		if (!gtk_text_iter_ends_word (end)) {
			gtk_text_iter_forward_word_end (end);
		}
	}
	word_wrapper_detects_wrapping (start, end, first_half, second_half);
}

/**
     * Detects if iterators' pointed text is surrounded by first and second halves
     */
static void
word_wrapper_detects_wrapping (GtkTextIter* start,
                               GtkTextIter* end,
                               const gchar* first_half,
                               const gchar* second_half)
{
	GtkTextIter _tmp0_;
	g_return_if_fail (start != NULL);
	g_return_if_fail (end != NULL);
	g_return_if_fail (first_half != NULL);
	g_return_if_fail (second_half != NULL);
	_tmp0_ = *start;
	if (word_wrapper_opens_wrapping (&_tmp0_, first_half, second_half)) {
		gint _tmp1_;
		gint _tmp2_;
		GtkTextIter _tmp3_;
		gint _tmp4_;
		gint _tmp5_;
		_tmp1_ = strlen (first_half);
		_tmp2_ = _tmp1_;
		word_wrapper_forwards_iter_until_whitespace (start, _tmp2_);
		_tmp3_ = *start;
		*end = _tmp3_;
		gtk_text_iter_forward_visible_word_end (end);
		_tmp4_ = strlen (second_half);
		_tmp5_ = _tmp4_;
		gtk_text_iter_forward_chars (end, _tmp5_);
	} else {
		GtkTextIter _tmp6_;
		_tmp6_ = *end;
		if (word_wrapper_closes_wrapping (&_tmp6_, first_half, second_half)) {
			gint _tmp7_;
			gint _tmp8_;
			GtkTextIter _tmp9_;
			gint _tmp10_;
			gint _tmp11_;
			_tmp7_ = strlen (second_half);
			_tmp8_ = _tmp7_;
			word_wrapper_forwards_iter_to_whitespace (end, _tmp8_);
			_tmp9_ = *end;
			*start = _tmp9_;
			gtk_text_iter_backward_visible_word_start (start);
			_tmp10_ = strlen (first_half);
			_tmp11_ = _tmp10_;
			gtk_text_iter_backward_chars (start, _tmp11_);
		}
	}
}

/**
     * Detects if current word pointed by iter is an opening tag that wraps a word
     */
static gboolean
word_wrapper_opens_wrapping (GtkTextIter* iter,
                             const gchar* first_half,
                             const gchar* second_half)
{
	gint _tmp0_;
	gint _tmp1_;
	gboolean _tmp2_ = FALSE;
	GtkTextIter _tmp3_;
	gboolean result;
	g_return_val_if_fail (iter != NULL, FALSE);
	g_return_val_if_fail (first_half != NULL, FALSE);
	g_return_val_if_fail (second_half != NULL, FALSE);
	_tmp0_ = strlen (first_half);
	_tmp1_ = _tmp0_;
	word_wrapper_forwards_iter_until_whitespace (iter, _tmp1_);
	_tmp3_ = *iter;
	if (word_wrapper_iter_is_followed_by (&_tmp3_, first_half)) {
		GtkTextIter _tmp4_;
		_tmp4_ = *iter;
		_tmp2_ = word_wrapper_word_ends_with (&_tmp4_, second_half);
	} else {
		_tmp2_ = FALSE;
	}
	result = _tmp2_;
	return result;
}

/**
     * Detects if current word pointed by iter is a closing tag that wraps a word
     */
static gboolean
word_wrapper_closes_wrapping (GtkTextIter* iter,
                              const gchar* first_half,
                              const gchar* second_half)
{
	gint _tmp0_;
	gint _tmp1_;
	gboolean _tmp2_ = FALSE;
	GtkTextIter _tmp3_;
	gboolean result;
	g_return_val_if_fail (iter != NULL, FALSE);
	g_return_val_if_fail (first_half != NULL, FALSE);
	g_return_val_if_fail (second_half != NULL, FALSE);
	_tmp0_ = strlen (second_half);
	_tmp1_ = _tmp0_;
	word_wrapper_forwards_iter_to_whitespace (iter, _tmp1_);
	_tmp3_ = *iter;
	if (word_wrapper_iter_starts_after (&_tmp3_, second_half)) {
		GtkTextIter _tmp4_;
		_tmp4_ = *iter;
		_tmp2_ = word_wrapper_word_starts_with (&_tmp4_, first_half);
	} else {
		_tmp2_ = FALSE;
	}
	result = _tmp2_;
	return result;
}

/**
     * Backwards an iterator up to n times searching for a whitespace
     */
static gboolean
__lambda11_ (gunichar c)
{
	gboolean result;
	result = g_unichar_isspace (c);
	return result;
}

static gboolean
___lambda11__gtk_text_char_predicate (gunichar ch,
                                      gpointer self)
{
	gboolean result;
	result = __lambda11_ (ch);
	return result;
}

static void
word_wrapper_forwards_iter_until_whitespace (GtkTextIter* iter,
                                             gint n)
{
	GtkTextIter search_limit = {0};
	GtkTextIter _tmp0_;
	GtkTextIter _tmp1_;
	g_return_if_fail (iter != NULL);
	_tmp0_ = *iter;
	search_limit = _tmp0_;
	gtk_text_iter_backward_chars (&search_limit, n + 1);
	_tmp1_ = search_limit;
	gtk_text_iter_backward_find_char (iter, ___lambda11__gtk_text_char_predicate, NULL, &_tmp1_);
	if (g_unichar_isspace (gtk_text_iter_get_char (iter))) {
		gtk_text_iter_forward_char (iter);
	}
}

/**
     * Forwards an iterator up to n times searching for a whitespace
     */
static gboolean
__lambda12_ (gunichar c)
{
	gboolean result;
	result = g_unichar_isspace (c);
	return result;
}

static gboolean
___lambda12__gtk_text_char_predicate (gunichar ch,
                                      gpointer self)
{
	gboolean result;
	result = __lambda12_ (ch);
	return result;
}

static void
word_wrapper_forwards_iter_to_whitespace (GtkTextIter* iter,
                                          gint n)
{
	GtkTextIter search_limit = {0};
	GtkTextIter _tmp0_;
	GtkTextIter _tmp1_;
	g_return_if_fail (iter != NULL);
	_tmp0_ = *iter;
	search_limit = _tmp0_;
	gtk_text_iter_forward_chars (&search_limit, n + 1);
	_tmp1_ = search_limit;
	gtk_text_iter_forward_find_char (iter, ___lambda12__gtk_text_char_predicate, NULL, &_tmp1_);
}

/**
     * Detects if the word pointed by the iterator is prefixed with tag
     */
static gboolean
word_wrapper_word_ends_with (GtkTextIter* iter,
                             const gchar* tag)
{
	GtkTextIter _tmp0_;
	gboolean result;
	g_return_val_if_fail (iter != NULL, FALSE);
	g_return_val_if_fail (tag != NULL, FALSE);
	gtk_text_iter_forward_visible_word_end (iter);
	_tmp0_ = *iter;
	result = word_wrapper_iter_is_followed_by (&_tmp0_, tag);
	return result;
}

/**
     * Detects if the word pointed by the iterator is prefixed with tag
     */
static gboolean
word_wrapper_word_starts_with (GtkTextIter* iter,
                               const gchar* tag)
{
	GtkTextIter _tmp0_;
	gboolean result;
	g_return_val_if_fail (iter != NULL, FALSE);
	g_return_val_if_fail (tag != NULL, FALSE);
	gtk_text_iter_backward_visible_word_start (iter);
	_tmp0_ = *iter;
	result = word_wrapper_iter_starts_after (&_tmp0_, tag);
	return result;
}

/**
     * Checks if a text iterator starts after parameter text
     */
static gboolean
word_wrapper_iter_starts_after (GtkTextIter* iter,
                                const gchar* text)
{
	GtkTextIter peek_surroundings = {0};
	GtkTextIter _tmp0_;
	gint _tmp1_;
	gint _tmp2_;
	GtkTextIter _tmp3_;
	gchar* _tmp4_;
	gchar* _tmp5_;
	gboolean _tmp6_;
	gboolean result;
	g_return_val_if_fail (iter != NULL, FALSE);
	g_return_val_if_fail (text != NULL, FALSE);
	_tmp0_ = *iter;
	peek_surroundings = _tmp0_;
	_tmp1_ = strlen (text);
	_tmp2_ = _tmp1_;
	gtk_text_iter_backward_chars (&peek_surroundings, _tmp2_);
	_tmp3_ = *iter;
	_tmp4_ = gtk_text_iter_get_text (&peek_surroundings, &_tmp3_);
	_tmp5_ = _tmp4_;
	_tmp6_ = g_strcmp0 (_tmp5_, text) == 0;
	_g_free0 (_tmp5_);
	result = _tmp6_;
	return result;
}

/**
     * Checks if a text iterator is followed by parameter text
     */
static gboolean
word_wrapper_iter_is_followed_by (GtkTextIter* iter,
                                  const gchar* text)
{
	GtkTextIter peek_surroundings = {0};
	GtkTextIter _tmp0_;
	gint _tmp1_;
	gint _tmp2_;
	GtkTextIter _tmp3_;
	gchar* _tmp4_;
	gchar* _tmp5_;
	gboolean _tmp6_;
	gboolean result;
	g_return_val_if_fail (iter != NULL, FALSE);
	g_return_val_if_fail (text != NULL, FALSE);
	_tmp0_ = *iter;
	peek_surroundings = _tmp0_;
	_tmp1_ = strlen (text);
	_tmp2_ = _tmp1_;
	gtk_text_iter_forward_chars (&peek_surroundings, _tmp2_);
	_tmp3_ = *iter;
	_tmp4_ = gtk_text_iter_get_text (&peek_surroundings, &_tmp3_);
	_tmp5_ = _tmp4_;
	_tmp6_ = g_strcmp0 (_tmp5_, text) == 0;
	_g_free0 (_tmp5_);
	result = _tmp6_;
	return result;
}

/**
     * Detects if iter is in between two whitespaces
     */
static gboolean
word_wrapper_no_edges (GtkTextIter* iter)
{
	gboolean previous_value = FALSE;
	gboolean _tmp0_ = FALSE;
	gboolean _tmp1_ = FALSE;
	gboolean result;
	g_return_val_if_fail (iter != NULL, FALSE);
	previous_value = g_unichar_isspace (gtk_text_iter_get_char (iter));
	gtk_text_iter_backward_char (iter);
	if (g_unichar_isspace (gtk_text_iter_get_char (iter))) {
		_tmp1_ = previous_value;
	} else {
		_tmp1_ = FALSE;
	}
	if (_tmp1_) {
		_tmp0_ = TRUE;
	} else {
		_tmp0_ = FALSE;
	}
	result = _tmp0_;
	return result;
}

static gboolean
word_wrapper_already_wrapped (const gchar* text,
                              const gchar* first_half,
                              const gchar* second_half)
{
	gboolean _tmp0_ = FALSE;
	gboolean result;
	g_return_val_if_fail (text != NULL, FALSE);
	g_return_val_if_fail (first_half != NULL, FALSE);
	g_return_val_if_fail (second_half != NULL, FALSE);
	if (g_str_has_prefix (text, first_half)) {
		_tmp0_ = g_str_has_suffix (text, second_half);
	} else {
		_tmp0_ = FALSE;
	}
	result = _tmp0_;
	return result;
}

WordWrapper*
word_wrapper_construct (GType object_type)
{
	WordWrapper * self = NULL;
	self = (WordWrapper*) g_object_new (object_type, NULL);
	return self;
}

WordWrapper*
word_wrapper_new (void)
{
	return word_wrapper_construct (TYPE_WORD_WRAPPER);
}

static void
word_wrapper_class_init (WordWrapperClass * klass,
                         gpointer klass_data)
{
	GRegex* _tmp0_ = NULL;
	GRegex* _tmp1_;
	GRegex* _tmp2_;
	GRegex* _tmp3_ = NULL;
	GRegex* _tmp4_;
	GRegex* _tmp5_;
	GError* _inner_error0_ = NULL;
	word_wrapper_parent_class = g_type_class_peek_parent (klass);
	G_OBJECT_CLASS (klass)->finalize = word_wrapper_finalize;
	_tmp1_ = g_regex_new ("^(\\s)+", G_REGEX_EXTENDED, 0, &_inner_error0_);
	_tmp0_ = _tmp1_;
	if (G_UNLIKELY (_inner_error0_ != NULL)) {
		g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error0_->message, g_quark_to_string (_inner_error0_->domain), _inner_error0_->code);
		g_clear_error (&_inner_error0_);
	}
	_tmp2_ = _tmp0_;
	_tmp0_ = NULL;
	_g_regex_unref0 (word_wrapper_starting_whitespaces_regex);
	word_wrapper_starting_whitespaces_regex = _tmp2_;
	_tmp4_ = g_regex_new ("(\\s)+$", G_REGEX_EXTENDED, 0, &_inner_error0_);
	_tmp3_ = _tmp4_;
	if (G_UNLIKELY (_inner_error0_ != NULL)) {
		_g_regex_unref0 (_tmp0_);
		g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error0_->message, g_quark_to_string (_inner_error0_->domain), _inner_error0_->code);
		g_clear_error (&_inner_error0_);
	}
	_tmp5_ = _tmp3_;
	_tmp3_ = NULL;
	_g_regex_unref0 (word_wrapper_ending_whitespaces_regex);
	word_wrapper_ending_whitespaces_regex = _tmp5_;
	_g_regex_unref0 (_tmp3_);
	_g_regex_unref0 (_tmp0_);
}

static void
word_wrapper_instance_init (WordWrapper * self,
                            gpointer klass)
{
}

static void
word_wrapper_finalize (GObject * obj)
{
	WordWrapper * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, TYPE_WORD_WRAPPER, WordWrapper);
	G_OBJECT_CLASS (word_wrapper_parent_class)->finalize (obj);
}

/**
 * This class handles the wrapping logic for a given text within the bounds of 
 * two informed strings, which act as "string wrappers" for the text 
 */
static GType
word_wrapper_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (WordWrapperClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) word_wrapper_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (WordWrapper), 0, (GInstanceInitFunc) word_wrapper_instance_init, NULL };
	GType word_wrapper_type_id;
	word_wrapper_type_id = g_type_register_static (G_TYPE_OBJECT, "WordWrapper", &g_define_type_info, 0);
	return word_wrapper_type_id;
}

GType
word_wrapper_get_type (void)
{
	static volatile gsize word_wrapper_type_id__once = 0;
	if (g_once_init_enter (&word_wrapper_type_id__once)) {
		GType word_wrapper_type_id;
		word_wrapper_type_id = word_wrapper_get_type_once ();
		g_once_init_leave (&word_wrapper_type_id__once, word_wrapper_type_id);
	}
	return word_wrapper_type_id__once;
}

static inline gpointer
_vala_memdup2 (gconstpointer mem,
               gsize byte_size)
{
	gpointer new_mem;
	if (mem && byte_size != 0) {
		new_mem = g_malloc (byte_size);
		memcpy (new_mem, mem, byte_size);
	} else {
		new_mem = NULL;
	}
	return new_mem;
}

