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

/*
 * Copyright (C) 2021 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 <glib.h>
#include <gtk/gtk.h>
#include <glib-object.h>
#include <gio/gio.h>
#include <stdlib.h>
#include <string.h>
#include <folks/folks.h>

enum  {
	CONTACTS_INDIVIDUAL_SORTER_0_PROPERTY,
	CONTACTS_INDIVIDUAL_SORTER_NUM_PROPERTIES
};
static GParamSpec* contacts_individual_sorter_properties[CONTACTS_INDIVIDUAL_SORTER_NUM_PROPERTIES];
#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))
typedef struct _Block1Data Block1Data;

struct _ContactsIndividualSorterPrivate {
	gboolean sort_on_surname;
};

struct _Block1Data {
	int _ref_count_;
	ContactsIndividualSorter* self;
	GSettings* settings;
};

static gint ContactsIndividualSorter_private_offset;
static gpointer contacts_individual_sorter_parent_class = NULL;

static Block1Data* block1_data_ref (Block1Data* _data1_);
static void block1_data_unref (void * _userdata_);
static void __lambda5_ (Block1Data* _data1_);
static void ___lambda5__g_settings_changed (GSettings* _sender,
                                     const gchar* key,
                                     gpointer self);
static GtkOrdering contacts_individual_sorter_real_compare (GtkSorter* base,
                                                     GObject* item1,
                                                     GObject* item2);
static const gchar* contacts_individual_sorter_try_get_surname (ContactsIndividualSorter* self,
                                                         FolksIndividual* indiv);
static GtkSorterOrder contacts_individual_sorter_real_get_order (GtkSorter* base);
static void contacts_individual_sorter_finalize (GObject * obj);
static GType contacts_individual_sorter_get_type_once (void);

static inline gpointer
contacts_individual_sorter_get_instance_private (ContactsIndividualSorter* self)
{
	return G_STRUCT_MEMBER_P (self, ContactsIndividualSorter_private_offset);
}

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

static Block1Data*
block1_data_ref (Block1Data* _data1_)
{
	g_atomic_int_inc (&_data1_->_ref_count_);
	return _data1_;
}

static void
block1_data_unref (void * _userdata_)
{
	Block1Data* _data1_;
	_data1_ = (Block1Data*) _userdata_;
	if (g_atomic_int_dec_and_test (&_data1_->_ref_count_)) {
		ContactsIndividualSorter* self;
		self = _data1_->self;
		_g_object_unref0 (_data1_->settings);
		_g_object_unref0 (self);
		g_slice_free (Block1Data, _data1_);
	}
}

static void
__lambda5_ (Block1Data* _data1_)
{
	ContactsIndividualSorter* self;
	self = _data1_->self;
	self->priv->sort_on_surname = g_settings_get_boolean (_data1_->settings, "sort-on-surname");
	gtk_sorter_changed ((GtkSorter*) self, GTK_SORTER_CHANGE_DIFFERENT);
}

static void
___lambda5__g_settings_changed (GSettings* _sender,
                                const gchar* key,
                                gpointer self)
{
	__lambda5_ (self);
}

ContactsIndividualSorter*
contacts_individual_sorter_construct (GType object_type,
                                      GSettings* settings)
{
	ContactsIndividualSorter * self = NULL;
	Block1Data* _data1_;
	GSettings* _tmp0_;
	g_return_val_if_fail (settings != NULL, NULL);
	_data1_ = g_slice_new0 (Block1Data);
	_data1_->_ref_count_ = 1;
	_tmp0_ = _g_object_ref0 (settings);
	_g_object_unref0 (_data1_->settings);
	_data1_->settings = _tmp0_;
	self = (ContactsIndividualSorter*) g_object_new (object_type, NULL);
	_data1_->self = g_object_ref (self);
	self->priv->sort_on_surname = g_settings_get_boolean (_data1_->settings, "sort-on-surname");
	g_signal_connect_data (_data1_->settings, "changed::sort-on-surname", (GCallback) ___lambda5__g_settings_changed, block1_data_ref (_data1_), (GClosureNotify) block1_data_unref, 0);
	block1_data_unref (_data1_);
	_data1_ = NULL;
	return self;
}

ContactsIndividualSorter*
contacts_individual_sorter_new (GSettings* settings)
{
	return contacts_individual_sorter_construct (CONTACTS_TYPE_INDIVIDUAL_SORTER, settings);
}

static GtkOrdering
contacts_individual_sorter_real_compare (GtkSorter* base,
                                         GObject* item1,
                                         GObject* item2)
{
	ContactsIndividualSorter * self;
	FolksIndividual* a = NULL;
	FolksIndividual* _tmp0_;
	FolksIndividual* b = NULL;
	FolksIndividual* _tmp1_;
	FolksIndividual* _tmp2_;
	gboolean _tmp3_;
	gboolean _tmp4_;
	FolksIndividual* _tmp5_;
	gboolean _tmp6_;
	gboolean _tmp7_;
	const gchar* _tmp12_ = NULL;
	const gchar* a_name = NULL;
	const gchar* _tmp18_ = NULL;
	const gchar* b_name = NULL;
	gint names_cmp = 0;
	const gchar* _tmp24_;
	const gchar* _tmp25_;
	GCompareFunc _tmp26_;
	FolksIndividual* _tmp27_;
	const gchar* _tmp28_;
	const gchar* _tmp29_;
	FolksIndividual* _tmp30_;
	const gchar* _tmp31_;
	const gchar* _tmp32_;
	GtkOrdering result;
	self = (ContactsIndividualSorter*) base;
	a = G_TYPE_CHECK_INSTANCE_TYPE (item1, FOLKS_TYPE_INDIVIDUAL) ? ((FolksIndividual*) item1) : NULL;
	_tmp0_ = a;
	if (_tmp0_ == NULL) {
		result = GTK_ORDERING_SMALLER;
		return result;
	}
	b = G_TYPE_CHECK_INSTANCE_TYPE (item2, FOLKS_TYPE_INDIVIDUAL) ? ((FolksIndividual*) item2) : NULL;
	_tmp1_ = b;
	if (_tmp1_ == NULL) {
		result = GTK_ORDERING_LARGER;
		return result;
	}
	_tmp2_ = a;
	_tmp3_ = folks_favourite_details_get_is_favourite ((FolksFavouriteDetails*) _tmp2_);
	_tmp4_ = _tmp3_;
	_tmp5_ = b;
	_tmp6_ = folks_favourite_details_get_is_favourite ((FolksFavouriteDetails*) _tmp5_);
	_tmp7_ = _tmp6_;
	if (_tmp4_ != _tmp7_) {
		GtkOrdering _tmp8_ = 0;
		FolksIndividual* _tmp9_;
		gboolean _tmp10_;
		gboolean _tmp11_;
		_tmp9_ = a;
		_tmp10_ = folks_favourite_details_get_is_favourite ((FolksFavouriteDetails*) _tmp9_);
		_tmp11_ = _tmp10_;
		if (_tmp11_) {
			_tmp8_ = GTK_ORDERING_SMALLER;
		} else {
			_tmp8_ = GTK_ORDERING_LARGER;
		}
		result = _tmp8_;
		return result;
	}
	if (self->priv->sort_on_surname) {
		FolksIndividual* _tmp13_;
		const gchar* _tmp14_;
		_tmp13_ = a;
		_tmp14_ = contacts_individual_sorter_try_get_surname (self, _tmp13_);
		_tmp12_ = _tmp14_;
	} else {
		FolksIndividual* _tmp15_;
		const gchar* _tmp16_;
		const gchar* _tmp17_;
		_tmp15_ = a;
		_tmp16_ = folks_individual_get_display_name (_tmp15_);
		_tmp17_ = _tmp16_;
		_tmp12_ = _tmp17_;
	}
	a_name = _tmp12_;
	if (self->priv->sort_on_surname) {
		FolksIndividual* _tmp19_;
		const gchar* _tmp20_;
		_tmp19_ = b;
		_tmp20_ = contacts_individual_sorter_try_get_surname (self, _tmp19_);
		_tmp18_ = _tmp20_;
	} else {
		FolksIndividual* _tmp21_;
		const gchar* _tmp22_;
		const gchar* _tmp23_;
		_tmp21_ = b;
		_tmp22_ = folks_individual_get_display_name (_tmp21_);
		_tmp23_ = _tmp22_;
		_tmp18_ = _tmp23_;
	}
	b_name = _tmp18_;
	_tmp24_ = a_name;
	_tmp25_ = b_name;
	names_cmp = g_utf8_collate (_tmp24_, _tmp25_);
	if (names_cmp != 0) {
		result = gtk_ordering_from_cmpfunc (names_cmp);
		return result;
	}
	_tmp26_ = ((GCompareFunc) g_strcmp0);
	_tmp27_ = a;
	_tmp28_ = folks_individual_get_id (_tmp27_);
	_tmp29_ = _tmp28_;
	_tmp30_ = b;
	_tmp31_ = folks_individual_get_id (_tmp30_);
	_tmp32_ = _tmp31_;
	result = gtk_ordering_from_cmpfunc (_tmp26_ (_tmp29_, _tmp32_));
	return result;
}

static const gchar*
contacts_individual_sorter_try_get_surname (ContactsIndividualSorter* self,
                                            FolksIndividual* indiv)
{
	gboolean _tmp0_ = FALSE;
	FolksStructuredName* _tmp1_;
	FolksStructuredName* _tmp2_;
	const gchar* _tmp11_;
	const gchar* _tmp12_;
	const gchar* result;
	g_return_val_if_fail (self != NULL, NULL);
	g_return_val_if_fail (indiv != NULL, NULL);
	_tmp1_ = folks_name_details_get_structured_name ((FolksNameDetails*) indiv);
	_tmp2_ = _tmp1_;
	if (_tmp2_ != NULL) {
		FolksStructuredName* _tmp3_;
		FolksStructuredName* _tmp4_;
		const gchar* _tmp5_;
		const gchar* _tmp6_;
		_tmp3_ = folks_name_details_get_structured_name ((FolksNameDetails*) indiv);
		_tmp4_ = _tmp3_;
		_tmp5_ = folks_structured_name_get_family_name (_tmp4_);
		_tmp6_ = _tmp5_;
		_tmp0_ = g_strcmp0 (_tmp6_, "") != 0;
	} else {
		_tmp0_ = FALSE;
	}
	if (_tmp0_) {
		FolksStructuredName* _tmp7_;
		FolksStructuredName* _tmp8_;
		const gchar* _tmp9_;
		const gchar* _tmp10_;
		_tmp7_ = folks_name_details_get_structured_name ((FolksNameDetails*) indiv);
		_tmp8_ = _tmp7_;
		_tmp9_ = folks_structured_name_get_family_name (_tmp8_);
		_tmp10_ = _tmp9_;
		result = _tmp10_;
		return result;
	}
	_tmp11_ = folks_individual_get_display_name (indiv);
	_tmp12_ = _tmp11_;
	result = _tmp12_;
	return result;
}

static GtkSorterOrder
contacts_individual_sorter_real_get_order (GtkSorter* base)
{
	ContactsIndividualSorter * self;
	GtkSorterOrder result;
	self = (ContactsIndividualSorter*) base;
	result = GTK_SORTER_ORDER_TOTAL;
	return result;
}

static void
contacts_individual_sorter_class_init (ContactsIndividualSorterClass * klass,
                                       gpointer klass_data)
{
	contacts_individual_sorter_parent_class = g_type_class_peek_parent (klass);
	g_type_class_adjust_private_offset (klass, &ContactsIndividualSorter_private_offset);
	((GtkSorterClass *) klass)->compare = (GtkOrdering (*) (GtkSorter*, GObject*, GObject*)) contacts_individual_sorter_real_compare;
	((GtkSorterClass *) klass)->get_order = (GtkSorterOrder (*) (GtkSorter*)) contacts_individual_sorter_real_get_order;
	G_OBJECT_CLASS (klass)->finalize = contacts_individual_sorter_finalize;
}

static void
contacts_individual_sorter_instance_init (ContactsIndividualSorter * self,
                                          gpointer klass)
{
	self->priv = contacts_individual_sorter_get_instance_private (self);
	self->priv->sort_on_surname = FALSE;
}

static void
contacts_individual_sorter_finalize (GObject * obj)
{
	ContactsIndividualSorter * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, CONTACTS_TYPE_INDIVIDUAL_SORTER, ContactsIndividualSorter);
	G_OBJECT_CLASS (contacts_individual_sorter_parent_class)->finalize (obj);
}

/**
 * A subclass of {@link Gtk.Sorter} which sorts {@link Folks.Individual}s.
 */
 G_GNUC_NO_INLINE static GType
contacts_individual_sorter_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (ContactsIndividualSorterClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) contacts_individual_sorter_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (ContactsIndividualSorter), 0, (GInstanceInitFunc) contacts_individual_sorter_instance_init, NULL };
	GType contacts_individual_sorter_type_id;
	contacts_individual_sorter_type_id = g_type_register_static (gtk_sorter_get_type (), "ContactsIndividualSorter", &g_define_type_info, 0);
	ContactsIndividualSorter_private_offset = g_type_add_instance_private (contacts_individual_sorter_type_id, sizeof (ContactsIndividualSorterPrivate));
	return contacts_individual_sorter_type_id;
}

GType
contacts_individual_sorter_get_type (void)
{
	static volatile gsize contacts_individual_sorter_type_id__once = 0;
	if (g_once_init_enter (&contacts_individual_sorter_type_id__once)) {
		GType contacts_individual_sorter_type_id;
		contacts_individual_sorter_type_id = contacts_individual_sorter_get_type_once ();
		g_once_init_leave (&contacts_individual_sorter_type_id__once, contacts_individual_sorter_type_id);
	}
	return contacts_individual_sorter_type_id__once;
}

