/* contacts-chunk-sorter.c generated by valac 0.56.3, the Vala compiler
 * generated from contacts-chunk-sorter.vala, do not modify */

/*
 * Copyright (C) 2022 Niels De Graef <nielsdegraef@gmail.com>
 *
 * 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 2 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/>.
 */

#include "contacts.h"
#include <gtk/gtk.h>
#include <glib-object.h>
#include <stdlib.h>
#include <string.h>
#include <glib.h>
#include "contactscore.h"
#include <folks/folks.h>

enum  {
	CONTACTS_CHUNK_SORTER_0_PROPERTY,
	CONTACTS_CHUNK_SORTER_NUM_PROPERTIES
};
static GParamSpec* contacts_chunk_sorter_properties[CONTACTS_CHUNK_SORTER_NUM_PROPERTIES];
#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))

struct _ContactsChunkSorterPrivate {
	ContactsPersonaSorter* persona_sorter;
};

static gint ContactsChunkSorter_private_offset;
static gpointer contacts_chunk_sorter_parent_class = NULL;

static GtkSorterOrder contacts_chunk_sorter_real_get_order (GtkSorter* base);
static GtkOrdering contacts_chunk_sorter_real_compare (GtkSorter* base,
                                                GObject* item1,
                                                GObject* item2);
static gint contacts_chunk_sorter_prop_index (ContactsChunkSorter* self,
                                       const gchar* property_name);
static void contacts_chunk_sorter_finalize (GObject * obj);
static GType contacts_chunk_sorter_get_type_once (void);

static const gchar* CONTACTS_CHUNK_SORTER_SORTED_PROPERTIES[9] = {"email-addresses", "phone-numbers", "im-addresses", "roles", "urls", "nickname", "birthday", "postal-addresses", "notes"};

static inline gpointer
contacts_chunk_sorter_get_instance_private (ContactsChunkSorter* self)
{
	return G_STRUCT_MEMBER_P (self, ContactsChunkSorter_private_offset);
}

static GtkSorterOrder
contacts_chunk_sorter_real_get_order (GtkSorter* base)
{
	ContactsChunkSorter * self;
	GtkSorterOrder result;
	self = (ContactsChunkSorter*) base;
	result = GTK_SORTER_ORDER_PARTIAL;
	return result;
}

static GtkOrdering
contacts_chunk_sorter_real_compare (GtkSorter* base,
                                    GObject* item1,
                                    GObject* item2)
{
	ContactsChunkSorter * self;
	ContactsChunk* chunk_1 = NULL;
	ContactsChunk* chunk_2 = NULL;
	ContactsChunk* _tmp0_;
	FolksPersona* _tmp1_;
	FolksPersona* _tmp2_;
	ContactsChunk* _tmp3_;
	FolksPersona* _tmp4_;
	FolksPersona* _tmp5_;
	ContactsChunk* _tmp10_;
	FolksPersona* _tmp11_;
	FolksPersona* _tmp12_;
	gint index_1 = 0;
	ContactsChunk* _tmp20_;
	const gchar* _tmp21_;
	const gchar* _tmp22_;
	gint index_2 = 0;
	ContactsChunk* _tmp23_;
	const gchar* _tmp24_;
	const gchar* _tmp25_;
	GtkOrdering result;
	self = (ContactsChunkSorter*) base;
	chunk_1 = G_TYPE_CHECK_INSTANCE_CAST (item1, CONTACTS_TYPE_CHUNK, ContactsChunk);
	chunk_2 = G_TYPE_CHECK_INSTANCE_CAST (item2, CONTACTS_TYPE_CHUNK, ContactsChunk);
	_tmp0_ = chunk_1;
	_tmp1_ = contacts_chunk_get_persona (_tmp0_);
	_tmp2_ = _tmp1_;
	_tmp3_ = chunk_2;
	_tmp4_ = contacts_chunk_get_persona (_tmp3_);
	_tmp5_ = _tmp4_;
	if ((_tmp2_ == NULL) != (_tmp5_ == NULL)) {
		GtkOrdering _tmp6_ = 0;
		ContactsChunk* _tmp7_;
		FolksPersona* _tmp8_;
		FolksPersona* _tmp9_;
		_tmp7_ = chunk_1;
		_tmp8_ = contacts_chunk_get_persona (_tmp7_);
		_tmp9_ = _tmp8_;
		if (_tmp9_ == NULL) {
			_tmp6_ = GTK_ORDERING_LARGER;
		} else {
			_tmp6_ = GTK_ORDERING_SMALLER;
		}
		result = _tmp6_;
		return result;
	}
	_tmp10_ = chunk_1;
	_tmp11_ = contacts_chunk_get_persona (_tmp10_);
	_tmp12_ = _tmp11_;
	if (_tmp12_ != NULL) {
		GtkOrdering persona_order = 0;
		ContactsPersonaSorter* _tmp13_;
		ContactsChunk* _tmp14_;
		FolksPersona* _tmp15_;
		FolksPersona* _tmp16_;
		ContactsChunk* _tmp17_;
		FolksPersona* _tmp18_;
		FolksPersona* _tmp19_;
		_tmp13_ = self->priv->persona_sorter;
		_tmp14_ = chunk_1;
		_tmp15_ = contacts_chunk_get_persona (_tmp14_);
		_tmp16_ = _tmp15_;
		_tmp17_ = chunk_2;
		_tmp18_ = contacts_chunk_get_persona (_tmp17_);
		_tmp19_ = _tmp18_;
		persona_order = gtk_sorter_compare ((GtkSorter*) _tmp13_, (GObject*) _tmp16_, (GObject*) _tmp19_);
		if (persona_order != GTK_ORDERING_EQUAL) {
			result = persona_order;
			return result;
		}
	}
	_tmp20_ = chunk_1;
	_tmp21_ = contacts_chunk_get_property_name (_tmp20_);
	_tmp22_ = _tmp21_;
	index_1 = contacts_chunk_sorter_prop_index (self, _tmp22_);
	_tmp23_ = chunk_2;
	_tmp24_ = contacts_chunk_get_property_name (_tmp23_);
	_tmp25_ = _tmp24_;
	index_2 = contacts_chunk_sorter_prop_index (self, _tmp25_);
	result = gtk_ordering_from_cmpfunc (index_1 - index_2);
	return result;
}

static gint
contacts_chunk_sorter_prop_index (ContactsChunkSorter* self,
                                  const gchar* property_name)
{
	gint result;
	g_return_val_if_fail (self != NULL, 0);
	g_return_val_if_fail (property_name != NULL, 0);
	{
		gint i = 0;
		i = 0;
		{
			gboolean _tmp0_ = FALSE;
			_tmp0_ = TRUE;
			while (TRUE) {
				const gchar* _tmp2_;
				if (!_tmp0_) {
					gint _tmp1_;
					_tmp1_ = i;
					i = _tmp1_ + 1;
				}
				_tmp0_ = FALSE;
				if (!(i < G_N_ELEMENTS (CONTACTS_CHUNK_SORTER_SORTED_PROPERTIES))) {
					break;
				}
				_tmp2_ = CONTACTS_CHUNK_SORTER_SORTED_PROPERTIES[i];
				if (g_strcmp0 (property_name, _tmp2_) == 0) {
					result = i;
					return result;
				}
			}
		}
	}
	result = -1;
	return result;
}

ContactsChunkSorter*
contacts_chunk_sorter_construct (GType object_type)
{
	ContactsChunkSorter * self = NULL;
	self = (ContactsChunkSorter*) g_object_new (object_type, NULL);
	return self;
}

ContactsChunkSorter*
contacts_chunk_sorter_new (void)
{
	return contacts_chunk_sorter_construct (CONTACTS_TYPE_CHUNK_SORTER);
}

static void
contacts_chunk_sorter_class_init (ContactsChunkSorterClass * klass,
                                  gpointer klass_data)
{
	contacts_chunk_sorter_parent_class = g_type_class_peek_parent (klass);
	g_type_class_adjust_private_offset (klass, &ContactsChunkSorter_private_offset);
	((GtkSorterClass *) klass)->get_order = (GtkSorterOrder (*) (GtkSorter*)) contacts_chunk_sorter_real_get_order;
	((GtkSorterClass *) klass)->compare = (GtkOrdering (*) (GtkSorter*, GObject*, GObject*)) contacts_chunk_sorter_real_compare;
	G_OBJECT_CLASS (klass)->finalize = contacts_chunk_sorter_finalize;
}

static void
contacts_chunk_sorter_instance_init (ContactsChunkSorter * self,
                                     gpointer klass)
{
	ContactsPersonaSorter* _tmp0_;
	self->priv = contacts_chunk_sorter_get_instance_private (self);
	_tmp0_ = contacts_persona_sorter_new ();
	self->priv->persona_sorter = _tmp0_;
}

static void
contacts_chunk_sorter_finalize (GObject * obj)
{
	ContactsChunkSorter * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, CONTACTS_TYPE_CHUNK_SORTER, ContactsChunkSorter);
	_g_object_unref0 (self->priv->persona_sorter);
	G_OBJECT_CLASS (contacts_chunk_sorter_parent_class)->finalize (obj);
}

/**
 * A customer sorter that sorts {@link Chunk}s so that personas are grouped.
 */
 G_GNUC_NO_INLINE static GType
contacts_chunk_sorter_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (ContactsChunkSorterClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) contacts_chunk_sorter_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (ContactsChunkSorter), 0, (GInstanceInitFunc) contacts_chunk_sorter_instance_init, NULL };
	GType contacts_chunk_sorter_type_id;
	contacts_chunk_sorter_type_id = g_type_register_static (gtk_sorter_get_type (), "ContactsChunkSorter", &g_define_type_info, 0);
	ContactsChunkSorter_private_offset = g_type_add_instance_private (contacts_chunk_sorter_type_id, sizeof (ContactsChunkSorterPrivate));
	return contacts_chunk_sorter_type_id;
}

GType
contacts_chunk_sorter_get_type (void)
{
	static volatile gsize contacts_chunk_sorter_type_id__once = 0;
	if (g_once_init_enter (&contacts_chunk_sorter_type_id__once)) {
		GType contacts_chunk_sorter_type_id;
		contacts_chunk_sorter_type_id = contacts_chunk_sorter_get_type_once ();
		g_once_init_leave (&contacts_chunk_sorter_type_id__once, contacts_chunk_sorter_type_id);
	}
	return contacts_chunk_sorter_type_id__once;
}

