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

/*-
 * Copyright (c) 2014-2018 elementary LLC.
 *
 * This software is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This software 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
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this software; if not, write to the
 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 *
 * Authored by: Corentin Noël <corentin@elementary.io>
 */

#include "display.h"
#include <gee.h>
#include <glib-object.h>
#include <glib.h>
#include <float.h>
#include <math.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

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

static gboolean _vala_double_array_contains (gdouble * stack,
                                      gssize stack_length,
                                      const gdouble needle);

static gboolean
_vala_double_array_contains (gdouble * stack,
                             gssize stack_length,
                             const gdouble needle)
{
	gssize i;
	for (i = 0; i < stack_length; i++) {
		if (needle == stack[i]) {
			return TRUE;
		}
	}
	return FALSE;
}

GeeLinkedList*
display_utils_get_common_monitor_modes (GeeLinkedList* monitors)
{
	GeeLinkedList* common_modes = NULL;
	GeeLinkedList* _tmp0_;
	gdouble min_scale = 0.0;
	gboolean first_monitor = FALSE;
	GeeLinkedList* result;
	g_return_val_if_fail (monitors != NULL, NULL);
	_tmp0_ = gee_linked_list_new (DISPLAY_TYPE_MONITOR_MODE, (GBoxedCopyFunc) g_object_ref, (GDestroyNotify) g_object_unref, NULL, NULL, NULL);
	common_modes = _tmp0_;
	min_scale = display_utils_get_min_compatible_scale (monitors);
	first_monitor = TRUE;
	{
		GeeLinkedList* _monitor_list = NULL;
		gint _monitor_size = 0;
		GeeLinkedList* _tmp1_;
		gint _tmp2_;
		gint _tmp3_;
		gint _monitor_index = 0;
		_monitor_list = monitors;
		_tmp1_ = _monitor_list;
		_tmp2_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) _tmp1_);
		_tmp3_ = _tmp2_;
		_monitor_size = _tmp3_;
		_monitor_index = -1;
		while (TRUE) {
			gint _tmp4_;
			gint _tmp5_;
			DisplayMonitor* monitor = NULL;
			GeeLinkedList* _tmp6_;
			gpointer _tmp7_;
			_monitor_index = _monitor_index + 1;
			_tmp4_ = _monitor_index;
			_tmp5_ = _monitor_size;
			if (!(_tmp4_ < _tmp5_)) {
				break;
			}
			_tmp6_ = _monitor_list;
			_tmp7_ = gee_abstract_list_get ((GeeAbstractList*) _tmp6_, _monitor_index);
			monitor = (DisplayMonitor*) _tmp7_;
			if (first_monitor) {
				{
					GeeLinkedList* _mode_list = NULL;
					DisplayMonitor* _tmp8_;
					GeeLinkedList* _tmp9_;
					GeeLinkedList* _tmp10_;
					gint _mode_size = 0;
					GeeLinkedList* _tmp11_;
					gint _tmp12_;
					gint _tmp13_;
					gint _mode_index = 0;
					_tmp8_ = monitor;
					_tmp9_ = display_monitor_get_modes (_tmp8_);
					_tmp10_ = _tmp9_;
					_mode_list = _tmp10_;
					_tmp11_ = _mode_list;
					_tmp12_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) _tmp11_);
					_tmp13_ = _tmp12_;
					_mode_size = _tmp13_;
					_mode_index = -1;
					while (TRUE) {
						gint _tmp14_;
						gint _tmp15_;
						DisplayMonitorMode* mode = NULL;
						GeeLinkedList* _tmp16_;
						gpointer _tmp17_;
						DisplayMonitorMode* _tmp18_;
						gdouble* _tmp19_;
						gint _tmp19__length1;
						_mode_index = _mode_index + 1;
						_tmp14_ = _mode_index;
						_tmp15_ = _mode_size;
						if (!(_tmp14_ < _tmp15_)) {
							break;
						}
						_tmp16_ = _mode_list;
						_tmp17_ = gee_abstract_list_get ((GeeAbstractList*) _tmp16_, _mode_index);
						mode = (DisplayMonitorMode*) _tmp17_;
						_tmp18_ = mode;
						_tmp19_ = _tmp18_->supported_scales;
						_tmp19__length1 = _tmp18_->supported_scales_length1;
						if (_vala_double_array_contains (_tmp19_, _tmp19__length1, min_scale)) {
							GeeLinkedList* _tmp20_;
							DisplayMonitorMode* _tmp21_;
							_tmp20_ = common_modes;
							_tmp21_ = mode;
							gee_abstract_collection_add ((GeeAbstractCollection*) _tmp20_, _tmp21_);
						}
						_g_object_unref0 (mode);
					}
				}
				first_monitor = FALSE;
			} else {
				GeeLinkedList* to_remove = NULL;
				GeeLinkedList* _tmp22_;
				GeeLinkedList* _tmp56_;
				GeeLinkedList* _tmp57_;
				_tmp22_ = gee_linked_list_new (DISPLAY_TYPE_MONITOR_MODE, (GBoxedCopyFunc) g_object_ref, (GDestroyNotify) g_object_unref, NULL, NULL, NULL);
				to_remove = _tmp22_;
				{
					GeeLinkedList* _mode_to_check_list = NULL;
					GeeLinkedList* _tmp23_;
					gint _mode_to_check_size = 0;
					GeeLinkedList* _tmp24_;
					gint _tmp25_;
					gint _tmp26_;
					gint _mode_to_check_index = 0;
					_tmp23_ = common_modes;
					_mode_to_check_list = _tmp23_;
					_tmp24_ = _mode_to_check_list;
					_tmp25_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) _tmp24_);
					_tmp26_ = _tmp25_;
					_mode_to_check_size = _tmp26_;
					_mode_to_check_index = -1;
					while (TRUE) {
						gint _tmp27_;
						gint _tmp28_;
						DisplayMonitorMode* mode_to_check = NULL;
						GeeLinkedList* _tmp29_;
						gpointer _tmp30_;
						gboolean mode_found = FALSE;
						_mode_to_check_index = _mode_to_check_index + 1;
						_tmp27_ = _mode_to_check_index;
						_tmp28_ = _mode_to_check_size;
						if (!(_tmp27_ < _tmp28_)) {
							break;
						}
						_tmp29_ = _mode_to_check_list;
						_tmp30_ = gee_abstract_list_get ((GeeAbstractList*) _tmp29_, _mode_to_check_index);
						mode_to_check = (DisplayMonitorMode*) _tmp30_;
						mode_found = FALSE;
						{
							GeeLinkedList* _monitor_mode_list = NULL;
							DisplayMonitor* _tmp31_;
							GeeLinkedList* _tmp32_;
							GeeLinkedList* _tmp33_;
							gint _monitor_mode_size = 0;
							GeeLinkedList* _tmp34_;
							gint _tmp35_;
							gint _tmp36_;
							gint _monitor_mode_index = 0;
							_tmp31_ = monitor;
							_tmp32_ = display_monitor_get_modes (_tmp31_);
							_tmp33_ = _tmp32_;
							_monitor_mode_list = _tmp33_;
							_tmp34_ = _monitor_mode_list;
							_tmp35_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) _tmp34_);
							_tmp36_ = _tmp35_;
							_monitor_mode_size = _tmp36_;
							_monitor_mode_index = -1;
							while (TRUE) {
								gint _tmp37_;
								gint _tmp38_;
								DisplayMonitorMode* monitor_mode = NULL;
								GeeLinkedList* _tmp39_;
								gpointer _tmp40_;
								gboolean _tmp41_ = FALSE;
								DisplayMonitorMode* _tmp42_;
								gint _tmp43_;
								gint _tmp44_;
								DisplayMonitorMode* _tmp45_;
								gint _tmp46_;
								gint _tmp47_;
								_monitor_mode_index = _monitor_mode_index + 1;
								_tmp37_ = _monitor_mode_index;
								_tmp38_ = _monitor_mode_size;
								if (!(_tmp37_ < _tmp38_)) {
									break;
								}
								_tmp39_ = _monitor_mode_list;
								_tmp40_ = gee_abstract_list_get ((GeeAbstractList*) _tmp39_, _monitor_mode_index);
								monitor_mode = (DisplayMonitorMode*) _tmp40_;
								_tmp42_ = mode_to_check;
								_tmp43_ = display_monitor_mode_get_width (_tmp42_);
								_tmp44_ = _tmp43_;
								_tmp45_ = monitor_mode;
								_tmp46_ = display_monitor_mode_get_width (_tmp45_);
								_tmp47_ = _tmp46_;
								if (_tmp44_ == _tmp47_) {
									DisplayMonitorMode* _tmp48_;
									gint _tmp49_;
									gint _tmp50_;
									DisplayMonitorMode* _tmp51_;
									gint _tmp52_;
									gint _tmp53_;
									_tmp48_ = mode_to_check;
									_tmp49_ = display_monitor_mode_get_height (_tmp48_);
									_tmp50_ = _tmp49_;
									_tmp51_ = monitor_mode;
									_tmp52_ = display_monitor_mode_get_height (_tmp51_);
									_tmp53_ = _tmp52_;
									_tmp41_ = _tmp50_ == _tmp53_;
								} else {
									_tmp41_ = FALSE;
								}
								if (_tmp41_) {
									mode_found = TRUE;
									_g_object_unref0 (monitor_mode);
									break;
								}
								_g_object_unref0 (monitor_mode);
							}
						}
						if (mode_found == FALSE) {
							GeeLinkedList* _tmp54_;
							DisplayMonitorMode* _tmp55_;
							_tmp54_ = to_remove;
							_tmp55_ = mode_to_check;
							gee_abstract_collection_add ((GeeAbstractCollection*) _tmp54_, _tmp55_);
						}
						_g_object_unref0 (mode_to_check);
					}
				}
				_tmp56_ = common_modes;
				_tmp57_ = to_remove;
				gee_collection_remove_all ((GeeCollection*) _tmp56_, (GeeCollection*) _tmp57_);
				_g_object_unref0 (to_remove);
			}
			_g_object_unref0 (monitor);
		}
	}
	result = common_modes;
	return result;
}

gdouble
display_utils_get_min_compatible_scale (GeeLinkedList* monitors)
{
	gdouble min_scale = 0.0;
	gdouble result;
	g_return_val_if_fail (monitors != NULL, -1.0);
	min_scale = DBL_MAX;
	{
		GeeLinkedList* _monitor_list = NULL;
		gint _monitor_size = 0;
		GeeLinkedList* _tmp0_;
		gint _tmp1_;
		gint _tmp2_;
		gint _monitor_index = 0;
		_monitor_list = monitors;
		_tmp0_ = _monitor_list;
		_tmp1_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) _tmp0_);
		_tmp2_ = _tmp1_;
		_monitor_size = _tmp2_;
		_monitor_index = -1;
		while (TRUE) {
			gint _tmp3_;
			gint _tmp4_;
			DisplayMonitor* monitor = NULL;
			GeeLinkedList* _tmp5_;
			gpointer _tmp6_;
			DisplayMonitor* _tmp7_;
			_monitor_index = _monitor_index + 1;
			_tmp3_ = _monitor_index;
			_tmp4_ = _monitor_size;
			if (!(_tmp3_ < _tmp4_)) {
				break;
			}
			_tmp5_ = _monitor_list;
			_tmp6_ = gee_abstract_list_get ((GeeAbstractList*) _tmp5_, _monitor_index);
			monitor = (DisplayMonitor*) _tmp6_;
			_tmp7_ = monitor;
			min_scale = MIN (min_scale, display_monitor_get_max_scale (_tmp7_));
			_g_object_unref0 (monitor);
		}
	}
	result = min_scale;
	return result;
}

