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

#include <gtk/gtk.h>
#include <glib-object.h>
#include <stdlib.h>
#include <string.h>
#include <glib.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
#include <cairo-gobject.h>
#include <float.h>
#include <math.h>
#include <gdk/gdk.h>

#define TOOTLE_WIDGETS_ATTACHMENT_TYPE_PICTURE (tootle_widgets_attachment_picture_get_type ())
#define TOOTLE_WIDGETS_ATTACHMENT_PICTURE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TOOTLE_WIDGETS_ATTACHMENT_TYPE_PICTURE, TootleWidgetsAttachmentPicture))
#define TOOTLE_WIDGETS_ATTACHMENT_PICTURE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TOOTLE_WIDGETS_ATTACHMENT_TYPE_PICTURE, TootleWidgetsAttachmentPictureClass))
#define TOOTLE_WIDGETS_ATTACHMENT_IS_PICTURE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TOOTLE_WIDGETS_ATTACHMENT_TYPE_PICTURE))
#define TOOTLE_WIDGETS_ATTACHMENT_IS_PICTURE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TOOTLE_WIDGETS_ATTACHMENT_TYPE_PICTURE))
#define TOOTLE_WIDGETS_ATTACHMENT_PICTURE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TOOTLE_WIDGETS_ATTACHMENT_TYPE_PICTURE, TootleWidgetsAttachmentPictureClass))

typedef struct _TootleWidgetsAttachmentPicture TootleWidgetsAttachmentPicture;
typedef struct _TootleWidgetsAttachmentPictureClass TootleWidgetsAttachmentPictureClass;
typedef struct _TootleWidgetsAttachmentPicturePrivate TootleWidgetsAttachmentPicturePrivate;

#define TOOTLE_CACHE_TYPE_REFERENCE (tootle_cache_reference_get_type ())
typedef struct _TootleCacheReference TootleCacheReference;
enum  {
	TOOTLE_WIDGETS_ATTACHMENT_PICTURE_0_PROPERTY,
	TOOTLE_WIDGETS_ATTACHMENT_PICTURE_URL_PROPERTY,
	TOOTLE_WIDGETS_ATTACHMENT_PICTURE_NUM_PROPERTIES
};
static GParamSpec* tootle_widgets_attachment_picture_properties[TOOTLE_WIDGETS_ATTACHMENT_PICTURE_NUM_PROPERTIES];

#define TOOTLE_TYPE_CACHE (tootle_cache_get_type ())
#define TOOTLE_CACHE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TOOTLE_TYPE_CACHE, TootleCache))
#define TOOTLE_CACHE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TOOTLE_TYPE_CACHE, TootleCacheClass))
#define TOOTLE_IS_CACHE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TOOTLE_TYPE_CACHE))
#define TOOTLE_IS_CACHE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TOOTLE_TYPE_CACHE))
#define TOOTLE_CACHE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TOOTLE_TYPE_CACHE, TootleCacheClass))

typedef struct _TootleCache TootleCache;
typedef struct _TootleCacheClass TootleCacheClass;
#define _g_free0(var) (var = (g_free (var), NULL))
#define _tootle_cache_reference_free0(var) ((var == NULL) ? NULL : (var = (tootle_cache_reference_free (var), NULL)))
typedef void (*TootleCacheCachedResultCallback) (TootleCacheReference* _result_, gpointer user_data);
#define _cairo_surface_destroy0(var) ((var == NULL) ? NULL : (var = (cairo_surface_destroy (var), NULL)))
#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))

struct _TootleWidgetsAttachmentPicture {
	GtkDrawingArea parent_instance;
	TootleWidgetsAttachmentPicturePrivate * priv;
};

struct _TootleWidgetsAttachmentPictureClass {
	GtkDrawingAreaClass parent_class;
};

struct _TootleCacheReference {
	gchar* key;
	GdkPixbuf* data;
	gboolean loading;
};

struct _TootleWidgetsAttachmentPicturePrivate {
	gchar* _url;
	TootleCacheReference* cached;
};

static gint TootleWidgetsAttachmentPicture_private_offset;
static gpointer tootle_widgets_attachment_picture_parent_class = NULL;
extern TootleCache* tootle_cache;

GType tootle_widgets_attachment_picture_get_type (void) G_GNUC_CONST ;
G_DEFINE_AUTOPTR_CLEANUP_FUNC (TootleWidgetsAttachmentPicture, g_object_unref)
GType tootle_cache_reference_get_type (void) G_GNUC_CONST ;
TootleCacheReference* tootle_cache_reference_dup (const TootleCacheReference* self);
void tootle_cache_reference_free (TootleCacheReference* self);
void tootle_cache_reference_copy (const TootleCacheReference* self,
                                  TootleCacheReference* dest);
void tootle_cache_reference_destroy (TootleCacheReference* self);
GType tootle_cache_get_type (void) G_GNUC_CONST ;
G_DEFINE_AUTOPTR_CLEANUP_FUNC (TootleCache, g_object_unref)
void tootle_cache_unload (TootleCache* self,
                          TootleCacheReference** r);
TootleWidgetsAttachmentPicture* tootle_widgets_attachment_picture_new (const gchar* url);
TootleWidgetsAttachmentPicture* tootle_widgets_attachment_picture_construct (GType object_type,
                                                                             const gchar* url);
void tootle_widgets_attachment_picture_on_request (TootleWidgetsAttachmentPicture* self);
static void tootle_widgets_attachment_picture_on_redraw (TootleWidgetsAttachmentPicture* self);
void tootle_cache_load (TootleCache* self,
                        const gchar* url,
                        TootleCacheCachedResultCallback cb,
                        gpointer cb_target,
                        GDestroyNotify cb_target_destroy_notify);
const gchar* tootle_widgets_attachment_picture_get_url (TootleWidgetsAttachmentPicture* self);
static void tootle_widgets_attachment_picture_on_cache_update (TootleWidgetsAttachmentPicture* self,
                                                        TootleCacheReference* _result_);
static void _tootle_widgets_attachment_picture_on_cache_update_tootle_cache_cached_result_callback (TootleCacheReference* _result_,
                                                                                             gpointer self);
static gfloat tootle_widgets_attachment_picture_get_ratio (TootleWidgetsAttachmentPicture* self,
                                                    gint w,
                                                    gint h);
static gboolean tootle_widgets_attachment_picture_real_draw (GtkWidget* base,
                                                      cairo_t* ctx);
void tootle_drawing_draw_rounded_rect (cairo_t* ctx,
                                       gdouble x,
                                       gdouble y,
                                       gdouble w,
                                       gdouble h,
                                       gdouble r);
void tootle_widgets_attachment_picture_set_url (TootleWidgetsAttachmentPicture* self,
                                                const gchar* value);
static GObject * tootle_widgets_attachment_picture_constructor (GType type,
                                                         guint n_construct_properties,
                                                         GObjectConstructParam * construct_properties);
static void tootle_widgets_attachment_picture_finalize (GObject * obj);
static GType tootle_widgets_attachment_picture_get_type_once (void);
static void _vala_tootle_widgets_attachment_picture_get_property (GObject * object,
                                                           guint property_id,
                                                           GValue * value,
                                                           GParamSpec * pspec);
static void _vala_tootle_widgets_attachment_picture_set_property (GObject * object,
                                                           guint property_id,
                                                           const GValue * value,
                                                           GParamSpec * pspec);
static inline gpointer _vala_memdup2 (gconstpointer mem,
                        gsize byte_size);

static inline gpointer
tootle_widgets_attachment_picture_get_instance_private (TootleWidgetsAttachmentPicture* self)
{
	return G_STRUCT_MEMBER_P (self, TootleWidgetsAttachmentPicture_private_offset);
}

TootleWidgetsAttachmentPicture*
tootle_widgets_attachment_picture_construct (GType object_type,
                                             const gchar* url)
{
	TootleWidgetsAttachmentPicture * self = NULL;
	g_return_val_if_fail (url != NULL, NULL);
	self = (TootleWidgetsAttachmentPicture*) g_object_new (object_type, "url", url, NULL);
	return self;
}

TootleWidgetsAttachmentPicture*
tootle_widgets_attachment_picture_new (const gchar* url)
{
	return tootle_widgets_attachment_picture_construct (TOOTLE_WIDGETS_ATTACHMENT_TYPE_PICTURE, url);
}

static void
_tootle_widgets_attachment_picture_on_cache_update_tootle_cache_cached_result_callback (TootleCacheReference* _result_,
                                                                                        gpointer self)
{
	tootle_widgets_attachment_picture_on_cache_update ((TootleWidgetsAttachmentPicture*) self, _result_);
}

void
tootle_widgets_attachment_picture_on_request (TootleWidgetsAttachmentPicture* self)
{
	TootleCache* _tmp0_;
	const gchar* _tmp1_;
	g_return_if_fail (self != NULL);
	_tootle_cache_reference_free0 (self->priv->cached);
	self->priv->cached = NULL;
	tootle_widgets_attachment_picture_on_redraw (self);
	_tmp0_ = tootle_cache;
	_tmp1_ = self->priv->_url;
	tootle_cache_load (_tmp0_, _tmp1_, _tootle_widgets_attachment_picture_on_cache_update_tootle_cache_cached_result_callback, g_object_ref (self), g_object_unref);
}

static gpointer
_tootle_cache_reference_dup0 (gpointer self)
{
	return self ? tootle_cache_reference_dup (self) : NULL;
}

static void
tootle_widgets_attachment_picture_on_cache_update (TootleWidgetsAttachmentPicture* self,
                                                   TootleCacheReference* _result_)
{
	TootleCacheReference* _tmp0_;
	TootleCacheReference* _tmp1_;
	g_return_if_fail (self != NULL);
	_tmp0_ = _tootle_cache_reference_dup0 (_result_);
	_tootle_cache_reference_free0 (self->priv->cached);
	self->priv->cached = _tmp0_;
	_tmp1_ = self->priv->cached;
	if (_tmp1_ != NULL) {
		TootleCacheReference* _tmp2_;
		_tmp2_ = self->priv->cached;
		gtk_widget_set_visible ((GtkWidget*) self, !(*_tmp2_).loading);
	}
	tootle_widgets_attachment_picture_on_redraw (self);
}

static void
tootle_widgets_attachment_picture_on_redraw (TootleWidgetsAttachmentPicture* self)
{
	gint w = 0;
	gint h = 0;
	g_return_if_fail (self != NULL);
	w = gtk_widget_get_allocated_width ((GtkWidget*) self);
	h = gtk_widget_get_allocated_height ((GtkWidget*) self);
	gtk_widget_queue_draw_area ((GtkWidget*) self, 0, 0, w, h);
}

static gfloat
tootle_widgets_attachment_picture_get_ratio (TootleWidgetsAttachmentPicture* self,
                                             gint w,
                                             gint h)
{
	gint ow = 0;
	TootleCacheReference* _tmp0_;
	GdkPixbuf* _tmp1_;
	gint oh = 0;
	TootleCacheReference* _tmp2_;
	GdkPixbuf* _tmp3_;
	gfloat xscale = 0.0F;
	gfloat yscale = 0.0F;
	gfloat result = 0.0F;
	g_return_val_if_fail (self != NULL, 0.0F);
	_tmp0_ = self->priv->cached;
	_tmp1_ = (*_tmp0_).data;
	ow = gdk_pixbuf_get_width (_tmp1_);
	_tmp2_ = self->priv->cached;
	_tmp3_ = (*_tmp2_).data;
	oh = gdk_pixbuf_get_height (_tmp3_);
	xscale = ((gfloat) w) / ow;
	yscale = ((gfloat) h) / oh;
	if (xscale > yscale) {
		result = xscale;
		return result;
	} else {
		result = yscale;
		return result;
	}
}

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

static gboolean
tootle_widgets_attachment_picture_real_draw (GtkWidget* base,
                                             cairo_t* ctx)
{
	TootleWidgetsAttachmentPicture * self;
	gint w = 0;
	gint h = 0;
	GtkStyleContext* style = NULL;
	GtkStyleContext* _tmp0_;
	GtkStyleContext* _tmp1_;
	gint border_radius = 0;
	GtkStyleContext* _tmp2_;
	GtkStyleContext* _tmp3_;
	GValue _tmp4_ = {0};
	GValue _tmp5_;
	gint _tmp6_;
	TootleCacheReference* _tmp7_;
	gboolean result = FALSE;
	self = (TootleWidgetsAttachmentPicture*) base;
	g_return_val_if_fail (ctx != NULL, FALSE);
	w = gtk_widget_get_allocated_width ((GtkWidget*) self);
	h = gtk_widget_get_allocated_height ((GtkWidget*) self);
	_tmp0_ = gtk_widget_get_style_context ((GtkWidget*) self);
	_tmp1_ = _g_object_ref0 (_tmp0_);
	style = _tmp1_;
	_tmp2_ = style;
	_tmp3_ = style;
	gtk_style_context_get_property (_tmp2_, GTK_STYLE_PROPERTY_BORDER_RADIUS, gtk_style_context_get_state (_tmp3_), &_tmp4_);
	_tmp5_ = _tmp4_;
	_tmp6_ = g_value_get_int (&_tmp5_);
	G_IS_VALUE (&_tmp5_) ? (g_value_unset (&_tmp5_), NULL) : NULL;
	border_radius = _tmp6_;
	_tmp7_ = self->priv->cached;
	if (_tmp7_ != NULL) {
		TootleCacheReference* _tmp8_;
		_tmp8_ = self->priv->cached;
		if (!(*_tmp8_).loading) {
			cairo_surface_t* surface = NULL;
			TootleCacheReference* _tmp9_;
			GdkPixbuf* _tmp10_;
			cairo_surface_t* _tmp11_;
			gfloat ratio = 0.0F;
			gint oh = 0;
			TootleCacheReference* _tmp12_;
			GdkPixbuf* _tmp13_;
			gfloat result_h = 0.0F;
			gfloat offset_y = 0.0F;
			gint ow = 0;
			TootleCacheReference* _tmp14_;
			GdkPixbuf* _tmp15_;
			gfloat result_w = 0.0F;
			gfloat offset_x = 0.0F;
			cairo_surface_t* _tmp16_;
			_tmp9_ = self->priv->cached;
			_tmp10_ = (*_tmp9_).data;
			_tmp11_ = gdk_cairo_surface_create_from_pixbuf (_tmp10_, 1, NULL);
			surface = _tmp11_;
			cairo_save (ctx);
			tootle_drawing_draw_rounded_rect (ctx, (gdouble) 0, (gdouble) 0, (gdouble) w, (gdouble) h, (gdouble) border_radius);
			ratio = tootle_widgets_attachment_picture_get_ratio (self, w, h);
			cairo_scale (ctx, (gdouble) ratio, (gdouble) ratio);
			_tmp12_ = self->priv->cached;
			_tmp13_ = (*_tmp12_).data;
			oh = gdk_pixbuf_get_height (_tmp13_);
			result_h = oh * ratio;
			offset_y = (h - result_h) / 2;
			_tmp14_ = self->priv->cached;
			_tmp15_ = (*_tmp14_).data;
			ow = gdk_pixbuf_get_width (_tmp15_);
			result_w = ow * ratio;
			offset_x = (w - result_w) / 2;
			cairo_translate (ctx, (gdouble) offset_x, (gdouble) offset_y);
			_tmp16_ = surface;
			cairo_set_source_surface (ctx, _tmp16_, (gdouble) 0, (gdouble) 0);
			cairo_fill (ctx);
			cairo_restore (ctx);
			_cairo_surface_destroy0 (surface);
		}
	}
	result = FALSE;
	_g_object_unref0 (style);
	return result;
}

const gchar*
tootle_widgets_attachment_picture_get_url (TootleWidgetsAttachmentPicture* self)
{
	const gchar* result;
	const gchar* _tmp0_;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = self->priv->_url;
	result = _tmp0_;
	return result;
}

void
tootle_widgets_attachment_picture_set_url (TootleWidgetsAttachmentPicture* self,
                                           const gchar* value)
{
	gchar* old_value;
	g_return_if_fail (self != NULL);
	old_value = tootle_widgets_attachment_picture_get_url (self);
	if (g_strcmp0 (value, old_value) != 0) {
		gchar* _tmp0_;
		_tmp0_ = g_strdup (value);
		_g_free0 (self->priv->_url);
		self->priv->_url = _tmp0_;
		g_object_notify_by_pspec ((GObject *) self, tootle_widgets_attachment_picture_properties[TOOTLE_WIDGETS_ATTACHMENT_PICTURE_URL_PROPERTY]);
	}
}

static GObject *
tootle_widgets_attachment_picture_constructor (GType type,
                                               guint n_construct_properties,
                                               GObjectConstructParam * construct_properties)
{
	GObject * obj;
	GObjectClass * parent_class;
	TootleWidgetsAttachmentPicture * self;
	GtkStyleContext* _tmp0_;
	parent_class = G_OBJECT_CLASS (tootle_widgets_attachment_picture_parent_class);
	obj = parent_class->constructor (type, n_construct_properties, construct_properties);
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, TOOTLE_WIDGETS_ATTACHMENT_TYPE_PICTURE, TootleWidgetsAttachmentPicture);
	gtk_widget_set_vexpand ((GtkWidget*) self, TRUE);
	gtk_widget_set_hexpand ((GtkWidget*) self, TRUE);
	_tmp0_ = gtk_widget_get_style_context ((GtkWidget*) self);
	gtk_style_context_add_class (_tmp0_, "pic");
	return obj;
}

static void
tootle_widgets_attachment_picture_class_init (TootleWidgetsAttachmentPictureClass * klass,
                                              gpointer klass_data)
{
	tootle_widgets_attachment_picture_parent_class = g_type_class_peek_parent (klass);
	g_type_class_adjust_private_offset (klass, &TootleWidgetsAttachmentPicture_private_offset);
	((GtkWidgetClass *) klass)->draw = (gboolean (*) (GtkWidget*, cairo_t*)) tootle_widgets_attachment_picture_real_draw;
	G_OBJECT_CLASS (klass)->get_property = _vala_tootle_widgets_attachment_picture_get_property;
	G_OBJECT_CLASS (klass)->set_property = _vala_tootle_widgets_attachment_picture_set_property;
	G_OBJECT_CLASS (klass)->constructor = tootle_widgets_attachment_picture_constructor;
	G_OBJECT_CLASS (klass)->finalize = tootle_widgets_attachment_picture_finalize;
	g_object_class_install_property (G_OBJECT_CLASS (klass), TOOTLE_WIDGETS_ATTACHMENT_PICTURE_URL_PROPERTY, tootle_widgets_attachment_picture_properties[TOOTLE_WIDGETS_ATTACHMENT_PICTURE_URL_PROPERTY] = g_param_spec_string ("url", "url", "url", NULL, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE | G_PARAM_WRITABLE));
}

static void
tootle_widgets_attachment_picture_instance_init (TootleWidgetsAttachmentPicture * self,
                                                 gpointer klass)
{
	self->priv = tootle_widgets_attachment_picture_get_instance_private (self);
}

static void
tootle_widgets_attachment_picture_finalize (GObject * obj)
{
	TootleWidgetsAttachmentPicture * self;
	TootleCache* _tmp0_;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, TOOTLE_WIDGETS_ATTACHMENT_TYPE_PICTURE, TootleWidgetsAttachmentPicture);
	_tmp0_ = tootle_cache;
	tootle_cache_unload (_tmp0_, &self->priv->cached);
	_g_free0 (self->priv->_url);
	_tootle_cache_reference_free0 (self->priv->cached);
	G_OBJECT_CLASS (tootle_widgets_attachment_picture_parent_class)->finalize (obj);
}

static GType
tootle_widgets_attachment_picture_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (TootleWidgetsAttachmentPictureClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) tootle_widgets_attachment_picture_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (TootleWidgetsAttachmentPicture), 0, (GInstanceInitFunc) tootle_widgets_attachment_picture_instance_init, NULL };
	GType tootle_widgets_attachment_picture_type_id;
	tootle_widgets_attachment_picture_type_id = g_type_register_static (gtk_drawing_area_get_type (), "TootleWidgetsAttachmentPicture", &g_define_type_info, 0);
	TootleWidgetsAttachmentPicture_private_offset = g_type_add_instance_private (tootle_widgets_attachment_picture_type_id, sizeof (TootleWidgetsAttachmentPicturePrivate));
	return tootle_widgets_attachment_picture_type_id;
}

GType
tootle_widgets_attachment_picture_get_type (void)
{
	static volatile gsize tootle_widgets_attachment_picture_type_id__volatile = 0;
	if (g_once_init_enter (&tootle_widgets_attachment_picture_type_id__volatile)) {
		GType tootle_widgets_attachment_picture_type_id;
		tootle_widgets_attachment_picture_type_id = tootle_widgets_attachment_picture_get_type_once ();
		g_once_init_leave (&tootle_widgets_attachment_picture_type_id__volatile, tootle_widgets_attachment_picture_type_id);
	}
	return tootle_widgets_attachment_picture_type_id__volatile;
}

static void
_vala_tootle_widgets_attachment_picture_get_property (GObject * object,
                                                      guint property_id,
                                                      GValue * value,
                                                      GParamSpec * pspec)
{
	TootleWidgetsAttachmentPicture * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (object, TOOTLE_WIDGETS_ATTACHMENT_TYPE_PICTURE, TootleWidgetsAttachmentPicture);
	switch (property_id) {
		case TOOTLE_WIDGETS_ATTACHMENT_PICTURE_URL_PROPERTY:
		g_value_set_string (value, tootle_widgets_attachment_picture_get_url (self));
		break;
		default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
	}
}

static void
_vala_tootle_widgets_attachment_picture_set_property (GObject * object,
                                                      guint property_id,
                                                      const GValue * value,
                                                      GParamSpec * pspec)
{
	TootleWidgetsAttachmentPicture * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (object, TOOTLE_WIDGETS_ATTACHMENT_TYPE_PICTURE, TootleWidgetsAttachmentPicture);
	switch (property_id) {
		case TOOTLE_WIDGETS_ATTACHMENT_PICTURE_URL_PROPERTY:
		tootle_widgets_attachment_picture_set_url (self, g_value_get_string (value));
		break;
		default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
	}
}

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

