/**
 *
 * @class Color
 * @author David Kaneda - https://www.davidkaneda.com
 *
 */

/**
 * Returns the brightness (out of 100) of a specified color.
 * @todo explain why this is useful
 * @param {color} $color The color you want the brightness value of
 * @return {measurement}
 */
@function brightness($color) {
    $r: red($color) / 255 * 100;
    $g: green($color) / 255 * 100;
    $b: blue($color) / 255 * 100;

    $brightness: (($r * 299) + ($g * 587) + ($b * 114)) / 1000;

    @return $brightness;
}

// @private
@function color-difference($c1, $c2) {
    @return (max(red($c1), red($c2)) - min(red($c1), red($c2))) + (max(green($c1), green($c2)) - min(green($c1), green($c2))) + (max(blue($c1), blue($c2)) - min(blue($c1), blue($c2)));
}

// @private
@function color-luminance($value) {
    @if $value <= 0.03928 {
        @return $value / 12.92;
    } @else {
        @return ($value + 0.055)/1.055 * ($value + 0.055)/1.055;
    }
}

/**
 * Returns the luminosity for a specified color
 * @param {color} The color to check
 * @return {measurement}
 */
@function luminosity($color) {
    $r: color-luminance(red($color) / 255);
    $g: color-luminance(green($color) / 255);
    $b: color-luminance(blue($color) / 255);
    $l: 0.2126 * $r + 0.7152 * $g + 0.0722 * $b;
    @debug 'luminosity for ' + $color + ' is ' + $l;
    @return $l;
}

/**
 * Returns the contrast ratio between two colors
 * @param {color1} The color to check
 * @return {measurement}
 */
@function contrast-ratio($color1, $color2) {
    $l1: luminosity($color1);
    $l2: luminosity($color2);

    @if $l2 > $l1 {
        @return $l2 / $l1;
    } @else {
        @return $l1 / $l2;
    }
}

@function get-color-mode($color) {
    @if brightness($color) > 55 {
        @return light;
    } @else {
        @return dark;
    }
}

@function color-offset($color, $contrast: 85%, $mode: $color-mode, $inverse: false) {
    $flat_color: check-opacity($color);

    @if $mode == inverse {
        $mode: reverse-color-mode($color-mode);
    }

    @if $inverse == true {
        $mode: reverse-color-mode($mode);
    }

    @if ($mode == light) {
        @return rgba(lighten($flat_color, $contrast), opacity($color));
    } @else if ($mode == dark) {
        @return rgba(darken($flat_color, $contrast), opacity($color));
    } @else {
        @debug $mode " is not a valid color mode. Use light, dark, or inverse.";
        @return white;
    }
}

@function reverse-color-mode($mode) {
    @if $mode == dark {
        @return light;
    } @else {
        @return dark;
    }
}

@function check-opacity($color) {
    @if (opacity($color) == 0) {
        $color: opacify($color, 1);
    }
    @if $color == transparent {
        $color: opacify($color, 1);
    }
    @return $color;
}

@function color-by-background($bg-color, $contrast: $default-text-contrast) {
    $bg-color: check-opacity($bg-color);
    $tmpmode: get-color-mode($bg-color);

    @return color-offset($bg-color, $contrast, $tmpmode, $inverse: true);
}

@function get-inset-offset($mode){
    @if $mode == light {
        @return 1px;
    } @else {
        @return -1px;
    }
}

@function safe-saturate($color, $amount) {
    @if saturation($color) > 0 {
        @return saturate($color, $amount);
    } @else {
        @return $color;
    }
}

/**
 * Colors the text of an element based on lightness of its background.
 *
 *     .my-element {
 *       @include color-by-background(#fff); // Colors text black.
 *     }
 *
 *     .my-element {
 *       @include color-by-background(#fff, 40%); // Colors text gray.
 *     }
 *
 * @param {color} $bg-color Background color of element.
 * @param {percent} $contrast Contrast of text color to its background.
 *
 */
@mixin color-by-background($bg-color, $contrast: $default-text-contrast, $default-color: false, $inset-text: false) {
    @if $default-color {
        color: color-by-background(hsla(hue($default-color), saturation($default-color), lightness($bg-color), opacity($bg-color)), $contrast);
    } @else {
        color: color-by-background($bg-color, $contrast);
    }

    @if $inset-text {
        @include inset-by-background($bg-color);
    }
}

@mixin inset-by-background($bg-color, $contrast: 10%, $box: false){
    $bg-color: check-opacity($bg-color);
    $offset: get-inset-offset(get-color-mode($bg-color));

    @if ($box == true) {
        @include box-shadow(color-offset($bg-color, $contrast, $mode: get-color-mode($bg-color)) 0 $offset 0);
    }

    @include text-shadow(color-offset($bg-color, $contrast, $mode: get-color-mode($bg-color)) 0 $offset 0);
}

@function hsv-to-rgb($color) {
    $r: red($color) / 255;
    $g: green($color) / 255;
    $b: blue($color) / 255;
    $a: opacity($color);
}

// @debug hsv(rgba(#3E87E3, .5));

@function brighten($color, $amount) {
    $current_brightness: brightness($color);
}

$base-color: blue !default;
$neutral-color: #ccc !default;
$highlight-color: darken(safe-saturate($base-color, 15), 5) !default;

$default-text-contrast: 85% !default;
$color-mode: get-color-mode($neutral-color) !default;

// @debug color-difference(#95419F, #0FFF90);
// @debug brightness(#cbea0d) - brightness(#ea850d);
// @debug contrast-ratio(#95419F, #0FFF90);
// @debug brightness(#E0F200);