/* gcalc-math-variable.c generated by valac 0.56.0, the Vala compiler
 * generated from gcalc-math-variable.vala, do not modify */

/* gcalc-math-variable.vala
 *
 * Copyright (C) 2018  Daniel Espinosa <esodan@gmail.com>
 *
 * 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 2.1 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.

 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *      Daniel Espinosa <esodan@gmail.com>
 */

#include "gcalc/gcalc.h"
#include <glib.h>
#include <glib/gi18n-lib.h>
#include <gio/gio.h>
#include <glib-object.h>
#include "gcalc.h"

#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))

static GCalcMathExpression* gcalc_math_variable_real_evaluate (GCalcMathVariable* self,
                                                        GError** error);
static GType gcalc_math_variable_get_type_once (void);

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

static GCalcMathExpression*
gcalc_math_variable_real_evaluate (GCalcMathVariable* self,
                                   GError** error)
{
	GCalcMathVariable* _tmp0_;
	GCalcMathVariable* _tmp1_;
	GCalcMathExpression* _tmp13_;
	GCalcMathExpression* _tmp14_;
	GCalcMathExpression* _tmp16_;
	GCalcMathExpression* _tmp17_;
	GCalcExpressionContainer* _tmp18_;
	GCalcExpressionContainer* _tmp19_;
	GCalcMathPolynomial* e = NULL;
	GCalcMathExpression* _tmp21_;
	GCalcMathExpression* _tmp22_;
	GCalcExpressionContainer* _tmp23_;
	GCalcExpressionContainer* _tmp24_;
	GObject* _tmp25_;
	GCalcMathPolynomial* _tmp26_;
	GCalcMathPolynomial* _tmp27_;
	GCalcMathExpression* _tmp29_ = NULL;
	GCalcMathPolynomial* _tmp30_;
	GCalcMathExpression* _tmp31_;
	GCalcMathConstant* exp = NULL;
	GCalcMathConstant* _tmp32_;
	GCalcMathConstant* _tmp33_;
	GCalcMathConstant* _tmp35_;
	GError* _inner_error0_ = NULL;
	GCalcMathExpression* result;
	_tmp0_ = gcalc_math_variable_get_bind (self);
	_tmp1_ = _tmp0_;
	if (_tmp1_ != NULL) {
		GCalcMathExpression* _tmp2_ = NULL;
		GCalcMathVariable* _tmp3_;
		GCalcMathVariable* _tmp4_;
		GCalcMathExpression* _tmp5_;
		GCalcMathExpression* _tmp6_;
		_tmp3_ = gcalc_math_variable_get_bind (self);
		_tmp4_ = _tmp3_;
		_tmp5_ = gcalc_math_variable_evaluate (_tmp4_, &_inner_error0_);
		_tmp2_ = _tmp5_;
		if (G_UNLIKELY (_inner_error0_ != NULL)) {
			g_propagate_error (error, _inner_error0_);
			return NULL;
		}
		_tmp6_ = _tmp2_;
		_tmp2_ = NULL;
		result = _tmp6_;
		_g_object_unref0 (_tmp2_);
		return result;
	}
	if (GCALC_IS_MATH_PARAMETER (self)) {
		GCalcMathConstant* _tmp7_;
		GCalcMathConstant* _tmp8_;
		GCalcMathConstant* _tmp10_;
		GCalcMathConstant* _tmp11_;
		GCalcMathExpression* _tmp12_;
		_tmp7_ = gcalc_math_variable_get_value (self);
		_tmp8_ = _tmp7_;
		if (_tmp8_ == NULL) {
			GCalcConstant* _tmp9_;
			_tmp9_ = gcalc_constant_new_double (0.0);
			result = (GCalcMathExpression*) _tmp9_;
			return result;
		}
		_tmp10_ = gcalc_math_variable_get_value (self);
		_tmp11_ = _tmp10_;
		_tmp12_ = _g_object_ref0 ((GCalcMathExpression*) _tmp11_);
		result = _tmp12_;
		return result;
	}
	_tmp13_ = gcalc_math_expression_get_parent ((GCalcMathExpression*) self);
	_tmp14_ = _tmp13_;
	if (_tmp14_ == NULL) {
		GError* _tmp15_;
		_tmp15_ = g_error_new_literal (GCALC_VARIABLE_ERROR, GCALC_VARIABLE_ERROR_INVALID_PARENT, _ ("Can't access to MathVariable's expression definition. Invalid parent. " \
"Expected Assign operator"));
		_inner_error0_ = _tmp15_;
		g_propagate_error (error, _inner_error0_);
		return NULL;
	}
	_tmp16_ = gcalc_math_expression_get_parent ((GCalcMathExpression*) self);
	_tmp17_ = _tmp16_;
	_tmp18_ = gcalc_math_expression_get_expressions (_tmp17_);
	_tmp19_ = _tmp18_;
	if (g_list_model_get_n_items ((GListModel*) _tmp19_) != ((guint) 2)) {
		GError* _tmp20_;
		_tmp20_ = g_error_new_literal (GCALC_VARIABLE_ERROR, GCALC_VARIABLE_ERROR_INVALID_EXPRESSION_DEFINITION, _ ("Can't access to MathVariable's expression definition. Expression not f" \
"ound"));
		_inner_error0_ = _tmp20_;
		g_propagate_error (error, _inner_error0_);
		return NULL;
	}
	_tmp21_ = gcalc_math_expression_get_parent ((GCalcMathExpression*) self);
	_tmp22_ = _tmp21_;
	_tmp23_ = gcalc_math_expression_get_expressions (_tmp22_);
	_tmp24_ = _tmp23_;
	_tmp25_ = g_list_model_get_item ((GListModel*) _tmp24_, (guint) 1);
	_tmp26_ = GCALC_IS_MATH_POLYNOMIAL (_tmp25_) ? ((GCalcMathPolynomial*) _tmp25_) : NULL;
	if (_tmp26_ == NULL) {
		_g_object_unref0 (_tmp25_);
	}
	e = _tmp26_;
	_tmp27_ = e;
	if (_tmp27_ == NULL) {
		GError* _tmp28_;
		_tmp28_ = g_error_new_literal (GCALC_VARIABLE_ERROR, GCALC_VARIABLE_ERROR_INVALID_EXPRESSION_DEFINITION, _ ("Can't access to MathVariable's expression definition. Unexpected objec" \
"t type"));
		_inner_error0_ = _tmp28_;
		g_propagate_error (error, _inner_error0_);
		_g_object_unref0 (e);
		return NULL;
	}
	_tmp30_ = e;
	_tmp31_ = gcalc_math_polynomial_evaluate (_tmp30_, &_inner_error0_);
	_tmp29_ = _tmp31_;
	if (G_UNLIKELY (_inner_error0_ != NULL)) {
		g_propagate_error (error, _inner_error0_);
		_g_object_unref0 (e);
		return NULL;
	}
	_tmp32_ = _g_object_ref0 (GCALC_IS_MATH_CONSTANT (_tmp29_) ? ((GCalcMathConstant*) _tmp29_) : NULL);
	exp = _tmp32_;
	_tmp33_ = exp;
	if (_tmp33_ == NULL) {
		GError* _tmp34_;
		_tmp34_ = g_error_new_literal (GCALC_VARIABLE_ERROR, GCALC_VARIABLE_ERROR_EVALUATION_FAIL, _ ("MathVariable evaluation fail. MathVariable's value not updated"));
		_inner_error0_ = _tmp34_;
		g_propagate_error (error, _inner_error0_);
		_g_object_unref0 (exp);
		_g_object_unref0 (_tmp29_);
		_g_object_unref0 (e);
		return NULL;
	}
	_tmp35_ = exp;
	gcalc_math_variable_set_value (self, _tmp35_);
	result = (GCalcMathExpression*) exp;
	_g_object_unref0 (_tmp29_);
	_g_object_unref0 (e);
	return result;
}

GCalcMathExpression*
gcalc_math_variable_evaluate (GCalcMathVariable* self,
                              GError** error)
{
	GCalcMathVariableIface* _iface_;
	g_return_val_if_fail (self != NULL, NULL);
	_iface_ = GCALC_MATH_VARIABLE_GET_INTERFACE (self);
	if (_iface_->evaluate) {
		return _iface_->evaluate (self, error);
	}
	return NULL;
}

const gchar*
gcalc_math_variable_get_name (GCalcMathVariable* self)
{
	GCalcMathVariableIface* _iface_;
	g_return_val_if_fail (self != NULL, NULL);
	_iface_ = GCALC_MATH_VARIABLE_GET_INTERFACE (self);
	if (_iface_->get_name) {
		return _iface_->get_name (self);
	}
	return NULL;
}

void
gcalc_math_variable_set_name (GCalcMathVariable* self,
                              const gchar* value)
{
	GCalcMathVariableIface* _iface_;
	g_return_if_fail (self != NULL);
	_iface_ = GCALC_MATH_VARIABLE_GET_INTERFACE (self);
	if (_iface_->set_name) {
		_iface_->set_name (self, value);
	}
}

GCalcMathConstant*
gcalc_math_variable_get_value (GCalcMathVariable* self)
{
	GCalcMathVariableIface* _iface_;
	g_return_val_if_fail (self != NULL, NULL);
	_iface_ = GCALC_MATH_VARIABLE_GET_INTERFACE (self);
	if (_iface_->get_value) {
		return _iface_->get_value (self);
	}
	return NULL;
}

void
gcalc_math_variable_set_value (GCalcMathVariable* self,
                               GCalcMathConstant* value)
{
	GCalcMathVariableIface* _iface_;
	g_return_if_fail (self != NULL);
	_iface_ = GCALC_MATH_VARIABLE_GET_INTERFACE (self);
	if (_iface_->set_value) {
		_iface_->set_value (self, value);
	}
}

GCalcMathVariable*
gcalc_math_variable_get_bind (GCalcMathVariable* self)
{
	GCalcMathVariableIface* _iface_;
	g_return_val_if_fail (self != NULL, NULL);
	_iface_ = GCALC_MATH_VARIABLE_GET_INTERFACE (self);
	if (_iface_->get_bind) {
		return _iface_->get_bind (self);
	}
	return NULL;
}

void
gcalc_math_variable_set_bind (GCalcMathVariable* self,
                              GCalcMathVariable* value)
{
	GCalcMathVariableIface* _iface_;
	g_return_if_fail (self != NULL);
	_iface_ = GCALC_MATH_VARIABLE_GET_INTERFACE (self);
	if (_iface_->set_bind) {
		_iface_->set_bind (self, value);
	}
}

gboolean
gcalc_math_variable_get_binded (GCalcMathVariable* self)
{
	GCalcMathVariableIface* _iface_;
	g_return_val_if_fail (self != NULL, FALSE);
	_iface_ = GCALC_MATH_VARIABLE_GET_INTERFACE (self);
	if (_iface_->get_binded) {
		return _iface_->get_binded (self);
	}
	return FALSE;
}

static gboolean
gcalc_math_variable_real_get_binded (GCalcMathVariable* base)
{
	gboolean result;
	GCalcMathVariable* self;
	GCalcMathVariable* _tmp0_;
	GCalcMathVariable* _tmp1_;
	self = base;
	_tmp0_ = gcalc_math_variable_get_bind (self);
	_tmp1_ = _tmp0_;
	result = _tmp1_ != NULL;
	return result;
}

static void
gcalc_math_variable_default_init (GCalcMathVariableIface * iface,
                                  gpointer iface_data)
{
	g_object_interface_install_property (iface, g_param_spec_string ("name", "name", "name", NULL, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT));
	g_object_interface_install_property (iface, g_param_spec_object ("value", "value", "value", GCALC_TYPE_MATH_CONSTANT, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE | G_PARAM_WRITABLE));
	g_object_interface_install_property (iface, g_param_spec_object ("bind", "bind", "bind", GCALC_TYPE_MATH_VARIABLE, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE | G_PARAM_WRITABLE));
	iface->evaluate = gcalc_math_variable_real_evaluate;
	iface->get_binded = gcalc_math_variable_real_get_binded;
}

/**
 * A variable that can be evaluated from an {@link MathExpression}
 */
static GType
gcalc_math_variable_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (GCalcMathVariableIface), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) gcalc_math_variable_default_init, (GClassFinalizeFunc) NULL, NULL, 0, 0, (GInstanceInitFunc) NULL, NULL };
	GType gcalc_math_variable_type_id;
	gcalc_math_variable_type_id = g_type_register_static (G_TYPE_INTERFACE, "GCalcMathVariable", &g_define_type_info, 0);
	g_type_interface_add_prerequisite (gcalc_math_variable_type_id, G_TYPE_OBJECT);
	g_type_interface_add_prerequisite (gcalc_math_variable_type_id, GCALC_TYPE_MATH_EXPRESSION);
	return gcalc_math_variable_type_id;
}

GType
gcalc_math_variable_get_type (void)
{
	static volatile gsize gcalc_math_variable_type_id__once = 0;
	if (g_once_init_enter (&gcalc_math_variable_type_id__once)) {
		GType gcalc_math_variable_type_id;
		gcalc_math_variable_type_id = gcalc_math_variable_get_type_once ();
		g_once_init_leave (&gcalc_math_variable_type_id__once, gcalc_math_variable_type_id);
	}
	return gcalc_math_variable_type_id__once;
}

GQuark
gcalc_variable_error_quark (void)
{
	return g_quark_from_static_string ("gcalc-variable-error-quark");
}

static GType
gcalc_variable_error_get_type_once (void)
{
	static const GEnumValue values[] = {{GCALC_VARIABLE_ERROR_INVALID_PARENT, "GCALC_VARIABLE_ERROR_INVALID_PARENT", "invalid-parent"}, {GCALC_VARIABLE_ERROR_INVALID_EXPRESSION_DEFINITION, "GCALC_VARIABLE_ERROR_INVALID_EXPRESSION_DEFINITION", "invalid-expression-definition"}, {GCALC_VARIABLE_ERROR_EVALUATION_FAIL, "GCALC_VARIABLE_ERROR_EVALUATION_FAIL", "evaluation-fail"}, {0, NULL, NULL}};
	GType gcalc_variable_error_type_id;
	gcalc_variable_error_type_id = g_enum_register_static ("GCalcVariableError", values);
	return gcalc_variable_error_type_id;
}

GType
gcalc_variable_error_get_type (void)
{
	static volatile gsize gcalc_variable_error_type_id__once = 0;
	if (g_once_init_enter (&gcalc_variable_error_type_id__once)) {
		GType gcalc_variable_error_type_id;
		gcalc_variable_error_type_id = gcalc_variable_error_get_type_once ();
		g_once_init_leave (&gcalc_variable_error_type_id__once, gcalc_variable_error_type_id);
	}
	return gcalc_variable_error_type_id__once;
}

