/* gca-indent-backend.c generated by valac 0.28.0.11-bbdd, the Vala compiler
 * generated from gca-indent-backend.vala, do not modify */

/*
 * This file is part of gedit-code-assistant.
 *
 * Copyright (C) 2014 - Ignacio Casal Quinteiro
 *
 * gedit-code-assistant 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.
 *
 * gedit-code-assistant 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 gedit-code-assistant.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <glib.h>
#include <glib-object.h>
#include <string.h>
#include <stdlib.h>
#include <gedit/gedit-document.h>
#include <gtk/gtk.h>
#include <gedit/gedit-view.h>
#include <gtksourceview/gtksource.h>


#define GCA_TYPE_INDENT_LEVEL (gca_indent_level_get_type ())
typedef struct _GcaIndentLevel GcaIndentLevel;

#define GCA_TYPE_INDENT_BACKEND (gca_indent_backend_get_type ())
#define GCA_INDENT_BACKEND(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GCA_TYPE_INDENT_BACKEND, GcaIndentBackend))
#define GCA_IS_INDENT_BACKEND(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GCA_TYPE_INDENT_BACKEND))
#define GCA_INDENT_BACKEND_GET_INTERFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), GCA_TYPE_INDENT_BACKEND, GcaIndentBackendIface))

typedef struct _GcaIndentBackend GcaIndentBackend;
typedef struct _GcaIndentBackendIface GcaIndentBackendIface;

struct _GcaIndentLevel {
	guint indent;
	guint alignment;
};

struct _GcaIndentBackendIface {
	GTypeInterface parent_iface;
	gchar** (*get_triggers) (GcaIndentBackend* self, int* result_length1);
	void (*get_indent) (GcaIndentBackend* self, GeditDocument* document, GtkTextIter* place, GcaIndentLevel* result);
	GeditView* (*get_view) (GcaIndentBackend* self);
	void (*set_view) (GcaIndentBackend* self, GeditView* value);
};



GType gca_indent_level_get_type (void) G_GNUC_CONST;
GcaIndentLevel* gca_indent_level_dup (const GcaIndentLevel* self);
void gca_indent_level_free (GcaIndentLevel* self);
GType gca_indent_backend_get_type (void) G_GNUC_CONST;
gchar** gca_indent_backend_get_triggers (GcaIndentBackend* self, int* result_length1);
void gca_indent_backend_get_indent (GcaIndentBackend* self, GeditDocument* document, GtkTextIter* place, GcaIndentLevel* result);
guint gca_indent_backend_get_indent_width (GcaIndentBackend* self);
GeditView* gca_indent_backend_get_view (GcaIndentBackend* self);
void gca_indent_backend_get_line_indents (GcaIndentBackend* self, GtkTextIter* place, GcaIndentLevel* result);
void gca_indent_backend_get_amount_indents_from_position (GcaIndentBackend* self, GtkTextIter* place, GcaIndentLevel* result);
void gca_indent_backend_set_view (GcaIndentBackend* self, GeditView* value);


GcaIndentLevel* gca_indent_level_dup (const GcaIndentLevel* self) {
	GcaIndentLevel* dup;
	dup = g_new0 (GcaIndentLevel, 1);
	memcpy (dup, self, sizeof (GcaIndentLevel));
	return dup;
}


void gca_indent_level_free (GcaIndentLevel* self) {
	g_free (self);
}


GType gca_indent_level_get_type (void) {
	static volatile gsize gca_indent_level_type_id__volatile = 0;
	if (g_once_init_enter (&gca_indent_level_type_id__volatile)) {
		GType gca_indent_level_type_id;
		gca_indent_level_type_id = g_boxed_type_register_static ("GcaIndentLevel", (GBoxedCopyFunc) gca_indent_level_dup, (GBoxedFreeFunc) gca_indent_level_free);
		g_once_init_leave (&gca_indent_level_type_id__volatile, gca_indent_level_type_id);
	}
	return gca_indent_level_type_id__volatile;
}


gchar** gca_indent_backend_get_triggers (GcaIndentBackend* self, int* result_length1) {
	g_return_val_if_fail (self != NULL, NULL);
	return GCA_INDENT_BACKEND_GET_INTERFACE (self)->get_triggers (self, result_length1);
}


void gca_indent_backend_get_indent (GcaIndentBackend* self, GeditDocument* document, GtkTextIter* place, GcaIndentLevel* result) {
	g_return_if_fail (self != NULL);
	GCA_INDENT_BACKEND_GET_INTERFACE (self)->get_indent (self, document, place, result);
}


guint gca_indent_backend_get_indent_width (GcaIndentBackend* self) {
	guint result = 0U;
	guint _tmp0_ = 0U;
	GeditView* _tmp1_ = NULL;
	GeditView* _tmp2_ = NULL;
	gint _tmp3_ = 0;
	gint _tmp4_ = 0;
	_tmp1_ = gca_indent_backend_get_view (self);
	_tmp2_ = _tmp1_;
	_tmp3_ = gtk_source_view_get_indent_width ((GtkSourceView*) _tmp2_);
	_tmp4_ = _tmp3_;
	if (_tmp4_ < 0) {
		GeditView* _tmp5_ = NULL;
		GeditView* _tmp6_ = NULL;
		guint _tmp7_ = 0U;
		guint _tmp8_ = 0U;
		_tmp5_ = gca_indent_backend_get_view (self);
		_tmp6_ = _tmp5_;
		_tmp7_ = gtk_source_view_get_tab_width ((GtkSourceView*) _tmp6_);
		_tmp8_ = _tmp7_;
		_tmp0_ = _tmp8_;
	} else {
		GeditView* _tmp9_ = NULL;
		GeditView* _tmp10_ = NULL;
		gint _tmp11_ = 0;
		gint _tmp12_ = 0;
		_tmp9_ = gca_indent_backend_get_view (self);
		_tmp10_ = _tmp9_;
		_tmp11_ = gtk_source_view_get_indent_width ((GtkSourceView*) _tmp10_);
		_tmp12_ = _tmp11_;
		_tmp0_ = (guint) _tmp12_;
	}
	result = _tmp0_;
	return result;
}


void gca_indent_backend_get_line_indents (GcaIndentBackend* self, GtkTextIter* place, GcaIndentLevel* result) {
	GtkTextIter start = {0};
	GtkTextIter _tmp0_ = {0};
	gunichar c = 0U;
	gunichar _tmp1_ = 0U;
	GtkTextIter _tmp10_ = {0};
	GcaIndentLevel _tmp11_ = {0};
	g_return_if_fail (place != NULL);
	_tmp0_ = *place;
	start = _tmp0_;
	gtk_text_iter_set_line_offset (&start, 0);
	_tmp1_ = gtk_text_iter_get_char (&start);
	c = _tmp1_;
	while (TRUE) {
		gboolean _tmp2_ = FALSE;
		gboolean _tmp3_ = FALSE;
		gunichar _tmp4_ = 0U;
		gboolean _tmp5_ = FALSE;
		gboolean _tmp8_ = FALSE;
		gunichar _tmp9_ = 0U;
		_tmp4_ = c;
		_tmp5_ = g_unichar_isspace (_tmp4_);
		if (_tmp5_) {
			gunichar _tmp6_ = 0U;
			_tmp6_ = c;
			_tmp3_ = _tmp6_ != ((gunichar) '\n');
		} else {
			_tmp3_ = FALSE;
		}
		if (_tmp3_) {
			gunichar _tmp7_ = 0U;
			_tmp7_ = c;
			_tmp2_ = _tmp7_ != ((gunichar) '\r');
		} else {
			_tmp2_ = FALSE;
		}
		if (!_tmp2_) {
			break;
		}
		_tmp8_ = gtk_text_iter_forward_char (&start);
		if (!_tmp8_) {
			break;
		}
		_tmp9_ = gtk_text_iter_get_char (&start);
		c = _tmp9_;
	}
	_tmp10_ = start;
	gca_indent_backend_get_amount_indents_from_position (self, &_tmp10_, &_tmp11_);
	*result = _tmp11_;
	return;
}


void gca_indent_backend_get_amount_indents_from_position (GcaIndentBackend* self, GtkTextIter* place, GcaIndentLevel* result) {
	guint indent_width = 0U;
	guint _tmp0_ = 0U;
	GtkTextIter start = {0};
	GtkTextIter _tmp1_ = {0};
	gint rest = 0;
	gunichar c = 0U;
	gunichar _tmp2_ = 0U;
	gboolean seen_space = FALSE;
	GcaIndentLevel ret = {0};
	GcaIndentLevel _tmp3_ = {0};
	guint _tmp19_ = 0U;
	gint _tmp20_ = 0;
	g_return_if_fail (place != NULL);
	_tmp0_ = gca_indent_backend_get_indent_width (self);
	indent_width = _tmp0_;
	_tmp1_ = *place;
	start = _tmp1_;
	gtk_text_iter_set_line_offset (&start, 0);
	rest = 0;
	_tmp2_ = gtk_text_iter_get_char (&start);
	c = _tmp2_;
	seen_space = FALSE;
	memset (&_tmp3_, 0, sizeof (GcaIndentLevel));
	_tmp3_.indent = (guint) 0;
	_tmp3_.alignment = (guint) 0;
	ret = _tmp3_;
	while (TRUE) {
		GtkTextIter _tmp4_ = {0};
		gint _tmp5_ = 0;
		gunichar _tmp6_ = 0U;
		gint _tmp13_ = 0;
		guint _tmp14_ = 0U;
		gboolean _tmp17_ = FALSE;
		gunichar _tmp18_ = 0U;
		_tmp4_ = *place;
		_tmp5_ = gtk_text_iter_compare (&start, &_tmp4_);
		if (!(_tmp5_ < 0)) {
			break;
		}
		_tmp6_ = c;
		if (_tmp6_ == ((gunichar) '\t')) {
			gboolean _tmp7_ = FALSE;
			_tmp7_ = seen_space;
			if (!_tmp7_) {
				guint _tmp8_ = 0U;
				guint _tmp9_ = 0U;
				_tmp8_ = ret.indent;
				_tmp9_ = indent_width;
				ret.indent = _tmp8_ + _tmp9_;
			} else {
				guint _tmp10_ = 0U;
				guint _tmp11_ = 0U;
				rest = 0;
				_tmp10_ = ret.alignment;
				_tmp11_ = indent_width;
				ret.alignment = _tmp10_ + _tmp11_;
			}
		} else {
			gint _tmp12_ = 0;
			seen_space = TRUE;
			_tmp12_ = rest;
			rest = _tmp12_ + 1;
		}
		_tmp13_ = rest;
		_tmp14_ = indent_width;
		if (((guint) _tmp13_) == _tmp14_) {
			guint _tmp15_ = 0U;
			guint _tmp16_ = 0U;
			_tmp15_ = ret.alignment;
			_tmp16_ = indent_width;
			ret.alignment = _tmp15_ + _tmp16_;
			rest = 0;
		}
		_tmp17_ = gtk_text_iter_forward_char (&start);
		if (!_tmp17_) {
			break;
		}
		_tmp18_ = gtk_text_iter_get_char (&start);
		c = _tmp18_;
	}
	_tmp19_ = ret.alignment;
	_tmp20_ = rest;
	ret.alignment = _tmp19_ + _tmp20_;
	*result = ret;
	return;
}


GeditView* gca_indent_backend_get_view (GcaIndentBackend* self) {
	g_return_val_if_fail (self != NULL, NULL);
	return GCA_INDENT_BACKEND_GET_INTERFACE (self)->get_view (self);
}


void gca_indent_backend_set_view (GcaIndentBackend* self, GeditView* value) {
	g_return_if_fail (self != NULL);
	GCA_INDENT_BACKEND_GET_INTERFACE (self)->set_view (self, value);
}


static void gca_indent_backend_base_init (GcaIndentBackendIface * iface) {
	static gboolean initialized = FALSE;
	if (!initialized) {
		initialized = TRUE;
		g_object_interface_install_property (iface, g_param_spec_object ("view", "view", "view", gedit_view_get_type (), G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT));
	}
}


GType gca_indent_backend_get_type (void) {
	static volatile gsize gca_indent_backend_type_id__volatile = 0;
	if (g_once_init_enter (&gca_indent_backend_type_id__volatile)) {
		static const GTypeInfo g_define_type_info = { sizeof (GcaIndentBackendIface), (GBaseInitFunc) gca_indent_backend_base_init, (GBaseFinalizeFunc) NULL, (GClassInitFunc) NULL, (GClassFinalizeFunc) NULL, NULL, 0, 0, (GInstanceInitFunc) NULL, NULL };
		GType gca_indent_backend_type_id;
		gca_indent_backend_type_id = g_type_register_static (G_TYPE_INTERFACE, "GcaIndentBackend", &g_define_type_info, 0);
		g_type_interface_add_prerequisite (gca_indent_backend_type_id, G_TYPE_OBJECT);
		g_once_init_leave (&gca_indent_backend_type_id__volatile, gca_indent_backend_type_id);
	}
	return gca_indent_backend_type_id__volatile;
}



