/* contacts-contact-selection-model.c generated by valac 0.56.18-dirty, the Vala compiler
 * generated from contacts-contact-selection-model.vala, do not modify */

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

#include <glib-object.h>
#include <gio/gio.h>
#include <gtk/gtk.h>
#include <glib.h>
#include <folks/folks.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
#if !defined(VALA_EXTERN)
#if defined(_MSC_VER)
#define VALA_EXTERN __declspec(dllexport) extern
#elif __GNUC__ >= 4
#define VALA_EXTERN __attribute__((visibility("default"))) extern
#else
#define VALA_EXTERN extern
#endif
#endif

#define CONTACTS_TYPE_CONTACT_SELECTION_MODEL (contacts_contact_selection_model_get_type ())
#define CONTACTS_CONTACT_SELECTION_MODEL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CONTACTS_TYPE_CONTACT_SELECTION_MODEL, ContactsContactSelectionModel))
#define CONTACTS_CONTACT_SELECTION_MODEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CONTACTS_TYPE_CONTACT_SELECTION_MODEL, ContactsContactSelectionModelClass))
#define CONTACTS_IS_CONTACT_SELECTION_MODEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CONTACTS_TYPE_CONTACT_SELECTION_MODEL))
#define CONTACTS_IS_CONTACT_SELECTION_MODEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CONTACTS_TYPE_CONTACT_SELECTION_MODEL))
#define CONTACTS_CONTACT_SELECTION_MODEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CONTACTS_TYPE_CONTACT_SELECTION_MODEL, ContactsContactSelectionModelClass))

typedef struct _ContactsContactSelectionModel ContactsContactSelectionModel;
typedef struct _ContactsContactSelectionModelClass ContactsContactSelectionModelClass;
typedef struct _ContactsContactSelectionModelPrivate ContactsContactSelectionModelPrivate;
typedef enum  {
	CONTACTS_UI_STATE_NORMAL,
	CONTACTS_UI_STATE_SHOWING,
	CONTACTS_UI_STATE_SELECTING,
	CONTACTS_UI_STATE_UPDATING,
	CONTACTS_UI_STATE_CREATING
} ContactsUiState;

#define CONTACTS_TYPE_UI_STATE (contacts_ui_state_get_type ())
enum  {
	CONTACTS_CONTACT_SELECTION_MODEL_0_PROPERTY,
	CONTACTS_CONTACT_SELECTION_MODEL_STATE_PROPERTY,
	CONTACTS_CONTACT_SELECTION_MODEL_BASE_MODEL_PROPERTY,
	CONTACTS_CONTACT_SELECTION_MODEL_SELECTED_PROPERTY,
	CONTACTS_CONTACT_SELECTION_MODEL_MARKED_PROPERTY,
	CONTACTS_CONTACT_SELECTION_MODEL_NUM_PROPERTIES
};
static GParamSpec* contacts_contact_selection_model_properties[CONTACTS_CONTACT_SELECTION_MODEL_NUM_PROPERTIES];
#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))
#define _vala_assert(expr, msg) if G_LIKELY (expr) ; else g_assertion_message_expr (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, msg);
#define _vala_return_if_fail(expr, msg) if G_LIKELY (expr) ; else { g_return_if_fail_warning (G_LOG_DOMAIN, G_STRFUNC, msg); return; }
#define _vala_return_val_if_fail(expr, msg, val) if G_LIKELY (expr) ; else { g_return_if_fail_warning (G_LOG_DOMAIN, G_STRFUNC, msg); return val; }
#define _vala_warn_if_fail(expr, msg) if G_LIKELY (expr) ; else g_warn_message (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, msg);

struct _ContactsContactSelectionModel {
	GObject parent_instance;
	ContactsContactSelectionModelPrivate * priv;
};

struct _ContactsContactSelectionModelClass {
	GObjectClass parent_class;
};

struct _ContactsContactSelectionModelPrivate {
	ContactsUiState _state;
	GListModel* _base_model;
	GtkSingleSelection* _selected;
	GtkMultiSelection* _marked;
};

static gint ContactsContactSelectionModel_private_offset;
static gpointer contacts_contact_selection_model_parent_class = NULL;
static GListModelInterface * contacts_contact_selection_model_g_list_model_parent_iface = NULL;
static GtkSelectionModelInterface * contacts_contact_selection_model_gtk_selection_model_parent_iface = NULL;
static GtkSectionModelInterface * contacts_contact_selection_model_gtk_section_model_parent_iface = NULL;

VALA_EXTERN GType contacts_contact_selection_model_get_type (void) G_GNUC_CONST ;
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ContactsContactSelectionModel, g_object_unref)
VALA_EXTERN GType contacts_ui_state_get_type (void) G_GNUC_CONST ;
VALA_EXTERN ContactsContactSelectionModel* contacts_contact_selection_model_new (GListModel* base_model);
VALA_EXTERN ContactsContactSelectionModel* contacts_contact_selection_model_construct (GType object_type,
                                                                           GListModel* base_model);
static void contacts_contact_selection_model_on_base_model_items_changed (ContactsContactSelectionModel* self,
                                                                   GListModel* base_model,
                                                                   guint pos,
                                                                   guint removed,
                                                                   guint added);
static void contacts_contact_selection_model_on_selected_selection_changed (ContactsContactSelectionModel* self,
                                                                     GtkSelectionModel* selected,
                                                                     guint position,
                                                                     guint n_changed);
static gboolean contacts_contact_selection_model_use_marked_model (ContactsContactSelectionModel* self);
static void contacts_contact_selection_model_on_marked_selection_changed (ContactsContactSelectionModel* self,
                                                                   GtkSelectionModel* marked,
                                                                   guint position,
                                                                   guint n_changed);
VALA_EXTERN FolksIndividual* contacts_contact_selection_model_get_selected_individual (ContactsContactSelectionModel* self);
VALA_EXTERN GtkSingleSelection* contacts_contact_selection_model_get_selected (ContactsContactSelectionModel* self);
VALA_EXTERN ContactsUiState contacts_contact_selection_model_get_state (ContactsContactSelectionModel* self);
static GObject* contacts_contact_selection_model_real_get_item (GListModel* base,
                                                         guint i);
VALA_EXTERN GListModel* contacts_contact_selection_model_get_base_model (ContactsContactSelectionModel* self);
static guint contacts_contact_selection_model_real_get_n_items (GListModel* base);
static GType contacts_contact_selection_model_real_get_item_type (GListModel* base);
static GtkBitset* contacts_contact_selection_model_real_get_selection_in_range (GtkSelectionModel* base,
                                                                         guint position,
                                                                         guint n_items);
VALA_EXTERN GtkMultiSelection* contacts_contact_selection_model_get_marked (ContactsContactSelectionModel* self);
static gboolean contacts_contact_selection_model_real_is_selected (GtkSelectionModel* base,
                                                            guint position);
static gboolean contacts_contact_selection_model_real_select_all (GtkSelectionModel* base);
static gboolean contacts_contact_selection_model_real_select_item (GtkSelectionModel* base,
                                                            guint position,
                                                            gboolean unselect_rest);
static gboolean contacts_contact_selection_model_real_select_range (GtkSelectionModel* base,
                                                             guint position,
                                                             guint n_items,
                                                             gboolean unselect_rest);
static gboolean contacts_contact_selection_model_real_set_selection (GtkSelectionModel* base,
                                                              GtkBitset* selected,
                                                              GtkBitset* mask);
static gboolean contacts_contact_selection_model_real_unselect_all (GtkSelectionModel* base);
static gboolean contacts_contact_selection_model_real_unselect_item (GtkSelectionModel* base,
                                                              guint position);
static gboolean contacts_contact_selection_model_real_unselect_range (GtkSelectionModel* base,
                                                               guint position,
                                                               guint n_items);
static void contacts_contact_selection_model_real_get_section (GtkSectionModel* base,
                                                        guint position,
                                                        guint* start,
                                                        guint* end);
VALA_EXTERN void contacts_contact_selection_model_set_state (ContactsContactSelectionModel* self,
                                                 ContactsUiState value);
VALA_EXTERN void contacts_contact_selection_model_set_base_model (ContactsContactSelectionModel* self,
                                                      GListModel* value);
static void contacts_contact_selection_model_set_selected (ContactsContactSelectionModel* self,
                                                    GtkSingleSelection* value);
static void contacts_contact_selection_model_set_marked (ContactsContactSelectionModel* self,
                                                  GtkMultiSelection* value);
static GObject * contacts_contact_selection_model_constructor (GType type,
                                                        guint n_construct_properties,
                                                        GObjectConstructParam * construct_properties);
static void _contacts_contact_selection_model_on_base_model_items_changed_g_list_model_items_changed (GListModel* _sender,
                                                                                               guint position,
                                                                                               guint removed,
                                                                                               guint added,
                                                                                               gpointer self);
static void _contacts_contact_selection_model_on_selected_selection_changed_gtk_selection_model_selection_changed (GtkSelectionModel* _sender,
                                                                                                            guint position,
                                                                                                            guint n_items,
                                                                                                            gpointer self);
static void _contacts_contact_selection_model_on_marked_selection_changed_gtk_selection_model_selection_changed (GtkSelectionModel* _sender,
                                                                                                          guint position,
                                                                                                          guint n_items,
                                                                                                          gpointer self);
static void contacts_contact_selection_model_finalize (GObject * obj);
static GType contacts_contact_selection_model_get_type_once (void);
static void _vala_contacts_contact_selection_model_get_property (GObject * object,
                                                          guint property_id,
                                                          GValue * value,
                                                          GParamSpec * pspec);
static void _vala_contacts_contact_selection_model_set_property (GObject * object,
                                                          guint property_id,
                                                          const GValue * value,
                                                          GParamSpec * pspec);

static inline gpointer
contacts_contact_selection_model_get_instance_private (ContactsContactSelectionModel* self)
{
	return G_STRUCT_MEMBER_P (self, ContactsContactSelectionModel_private_offset);
}

ContactsContactSelectionModel*
contacts_contact_selection_model_construct (GType object_type,
                                            GListModel* base_model)
{
	ContactsContactSelectionModel * self = NULL;
	g_return_val_if_fail (base_model != NULL, NULL);
	self = (ContactsContactSelectionModel*) g_object_new (object_type, "base-model", base_model, NULL);
	return self;
}

ContactsContactSelectionModel*
contacts_contact_selection_model_new (GListModel* base_model)
{
	return contacts_contact_selection_model_construct (CONTACTS_TYPE_CONTACT_SELECTION_MODEL, base_model);
}

static void
contacts_contact_selection_model_on_base_model_items_changed (ContactsContactSelectionModel* self,
                                                              GListModel* base_model,
                                                              guint pos,
                                                              guint removed,
                                                              guint added)
{
	g_return_if_fail (self != NULL);
	g_return_if_fail (base_model != NULL);
	g_list_model_items_changed ((GListModel*) self, pos, removed, added);
}

static void
contacts_contact_selection_model_on_selected_selection_changed (ContactsContactSelectionModel* self,
                                                                GtkSelectionModel* selected,
                                                                guint position,
                                                                guint n_changed)
{
	g_return_if_fail (self != NULL);
	g_return_if_fail (selected != NULL);
	if (!contacts_contact_selection_model_use_marked_model (self)) {
		gtk_selection_model_selection_changed ((GtkSelectionModel*) self, position, n_changed);
	}
}

static void
contacts_contact_selection_model_on_marked_selection_changed (ContactsContactSelectionModel* self,
                                                              GtkSelectionModel* marked,
                                                              guint position,
                                                              guint n_changed)
{
	g_return_if_fail (self != NULL);
	g_return_if_fail (marked != NULL);
	if (contacts_contact_selection_model_use_marked_model (self)) {
		gtk_selection_model_selection_changed ((GtkSelectionModel*) self, position, n_changed);
	}
}

FolksIndividual*
contacts_contact_selection_model_get_selected_individual (ContactsContactSelectionModel* self)
{
	GtkSingleSelection* _tmp0_;
	GObject* _tmp1_;
	GObject* _tmp2_;
	FolksIndividual* result;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = self->priv->_selected;
	_tmp1_ = gtk_single_selection_get_selected_item (_tmp0_);
	_tmp2_ = _tmp1_;
	result = G_TYPE_CHECK_INSTANCE_CAST (_tmp2_, FOLKS_TYPE_INDIVIDUAL, FolksIndividual);
	return result;
}

static gboolean
contacts_contact_selection_model_use_marked_model (ContactsContactSelectionModel* self)
{
	ContactsUiState _tmp0_;
	ContactsUiState _tmp1_;
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	_tmp0_ = contacts_contact_selection_model_get_state (self);
	_tmp1_ = _tmp0_;
	result = _tmp1_ == CONTACTS_UI_STATE_SELECTING;
	return result;
}

static GObject*
contacts_contact_selection_model_real_get_item (GListModel* base,
                                                guint i)
{
	ContactsContactSelectionModel * self;
	GListModel* _tmp0_;
	GObject* _tmp1_;
	GObject* result;
	self = (ContactsContactSelectionModel*) base;
	_tmp0_ = self->priv->_base_model;
	_tmp1_ = g_list_model_get_item (_tmp0_, i);
	result = _tmp1_;
	return result;
}

static guint
contacts_contact_selection_model_real_get_n_items (GListModel* base)
{
	ContactsContactSelectionModel * self;
	GListModel* _tmp0_;
	guint result;
	self = (ContactsContactSelectionModel*) base;
	_tmp0_ = self->priv->_base_model;
	result = g_list_model_get_n_items (_tmp0_);
	return result;
}

static GType
contacts_contact_selection_model_real_get_item_type (GListModel* base)
{
	ContactsContactSelectionModel * self;
	GType result;
	self = (ContactsContactSelectionModel*) base;
	result = FOLKS_TYPE_INDIVIDUAL;
	return result;
}

static GtkBitset*
contacts_contact_selection_model_real_get_selection_in_range (GtkSelectionModel* base,
                                                              guint position,
                                                              guint n_items)
{
	ContactsContactSelectionModel * self;
	GtkSingleSelection* _tmp2_;
	GtkBitset* _tmp3_;
	GtkBitset* result;
	self = (ContactsContactSelectionModel*) base;
	if (contacts_contact_selection_model_use_marked_model (self)) {
		GtkMultiSelection* _tmp0_;
		GtkBitset* _tmp1_;
		_tmp0_ = self->priv->_marked;
		_tmp1_ = gtk_selection_model_get_selection_in_range ((GtkSelectionModel*) _tmp0_, position, n_items);
		result = _tmp1_;
		return result;
	}
	_tmp2_ = self->priv->_selected;
	_tmp3_ = gtk_selection_model_get_selection_in_range ((GtkSelectionModel*) _tmp2_, position, n_items);
	result = _tmp3_;
	return result;
}

static gboolean
contacts_contact_selection_model_real_is_selected (GtkSelectionModel* base,
                                                   guint position)
{
	ContactsContactSelectionModel * self;
	GtkSingleSelection* _tmp1_;
	gboolean result;
	self = (ContactsContactSelectionModel*) base;
	if (contacts_contact_selection_model_use_marked_model (self)) {
		GtkMultiSelection* _tmp0_;
		_tmp0_ = self->priv->_marked;
		result = gtk_selection_model_is_selected ((GtkSelectionModel*) _tmp0_, position);
		return result;
	}
	_tmp1_ = self->priv->_selected;
	result = gtk_selection_model_is_selected ((GtkSelectionModel*) _tmp1_, position);
	return result;
}

static gboolean
contacts_contact_selection_model_real_select_all (GtkSelectionModel* base)
{
	ContactsContactSelectionModel * self;
	GtkSingleSelection* _tmp1_;
	gboolean result;
	self = (ContactsContactSelectionModel*) base;
	if (contacts_contact_selection_model_use_marked_model (self)) {
		GtkMultiSelection* _tmp0_;
		_tmp0_ = self->priv->_marked;
		result = gtk_selection_model_select_all ((GtkSelectionModel*) _tmp0_);
		return result;
	}
	_tmp1_ = self->priv->_selected;
	result = gtk_selection_model_select_all ((GtkSelectionModel*) _tmp1_);
	return result;
}

static gboolean
contacts_contact_selection_model_real_select_item (GtkSelectionModel* base,
                                                   guint position,
                                                   gboolean unselect_rest)
{
	ContactsContactSelectionModel * self;
	GtkSingleSelection* _tmp3_;
	gboolean result;
	self = (ContactsContactSelectionModel*) base;
	if (contacts_contact_selection_model_use_marked_model (self)) {
		GtkMultiSelection* _tmp0_;
		GtkMultiSelection* _tmp2_;
		_tmp0_ = self->priv->_marked;
		if (gtk_selection_model_is_selected ((GtkSelectionModel*) _tmp0_, position)) {
			GtkMultiSelection* _tmp1_;
			_tmp1_ = self->priv->_marked;
			result = gtk_selection_model_unselect_item ((GtkSelectionModel*) _tmp1_, position);
			return result;
		}
		_tmp2_ = self->priv->_marked;
		result = gtk_selection_model_select_item ((GtkSelectionModel*) _tmp2_, position, FALSE);
		return result;
	}
	_tmp3_ = self->priv->_selected;
	result = gtk_selection_model_select_item ((GtkSelectionModel*) _tmp3_, position, unselect_rest);
	return result;
}

static gboolean
contacts_contact_selection_model_real_select_range (GtkSelectionModel* base,
                                                    guint position,
                                                    guint n_items,
                                                    gboolean unselect_rest)
{
	ContactsContactSelectionModel * self;
	GtkSingleSelection* _tmp1_;
	gboolean result;
	self = (ContactsContactSelectionModel*) base;
	if (contacts_contact_selection_model_use_marked_model (self)) {
		GtkMultiSelection* _tmp0_;
		_tmp0_ = self->priv->_marked;
		result = gtk_selection_model_select_range ((GtkSelectionModel*) _tmp0_, position, n_items, FALSE);
		return result;
	}
	_tmp1_ = self->priv->_selected;
	result = gtk_selection_model_select_range ((GtkSelectionModel*) _tmp1_, position, n_items, unselect_rest);
	return result;
}

static gboolean
contacts_contact_selection_model_real_set_selection (GtkSelectionModel* base,
                                                     GtkBitset* selected,
                                                     GtkBitset* mask)
{
	ContactsContactSelectionModel * self;
	GtkSingleSelection* _tmp1_;
	gboolean result;
	self = (ContactsContactSelectionModel*) base;
	g_return_val_if_fail (selected != NULL, FALSE);
	g_return_val_if_fail (mask != NULL, FALSE);
	if (contacts_contact_selection_model_use_marked_model (self)) {
		GtkMultiSelection* _tmp0_;
		_tmp0_ = self->priv->_marked;
		result = gtk_selection_model_set_selection ((GtkSelectionModel*) _tmp0_, selected, mask);
		return result;
	}
	_tmp1_ = self->priv->_selected;
	result = gtk_selection_model_set_selection ((GtkSelectionModel*) _tmp1_, selected, mask);
	return result;
}

static gboolean
contacts_contact_selection_model_real_unselect_all (GtkSelectionModel* base)
{
	ContactsContactSelectionModel * self;
	GtkSingleSelection* _tmp1_;
	gboolean result;
	self = (ContactsContactSelectionModel*) base;
	if (contacts_contact_selection_model_use_marked_model (self)) {
		GtkMultiSelection* _tmp0_;
		_tmp0_ = self->priv->_marked;
		result = gtk_selection_model_unselect_all ((GtkSelectionModel*) _tmp0_);
		return result;
	}
	_tmp1_ = self->priv->_selected;
	result = gtk_selection_model_unselect_all ((GtkSelectionModel*) _tmp1_);
	return result;
}

static gboolean
contacts_contact_selection_model_real_unselect_item (GtkSelectionModel* base,
                                                     guint position)
{
	ContactsContactSelectionModel * self;
	GtkSingleSelection* _tmp1_;
	gboolean result;
	self = (ContactsContactSelectionModel*) base;
	if (contacts_contact_selection_model_use_marked_model (self)) {
		GtkMultiSelection* _tmp0_;
		_tmp0_ = self->priv->_marked;
		result = gtk_selection_model_unselect_item ((GtkSelectionModel*) _tmp0_, position);
		return result;
	}
	_tmp1_ = self->priv->_selected;
	result = gtk_selection_model_unselect_item ((GtkSelectionModel*) _tmp1_, position);
	return result;
}

static gboolean
contacts_contact_selection_model_real_unselect_range (GtkSelectionModel* base,
                                                      guint position,
                                                      guint n_items)
{
	ContactsContactSelectionModel * self;
	GtkSingleSelection* _tmp1_;
	gboolean result;
	self = (ContactsContactSelectionModel*) base;
	if (contacts_contact_selection_model_use_marked_model (self)) {
		GtkMultiSelection* _tmp0_;
		_tmp0_ = self->priv->_marked;
		result = gtk_selection_model_unselect_range ((GtkSelectionModel*) _tmp0_, position, n_items);
		return result;
	}
	_tmp1_ = self->priv->_selected;
	result = gtk_selection_model_unselect_range ((GtkSelectionModel*) _tmp1_, position, n_items);
	return result;
}

static void
contacts_contact_selection_model_real_get_section (GtkSectionModel* base,
                                                   guint position,
                                                   guint* start,
                                                   guint* end)
{
	ContactsContactSelectionModel * self;
	guint _vala_start = 0U;
	guint _vala_end = 0U;
	GListModel* _tmp0_;
	GtkSectionModel* section_model = NULL;
	GListModel* _tmp1_;
	guint _tmp2_ = 0U;
	guint _tmp3_ = 0U;
	self = (ContactsContactSelectionModel*) base;
	_tmp0_ = self->priv->_base_model;
	_vala_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (_tmp0_, gtk_section_model_get_type ()), "this.base_model is Gtk.SectionModel");
	_tmp1_ = self->priv->_base_model;
	section_model = G_TYPE_CHECK_INSTANCE_CAST (_tmp1_, gtk_section_model_get_type (), GtkSectionModel);
	gtk_section_model_get_section (section_model, position, &_tmp2_, &_tmp3_);
	_vala_start = _tmp2_;
	_vala_end = _tmp3_;
	if (start) {
		*start = _vala_start;
	}
	if (end) {
		*end = _vala_end;
	}
}

ContactsUiState
contacts_contact_selection_model_get_state (ContactsContactSelectionModel* self)
{
	ContactsUiState result;
	g_return_val_if_fail (self != NULL, 0);
	result = self->priv->_state;
	return result;
}

void
contacts_contact_selection_model_set_state (ContactsContactSelectionModel* self,
                                            ContactsUiState value)
{
	g_return_if_fail (self != NULL);
	if (self->priv->_state == value) {
		return;
	}
	self->priv->_state = value;
	g_object_notify ((GObject*) self, "state");
	if (g_list_model_get_n_items ((GListModel*) self) > ((guint) 0)) {
		gtk_selection_model_selection_changed ((GtkSelectionModel*) self, (guint) 0, g_list_model_get_n_items ((GListModel*) self));
	}
	g_object_notify_by_pspec ((GObject *) self, contacts_contact_selection_model_properties[CONTACTS_CONTACT_SELECTION_MODEL_STATE_PROPERTY]);
}

GListModel*
contacts_contact_selection_model_get_base_model (ContactsContactSelectionModel* self)
{
	GListModel* result;
	GListModel* _tmp0_;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = self->priv->_base_model;
	result = _tmp0_;
	return result;
}

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

void
contacts_contact_selection_model_set_base_model (ContactsContactSelectionModel* self,
                                                 GListModel* value)
{
	GListModel* old_value;
	g_return_if_fail (self != NULL);
	old_value = contacts_contact_selection_model_get_base_model (self);
	if (old_value != value) {
		GListModel* _tmp0_;
		_tmp0_ = _g_object_ref0 (value);
		_g_object_unref0 (self->priv->_base_model);
		self->priv->_base_model = _tmp0_;
		g_object_notify_by_pspec ((GObject *) self, contacts_contact_selection_model_properties[CONTACTS_CONTACT_SELECTION_MODEL_BASE_MODEL_PROPERTY]);
	}
}

GtkSingleSelection*
contacts_contact_selection_model_get_selected (ContactsContactSelectionModel* self)
{
	GtkSingleSelection* result;
	GtkSingleSelection* _tmp0_;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = self->priv->_selected;
	result = _tmp0_;
	return result;
}

static void
contacts_contact_selection_model_set_selected (ContactsContactSelectionModel* self,
                                               GtkSingleSelection* value)
{
	GtkSingleSelection* old_value;
	g_return_if_fail (self != NULL);
	old_value = contacts_contact_selection_model_get_selected (self);
	if (old_value != value) {
		GtkSingleSelection* _tmp0_;
		_tmp0_ = _g_object_ref0 (value);
		_g_object_unref0 (self->priv->_selected);
		self->priv->_selected = _tmp0_;
		g_object_notify_by_pspec ((GObject *) self, contacts_contact_selection_model_properties[CONTACTS_CONTACT_SELECTION_MODEL_SELECTED_PROPERTY]);
	}
}

GtkMultiSelection*
contacts_contact_selection_model_get_marked (ContactsContactSelectionModel* self)
{
	GtkMultiSelection* result;
	GtkMultiSelection* _tmp0_;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = self->priv->_marked;
	result = _tmp0_;
	return result;
}

static void
contacts_contact_selection_model_set_marked (ContactsContactSelectionModel* self,
                                             GtkMultiSelection* value)
{
	GtkMultiSelection* old_value;
	g_return_if_fail (self != NULL);
	old_value = contacts_contact_selection_model_get_marked (self);
	if (old_value != value) {
		GtkMultiSelection* _tmp0_;
		_tmp0_ = _g_object_ref0 (value);
		_g_object_unref0 (self->priv->_marked);
		self->priv->_marked = _tmp0_;
		g_object_notify_by_pspec ((GObject *) self, contacts_contact_selection_model_properties[CONTACTS_CONTACT_SELECTION_MODEL_MARKED_PROPERTY]);
	}
}

static void
_contacts_contact_selection_model_on_base_model_items_changed_g_list_model_items_changed (GListModel* _sender,
                                                                                          guint position,
                                                                                          guint removed,
                                                                                          guint added,
                                                                                          gpointer self)
{
	contacts_contact_selection_model_on_base_model_items_changed ((ContactsContactSelectionModel*) self, _sender, position, removed, added);
}

static void
_contacts_contact_selection_model_on_selected_selection_changed_gtk_selection_model_selection_changed (GtkSelectionModel* _sender,
                                                                                                       guint position,
                                                                                                       guint n_items,
                                                                                                       gpointer self)
{
	contacts_contact_selection_model_on_selected_selection_changed ((ContactsContactSelectionModel*) self, _sender, position, n_items);
}

static void
_contacts_contact_selection_model_on_marked_selection_changed_gtk_selection_model_selection_changed (GtkSelectionModel* _sender,
                                                                                                     guint position,
                                                                                                     guint n_items,
                                                                                                     gpointer self)
{
	contacts_contact_selection_model_on_marked_selection_changed ((ContactsContactSelectionModel*) self, _sender, position, n_items);
}

static GObject *
contacts_contact_selection_model_constructor (GType type,
                                              guint n_construct_properties,
                                              GObjectConstructParam * construct_properties)
{
	GObject * obj;
	GObjectClass * parent_class;
	ContactsContactSelectionModel * self;
	GListModel* _tmp0_;
	GListModel* _tmp1_;
	GListModel* _tmp2_;
	GtkSingleSelection* _tmp3_;
	GtkSingleSelection* _tmp4_;
	GtkSingleSelection* _tmp5_;
	GtkSingleSelection* _tmp6_;
	GtkSingleSelection* _tmp7_;
	GListModel* _tmp8_;
	GListModel* _tmp9_;
	GtkMultiSelection* _tmp10_;
	GtkMultiSelection* _tmp11_;
	GtkMultiSelection* _tmp12_;
	parent_class = G_OBJECT_CLASS (contacts_contact_selection_model_parent_class);
	obj = parent_class->constructor (type, n_construct_properties, construct_properties);
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, CONTACTS_TYPE_CONTACT_SELECTION_MODEL, ContactsContactSelectionModel);
	_tmp0_ = self->priv->_base_model;
	g_signal_connect_object (_tmp0_, "items-changed", (GCallback) _contacts_contact_selection_model_on_base_model_items_changed_g_list_model_items_changed, self, 0);
	_tmp1_ = self->priv->_base_model;
	_tmp2_ = _g_object_ref0 (_tmp1_);
	_tmp3_ = gtk_single_selection_new (_tmp2_);
	_tmp4_ = _tmp3_;
	contacts_contact_selection_model_set_selected (self, _tmp4_);
	_g_object_unref0 (_tmp4_);
	_tmp5_ = self->priv->_selected;
	gtk_single_selection_set_can_unselect (_tmp5_, TRUE);
	_tmp6_ = self->priv->_selected;
	gtk_single_selection_set_autoselect (_tmp6_, FALSE);
	_tmp7_ = self->priv->_selected;
	g_signal_connect_object ((GtkSelectionModel*) _tmp7_, "selection-changed", (GCallback) _contacts_contact_selection_model_on_selected_selection_changed_gtk_selection_model_selection_changed, self, 0);
	_tmp8_ = self->priv->_base_model;
	_tmp9_ = _g_object_ref0 (_tmp8_);
	_tmp10_ = gtk_multi_selection_new (_tmp9_);
	_tmp11_ = _tmp10_;
	contacts_contact_selection_model_set_marked (self, _tmp11_);
	_g_object_unref0 (_tmp11_);
	_tmp12_ = self->priv->_marked;
	g_signal_connect_object ((GtkSelectionModel*) _tmp12_, "selection-changed", (GCallback) _contacts_contact_selection_model_on_marked_selection_changed_gtk_selection_model_selection_changed, self, 0);
	return obj;
}

static void
contacts_contact_selection_model_class_init (ContactsContactSelectionModelClass * klass,
                                             gpointer klass_data)
{
	contacts_contact_selection_model_parent_class = g_type_class_peek_parent (klass);
	g_type_class_adjust_private_offset (klass, &ContactsContactSelectionModel_private_offset);
	G_OBJECT_CLASS (klass)->get_property = _vala_contacts_contact_selection_model_get_property;
	G_OBJECT_CLASS (klass)->set_property = _vala_contacts_contact_selection_model_set_property;
	G_OBJECT_CLASS (klass)->constructor = contacts_contact_selection_model_constructor;
	G_OBJECT_CLASS (klass)->finalize = contacts_contact_selection_model_finalize;
	g_object_class_install_property (G_OBJECT_CLASS (klass), CONTACTS_CONTACT_SELECTION_MODEL_STATE_PROPERTY, contacts_contact_selection_model_properties[CONTACTS_CONTACT_SELECTION_MODEL_STATE_PROPERTY] = g_param_spec_enum ("state", "state", "state", CONTACTS_TYPE_UI_STATE, 0, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE | G_PARAM_WRITABLE));
	g_object_class_install_property (G_OBJECT_CLASS (klass), CONTACTS_CONTACT_SELECTION_MODEL_BASE_MODEL_PROPERTY, contacts_contact_selection_model_properties[CONTACTS_CONTACT_SELECTION_MODEL_BASE_MODEL_PROPERTY] = g_param_spec_object ("base-model", "base-model", "base-model", g_list_model_get_type (), G_PARAM_STATIC_STRINGS | G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT));
	g_object_class_install_property (G_OBJECT_CLASS (klass), CONTACTS_CONTACT_SELECTION_MODEL_SELECTED_PROPERTY, contacts_contact_selection_model_properties[CONTACTS_CONTACT_SELECTION_MODEL_SELECTED_PROPERTY] = g_param_spec_object ("selected", "selected", "selected", gtk_single_selection_get_type (), G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
	g_object_class_install_property (G_OBJECT_CLASS (klass), CONTACTS_CONTACT_SELECTION_MODEL_MARKED_PROPERTY, contacts_contact_selection_model_properties[CONTACTS_CONTACT_SELECTION_MODEL_MARKED_PROPERTY] = g_param_spec_object ("marked", "marked", "marked", gtk_multi_selection_get_type (), G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
}

static void
contacts_contact_selection_model_g_list_model_interface_init (GListModelInterface * iface,
                                                              gpointer iface_data)
{
	contacts_contact_selection_model_g_list_model_parent_iface = g_type_interface_peek_parent (iface);
	iface->get_item = (GObject* (*) (GListModel*, guint)) contacts_contact_selection_model_real_get_item;
	iface->get_n_items = (guint (*) (GListModel*)) contacts_contact_selection_model_real_get_n_items;
	iface->get_item_type = (GType (*) (GListModel*)) contacts_contact_selection_model_real_get_item_type;
}

static void
contacts_contact_selection_model_gtk_selection_model_interface_init (GtkSelectionModelInterface * iface,
                                                                     gpointer iface_data)
{
	contacts_contact_selection_model_gtk_selection_model_parent_iface = g_type_interface_peek_parent (iface);
	iface->get_selection_in_range = (GtkBitset* (*) (GtkSelectionModel*, guint, guint)) contacts_contact_selection_model_real_get_selection_in_range;
	iface->is_selected = (gboolean (*) (GtkSelectionModel*, guint)) contacts_contact_selection_model_real_is_selected;
	iface->select_all = (gboolean (*) (GtkSelectionModel*)) contacts_contact_selection_model_real_select_all;
	iface->select_item = (gboolean (*) (GtkSelectionModel*, guint, gboolean)) contacts_contact_selection_model_real_select_item;
	iface->select_range = (gboolean (*) (GtkSelectionModel*, guint, guint, gboolean)) contacts_contact_selection_model_real_select_range;
	iface->set_selection = (gboolean (*) (GtkSelectionModel*, GtkBitset*, GtkBitset*)) contacts_contact_selection_model_real_set_selection;
	iface->unselect_all = (gboolean (*) (GtkSelectionModel*)) contacts_contact_selection_model_real_unselect_all;
	iface->unselect_item = (gboolean (*) (GtkSelectionModel*, guint)) contacts_contact_selection_model_real_unselect_item;
	iface->unselect_range = (gboolean (*) (GtkSelectionModel*, guint, guint)) contacts_contact_selection_model_real_unselect_range;
}

static void
contacts_contact_selection_model_gtk_section_model_interface_init (GtkSectionModelInterface * iface,
                                                                   gpointer iface_data)
{
	contacts_contact_selection_model_gtk_section_model_parent_iface = g_type_interface_peek_parent (iface);
	iface->get_section = (void (*) (GtkSectionModel*, guint, guint*, guint*)) contacts_contact_selection_model_real_get_section;
}

static void
contacts_contact_selection_model_instance_init (ContactsContactSelectionModel * self,
                                                gpointer klass)
{
	self->priv = contacts_contact_selection_model_get_instance_private (self);
}

static void
contacts_contact_selection_model_finalize (GObject * obj)
{
	ContactsContactSelectionModel * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, CONTACTS_TYPE_CONTACT_SELECTION_MODEL, ContactsContactSelectionModel);
	_g_object_unref0 (self->priv->_base_model);
	_g_object_unref0 (self->priv->_selected);
	_g_object_unref0 (self->priv->_marked);
	G_OBJECT_CLASS (contacts_contact_selection_model_parent_class)->finalize (obj);
}

/**
 * The ContactListSelectionModel is a custom selection model that basically
 * combines 2 selection models:
 * - the default single selection model
 * - a multi-selection model, for when we go into "selection mode"
 *
 * Providing a custom selection which delegates everything rather than using 2
 * models separately has some advantages:
 * - Switching the model for a GtkListView means that it will reload the whole
 * model, leading to unexpected jumps and performance issues
 * - The selection logic for "selection mode" is slighty different than the one
 * that GtkMultiSelection implements, so we can try to work around that here
 * in select_item() and select_range()
 *
 * If you still want access to a specific selection, you can still fetch them
 * as they are public properties of the instance.
 */
 G_GNUC_NO_INLINE static GType
contacts_contact_selection_model_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (ContactsContactSelectionModelClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) contacts_contact_selection_model_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (ContactsContactSelectionModel), 0, (GInstanceInitFunc) contacts_contact_selection_model_instance_init, NULL };
	static const GInterfaceInfo g_list_model_info = { (GInterfaceInitFunc) contacts_contact_selection_model_g_list_model_interface_init, (GInterfaceFinalizeFunc) NULL, NULL};
	static const GInterfaceInfo gtk_selection_model_info = { (GInterfaceInitFunc) contacts_contact_selection_model_gtk_selection_model_interface_init, (GInterfaceFinalizeFunc) NULL, NULL};
	static const GInterfaceInfo gtk_section_model_info = { (GInterfaceInitFunc) contacts_contact_selection_model_gtk_section_model_interface_init, (GInterfaceFinalizeFunc) NULL, NULL};
	GType contacts_contact_selection_model_type_id;
	contacts_contact_selection_model_type_id = g_type_register_static (G_TYPE_OBJECT, "ContactsContactSelectionModel", &g_define_type_info, 0);
	g_type_add_interface_static (contacts_contact_selection_model_type_id, g_list_model_get_type (), &g_list_model_info);
	g_type_add_interface_static (contacts_contact_selection_model_type_id, gtk_selection_model_get_type (), &gtk_selection_model_info);
	g_type_add_interface_static (contacts_contact_selection_model_type_id, gtk_section_model_get_type (), &gtk_section_model_info);
	ContactsContactSelectionModel_private_offset = g_type_add_instance_private (contacts_contact_selection_model_type_id, sizeof (ContactsContactSelectionModelPrivate));
	return contacts_contact_selection_model_type_id;
}

GType
contacts_contact_selection_model_get_type (void)
{
	static volatile gsize contacts_contact_selection_model_type_id__once = 0;
	if (g_once_init_enter (&contacts_contact_selection_model_type_id__once)) {
		GType contacts_contact_selection_model_type_id;
		contacts_contact_selection_model_type_id = contacts_contact_selection_model_get_type_once ();
		g_once_init_leave (&contacts_contact_selection_model_type_id__once, contacts_contact_selection_model_type_id);
	}
	return contacts_contact_selection_model_type_id__once;
}

static void
_vala_contacts_contact_selection_model_get_property (GObject * object,
                                                     guint property_id,
                                                     GValue * value,
                                                     GParamSpec * pspec)
{
	ContactsContactSelectionModel * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (object, CONTACTS_TYPE_CONTACT_SELECTION_MODEL, ContactsContactSelectionModel);
	switch (property_id) {
		case CONTACTS_CONTACT_SELECTION_MODEL_STATE_PROPERTY:
		g_value_set_enum (value, contacts_contact_selection_model_get_state (self));
		break;
		case CONTACTS_CONTACT_SELECTION_MODEL_BASE_MODEL_PROPERTY:
		g_value_set_object (value, contacts_contact_selection_model_get_base_model (self));
		break;
		case CONTACTS_CONTACT_SELECTION_MODEL_SELECTED_PROPERTY:
		g_value_set_object (value, contacts_contact_selection_model_get_selected (self));
		break;
		case CONTACTS_CONTACT_SELECTION_MODEL_MARKED_PROPERTY:
		g_value_set_object (value, contacts_contact_selection_model_get_marked (self));
		break;
		default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
	}
}

static void
_vala_contacts_contact_selection_model_set_property (GObject * object,
                                                     guint property_id,
                                                     const GValue * value,
                                                     GParamSpec * pspec)
{
	ContactsContactSelectionModel * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (object, CONTACTS_TYPE_CONTACT_SELECTION_MODEL, ContactsContactSelectionModel);
	switch (property_id) {
		case CONTACTS_CONTACT_SELECTION_MODEL_STATE_PROPERTY:
		contacts_contact_selection_model_set_state (self, g_value_get_enum (value));
		break;
		case CONTACTS_CONTACT_SELECTION_MODEL_BASE_MODEL_PROPERTY:
		contacts_contact_selection_model_set_base_model (self, g_value_get_object (value));
		break;
		case CONTACTS_CONTACT_SELECTION_MODEL_SELECTED_PROPERTY:
		contacts_contact_selection_model_set_selected (self, g_value_get_object (value));
		break;
		case CONTACTS_CONTACT_SELECTION_MODEL_MARKED_PROPERTY:
		contacts_contact_selection_model_set_marked (self, g_value_get_object (value));
		break;
		default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
	}
}

