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

/*
 * This file is part of budgie-desktop
 *
 * Copyright © 2015-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 "raven.h"
#include <glib.h>
#include <stdlib.h>
#include <string.h>
#include <gtk/gtk.h>
#include <glib-object.h>
#include <gio/gio.h>

enum  {
	MPRIS_WIDGET_0_PROPERTY,
	MPRIS_WIDGET_NUM_PROPERTIES
};
static GParamSpec* mpris_widget_properties[MPRIS_WIDGET_NUM_PROPERTIES];
#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))
#define _g_hash_table_unref0(var) ((var == NULL) ? NULL : (var = (g_hash_table_unref (var), NULL)))
#define _g_free0(var) (var = (g_free (var), NULL))
typedef struct _Block2Data Block2Data;
#define _g_error_free0(var) ((var == NULL) ? NULL : (var = (g_error_free (var), NULL)))
typedef struct _MprisWidgetSetupDbusData MprisWidgetSetupDbusData;

struct _MprisWidgetPrivate {
	DBusImpl* impl;
	GHashTable* ifaces;
	gint our_width;
};

struct _Block2Data {
	int _ref_count_;
	MprisWidget* self;
	gchar* n;
};

struct _MprisWidgetSetupDbusData {
	int _state_;
	GObject* _source_object_;
	GAsyncResult* _res_;
	GTask* _async_result;
	MprisWidget* self;
	DBusImpl* _tmp0_;
	DBusImpl* _tmp1_;
	DBusImpl* _tmp2_;
	gchar** names;
	DBusImpl* _tmp3_;
	gint _tmp4_;
	gchar** _tmp5_;
	gint names_length1;
	gint _names_size_;
	gchar** _tmp6_;
	gint _tmp6__length1;
	gchar** name_collection;
	gint name_collection_length1;
	gint _name_collection_size_;
	gint name_it;
	gchar* _tmp7_;
	gchar* name;
	const gchar* _tmp8_;
	MprisClient* iface;
	const gchar* _tmp9_;
	MprisClient* _tmp10_;
	MprisClient* _tmp11_;
	const gchar* _tmp12_;
	MprisClient* _tmp13_;
	DBusImpl* _tmp14_;
	GError* e;
	GError* _tmp15_;
	const gchar* _tmp16_;
	GError* _inner_error0_;
};

static gint MprisWidget_private_offset;
static gpointer mpris_widget_parent_class = NULL;

static void _g_free0_ (gpointer var);
static void _g_object_unref0_ (gpointer var);
static void mpris_widget_on_size_allocate (MprisWidget* self);
static void _mpris_widget_on_size_allocate_gtk_widget_size_allocate (GtkWidget* _sender,
                                                              GtkAllocation* allocation,
                                                              gpointer self);
static gboolean mpris_widget_notify_clients_on_width_change (MprisWidget* self);
static gboolean _mpris_widget_notify_clients_on_width_change_gsource_func (gpointer self);
static void mpris_widget_add_iface (MprisWidget* self,
                             const gchar* name,
                             MprisClient* iface);
static void mpris_widget_destroy_iface (MprisWidget* self,
                                 const gchar* name);
static void mpris_widget_on_name_owner_changed (MprisWidget* self,
                                         const gchar* n,
                                         const gchar* o,
                                         const gchar* ne);
static Block2Data* block2_data_ref (Block2Data* _data2_);
static void block2_data_unref (void * _userdata_);
static void ___lambda21_ (Block2Data* _data2_,
                   GObject* o,
                   GAsyncResult* r);
static void ____lambda21__gasync_ready_callback (GObject* source_object,
                                          GAsyncResult* res,
                                          gpointer self);
static gboolean ___lambda22_ (Block2Data* _data2_);
static gboolean ____lambda22__gsource_func (gpointer self);
static void mpris_widget_setup_dbus_data_free (gpointer _data);
static gboolean mpris_widget_setup_dbus_co (MprisWidgetSetupDbusData* _data_);
static void mpris_widget_setup_dbus_ready (GObject* source_object,
                                    GAsyncResult* _res_,
                                    gpointer _user_data_);
static void _mpris_widget_on_name_owner_changed_dbus_impl_name_owner_changed (DBusImpl* _sender,
                                                                       const gchar* name,
                                                                       const gchar* old_owner,
                                                                       const gchar* new_owner,
                                                                       gpointer self);
static void mpris_widget_finalize (GObject * obj);
static GType mpris_widget_get_type_once (void);
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
mpris_widget_get_instance_private (MprisWidget* self)
{
	return G_STRUCT_MEMBER_P (self, MprisWidget_private_offset);
}

static void
_g_free0_ (gpointer var)
{
	var = (g_free (var), NULL);
}

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

static void
_mpris_widget_on_size_allocate_gtk_widget_size_allocate (GtkWidget* _sender,
                                                         GtkAllocation* allocation,
                                                         gpointer self)
{
	mpris_widget_on_size_allocate ((MprisWidget*) self);
}

MprisWidget*
mpris_widget_construct (GType object_type)
{
	MprisWidget * self = NULL;
	GHashFunc _tmp0_;
	GEqualFunc _tmp1_;
	GHashTable* _tmp2_;
	self = (MprisWidget*) g_object_new (object_type, "orientation", GTK_ORIENTATION_VERTICAL, "spacing", 0, NULL);
	_tmp0_ = g_str_hash;
	_tmp1_ = g_str_equal;
	_tmp2_ = g_hash_table_new_full (_tmp0_, _tmp1_, _g_free0_, _g_object_unref0_);
	_g_hash_table_unref0 (self->priv->ifaces);
	self->priv->ifaces = _tmp2_;
	mpris_widget_setup_dbus (self, NULL, NULL);
	g_signal_connect_object ((GtkWidget*) self, "size-allocate", (GCallback) _mpris_widget_on_size_allocate_gtk_widget_size_allocate, self, 0);
	gtk_widget_show_all ((GtkWidget*) self);
	return self;
}

MprisWidget*
mpris_widget_new (void)
{
	return mpris_widget_construct (TYPE_MPRIS_WIDGET);
}

static gboolean
_mpris_widget_notify_clients_on_width_change_gsource_func (gpointer self)
{
	gboolean result;
	result = mpris_widget_notify_clients_on_width_change ((MprisWidget*) self);
	return result;
}

static void
mpris_widget_on_size_allocate (MprisWidget* self)
{
	gint w = 0;
	g_return_if_fail (self != NULL);
	w = gtk_widget_get_allocated_width ((GtkWidget*) self);
	if (w > self->priv->our_width) {
		self->priv->our_width = w;
		g_idle_add_full (G_PRIORITY_DEFAULT_IDLE, _mpris_widget_notify_clients_on_width_change_gsource_func, g_object_ref (self), g_object_unref);
	}
}

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

static gboolean
mpris_widget_notify_clients_on_width_change (MprisWidget* self)
{
	GHashTableIter iter = {0};
	GHashTable* _tmp0_;
	ClientWidget* widget = NULL;
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	_tmp0_ = self->priv->ifaces;
	g_hash_table_iter_init (&iter, _tmp0_);
	widget = NULL;
	while (TRUE) {
		gconstpointer _tmp1_ = NULL;
		gboolean _tmp2_;
		ClientWidget* _tmp3_;
		ClientWidget* _tmp4_;
		_tmp2_ = g_hash_table_iter_next (&iter, (gpointer*) NULL, (gpointer*) (&_tmp1_));
		_g_object_unref0 (widget);
		_tmp3_ = _g_object_ref0 (_tmp1_);
		widget = _tmp3_;
		if (!_tmp2_) {
			break;
		}
		_tmp4_ = widget;
		client_widget_update_width (_tmp4_, self->priv->our_width);
	}
	result = FALSE;
	_g_object_unref0 (widget);
	return result;
}

/**
 * Add an interface handler/widget to known list and UI
 *
 * @param name DBUS name (object path)
 * @param iface The constructed MprisClient instance
 */
static void
mpris_widget_add_iface (MprisWidget* self,
                        const gchar* name,
                        MprisClient* iface)
{
	ClientWidget* widg = NULL;
	ClientWidget* _tmp0_;
	GHashTable* _tmp1_;
	gchar* _tmp2_;
	ClientWidget* _tmp3_;
	GtkWidget* _tmp4_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (name != NULL);
	g_return_if_fail (iface != NULL);
	_tmp0_ = client_widget_new (iface, self->priv->our_width);
	g_object_ref_sink (_tmp0_);
	widg = _tmp0_;
	gtk_widget_show_all ((GtkWidget*) widg);
	gtk_box_pack_start ((GtkBox*) self, (GtkWidget*) widg, FALSE, FALSE, (guint) 0);
	_tmp1_ = self->priv->ifaces;
	_tmp2_ = g_strdup (name);
	_tmp3_ = _g_object_ref0 (widg);
	g_hash_table_insert (_tmp1_, _tmp2_, _tmp3_);
	gtk_widget_queue_draw ((GtkWidget*) self);
	_tmp4_ = gtk_widget_get_toplevel ((GtkWidget*) self);
	gtk_widget_queue_draw (_tmp4_);
	_g_object_unref0 (widg);
}

/**
 * Destroy an interface handler and remove from UI
 *
 * @param name DBUS name to remove handler for
 */
static void
mpris_widget_destroy_iface (MprisWidget* self,
                            const gchar* name)
{
	ClientWidget* widg = NULL;
	GHashTable* _tmp0_;
	gconstpointer _tmp1_;
	ClientWidget* _tmp2_;
	ClientWidget* _tmp3_;
	GtkWidget* _tmp6_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (name != NULL);
	_tmp0_ = self->priv->ifaces;
	_tmp1_ = g_hash_table_lookup (_tmp0_, name);
	_tmp2_ = _g_object_ref0 ((ClientWidget*) _tmp1_);
	widg = _tmp2_;
	_tmp3_ = widg;
	if (_tmp3_ != NULL) {
		ClientWidget* _tmp4_;
		GHashTable* _tmp5_;
		_tmp4_ = widg;
		gtk_container_remove ((GtkContainer*) self, (GtkWidget*) _tmp4_);
		_tmp5_ = self->priv->ifaces;
		g_hash_table_remove (_tmp5_, name);
	}
	gtk_widget_queue_draw ((GtkWidget*) self);
	_tmp6_ = gtk_widget_get_toplevel ((GtkWidget*) self);
	gtk_widget_queue_draw (_tmp6_);
	_g_object_unref0 (widg);
}

static Block2Data*
block2_data_ref (Block2Data* _data2_)
{
	g_atomic_int_inc (&_data2_->_ref_count_);
	return _data2_;
}

static void
block2_data_unref (void * _userdata_)
{
	Block2Data* _data2_;
	_data2_ = (Block2Data*) _userdata_;
	if (g_atomic_int_dec_and_test (&_data2_->_ref_count_)) {
		MprisWidget* self;
		self = _data2_->self;
		_g_free0 (_data2_->n);
		_g_object_unref0 (self);
		g_slice_free (Block2Data, _data2_);
	}
}

static void
___lambda21_ (Block2Data* _data2_,
              GObject* o,
              GAsyncResult* r)
{
	MprisWidget* self;
	MprisClient* iface = NULL;
	MprisClient* _tmp0_;
	MprisClient* _tmp1_;
	self = _data2_->self;
	g_return_if_fail (r != NULL);
	_tmp0_ = new_iface_finish (r);
	iface = _tmp0_;
	_tmp1_ = iface;
	if (_tmp1_ != NULL) {
		MprisClient* _tmp2_;
		_tmp2_ = iface;
		mpris_widget_add_iface (self, _data2_->n, _tmp2_);
	}
	_g_object_unref0 (iface);
}

static void
____lambda21__gasync_ready_callback (GObject* source_object,
                                     GAsyncResult* res,
                                     gpointer self)
{
	___lambda21_ (self, source_object, res);
	block2_data_unref (self);
}

static gboolean
___lambda22_ (Block2Data* _data2_)
{
	MprisWidget* self;
	gboolean result;
	self = _data2_->self;
	mpris_widget_destroy_iface (self, _data2_->n);
	result = FALSE;
	return result;
}

static gboolean
____lambda22__gsource_func (gpointer self)
{
	gboolean result;
	result = ___lambda22_ (self);
	return result;
}

static void
mpris_widget_on_name_owner_changed (MprisWidget* self,
                                    const gchar* n,
                                    const gchar* o,
                                    const gchar* ne)
{
	Block2Data* _data2_;
	gchar* _tmp0_;
	g_return_if_fail (self != NULL);
	_data2_ = g_slice_new0 (Block2Data);
	_data2_->_ref_count_ = 1;
	_data2_->self = g_object_ref (self);
	_tmp0_ = g_strdup (n);
	_g_free0 (_data2_->n);
	_data2_->n = _tmp0_;
	if (!g_str_has_prefix (_data2_->n, "org.mpris.MediaPlayer2.")) {
		block2_data_unref (_data2_);
		_data2_ = NULL;
		return;
	}
	if (g_strcmp0 (o, "") == 0) {
		new_iface (_data2_->n, ____lambda21__gasync_ready_callback, block2_data_ref (_data2_));
	} else {
		g_idle_add_full (G_PRIORITY_DEFAULT_IDLE, ____lambda22__gsource_func, block2_data_ref (_data2_), block2_data_unref);
	}
	block2_data_unref (_data2_);
	_data2_ = NULL;
}

static void
mpris_widget_setup_dbus_data_free (gpointer _data)
{
	MprisWidgetSetupDbusData* _data_;
	_data_ = _data;
	_g_object_unref0 (_data_->self);
	g_slice_free (MprisWidgetSetupDbusData, _data_);
}

void
mpris_widget_setup_dbus (MprisWidget* self,
                         GAsyncReadyCallback _callback_,
                         gpointer _user_data_)
{
	MprisWidgetSetupDbusData* _data_;
	MprisWidget* _tmp0_;
	g_return_if_fail (self != NULL);
	_data_ = g_slice_new0 (MprisWidgetSetupDbusData);
	_data_->_async_result = g_task_new (G_OBJECT (self), NULL, _callback_, _user_data_);
	g_task_set_task_data (_data_->_async_result, _data_, mpris_widget_setup_dbus_data_free);
	_tmp0_ = _g_object_ref0 (self);
	_data_->self = _tmp0_;
	mpris_widget_setup_dbus_co (_data_);
}

void
mpris_widget_setup_dbus_finish (MprisWidget* self,
                                GAsyncResult* _res_)
{
	MprisWidgetSetupDbusData* _data_;
	_data_ = g_task_propagate_pointer (G_TASK (_res_), NULL);
}

/**
 * Do basic dbus initialisation
 */
static void
mpris_widget_setup_dbus_ready (GObject* source_object,
                               GAsyncResult* _res_,
                               gpointer _user_data_)
{
	MprisWidgetSetupDbusData* _data_;
	_data_ = _user_data_;
	_data_->_source_object_ = source_object;
	_data_->_res_ = _res_;
	mpris_widget_setup_dbus_co (_data_);
}

static void
_mpris_widget_on_name_owner_changed_dbus_impl_name_owner_changed (DBusImpl* _sender,
                                                                  const gchar* name,
                                                                  const gchar* old_owner,
                                                                  const gchar* new_owner,
                                                                  gpointer self)
{
	mpris_widget_on_name_owner_changed ((MprisWidget*) self, name, old_owner, new_owner);
}

static gboolean
mpris_widget_setup_dbus_co (MprisWidgetSetupDbusData* _data_)
{
	switch (_data_->_state_) {
		case 0:
		goto _state_0;
		case 1:
		goto _state_1;
		case 2:
		goto _state_2;
		case 3:
		goto _state_3;
		default:
		g_assert_not_reached ();
	}
	_state_0:
	{
		_data_->_state_ = 1;
		g_async_initable_new_async (TYPE_DBUS_IMPL_PROXY, 0, NULL, mpris_widget_setup_dbus_ready, _data_, "g-flags", 0, "g-name", "org.freedesktop.DBus", "g-bus-type", G_BUS_TYPE_SESSION, "g-object-path", "/org/freedesktop/DBus", "g-interface-name", "org.freedesktop.DBus", NULL);
		return FALSE;
		_state_1:
		_data_->_tmp1_ = (DBusImpl*) g_async_initable_new_finish ((GAsyncInitable *) _data_->_source_object_, _data_->_res_, &_data_->_inner_error0_);
		_data_->_tmp0_ = (DBusImpl*) _data_->_tmp1_;
		if (G_UNLIKELY (_data_->_inner_error0_ != NULL)) {
			goto __catch0_g_error;
		}
		_data_->_tmp2_ = _data_->_tmp0_;
		_data_->_tmp0_ = NULL;
		_g_object_unref0 (_data_->self->priv->impl);
		_data_->self->priv->impl = _data_->_tmp2_;
		_data_->_tmp3_ = _data_->self->priv->impl;
		_data_->_tmp4_ = 0;
		_data_->_state_ = 2;
		dbus_impl_list_names (_data_->_tmp3_, mpris_widget_setup_dbus_ready, _data_);
		return FALSE;
		_state_2:
		_data_->_tmp5_ = dbus_impl_list_names_finish (_data_->_tmp3_, _data_->_res_, &_data_->_tmp4_, &_data_->_inner_error0_);
		_data_->names = _data_->_tmp5_;
		_data_->names_length1 = _data_->_tmp4_;
		_data_->_names_size_ = _data_->names_length1;
		if (G_UNLIKELY (_data_->_inner_error0_ != NULL)) {
			_g_object_unref0 (_data_->_tmp0_);
			goto __catch0_g_error;
		}
		_data_->_tmp6_ = _data_->names;
		_data_->_tmp6__length1 = _data_->names_length1;
		{
			_data_->name_collection_length1 = 0;
			_data_->_name_collection_size_ = 0;
			_data_->name_collection = _data_->_tmp6_;
			_data_->name_collection_length1 = _data_->_tmp6__length1;
			for (_data_->name_it = 0; _data_->name_it < _data_->name_collection_length1; _data_->name_it = _data_->name_it + 1) {
				_data_->_tmp7_ = g_strdup (_data_->name_collection[_data_->name_it]);
				_data_->name = _data_->_tmp7_;
				{
					_data_->_tmp8_ = _data_->name;
					if (g_str_has_prefix (_data_->_tmp8_, "org.mpris.MediaPlayer2.")) {
						_data_->_tmp9_ = _data_->name;
						_data_->_state_ = 3;
						new_iface (_data_->_tmp9_, mpris_widget_setup_dbus_ready, _data_);
						return FALSE;
						_state_3:
						_data_->_tmp10_ = new_iface_finish (_data_->_res_);
						_data_->iface = _data_->_tmp10_;
						_data_->_tmp11_ = _data_->iface;
						if (_data_->_tmp11_ != NULL) {
							_data_->_tmp12_ = _data_->name;
							_data_->_tmp13_ = _data_->iface;
							mpris_widget_add_iface (_data_->self, _data_->_tmp12_, _data_->_tmp13_);
						}
						_g_object_unref0 (_data_->iface);
					}
					_g_free0 (_data_->name);
				}
			}
		}
		_data_->_tmp14_ = _data_->self->priv->impl;
		g_signal_connect_object (_data_->_tmp14_, "name-owner-changed", (GCallback) _mpris_widget_on_name_owner_changed_dbus_impl_name_owner_changed, _data_->self, 0);
		_data_->names = (_vala_array_free (_data_->names, _data_->names_length1, (GDestroyNotify) g_free), NULL);
		_g_object_unref0 (_data_->_tmp0_);
	}
	goto __finally0;
	__catch0_g_error:
	{
		_data_->e = _data_->_inner_error0_;
		_data_->_inner_error0_ = NULL;
		_data_->_tmp15_ = _data_->e;
		_data_->_tmp16_ = _data_->_tmp15_->message;
		g_warning ("MprisWidget.vala:122: Failed to initialise dbus: %s", _data_->_tmp16_);
		_g_error_free0 (_data_->e);
	}
	__finally0:
	if (G_UNLIKELY (_data_->_inner_error0_ != NULL)) {
		g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _data_->_inner_error0_->message, g_quark_to_string (_data_->_inner_error0_->domain), _data_->_inner_error0_->code);
		g_clear_error (&_data_->_inner_error0_);
		g_object_unref (_data_->_async_result);
		return FALSE;
	}
	g_task_return_pointer (_data_->_async_result, _data_, NULL);
	if (_data_->_state_ != 0) {
		while (!g_task_get_completed (_data_->_async_result)) {
			g_main_context_iteration (g_task_get_context (_data_->_async_result), TRUE);
		}
	}
	g_object_unref (_data_->_async_result);
	return FALSE;
}

static void
mpris_widget_class_init (MprisWidgetClass * klass,
                         gpointer klass_data)
{
	mpris_widget_parent_class = g_type_class_peek_parent (klass);
	g_type_class_adjust_private_offset (klass, &MprisWidget_private_offset);
	G_OBJECT_CLASS (klass)->finalize = mpris_widget_finalize;
}

static void
mpris_widget_instance_init (MprisWidget * self,
                            gpointer klass)
{
	self->priv = mpris_widget_get_instance_private (self);
	self->priv->our_width = 250;
}

static void
mpris_widget_finalize (GObject * obj)
{
	MprisWidget * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, TYPE_MPRIS_WIDGET, MprisWidget);
	_g_object_unref0 (self->priv->impl);
	_g_hash_table_unref0 (self->priv->ifaces);
	G_OBJECT_CLASS (mpris_widget_parent_class)->finalize (obj);
}

static GType
mpris_widget_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (MprisWidgetClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) mpris_widget_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (MprisWidget), 0, (GInstanceInitFunc) mpris_widget_instance_init, NULL };
	GType mpris_widget_type_id;
	mpris_widget_type_id = g_type_register_static (TYPE_RAVEN_WIDGET, "MprisWidget", &g_define_type_info, 0);
	MprisWidget_private_offset = g_type_add_instance_private (mpris_widget_type_id, sizeof (MprisWidgetPrivate));
	return mpris_widget_type_id;
}

GType
mpris_widget_get_type (void)
{
	static volatile gsize mpris_widget_type_id__once = 0;
	if (g_once_init_enter (&mpris_widget_type_id__once)) {
		GType mpris_widget_type_id;
		mpris_widget_type_id = mpris_widget_get_type_once ();
		g_once_init_leave (&mpris_widget_type_id__once, mpris_widget_type_id);
	}
	return mpris_widget_type_id__once;
}

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);
}

