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

/*
Copyright (C) 2014 2015 2016 Johan Mattsson

This library is free software; you can redistribute it and/or modify 
it under the terms of the GNU Lesser General Public License as 
published by the Free Software Foundation; either version 3 of the 
License, or (at your option) any later version.

This library 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 
Lesser General Public License for more details.
*/

#include "birdfont.h"
#include <glib.h>
#include <float.h>
#include <math.h>
#include <glib-object.h>
#include <stdlib.h>
#include <string.h>
#include <gee.h>
#include <cairo-gobject.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

enum  {
	BIRD_FONT_TRACK_TOOL_0_PROPERTY,
	BIRD_FONT_TRACK_TOOL_NUM_PROPERTIES
};
static GParamSpec* bird_font_track_tool_properties[BIRD_FONT_TRACK_TOOL_NUM_PROPERTIES];
#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_source_unref0(var) ((var == NULL) ? NULL : (var = (g_source_unref (var), NULL)))

struct _BirdFontTrackToolPrivate {
	gboolean draw_freehand;
	gint added_points;
	gdouble last_update;
	gint last_x;
	gint last_y;
	gint last_timer_x;
	gint last_timer_y;
	gint update_cycles;
	gint join_x;
	gint join_y;
	gboolean join_paths;
	gdouble samples_per_point;
	gboolean drawing;
};

static gint BirdFontTrackTool_private_offset;
static gpointer bird_font_track_tool_parent_class = NULL;

static void __lambda159_ (BirdFontTrackTool* self);
static void ___lambda159__bird_font_tool_select_action (BirdFontTool* _sender,
                                                 BirdFontTool* selected,
                                                 gpointer self);
static void __lambda160_ (BirdFontTrackTool* self);
static void ___lambda160__bird_font_tool_deselect_action (BirdFontTool* _sender,
                                                   BirdFontTool* selected,
                                                   gpointer self);
static void __lambda161_ (BirdFontTrackTool* self,
                   BirdFontTool* _self_,
                   gint button,
                   gint x,
                   gint y);
static BirdFontPointSelection* bird_font_track_tool_get_path_with_end_point (BirdFontTrackTool* self,
                                                                      gint x,
                                                                      gint y);
static void bird_font_track_tool_start_update_timer (BirdFontTrackTool* self);
static void ___lambda161__bird_font_tool_press_action (BirdFontTool* _sender,
                                                BirdFontTool* selected,
                                                gint button,
                                                gint x,
                                                gint y,
                                                gpointer self);
static void __lambda163_ (BirdFontTrackTool* self,
                   BirdFontTool* _self_,
                   gint b,
                   gint x,
                   gint y);
static void ___lambda163__bird_font_tool_double_click_action (BirdFontTool* _sender,
                                                       BirdFontTool* selected,
                                                       gint button,
                                                       gint x,
                                                       gint y,
                                                       gpointer self);
static void __lambda164_ (BirdFontTrackTool* self,
                   BirdFontTool* _self_,
                   gint button,
                   gint x,
                   gint y);
static void bird_font_track_tool_add_endpoint_and_merge (BirdFontTrackTool* self,
                                                  gint x,
                                                  gint y);
static void bird_font_track_tool_convert_hidden_points (BirdFontTrackTool* self,
                                                 BirdFontPath* p);
static void bird_font_track_tool_set_tie (BirdFontTrackTool* self);
static void ___lambda164__bird_font_tool_release_action (BirdFontTool* _sender,
                                                  BirdFontTool* selected,
                                                  gint button,
                                                  gint x,
                                                  gint y,
                                                  gpointer self);
static void __lambda165_ (BirdFontTrackTool* self,
                   BirdFontTool* _self_,
                   gint x,
                   gint y);
static void bird_font_track_tool_record_new_position (BirdFontTrackTool* self,
                                               gint x,
                                               gint y);
static void bird_font_track_tool_convert_on_timeout (BirdFontTrackTool* self);
static void ___lambda165__bird_font_tool_move_action (BirdFontTool* _sender,
                                               BirdFontTool* selected,
                                               gint x,
                                               gint y,
                                               gpointer self);
static void __lambda166_ (BirdFontTrackTool* self,
                   BirdFontTool* tool,
                   cairo_t* cairo_context,
                   BirdFontGlyph* glyph);
static void ___lambda166__bird_font_tool_draw_action (BirdFontTool* _sender,
                                               BirdFontTool* selected,
                                               cairo_t* cr,
                                               BirdFontGlyph* glyph,
                                               gpointer self);
static void __lambda167_ (BirdFontTrackTool* self,
                   BirdFontTool* _self_,
                   guint32 keyval);
static void ___lambda167__bird_font_tool_key_press_action (BirdFontTool* _sender,
                                                    BirdFontTool* selected,
                                                    guint32 keyval,
                                                    gpointer self);
static void bird_font_track_tool_delete_last_points_at (BirdFontTrackTool* self,
                                                 gdouble px,
                                                 gdouble py);
static BirdFontPath* bird_font_track_tool_merge_paths (BirdFontPath* a,
                                                BirdFontPointSelection* b);
static void bird_font_track_tool_add_corner (BirdFontTrackTool* self,
                                      gdouble px,
                                      gdouble py);
static BirdFontPath* bird_font_track_tool_get_active_path (BirdFontTrackTool* self);
static gboolean __lambda162_ (BirdFontTrackTool* self);
static gboolean ___lambda162__gsource_func (gpointer self);
static gboolean bird_font_track_tool_is_moving (BirdFontTrackTool* self,
                                         gint x,
                                         gint y);
static gboolean bird_font_track_tool_is_close (BirdFontTrackTool* self,
                                        BirdFontEditPoint* p,
                                        gdouble x,
                                        gdouble y);
static void bird_font_track_tool_finalize (GObject * obj);
static GType bird_font_track_tool_get_type_once (void);
static inline gpointer _vala_memdup2 (gconstpointer mem,
                        gsize byte_size);

static inline gpointer
bird_font_track_tool_get_instance_private (BirdFontTrackTool* self)
{
	return G_STRUCT_MEMBER_P (self, BirdFontTrackTool_private_offset);
}

static void
__lambda159_ (BirdFontTrackTool* self)
{
	bird_font_track_tool_convert_points_to_line (self);
	self->priv->draw_freehand = FALSE;
}

static void
___lambda159__bird_font_tool_select_action (BirdFontTool* _sender,
                                            BirdFontTool* selected,
                                            gpointer self)
{
	__lambda159_ ((BirdFontTrackTool*) self);
}

static void
__lambda160_ (BirdFontTrackTool* self)
{
	bird_font_track_tool_convert_points_to_line (self);
	self->priv->draw_freehand = FALSE;
}

static void
___lambda160__bird_font_tool_deselect_action (BirdFontTool* _sender,
                                              BirdFontTool* selected,
                                              gpointer self)
{
	__lambda160_ ((BirdFontTrackTool*) self);
}

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

static void
__lambda161_ (BirdFontTrackTool* self,
              BirdFontTool* _self_,
              gint button,
              gint x,
              gint y)
{
	BirdFontGlyph* glyph = NULL;
	BirdFontGlyph* _tmp0_;
	BirdFontPath* p = NULL;
	BirdFontPointSelection* ps = NULL;
	BirdFontPointSelection* end_point = NULL;
	g_return_if_fail (_self_ != NULL);
	_tmp0_ = bird_font_main_window_get_current_glyph ();
	glyph = _tmp0_;
	if (button == 3) {
		BirdFontGlyph* _tmp1_;
		_tmp1_ = glyph;
		bird_font_glyph_clear_active_paths (_tmp1_);
	}
	if (button == 2) {
		BirdFontGlyph* _tmp2_;
		_tmp2_ = glyph;
		bird_font_glyph_close_path (_tmp2_);
	}
	if (button == 1) {
		BirdFontGlyph* _tmp3_;
		BirdFontGlyph* _tmp20_;
		BirdFontGlyph* _tmp21_;
		GeeArrayList* _tmp22_;
		if (self->priv->draw_freehand) {
			g_warning ("TrackTool.vala:85: Already drawing.");
			_g_object_unref0 (end_point);
			_g_object_unref0 (ps);
			_g_object_unref0 (p);
			_g_object_unref0 (glyph);
			return;
		}
		g_return_if_fail (!self->priv->drawing);
		self->priv->draw_freehand = TRUE;
		self->priv->last_x = x;
		self->priv->last_y = y;
		_tmp3_ = glyph;
		bird_font_glyph_store_undo_state (_tmp3_, FALSE);
		if (self->priv->join_paths) {
			BirdFontPointSelection* _tmp4_;
			BirdFontPointSelection* _tmp5_;
			BirdFontPointSelection* _tmp6_;
			BirdFontPointSelection* _tmp7_;
			BirdFontPointSelection* _tmp8_;
			BirdFontGlyph* _tmp11_;
			BirdFontPointSelection* _tmp12_;
			BirdFontPath* _tmp13_;
			_tmp4_ = bird_font_track_tool_get_path_with_end_point (self, x, y);
			_g_object_unref0 (ps);
			ps = _tmp4_;
			_tmp5_ = ps;
			if (G_UNLIKELY (_tmp5_ == NULL)) {
				g_warning ("TrackTool.vala:102: No end point.");
				_g_object_unref0 (end_point);
				_g_object_unref0 (ps);
				_g_object_unref0 (p);
				_g_object_unref0 (glyph);
				return;
			}
			_tmp6_ = ps;
			_tmp7_ = _g_object_ref0 (G_TYPE_CHECK_INSTANCE_CAST (_tmp6_, BIRD_FONT_TYPE_POINT_SELECTION, BirdFontPointSelection));
			_g_object_unref0 (end_point);
			end_point = _tmp7_;
			_tmp8_ = end_point;
			if (bird_font_point_selection_is_first (_tmp8_)) {
				BirdFontPointSelection* _tmp9_;
				BirdFontPath* _tmp10_;
				_tmp9_ = end_point;
				_tmp10_ = _tmp9_->path;
				bird_font_path_reverse (_tmp10_);
			}
			_tmp11_ = glyph;
			_tmp12_ = end_point;
			_tmp13_ = _tmp12_->path;
			bird_font_glyph_set_active_path (_tmp11_, _tmp13_);
		} else {
			BirdFontPath* _tmp14_;
			BirdFontGlyph* _tmp15_;
			BirdFontPath* _tmp16_;
			BirdFontGlyph* _tmp17_;
			BirdFontPointSelection* _tmp18_;
			BirdFontPointSelection* _tmp19_;
			_tmp14_ = bird_font_path_new ();
			_g_object_unref0 (p);
			p = _tmp14_;
			_tmp15_ = glyph;
			_tmp16_ = p;
			bird_font_glyph_add_path (_tmp15_, _tmp16_);
			_tmp17_ = glyph;
			bird_font_glyph_open_path (_tmp17_);
			_tmp18_ = bird_font_pen_tool_add_new_edit_point (x, y);
			_tmp19_ = _tmp18_;
			_g_object_unref0 (_tmp19_);
		}
		_tmp20_ = glyph;
		bird_font_glyph_update_view (_tmp20_);
		self->priv->added_points = 0;
		self->priv->last_update = bird_font_track_tool_get_current_time ();
		bird_font_track_tool_start_update_timer (self);
		self->priv->drawing = TRUE;
		_tmp21_ = glyph;
		_tmp22_ = _tmp21_->active_paths;
		if (bird_font_is_null (_tmp22_)) {
			g_warning ("TrackTool.vala:128: No active paths in free hand tool.");
			_g_object_unref0 (end_point);
			_g_object_unref0 (ps);
			_g_object_unref0 (p);
			_g_object_unref0 (glyph);
			return;
		}
		{
			GeeArrayList* _path_list = NULL;
			BirdFontGlyph* _tmp23_;
			GeeArrayList* _tmp24_;
			gint _path_size = 0;
			GeeArrayList* _tmp25_;
			gint _tmp26_;
			gint _tmp27_;
			gint _path_index = 0;
			_tmp23_ = glyph;
			_tmp24_ = _tmp23_->active_paths;
			_path_list = _tmp24_;
			_tmp25_ = _path_list;
			_tmp26_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) _tmp25_);
			_tmp27_ = _tmp26_;
			_path_size = _tmp27_;
			_path_index = -1;
			while (TRUE) {
				gint _tmp28_;
				gint _tmp29_;
				BirdFontPath* path = NULL;
				GeeArrayList* _tmp30_;
				gpointer _tmp31_;
				BirdFontPath* _tmp32_;
				_path_index = _path_index + 1;
				_tmp28_ = _path_index;
				_tmp29_ = _path_size;
				if (!(_tmp28_ < _tmp29_)) {
					break;
				}
				_tmp30_ = _path_list;
				_tmp31_ = gee_abstract_list_get ((GeeAbstractList*) _tmp30_, _path_index);
				path = (BirdFontPath*) _tmp31_;
				_tmp32_ = path;
				bird_font_path_create_full_stroke (_tmp32_);
				_g_object_unref0 (path);
			}
		}
	}
	_g_object_unref0 (end_point);
	_g_object_unref0 (ps);
	_g_object_unref0 (p);
	_g_object_unref0 (glyph);
}

static void
___lambda161__bird_font_tool_press_action (BirdFontTool* _sender,
                                           BirdFontTool* selected,
                                           gint button,
                                           gint x,
                                           gint y,
                                           gpointer self)
{
	__lambda161_ ((BirdFontTrackTool*) self, selected, button, x, y);
}

static void
__lambda163_ (BirdFontTrackTool* self,
              BirdFontTool* _self_,
              gint b,
              gint x,
              gint y)
{
	g_return_if_fail (_self_ != NULL);
}

static void
___lambda163__bird_font_tool_double_click_action (BirdFontTool* _sender,
                                                  BirdFontTool* selected,
                                                  gint button,
                                                  gint x,
                                                  gint y,
                                                  gpointer self)
{
	__lambda163_ ((BirdFontTrackTool*) self, selected, button, x, y);
}

static void
__lambda164_ (BirdFontTrackTool* self,
              BirdFontTool* _self_,
              gint button,
              gint x,
              gint y)
{
	BirdFontPath* p = NULL;
	BirdFontGlyph* g = NULL;
	BirdFontGlyph* _tmp0_;
	BirdFontEditPoint* previous = NULL;
	g_return_if_fail (_self_ != NULL);
	_tmp0_ = bird_font_main_window_get_current_glyph ();
	g = _tmp0_;
	if (button == 1) {
		BirdFontGlyph* _tmp1_;
		BirdFontGlyph* _tmp2_;
		GeeArrayList* _tmp3_;
		gboolean _tmp4_ = FALSE;
		BirdFontGlyph* _tmp5_;
		GeeArrayList* _tmp6_;
		gboolean _tmp47_ = FALSE;
		BirdFontPathList* paths_in_layer = NULL;
		BirdFontGlyph* _tmp48_;
		BirdFontLayer* _tmp49_;
		BirdFontPathList* _tmp50_;
		gboolean _tmp51_ = FALSE;
		BirdFontPathList* _tmp52_;
		BirdFontGlyph* _tmp65_;
		BirdFontFont* _tmp66_;
		BirdFontFont* _tmp67_;
		if (!self->priv->draw_freehand) {
			g_warning ("TrackTool.vala:148: Not drawing.");
			_g_object_unref0 (previous);
			_g_object_unref0 (g);
			_g_object_unref0 (p);
			return;
		}
		bird_font_track_tool_convert_points_to_line (self);
		_tmp1_ = bird_font_main_window_get_current_glyph ();
		_g_object_unref0 (g);
		g = _tmp1_;
		_tmp2_ = g;
		_tmp3_ = _tmp2_->active_paths;
		g_return_if_fail (!bird_font_is_null (_tmp3_));
		_tmp5_ = g;
		_tmp6_ = _tmp5_->active_paths;
		if (!bird_font_is_null (_tmp6_)) {
			BirdFontGlyph* _tmp7_;
			GeeArrayList* _tmp8_;
			gint _tmp9_;
			gint _tmp10_;
			_tmp7_ = g;
			_tmp8_ = _tmp7_->active_paths;
			_tmp9_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) _tmp8_);
			_tmp10_ = _tmp9_;
			_tmp4_ = _tmp10_ > 0;
		} else {
			_tmp4_ = FALSE;
		}
		if (_tmp4_) {
			BirdFontGlyph* _tmp11_;
			GeeArrayList* _tmp12_;
			BirdFontGlyph* _tmp13_;
			GeeArrayList* _tmp14_;
			gint _tmp15_;
			gint _tmp16_;
			gpointer _tmp17_;
			BirdFontPath* _tmp18_;
			GeeArrayList* _tmp19_;
			GeeArrayList* _tmp20_;
			gboolean _tmp21_ = FALSE;
			BirdFontPath* _tmp22_;
			GeeArrayList* _tmp23_;
			GeeArrayList* _tmp24_;
			_tmp11_ = g;
			_tmp12_ = _tmp11_->active_paths;
			_tmp13_ = g;
			_tmp14_ = _tmp13_->active_paths;
			_tmp15_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) _tmp14_);
			_tmp16_ = _tmp15_;
			_tmp17_ = gee_abstract_list_get ((GeeAbstractList*) _tmp12_, _tmp16_ - 1);
			_g_object_unref0 (p);
			p = (BirdFontPath*) _tmp17_;
			_tmp18_ = p;
			_tmp19_ = bird_font_path_get_points (_tmp18_);
			_tmp20_ = _tmp19_;
			g_return_if_fail (!bird_font_is_null (_tmp20_));
			_tmp22_ = p;
			_tmp23_ = bird_font_path_get_points (_tmp22_);
			_tmp24_ = _tmp23_;
			if (!bird_font_is_null (_tmp24_)) {
				BirdFontPath* _tmp25_;
				GeeArrayList* _tmp26_;
				GeeArrayList* _tmp27_;
				gint _tmp28_;
				gint _tmp29_;
				_tmp25_ = p;
				_tmp26_ = bird_font_path_get_points (_tmp25_);
				_tmp27_ = _tmp26_;
				_tmp28_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) _tmp27_);
				_tmp29_ = _tmp28_;
				_tmp21_ = _tmp29_ > 1;
			} else {
				_tmp21_ = FALSE;
			}
			if (_tmp21_) {
				BirdFontPath* _tmp30_;
				GeeArrayList* _tmp31_;
				GeeArrayList* _tmp32_;
				BirdFontPath* _tmp33_;
				GeeArrayList* _tmp34_;
				GeeArrayList* _tmp35_;
				gint _tmp36_;
				gint _tmp37_;
				gpointer _tmp38_;
				BirdFontEditPoint* _tmp39_;
				BirdFontEditPoint* _tmp40_;
				BirdFontPath* _tmp41_;
				GeeArrayList* _tmp42_;
				GeeArrayList* _tmp43_;
				gpointer _tmp44_;
				BirdFontEditPoint* _tmp45_;
				BirdFontEditPoint* _tmp46_;
				_tmp30_ = p;
				_tmp31_ = bird_font_path_get_points (_tmp30_);
				_tmp32_ = _tmp31_;
				_tmp33_ = p;
				_tmp34_ = bird_font_path_get_points (_tmp33_);
				_tmp35_ = _tmp34_;
				_tmp36_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) _tmp35_);
				_tmp37_ = _tmp36_;
				_tmp38_ = gee_abstract_list_get ((GeeAbstractList*) _tmp32_, _tmp37_ - 1);
				_g_object_unref0 (previous);
				previous = (BirdFontEditPoint*) _tmp38_;
				_tmp39_ = previous;
				_tmp39_->type = BIRD_FONT_POINT_TYPE_CUBIC;
				_tmp40_ = previous;
				bird_font_edit_point_set_tie_handle (_tmp40_, FALSE);
				_tmp41_ = p;
				_tmp42_ = bird_font_path_get_points (_tmp41_);
				_tmp43_ = _tmp42_;
				_tmp44_ = gee_abstract_list_get ((GeeAbstractList*) _tmp43_, 0);
				_g_object_unref0 (previous);
				previous = (BirdFontEditPoint*) _tmp44_;
				_tmp45_ = previous;
				_tmp45_->type = BIRD_FONT_POINT_TYPE_CUBIC;
				_tmp46_ = previous;
				bird_font_edit_point_set_tie_handle (_tmp46_, FALSE);
			}
		}
		if (button == 1) {
			_tmp47_ = self->priv->draw_freehand;
		} else {
			_tmp47_ = FALSE;
		}
		if (_tmp47_) {
			g_return_if_fail (self->priv->drawing);
			bird_font_track_tool_add_endpoint_and_merge (self, x, y);
		}
		_tmp48_ = g;
		_tmp49_ = _tmp48_->layers;
		_tmp50_ = bird_font_layer_get_all_paths (_tmp49_);
		paths_in_layer = _tmp50_;
		_tmp52_ = paths_in_layer;
		if (bird_font_is_null (_tmp52_)) {
			_tmp51_ = TRUE;
		} else {
			BirdFontPathList* _tmp53_;
			_tmp53_ = paths_in_layer;
			_tmp51_ = bird_font_is_null (_tmp53_);
		}
		if (_tmp51_) {
			g_warning ("TrackTool.vala:182: No layers in glyph.");
		} else {
			{
				GeeArrayList* _path_list = NULL;
				BirdFontPathList* _tmp54_;
				GeeArrayList* _tmp55_;
				gint _path_size = 0;
				GeeArrayList* _tmp56_;
				gint _tmp57_;
				gint _tmp58_;
				gint _path_index = 0;
				_tmp54_ = paths_in_layer;
				_tmp55_ = _tmp54_->paths;
				_path_list = _tmp55_;
				_tmp56_ = _path_list;
				_tmp57_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) _tmp56_);
				_tmp58_ = _tmp57_;
				_path_size = _tmp58_;
				_path_index = -1;
				while (TRUE) {
					gint _tmp59_;
					gint _tmp60_;
					BirdFontPath* path = NULL;
					GeeArrayList* _tmp61_;
					gpointer _tmp62_;
					BirdFontPath* _tmp63_;
					BirdFontPath* _tmp64_;
					_path_index = _path_index + 1;
					_tmp59_ = _path_index;
					_tmp60_ = _path_size;
					if (!(_tmp59_ < _tmp60_)) {
						break;
					}
					_tmp61_ = _path_list;
					_tmp62_ = gee_abstract_list_get ((GeeAbstractList*) _tmp61_, _path_index);
					path = (BirdFontPath*) _tmp62_;
					_tmp63_ = path;
					bird_font_track_tool_convert_hidden_points (self, _tmp63_);
					_tmp64_ = path;
					bird_font_path_update_region_boundaries (_tmp64_);
					_g_object_unref0 (path);
				}
			}
		}
		_tmp65_ = g;
		bird_font_glyph_clear_active_paths (_tmp65_);
		bird_font_track_tool_set_tie (self);
		bird_font_pen_tool_force_direction ();
		bird_font_pen_tool_reset_stroke ();
		_tmp66_ = bird_font_bird_font_get_current_font ();
		_tmp67_ = _tmp66_;
		bird_font_font_touch (_tmp67_);
		_g_object_unref0 (_tmp67_);
		self->priv->drawing = FALSE;
		_g_object_unref0 (paths_in_layer);
	}
	_g_object_unref0 (previous);
	_g_object_unref0 (g);
	_g_object_unref0 (p);
}

static void
___lambda164__bird_font_tool_release_action (BirdFontTool* _sender,
                                             BirdFontTool* selected,
                                             gint button,
                                             gint x,
                                             gint y,
                                             gpointer self)
{
	__lambda164_ ((BirdFontTrackTool*) self, selected, button, x, y);
}

static void
__lambda165_ (BirdFontTrackTool* self,
              BirdFontTool* _self_,
              gint x,
              gint y)
{
	BirdFontPointSelection* open_path = NULL;
	BirdFontPointSelection* _tmp0_;
	BirdFontPointSelection* p = NULL;
	gboolean join = FALSE;
	BirdFontPointSelection* _tmp1_;
	BirdFontPointSelection* _tmp4_;
	g_return_if_fail (_self_ != NULL);
	_tmp0_ = bird_font_track_tool_get_path_with_end_point (self, x, y);
	open_path = _tmp0_;
	_tmp1_ = open_path;
	join = _tmp1_ != NULL;
	if (join != self->priv->join_paths) {
		BirdFontGlyph* _tmp2_;
		BirdFontGlyph* _tmp3_;
		_tmp2_ = bird_font_main_window_get_current_glyph ();
		_tmp3_ = _tmp2_;
		bird_font_glyph_update_view (_tmp3_);
		_g_object_unref0 (_tmp3_);
		bird_font_pen_tool_reset_stroke ();
	}
	self->priv->join_paths = join;
	_tmp4_ = open_path;
	if (_tmp4_ != NULL) {
		BirdFontPointSelection* _tmp5_;
		BirdFontPointSelection* _tmp6_;
		BirdFontPointSelection* _tmp7_;
		BirdFontEditPoint* _tmp8_;
		BirdFontPointSelection* _tmp9_;
		BirdFontEditPoint* _tmp10_;
		_tmp5_ = open_path;
		_tmp6_ = _g_object_ref0 (G_TYPE_CHECK_INSTANCE_CAST (_tmp5_, BIRD_FONT_TYPE_POINT_SELECTION, BirdFontPointSelection));
		_g_object_unref0 (p);
		p = _tmp6_;
		_tmp7_ = p;
		_tmp8_ = _tmp7_->point;
		self->priv->join_x = bird_font_glyph_reverse_path_coordinate_x (_tmp8_->x);
		_tmp9_ = p;
		_tmp10_ = _tmp9_->point;
		self->priv->join_y = bird_font_glyph_reverse_path_coordinate_y (_tmp10_->y);
	}
	if (self->priv->draw_freehand) {
		bird_font_track_tool_record_new_position (self, x, y);
		bird_font_track_tool_convert_on_timeout (self);
		self->priv->last_x = x;
		self->priv->last_y = y;
		bird_font_pen_tool_reset_stroke ();
	}
	_g_object_unref0 (p);
	_g_object_unref0 (open_path);
}

static void
___lambda165__bird_font_tool_move_action (BirdFontTool* _sender,
                                          BirdFontTool* selected,
                                          gint x,
                                          gint y,
                                          gpointer self)
{
	__lambda165_ ((BirdFontTrackTool*) self, selected, x, y);
}

static void
__lambda166_ (BirdFontTrackTool* self,
              BirdFontTool* tool,
              cairo_t* cairo_context,
              BirdFontGlyph* glyph)
{
	g_return_if_fail (tool != NULL);
	g_return_if_fail (cairo_context != NULL);
	g_return_if_fail (glyph != NULL);
	if (self->priv->join_paths) {
		bird_font_pen_tool_draw_join_icon (cairo_context, (gdouble) self->priv->join_x, (gdouble) self->priv->join_y);
	}
}

static void
___lambda166__bird_font_tool_draw_action (BirdFontTool* _sender,
                                          BirdFontTool* selected,
                                          cairo_t* cr,
                                          BirdFontGlyph* glyph,
                                          gpointer self)
{
	__lambda166_ ((BirdFontTrackTool*) self, selected, cr, glyph);
}

static void
__lambda167_ (BirdFontTrackTool* self,
              BirdFontTool* _self_,
              guint32 keyval)
{
	g_return_if_fail (_self_ != NULL);
}

static void
___lambda167__bird_font_tool_key_press_action (BirdFontTool* _sender,
                                               BirdFontTool* selected,
                                               guint32 keyval,
                                               gpointer self)
{
	__lambda167_ ((BirdFontTrackTool*) self, selected, keyval);
}

BirdFontTrackTool*
bird_font_track_tool_construct (GType object_type,
                                const gchar* name)
{
	BirdFontTrackTool * self = NULL;
	gchar* _tmp0_;
	gchar* _tmp1_;
	g_return_val_if_fail (name != NULL, NULL);
	_tmp0_ = bird_font_t_ ("Freehand drawing");
	_tmp1_ = _tmp0_;
	self = (BirdFontTrackTool*) bird_font_tool_construct (object_type, name, _tmp1_);
	_g_free0 (_tmp1_);
	g_signal_connect_object ((BirdFontTool*) self, "select-action", (GCallback) ___lambda159__bird_font_tool_select_action, self, 0);
	g_signal_connect_object ((BirdFontTool*) self, "deselect-action", (GCallback) ___lambda160__bird_font_tool_deselect_action, self, 0);
	g_signal_connect_object ((BirdFontTool*) self, "press-action", (GCallback) ___lambda161__bird_font_tool_press_action, self, 0);
	g_signal_connect_object ((BirdFontTool*) self, "double-click-action", (GCallback) ___lambda163__bird_font_tool_double_click_action, self, 0);
	g_signal_connect_object ((BirdFontTool*) self, "release-action", (GCallback) ___lambda164__bird_font_tool_release_action, self, 0);
	g_signal_connect_object ((BirdFontTool*) self, "move-action", (GCallback) ___lambda165__bird_font_tool_move_action, self, 0);
	g_signal_connect_object ((BirdFontTool*) self, "draw-action", (GCallback) ___lambda166__bird_font_tool_draw_action, self, 0);
	g_signal_connect_object ((BirdFontTool*) self, "key-press-action", (GCallback) ___lambda167__bird_font_tool_key_press_action, self, 0);
	return self;
}

BirdFontTrackTool*
bird_font_track_tool_new (const gchar* name)
{
	return bird_font_track_tool_construct (BIRD_FONT_TYPE_TRACK_TOOL, name);
}

static void
bird_font_track_tool_convert_hidden_points (BirdFontTrackTool* self,
                                            BirdFontPath* p)
{
	g_return_if_fail (self != NULL);
	g_return_if_fail (p != NULL);
	{
		GeeArrayList* _e_list = NULL;
		GeeArrayList* _tmp0_;
		GeeArrayList* _tmp1_;
		gint _e_size = 0;
		GeeArrayList* _tmp2_;
		gint _tmp3_;
		gint _tmp4_;
		gint _e_index = 0;
		_tmp0_ = bird_font_path_get_points (p);
		_tmp1_ = _tmp0_;
		_e_list = _tmp1_;
		_tmp2_ = _e_list;
		_tmp3_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) _tmp2_);
		_tmp4_ = _tmp3_;
		_e_size = _tmp4_;
		_e_index = -1;
		while (TRUE) {
			gint _tmp5_;
			gint _tmp6_;
			BirdFontEditPoint* e = NULL;
			GeeArrayList* _tmp7_;
			gpointer _tmp8_;
			BirdFontEditPoint* _tmp9_;
			_e_index = _e_index + 1;
			_tmp5_ = _e_index;
			_tmp6_ = _e_size;
			if (!(_tmp5_ < _tmp6_)) {
				break;
			}
			_tmp7_ = _e_list;
			_tmp8_ = gee_abstract_list_get ((GeeAbstractList*) _tmp7_, _e_index);
			e = (BirdFontEditPoint*) _tmp8_;
			_tmp9_ = e;
			if (_tmp9_->type == BIRD_FONT_POINT_TYPE_HIDDEN) {
				BirdFontEditPoint* _tmp10_;
				BirdFontEditPoint* _tmp11_;
				BirdFontEditPointHandle* _tmp12_;
				BirdFontEditPoint* _tmp13_;
				BirdFontEditPointHandle* _tmp14_;
				_tmp10_ = e;
				_tmp10_->type = bird_font_drawing_tools_point_type;
				_tmp11_ = e;
				_tmp12_ = bird_font_edit_point_get_right_handle (_tmp11_);
				_tmp12_->type = BIRD_FONT_POINT_TYPE_CUBIC;
				_tmp13_ = e;
				_tmp14_ = bird_font_edit_point_get_left_handle (_tmp13_);
				_tmp14_->type = BIRD_FONT_POINT_TYPE_CUBIC;
			}
			_g_object_unref0 (e);
		}
	}
}

static void
bird_font_track_tool_set_tie (BirdFontTrackTool* self)
{
	BirdFontGlyph* glyph = NULL;
	BirdFontGlyph* _tmp0_;
	GeeArrayList* paths = NULL;
	BirdFontGlyph* _tmp1_;
	GeeArrayList* _tmp2_;
	GeeArrayList* _tmp3_;
	GeeArrayList* _tmp4_;
	gint _tmp5_;
	gint _tmp6_;
	BirdFontPath* p = NULL;
	GeeArrayList* _tmp7_;
	GeeArrayList* _tmp8_;
	gint _tmp9_;
	gint _tmp10_;
	gpointer _tmp11_;
	g_return_if_fail (self != NULL);
	_tmp0_ = bird_font_main_window_get_current_glyph ();
	glyph = _tmp0_;
	_tmp1_ = glyph;
	_tmp2_ = bird_font_glyph_get_visible_paths (_tmp1_);
	paths = _tmp2_;
	_tmp3_ = paths;
	g_return_if_fail (!bird_font_is_null (_tmp3_));
	_tmp4_ = paths;
	_tmp5_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) _tmp4_);
	_tmp6_ = _tmp5_;
	g_return_if_fail (_tmp6_ > 0);
	_tmp7_ = paths;
	_tmp8_ = paths;
	_tmp9_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) _tmp8_);
	_tmp10_ = _tmp9_;
	_tmp11_ = gee_abstract_list_get ((GeeAbstractList*) _tmp7_, _tmp10_ - 1);
	p = (BirdFontPath*) _tmp11_;
	{
		GeeArrayList* _ep_list = NULL;
		BirdFontPath* _tmp12_;
		GeeArrayList* _tmp13_;
		GeeArrayList* _tmp14_;
		gint _ep_size = 0;
		GeeArrayList* _tmp15_;
		gint _tmp16_;
		gint _tmp17_;
		gint _ep_index = 0;
		_tmp12_ = p;
		_tmp13_ = bird_font_path_get_points (_tmp12_);
		_tmp14_ = _tmp13_;
		_ep_list = _tmp14_;
		_tmp15_ = _ep_list;
		_tmp16_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) _tmp15_);
		_tmp17_ = _tmp16_;
		_ep_size = _tmp17_;
		_ep_index = -1;
		while (TRUE) {
			gint _tmp18_;
			gint _tmp19_;
			BirdFontEditPoint* ep = NULL;
			GeeArrayList* _tmp20_;
			gpointer _tmp21_;
			gboolean _tmp22_ = FALSE;
			BirdFontEditPoint* _tmp23_;
			BirdFontEditPointHandle* _tmp24_;
			gboolean _tmp28_ = FALSE;
			BirdFontEditPoint* _tmp29_;
			BirdFontEditPointHandle* _tmp30_;
			_ep_index = _ep_index + 1;
			_tmp18_ = _ep_index;
			_tmp19_ = _ep_size;
			if (!(_tmp18_ < _tmp19_)) {
				break;
			}
			_tmp20_ = _ep_list;
			_tmp21_ = gee_abstract_list_get ((GeeAbstractList*) _tmp20_, _ep_index);
			ep = (BirdFontEditPoint*) _tmp21_;
			_tmp23_ = ep;
			_tmp24_ = bird_font_edit_point_get_right_handle (_tmp23_);
			if (bird_font_edit_point_handle_is_line (_tmp24_)) {
				_tmp22_ = TRUE;
			} else {
				BirdFontEditPoint* _tmp25_;
				BirdFontEditPointHandle* _tmp26_;
				_tmp25_ = ep;
				_tmp26_ = bird_font_edit_point_get_left_handle (_tmp25_);
				_tmp22_ = bird_font_edit_point_handle_is_line (_tmp26_);
			}
			if (_tmp22_) {
				BirdFontEditPoint* _tmp27_;
				_tmp27_ = ep;
				bird_font_edit_point_set_tie_handle (_tmp27_, FALSE);
			}
			_tmp29_ = ep;
			_tmp30_ = bird_font_edit_point_get_right_handle (_tmp29_);
			if (!bird_font_edit_point_handle_is_line (_tmp30_)) {
				_tmp28_ = TRUE;
			} else {
				BirdFontEditPoint* _tmp31_;
				BirdFontEditPointHandle* _tmp32_;
				_tmp31_ = ep;
				_tmp32_ = bird_font_edit_point_get_left_handle (_tmp31_);
				_tmp28_ = !bird_font_edit_point_handle_is_line (_tmp32_);
			}
			if (_tmp28_) {
				BirdFontEditPoint* _tmp33_;
				_tmp33_ = ep;
				bird_font_edit_point_convert_to_curve (_tmp33_);
			}
			_g_object_unref0 (ep);
		}
	}
	_g_object_unref0 (p);
	_g_object_unref0 (paths);
	_g_object_unref0 (glyph);
}

void
bird_font_track_tool_set_samples_per_point (BirdFontTrackTool* self,
                                            gdouble s)
{
	g_return_if_fail (self != NULL);
	self->priv->samples_per_point = s;
}

static void
bird_font_track_tool_add_endpoint_and_merge (BirdFontTrackTool* self,
                                             gint x,
                                             gint y)
{
	BirdFontGlyph* glyph = NULL;
	BirdFontPath* p = NULL;
	BirdFontPointSelection* open_path = NULL;
	BirdFontPointSelection* _tmp0_;
	BirdFontPointSelection* joined_path = NULL;
	BirdFontGlyph* _tmp1_;
	GeeArrayList* paths = NULL;
	BirdFontGlyph* _tmp2_;
	GeeArrayList* _tmp3_;
	GeeArrayList* _tmp4_;
	gint _tmp5_;
	gint _tmp6_;
	GeeArrayList* _tmp7_;
	GeeArrayList* _tmp8_;
	gint _tmp9_;
	gint _tmp10_;
	gpointer _tmp11_;
	gboolean _tmp12_ = FALSE;
	BirdFontPath* _tmp27_;
	GeeArrayList* _tmp28_;
	GeeArrayList* _tmp29_;
	gint _tmp30_;
	gint _tmp31_;
	BirdFontEditPoint* last_point = NULL;
	BirdFontPath* _tmp32_;
	BirdFontEditPoint* _tmp33_;
	BirdFontEditPointHandle* handle = NULL;
	BirdFontEditPoint* _tmp34_;
	BirdFontEditPointHandle* _tmp35_;
	BirdFontEditPointHandle* _tmp36_;
	BirdFontEditPointHandle* _tmp37_;
	BirdFontPath* _tmp38_;
	BirdFontPath* _tmp39_;
	BirdFontEditPoint* _tmp40_;
	BirdFontEditPoint* _tmp41_;
	BirdFontPath* _tmp42_;
	BirdFontEditPoint* _tmp43_;
	BirdFontEditPoint* _tmp44_;
	BirdFontPath* _tmp45_;
	BirdFontPath* _tmp46_;
	BirdFontGlyph* _tmp49_;
	g_return_if_fail (self != NULL);
	_tmp0_ = bird_font_track_tool_get_path_with_end_point (self, x, y);
	open_path = _tmp0_;
	_tmp1_ = bird_font_main_window_get_current_glyph ();
	_g_object_unref0 (glyph);
	glyph = _tmp1_;
	_tmp2_ = glyph;
	_tmp3_ = bird_font_glyph_get_visible_paths (_tmp2_);
	paths = _tmp3_;
	_tmp4_ = paths;
	_tmp5_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) _tmp4_);
	_tmp6_ = _tmp5_;
	if (_tmp6_ == 0) {
		g_warning ("TrackTool.vala:284: No path.");
		_g_object_unref0 (paths);
		_g_object_unref0 (joined_path);
		_g_object_unref0 (open_path);
		_g_object_unref0 (p);
		_g_object_unref0 (glyph);
		return;
	}
	_tmp7_ = paths;
	_tmp8_ = paths;
	_tmp9_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) _tmp8_);
	_tmp10_ = _tmp9_;
	_tmp11_ = gee_abstract_list_get ((GeeAbstractList*) _tmp7_, _tmp10_ - 1);
	_g_object_unref0 (p);
	p = (BirdFontPath*) _tmp11_;
	self->priv->draw_freehand = FALSE;
	bird_font_track_tool_convert_points_to_line (self);
	if (self->priv->join_paths) {
		BirdFontPointSelection* _tmp13_;
		_tmp13_ = open_path;
		_tmp12_ = _tmp13_ != NULL;
	} else {
		_tmp12_ = FALSE;
	}
	if (_tmp12_) {
		BirdFontPointSelection* _tmp14_;
		BirdFontPointSelection* _tmp15_;
		BirdFontPointSelection* _tmp16_;
		BirdFontPath* _tmp17_;
		BirdFontPath* _tmp18_;
		BirdFontGlyph* _tmp26_;
		_tmp14_ = open_path;
		_tmp15_ = _g_object_ref0 (G_TYPE_CHECK_INSTANCE_CAST (_tmp14_, BIRD_FONT_TYPE_POINT_SELECTION, BirdFontPointSelection));
		_g_object_unref0 (joined_path);
		joined_path = _tmp15_;
		_tmp16_ = joined_path;
		_tmp17_ = _tmp16_->path;
		_tmp18_ = p;
		if (_tmp17_ == _tmp18_) {
			BirdFontGlyph* _tmp19_;
			BirdFontPath* _tmp20_;
			bird_font_track_tool_delete_last_points_at (self, (gdouble) x, (gdouble) y);
			_tmp19_ = glyph;
			bird_font_glyph_close_path (_tmp19_);
			_tmp20_ = p;
			bird_font_path_close (_tmp20_);
		} else {
			BirdFontPath* _tmp21_;
			BirdFontPointSelection* _tmp22_;
			BirdFontPath* _tmp23_;
			BirdFontPath* _tmp24_;
			_tmp21_ = p;
			_tmp22_ = joined_path;
			_tmp23_ = bird_font_track_tool_merge_paths (_tmp21_, _tmp22_);
			_g_object_unref0 (p);
			p = _tmp23_;
			_tmp24_ = p;
			if (!bird_font_path_is_open (_tmp24_)) {
				BirdFontGlyph* _tmp25_;
				_tmp25_ = glyph;
				bird_font_glyph_close_path (_tmp25_);
			}
		}
		_tmp26_ = glyph;
		bird_font_glyph_clear_active_paths (_tmp26_);
	} else {
		bird_font_track_tool_add_corner (self, (gdouble) x, (gdouble) y);
	}
	_tmp27_ = p;
	_tmp28_ = bird_font_path_get_points (_tmp27_);
	_tmp29_ = _tmp28_;
	_tmp30_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) _tmp29_);
	_tmp31_ = _tmp30_;
	if (_tmp31_ == 0) {
		g_warning ("TrackTool.vala:314: No point.");
		_g_object_unref0 (paths);
		_g_object_unref0 (joined_path);
		_g_object_unref0 (open_path);
		_g_object_unref0 (p);
		_g_object_unref0 (glyph);
		return;
	}
	_tmp32_ = p;
	_tmp33_ = bird_font_path_get_last_point (_tmp32_);
	last_point = _tmp33_;
	_tmp34_ = last_point;
	_tmp35_ = bird_font_edit_point_get_right_handle (_tmp34_);
	_tmp36_ = _g_object_ref0 (_tmp35_);
	handle = _tmp36_;
	_tmp37_ = handle;
	bird_font_edit_point_handle_convert_to_line (_tmp37_);
	_tmp38_ = p;
	bird_font_path_recalculate_linear_handles (_tmp38_);
	_tmp39_ = p;
	_tmp40_ = bird_font_path_get_last_point (_tmp39_);
	_tmp41_ = _tmp40_;
	bird_font_pen_tool_convert_point_type (_tmp41_, BIRD_FONT_POINT_TYPE_CUBIC);
	_g_object_unref0 (_tmp41_);
	_tmp42_ = p;
	_tmp43_ = bird_font_path_get_first_point (_tmp42_);
	_tmp44_ = _tmp43_;
	bird_font_pen_tool_convert_point_type (_tmp44_, BIRD_FONT_POINT_TYPE_CUBIC);
	_g_object_unref0 (_tmp44_);
	_tmp45_ = p;
	bird_font_path_create_list (_tmp45_);
	_tmp46_ = p;
	if (bird_font_pen_tool_is_counter_path (_tmp46_)) {
		BirdFontPath* _tmp47_;
		_tmp47_ = p;
		bird_font_path_force_direction (_tmp47_, BIRD_FONT_DIRECTION_COUNTER_CLOCKWISE);
	} else {
		BirdFontPath* _tmp48_;
		_tmp48_ = p;
		bird_font_path_force_direction (_tmp48_, BIRD_FONT_DIRECTION_CLOCKWISE);
	}
	_tmp49_ = glyph;
	bird_font_glyph_update_view (_tmp49_);
	_g_object_unref0 (handle);
	_g_object_unref0 (last_point);
	_g_object_unref0 (paths);
	_g_object_unref0 (joined_path);
	_g_object_unref0 (open_path);
	_g_object_unref0 (p);
	_g_object_unref0 (glyph);
}

static BirdFontPath*
bird_font_track_tool_merge_paths (BirdFontPath* a,
                                  BirdFontPointSelection* b)
{
	BirdFontGlyph* g = NULL;
	BirdFontPath* merged = NULL;
	BirdFontPath* _tmp0_;
	GeeArrayList* _tmp1_;
	GeeArrayList* _tmp2_;
	gint _tmp3_;
	gint _tmp4_;
	BirdFontPath* _tmp5_;
	GeeArrayList* _tmp6_;
	GeeArrayList* _tmp7_;
	gint _tmp8_;
	gint _tmp9_;
	BirdFontPath* _tmp13_;
	BirdFontPath* _tmp14_;
	BirdFontGlyph* _tmp15_;
	BirdFontGlyph* _tmp16_;
	BirdFontPath* _tmp17_;
	BirdFontEditPoint* _tmp18_;
	BirdFontEditPoint* _tmp19_;
	BirdFontEditPoint* _tmp20_;
	BirdFontEditPoint* _tmp21_;
	BirdFontPath* _tmp22_;
	BirdFontEditPoint* _tmp23_;
	BirdFontEditPoint* _tmp24_;
	BirdFontGlyph* _tmp25_;
	BirdFontGlyph* _tmp26_;
	BirdFontPath* _tmp27_;
	BirdFontPath* _tmp28_;
	BirdFontPath* _tmp29_;
	BirdFontPath* _tmp30_;
	BirdFontPath* _tmp31_;
	BirdFontPath* result;
	g_return_val_if_fail (a != NULL, NULL);
	g_return_val_if_fail (b != NULL, NULL);
	_tmp0_ = bird_font_path_copy (a);
	merged = _tmp0_;
	_tmp1_ = bird_font_path_get_points (a);
	_tmp2_ = _tmp1_;
	_tmp3_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) _tmp2_);
	_tmp4_ = _tmp3_;
	if (_tmp4_ < 2) {
		g_warning ("TrackTool.vala:342: Less than two points in path.");
		result = merged;
		_g_object_unref0 (g);
		return result;
	}
	_tmp5_ = b->path;
	_tmp6_ = bird_font_path_get_points (_tmp5_);
	_tmp7_ = _tmp6_;
	_tmp8_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) _tmp7_);
	_tmp9_ = _tmp8_;
	if (_tmp9_ < 2) {
		g_warning ("TrackTool.vala:347: Less than two points in path.");
		result = merged;
		_g_object_unref0 (g);
		return result;
	}
	if (!bird_font_point_selection_is_first (b)) {
		BirdFontPath* _tmp10_;
		BirdFontPath* _tmp11_;
		BirdFontPath* _tmp12_;
		_tmp10_ = b->path;
		bird_font_path_close (_tmp10_);
		_tmp11_ = b->path;
		bird_font_path_reverse (_tmp11_);
		_tmp12_ = b->path;
		bird_font_path_reopen (_tmp12_);
	}
	_tmp13_ = merged;
	_tmp14_ = b->path;
	bird_font_path_append_path (_tmp13_, _tmp14_);
	_tmp15_ = bird_font_main_window_get_current_glyph ();
	_g_object_unref0 (g);
	g = _tmp15_;
	_tmp16_ = g;
	_tmp17_ = merged;
	bird_font_glyph_add_path (_tmp16_, _tmp17_);
	_tmp18_ = bird_font_path_delete_last_point (a);
	_tmp19_ = _tmp18_;
	_g_object_unref0 (_tmp19_);
	_tmp20_ = bird_font_path_get_last_point (a);
	_tmp21_ = _tmp20_;
	_tmp22_ = b->path;
	_tmp23_ = bird_font_path_get_first_point (_tmp22_);
	_tmp24_ = _tmp23_;
	bird_font_track_tool_update_corner_handle (_tmp21_, _tmp24_);
	_g_object_unref0 (_tmp24_);
	_g_object_unref0 (_tmp21_);
	_tmp25_ = g;
	bird_font_glyph_delete_path (_tmp25_, a);
	_tmp26_ = g;
	_tmp27_ = b->path;
	bird_font_glyph_delete_path (_tmp26_, _tmp27_);
	_tmp28_ = merged;
	bird_font_path_create_list (_tmp28_);
	_tmp29_ = merged;
	bird_font_path_update_region_boundaries (_tmp29_);
	_tmp30_ = merged;
	bird_font_path_recalculate_linear_handles (_tmp30_);
	_tmp31_ = merged;
	bird_font_path_reopen (_tmp31_);
	result = merged;
	_g_object_unref0 (g);
	return result;
}

void
bird_font_track_tool_update_corner_handle (BirdFontEditPoint* end,
                                           BirdFontEditPoint* new_start)
{
	BirdFontEditPointHandle* h1 = NULL;
	BirdFontEditPointHandle* h2 = NULL;
	BirdFontEditPointHandle* _tmp0_;
	BirdFontEditPointHandle* _tmp1_;
	BirdFontEditPointHandle* _tmp2_;
	BirdFontEditPointHandle* _tmp3_;
	g_return_if_fail (end != NULL);
	g_return_if_fail (new_start != NULL);
	_tmp0_ = bird_font_edit_point_get_right_handle (end);
	_tmp1_ = _g_object_ref0 (_tmp0_);
	_g_object_unref0 (h1);
	h1 = _tmp1_;
	_tmp2_ = bird_font_edit_point_get_left_handle (new_start);
	_tmp3_ = _g_object_ref0 (_tmp2_);
	_g_object_unref0 (h2);
	h2 = _tmp3_;
	bird_font_edit_point_handle_convert_to_line (h1);
	bird_font_edit_point_handle_convert_to_line (h2);
	_g_object_unref0 (h2);
	_g_object_unref0 (h1);
}

static BirdFontPointSelection*
bird_font_track_tool_get_path_with_end_point (BirdFontTrackTool* self,
                                              gint x,
                                              gint y)
{
	BirdFontGlyph* glyph = NULL;
	BirdFontGlyph* _tmp0_;
	BirdFontEditPoint* e = NULL;
	BirdFontEditPoint* current_end = NULL;
	BirdFontEditPoint* _tmp1_;
	BirdFontPointSelection* result;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = bird_font_main_window_get_current_glyph ();
	glyph = _tmp0_;
	_tmp1_ = bird_font_edit_point_new ((gdouble) 0, (gdouble) 0, BIRD_FONT_POINT_TYPE_NONE);
	current_end = _tmp1_;
	if (self->priv->draw_freehand) {
		BirdFontPath* _tmp2_;
		BirdFontPath* _tmp3_;
		BirdFontEditPoint* _tmp4_;
		_tmp2_ = bird_font_track_tool_get_active_path (self);
		_tmp3_ = _tmp2_;
		_tmp4_ = bird_font_path_get_last_point (_tmp3_);
		_g_object_unref0 (current_end);
		current_end = _tmp4_;
		_g_object_unref0 (_tmp3_);
	}
	{
		GeeArrayList* _p_list = NULL;
		BirdFontGlyph* _tmp5_;
		GeeArrayList* _tmp6_;
		gint _p_size = 0;
		GeeArrayList* _tmp7_;
		gint _tmp8_;
		gint _tmp9_;
		gint _p_index = 0;
		_tmp5_ = glyph;
		_tmp6_ = bird_font_glyph_get_visible_paths (_tmp5_);
		_p_list = _tmp6_;
		_tmp7_ = _p_list;
		_tmp8_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) _tmp7_);
		_tmp9_ = _tmp8_;
		_p_size = _tmp9_;
		_p_index = -1;
		while (TRUE) {
			gint _tmp10_;
			gint _tmp11_;
			BirdFontPath* p = NULL;
			GeeArrayList* _tmp12_;
			gpointer _tmp13_;
			gboolean _tmp14_ = FALSE;
			BirdFontPath* _tmp15_;
			_p_index = _p_index + 1;
			_tmp10_ = _p_index;
			_tmp11_ = _p_size;
			if (!(_tmp10_ < _tmp11_)) {
				break;
			}
			_tmp12_ = _p_list;
			_tmp13_ = gee_abstract_list_get ((GeeAbstractList*) _tmp12_, _p_index);
			p = (BirdFontPath*) _tmp13_;
			_tmp15_ = p;
			if (bird_font_path_is_open (_tmp15_)) {
				BirdFontPath* _tmp16_;
				GeeArrayList* _tmp17_;
				GeeArrayList* _tmp18_;
				gint _tmp19_;
				gint _tmp20_;
				_tmp16_ = p;
				_tmp17_ = bird_font_path_get_points (_tmp16_);
				_tmp18_ = _tmp17_;
				_tmp19_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) _tmp18_);
				_tmp20_ = _tmp19_;
				_tmp14_ = _tmp20_ > 2;
			} else {
				_tmp14_ = FALSE;
			}
			if (_tmp14_) {
				BirdFontPath* _tmp21_;
				GeeArrayList* _tmp22_;
				GeeArrayList* _tmp23_;
				gpointer _tmp24_;
				BirdFontEditPoint* _tmp25_;
				BirdFontPath* _tmp29_;
				GeeArrayList* _tmp30_;
				GeeArrayList* _tmp31_;
				BirdFontPath* _tmp32_;
				GeeArrayList* _tmp33_;
				GeeArrayList* _tmp34_;
				gint _tmp35_;
				gint _tmp36_;
				gpointer _tmp37_;
				gboolean _tmp38_ = FALSE;
				BirdFontEditPoint* _tmp39_;
				BirdFontEditPoint* _tmp40_;
				_tmp21_ = p;
				_tmp22_ = bird_font_path_get_points (_tmp21_);
				_tmp23_ = _tmp22_;
				_tmp24_ = gee_abstract_list_get ((GeeAbstractList*) _tmp23_, 0);
				_g_object_unref0 (e);
				e = (BirdFontEditPoint*) _tmp24_;
				_tmp25_ = e;
				if (bird_font_pen_tool_is_close_to_point (_tmp25_, (gdouble) x, (gdouble) y)) {
					BirdFontEditPoint* _tmp26_;
					BirdFontPath* _tmp27_;
					BirdFontPointSelection* _tmp28_;
					_tmp26_ = e;
					_tmp27_ = p;
					_tmp28_ = bird_font_point_selection_new (_tmp26_, _tmp27_);
					result = _tmp28_;
					_g_object_unref0 (p);
					_g_object_unref0 (_p_list);
					_g_object_unref0 (current_end);
					_g_object_unref0 (e);
					_g_object_unref0 (glyph);
					return result;
				}
				_tmp29_ = p;
				_tmp30_ = bird_font_path_get_points (_tmp29_);
				_tmp31_ = _tmp30_;
				_tmp32_ = p;
				_tmp33_ = bird_font_path_get_points (_tmp32_);
				_tmp34_ = _tmp33_;
				_tmp35_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) _tmp34_);
				_tmp36_ = _tmp35_;
				_tmp37_ = gee_abstract_list_get ((GeeAbstractList*) _tmp31_, _tmp36_ - 1);
				_g_object_unref0 (e);
				e = (BirdFontEditPoint*) _tmp37_;
				_tmp39_ = current_end;
				_tmp40_ = e;
				if (_tmp39_ != _tmp40_) {
					BirdFontEditPoint* _tmp41_;
					_tmp41_ = e;
					_tmp38_ = bird_font_pen_tool_is_close_to_point (_tmp41_, (gdouble) x, (gdouble) y);
				} else {
					_tmp38_ = FALSE;
				}
				if (_tmp38_) {
					BirdFontEditPoint* _tmp42_;
					BirdFontPath* _tmp43_;
					BirdFontPointSelection* _tmp44_;
					_tmp42_ = e;
					_tmp43_ = p;
					_tmp44_ = bird_font_point_selection_new (_tmp42_, _tmp43_);
					result = _tmp44_;
					_g_object_unref0 (p);
					_g_object_unref0 (_p_list);
					_g_object_unref0 (current_end);
					_g_object_unref0 (e);
					_g_object_unref0 (glyph);
					return result;
				}
			}
			_g_object_unref0 (p);
		}
		_g_object_unref0 (_p_list);
	}
	result = NULL;
	_g_object_unref0 (current_end);
	_g_object_unref0 (e);
	_g_object_unref0 (glyph);
	return result;
}

static void
bird_font_track_tool_record_new_position (BirdFontTrackTool* self,
                                          gint x,
                                          gint y)
{
	BirdFontGlyph* glyph = NULL;
	BirdFontPath* p = NULL;
	BirdFontEditPoint* new_point = NULL;
	gdouble px = 0.0;
	gdouble py = 0.0;
	BirdFontGlyph* _tmp0_;
	BirdFontGlyph* _tmp1_;
	GeeArrayList* _tmp2_;
	gint _tmp3_;
	gint _tmp4_;
	BirdFontGlyph* _tmp5_;
	GeeArrayList* _tmp6_;
	BirdFontGlyph* _tmp7_;
	GeeArrayList* _tmp8_;
	gint _tmp9_;
	gint _tmp10_;
	gpointer _tmp11_;
	BirdFontPath* _tmp12_;
	BirdFontEditPoint* last_point = NULL;
	BirdFontEditPoint* _tmp13_;
	BirdFontPath* _tmp14_;
	GeeArrayList* _tmp15_;
	GeeArrayList* _tmp16_;
	gint _tmp17_;
	gint _tmp18_;
	BirdFontEditPoint* _tmp21_;
	BirdFontPath* _tmp22_;
	BirdFontEditPoint* _tmp23_;
	BirdFontEditPoint* _tmp24_;
	BirdFontEditPoint* _tmp25_;
	gint _tmp26_;
	BirdFontEditPoint* _tmp27_;
	BirdFontEditPoint* _tmp28_;
	BirdFontPath* _tmp29_;
	BirdFontEditPoint* _tmp30_;
	BirdFontEditPoint* _tmp31_;
	BirdFontEditPointHandle* _tmp32_;
	BirdFontPath* _tmp33_;
	GeeArrayList* _tmp34_;
	GeeArrayList* _tmp35_;
	gint _tmp36_;
	gint _tmp37_;
	BirdFontGlyph* _tmp42_;
	g_return_if_fail (self != NULL);
	_tmp0_ = bird_font_main_window_get_current_glyph ();
	_g_object_unref0 (glyph);
	glyph = _tmp0_;
	_tmp1_ = glyph;
	_tmp2_ = _tmp1_->active_paths;
	_tmp3_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) _tmp2_);
	_tmp4_ = _tmp3_;
	if (_tmp4_ == 0) {
		g_warning ("TrackTool.vala:422: No path.");
		_g_object_unref0 (new_point);
		_g_object_unref0 (p);
		_g_object_unref0 (glyph);
		return;
	}
	_tmp5_ = glyph;
	_tmp6_ = _tmp5_->active_paths;
	_tmp7_ = glyph;
	_tmp8_ = _tmp7_->active_paths;
	_tmp9_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) _tmp8_);
	_tmp10_ = _tmp9_;
	_tmp11_ = gee_abstract_list_get ((GeeAbstractList*) _tmp6_, _tmp10_ - 1);
	_g_object_unref0 (p);
	p = (BirdFontPath*) _tmp11_;
	_tmp12_ = p;
	bird_font_path_reopen (_tmp12_);
	_tmp13_ = bird_font_edit_point_new ((gdouble) 0, (gdouble) 0, BIRD_FONT_POINT_TYPE_NONE);
	last_point = _tmp13_;
	_tmp14_ = p;
	_tmp15_ = bird_font_path_get_points (_tmp14_);
	_tmp16_ = _tmp15_;
	_tmp17_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) _tmp16_);
	_tmp18_ = _tmp17_;
	if (_tmp18_ > 0) {
		BirdFontPath* _tmp19_;
		BirdFontEditPoint* _tmp20_;
		_tmp19_ = p;
		_tmp20_ = bird_font_path_get_last_point (_tmp19_);
		_g_object_unref0 (last_point);
		last_point = _tmp20_;
	}
	px = bird_font_glyph_path_coordinate_x ((gdouble) x);
	py = bird_font_glyph_path_coordinate_y ((gdouble) y);
	_tmp21_ = bird_font_edit_point_new (px, py, BIRD_FONT_POINT_TYPE_CUBIC);
	_g_object_unref0 (new_point);
	new_point = _tmp21_;
	_tmp22_ = p;
	_tmp23_ = new_point;
	_tmp24_ = bird_font_path_add_point (_tmp22_, _tmp23_);
	_tmp25_ = _tmp24_;
	_g_object_unref0 (_tmp25_);
	_tmp26_ = self->priv->added_points;
	self->priv->added_points = _tmp26_ + 1;
	_tmp27_ = new_point;
	bird_font_pen_tool_convert_point_to_line (_tmp27_, FALSE);
	_tmp28_ = new_point;
	bird_font_edit_point_set_point_type (_tmp28_, BIRD_FONT_POINT_TYPE_HIDDEN);
	_tmp29_ = p;
	_tmp30_ = new_point;
	bird_font_path_recalculate_linear_handles_for_point (_tmp29_, _tmp30_);
	_tmp31_ = last_point;
	_tmp32_ = bird_font_edit_point_get_right_handle (_tmp31_);
	_tmp32_->length = 0.000001;
	_tmp33_ = p;
	_tmp34_ = bird_font_path_get_points (_tmp33_);
	_tmp35_ = _tmp34_;
	_tmp36_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) _tmp35_);
	_tmp37_ = _tmp36_;
	if (_tmp37_ > 1) {
		BirdFontGlyph* _tmp38_;
		BirdFontEditPoint* _tmp39_;
		BirdFontEditPoint* _tmp40_;
		BirdFontEditPoint* _tmp41_;
		_tmp38_ = glyph;
		_tmp39_ = new_point;
		_tmp40_ = new_point;
		_tmp41_ = bird_font_edit_point_get_prev (_tmp40_);
		bird_font_glyph_redraw_segment (_tmp38_, _tmp39_, _tmp41_);
	}
	_tmp42_ = glyph;
	bird_font_glyph_update_view (_tmp42_);
	self->priv->last_x = x;
	self->priv->last_y = y;
	_g_object_unref0 (last_point);
	_g_object_unref0 (new_point);
	_g_object_unref0 (p);
	_g_object_unref0 (glyph);
}

static gboolean
__lambda162_ (BirdFontTrackTool* self)
{
	gboolean result;
	if (self->priv->draw_freehand) {
		bird_font_track_tool_record_new_position (self, self->priv->last_x, self->priv->last_y);
		bird_font_track_tool_convert_on_timeout (self);
	}
	result = self->priv->draw_freehand;
	return result;
}

static gboolean
___lambda162__gsource_func (gpointer self)
{
	gboolean result;
	result = __lambda162_ ((BirdFontTrackTool*) self);
	return result;
}

static void
bird_font_track_tool_start_update_timer (BirdFontTrackTool* self)
{
	GSource* timer = NULL;
	GSource* _tmp0_;
	g_return_if_fail (self != NULL);
	_tmp0_ = g_timeout_source_new ((guint) 100);
	timer = _tmp0_;
	g_source_set_callback (timer, ___lambda162__gsource_func, g_object_ref (self), g_object_unref);
	g_source_attach (timer, NULL);
	_g_source_unref0 (timer);
}

/** @returns true while the mounse pointer is moving. */
static gboolean
bird_font_track_tool_is_moving (BirdFontTrackTool* self,
                                gint x,
                                gint y)
{
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	result = bird_font_path_distance ((gdouble) x, (gdouble) self->priv->last_x, (gdouble) y, (gdouble) self->priv->last_y) >= ((gdouble) 1);
	return result;
}

/** Add a new point if the update period has ended. */
static void
bird_font_track_tool_convert_on_timeout (BirdFontTrackTool* self)
{
	g_return_if_fail (self != NULL);
	if (!bird_font_track_tool_is_moving (self, self->priv->last_timer_x, self->priv->last_timer_y)) {
		gint _tmp0_;
		_tmp0_ = self->priv->update_cycles;
		self->priv->update_cycles = _tmp0_ + 1;
	} else {
		self->priv->last_timer_x = self->priv->last_x;
		self->priv->last_timer_y = self->priv->last_y;
		self->priv->update_cycles = 0;
	}
	if (((gdouble) self->priv->update_cycles) > (0.7 * 10)) {
		bird_font_track_tool_convert_points_to_line (self);
		self->priv->last_update = bird_font_track_tool_get_current_time ();
		bird_font_track_tool_add_corner (self, (gdouble) self->priv->last_x, (gdouble) self->priv->last_y);
		self->priv->added_points = 0;
		self->priv->update_cycles = 0;
	}
	if (((gdouble) self->priv->added_points) > (80 / self->priv->samples_per_point)) {
		self->priv->last_update = bird_font_track_tool_get_current_time ();
		bird_font_track_tool_convert_points_to_line (self);
	}
}

/** Add a sharp corner instead of a smooth curve. */
static void
bird_font_track_tool_add_corner (BirdFontTrackTool* self,
                                 gdouble px,
                                 gdouble py)
{
	BirdFontEditPoint* p = NULL;
	BirdFontEditPoint* _tmp0_;
	BirdFontEditPointHandle* _tmp1_;
	BirdFontEditPointHandle* _tmp2_;
	BirdFontPath* _tmp3_;
	BirdFontPath* _tmp4_;
	BirdFontGlyph* _tmp5_;
	BirdFontGlyph* _tmp6_;
	g_return_if_fail (self != NULL);
	_tmp0_ = bird_font_edit_point_new (px, py, BIRD_FONT_POINT_TYPE_CUBIC);
	_g_object_unref0 (p);
	p = _tmp0_;
	bird_font_edit_point_set_tie_handle (p, FALSE);
	_tmp1_ = bird_font_edit_point_get_left_handle (p);
	bird_font_edit_point_handle_convert_to_line (_tmp1_);
	_tmp2_ = bird_font_edit_point_get_right_handle (p);
	bird_font_edit_point_handle_convert_to_line (_tmp2_);
	_tmp3_ = bird_font_track_tool_get_active_path (self);
	_tmp4_ = _tmp3_;
	bird_font_path_recalculate_linear_handles_for_point (_tmp4_, p);
	_g_object_unref0 (_tmp4_);
	self->priv->last_update = bird_font_track_tool_get_current_time ();
	_tmp5_ = bird_font_main_window_get_current_glyph ();
	_tmp6_ = _tmp5_;
	bird_font_glyph_update_view (_tmp6_);
	_g_object_unref0 (_tmp6_);
	_g_object_unref0 (p);
}

static BirdFontPath*
bird_font_track_tool_get_active_path (BirdFontTrackTool* self)
{
	BirdFontGlyph* glyph = NULL;
	BirdFontGlyph* _tmp0_;
	BirdFontGlyph* _tmp1_;
	GeeArrayList* _tmp2_;
	gint _tmp3_;
	gint _tmp4_;
	BirdFontGlyph* _tmp6_;
	GeeArrayList* _tmp7_;
	BirdFontGlyph* _tmp8_;
	GeeArrayList* _tmp9_;
	gint _tmp10_;
	gint _tmp11_;
	gpointer _tmp12_;
	BirdFontPath* result;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = bird_font_main_window_get_current_glyph ();
	glyph = _tmp0_;
	_tmp1_ = glyph;
	_tmp2_ = _tmp1_->active_paths;
	_tmp3_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) _tmp2_);
	_tmp4_ = _tmp3_;
	if (_tmp4_ == 0) {
		BirdFontPath* _tmp5_;
		g_warning ("TrackTool.vala:518: No path.");
		_tmp5_ = bird_font_path_new ();
		result = _tmp5_;
		_g_object_unref0 (glyph);
		return result;
	}
	_tmp6_ = glyph;
	_tmp7_ = _tmp6_->active_paths;
	_tmp8_ = glyph;
	_tmp9_ = _tmp8_->active_paths;
	_tmp10_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) _tmp9_);
	_tmp11_ = _tmp10_;
	_tmp12_ = gee_abstract_list_get ((GeeAbstractList*) _tmp7_, _tmp11_ - 1);
	result = (BirdFontPath*) _tmp12_;
	_g_object_unref0 (glyph);
	return result;
}

/** Delete all points close to the pixel at x,y. */
static void
bird_font_track_tool_delete_last_points_at (BirdFontTrackTool* self,
                                            gdouble px,
                                            gdouble py)
{
	BirdFontPath* p = NULL;
	BirdFontPath* _tmp0_;
	BirdFontPath* _tmp1_;
	GeeArrayList* _tmp2_;
	GeeArrayList* _tmp3_;
	gint _tmp4_;
	gint _tmp5_;
	g_return_if_fail (self != NULL);
	_tmp0_ = bird_font_track_tool_get_active_path (self);
	_g_object_unref0 (p);
	p = _tmp0_;
	_tmp1_ = p;
	_tmp2_ = bird_font_path_get_points (_tmp1_);
	_tmp3_ = _tmp2_;
	_tmp4_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) _tmp3_);
	_tmp5_ = _tmp4_;
	if (G_UNLIKELY (_tmp5_ == 0)) {
		g_warning ("TrackTool.vala:532: Missing point.");
		_g_object_unref0 (p);
		return;
	}
	while (TRUE) {
		gboolean _tmp6_ = FALSE;
		BirdFontPath* _tmp7_;
		GeeArrayList* _tmp8_;
		GeeArrayList* _tmp9_;
		gint _tmp10_;
		gint _tmp11_;
		BirdFontPath* _tmp22_;
		BirdFontEditPoint* _tmp23_;
		BirdFontEditPoint* _tmp24_;
		_tmp7_ = p;
		_tmp8_ = bird_font_path_get_points (_tmp7_);
		_tmp9_ = _tmp8_;
		_tmp10_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) _tmp9_);
		_tmp11_ = _tmp10_;
		if (_tmp11_ > 0) {
			BirdFontPath* _tmp12_;
			GeeArrayList* _tmp13_;
			GeeArrayList* _tmp14_;
			BirdFontPath* _tmp15_;
			GeeArrayList* _tmp16_;
			GeeArrayList* _tmp17_;
			gint _tmp18_;
			gint _tmp19_;
			gpointer _tmp20_;
			BirdFontEditPoint* _tmp21_;
			_tmp12_ = p;
			_tmp13_ = bird_font_path_get_points (_tmp12_);
			_tmp14_ = _tmp13_;
			_tmp15_ = p;
			_tmp16_ = bird_font_path_get_points (_tmp15_);
			_tmp17_ = _tmp16_;
			_tmp18_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) _tmp17_);
			_tmp19_ = _tmp18_;
			_tmp20_ = gee_abstract_list_get ((GeeAbstractList*) _tmp14_, _tmp19_ - 1);
			_tmp21_ = (BirdFontEditPoint*) _tmp20_;
			_tmp6_ = bird_font_track_tool_is_close (self, _tmp21_, px, py);
			_g_object_unref0 (_tmp21_);
		} else {
			_tmp6_ = FALSE;
		}
		if (!_tmp6_) {
			break;
		}
		_tmp22_ = p;
		_tmp23_ = bird_font_path_delete_last_point (_tmp22_);
		_tmp24_ = _tmp23_;
		_g_object_unref0 (_tmp24_);
	}
	_g_object_unref0 (p);
}

/** @return true if the new point point is closer than a few pixels from p. */
static gboolean
bird_font_track_tool_is_close (BirdFontTrackTool* self,
                               BirdFontEditPoint* p,
                               gdouble x,
                               gdouble y)
{
	BirdFontGlyph* glyph = NULL;
	BirdFontGlyph* _tmp0_;
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	g_return_val_if_fail (p != NULL, FALSE);
	_tmp0_ = bird_font_main_window_get_current_glyph ();
	glyph = _tmp0_;
	result = (glyph->view_zoom * bird_font_path_distance (p->x, x, p->y, y)) < ((gdouble) 5);
	_g_object_unref0 (glyph);
	return result;
}

/** Take the average of tracked points and create a smooth line.
 * @return the last removed point.
 */
void
bird_font_track_tool_convert_points_to_line (BirdFontTrackTool* self)
{
	gdouble sum_x = 0.0;
	gdouble sum_y = 0.0;
	BirdFontPath* p = NULL;
	BirdFontGlyph* glyph = NULL;
	GeeArrayList* points = NULL;
	GeeArrayList* _tmp0_;
	BirdFontGlyph* _tmp1_;
	GeeArrayList* paths = NULL;
	BirdFontGlyph* _tmp2_;
	GeeArrayList* _tmp3_;
	GeeArrayList* _tmp4_;
	gint _tmp5_;
	gint _tmp6_;
	GeeArrayList* _tmp7_;
	GeeArrayList* _tmp8_;
	gint _tmp9_;
	gint _tmp10_;
	gpointer _tmp11_;
	BirdFontPath* _tmp12_;
	GeeArrayList* _tmp13_;
	GeeArrayList* _tmp14_;
	gint _tmp15_;
	gint _tmp16_;
	gint start = 0;
	BirdFontPath* _tmp17_;
	GeeArrayList* _tmp18_;
	GeeArrayList* _tmp19_;
	gint _tmp20_;
	gint _tmp21_;
	gint stop = 0;
	BirdFontPath* _tmp22_;
	GeeArrayList* _tmp23_;
	GeeArrayList* _tmp24_;
	gint _tmp25_;
	gint _tmp26_;
	BirdFontEditPoint* end = NULL;
	BirdFontPath* _tmp27_;
	GeeArrayList* _tmp28_;
	GeeArrayList* _tmp29_;
	gpointer _tmp30_;
	BirdFontPath* segment = NULL;
	BirdFontPath* _tmp31_;
	BirdFontPath* _tmp32_;
	BirdFontPath* _tmp38_;
	BirdFontPath* _tmp39_;
	BirdFontPath* _tmp40_;
	BirdFontEditPoint* _tmp41_;
	BirdFontEditPoint* _tmp42_;
	BirdFontGlyph* _tmp43_;
	BirdFontPath* _tmp44_;
	g_return_if_fail (self != NULL);
	_tmp0_ = gee_array_list_new (BIRD_FONT_TYPE_EDIT_POINT, (GBoxedCopyFunc) g_object_ref, (GDestroyNotify) g_object_unref, NULL, NULL, NULL);
	_g_object_unref0 (points);
	points = _tmp0_;
	_tmp1_ = bird_font_main_window_get_current_glyph ();
	_g_object_unref0 (glyph);
	glyph = _tmp1_;
	_tmp2_ = glyph;
	_tmp3_ = bird_font_glyph_get_visible_paths (_tmp2_);
	paths = _tmp3_;
	_tmp4_ = paths;
	_tmp5_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) _tmp4_);
	_tmp6_ = _tmp5_;
	if (_tmp6_ == 0) {
		g_warning ("TrackTool.vala:561: No path.");
		_g_object_unref0 (paths);
		_g_object_unref0 (points);
		_g_object_unref0 (glyph);
		_g_object_unref0 (p);
		return;
	}
	_tmp7_ = paths;
	_tmp8_ = paths;
	_tmp9_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) _tmp8_);
	_tmp10_ = _tmp9_;
	_tmp11_ = gee_abstract_list_get ((GeeAbstractList*) _tmp7_, _tmp10_ - 1);
	_g_object_unref0 (p);
	p = (BirdFontPath*) _tmp11_;
	if (self->priv->added_points == 0) {
		_g_object_unref0 (paths);
		_g_object_unref0 (points);
		_g_object_unref0 (glyph);
		_g_object_unref0 (p);
		return;
	}
	_tmp12_ = p;
	_tmp13_ = bird_font_path_get_points (_tmp12_);
	_tmp14_ = _tmp13_;
	_tmp15_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) _tmp14_);
	_tmp16_ = _tmp15_;
	if (G_UNLIKELY (_tmp16_ < self->priv->added_points)) {
		g_warning ("TrackTool.vala:572: Missing point.");
		_g_object_unref0 (paths);
		_g_object_unref0 (points);
		_g_object_unref0 (glyph);
		_g_object_unref0 (p);
		return;
	}
	sum_x = (gdouble) 0;
	sum_y = (gdouble) 0;
	_tmp17_ = p;
	_tmp18_ = bird_font_path_get_points (_tmp17_);
	_tmp19_ = _tmp18_;
	_tmp20_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) _tmp19_);
	_tmp21_ = _tmp20_;
	start = (_tmp21_ - 1) - self->priv->added_points;
	_tmp22_ = p;
	_tmp23_ = bird_font_path_get_points (_tmp22_);
	_tmp24_ = _tmp23_;
	_tmp25_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) _tmp24_);
	_tmp26_ = _tmp25_;
	stop = _tmp26_ - 1;
	_tmp27_ = p;
	_tmp28_ = bird_font_path_get_points (_tmp27_);
	_tmp29_ = _tmp28_;
	_tmp30_ = gee_abstract_list_get ((GeeAbstractList*) _tmp29_, stop);
	end = (BirdFontEditPoint*) _tmp30_;
	_tmp31_ = p;
	_tmp32_ = bird_font_stroke_tool_fit_bezier_path (_tmp31_, start, stop, 5.0 / self->priv->samples_per_point);
	segment = _tmp32_;
	{
		gint i = 0;
		i = 0;
		{
			gboolean _tmp33_ = FALSE;
			_tmp33_ = TRUE;
			while (TRUE) {
				BirdFontPath* _tmp35_;
				BirdFontEditPoint* _tmp36_;
				BirdFontEditPoint* _tmp37_;
				if (!_tmp33_) {
					gint _tmp34_;
					_tmp34_ = i;
					i = _tmp34_ + 1;
				}
				_tmp33_ = FALSE;
				if (!(i < self->priv->added_points)) {
					break;
				}
				_tmp35_ = p;
				_tmp36_ = bird_font_path_delete_last_point (_tmp35_);
				_tmp37_ = _tmp36_;
				_g_object_unref0 (_tmp37_);
			}
		}
	}
	_tmp38_ = p;
	_tmp39_ = segment;
	bird_font_path_append_path (_tmp38_, _tmp39_);
	_tmp40_ = p;
	bird_font_path_remove_points_on_points (_tmp40_, 0.00001);
	_tmp41_ = end;
	_tmp42_ = end;
	bird_font_track_tool_add_corner (self, _tmp41_->x, _tmp42_->y);
	self->priv->added_points = 0;
	self->priv->last_update = bird_font_track_tool_get_current_time ();
	_tmp43_ = glyph;
	bird_font_glyph_update_view (_tmp43_);
	_tmp44_ = p;
	bird_font_path_reset_stroke (_tmp44_);
	_g_object_unref0 (segment);
	_g_object_unref0 (end);
	_g_object_unref0 (paths);
	_g_object_unref0 (points);
	_g_object_unref0 (glyph);
	_g_object_unref0 (p);
}

/** @return current time in milli seconds. */
gdouble
bird_font_track_tool_get_current_time (void)
{
	gdouble result;
	result = g_get_real_time () / 1000.0;
	return result;
}

static void
bird_font_track_tool_class_init (BirdFontTrackToolClass * klass,
                                 gpointer klass_data)
{
	bird_font_track_tool_parent_class = g_type_class_peek_parent (klass);
	g_type_class_adjust_private_offset (klass, &BirdFontTrackTool_private_offset);
	G_OBJECT_CLASS (klass)->finalize = bird_font_track_tool_finalize;
}

static void
bird_font_track_tool_instance_init (BirdFontTrackTool * self,
                                    gpointer klass)
{
	self->priv = bird_font_track_tool_get_instance_private (self);
	self->priv->draw_freehand = FALSE;
	self->priv->added_points = 0;
	self->priv->last_update = (gdouble) 0;
	self->priv->last_x = 0;
	self->priv->last_y = 0;
	self->priv->last_timer_x = 0;
	self->priv->last_timer_y = 0;
	self->priv->update_cycles = 0;
	self->priv->join_x = -1;
	self->priv->join_y = -1;
	self->priv->join_paths = FALSE;
	self->priv->samples_per_point = (gdouble) 1;
	self->priv->drawing = FALSE;
}

static void
bird_font_track_tool_finalize (GObject * obj)
{
	BirdFontTrackTool * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, BIRD_FONT_TYPE_TRACK_TOOL, BirdFontTrackTool);
	G_OBJECT_CLASS (bird_font_track_tool_parent_class)->finalize (obj);
}

/** A tool that lets the user draw fonts with the mouse 
  * instead of adding bezér points one by one.
  */
static GType
bird_font_track_tool_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (BirdFontTrackToolClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) bird_font_track_tool_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (BirdFontTrackTool), 0, (GInstanceInitFunc) bird_font_track_tool_instance_init, NULL };
	GType bird_font_track_tool_type_id;
	bird_font_track_tool_type_id = g_type_register_static (BIRD_FONT_TYPE_TOOL, "BirdFontTrackTool", &g_define_type_info, 0);
	BirdFontTrackTool_private_offset = g_type_add_instance_private (bird_font_track_tool_type_id, sizeof (BirdFontTrackToolPrivate));
	return bird_font_track_tool_type_id;
}

GType
bird_font_track_tool_get_type (void)
{
	static volatile gsize bird_font_track_tool_type_id__once = 0;
	if (g_once_init_enter (&bird_font_track_tool_type_id__once)) {
		GType bird_font_track_tool_type_id;
		bird_font_track_tool_type_id = bird_font_track_tool_get_type_once ();
		g_once_init_leave (&bird_font_track_tool_type_id__once, bird_font_track_tool_type_id);
	}
	return bird_font_track_tool_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;
}

