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

/* 
 * SmartSim - Digital Logic Circuit Designer and Simulator
 *   
 *   This program is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation, either version 3 of the License, or
 *   (at your option) any later version.
 *   
 *   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, see <http://www.gnu.org/licenses/>.
 *   
 *   Filename: pindef.vala
 *   
 *   Copyright Ashley Newson 2013
 */

#include <glib.h>
#include <glib-object.h>
#include <float.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>
#include <libxml/tree.h>
#include <stdio.h>
#include <libxml/xmlwriter.h>
#include <cairo.h>
#include <gobject/gvaluecollector.h>


#define TYPE_PIN_DEF (pin_def_get_type ())
#define PIN_DEF(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_PIN_DEF, PinDef))
#define PIN_DEF_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_PIN_DEF, PinDefClass))
#define IS_PIN_DEF(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_PIN_DEF))
#define IS_PIN_DEF_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_PIN_DEF))
#define PIN_DEF_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_PIN_DEF, PinDefClass))

typedef struct _PinDef PinDef;
typedef struct _PinDefClass PinDefClass;
typedef struct _PinDefPrivate PinDefPrivate;

#define TYPE_DIRECTION (direction_get_type ())

#define TYPE_FLOW (flow_get_type ())

#define PIN_DEF_TYPE_LABEL_TYPE (pin_def_label_type_get_type ())
#define _g_free0(var) (var = (g_free (var), NULL))
typedef struct _ParamSpecPinDef ParamSpecPinDef;

typedef enum  {
	DIRECTION_NONE,
	DIRECTION_RIGHT,
	DIRECTION_DOWN,
	DIRECTION_LEFT,
	DIRECTION_UP,
	DIRECTION_HORIZONTAL,
	DIRECTION_VERTICAL,
	DIRECTION_DIAGONAL
} Direction;

typedef enum  {
	FLOW_NONE,
	FLOW_IN,
	FLOW_OUT,
	FLOW_BIDIRECTIONAL
} Flow;

typedef enum  {
	PIN_DEF_LABEL_TYPE_NONE,
	PIN_DEF_LABEL_TYPE_TEXT,
	PIN_DEF_LABEL_TYPE_TEXTBAR,
	PIN_DEF_LABEL_TYPE_CLOCK
} PinDefLabelType;

struct _PinDef {
	GTypeInstance parent_instance;
	volatile int ref_count;
	PinDefPrivate * priv;
	gint x;
	gint y;
	gint xLabel;
	gint yLabel;
	gint xConnect;
	gint yConnect;
	Direction direction;
	gint length;
	gboolean array;
	Flow flow;
	gint defaultArraySize;
	gint idealSpace;
	gfloat minSpace;
	gchar* label;
	gboolean required;
	gboolean userArrayResize;
	gboolean showDefault;
	PinDefLabelType labelType;
};

struct _PinDefClass {
	GTypeClass parent_class;
	void (*finalize) (PinDef *self);
};

struct _ParamSpecPinDef {
	GParamSpec parent_instance;
};


static gpointer pin_def_parent_class = NULL;

gpointer pin_def_ref (gpointer instance);
void pin_def_unref (gpointer instance);
GParamSpec* param_spec_pin_def (const gchar* name, const gchar* nick, const gchar* blurb, GType object_type, GParamFlags flags);
void value_set_pin_def (GValue* value, gpointer v_object);
void value_take_pin_def (GValue* value, gpointer v_object);
gpointer value_get_pin_def (const GValue* value);
GType pin_def_get_type (void) G_GNUC_CONST;
GType direction_get_type (void) G_GNUC_CONST;
GType flow_get_type (void) G_GNUC_CONST;
GType pin_def_label_type_get_type (void) G_GNUC_CONST;
enum  {
	PIN_DEF_DUMMY_PROPERTY
};
PinDef* pin_def_new (gint x, gint y, Direction direction, Flow flow, gint length, gboolean array, gint defaultArraySize, gint idealSpace, gfloat minSpace, const gchar* label, PinDefLabelType labelType, gboolean required, gboolean userArrayResize, gboolean showDefault);
PinDef* pin_def_construct (GType object_type, gint x, gint y, Direction direction, Flow flow, gint length, gboolean array, gint defaultArraySize, gint idealSpace, gfloat minSpace, const gchar* label, PinDefLabelType labelType, gboolean required, gboolean userArrayResize, gboolean showDefault);
void pin_def_set_position (PinDef* self, gint x, gint y, gint length, Direction direction);
PinDef* pin_def_new_load (xmlNode* xmlnode);
PinDef* pin_def_construct_load (GType object_type, xmlNode* xmlnode);
void pin_def_save (PinDef* self, xmlTextWriter* xmlWriter, gint id);
void pin_def_render (PinDef* self, cairo_t* context, gboolean invert);
static void pin_def_finalize (PinDef* obj);


/**
 * Describes the appearance of the label
 */
GType pin_def_label_type_get_type (void) {
	static volatile gsize pin_def_label_type_type_id__volatile = 0;
	if (g_once_init_enter (&pin_def_label_type_type_id__volatile)) {
		static const GEnumValue values[] = {{PIN_DEF_LABEL_TYPE_NONE, "PIN_DEF_LABEL_TYPE_NONE", "none"}, {PIN_DEF_LABEL_TYPE_TEXT, "PIN_DEF_LABEL_TYPE_TEXT", "text"}, {PIN_DEF_LABEL_TYPE_TEXTBAR, "PIN_DEF_LABEL_TYPE_TEXTBAR", "textbar"}, {PIN_DEF_LABEL_TYPE_CLOCK, "PIN_DEF_LABEL_TYPE_CLOCK", "clock"}, {0, NULL, NULL}};
		GType pin_def_label_type_type_id;
		pin_def_label_type_type_id = g_enum_register_static ("PinDefLabelType", values);
		g_once_init_leave (&pin_def_label_type_type_id__volatile, pin_def_label_type_type_id);
	}
	return pin_def_label_type_type_id__volatile;
}


/**
 * Creates a new PinDef which the given properties.
 */
PinDef* pin_def_construct (GType object_type, gint x, gint y, Direction direction, Flow flow, gint length, gboolean array, gint defaultArraySize, gint idealSpace, gfloat minSpace, const gchar* label, PinDefLabelType labelType, gboolean required, gboolean userArrayResize, gboolean showDefault) {
	PinDef* self = NULL;
	Flow _tmp0_ = 0;
	gboolean _tmp1_ = FALSE;
	gint _tmp2_ = 0;
	gint _tmp3_ = 0;
	gfloat _tmp4_ = 0.0F;
	const gchar* _tmp5_ = NULL;
	gchar* _tmp6_ = NULL;
	PinDefLabelType _tmp7_ = 0;
	gboolean _tmp8_ = FALSE;
	gboolean _tmp9_ = FALSE;
	gboolean _tmp10_ = FALSE;
	gint _tmp11_ = 0;
	gint _tmp12_ = 0;
	gint _tmp13_ = 0;
	Direction _tmp14_ = 0;
	g_return_val_if_fail (label != NULL, NULL);
	self = (PinDef*) g_type_create_instance (object_type);
	_tmp0_ = flow;
	self->flow = _tmp0_;
	_tmp1_ = array;
	self->array = _tmp1_;
	_tmp2_ = defaultArraySize;
	self->defaultArraySize = _tmp2_;
	_tmp3_ = idealSpace;
	self->idealSpace = _tmp3_;
	_tmp4_ = minSpace;
	self->minSpace = _tmp4_;
	_tmp5_ = label;
	_tmp6_ = g_strdup (_tmp5_);
	_g_free0 (self->label);
	self->label = _tmp6_;
	_tmp7_ = labelType;
	self->labelType = _tmp7_;
	_tmp8_ = required;
	self->required = _tmp8_;
	_tmp9_ = userArrayResize;
	self->userArrayResize = _tmp9_;
	_tmp10_ = showDefault;
	self->showDefault = _tmp10_;
	_tmp11_ = x;
	_tmp12_ = y;
	_tmp13_ = length;
	_tmp14_ = direction;
	pin_def_set_position (self, _tmp11_, _tmp12_, _tmp13_, _tmp14_);
	return self;
}


PinDef* pin_def_new (gint x, gint y, Direction direction, Flow flow, gint length, gboolean array, gint defaultArraySize, gint idealSpace, gfloat minSpace, const gchar* label, PinDefLabelType labelType, gboolean required, gboolean userArrayResize, gboolean showDefault) {
	return pin_def_construct (TYPE_PIN_DEF, x, y, direction, flow, length, array, defaultArraySize, idealSpace, minSpace, label, labelType, required, userArrayResize, showDefault);
}


/**
 * Loads a PinDef from a file using libxml.
 */
static gboolean bool_parse (const gchar* str) {
	gboolean result = FALSE;
	const gchar* _tmp0_ = NULL;
	g_return_val_if_fail (str != NULL, FALSE);
	_tmp0_ = str;
	if (g_strcmp0 (_tmp0_, "true") == 0) {
		result = TRUE;
		return result;
	} else {
		result = FALSE;
		return result;
	}
}


static gdouble double_parse (const gchar* str) {
	gdouble result = 0.0;
	const gchar* _tmp0_ = NULL;
	gdouble _tmp1_ = 0.0;
	g_return_val_if_fail (str != NULL, 0.0);
	_tmp0_ = str;
	_tmp1_ = g_ascii_strtod (_tmp0_, NULL);
	result = _tmp1_;
	return result;
}


PinDef* pin_def_construct_load (GType object_type, xmlNode* xmlnode) {
	PinDef* self = NULL;
	gchar* _tmp0_ = NULL;
	gint x = 0;
	gint y = 0;
	Direction direction = 0;
	gint length = 0;
	Flow _tmp79_ = 0;
	gint _tmp81_ = 0;
	gint _tmp82_ = 0;
	gint _tmp83_ = 0;
	Direction _tmp84_ = 0;
	self = (PinDef*) g_type_create_instance (object_type);
	self->flow = FLOW_NONE;
	self->array = FALSE;
	self->defaultArraySize = 1;
	self->idealSpace = 0;
	self->minSpace = (gfloat) 0;
	_tmp0_ = g_strdup ("");
	_g_free0 (self->label);
	self->label = _tmp0_;
	self->labelType = PIN_DEF_LABEL_TYPE_NONE;
	self->required = TRUE;
	self->userArrayResize = TRUE;
	self->showDefault = TRUE;
	x = 0;
	y = 0;
	direction = DIRECTION_NONE;
	length = 1;
	{
		xmlAttr* xmlattr = NULL;
		xmlNode* _tmp1_ = NULL;
		xmlAttr* _tmp2_ = NULL;
		_tmp1_ = xmlnode;
		_tmp2_ = _tmp1_->properties;
		xmlattr = _tmp2_;
		{
			gboolean _tmp3_ = FALSE;
			_tmp3_ = TRUE;
			while (TRUE) {
				xmlAttr* _tmp6_ = NULL;
				xmlAttr* _tmp7_ = NULL;
				const gchar* _tmp8_ = NULL;
				const gchar* _tmp9_ = NULL;
				GQuark _tmp11_ = 0U;
				static GQuark _tmp10_label0 = 0;
				static GQuark _tmp10_label1 = 0;
				static GQuark _tmp10_label2 = 0;
				static GQuark _tmp10_label3 = 0;
				static GQuark _tmp10_label4 = 0;
				static GQuark _tmp10_label5 = 0;
				static GQuark _tmp10_label6 = 0;
				static GQuark _tmp10_label7 = 0;
				static GQuark _tmp10_label8 = 0;
				static GQuark _tmp10_label9 = 0;
				static GQuark _tmp10_label10 = 0;
				static GQuark _tmp10_label11 = 0;
				static GQuark _tmp10_label12 = 0;
				static GQuark _tmp10_label13 = 0;
				static GQuark _tmp10_label14 = 0;
				if (!_tmp3_) {
					xmlAttr* _tmp4_ = NULL;
					xmlAttr* _tmp5_ = NULL;
					_tmp4_ = xmlattr;
					_tmp5_ = _tmp4_->next;
					xmlattr = _tmp5_;
				}
				_tmp3_ = FALSE;
				_tmp6_ = xmlattr;
				if (!(_tmp6_ != NULL)) {
					break;
				}
				_tmp7_ = xmlattr;
				_tmp8_ = _tmp7_->name;
				_tmp9_ = _tmp8_;
				_tmp11_ = (NULL == _tmp9_) ? 0 : g_quark_from_string (_tmp9_);
				if (_tmp11_ == ((0 != _tmp10_label0) ? _tmp10_label0 : (_tmp10_label0 = g_quark_from_static_string ("x")))) {
					switch (0) {
						default:
						{
							xmlAttr* _tmp12_ = NULL;
							xmlNode* _tmp13_ = NULL;
							const gchar* _tmp14_ = NULL;
							gint _tmp15_ = 0;
							_tmp12_ = xmlattr;
							_tmp13_ = _tmp12_->children;
							_tmp14_ = _tmp13_->content;
							_tmp15_ = atoi (_tmp14_);
							x = _tmp15_;
							break;
						}
					}
				} else if (_tmp11_ == ((0 != _tmp10_label1) ? _tmp10_label1 : (_tmp10_label1 = g_quark_from_static_string ("y")))) {
					switch (0) {
						default:
						{
							xmlAttr* _tmp16_ = NULL;
							xmlNode* _tmp17_ = NULL;
							const gchar* _tmp18_ = NULL;
							gint _tmp19_ = 0;
							_tmp16_ = xmlattr;
							_tmp17_ = _tmp16_->children;
							_tmp18_ = _tmp17_->content;
							_tmp19_ = atoi (_tmp18_);
							y = _tmp19_;
							break;
						}
					}
				} else if (_tmp11_ == ((0 != _tmp10_label2) ? _tmp10_label2 : (_tmp10_label2 = g_quark_from_static_string ("direction")))) {
					switch (0) {
						default:
						{
							xmlAttr* _tmp20_ = NULL;
							xmlNode* _tmp21_ = NULL;
							const gchar* _tmp22_ = NULL;
							const gchar* _tmp23_ = NULL;
							GQuark _tmp25_ = 0U;
							static GQuark _tmp24_label0 = 0;
							static GQuark _tmp24_label1 = 0;
							static GQuark _tmp24_label2 = 0;
							static GQuark _tmp24_label3 = 0;
							_tmp20_ = xmlattr;
							_tmp21_ = _tmp20_->children;
							_tmp22_ = _tmp21_->content;
							_tmp23_ = _tmp22_;
							_tmp25_ = (NULL == _tmp23_) ? 0 : g_quark_from_string (_tmp23_);
							if (_tmp25_ == ((0 != _tmp24_label0) ? _tmp24_label0 : (_tmp24_label0 = g_quark_from_static_string ("left")))) {
								switch (0) {
									default:
									{
										direction = DIRECTION_LEFT;
										break;
									}
								}
							} else if (_tmp25_ == ((0 != _tmp24_label1) ? _tmp24_label1 : (_tmp24_label1 = g_quark_from_static_string ("down")))) {
								switch (0) {
									default:
									{
										direction = DIRECTION_DOWN;
										break;
									}
								}
							} else if (_tmp25_ == ((0 != _tmp24_label2) ? _tmp24_label2 : (_tmp24_label2 = g_quark_from_static_string ("right")))) {
								switch (0) {
									default:
									{
										direction = DIRECTION_RIGHT;
										break;
									}
								}
							} else if (_tmp25_ == ((0 != _tmp24_label3) ? _tmp24_label3 : (_tmp24_label3 = g_quark_from_static_string ("up")))) {
								switch (0) {
									default:
									{
										direction = DIRECTION_UP;
										break;
									}
								}
							} else {
								switch (0) {
									default:
									{
										direction = DIRECTION_NONE;
										break;
									}
								}
							}
							break;
						}
					}
				} else if (_tmp11_ == ((0 != _tmp10_label3) ? _tmp10_label3 : (_tmp10_label3 = g_quark_from_static_string ("length")))) {
					switch (0) {
						default:
						{
							xmlAttr* _tmp26_ = NULL;
							xmlNode* _tmp27_ = NULL;
							const gchar* _tmp28_ = NULL;
							gint _tmp29_ = 0;
							_tmp26_ = xmlattr;
							_tmp27_ = _tmp26_->children;
							_tmp28_ = _tmp27_->content;
							_tmp29_ = atoi (_tmp28_);
							length = _tmp29_;
							break;
						}
					}
				} else if (_tmp11_ == ((0 != _tmp10_label4) ? _tmp10_label4 : (_tmp10_label4 = g_quark_from_static_string ("flow")))) {
					switch (0) {
						default:
						{
							xmlAttr* _tmp30_ = NULL;
							xmlNode* _tmp31_ = NULL;
							const gchar* _tmp32_ = NULL;
							const gchar* _tmp33_ = NULL;
							GQuark _tmp35_ = 0U;
							static GQuark _tmp34_label0 = 0;
							static GQuark _tmp34_label1 = 0;
							static GQuark _tmp34_label2 = 0;
							_tmp30_ = xmlattr;
							_tmp31_ = _tmp30_->children;
							_tmp32_ = _tmp31_->content;
							_tmp33_ = _tmp32_;
							_tmp35_ = (NULL == _tmp33_) ? 0 : g_quark_from_string (_tmp33_);
							if (_tmp35_ == ((0 != _tmp34_label0) ? _tmp34_label0 : (_tmp34_label0 = g_quark_from_static_string ("in")))) {
								switch (0) {
									default:
									{
										self->flow = FLOW_IN;
										break;
									}
								}
							} else if (_tmp35_ == ((0 != _tmp34_label1) ? _tmp34_label1 : (_tmp34_label1 = g_quark_from_static_string ("out")))) {
								switch (0) {
									default:
									{
										self->flow = FLOW_OUT;
										break;
									}
								}
							} else if (_tmp35_ == ((0 != _tmp34_label2) ? _tmp34_label2 : (_tmp34_label2 = g_quark_from_static_string ("bi")))) {
								switch (0) {
									default:
									{
										self->flow = FLOW_BIDIRECTIONAL;
										break;
									}
								}
							} else {
								switch (0) {
									default:
									{
										FILE* _tmp36_ = NULL;
										_tmp36_ = stdout;
										fprintf (_tmp36_, "Error: Invalid flow\n");
										break;
									}
								}
							}
							break;
						}
					}
				} else if (_tmp11_ == ((0 != _tmp10_label5) ? _tmp10_label5 : (_tmp10_label5 = g_quark_from_static_string ("array")))) {
					switch (0) {
						default:
						{
							xmlAttr* _tmp37_ = NULL;
							xmlNode* _tmp38_ = NULL;
							const gchar* _tmp39_ = NULL;
							gboolean _tmp40_ = FALSE;
							_tmp37_ = xmlattr;
							_tmp38_ = _tmp37_->children;
							_tmp39_ = _tmp38_->content;
							_tmp40_ = bool_parse (_tmp39_);
							self->array = _tmp40_;
							break;
						}
					}
				} else if (_tmp11_ == ((0 != _tmp10_label6) ? _tmp10_label6 : (_tmp10_label6 = g_quark_from_static_string ("arraydefault")))) {
					switch (0) {
						default:
						{
							xmlAttr* _tmp41_ = NULL;
							xmlNode* _tmp42_ = NULL;
							const gchar* _tmp43_ = NULL;
							gint _tmp44_ = 0;
							_tmp41_ = xmlattr;
							_tmp42_ = _tmp41_->children;
							_tmp43_ = _tmp42_->content;
							_tmp44_ = atoi (_tmp43_);
							self->defaultArraySize = _tmp44_;
							break;
						}
					}
				} else if (_tmp11_ == ((0 != _tmp10_label7) ? _tmp10_label7 : (_tmp10_label7 = g_quark_from_static_string ("idealspace")))) {
					switch (0) {
						default:
						{
							xmlAttr* _tmp45_ = NULL;
							xmlNode* _tmp46_ = NULL;
							const gchar* _tmp47_ = NULL;
							gint _tmp48_ = 0;
							_tmp45_ = xmlattr;
							_tmp46_ = _tmp45_->children;
							_tmp47_ = _tmp46_->content;
							_tmp48_ = atoi (_tmp47_);
							self->idealSpace = _tmp48_;
							break;
						}
					}
				} else if (_tmp11_ == ((0 != _tmp10_label8) ? _tmp10_label8 : (_tmp10_label8 = g_quark_from_static_string ("minspace")))) {
					switch (0) {
						default:
						{
							xmlAttr* _tmp49_ = NULL;
							xmlNode* _tmp50_ = NULL;
							const gchar* _tmp51_ = NULL;
							gdouble _tmp52_ = 0.0;
							_tmp49_ = xmlattr;
							_tmp50_ = _tmp49_->children;
							_tmp51_ = _tmp50_->content;
							_tmp52_ = double_parse (_tmp51_);
							self->minSpace = (gfloat) _tmp52_;
							break;
						}
					}
				} else if (_tmp11_ == ((0 != _tmp10_label9) ? _tmp10_label9 : (_tmp10_label9 = g_quark_from_static_string ("label")))) {
					switch (0) {
						default:
						{
							xmlAttr* _tmp53_ = NULL;
							xmlNode* _tmp54_ = NULL;
							const gchar* _tmp55_ = NULL;
							gchar* _tmp56_ = NULL;
							_tmp53_ = xmlattr;
							_tmp54_ = _tmp53_->children;
							_tmp55_ = _tmp54_->content;
							_tmp56_ = g_strdup (_tmp55_);
							_g_free0 (self->label);
							self->label = _tmp56_;
							self->labelType = PIN_DEF_LABEL_TYPE_TEXT;
							break;
						}
					}
				} else if (_tmp11_ == ((0 != _tmp10_label10) ? _tmp10_label10 : (_tmp10_label10 = g_quark_from_static_string ("barlabel")))) {
					switch (0) {
						default:
						{
							xmlAttr* _tmp57_ = NULL;
							xmlNode* _tmp58_ = NULL;
							const gchar* _tmp59_ = NULL;
							gchar* _tmp60_ = NULL;
							_tmp57_ = xmlattr;
							_tmp58_ = _tmp57_->children;
							_tmp59_ = _tmp58_->content;
							_tmp60_ = g_strdup (_tmp59_);
							_g_free0 (self->label);
							self->label = _tmp60_;
							self->labelType = PIN_DEF_LABEL_TYPE_TEXTBAR;
							break;
						}
					}
				} else if (_tmp11_ == ((0 != _tmp10_label11) ? _tmp10_label11 : (_tmp10_label11 = g_quark_from_static_string ("symlabel")))) {
					switch (0) {
						default:
						{
							xmlAttr* _tmp61_ = NULL;
							xmlNode* _tmp62_ = NULL;
							const gchar* _tmp63_ = NULL;
							const gchar* _tmp64_ = NULL;
							GQuark _tmp66_ = 0U;
							static GQuark _tmp65_label0 = 0;
							_tmp61_ = xmlattr;
							_tmp62_ = _tmp61_->children;
							_tmp63_ = _tmp62_->content;
							_tmp64_ = _tmp63_;
							_tmp66_ = (NULL == _tmp64_) ? 0 : g_quark_from_string (_tmp64_);
							if (_tmp66_ == ((0 != _tmp65_label0) ? _tmp65_label0 : (_tmp65_label0 = g_quark_from_static_string ("clock")))) {
								switch (0) {
									default:
									{
										self->labelType = PIN_DEF_LABEL_TYPE_CLOCK;
										break;
									}
								}
							} else {
								switch (0) {
									default:
									{
										self->labelType = PIN_DEF_LABEL_TYPE_NONE;
										break;
									}
								}
							}
							break;
						}
					}
				} else if (_tmp11_ == ((0 != _tmp10_label12) ? _tmp10_label12 : (_tmp10_label12 = g_quark_from_static_string ("required")))) {
					switch (0) {
						default:
						{
							xmlAttr* _tmp67_ = NULL;
							xmlNode* _tmp68_ = NULL;
							const gchar* _tmp69_ = NULL;
							gboolean _tmp70_ = FALSE;
							_tmp67_ = xmlattr;
							_tmp68_ = _tmp67_->children;
							_tmp69_ = _tmp68_->content;
							_tmp70_ = bool_parse (_tmp69_);
							self->required = _tmp70_;
							break;
						}
					}
				} else if (_tmp11_ == ((0 != _tmp10_label13) ? _tmp10_label13 : (_tmp10_label13 = g_quark_from_static_string ("userresize")))) {
					switch (0) {
						default:
						{
							xmlAttr* _tmp71_ = NULL;
							xmlNode* _tmp72_ = NULL;
							const gchar* _tmp73_ = NULL;
							gboolean _tmp74_ = FALSE;
							_tmp71_ = xmlattr;
							_tmp72_ = _tmp71_->children;
							_tmp73_ = _tmp72_->content;
							_tmp74_ = bool_parse (_tmp73_);
							self->userArrayResize = _tmp74_;
							break;
						}
					}
				} else if (_tmp11_ == ((0 != _tmp10_label14) ? _tmp10_label14 : (_tmp10_label14 = g_quark_from_static_string ("show")))) {
					switch (0) {
						default:
						{
							xmlAttr* _tmp75_ = NULL;
							xmlNode* _tmp76_ = NULL;
							const gchar* _tmp77_ = NULL;
							gboolean _tmp78_ = FALSE;
							_tmp75_ = xmlattr;
							_tmp76_ = _tmp75_->children;
							_tmp77_ = _tmp76_->content;
							_tmp78_ = bool_parse (_tmp77_);
							self->showDefault = _tmp78_;
							break;
						}
					}
				}
			}
		}
	}
	_tmp79_ = self->flow;
	if (_tmp79_ == FLOW_NONE) {
		FILE* _tmp80_ = NULL;
		_tmp80_ = stdout;
		fprintf (_tmp80_, "Warning: No flow\n");
	}
	_tmp81_ = x;
	_tmp82_ = y;
	_tmp83_ = length;
	_tmp84_ = direction;
	pin_def_set_position (self, _tmp81_, _tmp82_, _tmp83_, _tmp84_);
	return self;
}


PinDef* pin_def_new_load (xmlNode* xmlnode) {
	return pin_def_construct_load (TYPE_PIN_DEF, xmlnode);
}


/**
 * Changes the position the pin extends from, its length, and
 * direction, updating necessary values.
 */
void pin_def_set_position (PinDef* self, gint x, gint y, gint length, Direction direction) {
	gint _tmp0_ = 0;
	gint _tmp1_ = 0;
	gint _tmp2_ = 0;
	Direction _tmp3_ = 0;
	Direction _tmp4_ = 0;
	g_return_if_fail (self != NULL);
	_tmp0_ = x;
	self->x = _tmp0_;
	_tmp1_ = y;
	self->y = _tmp1_;
	_tmp2_ = length;
	self->length = _tmp2_;
	_tmp3_ = direction;
	self->direction = _tmp3_;
	_tmp4_ = direction;
	switch (_tmp4_) {
		case DIRECTION_NONE:
		{
			gint _tmp5_ = 0;
			gint _tmp6_ = 0;
			gint _tmp7_ = 0;
			gint _tmp8_ = 0;
			_tmp5_ = x;
			self->xConnect = _tmp5_;
			_tmp6_ = y;
			self->yConnect = _tmp6_;
			_tmp7_ = x;
			self->xLabel = _tmp7_;
			_tmp8_ = y;
			self->yLabel = _tmp8_;
			break;
		}
		case DIRECTION_RIGHT:
		{
			gint _tmp9_ = 0;
			gint _tmp10_ = 0;
			gint _tmp11_ = 0;
			gint _tmp12_ = 0;
			gint _tmp13_ = 0;
			_tmp9_ = x;
			_tmp10_ = length;
			self->xConnect = _tmp9_ + _tmp10_;
			_tmp11_ = y;
			self->yConnect = _tmp11_;
			_tmp12_ = x;
			self->xLabel = _tmp12_ - 10;
			_tmp13_ = y;
			self->yLabel = _tmp13_;
			break;
		}
		case DIRECTION_DOWN:
		{
			gint _tmp14_ = 0;
			gint _tmp15_ = 0;
			gint _tmp16_ = 0;
			gint _tmp17_ = 0;
			gint _tmp18_ = 0;
			_tmp14_ = x;
			self->xConnect = _tmp14_;
			_tmp15_ = y;
			_tmp16_ = length;
			self->yConnect = _tmp15_ + _tmp16_;
			_tmp17_ = x;
			self->xLabel = _tmp17_;
			_tmp18_ = y;
			self->yLabel = _tmp18_ - 10;
			break;
		}
		case DIRECTION_LEFT:
		{
			gint _tmp19_ = 0;
			gint _tmp20_ = 0;
			gint _tmp21_ = 0;
			gint _tmp22_ = 0;
			gint _tmp23_ = 0;
			_tmp19_ = x;
			_tmp20_ = length;
			self->xConnect = _tmp19_ - _tmp20_;
			_tmp21_ = y;
			self->yConnect = _tmp21_;
			_tmp22_ = x;
			self->xLabel = _tmp22_ + 10;
			_tmp23_ = y;
			self->yLabel = _tmp23_;
			break;
		}
		case DIRECTION_UP:
		{
			gint _tmp24_ = 0;
			gint _tmp25_ = 0;
			gint _tmp26_ = 0;
			gint _tmp27_ = 0;
			gint _tmp28_ = 0;
			_tmp24_ = x;
			self->xConnect = _tmp24_;
			_tmp25_ = y;
			_tmp26_ = length;
			self->yConnect = _tmp25_ - _tmp26_;
			_tmp27_ = x;
			self->xLabel = _tmp27_;
			_tmp28_ = y;
			self->yLabel = _tmp28_ + 10;
			break;
		}
		default:
		break;
	}
}


/**
 * Saves the PinDef to a file using libxml.
 */
void pin_def_save (PinDef* self, xmlTextWriter* xmlWriter, gint id) {
	xmlTextWriter* _tmp0_ = NULL;
	xmlTextWriter* _tmp1_ = NULL;
	gint _tmp2_ = 0;
	gchar* _tmp3_ = NULL;
	gchar* _tmp4_ = NULL;
	xmlTextWriter* _tmp5_ = NULL;
	gint _tmp6_ = 0;
	gchar* _tmp7_ = NULL;
	gchar* _tmp8_ = NULL;
	xmlTextWriter* _tmp9_ = NULL;
	gint _tmp10_ = 0;
	gchar* _tmp11_ = NULL;
	gchar* _tmp12_ = NULL;
	gchar* tmpString = NULL;
	Direction _tmp13_ = 0;
	xmlTextWriter* _tmp19_ = NULL;
	const gchar* _tmp20_ = NULL;
	xmlTextWriter* _tmp21_ = NULL;
	gint _tmp22_ = 0;
	gchar* _tmp23_ = NULL;
	gchar* _tmp24_ = NULL;
	Flow _tmp25_ = 0;
	PinDefLabelType _tmp29_ = 0;
	const gchar* _tmp35_ = NULL;
	gboolean _tmp36_ = FALSE;
	xmlTextWriter* _tmp37_ = NULL;
	xmlTextWriter* _tmp38_ = NULL;
	g_return_if_fail (self != NULL);
	g_return_if_fail (xmlWriter != NULL);
	_tmp0_ = xmlWriter;
	xmlTextWriterStartElement (_tmp0_, (xmlChar*) "pin");
	_tmp1_ = xmlWriter;
	_tmp2_ = self->x;
	_tmp3_ = g_strdup_printf ("%i", _tmp2_);
	_tmp4_ = _tmp3_;
	xmlTextWriterWriteAttribute (_tmp1_, (xmlChar*) "x", (xmlChar*) _tmp4_);
	_g_free0 (_tmp4_);
	_tmp5_ = xmlWriter;
	_tmp6_ = self->y;
	_tmp7_ = g_strdup_printf ("%i", _tmp6_);
	_tmp8_ = _tmp7_;
	xmlTextWriterWriteAttribute (_tmp5_, (xmlChar*) "y", (xmlChar*) _tmp8_);
	_g_free0 (_tmp8_);
	_tmp9_ = xmlWriter;
	_tmp10_ = self->length;
	_tmp11_ = g_strdup_printf ("%i", _tmp10_);
	_tmp12_ = _tmp11_;
	xmlTextWriterWriteAttribute (_tmp9_, (xmlChar*) "length", (xmlChar*) _tmp12_);
	_g_free0 (_tmp12_);
	_tmp13_ = self->direction;
	switch (_tmp13_) {
		case DIRECTION_RIGHT:
		{
			gchar* _tmp14_ = NULL;
			_tmp14_ = g_strdup ("right");
			_g_free0 (tmpString);
			tmpString = _tmp14_;
			break;
		}
		case DIRECTION_DOWN:
		{
			gchar* _tmp15_ = NULL;
			_tmp15_ = g_strdup ("down");
			_g_free0 (tmpString);
			tmpString = _tmp15_;
			break;
		}
		case DIRECTION_LEFT:
		{
			gchar* _tmp16_ = NULL;
			_tmp16_ = g_strdup ("left");
			_g_free0 (tmpString);
			tmpString = _tmp16_;
			break;
		}
		case DIRECTION_UP:
		{
			gchar* _tmp17_ = NULL;
			_tmp17_ = g_strdup ("up");
			_g_free0 (tmpString);
			tmpString = _tmp17_;
			break;
		}
		default:
		{
			gchar* _tmp18_ = NULL;
			_tmp18_ = g_strdup ("none");
			_g_free0 (tmpString);
			tmpString = _tmp18_;
			break;
		}
	}
	_tmp19_ = xmlWriter;
	_tmp20_ = tmpString;
	xmlTextWriterWriteAttribute (_tmp19_, (xmlChar*) "direction", (xmlChar*) _tmp20_);
	_tmp21_ = xmlWriter;
	_tmp22_ = id;
	_tmp23_ = g_strdup_printf ("%i", _tmp22_);
	_tmp24_ = _tmp23_;
	xmlTextWriterWriteAttribute (_tmp21_, (xmlChar*) "id", (xmlChar*) _tmp24_);
	_g_free0 (_tmp24_);
	_tmp25_ = self->flow;
	switch (_tmp25_) {
		case FLOW_IN:
		{
			xmlTextWriter* _tmp26_ = NULL;
			_tmp26_ = xmlWriter;
			xmlTextWriterWriteAttribute (_tmp26_, (xmlChar*) "flow", (xmlChar*) "in");
			break;
		}
		case FLOW_OUT:
		{
			xmlTextWriter* _tmp27_ = NULL;
			_tmp27_ = xmlWriter;
			xmlTextWriterWriteAttribute (_tmp27_, (xmlChar*) "flow", (xmlChar*) "out");
			break;
		}
		case FLOW_BIDIRECTIONAL:
		{
			xmlTextWriter* _tmp28_ = NULL;
			_tmp28_ = xmlWriter;
			xmlTextWriterWriteAttribute (_tmp28_, (xmlChar*) "flow", (xmlChar*) "bi");
			break;
		}
		default:
		break;
	}
	_tmp29_ = self->labelType;
	switch (_tmp29_) {
		case PIN_DEF_LABEL_TYPE_TEXT:
		{
			xmlTextWriter* _tmp30_ = NULL;
			const gchar* _tmp31_ = NULL;
			_tmp30_ = xmlWriter;
			_tmp31_ = self->label;
			xmlTextWriterWriteAttribute (_tmp30_, (xmlChar*) "label", (xmlChar*) _tmp31_);
			break;
		}
		case PIN_DEF_LABEL_TYPE_TEXTBAR:
		{
			xmlTextWriter* _tmp32_ = NULL;
			const gchar* _tmp33_ = NULL;
			_tmp32_ = xmlWriter;
			_tmp33_ = self->label;
			xmlTextWriterWriteAttribute (_tmp32_, (xmlChar*) "barlabel", (xmlChar*) _tmp33_);
			break;
		}
		case PIN_DEF_LABEL_TYPE_CLOCK:
		{
			xmlTextWriter* _tmp34_ = NULL;
			_tmp34_ = xmlWriter;
			xmlTextWriterWriteAttribute (_tmp34_, (xmlChar*) "symlabel", (xmlChar*) "clock");
			break;
		}
		default:
		break;
	}
	_tmp36_ = self->required;
	if (_tmp36_) {
		_tmp35_ = "true";
	} else {
		_tmp35_ = "false";
	}
	_tmp37_ = xmlWriter;
	xmlTextWriterWriteAttribute (_tmp37_, (xmlChar*) "required", (xmlChar*) _tmp35_);
	_tmp38_ = xmlWriter;
	xmlTextWriterEndElement (_tmp38_);
	_g_free0 (tmpString);
}


/**
 * Renders the pin (without label). If //invert// is true, a small
 * circle is displayed on the start of the pin.
 */
void pin_def_render (PinDef* self, cairo_t* context, gboolean invert) {
	cairo_matrix_t oldMatrix = {0};
	cairo_t* _tmp0_ = NULL;
	cairo_matrix_t _tmp1_ = {0};
	cairo_t* _tmp2_ = NULL;
	gint _tmp3_ = 0;
	gint _tmp4_ = 0;
	Direction _tmp5_ = 0;
	cairo_t* _tmp19_ = NULL;
	cairo_matrix_t _tmp20_ = {0};
	g_return_if_fail (self != NULL);
	g_return_if_fail (context != NULL);
	_tmp0_ = context;
	cairo_get_matrix (_tmp0_, &_tmp1_);
	oldMatrix = _tmp1_;
	_tmp2_ = context;
	_tmp3_ = self->x;
	_tmp4_ = self->y;
	cairo_translate (_tmp2_, (gdouble) _tmp3_, (gdouble) _tmp4_);
	_tmp5_ = self->direction;
	if (_tmp5_ != DIRECTION_NONE) {
		gdouble angle = 0.0;
		Direction _tmp6_ = 0;
		cairo_t* _tmp7_ = NULL;
		gdouble _tmp8_ = 0.0;
		gboolean _tmp9_ = FALSE;
		angle = (gdouble) 0;
		_tmp6_ = self->direction;
		switch (_tmp6_) {
			case DIRECTION_RIGHT:
			{
				angle = (gdouble) 0;
				break;
			}
			case DIRECTION_DOWN:
			{
				angle = G_PI * 0.5;
				break;
			}
			case DIRECTION_LEFT:
			{
				angle = G_PI;
				break;
			}
			case DIRECTION_UP:
			{
				angle = G_PI * 1.5;
				break;
			}
			default:
			break;
		}
		_tmp7_ = context;
		_tmp8_ = angle;
		cairo_rotate (_tmp7_, _tmp8_);
		_tmp9_ = invert;
		if (_tmp9_) {
			cairo_t* _tmp10_ = NULL;
			cairo_t* _tmp11_ = NULL;
			gint _tmp12_ = 0;
			cairo_t* _tmp13_ = NULL;
			cairo_t* _tmp14_ = NULL;
			_tmp10_ = context;
			cairo_move_to (_tmp10_, (gdouble) 10, (gdouble) 0);
			_tmp11_ = context;
			_tmp12_ = self->length;
			cairo_line_to (_tmp11_, (gdouble) _tmp12_, (gdouble) 0);
			_tmp13_ = context;
			cairo_arc (_tmp13_, (gdouble) 5, (gdouble) 0, (gdouble) 5, (gdouble) 0, G_PI * 2);
			_tmp14_ = context;
			cairo_stroke (_tmp14_);
		} else {
			cairo_t* _tmp15_ = NULL;
			cairo_t* _tmp16_ = NULL;
			gint _tmp17_ = 0;
			cairo_t* _tmp18_ = NULL;
			_tmp15_ = context;
			cairo_move_to (_tmp15_, (gdouble) 0, (gdouble) 0);
			_tmp16_ = context;
			_tmp17_ = self->length;
			cairo_line_to (_tmp16_, (gdouble) _tmp17_, (gdouble) 0);
			_tmp18_ = context;
			cairo_stroke (_tmp18_);
		}
	}
	_tmp19_ = context;
	_tmp20_ = oldMatrix;
	cairo_set_matrix (_tmp19_, &_tmp20_);
}


static void value_pin_def_init (GValue* value) {
	value->data[0].v_pointer = NULL;
}


static void value_pin_def_free_value (GValue* value) {
	if (value->data[0].v_pointer) {
		pin_def_unref (value->data[0].v_pointer);
	}
}


static void value_pin_def_copy_value (const GValue* src_value, GValue* dest_value) {
	if (src_value->data[0].v_pointer) {
		dest_value->data[0].v_pointer = pin_def_ref (src_value->data[0].v_pointer);
	} else {
		dest_value->data[0].v_pointer = NULL;
	}
}


static gpointer value_pin_def_peek_pointer (const GValue* value) {
	return value->data[0].v_pointer;
}


static gchar* value_pin_def_collect_value (GValue* value, guint n_collect_values, GTypeCValue* collect_values, guint collect_flags) {
	if (collect_values[0].v_pointer) {
		PinDef* object;
		object = collect_values[0].v_pointer;
		if (object->parent_instance.g_class == NULL) {
			return g_strconcat ("invalid unclassed object pointer for value type `", G_VALUE_TYPE_NAME (value), "'", NULL);
		} else if (!g_value_type_compatible (G_TYPE_FROM_INSTANCE (object), G_VALUE_TYPE (value))) {
			return g_strconcat ("invalid object type `", g_type_name (G_TYPE_FROM_INSTANCE (object)), "' for value type `", G_VALUE_TYPE_NAME (value), "'", NULL);
		}
		value->data[0].v_pointer = pin_def_ref (object);
	} else {
		value->data[0].v_pointer = NULL;
	}
	return NULL;
}


static gchar* value_pin_def_lcopy_value (const GValue* value, guint n_collect_values, GTypeCValue* collect_values, guint collect_flags) {
	PinDef** object_p;
	object_p = collect_values[0].v_pointer;
	if (!object_p) {
		return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value));
	}
	if (!value->data[0].v_pointer) {
		*object_p = NULL;
	} else if (collect_flags & G_VALUE_NOCOPY_CONTENTS) {
		*object_p = value->data[0].v_pointer;
	} else {
		*object_p = pin_def_ref (value->data[0].v_pointer);
	}
	return NULL;
}


GParamSpec* param_spec_pin_def (const gchar* name, const gchar* nick, const gchar* blurb, GType object_type, GParamFlags flags) {
	ParamSpecPinDef* spec;
	g_return_val_if_fail (g_type_is_a (object_type, TYPE_PIN_DEF), NULL);
	spec = g_param_spec_internal (G_TYPE_PARAM_OBJECT, name, nick, blurb, flags);
	G_PARAM_SPEC (spec)->value_type = object_type;
	return G_PARAM_SPEC (spec);
}


gpointer value_get_pin_def (const GValue* value) {
	g_return_val_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, TYPE_PIN_DEF), NULL);
	return value->data[0].v_pointer;
}


void value_set_pin_def (GValue* value, gpointer v_object) {
	PinDef* old;
	g_return_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, TYPE_PIN_DEF));
	old = value->data[0].v_pointer;
	if (v_object) {
		g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (v_object, TYPE_PIN_DEF));
		g_return_if_fail (g_value_type_compatible (G_TYPE_FROM_INSTANCE (v_object), G_VALUE_TYPE (value)));
		value->data[0].v_pointer = v_object;
		pin_def_ref (value->data[0].v_pointer);
	} else {
		value->data[0].v_pointer = NULL;
	}
	if (old) {
		pin_def_unref (old);
	}
}


void value_take_pin_def (GValue* value, gpointer v_object) {
	PinDef* old;
	g_return_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, TYPE_PIN_DEF));
	old = value->data[0].v_pointer;
	if (v_object) {
		g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (v_object, TYPE_PIN_DEF));
		g_return_if_fail (g_value_type_compatible (G_TYPE_FROM_INSTANCE (v_object), G_VALUE_TYPE (value)));
		value->data[0].v_pointer = v_object;
	} else {
		value->data[0].v_pointer = NULL;
	}
	if (old) {
		pin_def_unref (old);
	}
}


static void pin_def_class_init (PinDefClass * klass) {
	pin_def_parent_class = g_type_class_peek_parent (klass);
	PIN_DEF_CLASS (klass)->finalize = pin_def_finalize;
}


static void pin_def_instance_init (PinDef * self) {
	self->ref_count = 1;
}


static void pin_def_finalize (PinDef* obj) {
	PinDef * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, TYPE_PIN_DEF, PinDef);
	_g_free0 (self->label);
}


/**
 * Definition of a pin.
 * 
 * Used to describe how a pin should appear, and properties such as
 * required connections, and arrays.
 */
GType pin_def_get_type (void) {
	static volatile gsize pin_def_type_id__volatile = 0;
	if (g_once_init_enter (&pin_def_type_id__volatile)) {
		static const GTypeValueTable g_define_type_value_table = { value_pin_def_init, value_pin_def_free_value, value_pin_def_copy_value, value_pin_def_peek_pointer, "p", value_pin_def_collect_value, "p", value_pin_def_lcopy_value };
		static const GTypeInfo g_define_type_info = { sizeof (PinDefClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) pin_def_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (PinDef), 0, (GInstanceInitFunc) pin_def_instance_init, &g_define_type_value_table };
		static const GTypeFundamentalInfo g_define_type_fundamental_info = { (G_TYPE_FLAG_CLASSED | G_TYPE_FLAG_INSTANTIATABLE | G_TYPE_FLAG_DERIVABLE | G_TYPE_FLAG_DEEP_DERIVABLE) };
		GType pin_def_type_id;
		pin_def_type_id = g_type_register_fundamental (g_type_fundamental_next (), "PinDef", &g_define_type_info, &g_define_type_fundamental_info, 0);
		g_once_init_leave (&pin_def_type_id__volatile, pin_def_type_id);
	}
	return pin_def_type_id__volatile;
}


gpointer pin_def_ref (gpointer instance) {
	PinDef* self;
	self = instance;
	g_atomic_int_inc (&self->ref_count);
	return instance;
}


void pin_def_unref (gpointer instance) {
	PinDef* self;
	self = instance;
	if (g_atomic_int_dec_and_test (&self->ref_count)) {
		PIN_DEF_GET_CLASS (self)->finalize (self);
		g_type_free_instance ((GTypeInstance *) self);
	}
}



