// // Functions // —————————————-

////// common functions //////

// returns the max of two values @function max($v1, $v2) {

@return if($v1 > $v2, $v1, $v2);

}

// returns the min of two values @function min($v1, $v2) {

@return if($v1 < $v2, $v1, $v2);

}

@function to-string($list, $glue: '', $is-nested: false) {

$result: null;

@for $i from 1 through length($list) {
  $e: nth($list, $i);

  @if type-of($e) == list {
    $result: $result#{to-string($e, $glue, true)};
  } @else {
    $result: if($i != length($list) or $is-nested, $result#{$e}#{$glue}, $result#{$e});
  }
}

@return $result;

}

////// unit handling functions //////

@function strip-unit($number) {

@if type-of($number) == 'number' and not unitless($number) {
  @return $number / ($number * 0 + 1);
}

@return $number;

}

@function strip-unit-when-zero($number) {

@if type-of($number) == 'number' and not unitless($number) {
  $unitless: strip-unit($number);
  @if $unitless == 0 {
    @return $unitless;
  }
}

@return $number;

}

////// common css helper //////

// returns a color, based on an alpha-value against a background-color // its the fallback solution for browsers without rgba support @function fallback-rgba($color, $alpha, $background-color: fff) {

@return mix($color, $background-color, percentage($alpha));

}

////// building unit functions //////

// calculates the padding of a button in the context of building units @function building-unit-box-padding($line-height, $height, $padding-horizontal) {

@return floor(max(0, (($height * $building-unit - 1) - $line-height) / 2) - 1) max(0, ($padding-horizontal * $building-unit - 1)) floor(max(0, (($height * $building-unit - 1) - $line-height) / 2));

}

@function building-units($value) {

@return $value * $building-unit;

}

// returns the pixels of the capline to the top based on the font-size @function calculate-line-height-offset($font-size, $line-height) {

@return ($font-size * $line-height - $font-size) / 2;

}

@function capline-pixels($font-size, $line-height) {

@return ceil($font-size * $font-capline-top-ratio + calculate-line-height-offset($font-size, $line-height));

}

@function capline-bu($bu, $font-size, $line-height: 1) {

@return strip-unit-when-zero($bu * $building-unit - capline-pixels($font-size, $line-height));

}

// returns the pixels of the capline to the top based on the font-size @function baseline-pixels($font-size, $line-height) {

@return floor($font-size * $font-baseline-bottom-ratio + calculate-line-height-offset($font-size, $line-height));

}

@function baseline-bu($bu, $font-size, $line-height: 1) {

@return strip-unit-when-zero($bu * $building-unit - baseline-pixels($font-size, $line-height));

}

////// HSV calculations //////

// returns a hsv color @function hsv($hue: 0, $saturation: 100%, $value: 100%) {

@return ($hue, $saturation, $value, 1);

}

// returns a hsva color @function hsva($hue: 0, $saturation: 100%, $value: 100%, $alpha: 1) {

@return ($hue, $saturation, $value, $alpha);

}

// returns the converted hsv color, based on a rbg color @function color-to-hsv($r, $g: 0, $b: 0, $a: 1) {

$color: #000;

@if type-of($r) != 'color' {
  $color: rgba($r, $g, $b, $a);
} @else {
  $color: $r;
}

// rgba
$r: red($color) / 255;
$g: green($color) / 255;
$b: blue($color) / 255;
$a: alpha($color);

// conversion values
$cmax: max($r, max($g, $b));
$cmin: min($r, min($g, $b));
$delta: $cmax - $cmin;

// hsv
$hue: hue($color);
$saturation: 0;
@if $cmax != 0 {
  $saturation: percentage($delta / $cmax);
}
$value: percentage($cmax);

@return ($hue, $saturation, $value, $a);

}

// returns the converted rgb color, based on a hsv color @function hsv-to-color($h, $saturation: 100%, $value: 100%, $alpha: 1) {

@if type-of($h) == 'list' {
  $alpha: hsv-alpha($h);
  $value: hsv-value($h);
  $saturation: hsv-saturation($h);
  $h: hsv-hue($h);
} @else if type-of($h) == 'number' {
  @if unitless($h) {
    $h: (360 * (0 + $h)) + 'deg';
  }
}

$chroma: hsl($h, 100%, 50%);

@if unit($saturation) == '%' {
  $saturation: 0 + ($saturation / 100%);
}
@if unit($value) == '%' {
  $value: 0 + ($value / 100%);
}

$c: $value * $saturation;
$m: ($value - $c) * 255;

$r: max(0, min(red($chroma) * $c + $m, 255));
$g: max(0, min(green($chroma) * $c + $m, 255));
$b: max(0, min(blue($chroma) * $c + $m, 255));

$color: rgba($r, $g, $b, $alpha);

@return $color;

}

// HSV properties //

// returns the hue value of a hsv color @function hsv-hue($hsv) {

@if type-of($hsv) == 'color' {
  $hsv: color-to-hsv($hsv);
}
@return nth($hsv, 1);

}

// sets the hue value of a hsv color @function hsv-set-hue($hsv, $value, $return-rgb-color: false) {

@if type-of($hsv) == 'color' {
  $hsv: color-to-hsv($hsv);
}
$result: ($value, hsv-saturation($hsv), hsv-value($hsv), hsv-alpha($hsv));
@if ($return-rgb-color) {
  @return hsv-to-color($result);
}
@return $result;

}

// returns the saturation value of a hsv color @function hsv-saturation($hsv) {

@if type-of($hsv) == 'color' {
  $hsv: color-to-hsv($hsv);
}
@return nth($hsv, 2);

}

// sets the saturation value of a hsv color @function hsv-set-saturation($hsv, $value, $return-rgb-color: false) {

@if type-of($hsv) == 'color' {
  $hsv: color-to-hsv($hsv);
}
$current: nth($hsv, 2);
$result: hsv-adjust-saturation($hsv, $value - $current);
@if ($return-rgb-color) {
  @return hsv-to-color($result);
}
@return $result;

}

// returns the value of a hsv color @function hsv-value($hsv) {

@if type-of($hsv) == 'color' {
  $hsv: color-to-hsv($hsv);
}
@return nth($hsv, 3);

}

// sets the value of a hsv color @function hsv-set-value($hsv, $value, $return-rgb-color: false) {

@if type-of($hsv) == 'color' {
  $hsv: color-to-hsv($hsv);
}
$current: nth($hsv, 3);
$result: hsv-adjust-brightness($hsv, $value - $current);
@if ($return-rgb-color) {
  @return hsv-to-color($result);
}
@return $result;

}

// returns the alpha value of a hsv color @function hsv-alpha($hsv) {

@if type-of($hsv) == 'color' {
  $hsv: color-to-hsv($hsv);
}
@return nth($hsv, 4);

}

// sets the alpha value of a hsv color @function hsv-set-alpha($hsv, $value, $return-rgb-color: false) {

@if type-of($hsv) == 'color' {
  $hsv: color-to-hsv($hsv);
}
$result: (hsv-hue($hsv), hsv-saturation($hsv), hsv-value($hsv), $value);
@if ($return-rgb-color) {
  @return hsv-to-color($result);
}
@return $result;

}

// HSV adjustment functions //

// returns the inverted hsv color @function hsv-invert($hsv-color, $return-rgb-color: false) {

@if type-of($hsv-color) == 'color' {
  $hsv-color: color-to-hsv($hsv-color);
}

$result: hsva(360deg - hsv-hue($hsv-color), 100% - hsv-saturation($hsv-color), 100% - hsv-value($hsv-color), hsv-alpha($hsv-color));
@if ($return-rgb-color) {
  @return hsv-to-color($result);
}
@return $result;

}

// changes the brightness of a hsv color @function hsv-adjust-brightness($hsv-color, $value, $return-rgb-color: false) {

@if $hsv-color == false {
  @return false;
}

@if type-of($hsv-color) == 'color' {
  $hsv-color: color-to-hsv($hsv-color);
}

$hue: hsv-hue($hsv-color);
$saturation: hsv-saturation($hsv-color);
$brightness: hsv-value($hsv-color);
$alpha: hsv-alpha($hsv-color);

@if unit($value) == '%' {
  $value: 0 + ($value / 100%);
}

$brightness: max(0, min(($brightness / 100%) + $value, 1));
$result: ($hue, $saturation, percentage($brightness), $alpha);
@if ($return-rgb-color) {
  @return hsv-to-color($result);
}
@return $result;

}

// changes the hue value of a hsv color @function hsv-adjust-hue($hsv-color, $value, $return-rgb-color: false) {

@if $hsv-color == false {
  @return false;
}

@if type-of($hsv-color) == 'color' {
  $hsv-color: color-to-hsv($hsv-color);
}

$hue: hsv-hue($hsv-color);
$saturation: hsv-saturation($hsv-color);
$brightness: hsv-value($hsv-color);
$alpha: hsv-alpha($hsv-color);

@if unit($value) != 'deg' {
  $value: $value * 360deg;
}

$hue: max(0, min($hue + $value, 1));
$result: ($hue, $saturation, $brightness, $alpha);
@if ($return-rgb-color) {
  @return hsv-to-color($result);
}
@return $result;

}

// changes the saturation of a hsv color @function hsv-adjust-saturation($hsv-color, $value, $return-rgb-color: false) {

@if $hsv-color == false {
  @return false;
}

@if type-of($hsv-color) == 'color' {
  $hsv-color: color-to-hsv($hsv-color);
}

$hue: hsv-hue($hsv-color);
$saturation: hsv-saturation($hsv-color);
$brightness: hsv-value($hsv-color);
$alpha: hsv-alpha($hsv-color);

@if unit($value) == '%' {
  $value: 0 + ($value / 100%);
}

$saturation: max(0, min(($saturation / 100%) + $value, 1));
$result: ($hue, $saturation, $brightness, $alpha);

@if $return-rgb-color == true {
  @return hsv-to-color($result);
}
@return $result;

}

// cloned common HSV functions //

@function hsv-lighten($hsv-color, $value, $return-rgb-color: false) {

@return hsv-adjust-brightness($hsv-color, $value, $return-rgb-color);

}

@function hsv-darken($hsv-color, $value, $return-rgb-color: false) {

@return hsv-adjust-brightness($hsv-color, 0 - $value, $return-rgb-color);

}

@function hsv-saturate($hsv-color, $value, $return-rgb-color: false) {

@return hsv-adjust-saturation($hsv-color, $value, $return-rgb-color);

}

@function hsv-desaturate($hsv-color, $value, $return-rgb-color: false) {

@return hsv-adjust-saturation($hsv-color, 0 - $value, $return-rgb-color);

}

@function hsv-grayscale($hsv-color, $return-rgb-color: false) {

@return hsv-adjust-saturation($hsv-color, 0 - hsv-saturation($hsv-color), $return-rgb-color);

}

@function hsv-complement($hsv-color, $return-rgb-color: false) {

@if type-of($hsv-color) == 'color' {
  $hsv-color: color-to-hsv($hsv-color);
}
$deg: hsv-hue($hsv-color) + 180deg;
@if ($deg >= 360deg) {
  $deg: $deg - 360deg;
}
$result: hsva($deg, hsv-saturation($hsv-color), hsv-value($hsv-color), hsv-alpha($hsv-color));
@if $return-rgb-color == true {
  @return hsv-to-color($result);
}
@return $result;

}