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

/*
* Copyright (c) 2009-2013 Yorba Foundation
*               2017-2018 elementary, Inc. (https://elementary.io)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program; if not, write to the
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301 USA
*/

#include "io.elementary.photos.h"
#include <gtk/gtk.h>
#include <gio/gio.h>
#include <glib.h>
#include <glib-object.h>
#include <stdlib.h>
#include <string.h>
#include <granite.h>
#include <float.h>
#include <math.h>
#include <glib/gi18n-lib.h>
#include <gdk/gdk.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

enum  {
	PROGRESS_DIALOG_0_PROPERTY,
	PROGRESS_DIALOG_NUM_PROPERTIES
};
static GParamSpec* progress_dialog_properties[PROGRESS_DIALOG_NUM_PROPERTIES];
#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))
#define _g_free0(var) (var = (g_free (var), NULL))
#define _vala_assert(expr, msg) if G_LIKELY (expr) ; else g_assertion_message_expr (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, msg);
#define _vala_return_if_fail(expr, msg) if G_LIKELY (expr) ; else { g_return_if_fail_warning (G_LOG_DOMAIN, G_STRFUNC, msg); return; }
#define _vala_return_val_if_fail(expr, msg, val) if G_LIKELY (expr) ; else { g_return_if_fail_warning (G_LOG_DOMAIN, G_STRFUNC, msg); return val; }
#define _vala_warn_if_fail(expr, msg) if G_LIKELY (expr) ; else g_warn_message (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, msg);

struct _ProgressDialogPrivate {
	GtkProgressBar* progress_bar;
	GtkButton* cancel_button;
	GCancellable* cancellable;
	guint64 last_count;
	gint update_every;
	gint minimum_on_screen_time_msec;
	gint64 time_started;
};

static gint ProgressDialog_private_offset;
static gpointer progress_dialog_parent_class = NULL;

static void progress_dialog_on_cancel (ProgressDialog* self);
static void _progress_dialog_on_cancel_gtk_button_clicked (GtkButton* _sender,
                                                    gpointer self);
static gboolean progress_dialog_on_window_closed (ProgressDialog* self);
static gboolean _progress_dialog_on_window_closed_gtk_widget_delete_event (GtkWidget* _sender,
                                                                    GdkEventAny* event,
                                                                    gpointer self);
static void progress_dialog_real_realize (GtkWidget* base);
static void progress_dialog_maybe_show_all (ProgressDialog* self,
                                     gdouble pct);
static void progress_dialog_finalize (GObject * obj);
static GType progress_dialog_get_type_once (void);

static inline gpointer
progress_dialog_get_instance_private (ProgressDialog* self)
{
	return G_STRUCT_MEMBER_P (self, ProgressDialog_private_offset);
}

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

static void
_progress_dialog_on_cancel_gtk_button_clicked (GtkButton* _sender,
                                               gpointer self)
{
	progress_dialog_on_cancel ((ProgressDialog*) self);
}

static gboolean
_progress_dialog_on_window_closed_gtk_widget_delete_event (GtkWidget* _sender,
                                                           GdkEventAny* event,
                                                           gpointer self)
{
	gboolean result;
	result = progress_dialog_on_window_closed ((ProgressDialog*) self);
	return result;
}

ProgressDialog*
progress_dialog_construct (GType object_type,
                           GtkWindow* owner,
                           const gchar* text,
                           GCancellable* cancellable)
{
	ProgressDialog * self = NULL;
	GCancellable* _tmp0_;
	GtkProgressBar* _tmp1_;
	GtkProgressBar* _tmp2_;
	GtkProgressBar* _tmp3_;
	GtkLabel* primary_text_label = NULL;
	GtkLabel* _tmp4_;
	GtkLabel* _tmp5_;
	GtkLabel* _tmp6_;
	GtkStyleContext* _tmp7_;
	GtkGrid* grid = NULL;
	GtkGrid* _tmp8_;
	GtkGrid* _tmp9_;
	GtkGrid* _tmp10_;
	GtkGrid* _tmp11_;
	GtkGrid* _tmp12_;
	GtkGrid* _tmp13_;
	GtkLabel* _tmp14_;
	GtkGrid* _tmp15_;
	GtkProgressBar* _tmp16_;
	GtkBox* _tmp17_;
	GtkGrid* _tmp18_;
	g_return_val_if_fail (text != NULL, NULL);
	self = (ProgressDialog*) granite_dialog_construct (object_type);
	_tmp0_ = _g_object_ref0 (cancellable);
	_g_object_unref0 (self->priv->cancellable);
	self->priv->cancellable = _tmp0_;
	gtk_window_set_deletable ((GtkWindow*) self, FALSE);
	gtk_window_set_resizable ((GtkWindow*) self, FALSE);
	gtk_window_set_modal ((GtkWindow*) self, TRUE);
	if (owner != NULL) {
		gtk_window_set_transient_for ((GtkWindow*) self, owner);
	}
	_tmp1_ = (GtkProgressBar*) gtk_progress_bar_new ();
	g_object_ref_sink (_tmp1_);
	_g_object_unref0 (self->priv->progress_bar);
	self->priv->progress_bar = _tmp1_;
	_tmp2_ = self->priv->progress_bar;
	g_object_set ((GtkWidget*) _tmp2_, "width-request", 300, NULL);
	_tmp3_ = self->priv->progress_bar;
	gtk_progress_bar_set_show_text (_tmp3_, TRUE);
	_tmp4_ = (GtkLabel*) gtk_label_new (text);
	g_object_ref_sink (_tmp4_);
	primary_text_label = _tmp4_;
	_tmp5_ = primary_text_label;
	gtk_label_set_xalign (_tmp5_, (gfloat) 0);
	_tmp6_ = primary_text_label;
	_tmp7_ = gtk_widget_get_style_context ((GtkWidget*) _tmp6_);
	gtk_style_context_add_class (_tmp7_, GRANITE_STYLE_CLASS_PRIMARY_LABEL);
	_tmp8_ = (GtkGrid*) gtk_grid_new ();
	g_object_ref_sink (_tmp8_);
	grid = _tmp8_;
	_tmp9_ = grid;
	gtk_orientable_set_orientation ((GtkOrientable*) _tmp9_, GTK_ORIENTATION_VERTICAL);
	_tmp10_ = grid;
	gtk_grid_set_row_spacing (_tmp10_, 12);
	_tmp11_ = grid;
	g_object_set ((GtkWidget*) _tmp11_, "margin", 12, NULL);
	_tmp12_ = grid;
	gtk_widget_set_margin_top ((GtkWidget*) _tmp12_, 0);
	_tmp13_ = grid;
	_tmp14_ = primary_text_label;
	gtk_container_add ((GtkContainer*) _tmp13_, (GtkWidget*) _tmp14_);
	_tmp15_ = grid;
	_tmp16_ = self->priv->progress_bar;
	gtk_container_add ((GtkContainer*) _tmp15_, (GtkWidget*) _tmp16_);
	_tmp17_ = gtk_dialog_get_content_area ((GtkDialog*) self);
	_tmp18_ = grid;
	gtk_container_add ((GtkContainer*) _tmp17_, (GtkWidget*) _tmp18_);
	if (cancellable != NULL) {
		GtkWidget* _tmp19_;
		GtkButton* _tmp20_;
		GtkButton* _tmp21_;
		_tmp19_ = gtk_dialog_add_button ((GtkDialog*) self, _ ("_Cancel"), (gint) GTK_RESPONSE_CANCEL);
		_tmp20_ = _g_object_ref0 (G_TYPE_CHECK_INSTANCE_CAST (_tmp19_, gtk_button_get_type (), GtkButton));
		_g_object_unref0 (self->priv->cancel_button);
		self->priv->cancel_button = _tmp20_;
		_tmp21_ = self->priv->cancel_button;
		g_signal_connect_object (_tmp21_, "clicked", (GCallback) _progress_dialog_on_cancel_gtk_button_clicked, self, 0);
		g_signal_connect_object ((GtkWidget*) self, "delete-event", (GCallback) _progress_dialog_on_window_closed_gtk_widget_delete_event, self, 0);
	}
	self->priv->time_started = now_ms ();
	_g_object_unref0 (grid);
	_g_object_unref0 (primary_text_label);
	return self;
}

ProgressDialog*
progress_dialog_new (GtkWindow* owner,
                     const gchar* text,
                     GCancellable* cancellable)
{
	return progress_dialog_construct (TYPE_PROGRESS_DIALOG, owner, text, cancellable);
}

static void
progress_dialog_real_realize (GtkWidget* base)
{
	ProgressDialog * self;
	GCancellable* _tmp0_;
	self = (ProgressDialog*) base;
	GTK_WIDGET_CLASS (progress_dialog_parent_class)->realize ((GtkWidget*) G_TYPE_CHECK_INSTANCE_CAST (self, GRANITE_TYPE_DIALOG, GraniteDialog));
	_tmp0_ = self->priv->cancellable;
	if (_tmp0_ == NULL) {
		GdkWindow* _tmp1_;
		_tmp1_ = gtk_widget_get_window ((GtkWidget*) self);
		gdk_window_set_functions (_tmp1_, GDK_FUNC_MOVE);
	}
}

void
progress_dialog_update_display_every (ProgressDialog* self,
                                      gint update_every)
{
	g_return_if_fail (self != NULL);
	_vala_assert (update_every >= 1, "update_every >= 1");
	self->priv->update_every = update_every;
}

void
progress_dialog_set_minimum_on_screen_time_msec (ProgressDialog* self,
                                                 gint minimum_on_screen_time_msec)
{
	g_return_if_fail (self != NULL);
	self->priv->minimum_on_screen_time_msec = minimum_on_screen_time_msec;
}

void
progress_dialog_set_fraction (ProgressDialog* self,
                              gint current,
                              gint total)
{
	g_return_if_fail (self != NULL);
	progress_dialog_set_percentage (self, ((gdouble) current) / ((gdouble) total));
}

void
progress_dialog_set_percentage (ProgressDialog* self,
                                gdouble pct)
{
	GtkProgressBar* _tmp0_;
	GtkProgressBar* _tmp1_;
	gchar* _tmp2_;
	gchar* _tmp3_;
	g_return_if_fail (self != NULL);
	pct = CLAMP (pct, 0.0, 1.0);
	progress_dialog_maybe_show_all (self, pct);
	_tmp0_ = self->priv->progress_bar;
	gtk_progress_bar_set_fraction (_tmp0_, pct);
	_tmp1_ = self->priv->progress_bar;
	_tmp2_ = g_strdup_printf (_ ("%d%%"), (gint) (pct * 100.0));
	_tmp3_ = _tmp2_;
	gtk_progress_bar_set_text (_tmp1_, _tmp3_);
	_g_free0 (_tmp3_);
	granite_services_application_set_progress (pct, NULL, NULL);
}

void
progress_dialog_set_status (ProgressDialog* self,
                            const gchar* text)
{
	GtkProgressBar* _tmp0_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (text != NULL);
	_tmp0_ = self->priv->progress_bar;
	gtk_progress_bar_set_text (_tmp0_, text);
	granite_services_application_set_progress_visible (TRUE, NULL, NULL);
	gtk_widget_show_all ((GtkWidget*) self);
}

gboolean
progress_dialog_monitor (ProgressDialog* self,
                         guint64 count,
                         guint64 total,
                         gboolean do_event_loop)
{
	gboolean _tmp0_ = FALSE;
	gboolean _tmp1_ = FALSE;
	GCancellable* _tmp2_;
	gboolean keep_going = FALSE;
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	if (self->priv->last_count == G_MAXUINT64) {
		_tmp0_ = TRUE;
	} else {
		_tmp0_ = (count - self->priv->last_count) >= ((guint64) self->priv->update_every);
	}
	if (_tmp0_) {
		progress_dialog_set_percentage (self, ((gdouble) count) / ((gdouble) total));
		self->priv->last_count = count;
	}
	_tmp2_ = self->priv->cancellable;
	if (_tmp2_ != NULL) {
		GCancellable* _tmp3_;
		_tmp3_ = self->priv->cancellable;
		_tmp1_ = !g_cancellable_is_cancelled (_tmp3_);
	} else {
		_tmp1_ = TRUE;
	}
	keep_going = _tmp1_;
	if (do_event_loop) {
		spin_event_loop ();
	}
	result = keep_going;
	return result;
}

void
progress_dialog_close (ProgressDialog* self)
{
	g_return_if_fail (self != NULL);
	granite_services_application_set_progress_visible (FALSE, NULL, NULL);
	granite_services_application_set_progress (0.0, NULL, NULL);
	gtk_widget_hide ((GtkWidget*) self);
	gtk_widget_destroy ((GtkWidget*) self);
}

static gboolean
progress_dialog_on_window_closed (ProgressDialog* self)
{
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	progress_dialog_on_cancel (self);
	result = FALSE;
	return result;
}

static void
progress_dialog_on_cancel (ProgressDialog* self)
{
	GCancellable* _tmp0_;
	GtkButton* _tmp2_;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->priv->cancellable;
	if (_tmp0_ != NULL) {
		GCancellable* _tmp1_;
		_tmp1_ = self->priv->cancellable;
		g_cancellable_cancel (_tmp1_);
	}
	_tmp2_ = self->priv->cancel_button;
	gtk_widget_set_sensitive ((GtkWidget*) _tmp2_, FALSE);
}

static void
progress_dialog_maybe_show_all (ProgressDialog* self,
                                gdouble pct)
{
	gboolean _tmp0_ = FALSE;
	gboolean _tmp1_;
	gboolean _tmp2_;
	g_return_if_fail (self != NULL);
	_tmp1_ = gtk_widget_get_visible ((GtkWidget*) self);
	_tmp2_ = _tmp1_;
	if (!_tmp2_) {
		_tmp0_ = (now_ms () - self->priv->time_started) > ((gint64) self->priv->minimum_on_screen_time_msec);
	} else {
		_tmp0_ = FALSE;
	}
	if (_tmp0_) {
		gdouble pps = 0.0;
		gdouble ttc = 0.0;
		pps = (pct * 100.0) / self->priv->minimum_on_screen_time_msec;
		ttc = 100.0 / pps;
		if (ttc > ((gdouble) self->priv->minimum_on_screen_time_msec)) {
			granite_services_application_set_progress_visible (TRUE, NULL, NULL);
			gtk_widget_show_all ((GtkWidget*) self);
			spin_event_loop ();
		}
	}
}

static void
progress_dialog_class_init (ProgressDialogClass * klass,
                            gpointer klass_data)
{
	progress_dialog_parent_class = g_type_class_peek_parent (klass);
	g_type_class_adjust_private_offset (klass, &ProgressDialog_private_offset);
	((GtkWidgetClass *) klass)->realize = (void (*) (GtkWidget*)) progress_dialog_real_realize;
	G_OBJECT_CLASS (klass)->finalize = progress_dialog_finalize;
}

static void
progress_dialog_instance_init (ProgressDialog * self,
                               gpointer klass)
{
	self->priv = progress_dialog_get_instance_private (self);
	self->priv->cancel_button = NULL;
	self->priv->last_count = G_MAXUINT64;
	self->priv->update_every = 1;
	self->priv->minimum_on_screen_time_msec = 500;
}

static void
progress_dialog_finalize (GObject * obj)
{
	ProgressDialog * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, TYPE_PROGRESS_DIALOG, ProgressDialog);
	_g_object_unref0 (self->priv->progress_bar);
	_g_object_unref0 (self->priv->cancel_button);
	_g_object_unref0 (self->priv->cancellable);
	G_OBJECT_CLASS (progress_dialog_parent_class)->finalize (obj);
}

static GType
progress_dialog_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (ProgressDialogClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) progress_dialog_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (ProgressDialog), 0, (GInstanceInitFunc) progress_dialog_instance_init, NULL };
	GType progress_dialog_type_id;
	progress_dialog_type_id = g_type_register_static (GRANITE_TYPE_DIALOG, "ProgressDialog", &g_define_type_info, 0);
	ProgressDialog_private_offset = g_type_add_instance_private (progress_dialog_type_id, sizeof (ProgressDialogPrivate));
	return progress_dialog_type_id;
}

GType
progress_dialog_get_type (void)
{
	static volatile gsize progress_dialog_type_id__once = 0;
	if (g_once_init_enter (&progress_dialog_type_id__once)) {
		GType progress_dialog_type_id;
		progress_dialog_type_id = progress_dialog_get_type_once ();
		g_once_init_leave (&progress_dialog_type_id__once, progress_dialog_type_id);
	}
	return progress_dialog_type_id__once;
}

