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

/**/
/*  Copyright (C) 2011 Robert Dyer*/
/**/
/*  This file is part of Plank.*/
/**/
/*  Plank 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 3 of the License, or*/
/*  (at your option) any later version.*/
/**/
/*  Plank 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, see <http://www.gnu.org/licenses/>.*/
/**/

#include "plank.h"
#include <glib.h>
#include <float.h>
#include <math.h>
#include <gdk/gdk.h>
#include <stdlib.h>
#include <string.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

#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);

static void plank_color_hsv_to_rgb (gdouble h,
                             gdouble s,
                             gdouble v,
                             gdouble* r,
                             gdouble* g,
                             gdouble* b);
static void plank_color_rgb_to_hsv (gdouble r,
                             gdouble g,
                             gdouble b,
                             gdouble* h,
                             gdouble* s,
                             gdouble* v);
static void plank_color_rgb_to_hsl (gdouble r,
                             gdouble g,
                             gdouble b,
                             gdouble* h,
                             gdouble* s,
                             gdouble* l);
static void plank_color_hsl_to_rgb (gdouble h,
                             gdouble s,
                             gdouble l,
                             gdouble* r,
                             gdouble* g,
                             gdouble* b);
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 gssize _vala_array_length (gpointer array);

/**
 * Create new color for the given HSV values while
 * h in [0,360), s in [0,1] and v in [0,1]
 *
 * @param h the hue for the color
 * @param s the saturation for the color
 * @param v the value for the color
 * @return new {@link Color} based on the HSV values
 */
void
plank_color_from_hsv (gdouble h,
                      gdouble s,
                      gdouble v,
                      PlankColor* result)
{
	PlankColor _result_ = {0};
	PlankColor _tmp0_ = {0};
	_tmp0_.red = 1.0;
	_tmp0_.green = 1.0;
	_tmp0_.blue = 1.0;
	_tmp0_.alpha = 1.0;
	_result_ = _tmp0_;
	plank_color_set_hsv (&_result_, h, s, v);
	*result = _result_;
	return;
}

/**
 * Create new color for the given HSL values while
 * h in [0,360), s in [0,1] and l in [0,1]
 *
 * @param h the hue for the color
 * @param s the saturation for the color
 * @param l the lightness for the color
 * @return new {@link Color} based on the HSL values
 */
void
plank_color_from_hsl (gdouble h,
                      gdouble s,
                      gdouble l,
                      PlankColor* result)
{
	PlankColor _result_ = {0};
	PlankColor _tmp0_ = {0};
	_tmp0_.red = 1.0;
	_tmp0_.green = 1.0;
	_tmp0_.blue = 1.0;
	_tmp0_.alpha = 1.0;
	_result_ = _tmp0_;
	plank_color_set_hsl (&_result_, h, s, l);
	*result = _result_;
	return;
}

/**
 * Set HSV color values of this color.
 */
void
plank_color_set_hsv (PlankColor *self,
                     gdouble h,
                     gdouble s,
                     gdouble v)
{
	gdouble _tmp0_ = 0.0;
	gdouble _tmp1_ = 0.0;
	gdouble _tmp2_ = 0.0;
	plank_color_hsv_to_rgb (h, s, v, &_tmp0_, &_tmp1_, &_tmp2_);
	(*self).red = _tmp0_;
	(*self).green = _tmp1_;
	(*self).blue = _tmp2_;
}

/**
 * Sets the hue for the color.
 *
 * @param hue the new hue for the color
 */
void
plank_color_set_hue (PlankColor *self,
                     gdouble hue)
{
	gdouble h = 0.0;
	gdouble s = 0.0;
	gdouble v = 0.0;
	gdouble _tmp0_ = 0.0;
	gdouble _tmp1_ = 0.0;
	gdouble _tmp2_ = 0.0;
	gdouble _tmp3_ = 0.0;
	gdouble _tmp4_ = 0.0;
	gdouble _tmp5_ = 0.0;
	_vala_return_if_fail ((hue >= ((gdouble) 0)) && (hue <= ((gdouble) 360)), "hue >= 0 && hue <= 360");
	plank_color_rgb_to_hsv ((*self).red, (*self).green, (*self).blue, &_tmp0_, &_tmp1_, &_tmp2_);
	h = _tmp0_;
	s = _tmp1_;
	v = _tmp2_;
	h = hue;
	plank_color_hsv_to_rgb (h, s, v, &_tmp3_, &_tmp4_, &_tmp5_);
	(*self).red = _tmp3_;
	(*self).green = _tmp4_;
	(*self).blue = _tmp5_;
}

/**
 * Sets the saturation for the color.
 *
 * @param sat the new saturation for the color
 */
void
plank_color_set_sat (PlankColor *self,
                     gdouble sat)
{
	gdouble h = 0.0;
	gdouble s = 0.0;
	gdouble v = 0.0;
	gdouble _tmp0_ = 0.0;
	gdouble _tmp1_ = 0.0;
	gdouble _tmp2_ = 0.0;
	gdouble _tmp3_ = 0.0;
	gdouble _tmp4_ = 0.0;
	gdouble _tmp5_ = 0.0;
	_vala_return_if_fail ((sat >= ((gdouble) 0)) && (sat <= ((gdouble) 1)), "sat >= 0 && sat <= 1");
	plank_color_rgb_to_hsv ((*self).red, (*self).green, (*self).blue, &_tmp0_, &_tmp1_, &_tmp2_);
	h = _tmp0_;
	s = _tmp1_;
	v = _tmp2_;
	s = sat;
	plank_color_hsv_to_rgb (h, s, v, &_tmp3_, &_tmp4_, &_tmp5_);
	(*self).red = _tmp3_;
	(*self).green = _tmp4_;
	(*self).blue = _tmp5_;
}

/**
 * Sets the value for the color.
 *
 * @param val the new value for the color
 */
void
plank_color_set_val (PlankColor *self,
                     gdouble val)
{
	gdouble h = 0.0;
	gdouble s = 0.0;
	gdouble v = 0.0;
	gdouble _tmp0_ = 0.0;
	gdouble _tmp1_ = 0.0;
	gdouble _tmp2_ = 0.0;
	gdouble _tmp3_ = 0.0;
	gdouble _tmp4_ = 0.0;
	gdouble _tmp5_ = 0.0;
	_vala_return_if_fail ((val >= ((gdouble) 0)) && (val <= ((gdouble) 1)), "val >= 0 && val <= 1");
	plank_color_rgb_to_hsv ((*self).red, (*self).green, (*self).blue, &_tmp0_, &_tmp1_, &_tmp2_);
	h = _tmp0_;
	s = _tmp1_;
	v = _tmp2_;
	v = val;
	plank_color_hsv_to_rgb (h, s, v, &_tmp3_, &_tmp4_, &_tmp5_);
	(*self).red = _tmp3_;
	(*self).green = _tmp4_;
	(*self).blue = _tmp5_;
}

/**
 * Get HSV color values of this color.
 */
void
plank_color_get_hsv (PlankColor *self,
                     gdouble* h,
                     gdouble* s,
                     gdouble* v)
{
	gdouble _vala_h = 0.0;
	gdouble _vala_s = 0.0;
	gdouble _vala_v = 0.0;
	gdouble _tmp0_ = 0.0;
	gdouble _tmp1_ = 0.0;
	gdouble _tmp2_ = 0.0;
	plank_color_rgb_to_hsv ((*self).red, (*self).green, (*self).blue, &_tmp0_, &_tmp1_, &_tmp2_);
	_vala_h = _tmp0_;
	_vala_s = _tmp1_;
	_vala_v = _tmp2_;
	if (h) {
		*h = _vala_h;
	}
	if (s) {
		*s = _vala_s;
	}
	if (v) {
		*v = _vala_v;
	}
}

/**
 * Returns the hue for the color.
 *
 * @return the hue for the color
 */
gdouble
plank_color_get_hue (PlankColor *self)
{
	gdouble h = 0.0;
	gdouble s = 0.0;
	gdouble v = 0.0;
	gdouble _tmp0_ = 0.0;
	gdouble _tmp1_ = 0.0;
	gdouble _tmp2_ = 0.0;
	gdouble result;
	plank_color_rgb_to_hsv ((*self).red, (*self).green, (*self).blue, &_tmp0_, &_tmp1_, &_tmp2_);
	h = _tmp0_;
	s = _tmp1_;
	v = _tmp2_;
	result = h;
	return result;
}

/**
 * Returns the saturation for the color.
 *
 * @return the saturation for the color
 */
gdouble
plank_color_get_sat (PlankColor *self)
{
	gdouble h = 0.0;
	gdouble s = 0.0;
	gdouble v = 0.0;
	gdouble _tmp0_ = 0.0;
	gdouble _tmp1_ = 0.0;
	gdouble _tmp2_ = 0.0;
	gdouble result;
	plank_color_rgb_to_hsv ((*self).red, (*self).green, (*self).blue, &_tmp0_, &_tmp1_, &_tmp2_);
	h = _tmp0_;
	s = _tmp1_;
	v = _tmp2_;
	result = s;
	return result;
}

/**
 * Returns the value for the color.
 *
 * @return the value for the color
 */
gdouble
plank_color_get_val (PlankColor *self)
{
	gdouble h = 0.0;
	gdouble s = 0.0;
	gdouble v = 0.0;
	gdouble _tmp0_ = 0.0;
	gdouble _tmp1_ = 0.0;
	gdouble _tmp2_ = 0.0;
	gdouble result;
	plank_color_rgb_to_hsv ((*self).red, (*self).green, (*self).blue, &_tmp0_, &_tmp1_, &_tmp2_);
	h = _tmp0_;
	s = _tmp1_;
	v = _tmp2_;
	result = v;
	return result;
}

/**
 * Increases the color's hue.
 *
 * @param val the amount to add to the hue
 */
void
plank_color_add_hue (PlankColor *self,
                     gdouble val)
{
	gdouble h = 0.0;
	gdouble s = 0.0;
	gdouble v = 0.0;
	gdouble _tmp0_ = 0.0;
	gdouble _tmp1_ = 0.0;
	gdouble _tmp2_ = 0.0;
	gdouble _tmp3_ = 0.0;
	gdouble _tmp4_ = 0.0;
	gdouble _tmp5_ = 0.0;
	plank_color_rgb_to_hsv ((*self).red, (*self).green, (*self).blue, &_tmp0_, &_tmp1_, &_tmp2_);
	h = _tmp0_;
	s = _tmp1_;
	v = _tmp2_;
	h = fmod (fmod (h + val, 360) + 360, 360);
	plank_color_hsv_to_rgb (h, s, v, &_tmp3_, &_tmp4_, &_tmp5_);
	(*self).red = _tmp3_;
	(*self).green = _tmp4_;
	(*self).blue = _tmp5_;
}

/**
 * Assures the color's saturation is greater than or equal to the given one.
 *
 * @param sat the minimum saturation
 */
void
plank_color_set_min_sat (PlankColor *self,
                         gdouble sat)
{
	gdouble h = 0.0;
	gdouble s = 0.0;
	gdouble v = 0.0;
	gdouble _tmp0_ = 0.0;
	gdouble _tmp1_ = 0.0;
	gdouble _tmp2_ = 0.0;
	gdouble _tmp3_ = 0.0;
	gdouble _tmp4_ = 0.0;
	gdouble _tmp5_ = 0.0;
	_vala_return_if_fail ((sat >= ((gdouble) 0)) && (sat <= ((gdouble) 1)), "sat >= 0 && sat <= 1");
	plank_color_rgb_to_hsv ((*self).red, (*self).green, (*self).blue, &_tmp0_, &_tmp1_, &_tmp2_);
	h = _tmp0_;
	s = _tmp1_;
	v = _tmp2_;
	s = MAX (s, sat);
	plank_color_hsv_to_rgb (h, s, v, &_tmp3_, &_tmp4_, &_tmp5_);
	(*self).red = _tmp3_;
	(*self).green = _tmp4_;
	(*self).blue = _tmp5_;
}

/**
 * Assures the color's value is greater than or equal to the given one.
 *
 * @param val the minimum value
 */
void
plank_color_set_min_val (PlankColor *self,
                         gdouble val)
{
	gdouble h = 0.0;
	gdouble s = 0.0;
	gdouble v = 0.0;
	gdouble _tmp0_ = 0.0;
	gdouble _tmp1_ = 0.0;
	gdouble _tmp2_ = 0.0;
	gdouble _tmp3_ = 0.0;
	gdouble _tmp4_ = 0.0;
	gdouble _tmp5_ = 0.0;
	_vala_return_if_fail ((val >= ((gdouble) 0)) && (val <= ((gdouble) 1)), "val >= 0 && val <= 1");
	plank_color_rgb_to_hsv ((*self).red, (*self).green, (*self).blue, &_tmp0_, &_tmp1_, &_tmp2_);
	h = _tmp0_;
	s = _tmp1_;
	v = _tmp2_;
	v = MAX (v, val);
	plank_color_hsv_to_rgb (h, s, v, &_tmp3_, &_tmp4_, &_tmp5_);
	(*self).red = _tmp3_;
	(*self).green = _tmp4_;
	(*self).blue = _tmp5_;
}

/**
 * Assures the color's saturation is less than or equal to the given one.
 *
 * @param sat the maximum saturation
 */
void
plank_color_set_max_sat (PlankColor *self,
                         gdouble sat)
{
	gdouble h = 0.0;
	gdouble s = 0.0;
	gdouble v = 0.0;
	gdouble _tmp0_ = 0.0;
	gdouble _tmp1_ = 0.0;
	gdouble _tmp2_ = 0.0;
	gdouble _tmp3_ = 0.0;
	gdouble _tmp4_ = 0.0;
	gdouble _tmp5_ = 0.0;
	_vala_return_if_fail ((sat >= ((gdouble) 0)) && (sat <= ((gdouble) 1)), "sat >= 0 && sat <= 1");
	plank_color_rgb_to_hsv ((*self).red, (*self).green, (*self).blue, &_tmp0_, &_tmp1_, &_tmp2_);
	h = _tmp0_;
	s = _tmp1_;
	v = _tmp2_;
	s = MIN (s, sat);
	plank_color_hsv_to_rgb (h, s, v, &_tmp3_, &_tmp4_, &_tmp5_);
	(*self).red = _tmp3_;
	(*self).green = _tmp4_;
	(*self).blue = _tmp5_;
}

/**
 * Assures the color's value is less than or equal to the given one.
 *
 * @param val the maximum value
 */
void
plank_color_set_max_val (PlankColor *self,
                         gdouble val)
{
	gdouble h = 0.0;
	gdouble s = 0.0;
	gdouble v = 0.0;
	gdouble _tmp0_ = 0.0;
	gdouble _tmp1_ = 0.0;
	gdouble _tmp2_ = 0.0;
	gdouble _tmp3_ = 0.0;
	gdouble _tmp4_ = 0.0;
	gdouble _tmp5_ = 0.0;
	_vala_return_if_fail ((val >= ((gdouble) 0)) && (val <= ((gdouble) 1)), "val >= 0 && val <= 1");
	plank_color_rgb_to_hsv ((*self).red, (*self).green, (*self).blue, &_tmp0_, &_tmp1_, &_tmp2_);
	h = _tmp0_;
	s = _tmp1_;
	v = _tmp2_;
	v = MIN (v, val);
	plank_color_hsv_to_rgb (h, s, v, &_tmp3_, &_tmp4_, &_tmp5_);
	(*self).red = _tmp3_;
	(*self).green = _tmp4_;
	(*self).blue = _tmp5_;
}

/**
 * Multiplies the color's saturation using the amount.
 *
 * @param amount amount to multiply the saturation by
 */
void
plank_color_multiply_sat (PlankColor *self,
                          gdouble amount)
{
	gdouble h = 0.0;
	gdouble s = 0.0;
	gdouble v = 0.0;
	gdouble _tmp0_ = 0.0;
	gdouble _tmp1_ = 0.0;
	gdouble _tmp2_ = 0.0;
	gdouble _tmp3_ = 0.0;
	gdouble _tmp4_ = 0.0;
	gdouble _tmp5_ = 0.0;
	_vala_return_if_fail (amount >= ((gdouble) 0), "amount >= 0");
	plank_color_rgb_to_hsv ((*self).red, (*self).green, (*self).blue, &_tmp0_, &_tmp1_, &_tmp2_);
	h = _tmp0_;
	s = _tmp1_;
	v = _tmp2_;
	s = MIN ((gdouble) 1, s * amount);
	plank_color_hsv_to_rgb (h, s, v, &_tmp3_, &_tmp4_, &_tmp5_);
	(*self).red = _tmp3_;
	(*self).green = _tmp4_;
	(*self).blue = _tmp5_;
}

/**
 * Brighten the color's value using the value.
 *
 * @param amount percent of the value to brighten by
 */
void
plank_color_brighten_val (PlankColor *self,
                          gdouble amount)
{
	gdouble h = 0.0;
	gdouble s = 0.0;
	gdouble v = 0.0;
	gdouble _tmp0_ = 0.0;
	gdouble _tmp1_ = 0.0;
	gdouble _tmp2_ = 0.0;
	gdouble _tmp3_ = 0.0;
	gdouble _tmp4_ = 0.0;
	gdouble _tmp5_ = 0.0;
	_vala_return_if_fail ((amount >= ((gdouble) 0)) && (amount <= ((gdouble) 1)), "amount >= 0 && amount <= 1");
	plank_color_rgb_to_hsv ((*self).red, (*self).green, (*self).blue, &_tmp0_, &_tmp1_, &_tmp2_);
	h = _tmp0_;
	s = _tmp1_;
	v = _tmp2_;
	v = MIN ((gdouble) 1, v + ((1 - v) * amount));
	plank_color_hsv_to_rgb (h, s, v, &_tmp3_, &_tmp4_, &_tmp5_);
	(*self).red = _tmp3_;
	(*self).green = _tmp4_;
	(*self).blue = _tmp5_;
}

/**
 * Darkens the color's value using the value.
 *
 * @param amount percent of the value to darken by
 */
void
plank_color_darken_val (PlankColor *self,
                        gdouble amount)
{
	gdouble h = 0.0;
	gdouble s = 0.0;
	gdouble v = 0.0;
	gdouble _tmp0_ = 0.0;
	gdouble _tmp1_ = 0.0;
	gdouble _tmp2_ = 0.0;
	gdouble _tmp3_ = 0.0;
	gdouble _tmp4_ = 0.0;
	gdouble _tmp5_ = 0.0;
	_vala_return_if_fail ((amount >= ((gdouble) 0)) && (amount <= ((gdouble) 1)), "amount >= 0 && amount <= 1");
	plank_color_rgb_to_hsv ((*self).red, (*self).green, (*self).blue, &_tmp0_, &_tmp1_, &_tmp2_);
	h = _tmp0_;
	s = _tmp1_;
	v = _tmp2_;
	v = MAX ((gdouble) 0, v - ((1 - v) * amount));
	plank_color_hsv_to_rgb (h, s, v, &_tmp3_, &_tmp4_, &_tmp5_);
	(*self).red = _tmp3_;
	(*self).green = _tmp4_;
	(*self).blue = _tmp5_;
}

/**
 * Darkens the color's value using the saturtion.
 *
 * @param amount percent of the saturation to darken by
 */
void
plank_color_darken_by_sat (PlankColor *self,
                           gdouble amount)
{
	gdouble h = 0.0;
	gdouble s = 0.0;
	gdouble v = 0.0;
	gdouble _tmp0_ = 0.0;
	gdouble _tmp1_ = 0.0;
	gdouble _tmp2_ = 0.0;
	gdouble _tmp3_ = 0.0;
	gdouble _tmp4_ = 0.0;
	gdouble _tmp5_ = 0.0;
	_vala_return_if_fail ((amount >= ((gdouble) 0)) && (amount <= ((gdouble) 1)), "amount >= 0 && amount <= 1");
	plank_color_rgb_to_hsv ((*self).red, (*self).green, (*self).blue, &_tmp0_, &_tmp1_, &_tmp2_);
	h = _tmp0_;
	s = _tmp1_;
	v = _tmp2_;
	v = MAX ((gdouble) 0, v - (amount * s));
	plank_color_hsv_to_rgb (h, s, v, &_tmp3_, &_tmp4_, &_tmp5_);
	(*self).red = _tmp3_;
	(*self).green = _tmp4_;
	(*self).blue = _tmp5_;
}

/**
 * Get HSL color values of this color.
 */
void
plank_color_get_hsl (PlankColor *self,
                     gdouble* h,
                     gdouble* s,
                     gdouble* l)
{
	gdouble _vala_h = 0.0;
	gdouble _vala_s = 0.0;
	gdouble _vala_l = 0.0;
	gdouble _tmp0_ = 0.0;
	gdouble _tmp1_ = 0.0;
	gdouble _tmp2_ = 0.0;
	plank_color_rgb_to_hsl ((*self).red, (*self).green, (*self).blue, &_tmp0_, &_tmp1_, &_tmp2_);
	_vala_h = _tmp0_;
	_vala_s = _tmp1_;
	_vala_l = _tmp2_;
	if (h) {
		*h = _vala_h;
	}
	if (s) {
		*s = _vala_s;
	}
	if (l) {
		*l = _vala_l;
	}
}

/**
 * Set HSL color values of this color.
 */
void
plank_color_set_hsl (PlankColor *self,
                     gdouble h,
                     gdouble s,
                     gdouble v)
{
	gdouble _tmp0_ = 0.0;
	gdouble _tmp1_ = 0.0;
	gdouble _tmp2_ = 0.0;
	plank_color_hsl_to_rgb (h, s, v, &_tmp0_, &_tmp1_, &_tmp2_);
	(*self).red = _tmp0_;
	(*self).green = _tmp1_;
	(*self).blue = _tmp2_;
}

static void
plank_color_rgb_to_hsv (gdouble r,
                        gdouble g,
                        gdouble b,
                        gdouble* h,
                        gdouble* s,
                        gdouble* v)
{
	gdouble _vala_h = 0.0;
	gdouble _vala_s = 0.0;
	gdouble _vala_v = 0.0;
	gdouble min = 0.0;
	gdouble max = 0.0;
	gdouble delta = 0.0;
	_vala_return_if_fail ((r >= ((gdouble) 0)) && (r <= ((gdouble) 1)), "r >= 0 && r <= 1");
	_vala_return_if_fail ((g >= ((gdouble) 0)) && (g <= ((gdouble) 1)), "g >= 0 && g <= 1");
	_vala_return_if_fail ((b >= ((gdouble) 0)) && (b <= ((gdouble) 1)), "b >= 0 && b <= 1");
	_vala_v = MAX (r, MAX (g, b));
	if (_vala_v == ((gdouble) 0)) {
		_vala_h = (gdouble) 0;
		_vala_s = (gdouble) 0;
		if (h) {
			*h = _vala_h;
		}
		if (s) {
			*s = _vala_s;
		}
		if (v) {
			*v = _vala_v;
		}
		return;
	}
	r = r / _vala_v;
	g = g / _vala_v;
	b = b / _vala_v;
	min = MIN (r, MIN (g, b));
	max = MAX (r, MAX (g, b));
	delta = max - min;
	_vala_s = delta;
	if (_vala_s == ((gdouble) 0)) {
		_vala_h = (gdouble) 0;
		if (h) {
			*h = _vala_h;
		}
		if (s) {
			*s = _vala_s;
		}
		if (v) {
			*v = _vala_v;
		}
		return;
	}
	r = (r - min) / delta;
	g = (g - min) / delta;
	b = (b - min) / delta;
	if (max == r) {
		_vala_h = 0 + (60 * (g - b));
		if (_vala_h < ((gdouble) 0)) {
			_vala_h = _vala_h + 360;
		}
	} else {
		if (max == g) {
			_vala_h = 120 + (60 * (b - r));
		} else {
			_vala_h = 240 + (60 * (r - g));
		}
	}
	if (h) {
		*h = _vala_h;
	}
	if (s) {
		*s = _vala_s;
	}
	if (v) {
		*v = _vala_v;
	}
}

static void
plank_color_hsv_to_rgb (gdouble h,
                        gdouble s,
                        gdouble v,
                        gdouble* r,
                        gdouble* g,
                        gdouble* b)
{
	gdouble _vala_r = 0.0;
	gdouble _vala_g = 0.0;
	gdouble _vala_b = 0.0;
	_vala_return_if_fail ((h >= ((gdouble) 0)) && (h < ((gdouble) 360)), "h >= 0 && h < 360");
	_vala_return_if_fail ((s >= ((gdouble) 0)) && (s <= ((gdouble) 1)), "s >= 0 && s <= 1");
	_vala_return_if_fail ((v >= ((gdouble) 0)) && (v <= ((gdouble) 1)), "v >= 0 && v <= 1");
	if (s == ((gdouble) 0)) {
		_vala_r = v;
		_vala_g = v;
		_vala_b = v;
	} else {
		gint secNum = 0;
		gdouble fracSec = 0.0;
		gdouble p = 0.0;
		gdouble q = 0.0;
		gdouble t = 0.0;
		secNum = (gint) (h / 60);
		fracSec = (h / 60.0) - secNum;
		p = v * (1 - s);
		q = v * (1 - (s * fracSec));
		t = v * (1 - (s * (1 - fracSec)));
		switch (secNum) {
			case 0:
			{
				_vala_r = v;
				_vala_g = t;
				_vala_b = p;
				break;
			}
			case 1:
			{
				_vala_r = q;
				_vala_g = v;
				_vala_b = p;
				break;
			}
			case 2:
			{
				_vala_r = p;
				_vala_g = v;
				_vala_b = t;
				break;
			}
			case 3:
			{
				_vala_r = p;
				_vala_g = q;
				_vala_b = v;
				break;
			}
			case 4:
			{
				_vala_r = t;
				_vala_g = p;
				_vala_b = v;
				break;
			}
			case 5:
			{
				_vala_r = v;
				_vala_g = p;
				_vala_b = q;
				break;
			}
			default:
			{
				g_assert_not_reached ();
			}
		}
	}
	if (r) {
		*r = _vala_r;
	}
	if (g) {
		*g = _vala_g;
	}
	if (b) {
		*b = _vala_b;
	}
}

static void
plank_color_rgb_to_hsl (gdouble r,
                        gdouble g,
                        gdouble b,
                        gdouble* h,
                        gdouble* s,
                        gdouble* l)
{
	gdouble _vala_h = 0.0;
	gdouble _vala_s = 0.0;
	gdouble _vala_l = 0.0;
	gdouble max = 0.0;
	gdouble min = 0.0;
	gdouble delta = 0.0;
	gdouble _tmp0_ = 0.0;
	gdouble r2 = 0.0;
	gdouble g2 = 0.0;
	gdouble b2 = 0.0;
	_vala_return_if_fail ((r >= ((gdouble) 0)) && (r <= ((gdouble) 1)), "r >= 0 && r <= 1");
	_vala_return_if_fail ((g >= ((gdouble) 0)) && (g <= ((gdouble) 1)), "g >= 0 && g <= 1");
	_vala_return_if_fail ((b >= ((gdouble) 0)) && (b <= ((gdouble) 1)), "b >= 0 && b <= 1");
	max = MAX (r, MAX (g, b));
	if (max == 0.0) {
		_vala_h = 0.0;
		_vala_s = 0.0;
		_vala_l = 0.0;
		if (h) {
			*h = _vala_h;
		}
		if (s) {
			*s = _vala_s;
		}
		if (l) {
			*l = _vala_l;
		}
		return;
	}
	min = MIN (r, MIN (g, b));
	_vala_l = (min + max) / 2.0;
	if (_vala_l <= 0.0) {
		_vala_h = 0.0;
		_vala_s = 0.0;
		if (h) {
			*h = _vala_h;
		}
		if (s) {
			*s = _vala_s;
		}
		if (l) {
			*l = _vala_l;
		}
		return;
	}
	delta = max - min;
	if (delta <= 0.0) {
		_vala_h = 0.0;
		_vala_s = 0.0;
		if (h) {
			*h = _vala_h;
		}
		if (s) {
			*s = _vala_s;
		}
		if (l) {
			*l = _vala_l;
		}
		return;
	}
	if (_vala_l <= 0.5) {
		_tmp0_ = min + max;
	} else {
		_tmp0_ = (2.0 - min) - max;
	}
	_vala_s = delta / _tmp0_;
	r2 = (60 * (max - r)) / delta;
	g2 = (60 * (max - g)) / delta;
	b2 = (60 * (max - b)) / delta;
	if (max == r) {
		_vala_h = b2 - g2;
		if (_vala_h < ((gdouble) 0)) {
			_vala_h = _vala_h + 360;
		}
	} else {
		if (max == g) {
			_vala_h = 120 + (r2 - b2);
		} else {
			_vala_h = 240 + (g2 - r2);
		}
	}
	if (h) {
		*h = _vala_h;
	}
	if (s) {
		*s = _vala_s;
	}
	if (l) {
		*l = _vala_l;
	}
}

static void
plank_color_hsl_to_rgb (gdouble h,
                        gdouble s,
                        gdouble l,
                        gdouble* r,
                        gdouble* g,
                        gdouble* b)
{
	gdouble _vala_r = 0.0;
	gdouble _vala_g = 0.0;
	gdouble _vala_b = 0.0;
	gdouble _tmp0_ = 0.0;
	gdouble v = 0.0;
	gint secNum = 0;
	gdouble fracSec = 0.0;
	gdouble p = 0.0;
	gdouble q = 0.0;
	gdouble t = 0.0;
	_vala_return_if_fail ((h >= ((gdouble) 0)) && (h < ((gdouble) 360)), "h >= 0 && h < 360");
	_vala_return_if_fail ((s >= ((gdouble) 0)) && (s <= ((gdouble) 1)), "s >= 0 && s <= 1");
	_vala_return_if_fail ((l >= ((gdouble) 0)) && (l <= ((gdouble) 1)), "l >= 0 && l <= 1");
	if (l <= 0.5) {
		_tmp0_ = l * (1.0 + s);
	} else {
		_tmp0_ = (l + s) - (l * s);
	}
	v = _tmp0_;
	if (v <= 0.0) {
		_vala_r = l;
		_vala_g = l;
		_vala_b = l;
		if (r) {
			*r = _vala_r;
		}
		if (g) {
			*g = _vala_g;
		}
		if (b) {
			*b = _vala_b;
		}
		return;
	}
	secNum = (gint) (h / 60);
	fracSec = (h / 30.0) - (2 * secNum);
	p = l - (v - l);
	q = v - ((v - l) * fracSec);
	t = l + ((v - l) * (fracSec - 1));
	switch (secNum) {
		case 0:
		{
			_vala_r = v;
			_vala_g = t;
			_vala_b = p;
			break;
		}
		case 1:
		{
			_vala_r = q;
			_vala_g = v;
			_vala_b = p;
			break;
		}
		case 2:
		{
			_vala_r = p;
			_vala_g = v;
			_vala_b = t;
			break;
		}
		case 3:
		{
			_vala_r = p;
			_vala_g = q;
			_vala_b = v;
			break;
		}
		case 4:
		{
			_vala_r = t;
			_vala_g = p;
			_vala_b = v;
			break;
		}
		case 5:
		{
			_vala_r = v;
			_vala_g = p;
			_vala_b = q;
			break;
		}
		default:
		{
			g_assert_not_reached ();
		}
	}
	if (r) {
		*r = _vala_r;
	}
	if (g) {
		*g = _vala_g;
	}
	if (b) {
		*b = _vala_b;
	}
}

/**
 * Convert color to string formatted like "%d;;%d;;%d;;%d"
 * with numeric entries ranged in 0..255
 *
 * @return the string representation of this color
 */
gchar*
plank_color_to_prefs_string (PlankColor *self)
{
	gchar* _tmp0_;
	gchar* result;
	_tmp0_ = g_strdup_printf ("%d;;%d;;%d;;%d", (gint) ((*self).red * G_MAXUINT8), (gint) ((*self).green * G_MAXUINT8), (gint) ((*self).blue * G_MAXUINT8), (gint) ((*self).alpha * G_MAXUINT8));
	result = _tmp0_;
	return result;
}

/**
 * Create new color converted from string formatted like
 * "%d;;%d;;%d;;%d" with numeric entries ranged in 0..255
 *
 * @return new {@link Color} based on the given string
 */
void
plank_color_from_prefs_string (const gchar* s,
                               PlankColor* result)
{
	gchar** parts = NULL;
	gchar** _tmp0_;
	gchar** _tmp1_;
	gint parts_length1;
	gint _parts_size_;
	gchar** _tmp2_;
	gint _tmp2__length1;
	gchar** _tmp4_;
	gint _tmp4__length1;
	const gchar* _tmp5_;
	gchar** _tmp6_;
	gint _tmp6__length1;
	const gchar* _tmp7_;
	gchar** _tmp8_;
	gint _tmp8__length1;
	const gchar* _tmp9_;
	gchar** _tmp10_;
	gint _tmp10__length1;
	const gchar* _tmp11_;
	PlankColor _tmp12_ = {0};
	g_return_if_fail (s != NULL);
	_tmp1_ = _tmp0_ = g_strsplit (s, ";;", 0);
	parts = _tmp1_;
	parts_length1 = _vala_array_length (_tmp0_);
	_parts_size_ = parts_length1;
	_tmp2_ = parts;
	_tmp2__length1 = parts_length1;
	if (_tmp2__length1 != 4) {
		PlankColor _tmp3_ = {0};
		g_critical ("Color.vala:517: Malformed color string '%s'", s);
		*result = _tmp3_;
		parts = (_vala_array_free (parts, parts_length1, (GDestroyNotify) g_free), NULL);
		return;
	}
	_tmp4_ = parts;
	_tmp4__length1 = parts_length1;
	_tmp5_ = _tmp4_[0];
	_tmp6_ = parts;
	_tmp6__length1 = parts_length1;
	_tmp7_ = _tmp6_[1];
	_tmp8_ = parts;
	_tmp8__length1 = parts_length1;
	_tmp9_ = _tmp8_[2];
	_tmp10_ = parts;
	_tmp10__length1 = parts_length1;
	_tmp11_ = _tmp10_[3];
	_tmp12_.red = CLAMP ((gdouble) atoi (_tmp5_), 0.0, (gdouble) G_MAXUINT8) / G_MAXUINT8;
	_tmp12_.green = CLAMP ((gdouble) atoi (_tmp7_), 0.0, (gdouble) G_MAXUINT8) / G_MAXUINT8;
	_tmp12_.blue = CLAMP ((gdouble) atoi (_tmp9_), 0.0, (gdouble) G_MAXUINT8) / G_MAXUINT8;
	_tmp12_.alpha = CLAMP ((gdouble) atoi (_tmp11_), 0.0, (gdouble) G_MAXUINT8) / G_MAXUINT8;
	*result = _tmp12_;
	parts = (_vala_array_free (parts, parts_length1, (GDestroyNotify) g_free), NULL);
	return;
}

PlankColor*
plank_color_dup (const PlankColor* self)
{
	PlankColor* dup;
	dup = g_new0 (PlankColor, 1);
	memcpy (dup, self, sizeof (PlankColor));
	return dup;
}

void
plank_color_free (PlankColor* self)
{
	g_free (self);
}

static GType
plank_color_get_type_once (void)
{
	GType plank_color_type_id;
	plank_color_type_id = g_boxed_type_register_static ("PlankColor", (GBoxedCopyFunc) plank_color_dup, (GBoxedFreeFunc) plank_color_free);
	return plank_color_type_id;
}

GType
plank_color_get_type (void)
{
	static volatile gsize plank_color_type_id__once = 0;
	if (g_once_init_enter (&plank_color_type_id__once)) {
		GType plank_color_type_id;
		plank_color_type_id = plank_color_get_type_once ();
		g_once_init_leave (&plank_color_type_id__once, plank_color_type_id);
	}
	return plank_color_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 gssize
_vala_array_length (gpointer array)
{
	gssize length;
	length = 0;
	if (array) {
		while (((gpointer*) array)[length]) {
			length++;
		}
	}
	return length;
}

