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

#include <gtk/gtk.h>
#include <glib-object.h>
#include <stdlib.h>
#include <string.h>
#include <glib.h>
#include <gio/gio.h>
#include <sys/types.h>
#include <pango/pango.h>
#include <float.h>
#include <math.h>
#include <signal.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 DC_TYPE_AUDIO_PLAYER (dc_audio_player_get_type ())
#define DC_AUDIO_PLAYER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), DC_TYPE_AUDIO_PLAYER, DcAudioPlayer))
#define DC_AUDIO_PLAYER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), DC_TYPE_AUDIO_PLAYER, DcAudioPlayerClass))
#define DC_IS_AUDIO_PLAYER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), DC_TYPE_AUDIO_PLAYER))
#define DC_IS_AUDIO_PLAYER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), DC_TYPE_AUDIO_PLAYER))
#define DC_AUDIO_PLAYER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), DC_TYPE_AUDIO_PLAYER, DcAudioPlayerClass))

typedef struct _DcAudioPlayer DcAudioPlayer;
typedef struct _DcAudioPlayerClass DcAudioPlayerClass;
typedef struct _DcAudioPlayerPrivate DcAudioPlayerPrivate;
enum  {
	DC_AUDIO_PLAYER_0_PROPERTY,
	DC_AUDIO_PLAYER_NUM_PROPERTIES
};
static GParamSpec* dc_audio_player_properties[DC_AUDIO_PLAYER_NUM_PROPERTIES];
#define _g_free0(var) (var = (g_free (var), NULL))
#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))
typedef struct _Block24Data Block24Data;
#define _g_error_free0(var) ((var == NULL) ? NULL : (var = (g_error_free (var), NULL)))
typedef struct _Block25Data Block25Data;

struct _DcAudioPlayer {
	GtkBox parent_instance;
	DcAudioPlayerPrivate * priv;
};

struct _DcAudioPlayerClass {
	GtkBoxClass parent_class;
};

struct _DcAudioPlayerPrivate {
	gchar* path;
	GtkButton* btn;
	GtkMediaFile* media;
	GSubprocess* proc;
	pid_t proc_pid;
	GCancellable* proc_cancel;
};

struct _Block24Data {
	int _ref_count_;
	DcAudioPlayer* self;
	GSubprocess* p;
};

struct _Block25Data {
	int _ref_count_;
	DcAudioPlayer* self;
	GtkMediaFile* m;
};

static gint DcAudioPlayer_private_offset;
static gpointer dc_audio_player_parent_class = NULL;
VALA_EXTERN gboolean dc_audio_player_prefer_system;
gboolean dc_audio_player_prefer_system = FALSE;

VALA_EXTERN GType dc_audio_player_get_type (void) G_GNUC_CONST ;
G_DEFINE_AUTOPTR_CLEANUP_FUNC (DcAudioPlayer, g_object_unref)
VALA_EXTERN DcAudioPlayer* dc_audio_player_new (const gchar* path,
                                    const gchar* name);
VALA_EXTERN DcAudioPlayer* dc_audio_player_construct (GType object_type,
                                          const gchar* path,
                                          const gchar* name);
static void dc_audio_player_toggle (DcAudioPlayer* self);
static void _dc_audio_player_toggle_gtk_button_clicked (GtkButton* _sender,
                                                 gpointer self);
static void dc_audio_player_stop (DcAudioPlayer* self);
static void dc_audio_player_play (DcAudioPlayer* self);
VALA_EXTERN gboolean dc_platform_is_macos (void);
static gchar** dc_audio_player_find_external_command (DcAudioPlayer* self,
                                               gint* result_length1);
static gboolean dc_audio_player_play_external (DcAudioPlayer* self,
                                        gchar** argv,
                                        gint argv_length1);
static void dc_audio_player_set_playing_visuals (DcAudioPlayer* self,
                                          gboolean playing);
static void dc_audio_player_play_media (DcAudioPlayer* self);
static Block24Data* block24_data_ref (Block24Data* _data24_);
static void block24_data_unref (void * _userdata_);
static void ___lambda8_ (Block24Data* _data24_,
                  GObject* obj,
                  GAsyncResult* res);
static void ____lambda8__gasync_ready_callback (GObject* source_object,
                                         GAsyncResult* res,
                                         gpointer self);
static Block25Data* block25_data_ref (Block25Data* _data25_);
static void block25_data_unref (void * _userdata_);
static void __lambda9_ (Block25Data* _data25_);
static void ___lambda9__g_object_notify (GObject* _sender,
                                  GParamSpec* pspec,
                                  gpointer self);
static void __lambda10_ (Block25Data* _data25_);
static void ___lambda10__g_object_notify (GObject* _sender,
                                   GParamSpec* pspec,
                                   gpointer self);
static void dc_audio_player_finalize (GObject * obj);
static GType dc_audio_player_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 _vala_memdup2 (gconstpointer mem,
                        gsize byte_size);

static inline gpointer
dc_audio_player_get_instance_private (DcAudioPlayer* self)
{
	return G_STRUCT_MEMBER_P (self, DcAudioPlayer_private_offset);
}

static void
_dc_audio_player_toggle_gtk_button_clicked (GtkButton* _sender,
                                            gpointer self)
{
	dc_audio_player_toggle ((DcAudioPlayer*) self);
}

DcAudioPlayer*
dc_audio_player_construct (GType object_type,
                           const gchar* path,
                           const gchar* name)
{
	DcAudioPlayer * self = NULL;
	gchar* _tmp0_;
	GtkButton* _tmp1_;
	GtkButton* _tmp2_;
	GtkButton* _tmp3_;
	GtkButton* _tmp4_;
	GtkButton* _tmp5_;
	GtkButton* _tmp6_;
	const gchar* _tmp7_ = NULL;
	gboolean _tmp8_ = FALSE;
	GtkLabel* label = NULL;
	GtkLabel* _tmp11_;
	g_return_val_if_fail (path != NULL, NULL);
	self = (DcAudioPlayer*) g_object_new (object_type, "orientation", GTK_ORIENTATION_HORIZONTAL, "spacing", 8, NULL);
	_tmp0_ = g_strdup (path);
	_g_free0 (self->priv->path);
	self->priv->path = _tmp0_;
	gtk_widget_add_css_class ((GtkWidget*) self, "message-audio");
	gtk_widget_set_halign ((GtkWidget*) self, GTK_ALIGN_START);
	_tmp1_ = (GtkButton*) gtk_button_new_from_icon_name ("media-playback-start-symbolic");
	g_object_ref_sink (_tmp1_);
	_g_object_unref0 (self->priv->btn);
	self->priv->btn = _tmp1_;
	_tmp2_ = self->priv->btn;
	gtk_widget_add_css_class ((GtkWidget*) _tmp2_, "circular");
	_tmp3_ = self->priv->btn;
	gtk_widget_set_valign ((GtkWidget*) _tmp3_, GTK_ALIGN_CENTER);
	_tmp4_ = self->priv->btn;
	gtk_widget_set_tooltip_text ((GtkWidget*) _tmp4_, "Play");
	_tmp5_ = self->priv->btn;
	g_signal_connect_object (_tmp5_, "clicked", (GCallback) _dc_audio_player_toggle_gtk_button_clicked, self, 0);
	_tmp6_ = self->priv->btn;
	gtk_box_append ((GtkBox*) self, (GtkWidget*) _tmp6_);
	if (name != NULL) {
		gint _tmp9_;
		gint _tmp10_;
		_tmp9_ = strlen (name);
		_tmp10_ = _tmp9_;
		_tmp8_ = _tmp10_ > 0;
	} else {
		_tmp8_ = FALSE;
	}
	if (_tmp8_) {
		_tmp7_ = name;
	} else {
		_tmp7_ = "Voice message";
	}
	_tmp11_ = (GtkLabel*) gtk_label_new (_tmp7_);
	g_object_ref_sink (_tmp11_);
	label = _tmp11_;
	gtk_widget_add_css_class ((GtkWidget*) label, "message-audio-name");
	gtk_label_set_ellipsize (label, PANGO_ELLIPSIZE_MIDDLE);
	gtk_label_set_max_width_chars (label, 22);
	gtk_label_set_xalign (label, (gfloat) 0);
	gtk_widget_set_valign ((GtkWidget*) label, GTK_ALIGN_CENTER);
	gtk_box_append ((GtkBox*) self, (GtkWidget*) label);
	_g_object_unref0 (label);
	return self;
}

DcAudioPlayer*
dc_audio_player_new (const gchar* path,
                     const gchar* name)
{
	return dc_audio_player_construct (DC_TYPE_AUDIO_PLAYER, path, name);
}

static void
dc_audio_player_toggle (DcAudioPlayer* self)
{
	gboolean _tmp0_ = FALSE;
	GtkMediaFile* _tmp1_;
	g_return_if_fail (self != NULL);
	_tmp1_ = self->priv->media;
	if (_tmp1_ != NULL) {
		_tmp0_ = TRUE;
	} else {
		GSubprocess* _tmp2_;
		_tmp2_ = self->priv->proc;
		_tmp0_ = _tmp2_ != NULL;
	}
	if (_tmp0_) {
		dc_audio_player_stop (self);
	} else {
		dc_audio_player_play (self);
	}
}

static void
dc_audio_player_play (DcAudioPlayer* self)
{
	gboolean _tmp0_ = FALSE;
	gboolean try_external = FALSE;
	g_return_if_fail (self != NULL);
	dc_audio_player_stop (self);
	if (dc_audio_player_prefer_system) {
		_tmp0_ = TRUE;
	} else {
		_tmp0_ = dc_platform_is_macos ();
	}
	try_external = _tmp0_;
	if (try_external) {
		gchar** argv = NULL;
		gint _tmp1_ = 0;
		gchar** _tmp2_;
		gint argv_length1;
		gint _argv_size_;
		gboolean _tmp3_ = FALSE;
		gchar** _tmp4_;
		gint _tmp4__length1;
		_tmp2_ = dc_audio_player_find_external_command (self, &_tmp1_);
		argv = _tmp2_;
		argv_length1 = _tmp1_;
		_argv_size_ = argv_length1;
		_tmp4_ = argv;
		_tmp4__length1 = argv_length1;
		if (_tmp4_ != NULL) {
			gchar** _tmp5_;
			gint _tmp5__length1;
			_tmp5_ = argv;
			_tmp5__length1 = argv_length1;
			_tmp3_ = dc_audio_player_play_external (self, _tmp5_, (gint) _tmp5__length1);
		} else {
			_tmp3_ = FALSE;
		}
		if (_tmp3_) {
			dc_audio_player_set_playing_visuals (self, TRUE);
			argv = (_vala_array_free (argv, argv_length1, (GDestroyNotify) g_free), NULL);
			return;
		}
		argv = (_vala_array_free (argv, argv_length1, (GDestroyNotify) g_free), NULL);
	}
	dc_audio_player_play_media (self);
	dc_audio_player_set_playing_visuals (self, TRUE);
}

static gchar**
dc_audio_player_find_external_command (DcAudioPlayer* self,
                                       gint* result_length1)
{
	gchar* _tmp0_;
	gchar* _tmp1_;
	gboolean _tmp2_;
	gchar* _tmp8_;
	gchar* _tmp9_;
	gboolean _tmp10_;
	gchar* _tmp17_;
	gchar* _tmp18_;
	gboolean _tmp19_;
	gchar* _tmp27_;
	gchar* _tmp28_;
	gboolean _tmp29_;
	gchar** _tmp39_;
	gint _tmp39__length1;
	gchar** result;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = g_find_program_in_path ("afplay");
	_tmp1_ = _tmp0_;
	_tmp2_ = _tmp1_ != NULL;
	_g_free0 (_tmp1_);
	if (_tmp2_) {
		gchar* _tmp3_;
		const gchar* _tmp4_;
		gchar* _tmp5_;
		gchar** _tmp6_;
		gchar** _tmp7_;
		gint _tmp7__length1;
		_tmp3_ = g_strdup ("afplay");
		_tmp4_ = self->priv->path;
		_tmp5_ = g_strdup (_tmp4_);
		_tmp6_ = g_new0 (gchar*, 2 + 1);
		_tmp6_[0] = _tmp3_;
		_tmp6_[1] = _tmp5_;
		_tmp7_ = _tmp6_;
		_tmp7__length1 = 2;
		if (result_length1) {
			*result_length1 = _tmp7__length1;
		}
		result = _tmp7_;
		return result;
	}
	_tmp8_ = g_find_program_in_path ("gst-play-1.0");
	_tmp9_ = _tmp8_;
	_tmp10_ = _tmp9_ != NULL;
	_g_free0 (_tmp9_);
	if (_tmp10_) {
		gchar* _tmp11_;
		gchar* _tmp12_;
		const gchar* _tmp13_;
		gchar* _tmp14_;
		gchar** _tmp15_;
		gchar** _tmp16_;
		gint _tmp16__length1;
		_tmp11_ = g_strdup ("gst-play-1.0");
		_tmp12_ = g_strdup ("--quiet");
		_tmp13_ = self->priv->path;
		_tmp14_ = g_strdup (_tmp13_);
		_tmp15_ = g_new0 (gchar*, 3 + 1);
		_tmp15_[0] = _tmp11_;
		_tmp15_[1] = _tmp12_;
		_tmp15_[2] = _tmp14_;
		_tmp16_ = _tmp15_;
		_tmp16__length1 = 3;
		if (result_length1) {
			*result_length1 = _tmp16__length1;
		}
		result = _tmp16_;
		return result;
	}
	_tmp17_ = g_find_program_in_path ("mpv");
	_tmp18_ = _tmp17_;
	_tmp19_ = _tmp18_ != NULL;
	_g_free0 (_tmp18_);
	if (_tmp19_) {
		gchar* _tmp20_;
		gchar* _tmp21_;
		gchar* _tmp22_;
		const gchar* _tmp23_;
		gchar* _tmp24_;
		gchar** _tmp25_;
		gchar** _tmp26_;
		gint _tmp26__length1;
		_tmp20_ = g_strdup ("mpv");
		_tmp21_ = g_strdup ("--no-video");
		_tmp22_ = g_strdup ("--really-quiet");
		_tmp23_ = self->priv->path;
		_tmp24_ = g_strdup (_tmp23_);
		_tmp25_ = g_new0 (gchar*, 4 + 1);
		_tmp25_[0] = _tmp20_;
		_tmp25_[1] = _tmp21_;
		_tmp25_[2] = _tmp22_;
		_tmp25_[3] = _tmp24_;
		_tmp26_ = _tmp25_;
		_tmp26__length1 = 4;
		if (result_length1) {
			*result_length1 = _tmp26__length1;
		}
		result = _tmp26_;
		return result;
	}
	_tmp27_ = g_find_program_in_path ("ffplay");
	_tmp28_ = _tmp27_;
	_tmp29_ = _tmp28_ != NULL;
	_g_free0 (_tmp28_);
	if (_tmp29_) {
		gchar* _tmp30_;
		gchar* _tmp31_;
		gchar* _tmp32_;
		gchar* _tmp33_;
		gchar* _tmp34_;
		const gchar* _tmp35_;
		gchar* _tmp36_;
		gchar** _tmp37_;
		gchar** _tmp38_;
		gint _tmp38__length1;
		_tmp30_ = g_strdup ("ffplay");
		_tmp31_ = g_strdup ("-nodisp");
		_tmp32_ = g_strdup ("-autoexit");
		_tmp33_ = g_strdup ("-loglevel");
		_tmp34_ = g_strdup ("quiet");
		_tmp35_ = self->priv->path;
		_tmp36_ = g_strdup (_tmp35_);
		_tmp37_ = g_new0 (gchar*, 6 + 1);
		_tmp37_[0] = _tmp30_;
		_tmp37_[1] = _tmp31_;
		_tmp37_[2] = _tmp32_;
		_tmp37_[3] = _tmp33_;
		_tmp37_[4] = _tmp34_;
		_tmp37_[5] = _tmp36_;
		_tmp38_ = _tmp37_;
		_tmp38__length1 = 6;
		if (result_length1) {
			*result_length1 = _tmp38__length1;
		}
		result = _tmp38_;
		return result;
	}
	_tmp39_ = NULL;
	_tmp39__length1 = 0;
	if (result_length1) {
		*result_length1 = _tmp39__length1;
	}
	result = _tmp39_;
	return result;
}

static Block24Data*
block24_data_ref (Block24Data* _data24_)
{
	g_atomic_int_inc (&_data24_->_ref_count_);
	return _data24_;
}

static void
block24_data_unref (void * _userdata_)
{
	Block24Data* _data24_;
	_data24_ = (Block24Data*) _userdata_;
	if (g_atomic_int_dec_and_test (&_data24_->_ref_count_)) {
		DcAudioPlayer* self;
		self = _data24_->self;
		_g_object_unref0 (_data24_->p);
		_g_object_unref0 (self);
		g_slice_free (Block24Data, _data24_);
	}
}

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

static void
___lambda8_ (Block24Data* _data24_,
             GObject* obj,
             GAsyncResult* res)
{
	DcAudioPlayer* self;
	GSubprocess* _tmp0_;
	GError* _inner_error0_ = NULL;
	self = _data24_->self;
	g_return_if_fail (res != NULL);
	{
		g_subprocess_wait_finish (_data24_->p, res, &_inner_error0_);
		if (G_UNLIKELY (_inner_error0_ != NULL)) {
			goto __catch0_g_error;
		}
	}
	goto __finally0;
	__catch0_g_error:
	{
		g_clear_error (&_inner_error0_);
	}
	__finally0:
	if (G_UNLIKELY (_inner_error0_ != NULL)) {
		g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error0_->message, g_quark_to_string (_inner_error0_->domain), _inner_error0_->code);
		g_clear_error (&_inner_error0_);
		return;
	}
	_tmp0_ = self->priv->proc;
	if (_tmp0_ == _data24_->p) {
		dc_audio_player_stop (self);
	}
}

static void
____lambda8__gasync_ready_callback (GObject* source_object,
                                    GAsyncResult* res,
                                    gpointer self)
{
	___lambda8_ (self, source_object, res);
	block24_data_unref (self);
}

static gboolean
dc_audio_player_play_external (DcAudioPlayer* self,
                               gchar** argv,
                               gint argv_length1)
{
	gboolean _tmp13_ = FALSE;
	GError* _inner_error0_ = NULL;
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	{
		Block24Data* _data24_;
		GSubprocessLauncher* launcher = NULL;
		GSubprocessLauncher* _tmp0_;
		GSubprocess* _tmp1_;
		GSubprocess* _tmp2_;
		gchar* pid_str = NULL;
		const gchar* _tmp3_;
		gchar* _tmp4_;
		pid_t _tmp5_ = 0;
		const gchar* _tmp6_;
		GCancellable* _tmp8_;
		GCancellable* _tmp9_;
		_data24_ = g_slice_new0 (Block24Data);
		_data24_->_ref_count_ = 1;
		_data24_->self = g_object_ref (self);
		_tmp0_ = g_subprocess_launcher_new (G_SUBPROCESS_FLAGS_STDOUT_SILENCE | G_SUBPROCESS_FLAGS_STDERR_SILENCE);
		launcher = _tmp0_;
		_tmp1_ = g_subprocess_launcher_spawnv (launcher, argv, &_inner_error0_);
		_data24_->p = _tmp1_;
		if (G_UNLIKELY (_inner_error0_ != NULL)) {
			_g_object_unref0 (launcher);
			block24_data_unref (_data24_);
			_data24_ = NULL;
			goto __catch0_g_error;
		}
		_tmp2_ = _g_object_ref0 (_data24_->p);
		_g_object_unref0 (self->priv->proc);
		self->priv->proc = _tmp2_;
		_tmp3_ = g_subprocess_get_identifier (_data24_->p);
		_tmp4_ = g_strdup (_tmp3_);
		pid_str = _tmp4_;
		_tmp6_ = pid_str;
		if (_tmp6_ != NULL) {
			const gchar* _tmp7_;
			_tmp7_ = pid_str;
			_tmp5_ = (pid_t) atoi (_tmp7_);
		} else {
			_tmp5_ = (pid_t) 0;
		}
		self->priv->proc_pid = _tmp5_;
		_tmp8_ = g_cancellable_new ();
		_g_object_unref0 (self->priv->proc_cancel);
		self->priv->proc_cancel = _tmp8_;
		_tmp9_ = self->priv->proc_cancel;
		g_subprocess_wait_async (_data24_->p, _tmp9_, ____lambda8__gasync_ready_callback, block24_data_ref (_data24_));
		result = TRUE;
		_g_free0 (pid_str);
		_g_object_unref0 (launcher);
		block24_data_unref (_data24_);
		_data24_ = NULL;
		return result;
	}
	goto __finally0;
	__catch0_g_error:
	{
		GError* e = NULL;
		const gchar* _tmp10_;
		GError* _tmp11_;
		const gchar* _tmp12_;
		e = _inner_error0_;
		_inner_error0_ = NULL;
		_tmp10_ = argv[0];
		_tmp11_ = e;
		_tmp12_ = _tmp11_->message;
		g_warning ("audio_player.vala:97: audio: failed to spawn %s: %s", _tmp10_, _tmp12_);
		result = FALSE;
		_g_error_free0 (e);
		return result;
	}
	__finally0:
	g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error0_->message, g_quark_to_string (_inner_error0_->domain), _inner_error0_->code);
	g_clear_error (&_inner_error0_);
	return _tmp13_;
}

static Block25Data*
block25_data_ref (Block25Data* _data25_)
{
	g_atomic_int_inc (&_data25_->_ref_count_);
	return _data25_;
}

static void
block25_data_unref (void * _userdata_)
{
	Block25Data* _data25_;
	_data25_ = (Block25Data*) _userdata_;
	if (g_atomic_int_dec_and_test (&_data25_->_ref_count_)) {
		DcAudioPlayer* self;
		self = _data25_->self;
		_g_object_unref0 (_data25_->m);
		_g_object_unref0 (self);
		g_slice_free (Block25Data, _data25_);
	}
}

static void
__lambda9_ (Block25Data* _data25_)
{
	DcAudioPlayer* self;
	gboolean _tmp0_ = FALSE;
	GtkMediaFile* _tmp1_;
	self = _data25_->self;
	_tmp1_ = self->priv->media;
	if (_tmp1_ == _data25_->m) {
		gboolean _tmp2_;
		gboolean _tmp3_;
		_tmp2_ = gtk_media_stream_get_ended ((GtkMediaStream*) _data25_->m);
		_tmp3_ = _tmp2_;
		_tmp0_ = _tmp3_;
	} else {
		_tmp0_ = FALSE;
	}
	if (_tmp0_) {
		dc_audio_player_stop (self);
	}
}

static void
___lambda9__g_object_notify (GObject* _sender,
                             GParamSpec* pspec,
                             gpointer self)
{
	__lambda9_ (self);
}

static void
__lambda10_ (Block25Data* _data25_)
{
	DcAudioPlayer* self;
	gboolean _tmp0_ = FALSE;
	GtkMediaFile* _tmp1_;
	self = _data25_->self;
	_tmp1_ = self->priv->media;
	if (_tmp1_ == _data25_->m) {
		GError* _tmp2_;
		GError* _tmp3_;
		_tmp2_ = gtk_media_stream_get_error ((GtkMediaStream*) _data25_->m);
		_tmp3_ = _tmp2_;
		_tmp0_ = _tmp3_ != NULL;
	} else {
		_tmp0_ = FALSE;
	}
	if (_tmp0_) {
		dc_audio_player_stop (self);
	}
}

static void
___lambda10__g_object_notify (GObject* _sender,
                              GParamSpec* pspec,
                              gpointer self)
{
	__lambda10_ (self);
}

static void
dc_audio_player_play_media (DcAudioPlayer* self)
{
	Block25Data* _data25_;
	const gchar* _tmp0_;
	GtkMediaFile* _tmp1_;
	GtkMediaFile* _tmp2_;
	g_return_if_fail (self != NULL);
	_data25_ = g_slice_new0 (Block25Data);
	_data25_->_ref_count_ = 1;
	_data25_->self = g_object_ref (self);
	_tmp0_ = self->priv->path;
	_tmp1_ = (GtkMediaFile*) gtk_media_file_new_for_filename (_tmp0_);
	_data25_->m = _tmp1_;
	_tmp2_ = _g_object_ref0 (_data25_->m);
	_g_object_unref0 (self->priv->media);
	self->priv->media = _tmp2_;
	g_signal_connect_data ((GObject*) _data25_->m, "notify::ended", (GCallback) ___lambda9__g_object_notify, block25_data_ref (_data25_), (GClosureNotify) block25_data_unref, 0);
	g_signal_connect_data ((GObject*) _data25_->m, "notify::error", (GCallback) ___lambda10__g_object_notify, block25_data_ref (_data25_), (GClosureNotify) block25_data_unref, 0);
	gtk_media_stream_play ((GtkMediaStream*) _data25_->m);
	block25_data_unref (_data25_);
	_data25_ = NULL;
}

static void
dc_audio_player_stop (DcAudioPlayer* self)
{
	GSubprocess* _tmp0_;
	GCancellable* _tmp1_;
	GtkMediaFile* _tmp3_;
	g_return_if_fail (self != NULL);
	if (self->priv->proc_pid > ((pid_t) 0)) {
		kill (self->priv->proc_pid, (gint) SIGTERM);
		kill (self->priv->proc_pid, (gint) SIGKILL);
		self->priv->proc_pid = (pid_t) 0;
	}
	_tmp0_ = self->priv->proc;
	if (_tmp0_ != NULL) {
		_g_object_unref0 (self->priv->proc);
		self->priv->proc = NULL;
	}
	_tmp1_ = self->priv->proc_cancel;
	if (_tmp1_ != NULL) {
		GCancellable* _tmp2_;
		_tmp2_ = self->priv->proc_cancel;
		g_cancellable_cancel (_tmp2_);
		_g_object_unref0 (self->priv->proc_cancel);
		self->priv->proc_cancel = NULL;
	}
	_tmp3_ = self->priv->media;
	if (_tmp3_ != NULL) {
		GtkMediaFile* _tmp4_;
		_tmp4_ = self->priv->media;
		gtk_media_stream_pause ((GtkMediaStream*) _tmp4_);
		_g_object_unref0 (self->priv->media);
		self->priv->media = NULL;
	}
	dc_audio_player_set_playing_visuals (self, FALSE);
}

static void
dc_audio_player_set_playing_visuals (DcAudioPlayer* self,
                                     gboolean playing)
{
	const gchar* _tmp0_ = NULL;
	GtkButton* _tmp1_;
	const gchar* _tmp2_ = NULL;
	GtkButton* _tmp3_;
	g_return_if_fail (self != NULL);
	if (playing) {
		_tmp0_ = "media-playback-stop-symbolic";
	} else {
		_tmp0_ = "media-playback-start-symbolic";
	}
	_tmp1_ = self->priv->btn;
	gtk_button_set_icon_name (_tmp1_, _tmp0_);
	if (playing) {
		_tmp2_ = "Stop";
	} else {
		_tmp2_ = "Play";
	}
	_tmp3_ = self->priv->btn;
	gtk_widget_set_tooltip_text ((GtkWidget*) _tmp3_, _tmp2_);
}

static void
dc_audio_player_class_init (DcAudioPlayerClass * klass,
                            gpointer klass_data)
{
	dc_audio_player_parent_class = g_type_class_peek_parent (klass);
	g_type_class_adjust_private_offset (klass, &DcAudioPlayer_private_offset);
	G_OBJECT_CLASS (klass)->finalize = dc_audio_player_finalize;
}

static void
dc_audio_player_instance_init (DcAudioPlayer * self,
                               gpointer klass)
{
	self->priv = dc_audio_player_get_instance_private (self);
	self->priv->media = NULL;
	self->priv->proc = NULL;
	self->priv->proc_pid = (pid_t) 0;
	self->priv->proc_cancel = NULL;
}

static void
dc_audio_player_finalize (GObject * obj)
{
	DcAudioPlayer * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, DC_TYPE_AUDIO_PLAYER, DcAudioPlayer);
	_g_free0 (self->priv->path);
	_g_object_unref0 (self->priv->btn);
	_g_object_unref0 (self->priv->media);
	_g_object_unref0 (self->priv->proc);
	_g_object_unref0 (self->priv->proc_cancel);
	G_OBJECT_CLASS (dc_audio_player_parent_class)->finalize (obj);
}

/**
     * Compact inline player for audio / voice attachments: a single
     * play/stop button plus the file name.
     *
     * On Linux, GTK4's gstreamer media backend drives Gtk.MediaFile fine.
     * macOS brew's gtk4 ships without a media backend, so MediaFile is a
     * silent no-op there — we shell out to afplay instead. The same
     * shell-out path is also available on Linux via gst-play-1.0/mpv/
     * ffplay, opt-in through the "System audio player" setting.
     */
static GType
dc_audio_player_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (DcAudioPlayerClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) dc_audio_player_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (DcAudioPlayer), 0, (GInstanceInitFunc) dc_audio_player_instance_init, NULL };
	GType dc_audio_player_type_id;
	dc_audio_player_type_id = g_type_register_static (gtk_box_get_type (), "DcAudioPlayer", &g_define_type_info, 0);
	DcAudioPlayer_private_offset = g_type_add_instance_private (dc_audio_player_type_id, sizeof (DcAudioPlayerPrivate));
	return dc_audio_player_type_id;
}

GType
dc_audio_player_get_type (void)
{
	static volatile gsize dc_audio_player_type_id__once = 0;
	if (g_once_init_enter (&dc_audio_player_type_id__once)) {
		GType dc_audio_player_type_id;
		dc_audio_player_type_id = dc_audio_player_get_type_once ();
		g_once_init_leave (&dc_audio_player_type_id__once, dc_audio_player_type_id);
	}
	return dc_audio_player_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);
}

static inline gpointer
_vala_memdup2 (gconstpointer mem,
               gsize byte_size)
{
	gpointer new_mem;
	if (mem && byte_size != 0) {
		new_mem = g_malloc (byte_size);
		memcpy (new_mem, mem, byte_size);
	} else {
		new_mem = NULL;
	}
	return new_mem;
}

