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

/*
 * This file is part of budgie-desktop
 * 
 * Copyright (C) 2015-2016 Ikey Doherty <ikey@solus-project.com>
 * 
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 */

#include <glib.h>
#include <glib-object.h>
#include <stdlib.h>
#include <string.h>
#include <gtk/gtk.h>
#include <pulse/pulseaudio.h>
#include <gvc-mixer-control.h>
#include <gvc-mixer-stream.h>
#include <float.h>
#include <math.h>
#include <gdk/gdk.h>


#define TYPE_SOUND_INDICATOR (sound_indicator_get_type ())
#define SOUND_INDICATOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_SOUND_INDICATOR, SoundIndicator))
#define SOUND_INDICATOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_SOUND_INDICATOR, SoundIndicatorClass))
#define IS_SOUND_INDICATOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_SOUND_INDICATOR))
#define IS_SOUND_INDICATOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_SOUND_INDICATOR))
#define SOUND_INDICATOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_SOUND_INDICATOR, SoundIndicatorClass))

typedef struct _SoundIndicator SoundIndicator;
typedef struct _SoundIndicatorClass SoundIndicatorClass;
typedef struct _SoundIndicatorPrivate SoundIndicatorPrivate;
#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))
#define _g_free0(var) (var = (g_free (var), NULL))

struct _SoundIndicator {
	GtkBin parent_instance;
	SoundIndicatorPrivate * priv;
	GtkEventBox* ebox;
	GtkPopover* popover;
};

struct _SoundIndicatorClass {
	GtkBinClass parent_class;
};

struct _SoundIndicatorPrivate {
	GtkImage* _widget;
	GvcMixerControl* _mixer;
	GvcMixerStream* stream;
	GtkScale* volume_scale;
	gdouble step_size;
	gulong notify_id;
	gulong scale_id;
};


static gpointer sound_indicator_parent_class = NULL;
static GType sound_indicator_type_id = 0;

#define MIXER_NAME "Budgie Volume Control"
GType sound_indicator_get_type (void) G_GNUC_CONST;
GType sound_indicator_register_type (GTypeModule * module);
#define SOUND_INDICATOR_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), TYPE_SOUND_INDICATOR, SoundIndicatorPrivate))
enum  {
	SOUND_INDICATOR_DUMMY_PROPERTY,
	SOUND_INDICATOR_WIDGET,
	SOUND_INDICATOR_MIXER
};
SoundIndicator* sound_indicator_new (void);
SoundIndicator* sound_indicator_construct (GType object_type);
void sound_indicator_set_widget (SoundIndicator* self, GtkImage* value);
GtkImage* sound_indicator_get_widget (SoundIndicator* self);
void sound_indicator_set_mixer (SoundIndicator* self, GvcMixerControl* value);
GvcMixerControl* sound_indicator_get_mixer (SoundIndicator* self);
void sound_indicator_on_state_change (SoundIndicator* self, guint new_state);
static void _sound_indicator_on_state_change_gvc_mixer_control_state_changed (GvcMixerControl* _sender, guint new_state, gpointer self);
static void sound_indicator_on_sink_changed (SoundIndicator* self, guint id);
static void _sound_indicator_on_sink_changed_gvc_mixer_control_default_sink_changed (GvcMixerControl* _sender, guint id, gpointer self);
static void sound_indicator_create_sound_popover (SoundIndicator* self);
gboolean sound_indicator_on_scroll_event (SoundIndicator* self, GdkEventScroll* event);
static gboolean _sound_indicator_on_scroll_event_gtk_widget_scroll_event (GtkWidget* _sender, GdkEventScroll* event, gpointer self);
static void __lambda8_ (SoundIndicator* self);
static void sound_indicator_adjust_volume_increment (SoundIndicator* self, gdouble increment);
static void ___lambda8__gtk_button_clicked (GtkButton* _sender, gpointer self);
static void sound_indicator_on_scale_changed (SoundIndicator* self);
static void _sound_indicator_on_scale_changed_gtk_range_value_changed (GtkRange* _sender, gpointer self);
static void __lambda9_ (SoundIndicator* self);
static void ___lambda9__gtk_button_clicked (GtkButton* _sender, gpointer self);
static void sound_indicator_set_default_mixer (SoundIndicator* self);
static void sound_indicator_on_notify (SoundIndicator* self, GObject* o, GParamSpec* p);
static void _sound_indicator_on_notify_g_object_notify (GObject* _sender, GParamSpec* pspec, gpointer self);
void sound_indicator_update_volume (SoundIndicator* self);
static void sound_indicator_finalize (GObject* obj);
static void _vala_sound_indicator_get_property (GObject * object, guint property_id, GValue * value, GParamSpec * pspec);
static void _vala_sound_indicator_set_property (GObject * object, guint property_id, const GValue * value, GParamSpec * pspec);


static void _sound_indicator_on_state_change_gvc_mixer_control_state_changed (GvcMixerControl* _sender, guint new_state, gpointer self) {
	sound_indicator_on_state_change ((SoundIndicator*) self, new_state);
}


static void _sound_indicator_on_sink_changed_gvc_mixer_control_default_sink_changed (GvcMixerControl* _sender, guint id, gpointer self) {
	sound_indicator_on_sink_changed ((SoundIndicator*) self, id);
}


static gboolean _sound_indicator_on_scroll_event_gtk_widget_scroll_event (GtkWidget* _sender, GdkEventScroll* event, gpointer self) {
	gboolean result;
	result = sound_indicator_on_scroll_event ((SoundIndicator*) self, event);
	return result;
}


SoundIndicator* sound_indicator_construct (GType object_type) {
	SoundIndicator * self = NULL;
	GtkImage* _tmp0_ = NULL;
	GtkImage* _tmp1_ = NULL;
	GtkEventBox* _tmp2_ = NULL;
	GtkEventBox* _tmp3_ = NULL;
	GtkImage* _tmp4_ = NULL;
	GtkEventBox* _tmp5_ = NULL;
	GtkEventBox* _tmp6_ = NULL;
	GtkEventBox* _tmp7_ = NULL;
	GvcMixerControl* _tmp8_ = NULL;
	GvcMixerControl* _tmp9_ = NULL;
	GvcMixerControl* _tmp10_ = NULL;
	GvcMixerControl* _tmp11_ = NULL;
	GvcMixerControl* _tmp12_ = NULL;
	GtkEventBox* _tmp13_ = NULL;
	GtkEventBox* _tmp14_ = NULL;
	self = (SoundIndicator*) g_object_new (object_type, NULL);
	_tmp0_ = (GtkImage*) gtk_image_new_from_icon_name ("audio-volume-muted-symbolic", GTK_ICON_SIZE_MENU);
	g_object_ref_sink (_tmp0_);
	_tmp1_ = _tmp0_;
	sound_indicator_set_widget (self, _tmp1_);
	_g_object_unref0 (_tmp1_);
	_tmp2_ = (GtkEventBox*) gtk_event_box_new ();
	g_object_ref_sink (_tmp2_);
	_g_object_unref0 (self->ebox);
	self->ebox = _tmp2_;
	_tmp3_ = self->ebox;
	_tmp4_ = self->priv->_widget;
	gtk_container_add ((GtkContainer*) _tmp3_, (GtkWidget*) _tmp4_);
	_tmp5_ = self->ebox;
	g_object_set ((GtkWidget*) _tmp5_, "margin", 0, NULL);
	_tmp6_ = self->ebox;
	gtk_container_set_border_width ((GtkContainer*) _tmp6_, (guint) 0);
	_tmp7_ = self->ebox;
	gtk_container_add ((GtkContainer*) self, (GtkWidget*) _tmp7_);
	_tmp8_ = gvc_mixer_control_new (MIXER_NAME);
	_tmp9_ = _tmp8_;
	sound_indicator_set_mixer (self, _tmp9_);
	_g_object_unref0 (_tmp9_);
	_tmp10_ = self->priv->_mixer;
	g_signal_connect_object (_tmp10_, "state-changed", (GCallback) _sound_indicator_on_state_change_gvc_mixer_control_state_changed, self, 0);
	_tmp11_ = self->priv->_mixer;
	g_signal_connect_object (_tmp11_, "default-sink-changed", (GCallback) _sound_indicator_on_sink_changed_gvc_mixer_control_default_sink_changed, self, 0);
	_tmp12_ = self->priv->_mixer;
	gvc_mixer_control_open (_tmp12_);
	sound_indicator_create_sound_popover (self);
	_tmp13_ = self->ebox;
	gtk_widget_add_events ((GtkWidget*) _tmp13_, (gint) GDK_SCROLL_MASK);
	_tmp14_ = self->ebox;
	g_signal_connect_object ((GtkWidget*) _tmp14_, "scroll-event", (GCallback) _sound_indicator_on_scroll_event_gtk_widget_scroll_event, self, 0);
	gtk_widget_show_all ((GtkWidget*) self);
	return self;
}


SoundIndicator* sound_indicator_new (void) {
	return sound_indicator_construct (TYPE_SOUND_INDICATOR);
}


/**
     * Create the GtkPopover to display on primary click action, with an adjustable
     * scale
     */
static void __lambda8_ (SoundIndicator* self) {
	gdouble _tmp0_ = 0.0;
	_tmp0_ = self->priv->step_size;
	sound_indicator_adjust_volume_increment (self, +_tmp0_);
}


static void ___lambda8__gtk_button_clicked (GtkButton* _sender, gpointer self) {
	__lambda8_ ((SoundIndicator*) self);
}


static void _sound_indicator_on_scale_changed_gtk_range_value_changed (GtkRange* _sender, gpointer self) {
	sound_indicator_on_scale_changed ((SoundIndicator*) self);
}


static void __lambda9_ (SoundIndicator* self) {
	gdouble _tmp0_ = 0.0;
	_tmp0_ = self->priv->step_size;
	sound_indicator_adjust_volume_increment (self, -_tmp0_);
}


static void ___lambda9__gtk_button_clicked (GtkButton* _sender, gpointer self) {
	__lambda9_ ((SoundIndicator*) self);
}


static void sound_indicator_create_sound_popover (SoundIndicator* self) {
	GtkEventBox* _tmp0_ = NULL;
	GtkPopover* _tmp1_ = NULL;
	GtkBox* popover_box = NULL;
	GtkBox* _tmp2_ = NULL;
	GtkPopover* _tmp3_ = NULL;
	GtkButton* sub_button = NULL;
	GtkButton* _tmp4_ = NULL;
	GtkButton* plus_button = NULL;
	GtkButton* _tmp5_ = NULL;
	GtkScale* _tmp6_ = NULL;
	GtkScale* _tmp7_ = NULL;
	GtkScale* _tmp8_ = NULL;
	gulong _tmp9_ = 0UL;
	GtkScale* _tmp10_ = NULL;
	GtkScale* _tmp11_ = NULL;
	GtkStyleContext* _tmp12_ = NULL;
	GtkStyleContext* _tmp13_ = NULL;
	GtkStyleContext* _tmp14_ = NULL;
	GtkStyleContext* _tmp15_ = NULL;
	GtkScale* _tmp16_ = NULL;
	GtkScale* _tmp17_ = NULL;
	GtkPopover* _tmp18_ = NULL;
	GtkWidget* _tmp19_ = NULL;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->ebox;
	_tmp1_ = (GtkPopover*) gtk_popover_new ((GtkWidget*) _tmp0_);
	g_object_ref_sink (_tmp1_);
	_g_object_unref0 (self->popover);
	self->popover = _tmp1_;
	_tmp2_ = (GtkBox*) gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
	g_object_ref_sink (_tmp2_);
	popover_box = _tmp2_;
	_tmp3_ = self->popover;
	gtk_container_add ((GtkContainer*) _tmp3_, (GtkWidget*) popover_box);
	_tmp4_ = (GtkButton*) gtk_button_new_from_icon_name ("list-remove-symbolic", GTK_ICON_SIZE_BUTTON);
	g_object_ref_sink (_tmp4_);
	sub_button = _tmp4_;
	_tmp5_ = (GtkButton*) gtk_button_new_from_icon_name ("list-add-symbolic", GTK_ICON_SIZE_BUTTON);
	g_object_ref_sink (_tmp5_);
	plus_button = _tmp5_;
	gtk_box_pack_start (popover_box, (GtkWidget*) plus_button, FALSE, FALSE, (guint) 1);
	g_signal_connect_object (plus_button, "clicked", (GCallback) ___lambda8__gtk_button_clicked, self, 0);
	_tmp6_ = (GtkScale*) gtk_scale_new_with_range (GTK_ORIENTATION_VERTICAL, (gdouble) 0, (gdouble) 100, (gdouble) 1);
	g_object_ref_sink (_tmp6_);
	_g_object_unref0 (self->priv->volume_scale);
	self->priv->volume_scale = _tmp6_;
	_tmp7_ = self->priv->volume_scale;
	gtk_box_pack_start (popover_box, (GtkWidget*) _tmp7_, FALSE, FALSE, (guint) 0);
	_tmp8_ = self->priv->volume_scale;
	_tmp9_ = g_signal_connect_object ((GtkRange*) _tmp8_, "value-changed", (GCallback) _sound_indicator_on_scale_changed_gtk_range_value_changed, self, 0);
	self->priv->scale_id = _tmp9_;
	gtk_box_pack_start (popover_box, (GtkWidget*) sub_button, FALSE, FALSE, (guint) 1);
	g_signal_connect_object (sub_button, "clicked", (GCallback) ___lambda9__gtk_button_clicked, self, 0);
	_tmp10_ = self->priv->volume_scale;
	gtk_scale_set_draw_value (_tmp10_, FALSE);
	_tmp11_ = self->priv->volume_scale;
	gtk_widget_set_size_request ((GtkWidget*) _tmp11_, -1, 100);
	_tmp12_ = gtk_widget_get_style_context ((GtkWidget*) sub_button);
	gtk_style_context_add_class (_tmp12_, "flat");
	_tmp13_ = gtk_widget_get_style_context ((GtkWidget*) sub_button);
	gtk_style_context_add_class (_tmp13_, "image-button");
	_tmp14_ = gtk_widget_get_style_context ((GtkWidget*) plus_button);
	gtk_style_context_add_class (_tmp14_, "flat");
	_tmp15_ = gtk_widget_get_style_context ((GtkWidget*) plus_button);
	gtk_style_context_add_class (_tmp15_, "image-button");
	gtk_widget_set_can_focus ((GtkWidget*) sub_button, FALSE);
	gtk_widget_set_can_focus ((GtkWidget*) plus_button, FALSE);
	_tmp16_ = self->priv->volume_scale;
	gtk_widget_set_can_focus ((GtkWidget*) _tmp16_, FALSE);
	_tmp17_ = self->priv->volume_scale;
	gtk_range_set_inverted ((GtkRange*) _tmp17_, TRUE);
	_tmp18_ = self->popover;
	_tmp19_ = gtk_bin_get_child ((GtkBin*) _tmp18_);
	gtk_widget_show_all (_tmp19_);
	_g_object_unref0 (plus_button);
	_g_object_unref0 (sub_button);
	_g_object_unref0 (popover_box);
}


static void sound_indicator_on_sink_changed (SoundIndicator* self, guint id) {
	g_return_if_fail (self != NULL);
	sound_indicator_set_default_mixer (self);
}


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


static void _sound_indicator_on_notify_g_object_notify (GObject* _sender, GParamSpec* pspec, gpointer self) {
	sound_indicator_on_notify ((SoundIndicator*) self, _sender, pspec);
}


static void sound_indicator_set_default_mixer (SoundIndicator* self) {
	GvcMixerStream* _tmp0_ = NULL;
	GvcMixerControl* _tmp3_ = NULL;
	GvcMixerStream* _tmp4_ = NULL;
	GvcMixerStream* _tmp5_ = NULL;
	GvcMixerStream* _tmp6_ = NULL;
	gulong _tmp7_ = 0UL;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->priv->stream;
	if (_tmp0_ != NULL) {
		GvcMixerStream* _tmp1_ = NULL;
		gulong _tmp2_ = 0UL;
		_tmp1_ = self->priv->stream;
		_tmp2_ = self->priv->notify_id;
		g_signal_handler_disconnect (_tmp1_, _tmp2_);
	}
	_tmp3_ = self->priv->_mixer;
	_tmp4_ = gvc_mixer_control_get_default_sink (_tmp3_);
	_tmp5_ = _g_object_ref0 (_tmp4_);
	_g_object_unref0 (self->priv->stream);
	self->priv->stream = _tmp5_;
	_tmp6_ = self->priv->stream;
	_tmp7_ = g_signal_connect_object ((GObject*) _tmp6_, "notify", (GCallback) _sound_indicator_on_notify_g_object_notify, self, 0);
	self->priv->notify_id = _tmp7_;
	sound_indicator_update_volume (self);
}


static void sound_indicator_on_notify (SoundIndicator* self, GObject* o, GParamSpec* p) {
	gboolean _tmp0_ = FALSE;
	GParamSpec* _tmp1_ = NULL;
	const gchar* _tmp2_ = NULL;
	g_return_if_fail (self != NULL);
	_tmp1_ = p;
	_tmp2_ = _tmp1_->name;
	if (g_strcmp0 (_tmp2_, "volume") == 0) {
		_tmp0_ = TRUE;
	} else {
		GParamSpec* _tmp3_ = NULL;
		const gchar* _tmp4_ = NULL;
		_tmp3_ = p;
		_tmp4_ = _tmp3_->name;
		_tmp0_ = g_strcmp0 (_tmp4_, "is-muted") == 0;
	}
	if (_tmp0_) {
		sound_indicator_update_volume (self);
	}
}


/**
     * Called when something changes on the mixer, i.e. we connected
     * This is where we hook into the stream for changes
     */
void sound_indicator_on_state_change (SoundIndicator* self, guint new_state) {
	guint _tmp0_ = 0U;
	g_return_if_fail (self != NULL);
	_tmp0_ = new_state;
	if (_tmp0_ == ((guint) GVC_STATE_READY)) {
		sound_indicator_set_default_mixer (self);
	}
}


/**
     * Update from scroll events. turn volume up + down.
     */
gboolean sound_indicator_on_scroll_event (SoundIndicator* self, GdkEventScroll* event) {
	gboolean result = FALSE;
	GvcMixerStream* _tmp0_ = NULL;
	guint32 vol = 0U;
	GvcMixerStream* _tmp1_ = NULL;
	guint32 _tmp2_ = 0U;
	guint32 orig_vol = 0U;
	guint32 _tmp3_ = 0U;
	GdkEventScroll* _tmp4_ = NULL;
	GdkScrollDirection _tmp5_ = 0;
	gdouble max_amp = 0.0;
	GvcMixerControl* _tmp12_ = NULL;
	gdouble _tmp13_ = 0.0;
	gdouble norm = 0.0;
	GvcMixerControl* _tmp14_ = NULL;
	gdouble _tmp15_ = 0.0;
	gdouble _tmp16_ = 0.0;
	gdouble _tmp17_ = 0.0;
	guint32 _tmp19_ = 0U;
	gdouble _tmp20_ = 0.0;
	guint32 _tmp22_ = 0U;
	gdouble _tmp23_ = 0.0;
	GtkScale* _tmp25_ = NULL;
	gulong _tmp26_ = 0UL;
	GvcMixerStream* _tmp27_ = NULL;
	guint32 _tmp28_ = 0U;
	gboolean _tmp29_ = FALSE;
	GtkScale* _tmp31_ = NULL;
	gulong _tmp32_ = 0UL;
	g_return_val_if_fail (self != NULL, FALSE);
	g_return_val_if_fail (event != NULL, FALSE);
	_tmp0_ = self->priv->stream;
	g_return_val_if_fail (_tmp0_ != NULL, FALSE);
	_tmp1_ = self->priv->stream;
	_tmp2_ = gvc_mixer_stream_get_volume (_tmp1_);
	vol = _tmp2_;
	_tmp3_ = vol;
	orig_vol = _tmp3_;
	_tmp4_ = event;
	_tmp5_ = _tmp4_->direction;
	switch (_tmp5_) {
		case GDK_SCROLL_UP:
		{
			guint32 _tmp6_ = 0U;
			gdouble _tmp7_ = 0.0;
			_tmp6_ = vol;
			_tmp7_ = self->priv->step_size;
			vol = _tmp6_ + ((guint32) _tmp7_);
			break;
		}
		case GDK_SCROLL_DOWN:
		{
			guint32 _tmp8_ = 0U;
			gdouble _tmp9_ = 0.0;
			guint32 _tmp10_ = 0U;
			guint32 _tmp11_ = 0U;
			_tmp8_ = vol;
			_tmp9_ = self->priv->step_size;
			vol = _tmp8_ - ((guint32) _tmp9_);
			_tmp10_ = vol;
			_tmp11_ = orig_vol;
			if (_tmp10_ > _tmp11_) {
				vol = (guint32) 0;
			}
			break;
		}
		default:
		{
			result = FALSE;
			return result;
		}
	}
	_tmp12_ = self->priv->_mixer;
	_tmp13_ = gvc_mixer_control_get_vol_max_amplified (_tmp12_);
	max_amp = _tmp13_;
	_tmp14_ = self->priv->_mixer;
	_tmp15_ = gvc_mixer_control_get_vol_max_norm (_tmp14_);
	norm = _tmp15_;
	_tmp16_ = max_amp;
	_tmp17_ = norm;
	if (_tmp16_ < _tmp17_) {
		gdouble _tmp18_ = 0.0;
		_tmp18_ = norm;
		max_amp = _tmp18_;
	}
	_tmp19_ = vol;
	_tmp20_ = max_amp;
	if (((gdouble) _tmp19_) > _tmp20_) {
		gdouble _tmp21_ = 0.0;
		_tmp21_ = max_amp;
		vol = (guint32) _tmp21_;
	}
	_tmp22_ = vol;
	_tmp23_ = norm;
	if (((gdouble) _tmp22_) >= _tmp23_) {
		gdouble _tmp24_ = 0.0;
		_tmp24_ = norm;
		vol = (guint32) _tmp24_;
	}
	_tmp25_ = self->priv->volume_scale;
	_tmp26_ = self->priv->scale_id;
	g_signal_handler_block (_tmp25_, _tmp26_);
	_tmp27_ = self->priv->stream;
	_tmp28_ = vol;
	_tmp29_ = gvc_mixer_stream_set_volume (_tmp27_, _tmp28_);
	if (_tmp29_) {
		GvcMixerStream* _tmp30_ = NULL;
		_tmp30_ = self->priv->stream;
		gvc_mixer_stream_push_volume (_tmp30_);
	}
	_tmp31_ = self->priv->volume_scale;
	_tmp32_ = self->priv->scale_id;
	g_signal_handler_unblock (_tmp31_, _tmp32_);
	result = TRUE;
	return result;
}


/**
     * Update our icon when something changed (volume/mute)
     */
void sound_indicator_update_volume (SoundIndicator* self) {
	gdouble vol_norm = 0.0;
	GvcMixerControl* _tmp0_ = NULL;
	gdouble _tmp1_ = 0.0;
	guint32 vol = 0U;
	GvcMixerStream* _tmp2_ = NULL;
	guint32 _tmp3_ = 0U;
	gint n = 0;
	guint32 _tmp4_ = 0U;
	gdouble _tmp5_ = 0.0;
	gdouble _tmp6_ = 0.0;
	gchar* image_name = NULL;
	gboolean _tmp7_ = FALSE;
	GvcMixerStream* _tmp8_ = NULL;
	gboolean _tmp9_ = FALSE;
	GtkImage* _tmp16_ = NULL;
	const gchar* _tmp17_ = NULL;
	gdouble vol_max = 0.0;
	GvcMixerControl* _tmp18_ = NULL;
	gdouble _tmp19_ = 0.0;
	gdouble _tmp20_ = 0.0;
	gfloat pct = 0.0F;
	guint32 _tmp21_ = 0U;
	gdouble _tmp22_ = 0.0;
	guint ipct = 0U;
	gfloat _tmp23_ = 0.0F;
	GtkImage* _tmp24_ = NULL;
	guint _tmp25_ = 0U;
	gchar* _tmp26_ = NULL;
	gchar* _tmp27_ = NULL;
	gchar* _tmp28_ = NULL;
	gchar* _tmp29_ = NULL;
	GtkScale* _tmp30_ = NULL;
	gulong _tmp31_ = 0UL;
	GtkScale* _tmp32_ = NULL;
	gdouble _tmp33_ = 0.0;
	guint32 _tmp34_ = 0U;
	gdouble _tmp35_ = 0.0;
	GtkScale* _tmp40_ = NULL;
	GtkAdjustment* _tmp41_ = NULL;
	gdouble _tmp42_ = 0.0;
	GtkScale* _tmp43_ = NULL;
	gulong _tmp44_ = 0UL;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->priv->_mixer;
	_tmp1_ = gvc_mixer_control_get_vol_max_norm (_tmp0_);
	vol_norm = _tmp1_;
	_tmp2_ = self->priv->stream;
	_tmp3_ = gvc_mixer_stream_get_volume (_tmp2_);
	vol = _tmp3_;
	_tmp4_ = vol;
	_tmp5_ = vol_norm;
	_tmp6_ = floor ((3 * _tmp4_) / _tmp5_);
	n = ((gint) _tmp6_) + 1;
	_tmp8_ = self->priv->stream;
	_tmp9_ = gvc_mixer_stream_get_is_muted (_tmp8_);
	if (_tmp9_) {
		_tmp7_ = TRUE;
	} else {
		guint32 _tmp10_ = 0U;
		_tmp10_ = vol;
		_tmp7_ = _tmp10_ <= ((guint32) 0);
	}
	if (_tmp7_) {
		gchar* _tmp11_ = NULL;
		_tmp11_ = g_strdup ("audio-volume-muted-symbolic");
		_g_free0 (image_name);
		image_name = _tmp11_;
	} else {
		gint _tmp12_ = 0;
		_tmp12_ = n;
		switch (_tmp12_) {
			case 1:
			{
				gchar* _tmp13_ = NULL;
				_tmp13_ = g_strdup ("audio-volume-low-symbolic");
				_g_free0 (image_name);
				image_name = _tmp13_;
				break;
			}
			case 2:
			{
				gchar* _tmp14_ = NULL;
				_tmp14_ = g_strdup ("audio-volume-medium-symbolic");
				_g_free0 (image_name);
				image_name = _tmp14_;
				break;
			}
			default:
			{
				gchar* _tmp15_ = NULL;
				_tmp15_ = g_strdup ("audio-volume-high-symbolic");
				_g_free0 (image_name);
				image_name = _tmp15_;
				break;
			}
		}
	}
	_tmp16_ = self->priv->_widget;
	_tmp17_ = image_name;
	gtk_image_set_from_icon_name (_tmp16_, _tmp17_, GTK_ICON_SIZE_MENU);
	_tmp18_ = self->priv->_mixer;
	_tmp19_ = gvc_mixer_control_get_vol_max_amplified (_tmp18_);
	vol_max = _tmp19_;
	_tmp20_ = vol_max;
	self->priv->step_size = _tmp20_ / 20;
	_tmp21_ = vol;
	_tmp22_ = vol_norm;
	pct = (((gfloat) _tmp21_) / ((gfloat) _tmp22_)) * 100;
	_tmp23_ = pct;
	ipct = (guint) _tmp23_;
	_tmp24_ = self->priv->_widget;
	_tmp25_ = ipct;
	_tmp26_ = g_strdup_printf ("%u", _tmp25_);
	_tmp27_ = _tmp26_;
	_tmp28_ = g_strconcat (_tmp27_, "%", NULL);
	_tmp29_ = _tmp28_;
	gtk_widget_set_tooltip_text ((GtkWidget*) _tmp24_, _tmp29_);
	_g_free0 (_tmp29_);
	_g_free0 (_tmp27_);
	_tmp30_ = self->priv->volume_scale;
	_tmp31_ = self->priv->scale_id;
	g_signal_handler_block (_tmp30_, _tmp31_);
	_tmp32_ = self->priv->volume_scale;
	_tmp33_ = vol_norm;
	gtk_range_set_range ((GtkRange*) _tmp32_, (gdouble) 0, _tmp33_);
	_tmp34_ = vol;
	_tmp35_ = vol_norm;
	if (((gdouble) _tmp34_) > _tmp35_) {
		GtkScale* _tmp36_ = NULL;
		guint32 _tmp37_ = 0U;
		_tmp36_ = self->priv->volume_scale;
		_tmp37_ = vol;
		gtk_range_set_value ((GtkRange*) _tmp36_, (gdouble) _tmp37_);
	} else {
		GtkScale* _tmp38_ = NULL;
		guint32 _tmp39_ = 0U;
		_tmp38_ = self->priv->volume_scale;
		_tmp39_ = vol;
		gtk_range_set_value ((GtkRange*) _tmp38_, (gdouble) _tmp39_);
	}
	_tmp40_ = self->priv->volume_scale;
	_tmp41_ = gtk_range_get_adjustment ((GtkRange*) _tmp40_);
	_tmp42_ = self->priv->step_size;
	gtk_adjustment_set_page_increment (_tmp41_, _tmp42_);
	_tmp43_ = self->priv->volume_scale;
	_tmp44_ = self->priv->scale_id;
	g_signal_handler_unblock (_tmp43_, _tmp44_);
	gtk_widget_show_all ((GtkWidget*) self);
	gtk_widget_queue_draw ((GtkWidget*) self);
	_g_free0 (image_name);
}


/**
     * The scale changed value - update the stream volume to match
     */
static void sound_indicator_on_scale_changed (SoundIndicator* self) {
	gboolean _tmp0_ = FALSE;
	GvcMixerStream* _tmp1_ = NULL;
	gdouble scale_value = 0.0;
	GtkScale* _tmp3_ = NULL;
	gdouble _tmp4_ = 0.0;
	GtkScale* _tmp5_ = NULL;
	gulong _tmp6_ = 0UL;
	GvcMixerStream* _tmp7_ = NULL;
	gdouble _tmp8_ = 0.0;
	gboolean _tmp9_ = FALSE;
	GtkScale* _tmp11_ = NULL;
	gulong _tmp12_ = 0UL;
	g_return_if_fail (self != NULL);
	_tmp1_ = self->priv->stream;
	if (_tmp1_ == NULL) {
		_tmp0_ = TRUE;
	} else {
		GvcMixerControl* _tmp2_ = NULL;
		_tmp2_ = self->priv->_mixer;
		_tmp0_ = _tmp2_ == NULL;
	}
	if (_tmp0_) {
		return;
	}
	_tmp3_ = self->priv->volume_scale;
	_tmp4_ = gtk_range_get_value ((GtkRange*) _tmp3_);
	scale_value = _tmp4_;
	_tmp5_ = self->priv->volume_scale;
	_tmp6_ = self->priv->scale_id;
	g_signal_handler_block (_tmp5_, _tmp6_);
	_tmp7_ = self->priv->stream;
	_tmp8_ = scale_value;
	_tmp9_ = gvc_mixer_stream_set_volume (_tmp7_, (guint32) _tmp8_);
	if (_tmp9_) {
		GvcMixerStream* _tmp10_ = NULL;
		_tmp10_ = self->priv->stream;
		gvc_mixer_stream_push_volume (_tmp10_);
	}
	_tmp11_ = self->priv->volume_scale;
	_tmp12_ = self->priv->scale_id;
	g_signal_handler_unblock (_tmp11_, _tmp12_);
}


/**
     * Adjust the volume by a given +/- increment and bounds limit it
     */
static void sound_indicator_adjust_volume_increment (SoundIndicator* self, gdouble increment) {
	gboolean _tmp0_ = FALSE;
	GvcMixerStream* _tmp1_ = NULL;
	gint32 vol = 0;
	GvcMixerStream* _tmp3_ = NULL;
	guint32 _tmp4_ = 0U;
	gdouble max_norm = 0.0;
	GvcMixerControl* _tmp5_ = NULL;
	gdouble _tmp6_ = 0.0;
	gint32 _tmp7_ = 0;
	gdouble _tmp8_ = 0.0;
	gint32 _tmp9_ = 0;
	GtkScale* _tmp13_ = NULL;
	gulong _tmp14_ = 0UL;
	GvcMixerStream* _tmp15_ = NULL;
	gint32 _tmp16_ = 0;
	gboolean _tmp17_ = FALSE;
	GtkScale* _tmp19_ = NULL;
	gulong _tmp20_ = 0UL;
	g_return_if_fail (self != NULL);
	_tmp1_ = self->priv->stream;
	if (_tmp1_ == NULL) {
		_tmp0_ = TRUE;
	} else {
		GvcMixerControl* _tmp2_ = NULL;
		_tmp2_ = self->priv->_mixer;
		_tmp0_ = _tmp2_ == NULL;
	}
	if (_tmp0_) {
		return;
	}
	_tmp3_ = self->priv->stream;
	_tmp4_ = gvc_mixer_stream_get_volume (_tmp3_);
	vol = (gint32) _tmp4_;
	_tmp5_ = self->priv->_mixer;
	_tmp6_ = gvc_mixer_control_get_vol_max_norm (_tmp5_);
	max_norm = _tmp6_;
	_tmp7_ = vol;
	_tmp8_ = increment;
	vol = _tmp7_ + ((gint32) _tmp8_);
	_tmp9_ = vol;
	if (_tmp9_ < ((gint32) 0)) {
		vol = (gint32) 0;
	} else {
		gint32 _tmp10_ = 0;
		gdouble _tmp11_ = 0.0;
		_tmp10_ = vol;
		_tmp11_ = max_norm;
		if (((gdouble) _tmp10_) > _tmp11_) {
			gdouble _tmp12_ = 0.0;
			_tmp12_ = max_norm;
			vol = (gint32) _tmp12_;
		}
	}
	_tmp13_ = self->priv->volume_scale;
	_tmp14_ = self->priv->scale_id;
	g_signal_handler_block (_tmp13_, _tmp14_);
	_tmp15_ = self->priv->stream;
	_tmp16_ = vol;
	_tmp17_ = gvc_mixer_stream_set_volume (_tmp15_, (guint32) _tmp16_);
	if (_tmp17_) {
		GvcMixerStream* _tmp18_ = NULL;
		_tmp18_ = self->priv->stream;
		gvc_mixer_stream_push_volume (_tmp18_);
	}
	_tmp19_ = self->priv->volume_scale;
	_tmp20_ = self->priv->scale_id;
	g_signal_handler_unblock (_tmp19_, _tmp20_);
}


GtkImage* sound_indicator_get_widget (SoundIndicator* self) {
	GtkImage* result;
	GtkImage* _tmp0_ = NULL;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = self->priv->_widget;
	result = _tmp0_;
	return result;
}


void sound_indicator_set_widget (SoundIndicator* self, GtkImage* value) {
	GtkImage* _tmp0_ = NULL;
	GtkImage* _tmp1_ = NULL;
	g_return_if_fail (self != NULL);
	_tmp0_ = value;
	_tmp1_ = _g_object_ref0 (_tmp0_);
	_g_object_unref0 (self->priv->_widget);
	self->priv->_widget = _tmp1_;
	g_object_notify ((GObject *) self, "widget");
}


GvcMixerControl* sound_indicator_get_mixer (SoundIndicator* self) {
	GvcMixerControl* result;
	GvcMixerControl* _tmp0_ = NULL;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = self->priv->_mixer;
	result = _tmp0_;
	return result;
}


void sound_indicator_set_mixer (SoundIndicator* self, GvcMixerControl* value) {
	GvcMixerControl* _tmp0_ = NULL;
	GvcMixerControl* _tmp1_ = NULL;
	g_return_if_fail (self != NULL);
	_tmp0_ = value;
	_tmp1_ = _g_object_ref0 (_tmp0_);
	_g_object_unref0 (self->priv->_mixer);
	self->priv->_mixer = _tmp1_;
	g_object_notify ((GObject *) self, "mixer");
}


static void sound_indicator_class_init (SoundIndicatorClass * klass) {
	sound_indicator_parent_class = g_type_class_peek_parent (klass);
	g_type_class_add_private (klass, sizeof (SoundIndicatorPrivate));
	G_OBJECT_CLASS (klass)->get_property = _vala_sound_indicator_get_property;
	G_OBJECT_CLASS (klass)->set_property = _vala_sound_indicator_set_property;
	G_OBJECT_CLASS (klass)->finalize = sound_indicator_finalize;
	/** Current image to display */
	g_object_class_install_property (G_OBJECT_CLASS (klass), SOUND_INDICATOR_WIDGET, g_param_spec_object ("widget", "widget", "widget", gtk_image_get_type (), G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_READABLE | G_PARAM_WRITABLE));
	/** Our mixer */
	g_object_class_install_property (G_OBJECT_CLASS (klass), SOUND_INDICATOR_MIXER, g_param_spec_object ("mixer", "mixer", "mixer", gvc_mixer_control_get_type (), G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_READABLE | G_PARAM_WRITABLE));
}


static void sound_indicator_instance_init (SoundIndicator * self) {
	self->priv = SOUND_INDICATOR_GET_PRIVATE (self);
}


static void sound_indicator_finalize (GObject* obj) {
	SoundIndicator * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, TYPE_SOUND_INDICATOR, SoundIndicator);
	_g_object_unref0 (self->priv->_widget);
	_g_object_unref0 (self->priv->_mixer);
	_g_object_unref0 (self->priv->stream);
	_g_object_unref0 (self->ebox);
	_g_object_unref0 (self->popover);
	_g_object_unref0 (self->priv->volume_scale);
	G_OBJECT_CLASS (sound_indicator_parent_class)->finalize (obj);
}


GType sound_indicator_get_type (void) {
	return sound_indicator_type_id;
}


GType sound_indicator_register_type (GTypeModule * module) {
	static const GTypeInfo g_define_type_info = { sizeof (SoundIndicatorClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) sound_indicator_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (SoundIndicator), 0, (GInstanceInitFunc) sound_indicator_instance_init, NULL };
	sound_indicator_type_id = g_type_module_register_type (module, gtk_bin_get_type (), "SoundIndicator", &g_define_type_info, 0);
	return sound_indicator_type_id;
}


static void _vala_sound_indicator_get_property (GObject * object, guint property_id, GValue * value, GParamSpec * pspec) {
	SoundIndicator * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (object, TYPE_SOUND_INDICATOR, SoundIndicator);
	switch (property_id) {
		case SOUND_INDICATOR_WIDGET:
		g_value_set_object (value, sound_indicator_get_widget (self));
		break;
		case SOUND_INDICATOR_MIXER:
		g_value_set_object (value, sound_indicator_get_mixer (self));
		break;
		default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
	}
}


static void _vala_sound_indicator_set_property (GObject * object, guint property_id, const GValue * value, GParamSpec * pspec) {
	SoundIndicator * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (object, TYPE_SOUND_INDICATOR, SoundIndicator);
	switch (property_id) {
		case SOUND_INDICATOR_WIDGET:
		sound_indicator_set_widget (self, g_value_get_object (value));
		break;
		case SOUND_INDICATOR_MIXER:
		sound_indicator_set_mixer (self, g_value_get_object (value));
		break;
		default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
	}
}



