/* baobab-treemap.c generated by valac 0.56.0, the Vala compiler
 * generated from baobab-treemap.vala, do not modify */

/* -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* Baobab - disk usage analyzer
 *
 * Copyright (C) 2008  Igalia
 * Copyright (C) 2013  Stefano Facchini <stefano.facchini@gmail.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.
 *
 * 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 St, Fifth Floor,
 * Boston, MA  02110-1301  USA
 *
 * Authors of the original code:
 *   Fabio Marzocca  <thesaltydog@gmail.com>
 *   Paolo Borelli <pborelli@katamail.com>
 *   Miguel Gomez <magomez@igalia.com>
 *   Eduardo Lima Mitev <elima@igalia.com>
 */

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

#define BAOBAB_TREEMAP_ITEM_BORDER_WIDTH 1
#define BAOBAB_TREEMAP_ITEM_PADDING 6
#define BAOBAB_TREEMAP_ITEM_TEXT_PADDING 3
#define BAOBAB_TREEMAP_ITEM_MIN_WIDTH 3
#define BAOBAB_TREEMAP_ITEM_MIN_HEIGHT 3

#define BAOBAB_TYPE_TREEMAP_ITEM (baobab_treemap_item_get_type ())
#define BAOBAB_TREEMAP_ITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), BAOBAB_TYPE_TREEMAP_ITEM, BaobabTreemapItem))
#define BAOBAB_TREEMAP_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), BAOBAB_TYPE_TREEMAP_ITEM, BaobabTreemapItemClass))
#define BAOBAB_IS_TREEMAP_ITEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), BAOBAB_TYPE_TREEMAP_ITEM))
#define BAOBAB_IS_TREEMAP_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), BAOBAB_TYPE_TREEMAP_ITEM))
#define BAOBAB_TREEMAP_ITEM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), BAOBAB_TYPE_TREEMAP_ITEM, BaobabTreemapItemClass))

typedef struct _BaobabTreemapItem BaobabTreemapItem;
typedef struct _BaobabTreemapItemClass BaobabTreemapItemClass;
typedef struct _BaobabTreemapItemPrivate BaobabTreemapItemPrivate;
enum  {
	BAOBAB_TREEMAP_0_PROPERTY,
	BAOBAB_TREEMAP_NUM_PROPERTIES
};
static GParamSpec* baobab_treemap_properties[BAOBAB_TREEMAP_NUM_PROPERTIES];
#define _baobab_chart_item_unref0(var) ((var == NULL) ? NULL : (var = (baobab_chart_item_unref (var), NULL)))
#define _g_free0(var) (var = (g_free (var), NULL))
#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))

struct _BaobabTreemapItem {
	BaobabChartItem parent_instance;
	BaobabTreemapItemPrivate * priv;
	cairo_rectangle_t cr_rect;
};

struct _BaobabTreemapItemClass {
	BaobabChartItemClass parent_class;
};

struct _BaobabTreemapPrivate {
	guint max_visible_depth;
	gboolean more_visible_children;
};

static gpointer baobab_treemap_item_parent_class = NULL;
static gint BaobabTreemap_private_offset;
static gpointer baobab_treemap_parent_class = NULL;

VALA_EXTERN GType baobab_treemap_item_get_type (void) G_GNUC_CONST ;
VALA_EXTERN BaobabTreemapItem* baobab_treemap_item_new (void);
VALA_EXTERN BaobabTreemapItem* baobab_treemap_item_construct (GType object_type);
static void baobab_treemap_item_finalize (BaobabChartItem * obj);
static GType baobab_treemap_item_get_type_once (void);
static BaobabChartItem* baobab_treemap_real_create_new_chartitem (BaobabChart* base);
static void baobab_treemap_draw_rectangle (BaobabTreemap* self,
                                    cairo_t* cr,
                                    gdouble x,
                                    gdouble y,
                                    gdouble width,
                                    gdouble height,
                                    GdkRGBA* fill_color,
                                    const gchar* text,
                                    gboolean show_text);
static void baobab_treemap_real_draw_item (BaobabChart* base,
                                    cairo_t* cr,
                                    BaobabChartItem* item,
                                    gboolean highlighted);
static void baobab_treemap_real_calculate_item_geometry (BaobabChart* base,
                                                  BaobabChartItem* item);
static void baobab_treemap_real_get_item_rectangle (BaobabChart* base,
                                             BaobabChartItem* item);
static gboolean baobab_treemap_real_is_point_over_item (BaobabChart* base,
                                                 BaobabChartItem* item,
                                                 gdouble x,
                                                 gdouble y);
static gboolean baobab_treemap_real_can_zoom_out (BaobabChart* base);
static gboolean baobab_treemap_real_can_zoom_in (BaobabChart* base);
static void baobab_treemap_finalize (GObject * obj);
static GType baobab_treemap_get_type_once (void);

BaobabTreemapItem*
baobab_treemap_item_construct (GType object_type)
{
	BaobabTreemapItem* self = NULL;
	self = (BaobabTreemapItem*) baobab_chart_item_construct (object_type);
	return self;
}

BaobabTreemapItem*
baobab_treemap_item_new (void)
{
	return baobab_treemap_item_construct (BAOBAB_TYPE_TREEMAP_ITEM);
}

static void
baobab_treemap_item_class_init (BaobabTreemapItemClass * klass,
                                gpointer klass_data)
{
	baobab_treemap_item_parent_class = g_type_class_peek_parent (klass);
	((BaobabChartItemClass *) klass)->finalize = baobab_treemap_item_finalize;
}

static void
baobab_treemap_item_instance_init (BaobabTreemapItem * self,
                                   gpointer klass)
{
}

static void
baobab_treemap_item_finalize (BaobabChartItem * obj)
{
	BaobabTreemapItem * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, BAOBAB_TYPE_TREEMAP_ITEM, BaobabTreemapItem);
	BAOBAB_CHART_ITEM_CLASS (baobab_treemap_item_parent_class)->finalize (obj);
}

static GType
baobab_treemap_item_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (BaobabTreemapItemClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) baobab_treemap_item_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (BaobabTreemapItem), 0, (GInstanceInitFunc) baobab_treemap_item_instance_init, NULL };
	GType baobab_treemap_item_type_id;
	baobab_treemap_item_type_id = g_type_register_static (BAOBAB_TYPE_CHART_ITEM, "BaobabTreemapItem", &g_define_type_info, 0);
	return baobab_treemap_item_type_id;
}

GType
baobab_treemap_item_get_type (void)
{
	static volatile gsize baobab_treemap_item_type_id__once = 0;
	if (g_once_init_enter (&baobab_treemap_item_type_id__once)) {
		GType baobab_treemap_item_type_id;
		baobab_treemap_item_type_id = baobab_treemap_item_get_type_once ();
		g_once_init_leave (&baobab_treemap_item_type_id__once, baobab_treemap_item_type_id);
	}
	return baobab_treemap_item_type_id__once;
}

static inline gpointer
baobab_treemap_get_instance_private (BaobabTreemap* self)
{
	return G_STRUCT_MEMBER_P (self, BaobabTreemap_private_offset);
}

static BaobabChartItem*
baobab_treemap_real_create_new_chartitem (BaobabChart* base)
{
	BaobabTreemap * self;
	BaobabTreemapItem* _tmp0_;
	BaobabChartItem* _tmp1_;
	BaobabChartItem* result;
	self = (BaobabTreemap*) base;
	_tmp0_ = baobab_treemap_item_new ();
	_tmp1_ = BAOBAB_IS_CHART_ITEM (_tmp0_) ? ((BaobabChartItem*) _tmp0_) : NULL;
	if (_tmp1_ == NULL) {
		_baobab_chart_item_unref0 (_tmp0_);
	}
	result = _tmp1_;
	return result;
}

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

static void
baobab_treemap_draw_rectangle (BaobabTreemap* self,
                               cairo_t* cr,
                               gdouble x,
                               gdouble y,
                               gdouble width,
                               gdouble height,
                               GdkRGBA* fill_color,
                               const gchar* text,
                               gboolean show_text)
{
	guint border = 0U;
	GtkStyleContext* context = NULL;
	GtkStyleContext* _tmp0_;
	GtkStyleContext* _tmp1_;
	GdkRGBA _tmp2_;
	GtkStyleContext* _tmp3_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (cr != NULL);
	g_return_if_fail (fill_color != NULL);
	g_return_if_fail (text != NULL);
	border = (guint) BAOBAB_TREEMAP_ITEM_BORDER_WIDTH;
	_tmp0_ = gtk_widget_get_style_context ((GtkWidget*) self);
	_tmp1_ = _g_object_ref0 (_tmp0_);
	context = _tmp1_;
	cairo_set_line_width (cr, (gdouble) border);
	cairo_rectangle (cr, x + border, y + border, width - (border * 2), height - (border * 2));
	_tmp2_ = *fill_color;
	gdk_cairo_set_source_rgba (cr, &_tmp2_);
	cairo_fill (cr);
	_tmp3_ = context;
	gtk_render_frame (_tmp3_, cr, x + 0.5, y + 0.5, width - 1, height - 1);
	if (show_text) {
		PangoLayout* layout = NULL;
		PangoLayout* _tmp4_;
		gchar* markup = NULL;
		gchar* _tmp5_;
		PangoLayout* _tmp6_;
		const gchar* _tmp7_;
		PangoRectangle rect = {0};
		PangoLayout* _tmp8_;
		PangoRectangle _tmp9_ = {0};
		gboolean _tmp10_ = FALSE;
		PangoRectangle _tmp11_;
		_tmp4_ = gtk_widget_create_pango_layout ((GtkWidget*) self, NULL);
		layout = _tmp4_;
		_tmp5_ = g_markup_escape_text (text, (gssize) -1);
		markup = _tmp5_;
		_tmp6_ = layout;
		_tmp7_ = markup;
		pango_layout_set_markup (_tmp6_, _tmp7_, -1);
		_tmp8_ = layout;
		pango_layout_get_pixel_extents (_tmp8_, NULL, &_tmp9_);
		rect = _tmp9_;
		_tmp11_ = rect;
		if (((gdouble) (_tmp11_.width + (BAOBAB_TREEMAP_ITEM_TEXT_PADDING * 2))) <= width) {
			PangoRectangle _tmp12_;
			_tmp12_ = rect;
			_tmp10_ = ((gdouble) (_tmp12_.height + (BAOBAB_TREEMAP_ITEM_TEXT_PADDING * 2))) <= height;
		} else {
			_tmp10_ = FALSE;
		}
		if (_tmp10_) {
			GtkStyleContext* _tmp13_;
			PangoRectangle _tmp14_;
			PangoRectangle _tmp15_;
			PangoLayout* _tmp16_;
			_tmp13_ = context;
			_tmp14_ = rect;
			_tmp15_ = rect;
			_tmp16_ = layout;
			gtk_render_layout (_tmp13_, cr, (x + (width / 2)) - (_tmp14_.width / 2), (y + (height / 2)) - (_tmp15_.height / 2), _tmp16_);
		}
		_g_free0 (markup);
		_g_object_unref0 (layout);
	}
	_g_object_unref0 (context);
}

static void
baobab_treemap_real_draw_item (BaobabChart* base,
                               cairo_t* cr,
                               BaobabChartItem* item,
                               gboolean highlighted)
{
	BaobabTreemap * self;
	cairo_rectangle_t rect = {0};
	GdkRGBA fill_color = {0};
	GtkAllocation allocation = {0};
	gdouble width = 0.0;
	gdouble height = 0.0;
	cairo_rectangle_t _tmp0_;
	GtkAllocation _tmp1_ = {0};
	cairo_rectangle_t _tmp12_;
	cairo_rectangle_t _tmp13_;
	GdkRGBA _tmp14_;
	const gchar* _tmp15_;
	self = (BaobabTreemap*) base;
	g_return_if_fail (cr != NULL);
	g_return_if_fail (item != NULL);
	memset (&fill_color, 0, sizeof (GdkRGBA));
	width = (gdouble) 0;
	height = (gdouble) 0;
	_tmp0_ = G_TYPE_CHECK_INSTANCE_CAST (item, BAOBAB_TYPE_TREEMAP_ITEM, BaobabTreemapItem)->cr_rect;
	rect = _tmp0_;
	gtk_widget_get_allocation ((GtkWidget*) self, &_tmp1_);
	allocation = _tmp1_;
	if ((item->depth % 2) != ((guint) 0)) {
		cairo_rectangle_t _tmp2_;
		GtkAllocation _tmp3_;
		GdkRGBA _tmp4_ = {0};
		cairo_rectangle_t _tmp5_;
		cairo_rectangle_t _tmp6_;
		_tmp2_ = rect;
		_tmp3_ = allocation;
		baobab_chart_get_item_color ((BaobabChart*) self, (_tmp2_.x / _tmp3_.width) * 200, item->depth, highlighted, &_tmp4_);
		fill_color = _tmp4_;
		_tmp5_ = rect;
		width = _tmp5_.width - BAOBAB_TREEMAP_ITEM_PADDING;
		_tmp6_ = rect;
		height = _tmp6_.height;
	} else {
		cairo_rectangle_t _tmp7_;
		GtkAllocation _tmp8_;
		GdkRGBA _tmp9_ = {0};
		cairo_rectangle_t _tmp10_;
		cairo_rectangle_t _tmp11_;
		_tmp7_ = rect;
		_tmp8_ = allocation;
		baobab_chart_get_item_color ((BaobabChart*) self, (_tmp7_.y / _tmp8_.height) * 200, item->depth, highlighted, &_tmp9_);
		fill_color = _tmp9_;
		_tmp10_ = rect;
		width = _tmp10_.width;
		_tmp11_ = rect;
		height = _tmp11_.height - BAOBAB_TREEMAP_ITEM_PADDING;
	}
	_tmp12_ = rect;
	_tmp13_ = rect;
	_tmp14_ = fill_color;
	_tmp15_ = item->name;
	baobab_treemap_draw_rectangle (self, cr, _tmp12_.x, _tmp13_.y, width, height, &_tmp14_, _tmp15_, !item->has_visible_children);
}

static gpointer
_baobab_chart_item_ref0 (gpointer self)
{
	return self ? baobab_chart_item_ref (self) : NULL;
}

static void
baobab_treemap_real_calculate_item_geometry (BaobabChart* base,
                                             BaobabChartItem* item)
{
	BaobabTreemap * self;
	BaobabTreemapItem* treemapitem = NULL;
	BaobabTreemapItem* _tmp0_;
	cairo_rectangle_t p_area = {0};
	GList* _tmp1_;
	gboolean _tmp24_ = FALSE;
	BaobabTreemapItem* _tmp25_;
	cairo_rectangle_t _tmp26_;
	BaobabTreemapItem* _tmp29_;
	BaobabTreemapItem* _tmp30_;
	cairo_rectangle_t _tmp31_;
	BaobabTreemapItem* _tmp32_;
	BaobabTreemapItem* _tmp33_;
	cairo_rectangle_t _tmp34_;
	BaobabTreemapItem* _tmp35_;
	BaobabTreemapItem* _tmp36_;
	cairo_rectangle_t _tmp37_;
	BaobabTreemapItem* _tmp38_;
	BaobabTreemapItem* _tmp39_;
	cairo_rectangle_t _tmp40_;
	GList* _tmp41_;
	guint _tmp44_;
	guint _tmp45_;
	self = (BaobabTreemap*) base;
	g_return_if_fail (item != NULL);
	_tmp0_ = _baobab_chart_item_ref0 (G_TYPE_CHECK_INSTANCE_CAST (item, BAOBAB_TYPE_TREEMAP_ITEM, BaobabTreemapItem));
	treemapitem = _tmp0_;
	memset (&p_area, 0, sizeof (cairo_rectangle_t));
	if (item->depth == ((guint) 0)) {
		self->priv->max_visible_depth = (guint) 0;
		self->priv->more_visible_children = FALSE;
	}
	item->visible = FALSE;
	_tmp1_ = item->parent;
	if (_tmp1_ == NULL) {
		GtkAllocation allocation = {0};
		GtkAllocation _tmp2_ = {0};
		GtkAllocation _tmp3_;
		GtkAllocation _tmp4_;
		gtk_widget_get_allocation ((GtkWidget*) self, &_tmp2_);
		allocation = _tmp2_;
		p_area.x = (gdouble) ((-BAOBAB_TREEMAP_ITEM_PADDING) / 2);
		p_area.y = (gdouble) ((-BAOBAB_TREEMAP_ITEM_PADDING) / 2);
		_tmp3_ = allocation;
		p_area.width = (gdouble) (_tmp3_.width + (BAOBAB_TREEMAP_ITEM_PADDING * 2));
		_tmp4_ = allocation;
		p_area.height = (gdouble) (_tmp4_.height + (BAOBAB_TREEMAP_ITEM_PADDING * 2));
	} else {
		GList* _tmp5_;
		gconstpointer _tmp6_;
		cairo_rectangle_t _tmp7_;
		_tmp5_ = item->parent;
		_tmp6_ = _tmp5_->data;
		_tmp7_ = G_TYPE_CHECK_INSTANCE_CAST ((BaobabChartItem*) _tmp6_, BAOBAB_TYPE_TREEMAP_ITEM, BaobabTreemapItem)->cr_rect;
		p_area = _tmp7_;
	}
	if ((item->depth % 2) != ((guint) 0)) {
		gdouble width = 0.0;
		cairo_rectangle_t _tmp8_;
		BaobabTreemapItem* _tmp9_;
		cairo_rectangle_t _tmp10_;
		BaobabTreemapItem* _tmp11_;
		cairo_rectangle_t _tmp12_;
		BaobabTreemapItem* _tmp13_;
		BaobabTreemapItem* _tmp14_;
		cairo_rectangle_t _tmp15_;
		_tmp8_ = p_area;
		width = _tmp8_.width - BAOBAB_TREEMAP_ITEM_PADDING;
		_tmp9_ = treemapitem;
		_tmp10_ = p_area;
		_tmp9_->cr_rect.x = (_tmp10_.x + ((item->rel_start * width) / 100)) + BAOBAB_TREEMAP_ITEM_PADDING;
		_tmp11_ = treemapitem;
		_tmp12_ = p_area;
		_tmp11_->cr_rect.y = _tmp12_.y + BAOBAB_TREEMAP_ITEM_PADDING;
		_tmp13_ = treemapitem;
		_tmp13_->cr_rect.width = (width * item->rel_size) / 100;
		_tmp14_ = treemapitem;
		_tmp15_ = p_area;
		_tmp14_->cr_rect.height = _tmp15_.height - (BAOBAB_TREEMAP_ITEM_PADDING * 3);
	} else {
		gdouble height = 0.0;
		cairo_rectangle_t _tmp16_;
		BaobabTreemapItem* _tmp17_;
		cairo_rectangle_t _tmp18_;
		BaobabTreemapItem* _tmp19_;
		cairo_rectangle_t _tmp20_;
		BaobabTreemapItem* _tmp21_;
		cairo_rectangle_t _tmp22_;
		BaobabTreemapItem* _tmp23_;
		_tmp16_ = p_area;
		height = _tmp16_.height - BAOBAB_TREEMAP_ITEM_PADDING;
		_tmp17_ = treemapitem;
		_tmp18_ = p_area;
		_tmp17_->cr_rect.x = _tmp18_.x + BAOBAB_TREEMAP_ITEM_PADDING;
		_tmp19_ = treemapitem;
		_tmp20_ = p_area;
		_tmp19_->cr_rect.y = (_tmp20_.y + ((item->rel_start * height) / 100)) + BAOBAB_TREEMAP_ITEM_PADDING;
		_tmp21_ = treemapitem;
		_tmp22_ = p_area;
		_tmp21_->cr_rect.width = _tmp22_.width - (BAOBAB_TREEMAP_ITEM_PADDING * 3);
		_tmp23_ = treemapitem;
		_tmp23_->cr_rect.height = (height * item->rel_size) / 100;
	}
	_tmp25_ = treemapitem;
	_tmp26_ = _tmp25_->cr_rect;
	if ((_tmp26_.width - BAOBAB_TREEMAP_ITEM_PADDING) < ((gdouble) BAOBAB_TREEMAP_ITEM_MIN_WIDTH)) {
		_tmp24_ = TRUE;
	} else {
		BaobabTreemapItem* _tmp27_;
		cairo_rectangle_t _tmp28_;
		_tmp27_ = treemapitem;
		_tmp28_ = _tmp27_->cr_rect;
		_tmp24_ = (_tmp28_.height - BAOBAB_TREEMAP_ITEM_PADDING) < ((gdouble) BAOBAB_TREEMAP_ITEM_MIN_HEIGHT);
	}
	if (_tmp24_) {
		_baobab_chart_item_unref0 (treemapitem);
		return;
	}
	_tmp29_ = treemapitem;
	_tmp30_ = treemapitem;
	_tmp31_ = _tmp30_->cr_rect;
	_tmp29_->cr_rect.x = floor (_tmp31_.x) + 0.5;
	_tmp32_ = treemapitem;
	_tmp33_ = treemapitem;
	_tmp34_ = _tmp33_->cr_rect;
	_tmp32_->cr_rect.y = floor (_tmp34_.y) + 0.5;
	_tmp35_ = treemapitem;
	_tmp36_ = treemapitem;
	_tmp37_ = _tmp36_->cr_rect;
	_tmp35_->cr_rect.width = floor (_tmp37_.width);
	_tmp38_ = treemapitem;
	_tmp39_ = treemapitem;
	_tmp40_ = _tmp39_->cr_rect;
	_tmp38_->cr_rect.height = floor (_tmp40_.height);
	item->visible = TRUE;
	_tmp41_ = item->parent;
	if (_tmp41_ != NULL) {
		GList* _tmp42_;
		gconstpointer _tmp43_;
		_tmp42_ = item->parent;
		_tmp43_ = _tmp42_->data;
		((BaobabChartItem*) _tmp43_)->has_visible_children = TRUE;
	}
	baobab_chart_get_item_rectangle ((BaobabChart*) self, item);
	_tmp44_ = baobab_chart_get_max_depth ((BaobabChart*) self);
	_tmp45_ = _tmp44_;
	if (item->depth == (_tmp45_ + 1)) {
		self->priv->more_visible_children = TRUE;
	} else {
		self->priv->max_visible_depth = MAX (self->priv->max_visible_depth, item->depth);
	}
	_baobab_chart_item_unref0 (treemapitem);
}

static void
baobab_treemap_real_get_item_rectangle (BaobabChart* base,
                                        BaobabChartItem* item)
{
	BaobabTreemap * self;
	cairo_rectangle_t crect = {0};
	cairo_rectangle_t _tmp0_;
	cairo_rectangle_t _tmp1_;
	cairo_rectangle_t _tmp2_;
	self = (BaobabTreemap*) base;
	g_return_if_fail (item != NULL);
	_tmp0_ = G_TYPE_CHECK_INSTANCE_CAST (item, BAOBAB_TYPE_TREEMAP_ITEM, BaobabTreemapItem)->cr_rect;
	crect = _tmp0_;
	_tmp1_ = crect;
	item->rect.x = (gint) _tmp1_.x;
	_tmp2_ = crect;
	item->rect.y = (gint) _tmp2_.y;
	if ((item->depth % 2) != ((guint) 0)) {
		cairo_rectangle_t _tmp3_;
		cairo_rectangle_t _tmp4_;
		_tmp3_ = crect;
		item->rect.width = ((gint) _tmp3_.width) - BAOBAB_TREEMAP_ITEM_PADDING;
		_tmp4_ = crect;
		item->rect.height = (gint) _tmp4_.height;
	} else {
		cairo_rectangle_t _tmp5_;
		cairo_rectangle_t _tmp6_;
		_tmp5_ = crect;
		item->rect.width = (gint) _tmp5_.width;
		_tmp6_ = crect;
		item->rect.height = ((gint) _tmp6_.height) - BAOBAB_TREEMAP_ITEM_PADDING;
	}
}

static gboolean
baobab_treemap_real_is_point_over_item (BaobabChart* base,
                                        BaobabChartItem* item,
                                        gdouble x,
                                        gdouble y)
{
	BaobabTreemap * self;
	GdkRectangle rect = {0};
	GdkRectangle _tmp0_;
	gboolean _tmp1_ = FALSE;
	gboolean _tmp2_ = FALSE;
	gboolean _tmp3_ = FALSE;
	GdkRectangle _tmp4_;
	gboolean result;
	self = (BaobabTreemap*) base;
	g_return_val_if_fail (item != NULL, FALSE);
	_tmp0_ = item->rect;
	rect = _tmp0_;
	_tmp4_ = rect;
	if (x >= ((gdouble) _tmp4_.x)) {
		GdkRectangle _tmp5_;
		GdkRectangle _tmp6_;
		_tmp5_ = rect;
		_tmp6_ = rect;
		_tmp3_ = x <= ((gdouble) (_tmp5_.x + _tmp6_.width));
	} else {
		_tmp3_ = FALSE;
	}
	if (_tmp3_) {
		GdkRectangle _tmp7_;
		_tmp7_ = rect;
		_tmp2_ = y >= ((gdouble) _tmp7_.y);
	} else {
		_tmp2_ = FALSE;
	}
	if (_tmp2_) {
		GdkRectangle _tmp8_;
		GdkRectangle _tmp9_;
		_tmp8_ = rect;
		_tmp9_ = rect;
		_tmp1_ = y <= ((gdouble) (_tmp8_.y + _tmp9_.height));
	} else {
		_tmp1_ = FALSE;
	}
	result = _tmp1_;
	return result;
}

static gboolean
baobab_treemap_real_can_zoom_out (BaobabChart* base)
{
	BaobabTreemap * self;
	gboolean _tmp0_ = FALSE;
	guint _tmp1_;
	guint _tmp2_;
	gboolean result;
	self = (BaobabTreemap*) base;
	_tmp1_ = baobab_chart_get_max_depth ((BaobabChart*) self);
	_tmp2_ = _tmp1_;
	if (_tmp2_ < BAOBAB_CHART_MAX_DEPTH) {
		_tmp0_ = self->priv->more_visible_children;
	} else {
		_tmp0_ = FALSE;
	}
	result = _tmp0_;
	return result;
}

static gboolean
baobab_treemap_real_can_zoom_in (BaobabChart* base)
{
	BaobabTreemap * self;
	gboolean result;
	self = (BaobabTreemap*) base;
	result = self->priv->max_visible_depth > ((guint) 1);
	return result;
}

BaobabTreemap*
baobab_treemap_construct (GType object_type)
{
	BaobabTreemap * self = NULL;
	self = (BaobabTreemap*) baobab_chart_construct (object_type);
	return self;
}

BaobabTreemap*
baobab_treemap_new (void)
{
	return baobab_treemap_construct (BAOBAB_TYPE_TREEMAP);
}

static void
baobab_treemap_class_init (BaobabTreemapClass * klass,
                           gpointer klass_data)
{
	baobab_treemap_parent_class = g_type_class_peek_parent (klass);
	g_type_class_adjust_private_offset (klass, &BaobabTreemap_private_offset);
	((BaobabChartClass *) klass)->create_new_chartitem = (BaobabChartItem* (*) (BaobabChart*)) baobab_treemap_real_create_new_chartitem;
	((BaobabChartClass *) klass)->draw_item = (void (*) (BaobabChart*, cairo_t*, BaobabChartItem*, gboolean)) baobab_treemap_real_draw_item;
	((BaobabChartClass *) klass)->calculate_item_geometry = (void (*) (BaobabChart*, BaobabChartItem*)) baobab_treemap_real_calculate_item_geometry;
	((BaobabChartClass *) klass)->get_item_rectangle = (void (*) (BaobabChart*, BaobabChartItem*)) baobab_treemap_real_get_item_rectangle;
	((BaobabChartClass *) klass)->is_point_over_item = (gboolean (*) (BaobabChart*, BaobabChartItem*, gdouble, gdouble)) baobab_treemap_real_is_point_over_item;
	((BaobabChartClass *) klass)->can_zoom_out = (gboolean (*) (BaobabChart*)) baobab_treemap_real_can_zoom_out;
	((BaobabChartClass *) klass)->can_zoom_in = (gboolean (*) (BaobabChart*)) baobab_treemap_real_can_zoom_in;
	G_OBJECT_CLASS (klass)->finalize = baobab_treemap_finalize;
	gtk_widget_class_set_css_name (GTK_WIDGET_CLASS (klass), "treemap");
}

static void
baobab_treemap_instance_init (BaobabTreemap * self,
                              gpointer klass)
{
	self->priv = baobab_treemap_get_instance_private (self);
}

static void
baobab_treemap_finalize (GObject * obj)
{
	BaobabTreemap * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, BAOBAB_TYPE_TREEMAP, BaobabTreemap);
	G_OBJECT_CLASS (baobab_treemap_parent_class)->finalize (obj);
}

static GType
baobab_treemap_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (BaobabTreemapClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) baobab_treemap_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (BaobabTreemap), 0, (GInstanceInitFunc) baobab_treemap_instance_init, NULL };
	GType baobab_treemap_type_id;
	baobab_treemap_type_id = g_type_register_static (BAOBAB_TYPE_CHART, "BaobabTreemap", &g_define_type_info, 0);
	BaobabTreemap_private_offset = g_type_add_instance_private (baobab_treemap_type_id, sizeof (BaobabTreemapPrivate));
	return baobab_treemap_type_id;
}

GType
baobab_treemap_get_type (void)
{
	static volatile gsize baobab_treemap_type_id__once = 0;
	if (g_once_init_enter (&baobab_treemap_type_id__once)) {
		GType baobab_treemap_type_id;
		baobab_treemap_type_id = baobab_treemap_get_type_once ();
		g_once_init_leave (&baobab_treemap_type_id__once, baobab_treemap_type_id);
	}
	return baobab_treemap_type_id__once;
}

