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

/* gcalc-math-polynomial.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 <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_polynomial_real_evaluate (GCalcMathPolynomial* self,
                                                          GError** error);
static GType gcalc_math_polynomial_get_type_once (void);

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

static GCalcMathExpression*
gcalc_math_polynomial_real_evaluate (GCalcMathPolynomial* self,
                                     GError** error)
{
	GCalcMathTerm* current = NULL;
	GCalcMathExpression* res = NULL;
	GCalcMathExpression* _tmp38_;
	GError* _inner_error0_ = NULL;
	GCalcMathExpression* result;
	current = NULL;
	res = NULL;
	{
		guint i = 0U;
		i = (guint) 0;
		{
			gboolean _tmp0_ = FALSE;
			_tmp0_ = TRUE;
			while (TRUE) {
				GCalcExpressionContainer* _tmp2_;
				GCalcExpressionContainer* _tmp3_;
				GCalcMathTerm* e = NULL;
				GCalcExpressionContainer* _tmp4_;
				GCalcExpressionContainer* _tmp5_;
				GObject* _tmp6_;
				GCalcMathTerm* _tmp7_;
				GCalcMathTerm* _tmp8_;
				GCalcMathTerm* _tmp9_;
				GCalcMathExpression* re = NULL;
				GCalcMathTerm* _tmp25_;
				GCalcMathTerm* _tmp26_;
				GCalcMathExpression* _tmp27_;
				GCalcMathExpression* _tmp28_;
				GCalcMathExpression* _tmp37_;
				if (!_tmp0_) {
					guint _tmp1_;
					_tmp1_ = i;
					i = _tmp1_ + 1;
				}
				_tmp0_ = FALSE;
				_tmp2_ = gcalc_math_expression_get_expressions ((GCalcMathExpression*) self);
				_tmp3_ = _tmp2_;
				if (!(i < g_list_model_get_n_items ((GListModel*) _tmp3_))) {
					break;
				}
				_tmp4_ = gcalc_math_expression_get_expressions ((GCalcMathExpression*) self);
				_tmp5_ = _tmp4_;
				_tmp6_ = g_list_model_get_item ((GListModel*) _tmp5_, i);
				_tmp7_ = GCALC_IS_MATH_TERM (_tmp6_) ? ((GCalcMathTerm*) _tmp6_) : NULL;
				if (_tmp7_ == NULL) {
					_g_object_unref0 (_tmp6_);
				}
				e = _tmp7_;
				_tmp8_ = e;
				if (_tmp8_ == NULL) {
					_g_object_unref0 (e);
					continue;
				}
				_tmp9_ = current;
				if (_tmp9_ == NULL) {
					GCalcMathTerm* _tmp10_;
					GCalcMathTerm* _tmp11_;
					GCalcExpressionContainer* _tmp12_;
					GCalcExpressionContainer* _tmp13_;
					GCalcMathExpression* er = NULL;
					GCalcMathTerm* _tmp14_;
					GCalcMathExpression* _tmp15_;
					GCalcMathExpression* _tmp16_;
					gboolean _tmp19_ = FALSE;
					GCalcMathExpression* _tmp20_;
					_tmp10_ = e;
					_tmp11_ = _g_object_ref0 (G_TYPE_CHECK_INSTANCE_CAST (_tmp10_, GCALC_TYPE_MATH_TERM, GCalcMathTerm));
					_g_object_unref0 (current);
					current = _tmp11_;
					_tmp12_ = gcalc_math_expression_get_expressions ((GCalcMathExpression*) self);
					_tmp13_ = _tmp12_;
					if ((i + 1) < g_list_model_get_n_items ((GListModel*) _tmp13_)) {
						_g_object_unref0 (e);
						continue;
					}
					_tmp14_ = e;
					_tmp15_ = gcalc_math_term_evaluate (G_TYPE_CHECK_INSTANCE_CAST (_tmp14_, GCALC_TYPE_MATH_TERM, GCalcMathTerm), &_inner_error0_);
					er = _tmp15_;
					if (G_UNLIKELY (_inner_error0_ != NULL)) {
						g_propagate_error (error, _inner_error0_);
						_g_object_unref0 (e);
						_g_object_unref0 (res);
						_g_object_unref0 (current);
						return NULL;
					}
					_tmp16_ = res;
					if (_tmp16_ == NULL) {
						GCalcMathExpression* _tmp17_;
						GCalcMathExpression* _tmp18_;
						_tmp17_ = er;
						_tmp18_ = _g_object_ref0 (_tmp17_);
						_g_object_unref0 (res);
						res = _tmp18_;
						_g_object_unref0 (er);
						_g_object_unref0 (e);
						break;
					}
					_tmp20_ = res;
					if (GCALC_IS_MATH_CONSTANT (_tmp20_)) {
						GCalcMathExpression* _tmp21_;
						_tmp21_ = er;
						_tmp19_ = GCALC_IS_MATH_CONSTANT (_tmp21_);
					} else {
						_tmp19_ = FALSE;
					}
					if (_tmp19_) {
						GCalcMathExpression* _tmp22_;
						GCalcMathExpression* _tmp23_;
						GCalcMathConstant* _tmp24_;
						_tmp22_ = res;
						_tmp23_ = er;
						_tmp24_ = gcalc_math_constant_add (G_TYPE_CHECK_INSTANCE_CAST (_tmp22_, GCALC_TYPE_MATH_CONSTANT, GCalcMathConstant), G_TYPE_CHECK_INSTANCE_CAST (_tmp23_, GCALC_TYPE_MATH_CONSTANT, GCalcMathConstant));
						_g_object_unref0 (res);
						res = (GCalcMathExpression*) _tmp24_;
						_g_object_unref0 (er);
						_g_object_unref0 (e);
						break;
					}
					_g_object_unref0 (er);
				}
				_tmp25_ = current;
				_tmp26_ = e;
				_tmp27_ = gcalc_math_term_add (_tmp25_, G_TYPE_CHECK_INSTANCE_CAST (_tmp26_, GCALC_TYPE_MATH_TERM, GCalcMathTerm), &_inner_error0_);
				re = _tmp27_;
				if (G_UNLIKELY (_inner_error0_ != NULL)) {
					g_propagate_error (error, _inner_error0_);
					_g_object_unref0 (e);
					_g_object_unref0 (res);
					_g_object_unref0 (current);
					return NULL;
				}
				_g_object_unref0 (current);
				current = NULL;
				_tmp28_ = res;
				if (_tmp28_ == NULL) {
					GCalcMathExpression* _tmp29_;
					GCalcMathExpression* _tmp30_;
					_tmp29_ = re;
					_tmp30_ = _g_object_ref0 (_tmp29_);
					_g_object_unref0 (res);
					res = _tmp30_;
				} else {
					gboolean _tmp31_ = FALSE;
					GCalcMathExpression* _tmp32_;
					_tmp32_ = res;
					if (GCALC_IS_MATH_CONSTANT (_tmp32_)) {
						GCalcMathExpression* _tmp33_;
						_tmp33_ = re;
						_tmp31_ = GCALC_IS_MATH_CONSTANT (_tmp33_);
					} else {
						_tmp31_ = FALSE;
					}
					if (_tmp31_) {
						GCalcMathExpression* _tmp34_;
						GCalcMathExpression* _tmp35_;
						GCalcMathConstant* _tmp36_;
						_tmp34_ = res;
						_tmp35_ = re;
						_tmp36_ = gcalc_math_constant_add (G_TYPE_CHECK_INSTANCE_CAST (_tmp34_, GCALC_TYPE_MATH_CONSTANT, GCalcMathConstant), G_TYPE_CHECK_INSTANCE_CAST (_tmp35_, GCALC_TYPE_MATH_CONSTANT, GCalcMathConstant));
						_g_object_unref0 (res);
						res = (GCalcMathExpression*) _tmp36_;
					}
				}
				_tmp37_ = res;
				if (_tmp37_ != NULL) {
				}
				_g_object_unref0 (re);
				_g_object_unref0 (e);
			}
		}
	}
	_tmp38_ = res;
	if (_tmp38_ == NULL) {
		GCalcErrorExpression* _tmp39_;
		_tmp39_ = gcalc_error_expression_new ();
		result = (GCalcMathExpression*) _tmp39_;
		_g_object_unref0 (res);
		_g_object_unref0 (current);
		return result;
	}
	result = res;
	_g_object_unref0 (current);
	return result;
}

GCalcMathExpression*
gcalc_math_polynomial_evaluate (GCalcMathPolynomial* self,
                                GError** error)
{
	GCalcMathPolynomialIface* _iface_;
	g_return_val_if_fail (self != NULL, NULL);
	_iface_ = GCALC_MATH_POLYNOMIAL_GET_INTERFACE (self);
	if (_iface_->evaluate) {
		return _iface_->evaluate (self, error);
	}
	return NULL;
}

static void
gcalc_math_polynomial_default_init (GCalcMathPolynomialIface * iface,
                                    gpointer iface_data)
{
	iface->evaluate = gcalc_math_polynomial_real_evaluate;
}

/**
 * A multiple expressions in a math expression
 */
static GType
gcalc_math_polynomial_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (GCalcMathPolynomialIface), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) gcalc_math_polynomial_default_init, (GClassFinalizeFunc) NULL, NULL, 0, 0, (GInstanceInitFunc) NULL, NULL };
	GType gcalc_math_polynomial_type_id;
	gcalc_math_polynomial_type_id = g_type_register_static (G_TYPE_INTERFACE, "GCalcMathPolynomial", &g_define_type_info, 0);
	g_type_interface_add_prerequisite (gcalc_math_polynomial_type_id, G_TYPE_OBJECT);
	g_type_interface_add_prerequisite (gcalc_math_polynomial_type_id, GCALC_TYPE_MATH_EXPRESSION);
	return gcalc_math_polynomial_type_id;
}

GType
gcalc_math_polynomial_get_type (void)
{
	static volatile gsize gcalc_math_polynomial_type_id__once = 0;
	if (g_once_init_enter (&gcalc_math_polynomial_type_id__once)) {
		GType gcalc_math_polynomial_type_id;
		gcalc_math_polynomial_type_id = gcalc_math_polynomial_get_type_once ();
		g_once_init_leave (&gcalc_math_polynomial_type_id__once, gcalc_math_polynomial_type_id);
	}
	return gcalc_math_polynomial_type_id__once;
}

