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

/*
 * This file is part of budgie-desktop
 *
 * Copyright © 2018-2022 Budgie Desktop Developers
 *
 * 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.
 */

#include "abomination.h"
#include <stdlib.h>
#include <string.h>
#include <glib.h>
#include <libwnck/libwnck.h>
#include <glib-object.h>
#include <gdk-pixbuf/gdk-pixbuf.h>

enum  {
	BUDGIE_ABOMINATION_APP_GROUP_0_PROPERTY,
	BUDGIE_ABOMINATION_APP_GROUP_NUM_PROPERTIES
};
static GParamSpec* budgie_abomination_app_group_properties[BUDGIE_ABOMINATION_APP_GROUP_NUM_PROPERTIES];
#define _g_free0(var) (var = (g_free (var), NULL))
#define _g_hash_table_unref0(var) ((var == NULL) ? NULL : (var = (g_hash_table_unref (var), NULL)))
#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))
typedef struct _Block5Data Block5Data;
enum  {
	BUDGIE_ABOMINATION_APP_GROUP_ICON_CHANGED_SIGNAL,
	BUDGIE_ABOMINATION_APP_GROUP_ADDED_WINDOW_SIGNAL,
	BUDGIE_ABOMINATION_APP_GROUP_REMOVED_WINDOW_SIGNAL,
	BUDGIE_ABOMINATION_APP_GROUP_RENAMED_GROUP_SIGNAL,
	BUDGIE_ABOMINATION_APP_GROUP_NUM_SIGNALS
};
static guint budgie_abomination_app_group_signals[BUDGIE_ABOMINATION_APP_GROUP_NUM_SIGNALS] = {0};

struct _BudgieAbominationAppGroupPrivate {
	gchar* name;
	GHashTable* windows;
};

struct _Block5Data {
	int _ref_count_;
	BudgieAbominationAppGroup* self;
	WnckWindow* window;
};

static gint BudgieAbominationAppGroup_private_offset;
static gpointer budgie_abomination_app_group_parent_class = NULL;

VALA_EXTERN BudgieAbominationAppGroup* budgie_abomination_app_group_new (WnckWindow* window);
VALA_EXTERN BudgieAbominationAppGroup* budgie_abomination_app_group_construct (GType object_type,
                                                                   WnckWindow* window);
static void _g_free0_ (gpointer var);
static void _g_object_unref0_ (gpointer var);
VALA_EXTERN gchar* budgie_abomination_get_group_name (WnckWindow* window);
static void __lambda6_ (BudgieAbominationAppGroup* self);
static void ___lambda6__wnck_window_icon_changed (WnckWindow* _sender,
                                           gpointer self);
static Block5Data* block5_data_ref (Block5Data* _data5_);
static void block5_data_unref (void * _userdata_);
static gulong* _ulong_dup (gulong* self);
static void __lambda4_ (Block5Data* _data5_);
static void budgie_abomination_app_group_update_group (BudgieAbominationAppGroup* self,
                                                WnckWindow* window);
static void ___lambda4__wnck_window_name_changed (WnckWindow* _sender,
                                           gpointer self);
static void __lambda5_ (Block5Data* _data5_);
static void ___lambda5__wnck_window_class_changed (WnckWindow* _sender,
                                            gpointer self);
static void g_cclosure_user_marshal_VOID__STRING_STRING (GClosure * closure,
                                                  GValue * return_value,
                                                  guint n_param_values,
                                                  const GValue * param_values,
                                                  gpointer invocation_hint,
                                                  gpointer marshal_data);
static void budgie_abomination_app_group_finalize (GObject * obj);
static GType budgie_abomination_app_group_get_type_once (void);

static inline gpointer
budgie_abomination_app_group_get_instance_private (BudgieAbominationAppGroup* self)
{
	return G_STRUCT_MEMBER_P (self, BudgieAbominationAppGroup_private_offset);
}

/**
 * Create a new group from a window instance
 */
static void
_g_free0_ (gpointer var)
{
	(var == NULL) ? NULL : (var = (g_free (var), NULL));
}

static void
_g_object_unref0_ (gpointer var)
{
	(var == NULL) ? NULL : (var = (g_object_unref (var), NULL));
}

static void
__lambda6_ (BudgieAbominationAppGroup* self)
{
	g_signal_emit (self, budgie_abomination_app_group_signals[BUDGIE_ABOMINATION_APP_GROUP_ICON_CHANGED_SIGNAL], 0);
}

static void
___lambda6__wnck_window_icon_changed (WnckWindow* _sender,
                                      gpointer self)
{
	__lambda6_ ((BudgieAbominationAppGroup*) self);
}

BudgieAbominationAppGroup*
budgie_abomination_app_group_construct (GType object_type,
                                        WnckWindow* window)
{
	BudgieAbominationAppGroup * self = NULL;
	GHashFunc _tmp0_;
	GEqualFunc _tmp1_;
	GHashTable* _tmp2_;
	gchar* _tmp3_;
	const gchar* _tmp4_;
	g_return_val_if_fail (window != NULL, NULL);
	self = (BudgieAbominationAppGroup*) g_object_new (object_type, NULL);
	_tmp0_ = g_int_hash;
	_tmp1_ = g_int_equal;
	_tmp2_ = g_hash_table_new_full (_tmp0_, _tmp1_, _g_free0_, _g_object_unref0_);
	_g_hash_table_unref0 (self->priv->windows);
	self->priv->windows = _tmp2_;
	_tmp3_ = budgie_abomination_get_group_name (window);
	_g_free0 (self->priv->name);
	self->priv->name = _tmp3_;
	budgie_abomination_app_group_add_window (self, window);
	_tmp4_ = self->priv->name;
	g_debug ("AppGroup.vala:38: Created group: %s", _tmp4_);
	g_signal_connect_object (window, "icon-changed", (GCallback) ___lambda6__wnck_window_icon_changed, self, 0);
	return self;
}

BudgieAbominationAppGroup*
budgie_abomination_app_group_new (WnckWindow* window)
{
	return budgie_abomination_app_group_construct (BUDGIE_ABOMINATION_TYPE_APP_GROUP, window);
}

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

static Block5Data*
block5_data_ref (Block5Data* _data5_)
{
	g_atomic_int_inc (&_data5_->_ref_count_);
	return _data5_;
}

static void
block5_data_unref (void * _userdata_)
{
	Block5Data* _data5_;
	_data5_ = (Block5Data*) _userdata_;
	if (g_atomic_int_dec_and_test (&_data5_->_ref_count_)) {
		BudgieAbominationAppGroup* self;
		self = _data5_->self;
		_g_object_unref0 (_data5_->window);
		_g_object_unref0 (self);
		g_slice_free (Block5Data, _data5_);
	}
}

static gulong*
_ulong_dup (gulong* self)
{
	gulong* dup;
	dup = g_new0 (gulong, 1);
	memcpy (dup, self, sizeof (gulong));
	return dup;
}

static gpointer
__ulong_dup0 (gpointer self)
{
	return self ? _ulong_dup (self) : NULL;
}

static void
__lambda4_ (Block5Data* _data5_)
{
	BudgieAbominationAppGroup* self;
	self = _data5_->self;
	budgie_abomination_app_group_update_group (self, _data5_->window);
}

static void
___lambda4__wnck_window_name_changed (WnckWindow* _sender,
                                      gpointer self)
{
	__lambda4_ (self);
}

static void
__lambda5_ (Block5Data* _data5_)
{
	BudgieAbominationAppGroup* self;
	self = _data5_->self;
	budgie_abomination_app_group_update_group (self, _data5_->window);
}

static void
___lambda5__wnck_window_class_changed (WnckWindow* _sender,
                                       gpointer self)
{
	__lambda5_ (self);
}

void
budgie_abomination_app_group_add_window (BudgieAbominationAppGroup* self,
                                         WnckWindow* window)
{
	Block5Data* _data5_;
	WnckWindow* _tmp0_;
	GHashTable* _tmp1_;
	gulong _tmp2_;
	GHashTable* _tmp3_;
	gulong _tmp4_;
	gulong* _tmp5_;
	WnckWindow* _tmp6_;
	GList* _tmp7_;
	GList* _tmp8_;
	const gchar* _tmp9_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (window != NULL);
	_data5_ = g_slice_new0 (Block5Data);
	_data5_->_ref_count_ = 1;
	_data5_->self = g_object_ref (self);
	_tmp0_ = _g_object_ref0 (window);
	_g_object_unref0 (_data5_->window);
	_data5_->window = _tmp0_;
	_tmp1_ = self->priv->windows;
	_tmp2_ = wnck_window_get_xid (_data5_->window);
	if (g_hash_table_contains (_tmp1_, &_tmp2_)) {
		block5_data_unref (_data5_);
		_data5_ = NULL;
		return;
	}
	_tmp3_ = self->priv->windows;
	_tmp4_ = wnck_window_get_xid (_data5_->window);
	_tmp5_ = __ulong_dup0 (&_tmp4_);
	_tmp6_ = _g_object_ref0 (_data5_->window);
	g_hash_table_insert (_tmp3_, _tmp5_, _tmp6_);
	g_signal_connect_data (_data5_->window, "name-changed", (GCallback) ___lambda4__wnck_window_name_changed, block5_data_ref (_data5_), (GClosureNotify) block5_data_unref, G_CONNECT_AFTER);
	g_signal_connect_data (_data5_->window, "class-changed", (GCallback) ___lambda5__wnck_window_class_changed, block5_data_ref (_data5_), (GClosureNotify) block5_data_unref, G_CONNECT_AFTER);
	_tmp7_ = budgie_abomination_app_group_get_windows (self);
	_tmp8_ = _tmp7_;
	_tmp9_ = self->priv->name;
	g_debug ("AppGroup.vala:56: Number of window: %u (group: %s)", g_list_length (_tmp8_), _tmp9_);
	(_tmp8_ == NULL) ? NULL : (_tmp8_ = (g_list_free (_tmp8_), NULL));
	g_signal_emit (self, budgie_abomination_app_group_signals[BUDGIE_ABOMINATION_APP_GROUP_ADDED_WINDOW_SIGNAL], 0, _data5_->window);
	block5_data_unref (_data5_);
	_data5_ = NULL;
}

void
budgie_abomination_app_group_remove_window (BudgieAbominationAppGroup* self,
                                            WnckWindow* window)
{
	GHashTable* _tmp0_;
	gulong _tmp1_;
	GHashTable* _tmp2_;
	gulong _tmp3_;
	GList* _tmp4_;
	GList* _tmp5_;
	const gchar* _tmp6_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (window != NULL);
	_tmp0_ = self->priv->windows;
	_tmp1_ = wnck_window_get_xid (window);
	if (!g_hash_table_contains (_tmp0_, &_tmp1_)) {
		return;
	}
	_tmp2_ = self->priv->windows;
	_tmp3_ = wnck_window_get_xid (window);
	g_hash_table_remove (_tmp2_, &_tmp3_);
	_tmp4_ = budgie_abomination_app_group_get_windows (self);
	_tmp5_ = _tmp4_;
	_tmp6_ = self->priv->name;
	g_debug ("AppGroup.vala:68: Number of window: %u (group: %s)", g_list_length (_tmp5_), _tmp6_);
	(_tmp5_ == NULL) ? NULL : (_tmp5_ = (g_list_free (_tmp5_), NULL));
	g_signal_emit (self, budgie_abomination_app_group_signals[BUDGIE_ABOMINATION_APP_GROUP_REMOVED_WINDOW_SIGNAL], 0, window);
}

GList*
budgie_abomination_app_group_get_windows (BudgieAbominationAppGroup* self)
{
	GHashTable* _tmp0_;
	GList* _tmp1_;
	GList* result;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = self->priv->windows;
	_tmp1_ = g_hash_table_get_values (_tmp0_);
	result = _tmp1_;
	return result;
}

gchar*
budgie_abomination_app_group_get_name (BudgieAbominationAppGroup* self)
{
	const gchar* _tmp0_;
	gchar* _tmp1_;
	gchar* result;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = self->priv->name;
	_tmp1_ = g_strdup (_tmp0_);
	result = _tmp1_;
	return result;
}

GdkPixbuf*
budgie_abomination_app_group_get_icon (BudgieAbominationAppGroup* self)
{
	gboolean _tmp0_ = FALSE;
	GList* _tmp1_;
	GList* _tmp2_;
	gboolean _tmp3_;
	GList* _tmp8_;
	GList* _tmp9_;
	gconstpointer _tmp10_;
	WnckClassGroup* _tmp11_;
	GdkPixbuf* _tmp12_;
	GdkPixbuf* _tmp13_;
	GdkPixbuf* _tmp14_;
	GdkPixbuf* result;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp1_ = budgie_abomination_app_group_get_windows (self);
	_tmp2_ = _tmp1_;
	_tmp3_ = g_list_length (_tmp2_) == ((guint) 0);
	(_tmp2_ == NULL) ? NULL : (_tmp2_ = (g_list_free (_tmp2_), NULL));
	if (_tmp3_) {
		_tmp0_ = TRUE;
	} else {
		GList* _tmp4_;
		GList* _tmp5_;
		gconstpointer _tmp6_;
		WnckClassGroup* _tmp7_;
		_tmp4_ = budgie_abomination_app_group_get_windows (self);
		_tmp5_ = _tmp4_;
		_tmp6_ = g_list_nth_data (_tmp5_, (guint) 0);
		_tmp7_ = wnck_window_get_class_group ((WnckWindow*) _tmp6_);
		_tmp0_ = _tmp7_ == NULL;
		(_tmp5_ == NULL) ? NULL : (_tmp5_ = (g_list_free (_tmp5_), NULL));
	}
	if (_tmp0_) {
		result = NULL;
		return result;
	}
	_tmp8_ = budgie_abomination_app_group_get_windows (self);
	_tmp9_ = _tmp8_;
	_tmp10_ = g_list_nth_data (_tmp9_, (guint) 0);
	_tmp11_ = wnck_window_get_class_group ((WnckWindow*) _tmp10_);
	_tmp12_ = wnck_class_group_get_icon (_tmp11_);
	_tmp13_ = _g_object_ref0 (_tmp12_);
	_tmp14_ = _tmp13_;
	(_tmp9_ == NULL) ? NULL : (_tmp9_ = (g_list_free (_tmp9_), NULL));
	result = _tmp14_;
	return result;
}

static void
budgie_abomination_app_group_update_group (BudgieAbominationAppGroup* self,
                                           WnckWindow* window)
{
	gchar* old_name = NULL;
	const gchar* _tmp0_;
	gchar* _tmp1_;
	gchar* _tmp2_;
	const gchar* _tmp3_;
	const gchar* _tmp4_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (window != NULL);
	if (window == NULL) {
		return;
	}
	_tmp0_ = self->priv->name;
	_tmp1_ = g_strdup (_tmp0_);
	old_name = _tmp1_;
	_tmp2_ = budgie_abomination_get_group_name (window);
	_g_free0 (self->priv->name);
	self->priv->name = _tmp2_;
	_tmp3_ = self->priv->name;
	_tmp4_ = old_name;
	if (g_strcmp0 (_tmp3_, _tmp4_) != 0) {
		const gchar* _tmp5_;
		const gchar* _tmp6_;
		const gchar* _tmp7_;
		const gchar* _tmp8_;
		_tmp5_ = old_name;
		_tmp6_ = self->priv->name;
		g_debug ("AppGroup.vala:97: Renamed group %s into %s", _tmp5_, _tmp6_);
		_tmp7_ = old_name;
		_tmp8_ = self->priv->name;
		g_signal_emit (self, budgie_abomination_app_group_signals[BUDGIE_ABOMINATION_APP_GROUP_RENAMED_GROUP_SIGNAL], 0, _tmp7_, _tmp8_);
	}
	_g_free0 (old_name);
}

static void
g_cclosure_user_marshal_VOID__STRING_STRING (GClosure * closure,
                                             GValue * return_value,
                                             guint n_param_values,
                                             const GValue * param_values,
                                             gpointer invocation_hint,
                                             gpointer marshal_data)
{
	typedef void (*GMarshalFunc_VOID__STRING_STRING) (gpointer data1, const char* arg_1, const char* arg_2, gpointer data2);
	register GMarshalFunc_VOID__STRING_STRING callback;
	register GCClosure * cc;
	register gpointer data1;
	register gpointer data2;
	cc = (GCClosure *) closure;
	g_return_if_fail (n_param_values == 3);
	if (G_CCLOSURE_SWAP_DATA (closure)) {
		data1 = closure->data;
		data2 = param_values->data[0].v_pointer;
	} else {
		data1 = param_values->data[0].v_pointer;
		data2 = closure->data;
	}
	callback = (GMarshalFunc_VOID__STRING_STRING) (marshal_data ? marshal_data : cc->callback);
	callback (data1, g_value_get_string (param_values + 1), g_value_get_string (param_values + 2), data2);
}

static void
budgie_abomination_app_group_class_init (BudgieAbominationAppGroupClass * klass,
                                         gpointer klass_data)
{
	budgie_abomination_app_group_parent_class = g_type_class_peek_parent (klass);
	g_type_class_adjust_private_offset (klass, &BudgieAbominationAppGroup_private_offset);
	G_OBJECT_CLASS (klass)->finalize = budgie_abomination_app_group_finalize;
	/**
	 * Signals
	 */
	budgie_abomination_app_group_signals[BUDGIE_ABOMINATION_APP_GROUP_ICON_CHANGED_SIGNAL] = g_signal_new ("icon-changed", BUDGIE_ABOMINATION_TYPE_APP_GROUP, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
	budgie_abomination_app_group_signals[BUDGIE_ABOMINATION_APP_GROUP_ADDED_WINDOW_SIGNAL] = g_signal_new ("added-window", BUDGIE_ABOMINATION_TYPE_APP_GROUP, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__OBJECT, G_TYPE_NONE, 1, wnck_window_get_type ());
	budgie_abomination_app_group_signals[BUDGIE_ABOMINATION_APP_GROUP_REMOVED_WINDOW_SIGNAL] = g_signal_new ("removed-window", BUDGIE_ABOMINATION_TYPE_APP_GROUP, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__OBJECT, G_TYPE_NONE, 1, wnck_window_get_type ());
	budgie_abomination_app_group_signals[BUDGIE_ABOMINATION_APP_GROUP_RENAMED_GROUP_SIGNAL] = g_signal_new ("renamed-group", BUDGIE_ABOMINATION_TYPE_APP_GROUP, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_user_marshal_VOID__STRING_STRING, G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_STRING);
}

static void
budgie_abomination_app_group_instance_init (BudgieAbominationAppGroup * self,
                                            gpointer klass)
{
	self->priv = budgie_abomination_app_group_get_instance_private (self);
}

static void
budgie_abomination_app_group_finalize (GObject * obj)
{
	BudgieAbominationAppGroup * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, BUDGIE_ABOMINATION_TYPE_APP_GROUP, BudgieAbominationAppGroup);
	_g_free0 (self->priv->name);
	_g_hash_table_unref0 (self->priv->windows);
	G_OBJECT_CLASS (budgie_abomination_app_group_parent_class)->finalize (obj);
}

/**
 * A replacement for Wnck.ClassGroup as Wnck.ClassGroup relies on the sometime
 * missing, sometime incoherent WM_CLASS property to group windows together.
 */
static GType
budgie_abomination_app_group_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (BudgieAbominationAppGroupClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) budgie_abomination_app_group_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (BudgieAbominationAppGroup), 0, (GInstanceInitFunc) budgie_abomination_app_group_instance_init, NULL };
	GType budgie_abomination_app_group_type_id;
	budgie_abomination_app_group_type_id = g_type_register_static (G_TYPE_OBJECT, "BudgieAbominationAppGroup", &g_define_type_info, 0);
	BudgieAbominationAppGroup_private_offset = g_type_add_instance_private (budgie_abomination_app_group_type_id, sizeof (BudgieAbominationAppGroupPrivate));
	return budgie_abomination_app_group_type_id;
}

GType
budgie_abomination_app_group_get_type (void)
{
	static volatile gsize budgie_abomination_app_group_type_id__once = 0;
	if (g_once_init_enter (&budgie_abomination_app_group_type_id__once)) {
		GType budgie_abomination_app_group_type_id;
		budgie_abomination_app_group_type_id = budgie_abomination_app_group_get_type_once ();
		g_once_init_leave (&budgie_abomination_app_group_type_id__once, budgie_abomination_app_group_type_id);
	}
	return budgie_abomination_app_group_type_id__once;
}

