/* contacts-chunk-property-filter.c generated by valac 0.56.18-dirty, the Vala compiler
 * generated from contacts-chunk-property-filter.vala, do not modify */

/*
 * Copyright (C) 2022 Niels De Graef <nielsdegraef@gmail.com>
 *
 * SPDX-License-Identifier: GPL-2.0-or-later
 */

#include "contacts.h"
#include <gtk/gtk.h>
#include <glib-object.h>
#include <glib.h>
#include <stdlib.h>
#include <string.h>
#include "contactscore.h"
#include <gio/gio.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  {
	CONTACTS_CHUNK_PROPERTY_FILTER_0_PROPERTY,
	CONTACTS_CHUNK_PROPERTY_FILTER_ALLOWED_PROPERTIES_PROPERTY,
	CONTACTS_CHUNK_PROPERTY_FILTER_NUM_PROPERTIES
};
static GParamSpec* contacts_chunk_property_filter_properties[CONTACTS_CHUNK_PROPERTY_FILTER_NUM_PROPERTIES];
#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))

struct _ContactsChunkPropertyFilterPrivate {
	GtkStringList* _allowed_properties;
};

static gint ContactsChunkPropertyFilter_private_offset;
static gpointer contacts_chunk_property_filter_parent_class = NULL;

static gboolean contacts_chunk_property_filter_real_match (GtkFilter* base,
                                                    GObject* item);
static gboolean contacts_chunk_property_filter_match_property_name (ContactsChunkPropertyFilter* self,
                                                             ContactsChunk* chunk);
static GtkFilterMatch contacts_chunk_property_filter_real_get_strictness (GtkFilter* base);
static void _contacts_chunk_property_filter_allowed_properties___lambda4_ (ContactsChunkPropertyFilter* self,
                                                                    GListModel* list,
                                                                    guint pos,
                                                                    guint removed,
                                                                    guint added);
static void __contacts_chunk_property_filter_allowed_properties___lambda4__g_list_model_items_changed (GListModel* _sender,
                                                                                                guint position,
                                                                                                guint removed,
                                                                                                guint added,
                                                                                                gpointer self);
static void contacts_chunk_property_filter_finalize (GObject * obj);
static GType contacts_chunk_property_filter_get_type_once (void);
static void _vala_contacts_chunk_property_filter_get_property (GObject * object,
                                                        guint property_id,
                                                        GValue * value,
                                                        GParamSpec * pspec);
static void _vala_contacts_chunk_property_filter_set_property (GObject * object,
                                                        guint property_id,
                                                        const GValue * value,
                                                        GParamSpec * pspec);
static void _vala_array_destroy (gpointer array,
                          gssize array_length,
                          GDestroyNotify destroy_func);
static void _vala_array_free (gpointer array,
                       gssize array_length,
                       GDestroyNotify destroy_func);

static inline gpointer
contacts_chunk_property_filter_get_instance_private (ContactsChunkPropertyFilter* self)
{
	return G_STRUCT_MEMBER_P (self, ContactsChunkPropertyFilter_private_offset);
}

/**
   * Creates a ChunkPropertyFilter for a specific property
   */
ContactsChunkPropertyFilter*
contacts_chunk_property_filter_construct (GType object_type,
                                          gchar** properties,
                                          gint properties_length1)
{
	ContactsChunkPropertyFilter * self = NULL;
	GtkStringList* _tmp0_;
	GtkStringList* _tmp1_;
	_tmp0_ = gtk_string_list_new (properties);
	_tmp1_ = _tmp0_;
	self = (ContactsChunkPropertyFilter*) g_object_new (object_type, "allowed-properties", _tmp1_, NULL);
	_g_object_unref0 (_tmp1_);
	return self;
}

ContactsChunkPropertyFilter*
contacts_chunk_property_filter_new (gchar** properties,
                                    gint properties_length1)
{
	return contacts_chunk_property_filter_construct (CONTACTS_TYPE_CHUNK_PROPERTY_FILTER, properties, properties_length1);
}

/**
   * Creates a ChunkPropertyFilter for a specific property
   */
ContactsChunkPropertyFilter*
contacts_chunk_property_filter_construct_for_single (GType object_type,
                                                     const gchar* property_name)
{
	ContactsChunkPropertyFilter * self = NULL;
	gchar* _tmp0_;
	gchar** _tmp1_;
	gchar** _tmp2_;
	gint _tmp2__length1;
	GtkStringList* _tmp3_;
	GtkStringList* _tmp4_;
	g_return_val_if_fail (property_name != NULL, NULL);
	_tmp0_ = g_strdup (property_name);
	_tmp1_ = g_new0 (gchar*, 1 + 1);
	_tmp1_[0] = _tmp0_;
	_tmp2_ = _tmp1_;
	_tmp2__length1 = 1;
	_tmp3_ = gtk_string_list_new (_tmp2_);
	_tmp4_ = _tmp3_;
	self = (ContactsChunkPropertyFilter*) g_object_new (object_type, "allowed-properties", _tmp4_, NULL);
	_g_object_unref0 (_tmp4_);
	_tmp2_ = (_vala_array_free (_tmp2_, _tmp2__length1, (GDestroyNotify) g_free), NULL);
	return self;
}

ContactsChunkPropertyFilter*
contacts_chunk_property_filter_new_for_single (const gchar* property_name)
{
	return contacts_chunk_property_filter_construct_for_single (CONTACTS_TYPE_CHUNK_PROPERTY_FILTER, property_name);
}

static gboolean
contacts_chunk_property_filter_real_match (GtkFilter* base,
                                           GObject* item)
{
	ContactsChunkPropertyFilter * self;
	ContactsChunk* chunk = NULL;
	gboolean result;
	self = (ContactsChunkPropertyFilter*) base;
	chunk = G_TYPE_CHECK_INSTANCE_CAST (item, CONTACTS_TYPE_CHUNK, ContactsChunk);
	result = contacts_chunk_property_filter_match_property_name (self, chunk);
	return result;
}

static gboolean
contacts_chunk_property_filter_match_property_name (ContactsChunkPropertyFilter* self,
                                                    ContactsChunk* chunk)
{
	GtkStringList* _tmp0_;
	GtkStringList* _tmp1_;
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	g_return_val_if_fail (chunk != NULL, FALSE);
	_tmp0_ = contacts_chunk_property_filter_get_allowed_properties (self);
	_tmp1_ = _tmp0_;
	if (g_list_model_get_n_items ((GListModel*) _tmp1_) == ((guint) 0)) {
		result = TRUE;
		return result;
	}
	{
		guint i = 0U;
		i = (guint) 0;
		{
			gboolean _tmp2_ = FALSE;
			_tmp2_ = TRUE;
			while (TRUE) {
				GtkStringList* _tmp4_;
				GtkStringList* _tmp5_;
				const gchar* _tmp6_;
				const gchar* _tmp7_;
				GtkStringList* _tmp8_;
				GtkStringList* _tmp9_;
				const gchar* _tmp10_;
				if (!_tmp2_) {
					guint _tmp3_;
					_tmp3_ = i;
					i = _tmp3_ + 1;
				}
				_tmp2_ = FALSE;
				_tmp4_ = contacts_chunk_property_filter_get_allowed_properties (self);
				_tmp5_ = _tmp4_;
				if (!(i < g_list_model_get_n_items ((GListModel*) _tmp5_))) {
					break;
				}
				_tmp6_ = contacts_chunk_get_property_name (chunk);
				_tmp7_ = _tmp6_;
				_tmp8_ = contacts_chunk_property_filter_get_allowed_properties (self);
				_tmp9_ = _tmp8_;
				_tmp10_ = gtk_string_list_get_string (_tmp9_, i);
				if (g_strcmp0 (_tmp7_, _tmp10_) == 0) {
					result = TRUE;
					return result;
				}
			}
		}
	}
	result = FALSE;
	return result;
}

static GtkFilterMatch
contacts_chunk_property_filter_real_get_strictness (GtkFilter* base)
{
	ContactsChunkPropertyFilter * self;
	GtkStringList* _tmp0_;
	GtkStringList* _tmp1_;
	GtkFilterMatch result;
	self = (ContactsChunkPropertyFilter*) base;
	_tmp0_ = contacts_chunk_property_filter_get_allowed_properties (self);
	_tmp1_ = _tmp0_;
	if (g_list_model_get_n_items ((GListModel*) _tmp1_) == ((guint) 0)) {
		result = GTK_FILTER_MATCH_ALL;
		return result;
	}
	result = GTK_FILTER_MATCH_SOME;
	return result;
}

GtkStringList*
contacts_chunk_property_filter_get_allowed_properties (ContactsChunkPropertyFilter* self)
{
	GtkStringList* result;
	GtkStringList* _tmp0_;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = self->priv->_allowed_properties;
	result = _tmp0_;
	return result;
}

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

static void
_contacts_chunk_property_filter_allowed_properties___lambda4_ (ContactsChunkPropertyFilter* self,
                                                               GListModel* list,
                                                               guint pos,
                                                               guint removed,
                                                               guint added)
{
	gboolean _tmp0_ = FALSE;
	gboolean _tmp1_ = FALSE;
	g_return_if_fail (list != NULL);
	if (added > ((guint) 0)) {
		_tmp1_ = removed == ((guint) 0);
	} else {
		_tmp1_ = FALSE;
	}
	if (_tmp1_) {
		_tmp0_ = TRUE;
	} else {
		_tmp0_ = g_list_model_get_n_items (list) == ((guint) 0);
	}
	if (_tmp0_) {
		gtk_filter_changed ((GtkFilter*) self, GTK_FILTER_CHANGE_LESS_STRICT);
	} else {
		gboolean _tmp2_ = FALSE;
		if (added == ((guint) 0)) {
			_tmp2_ = removed > ((guint) 0);
		} else {
			_tmp2_ = FALSE;
		}
		if (_tmp2_) {
			gtk_filter_changed ((GtkFilter*) self, GTK_FILTER_CHANGE_MORE_STRICT);
		} else {
			gtk_filter_changed ((GtkFilter*) self, GTK_FILTER_CHANGE_DIFFERENT);
		}
	}
}

static void
__contacts_chunk_property_filter_allowed_properties___lambda4__g_list_model_items_changed (GListModel* _sender,
                                                                                           guint position,
                                                                                           guint removed,
                                                                                           guint added,
                                                                                           gpointer self)
{
	_contacts_chunk_property_filter_allowed_properties___lambda4_ ((ContactsChunkPropertyFilter*) self, _sender, position, removed, added);
}

void
contacts_chunk_property_filter_set_allowed_properties (ContactsChunkPropertyFilter* self,
                                                       GtkStringList* value)
{
	GtkStringList* _tmp0_;
	g_return_if_fail (self != NULL);
	_tmp0_ = _g_object_ref0 (value);
	_g_object_unref0 (self->priv->_allowed_properties);
	self->priv->_allowed_properties = _tmp0_;
	g_signal_connect_object ((GListModel*) value, "items-changed", (GCallback) __contacts_chunk_property_filter_allowed_properties___lambda4__g_list_model_items_changed, self, 0);
	g_object_notify_by_pspec ((GObject *) self, contacts_chunk_property_filter_properties[CONTACTS_CHUNK_PROPERTY_FILTER_ALLOWED_PROPERTIES_PROPERTY]);
}

static void
contacts_chunk_property_filter_class_init (ContactsChunkPropertyFilterClass * klass,
                                           gpointer klass_data)
{
	contacts_chunk_property_filter_parent_class = g_type_class_peek_parent (klass);
	g_type_class_adjust_private_offset (klass, &ContactsChunkPropertyFilter_private_offset);
	((GtkFilterClass *) klass)->match = (gboolean (*) (GtkFilter*, GObject*)) contacts_chunk_property_filter_real_match;
	((GtkFilterClass *) klass)->get_strictness = (GtkFilterMatch (*) (GtkFilter*)) contacts_chunk_property_filter_real_get_strictness;
	G_OBJECT_CLASS (klass)->get_property = _vala_contacts_chunk_property_filter_get_property;
	G_OBJECT_CLASS (klass)->set_property = _vala_contacts_chunk_property_filter_set_property;
	G_OBJECT_CLASS (klass)->finalize = contacts_chunk_property_filter_finalize;
	/** If not empty, only the properties in the string list will match */
	g_object_class_install_property (G_OBJECT_CLASS (klass), CONTACTS_CHUNK_PROPERTY_FILTER_ALLOWED_PROPERTIES_PROPERTY, contacts_chunk_property_filter_properties[CONTACTS_CHUNK_PROPERTY_FILTER_ALLOWED_PROPERTIES_PROPERTY] = g_param_spec_object ("allowed-properties", "allowed-properties", "allowed-properties", gtk_string_list_get_type (), G_PARAM_STATIC_STRINGS | G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT));
}

static void
contacts_chunk_property_filter_instance_init (ContactsChunkPropertyFilter * self,
                                              gpointer klass)
{
	self->priv = contacts_chunk_property_filter_get_instance_private (self);
	self->priv->_allowed_properties = NULL;
}

static void
contacts_chunk_property_filter_finalize (GObject * obj)
{
	ContactsChunkPropertyFilter * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, CONTACTS_TYPE_CHUNK_PROPERTY_FILTER, ContactsChunkPropertyFilter);
	_g_object_unref0 (self->priv->_allowed_properties);
	G_OBJECT_CLASS (contacts_chunk_property_filter_parent_class)->finalize (obj);
}

/**
 * A custom GtkFilter to filter {@link Chunk}s on a given property.
 */
 G_GNUC_NO_INLINE static GType
contacts_chunk_property_filter_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (ContactsChunkPropertyFilterClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) contacts_chunk_property_filter_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (ContactsChunkPropertyFilter), 0, (GInstanceInitFunc) contacts_chunk_property_filter_instance_init, NULL };
	GType contacts_chunk_property_filter_type_id;
	contacts_chunk_property_filter_type_id = g_type_register_static (gtk_filter_get_type (), "ContactsChunkPropertyFilter", &g_define_type_info, 0);
	ContactsChunkPropertyFilter_private_offset = g_type_add_instance_private (contacts_chunk_property_filter_type_id, sizeof (ContactsChunkPropertyFilterPrivate));
	return contacts_chunk_property_filter_type_id;
}

GType
contacts_chunk_property_filter_get_type (void)
{
	static volatile gsize contacts_chunk_property_filter_type_id__once = 0;
	if (g_once_init_enter (&contacts_chunk_property_filter_type_id__once)) {
		GType contacts_chunk_property_filter_type_id;
		contacts_chunk_property_filter_type_id = contacts_chunk_property_filter_get_type_once ();
		g_once_init_leave (&contacts_chunk_property_filter_type_id__once, contacts_chunk_property_filter_type_id);
	}
	return contacts_chunk_property_filter_type_id__once;
}

static void
_vala_contacts_chunk_property_filter_get_property (GObject * object,
                                                   guint property_id,
                                                   GValue * value,
                                                   GParamSpec * pspec)
{
	ContactsChunkPropertyFilter * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (object, CONTACTS_TYPE_CHUNK_PROPERTY_FILTER, ContactsChunkPropertyFilter);
	switch (property_id) {
		case CONTACTS_CHUNK_PROPERTY_FILTER_ALLOWED_PROPERTIES_PROPERTY:
		g_value_set_object (value, contacts_chunk_property_filter_get_allowed_properties (self));
		break;
		default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
	}
}

static void
_vala_contacts_chunk_property_filter_set_property (GObject * object,
                                                   guint property_id,
                                                   const GValue * value,
                                                   GParamSpec * pspec)
{
	ContactsChunkPropertyFilter * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (object, CONTACTS_TYPE_CHUNK_PROPERTY_FILTER, ContactsChunkPropertyFilter);
	switch (property_id) {
		case CONTACTS_CHUNK_PROPERTY_FILTER_ALLOWED_PROPERTIES_PROPERTY:
		contacts_chunk_property_filter_set_allowed_properties (self, g_value_get_object (value));
		break;
		default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
	}
}

static void
_vala_array_destroy (gpointer array,
                     gssize array_length,
                     GDestroyNotify destroy_func)
{
	if ((array != NULL) && (destroy_func != NULL)) {
		gssize i;
		for (i = 0; i < array_length; i = i + 1) {
			if (((gpointer*) array)[i] != NULL) {
				destroy_func (((gpointer*) array)[i]);
			}
		}
	}
}

static void
_vala_array_free (gpointer array,
                  gssize array_length,
                  GDestroyNotify destroy_func)
{
	_vala_array_destroy (array, array_length, destroy_func);
	g_free (array);
}

