xref: /template/strap/ComboStrap/ColorRgb.php (revision 04fd306c7c155fa133ebb3669986875d65988276)
14cadd4f8SNickeau<?php
24cadd4f8SNickeau/**
34cadd4f8SNickeau * Copyright (c) 2020. ComboStrap, Inc. and its affiliates. All Rights Reserved.
44cadd4f8SNickeau *
54cadd4f8SNickeau * This source code is licensed under the GPL license found in the
64cadd4f8SNickeau * COPYING  file in the root directory of this source tree.
74cadd4f8SNickeau *
84cadd4f8SNickeau * @license  GPL 3 (https://www.gnu.org/licenses/gpl-3.0.en.html)
94cadd4f8SNickeau * @author   ComboStrap <support@combostrap.com>
104cadd4f8SNickeau *
114cadd4f8SNickeau */
124cadd4f8SNickeau
134cadd4f8SNickeaunamespace ComboStrap;
144cadd4f8SNickeau
154cadd4f8SNickeau
164cadd4f8SNickeauuse dokuwiki\StyleUtils;
174cadd4f8SNickeau
184cadd4f8SNickeauclass ColorRgb
194cadd4f8SNickeau{
204cadd4f8SNickeau
214cadd4f8SNickeau    const COLOR = "color";
224cadd4f8SNickeau
234cadd4f8SNickeau    const BORDER_COLOR = "border-color";
244cadd4f8SNickeau
254cadd4f8SNickeau    const BOOTSTRAP_COLORS = array(
264cadd4f8SNickeau        'blue',
274cadd4f8SNickeau        'indigo',
284cadd4f8SNickeau        'purple',
294cadd4f8SNickeau        'pink',
304cadd4f8SNickeau        'red',
314cadd4f8SNickeau        'orange',
324cadd4f8SNickeau        'yellow',
334cadd4f8SNickeau        'green',
344cadd4f8SNickeau        'teal',
354cadd4f8SNickeau        'cyan',
364cadd4f8SNickeau        //'white', css value for now otherwise we don't know the value when tinting
374cadd4f8SNickeau        //'gray', css value for now otherwise we don't know the value when tinting
384cadd4f8SNickeau        'gray-dark',
394cadd4f8SNickeau        self::PRIMARY_VALUE,
404cadd4f8SNickeau        self::SECONDARY_VALUE,
414cadd4f8SNickeau        'success',
424cadd4f8SNickeau        'info',
434cadd4f8SNickeau        'warning',
444cadd4f8SNickeau        'danger',
454cadd4f8SNickeau        'light',
464cadd4f8SNickeau        'dark'
474cadd4f8SNickeau    );
484cadd4f8SNickeau    /**
494cadd4f8SNickeau     * https://drafts.csswg.org/css-color/#color-keywords
50*04fd306cSNickeau     *
51*04fd306cSNickeau     * See also: https://www.w3.org/TR/SVG11/types.html#ColorKeywords
524cadd4f8SNickeau     */
534cadd4f8SNickeau    const CSS_COLOR_NAMES = array(
544cadd4f8SNickeau        'aliceblue' => '#F0F8FF',
554cadd4f8SNickeau        'antiquewhite' => '#FAEBD7',
564cadd4f8SNickeau        'aqua' => '#00FFFF',
574cadd4f8SNickeau        'aquamarine' => '#7FFFD4',
584cadd4f8SNickeau        'azure' => '#F0FFFF',
594cadd4f8SNickeau        'beige' => '#F5F5DC',
604cadd4f8SNickeau        'bisque' => '#FFE4C4',
614cadd4f8SNickeau        'black' => '#000000',
624cadd4f8SNickeau        'blanchedalmond' => '#FFEBCD',
634cadd4f8SNickeau        'blue' => '#0000FF',
644cadd4f8SNickeau        'blueviolet' => '#8A2BE2',
654cadd4f8SNickeau        'brown' => '#A52A2A',
664cadd4f8SNickeau        'burlywood' => '#DEB887',
674cadd4f8SNickeau        'cadetblue' => '#5F9EA0',
684cadd4f8SNickeau        'chartreuse' => '#7FFF00',
694cadd4f8SNickeau        'chocolate' => '#D2691E',
704cadd4f8SNickeau        'coral' => '#FF7F50',
714cadd4f8SNickeau        'cornflowerblue' => '#6495ED',
724cadd4f8SNickeau        'cornsilk' => '#FFF8DC',
734cadd4f8SNickeau        'crimson' => '#DC143C',
744cadd4f8SNickeau        'cyan' => '#00FFFF',
754cadd4f8SNickeau        'darkblue' => '#00008B',
764cadd4f8SNickeau        'darkcyan' => '#008B8B',
774cadd4f8SNickeau        'darkgoldenrod' => '#B8860B',
784cadd4f8SNickeau        'darkgray' => '#A9A9A9',
794cadd4f8SNickeau        'darkgreen' => '#006400',
804cadd4f8SNickeau        'darkgrey' => '#A9A9A9',
814cadd4f8SNickeau        'darkkhaki' => '#BDB76B',
824cadd4f8SNickeau        'darkmagenta' => '#8B008B',
834cadd4f8SNickeau        'darkolivegreen' => '#556B2F',
844cadd4f8SNickeau        'darkorange' => '#FF8C00',
854cadd4f8SNickeau        'darkorchid' => '#9932CC',
864cadd4f8SNickeau        'darkred' => '#8B0000',
874cadd4f8SNickeau        'darksalmon' => '#E9967A',
884cadd4f8SNickeau        'darkseagreen' => '#8FBC8F',
894cadd4f8SNickeau        'darkslateblue' => '#483D8B',
904cadd4f8SNickeau        'darkslategray' => '#2F4F4F',
914cadd4f8SNickeau        'darkslategrey' => '#2F4F4F',
924cadd4f8SNickeau        'darkturquoise' => '#00CED1',
934cadd4f8SNickeau        'darkviolet' => '#9400D3',
944cadd4f8SNickeau        'deeppink' => '#FF1493',
954cadd4f8SNickeau        'deepskyblue' => '#00BFFF',
964cadd4f8SNickeau        'dimgray' => '#696969',
974cadd4f8SNickeau        'dimgrey' => '#696969',
984cadd4f8SNickeau        'dodgerblue' => '#1E90FF',
994cadd4f8SNickeau        'firebrick' => '#B22222',
1004cadd4f8SNickeau        'floralwhite' => '#FFFAF0',
1014cadd4f8SNickeau        'forestgreen' => '#228B22',
1024cadd4f8SNickeau        'fuchsia' => '#FF00FF',
1034cadd4f8SNickeau        'gainsboro' => '#DCDCDC',
1044cadd4f8SNickeau        'ghostwhite' => '#F8F8FF',
1054cadd4f8SNickeau        'gold' => '#FFD700',
1064cadd4f8SNickeau        'goldenrod' => '#DAA520',
1074cadd4f8SNickeau        'gray' => '#808080',
1084cadd4f8SNickeau        'green' => '#008000',
1094cadd4f8SNickeau        'greenyellow' => '#ADFF2F',
1104cadd4f8SNickeau        'grey' => '#808080',
1114cadd4f8SNickeau        'honeydew' => '#F0FFF0',
1124cadd4f8SNickeau        'hotpink' => '#FF69B4',
1134cadd4f8SNickeau        'indianred' => '#CD5C5C',
1144cadd4f8SNickeau        'indigo' => '#4B0082',
1154cadd4f8SNickeau        'ivory' => '#FFFFF0',
1164cadd4f8SNickeau        'khaki' => '#F0E68C',
1174cadd4f8SNickeau        'lavender' => '#E6E6FA',
1184cadd4f8SNickeau        'lavenderblush' => '#FFF0F5',
1194cadd4f8SNickeau        'lawngreen' => '#7CFC00',
1204cadd4f8SNickeau        'lemonchiffon' => '#FFFACD',
1214cadd4f8SNickeau        'lightblue' => '#ADD8E6',
1224cadd4f8SNickeau        'lightcoral' => '#F08080',
1234cadd4f8SNickeau        'lightcyan' => '#E0FFFF',
1244cadd4f8SNickeau        'lightgoldenrodyellow' => '#FAFAD2',
1254cadd4f8SNickeau        'lightgray' => '#D3D3D3',
1264cadd4f8SNickeau        'lightgreen' => '#90EE90',
1274cadd4f8SNickeau        'lightgrey' => '#D3D3D3',
1284cadd4f8SNickeau        'lightpink' => '#FFB6C1',
1294cadd4f8SNickeau        'lightsalmon' => '#FFA07A',
1304cadd4f8SNickeau        'lightseagreen' => '#20B2AA',
1314cadd4f8SNickeau        'lightskyblue' => '#87CEFA',
1324cadd4f8SNickeau        'lightslategray' => '#778899',
1334cadd4f8SNickeau        'lightslategrey' => '#778899',
1344cadd4f8SNickeau        'lightsteelblue' => '#B0C4DE',
1354cadd4f8SNickeau        'lightyellow' => '#FFFFE0',
1364cadd4f8SNickeau        'lime' => '#00FF00',
1374cadd4f8SNickeau        'limegreen' => '#32CD32',
1384cadd4f8SNickeau        'linen' => '#FAF0E6',
1394cadd4f8SNickeau        'magenta' => '#FF00FF',
1404cadd4f8SNickeau        'maroon' => '#800000',
1414cadd4f8SNickeau        'mediumaquamarine' => '#66CDAA',
1424cadd4f8SNickeau        'mediumblue' => '#0000CD',
1434cadd4f8SNickeau        'mediumorchid' => '#BA55D3',
1444cadd4f8SNickeau        'mediumpurple' => '#9370DB',
1454cadd4f8SNickeau        'mediumseagreen' => '#3CB371',
1464cadd4f8SNickeau        'mediumslateblue' => '#7B68EE',
1474cadd4f8SNickeau        'mediumspringgreen' => '#00FA9A',
1484cadd4f8SNickeau        'mediumturquoise' => '#48D1CC',
1494cadd4f8SNickeau        'mediumvioletred' => '#C71585',
1504cadd4f8SNickeau        'midnightblue' => '#191970',
1514cadd4f8SNickeau        'mintcream' => '#F5FFFA',
1524cadd4f8SNickeau        'mistyrose' => '#FFE4E1',
1534cadd4f8SNickeau        'moccasin' => '#FFE4B5',
1544cadd4f8SNickeau        'navajowhite' => '#FFDEAD',
1554cadd4f8SNickeau        'navy' => '#000080',
1564cadd4f8SNickeau        'oldlace' => '#FDF5E6',
1574cadd4f8SNickeau        'olive' => '#808000',
1584cadd4f8SNickeau        'olivedrab' => '#6B8E23',
1594cadd4f8SNickeau        'orange' => '#FFA500',
1604cadd4f8SNickeau        'orangered' => '#FF4500',
1614cadd4f8SNickeau        'orchid' => '#DA70D6',
1624cadd4f8SNickeau        'palegoldenrod' => '#EEE8AA',
1634cadd4f8SNickeau        'palegreen' => '#98FB98',
1644cadd4f8SNickeau        'paleturquoise' => '#AFEEEE',
1654cadd4f8SNickeau        'palevioletred' => '#DB7093',
1664cadd4f8SNickeau        'papayawhip' => '#FFEFD5',
1674cadd4f8SNickeau        'peachpuff' => '#FFDAB9',
1684cadd4f8SNickeau        'peru' => '#CD853F',
1694cadd4f8SNickeau        'pink' => '#FFC0CB',
1704cadd4f8SNickeau        'plum' => '#DDA0DD',
1714cadd4f8SNickeau        'powderblue' => '#B0E0E6',
1724cadd4f8SNickeau        'purple' => '#800080',
1734cadd4f8SNickeau        'rebeccapurple' => '#663399',
1744cadd4f8SNickeau        'red' => '#FF0000',
1754cadd4f8SNickeau        'rosybrown' => '#BC8F8F',
1764cadd4f8SNickeau        'royalblue' => '#4169E1',
1774cadd4f8SNickeau        'saddlebrown' => '#8B4513',
1784cadd4f8SNickeau        'salmon' => '#FA8072',
1794cadd4f8SNickeau        'sandybrown' => '#F4A460',
1804cadd4f8SNickeau        'seagreen' => '#2E8B57',
1814cadd4f8SNickeau        'seashell' => '#FFF5EE',
1824cadd4f8SNickeau        'sienna' => '#A0522D',
1834cadd4f8SNickeau        'silver' => '#C0C0C0',
1844cadd4f8SNickeau        'skyblue' => '#87CEEB',
1854cadd4f8SNickeau        'slateblue' => '#6A5ACD',
1864cadd4f8SNickeau        'slategray' => '#708090',
1874cadd4f8SNickeau        'slategrey' => '#708090',
1884cadd4f8SNickeau        'snow' => '#FFFAFA',
1894cadd4f8SNickeau        'springgreen' => '#00FF7F',
1904cadd4f8SNickeau        'steelblue' => '#4682B4',
1914cadd4f8SNickeau        'tan' => '#D2B48C',
1924cadd4f8SNickeau        'teal' => '#008080',
1934cadd4f8SNickeau        'tip' => self::TIP_COLOR,
1944cadd4f8SNickeau        'thistle' => '#D8BFD8',
1954cadd4f8SNickeau        'tomato' => '#FF6347',
1964cadd4f8SNickeau        'turquoise' => '#40E0D0',
1974cadd4f8SNickeau        'violet' => '#EE82EE',
1984cadd4f8SNickeau        'wheat' => '#F5DEB3',
1994cadd4f8SNickeau        'white' => '#FFFFFF',
2004cadd4f8SNickeau        'whitesmoke' => '#F5F5F5',
2014cadd4f8SNickeau        'yellow' => '#FFFF00',
2024cadd4f8SNickeau        'yellowgreen' => '#9ACD32'
2034cadd4f8SNickeau    );
2044cadd4f8SNickeau
2054cadd4f8SNickeau    /**
2064cadd4f8SNickeau     * Branding colors
2074cadd4f8SNickeau     */
2084cadd4f8SNickeau    const PRIMARY_VALUE = "primary";
2094cadd4f8SNickeau    const SECONDARY_VALUE = "secondary";
2104cadd4f8SNickeau
2114cadd4f8SNickeau    const SECONDARY_COLOR_CONF = "secondaryColor";
2124cadd4f8SNickeau    const BRANDING_COLOR_CANONICAL = "branding-colors";
2134cadd4f8SNickeau    public const BACKGROUND_COLOR = "background-color";
2144cadd4f8SNickeau
2154cadd4f8SNickeau    // the value is a bootstrap name
2164cadd4f8SNickeau    const VALUE_TYPE_BOOTSTRAP_NAME = "bootstrap";
2174cadd4f8SNickeau    const VALUE_TYPE_RGB_HEX = "rgb-hex";
2184cadd4f8SNickeau    const VALUE_TYPE_RGB_ARRAY = "rgb-array";
2194cadd4f8SNickeau    const VALUE_TYPE_RESET = "reset";
2204cadd4f8SNickeau    const VALUE_TYPE_CSS_NAME = "css-name";
2214cadd4f8SNickeau    const VALUE_TYPE_UNKNOWN_NAME = "unknown-name";
2224cadd4f8SNickeau
2234cadd4f8SNickeau    /**
2244cadd4f8SNickeau     * Minimum recommended ratio by the w3c
2254cadd4f8SNickeau     */
2264cadd4f8SNickeau    const MINIMUM_CONTRAST_RATIO = 5;
2274cadd4f8SNickeau    const WHITE = "white";
2284cadd4f8SNickeau    const TIP_COLOR = "#ffee33";
2294cadd4f8SNickeau    const CURRENT_COLOR = "currentColor";
2304cadd4f8SNickeau
2314cadd4f8SNickeau    /**
2324cadd4f8SNickeau     * @var array
2334cadd4f8SNickeau     */
2344cadd4f8SNickeau    private static $dokuWikiStyles;
2354cadd4f8SNickeau
2364cadd4f8SNickeau    /**
2374cadd4f8SNickeau     * @var int
2384cadd4f8SNickeau     */
2394cadd4f8SNickeau    private $red;
2404cadd4f8SNickeau    /**
2414cadd4f8SNickeau     * @var mixed
2424cadd4f8SNickeau     */
2434cadd4f8SNickeau    private $green;
2444cadd4f8SNickeau    /**
2454cadd4f8SNickeau     * @var mixed
2464cadd4f8SNickeau     */
2474cadd4f8SNickeau    private $blue;
2484cadd4f8SNickeau    /**
2494cadd4f8SNickeau     * @var string
2504cadd4f8SNickeau     */
2514cadd4f8SNickeau    private $nameType = self::VALUE_TYPE_UNKNOWN_NAME;
2524cadd4f8SNickeau    /**
2534cadd4f8SNickeau     * The color name
2544cadd4f8SNickeau     * It can be:
2554cadd4f8SNickeau     *   * a bootstrap
2564cadd4f8SNickeau     *   * a css name
2574cadd4f8SNickeau     *   * or `reset`
2584cadd4f8SNickeau     * @var null|string
2594cadd4f8SNickeau     */
2604cadd4f8SNickeau    private $name;
2614cadd4f8SNickeau    private $transparency;
2624cadd4f8SNickeau
2634cadd4f8SNickeau
2644cadd4f8SNickeau    /**
2654cadd4f8SNickeau     * The styles of the dokuwiki systems
2664cadd4f8SNickeau     * @return array
2674cadd4f8SNickeau     */
2684cadd4f8SNickeau    public static function getDokuWikiStyles(): array
2694cadd4f8SNickeau    {
2704cadd4f8SNickeau        if (self::$dokuWikiStyles === null) {
2714cadd4f8SNickeau            self::$dokuWikiStyles = (new StyleUtils())->cssStyleini();
2724cadd4f8SNickeau        }
2734cadd4f8SNickeau        return self::$dokuWikiStyles;
2744cadd4f8SNickeau
2754cadd4f8SNickeau    }
2764cadd4f8SNickeau
2774cadd4f8SNickeau    /**
278*04fd306cSNickeau     * @return ColorRgb - the default primary color in case of any errors
279*04fd306cSNickeau     * Used only in case of errors
280*04fd306cSNickeau     */
281*04fd306cSNickeau    public static function getDefaultPrimary(): ColorRgb
282*04fd306cSNickeau    {
283*04fd306cSNickeau        try {
284*04fd306cSNickeau            return self::createFromHex("#0d6efd");
285*04fd306cSNickeau        } catch (ExceptionCompile $e) {
286*04fd306cSNickeau            throw new ExceptionRuntimeInternal("It should not happen as the rbg channles are handwritten");
287*04fd306cSNickeau        }
288*04fd306cSNickeau    }
289*04fd306cSNickeau
290*04fd306cSNickeau    /**
2914cadd4f8SNickeau     * Same round instructions than SCSS to be able to do the test
2924cadd4f8SNickeau     * have value as bootstrap
2934cadd4f8SNickeau     * @param float $value
2944cadd4f8SNickeau     * @return float
2954cadd4f8SNickeau     */
2964cadd4f8SNickeau    private static function round(float $value): float
2974cadd4f8SNickeau    {
2984cadd4f8SNickeau        $rest = fmod($value, 1);
2994cadd4f8SNickeau        if ($rest < 0.5) {
3004cadd4f8SNickeau            return round($value, 0, PHP_ROUND_HALF_DOWN);
3014cadd4f8SNickeau        } else {
3024cadd4f8SNickeau            return round($value, 0, PHP_ROUND_HALF_UP);
3034cadd4f8SNickeau        }
3044cadd4f8SNickeau    }
3054cadd4f8SNickeau
3064cadd4f8SNickeau    /**
307*04fd306cSNickeau     * @throws ExceptionCompile
3084cadd4f8SNickeau     */
3094cadd4f8SNickeau    public static function createFromRgbChannels(int $red, int $green, int $blue): ColorRgb
3104cadd4f8SNickeau    {
3114cadd4f8SNickeau        return (new ColorRgb())
3124cadd4f8SNickeau            ->setRgbChannels([$red, $green, $blue]);
3134cadd4f8SNickeau    }
3144cadd4f8SNickeau
3154cadd4f8SNickeau    /**
3164cadd4f8SNickeau     * Utility function to get white
317*04fd306cSNickeau     * @throws ExceptionCompile
3184cadd4f8SNickeau     */
3194cadd4f8SNickeau    public static function getWhite(): ColorRgb
3204cadd4f8SNickeau    {
3214cadd4f8SNickeau
3224cadd4f8SNickeau        return (new ColorRgb())
3234cadd4f8SNickeau            ->setName("white")
3244cadd4f8SNickeau            ->setRgbChannels([255, 255, 255])
3254cadd4f8SNickeau            ->setNameType(self::VALUE_TYPE_CSS_NAME);
3264cadd4f8SNickeau
3274cadd4f8SNickeau    }
3284cadd4f8SNickeau
3294cadd4f8SNickeau    /**
3304cadd4f8SNickeau     * Utility function to get black
3314cadd4f8SNickeau     */
3324cadd4f8SNickeau    public static function getBlack(): ColorRgb
3334cadd4f8SNickeau    {
3344cadd4f8SNickeau
335*04fd306cSNickeau        try {
3364cadd4f8SNickeau            return (new ColorRgb())
3374cadd4f8SNickeau                ->setName("black")
3384cadd4f8SNickeau                ->setRgbChannels([0, 0, 0])
3394cadd4f8SNickeau                ->setNameType(self::VALUE_TYPE_CSS_NAME);
340*04fd306cSNickeau        } catch (ExceptionCompile $e) {
341*04fd306cSNickeau            throw new ExceptionRuntimeInternal("It should not happen as the rbg channles are handwritten");
342*04fd306cSNickeau        }
3434cadd4f8SNickeau
3444cadd4f8SNickeau    }
3454cadd4f8SNickeau
3464cadd4f8SNickeau    /**
347*04fd306cSNickeau     * @throws ExceptionBadArgument
3484cadd4f8SNickeau     */
349*04fd306cSNickeau    public static function createFromHex(string $color): ColorRgb
3504cadd4f8SNickeau    {
3514cadd4f8SNickeau
3524cadd4f8SNickeau        return (new ColorRgb())
3534cadd4f8SNickeau            ->setHex($color);
3544cadd4f8SNickeau
3554cadd4f8SNickeau
3564cadd4f8SNickeau    }
3574cadd4f8SNickeau
3584cadd4f8SNickeau
3594cadd4f8SNickeau    /**
3604cadd4f8SNickeau     * @return ColorHsl
361*04fd306cSNickeau     * @throws ExceptionCompile
3624cadd4f8SNickeau     */
3634cadd4f8SNickeau    public function toHsl(): ColorHsl
3644cadd4f8SNickeau    {
3654cadd4f8SNickeau
3664cadd4f8SNickeau        if ($this->red === null) {
367*04fd306cSNickeau            throw new ExceptionCompile("This color ($this) does not have any channel known, we can't transform it to hsl");
3684cadd4f8SNickeau        }
3694cadd4f8SNickeau        $red = $this->red / 255;
3704cadd4f8SNickeau        $green = $this->green / 255;
3714cadd4f8SNickeau        $blue = $this->blue / 255;
3724cadd4f8SNickeau
3734cadd4f8SNickeau        $max = max($red, $green, $blue);
3744cadd4f8SNickeau        $min = min($red, $green, $blue);
3754cadd4f8SNickeau
3764cadd4f8SNickeau
3774cadd4f8SNickeau        $lightness = ($max + $min) / 2;
3784cadd4f8SNickeau        $d = $max - $min;
3794cadd4f8SNickeau
3804cadd4f8SNickeau        if ($d == 0) {
3814cadd4f8SNickeau            $hue = $saturation = 0; // achromatic
3824cadd4f8SNickeau        } else {
3834cadd4f8SNickeau            $saturation = $d / (1 - abs(2 * $lightness - 1));
3844cadd4f8SNickeau
3854cadd4f8SNickeau            switch ($max) {
3864cadd4f8SNickeau                case $red:
3874cadd4f8SNickeau                    $hue = 60 * fmod((($green - $blue) / $d), 6);
3884cadd4f8SNickeau                    if ($blue > $green) {
3894cadd4f8SNickeau                        $hue += 360;
3904cadd4f8SNickeau                    }
3914cadd4f8SNickeau                    break;
3924cadd4f8SNickeau
3934cadd4f8SNickeau                case $green:
3944cadd4f8SNickeau                    $hue = 60 * (($blue - $red) / $d + 2);
3954cadd4f8SNickeau                    break;
3964cadd4f8SNickeau
3974cadd4f8SNickeau                default:
3984cadd4f8SNickeau                case $blue:
3994cadd4f8SNickeau                    $hue = 60 * (($red - $green) / $d + 4);
4004cadd4f8SNickeau                    break;
4014cadd4f8SNickeau
4024cadd4f8SNickeau            }
4034cadd4f8SNickeau        }
4044cadd4f8SNickeau
4054cadd4f8SNickeau        /**
4064cadd4f8SNickeau         * No round to get a neat inverse
4074cadd4f8SNickeau         */
4084cadd4f8SNickeau
4094cadd4f8SNickeau        return ColorHsl::createFromChannels($hue, $saturation * 100, $lightness * 100);
4104cadd4f8SNickeau
4114cadd4f8SNickeau
4124cadd4f8SNickeau    }
4134cadd4f8SNickeau
4144cadd4f8SNickeau
4154cadd4f8SNickeau    /**
4164cadd4f8SNickeau     * @param array|string|ColorRgb $color
4174cadd4f8SNickeau     * @param int|null $weight
4184cadd4f8SNickeau     * @return ColorRgb
4194cadd4f8SNickeau     *
4204cadd4f8SNickeau     *
4214cadd4f8SNickeau     * Because Bootstrap uses the mix function of SCSS
4224cadd4f8SNickeau     * https://sass-lang.com/documentation/modules/color#mix
4234cadd4f8SNickeau     * We try to be as clause as possible
4244cadd4f8SNickeau     *
4254cadd4f8SNickeau     * https://gist.github.com/jedfoster/7939513
4264cadd4f8SNickeau     *
4274cadd4f8SNickeau     * This is a linear extrapolation along the segment
428*04fd306cSNickeau     * @throws ExceptionCompile
4294cadd4f8SNickeau     */
4304cadd4f8SNickeau    function mix($color, ?int $weight = 50): ColorRgb
4314cadd4f8SNickeau    {
4324cadd4f8SNickeau        if ($weight === null) {
4334cadd4f8SNickeau            $weight = 50;
4344cadd4f8SNickeau        }
4354cadd4f8SNickeau
4364cadd4f8SNickeau        $color2 = ColorRgb::createFromString($color);
4374cadd4f8SNickeau        $targetRed = self::round(Math::lerp($color2->getRed(), $this->getRed(), $weight));
4384cadd4f8SNickeau        $targetGreen = self::round(Math::lerp($color2->getGreen(), $this->getGreen(), $weight));
4394cadd4f8SNickeau        $targetBlue = self::round(Math::lerp($color2->getBlue(), $this->getBlue(), $weight));
4404cadd4f8SNickeau        return ColorRgb::createFromRgbChannels($targetRed, $targetGreen, $targetBlue);
4414cadd4f8SNickeau
4424cadd4f8SNickeau    }
4434cadd4f8SNickeau
4444cadd4f8SNickeau    /**
445*04fd306cSNickeau     * @throws ExceptionCompile
4464cadd4f8SNickeau     */
4474cadd4f8SNickeau    function unmix($color, ?int $weight = 50): ColorRgb
4484cadd4f8SNickeau    {
4494cadd4f8SNickeau        if ($weight === null) {
4504cadd4f8SNickeau            $weight = 50;
4514cadd4f8SNickeau        }
4524cadd4f8SNickeau
4534cadd4f8SNickeau        $color2 = ColorRgb::createFromString($color);
4544cadd4f8SNickeau        $targetRed = self::round(Math::unlerp($color2->getRed(), $this->getRed(), $weight));
4554cadd4f8SNickeau        if ($targetRed < 0) {
456*04fd306cSNickeau            throw new ExceptionCompile("This is not possible, the red value ({$color2->getBlue()}) with the percentage $weight could not be unmixed. They were not calculated with color mixing.");
4574cadd4f8SNickeau        }
4584cadd4f8SNickeau        $targetGreen = self::round(Math::unlerp($color2->getGreen(), $this->getGreen(), $weight));
4594cadd4f8SNickeau        if ($targetGreen < 0) {
460*04fd306cSNickeau            throw new ExceptionCompile("This is not possible, the green value ({$color2->getGreen()}) with the percentage $weight could not be unmixed. They were not calculated with color mixing.");
4614cadd4f8SNickeau        }
4624cadd4f8SNickeau        $targetBlue = self::round(Math::unlerp($color2->getBlue(), $this->getBlue(), $weight));
4634cadd4f8SNickeau        if ($targetBlue < 0) {
464*04fd306cSNickeau            throw new ExceptionCompile("This is not possible, the blue value ({$color2->getBlue()}) with the percentage $weight could not be unmixed. They were not calculated with color mixing.");
4654cadd4f8SNickeau        }
4664cadd4f8SNickeau        return ColorRgb::createFromRgbChannels($targetRed, $targetGreen, $targetBlue);
4674cadd4f8SNickeau
4684cadd4f8SNickeau    }
4694cadd4f8SNickeau
4704cadd4f8SNickeau    /**
4714cadd4f8SNickeau     * Takes an hexadecimal color and returns the rgb channels
4724cadd4f8SNickeau     *
4734cadd4f8SNickeau     * @param mixed $hex
4744cadd4f8SNickeau     *
475*04fd306cSNickeau     * @throws ExceptionBadArgument
4764cadd4f8SNickeau     */
4774cadd4f8SNickeau    function hex2rgb($hex = '#000000'): array
4784cadd4f8SNickeau    {
4794cadd4f8SNickeau        if ($hex[0] !== "#") {
480*04fd306cSNickeau            throw new ExceptionBadArgument("The color value ($hex) does not start with a #, this is not valid CSS hexadecimal color value");
4814cadd4f8SNickeau        }
4824cadd4f8SNickeau        $digits = str_replace("#", "", $hex);
4834cadd4f8SNickeau        $hexLen = strlen($digits);
4844cadd4f8SNickeau        $transparency = false;
4854cadd4f8SNickeau        switch ($hexLen) {
4864cadd4f8SNickeau            case 3:
4874cadd4f8SNickeau                $lengthColorHex = 1;
4884cadd4f8SNickeau                break;
4894cadd4f8SNickeau            case 6:
4904cadd4f8SNickeau                $lengthColorHex = 2;
4914cadd4f8SNickeau                break;
4924cadd4f8SNickeau            case 8:
4934cadd4f8SNickeau                $lengthColorHex = 2;
4944cadd4f8SNickeau                $transparency = true;
4954cadd4f8SNickeau                break;
4964cadd4f8SNickeau            default:
497*04fd306cSNickeau                throw new ExceptionBadArgument("The digit color value ($hex) is not 3 or 6 in length, this is not a valid CSS hexadecimal color value");
4984cadd4f8SNickeau        }
4994cadd4f8SNickeau        $result = preg_match("/[0-9a-f]{3,8}/i", $digits);
5004cadd4f8SNickeau        if ($result !== 1) {
501*04fd306cSNickeau            throw new ExceptionBadArgument("The digit color value ($hex) is not a hexadecimal value, this is not a valid CSS hexadecimal color value");
5024cadd4f8SNickeau        }
5034cadd4f8SNickeau        $channelHexs = str_split($digits, $lengthColorHex);
5044cadd4f8SNickeau        $rgbDec = [];
5054cadd4f8SNickeau        foreach ($channelHexs as $channelHex) {
5064cadd4f8SNickeau            if ($lengthColorHex === 1) {
5074cadd4f8SNickeau                $channelHex .= $channelHex;
5084cadd4f8SNickeau            }
5094cadd4f8SNickeau            $rgbDec[] = hexdec($channelHex);
5104cadd4f8SNickeau        }
5114cadd4f8SNickeau        if (!$transparency) {
5124cadd4f8SNickeau            $rgbDec[] = null;
5134cadd4f8SNickeau        }
5144cadd4f8SNickeau        return $rgbDec;
5154cadd4f8SNickeau    }
5164cadd4f8SNickeau
5174cadd4f8SNickeau    /**
5184cadd4f8SNickeau     * rgb2hex
5194cadd4f8SNickeau     *
5204cadd4f8SNickeau     * @return string
5214cadd4f8SNickeau     */
5224cadd4f8SNickeau    function toRgbHex(): string
5234cadd4f8SNickeau    {
5244cadd4f8SNickeau
5254cadd4f8SNickeau        switch ($this->nameType) {
5264cadd4f8SNickeau            case self::VALUE_TYPE_CSS_NAME:
5274cadd4f8SNickeau                return strtolower(self::CSS_COLOR_NAMES[$this->name]);
5284cadd4f8SNickeau            default:
5294cadd4f8SNickeau                $toCssHex = function ($x) {
5304cadd4f8SNickeau                    return str_pad(dechex($x), 2, "0", STR_PAD_LEFT);
5314cadd4f8SNickeau                };
5324cadd4f8SNickeau                $redHex = $toCssHex($this->getRed());
5334cadd4f8SNickeau                $greenHex = $toCssHex($this->getGreen());
5344cadd4f8SNickeau                $blueHex = $toCssHex($this->getBlue());
5354cadd4f8SNickeau                $withoutAlpha = "#" . $redHex . $greenHex . $blueHex;
5364cadd4f8SNickeau                if ($this->transparency === null) {
5374cadd4f8SNickeau                    return $withoutAlpha;
5384cadd4f8SNickeau                }
5394cadd4f8SNickeau                return $withoutAlpha . $toCssHex($this->getTransparency());
5404cadd4f8SNickeau        }
5414cadd4f8SNickeau
5424cadd4f8SNickeau    }
5434cadd4f8SNickeau
5444cadd4f8SNickeau    /**
545*04fd306cSNickeau     * @throws ExceptionBadArgument
5464cadd4f8SNickeau     */
5474cadd4f8SNickeau    public
5484cadd4f8SNickeau    static function createFromString(string $color): ColorRgb
5494cadd4f8SNickeau    {
5504cadd4f8SNickeau        if ($color[0] === "#") {
5514cadd4f8SNickeau            return self::createFromHex($color);
5524cadd4f8SNickeau        } else {
5534cadd4f8SNickeau            return self::createFromName($color);
5544cadd4f8SNickeau        }
5554cadd4f8SNickeau    }
5564cadd4f8SNickeau
5574cadd4f8SNickeau    /**
558*04fd306cSNickeau     *
5594cadd4f8SNickeau     */
5604cadd4f8SNickeau    public
5614cadd4f8SNickeau    static function createFromName(string $color): ColorRgb
5624cadd4f8SNickeau    {
5634cadd4f8SNickeau        return (new ColorRgb())
5644cadd4f8SNickeau            ->setName($color);
5654cadd4f8SNickeau    }
5664cadd4f8SNickeau
5674cadd4f8SNickeau
5684cadd4f8SNickeau    public
5694cadd4f8SNickeau    function toCssValue(): string
5704cadd4f8SNickeau    {
5714cadd4f8SNickeau
5724cadd4f8SNickeau        switch ($this->nameType) {
5734cadd4f8SNickeau            case self::VALUE_TYPE_RGB_ARRAY:
5744cadd4f8SNickeau                return $this->toRgbHex();
5754cadd4f8SNickeau            case self::VALUE_TYPE_CSS_NAME:
5764cadd4f8SNickeau            case self::VALUE_TYPE_RGB_HEX;
5774cadd4f8SNickeau                return $this->name;
5784cadd4f8SNickeau            case self::VALUE_TYPE_BOOTSTRAP_NAME:
5794cadd4f8SNickeau                $bootstrapVersion = Bootstrap::getBootStrapMajorVersion();
5804cadd4f8SNickeau                switch ($bootstrapVersion) {
5814cadd4f8SNickeau                    case Bootstrap::BootStrapFiveMajorVersion:
5824cadd4f8SNickeau                        $colorValue = "bs-" . $this->name;
5834cadd4f8SNickeau                        break;
5844cadd4f8SNickeau                    default:
5854cadd4f8SNickeau                        $colorValue = $this->name;
5864cadd4f8SNickeau                        break;
5874cadd4f8SNickeau                }
5884cadd4f8SNickeau                return "var(--" . $colorValue . ")";
5894cadd4f8SNickeau            case self::VALUE_TYPE_RESET:
5904cadd4f8SNickeau                return "inherit!important";
5914cadd4f8SNickeau            default:
5924cadd4f8SNickeau                // unknown color name
5934cadd4f8SNickeau                if ($this->name === null) {
5944cadd4f8SNickeau                    LogUtility::msg("The name should not be null");
5954cadd4f8SNickeau                    return "black";
5964cadd4f8SNickeau                }
5974cadd4f8SNickeau                return $this->name;
5984cadd4f8SNickeau        }
5994cadd4f8SNickeau
6004cadd4f8SNickeau
6014cadd4f8SNickeau    }
6024cadd4f8SNickeau
6034cadd4f8SNickeau    public
6044cadd4f8SNickeau    function getRed()
6054cadd4f8SNickeau    {
6064cadd4f8SNickeau        return $this->red;
6074cadd4f8SNickeau    }
6084cadd4f8SNickeau
6094cadd4f8SNickeau    public
6104cadd4f8SNickeau    function getGreen()
6114cadd4f8SNickeau    {
6124cadd4f8SNickeau        return $this->green;
6134cadd4f8SNickeau    }
6144cadd4f8SNickeau
6154cadd4f8SNickeau    public
6164cadd4f8SNickeau    function getBlue()
6174cadd4f8SNickeau    {
6184cadd4f8SNickeau        return $this->blue;
6194cadd4f8SNickeau    }
6204cadd4f8SNickeau
6214cadd4f8SNickeau    /**
6224cadd4f8SNickeau     * Mix with black
6234cadd4f8SNickeau     * @var int $percentage between 0 and 100
6244cadd4f8SNickeau     */
6254cadd4f8SNickeau    public
6264cadd4f8SNickeau    function shade(int $percentage): ColorRgb
6274cadd4f8SNickeau    {
6284cadd4f8SNickeau        try {
6294cadd4f8SNickeau            return $this->mix('black', $percentage);
630*04fd306cSNickeau        } catch (ExceptionCompile $e) {
6314cadd4f8SNickeau            // should not happen
6324cadd4f8SNickeau            LogUtility::msg("Error while shading. Error: {$e->getMessage()}");
6334cadd4f8SNickeau            return $this;
6344cadd4f8SNickeau        }
6354cadd4f8SNickeau    }
6364cadd4f8SNickeau
6374cadd4f8SNickeau    public
6384cadd4f8SNickeau    function getNameType(): string
6394cadd4f8SNickeau    {
6404cadd4f8SNickeau        return $this->nameType;
6414cadd4f8SNickeau    }
6424cadd4f8SNickeau
6434cadd4f8SNickeau    /**
6444cadd4f8SNickeau     * @param int $percentage between -100 and 100
6454cadd4f8SNickeau     * @return $this
6464cadd4f8SNickeau     */
6474cadd4f8SNickeau    public
6484cadd4f8SNickeau    function scale(int $percentage): ColorRgb
6494cadd4f8SNickeau    {
6504cadd4f8SNickeau        if ($percentage === 0) {
6514cadd4f8SNickeau            return $this;
6524cadd4f8SNickeau        }
6534cadd4f8SNickeau        if ($percentage > 0) {
6544cadd4f8SNickeau            return $this->shade($percentage);
6554cadd4f8SNickeau        } else {
6564cadd4f8SNickeau            return $this->tint(abs($percentage));
6574cadd4f8SNickeau        }
6584cadd4f8SNickeau
6594cadd4f8SNickeau    }
6604cadd4f8SNickeau
6614cadd4f8SNickeau
6624cadd4f8SNickeau    public
6634cadd4f8SNickeau    function toRgbChannels(): array
6644cadd4f8SNickeau    {
6654cadd4f8SNickeau        return [$this->getRed(), $this->getGreen(), $this->getBlue()];
6664cadd4f8SNickeau    }
6674cadd4f8SNickeau
6684cadd4f8SNickeau    /**
6694cadd4f8SNickeau     * @param int $percentage between 0 and 100
6704cadd4f8SNickeau     * @return $this
6714cadd4f8SNickeau     */
6724cadd4f8SNickeau    public
6734cadd4f8SNickeau    function tint(int $percentage): ColorRgb
6744cadd4f8SNickeau    {
6754cadd4f8SNickeau        try {
6764cadd4f8SNickeau            return $this->mix("white", $percentage);
677*04fd306cSNickeau        } catch (ExceptionCompile $e) {
6784cadd4f8SNickeau            // should not happen
6794cadd4f8SNickeau            LogUtility::msg("Error while tinting ($this) with a percentage ($percentage. Error: {$e->getMessage()}");
6804cadd4f8SNickeau            return $this;
6814cadd4f8SNickeau        }
6824cadd4f8SNickeau    }
6834cadd4f8SNickeau
6844cadd4f8SNickeau    public
6854cadd4f8SNickeau    function __toString()
6864cadd4f8SNickeau    {
6874cadd4f8SNickeau        return $this->toCssValue();
6884cadd4f8SNickeau    }
6894cadd4f8SNickeau
6904cadd4f8SNickeau    public
6914cadd4f8SNickeau    function getLuminance(): float
6924cadd4f8SNickeau    {
6934cadd4f8SNickeau        $toLuminanceFactor = function ($channel) {
6944cadd4f8SNickeau            $pigmentRatio = $channel / 255;
6954cadd4f8SNickeau            return $pigmentRatio <= 0.03928 ? $pigmentRatio / 12.92 : pow(($pigmentRatio + 0.055) / 1.055, 2.4);
6964cadd4f8SNickeau        };
6974cadd4f8SNickeau        $R = $toLuminanceFactor($this->getRed());
6984cadd4f8SNickeau        $G = $toLuminanceFactor($this->getGreen());
6994cadd4f8SNickeau        $B = $toLuminanceFactor($this->getBlue());
7004cadd4f8SNickeau        return $R * 0.2126 + $G * 0.7152 + $B * 0.0722;
7014cadd4f8SNickeau
7024cadd4f8SNickeau    }
7034cadd4f8SNickeau
7044cadd4f8SNickeau    /**
7054cadd4f8SNickeau     * The ratio that returns the chrome browser
7064cadd4f8SNickeau     * @param ColorRgb $colorRgb
7074cadd4f8SNickeau     * @return float
708*04fd306cSNickeau     * @throws ExceptionCompile
7094cadd4f8SNickeau     */
7104cadd4f8SNickeau    public
7114cadd4f8SNickeau    function getContrastRatio(ColorRgb $colorRgb): float
7124cadd4f8SNickeau    {
7134cadd4f8SNickeau        $actualColorHsl = $this->toHsl();
7144cadd4f8SNickeau        $actualLightness = $actualColorHsl->getLightness();
7154cadd4f8SNickeau        $targetColorHsl = $colorRgb->toHsl();
7164cadd4f8SNickeau        $targetLightNess = $targetColorHsl->getLightness();
7174cadd4f8SNickeau        if ($actualLightness > $targetLightNess) {
7184cadd4f8SNickeau            $lighter = $this;
7194cadd4f8SNickeau            $darker = $colorRgb;
7204cadd4f8SNickeau        } else {
7214cadd4f8SNickeau            $lighter = $colorRgb;
7224cadd4f8SNickeau            $darker = $this;
7234cadd4f8SNickeau        }
7244cadd4f8SNickeau        $ratio = ($lighter->getLuminance() + 0.05) / ($darker->getLuminance() + 0.05);
7254cadd4f8SNickeau        return floor($ratio * 100) / 100;
7264cadd4f8SNickeau    }
7274cadd4f8SNickeau
7284cadd4f8SNickeau    /**
729*04fd306cSNickeau     * @throws ExceptionCompile
7304cadd4f8SNickeau     */
7314cadd4f8SNickeau    public
7324cadd4f8SNickeau    function toMinimumContrastRatio(string $color, float $minimum = self::MINIMUM_CONTRAST_RATIO, $darknessIncrement = 5): ColorRgb
7334cadd4f8SNickeau    {
7344cadd4f8SNickeau        $targetColor = ColorRgb::createFromString($color);
7354cadd4f8SNickeau        $ratio = $this->getContrastRatio($targetColor);
7364cadd4f8SNickeau        $newColorRgb = $this;
7374cadd4f8SNickeau        $newColorHsl = $this->toHsl();
7384cadd4f8SNickeau        while ($ratio < $minimum) {
7394cadd4f8SNickeau            $newColorHsl = $newColorHsl->darken($darknessIncrement);
7404cadd4f8SNickeau            $newColorRgb = $newColorHsl->toRgb();
7414cadd4f8SNickeau            if ($newColorHsl->getLightness() === 0) {
7424cadd4f8SNickeau                break;
7434cadd4f8SNickeau            }
7444cadd4f8SNickeau            $ratio = $newColorRgb->getContrastRatio($targetColor);
7454cadd4f8SNickeau        }
7464cadd4f8SNickeau        return $newColorRgb;
7474cadd4f8SNickeau    }
7484cadd4f8SNickeau
7494cadd4f8SNickeau    /**
7504cadd4f8SNickeau     * Returns the complimentary color
7514cadd4f8SNickeau     */
7524cadd4f8SNickeau    public
7534cadd4f8SNickeau    function complementary(): ColorRgb
7544cadd4f8SNickeau    {
7554cadd4f8SNickeau        try {
7564cadd4f8SNickeau            return $this
7574cadd4f8SNickeau                ->toHsl()
7584cadd4f8SNickeau                ->toComplement()
7594cadd4f8SNickeau                ->toRgb();
760*04fd306cSNickeau        } catch (ExceptionCompile $e) {
7614cadd4f8SNickeau            LogUtility::msg("Error while getting the complementary color of ($this). Error: {$e->getMessage()}");
7624cadd4f8SNickeau            return $this;
7634cadd4f8SNickeau        }
7644cadd4f8SNickeau
7654cadd4f8SNickeau    }
7664cadd4f8SNickeau
7674cadd4f8SNickeau    public
7684cadd4f8SNickeau    function getName(): string
7694cadd4f8SNickeau    {
7704cadd4f8SNickeau        $hexColor = $this->toRgbHex();
7714cadd4f8SNickeau        if (in_array($hexColor, self::CSS_COLOR_NAMES)) {
7724cadd4f8SNickeau            return self::CSS_COLOR_NAMES[$hexColor];
7734cadd4f8SNickeau        }
7744cadd4f8SNickeau        return $hexColor;
7754cadd4f8SNickeau    }
7764cadd4f8SNickeau
7774cadd4f8SNickeau    /**
778*04fd306cSNickeau     * @throws ExceptionCompile
7794cadd4f8SNickeau     */
7804cadd4f8SNickeau    public
7814cadd4f8SNickeau    function toMinimumContrastRatioAgainstWhite(float $minimumContrastRatio = self::MINIMUM_CONTRAST_RATIO, int $darknessIncrement = 5): ColorRgb
7824cadd4f8SNickeau    {
7834cadd4f8SNickeau        return $this->toMinimumContrastRatio(self::WHITE, $minimumContrastRatio, $darknessIncrement);
7844cadd4f8SNickeau    }
7854cadd4f8SNickeau
7864cadd4f8SNickeau    /**
787*04fd306cSNickeau     * @throws ExceptionBadArgument
7884cadd4f8SNickeau     */
7894cadd4f8SNickeau    private
7904cadd4f8SNickeau    function setHex(string $color): ColorRgb
7914cadd4f8SNickeau    {
7924cadd4f8SNickeau        // Hexadecimal
7934cadd4f8SNickeau        if ($color[0] !== "#") {
794*04fd306cSNickeau            throw new ExceptionBadArgument("The value is not an hexadecimal color value ($color)");
7954cadd4f8SNickeau        }
7964cadd4f8SNickeau        [$this->red, $this->green, $this->blue, $this->transparency] = $this->hex2rgb($color);
7974cadd4f8SNickeau        $this->nameType = self::VALUE_TYPE_RGB_HEX;
7984cadd4f8SNickeau        $this->name = $color;
7994cadd4f8SNickeau        return $this;
8004cadd4f8SNickeau    }
8014cadd4f8SNickeau
8024cadd4f8SNickeau    /**
803*04fd306cSNickeau     * @throws ExceptionCompile
8044cadd4f8SNickeau     */
8054cadd4f8SNickeau    public
8064cadd4f8SNickeau    function setRgbChannels(array $colorValue): ColorRgb
8074cadd4f8SNickeau    {
8084cadd4f8SNickeau        if (sizeof($colorValue) != 3) {
809*04fd306cSNickeau            throw new ExceptionCompile("A rgb color array should be of length 3");
8104cadd4f8SNickeau        }
8114cadd4f8SNickeau        foreach ($colorValue as $color) {
8124cadd4f8SNickeau            try {
8134cadd4f8SNickeau                $channel = DataType::toInteger($color);
814*04fd306cSNickeau            } catch (ExceptionCompile $e) {
815*04fd306cSNickeau                throw new ExceptionCompile("The rgb color $color is not an integer. Error: {$e->getMessage()}");
8164cadd4f8SNickeau            }
8174cadd4f8SNickeau            if ($channel < 0 and $channel > 255) {
818*04fd306cSNickeau                throw new ExceptionCompile("The rgb color $color is not between 0 and 255");
8194cadd4f8SNickeau            }
8204cadd4f8SNickeau        }
8214cadd4f8SNickeau        [$this->red, $this->green, $this->blue] = $colorValue;
8224cadd4f8SNickeau        $this->nameType = self::VALUE_TYPE_RGB_ARRAY;
8234cadd4f8SNickeau        return $this;
8244cadd4f8SNickeau    }
8254cadd4f8SNickeau
8264cadd4f8SNickeau    private
8274cadd4f8SNickeau    function setNameType(string $type): ColorRgb
8284cadd4f8SNickeau    {
8294cadd4f8SNickeau        $this->nameType = $type;
8304cadd4f8SNickeau        return $this;
8314cadd4f8SNickeau    }
8324cadd4f8SNickeau
8334cadd4f8SNickeau    /**
8344cadd4f8SNickeau     * Via a name
8354cadd4f8SNickeau     */
8364cadd4f8SNickeau    private
8374cadd4f8SNickeau    function setName(string $name): ColorRgb
8384cadd4f8SNickeau    {
8394cadd4f8SNickeau
8404cadd4f8SNickeau        $qualifiedName = strtolower($name);
8414cadd4f8SNickeau        $this->name = $qualifiedName;
8424cadd4f8SNickeau        if (in_array($qualifiedName, self::BOOTSTRAP_COLORS)) {
8434cadd4f8SNickeau            /**
8444cadd4f8SNickeau             * Branding colors overwrite
8454cadd4f8SNickeau             */
8464cadd4f8SNickeau            switch ($this->name) {
8474cadd4f8SNickeau                case ColorRgb::PRIMARY_VALUE:
8484cadd4f8SNickeau                    $primaryColor = Site::getPrimaryColorValue();
8494cadd4f8SNickeau                    if ($primaryColor !== null) {
8504cadd4f8SNickeau                        if ($primaryColor !== ColorRgb::PRIMARY_VALUE) {
8514cadd4f8SNickeau                            return self::createFromString($primaryColor);
8524cadd4f8SNickeau                        }
8534cadd4f8SNickeau                        LogUtility::msg("The primary color cannot be set with the value primary. Default to bootstrap color.", self::BRANDING_COLOR_CANONICAL);
8544cadd4f8SNickeau                    }
8554cadd4f8SNickeau                    break;
8564cadd4f8SNickeau                case ColorRgb::SECONDARY_VALUE:
8574cadd4f8SNickeau                    $secondaryColor = Site::getSecondaryColorValue();
8584cadd4f8SNickeau                    if ($secondaryColor !== null) {
8594cadd4f8SNickeau                        if ($secondaryColor !== ColorRgb::SECONDARY_VALUE) {
8604cadd4f8SNickeau                            return self::createFromString($secondaryColor);
8614cadd4f8SNickeau                        }
8624cadd4f8SNickeau                        LogUtility::msg("The secondary color cannot be set with the value secondary. Default to bootstrap color.", self::BRANDING_COLOR_CANONICAL);
8634cadd4f8SNickeau                    }
8644cadd4f8SNickeau                    break;
8654cadd4f8SNickeau            }
8664cadd4f8SNickeau
8674cadd4f8SNickeau            return $this->setNameType(self::VALUE_TYPE_BOOTSTRAP_NAME);
8684cadd4f8SNickeau        }
8694cadd4f8SNickeau        if ($qualifiedName === self::VALUE_TYPE_RESET) {
8704cadd4f8SNickeau            return $this->setNameType(self::VALUE_TYPE_RESET);
8714cadd4f8SNickeau        }
8724cadd4f8SNickeau        if (in_array($qualifiedName, array_keys(self::CSS_COLOR_NAMES))) {
8734cadd4f8SNickeau            $this->setHex(self::CSS_COLOR_NAMES[$qualifiedName])
8744cadd4f8SNickeau                ->setNameType(self::VALUE_TYPE_CSS_NAME);
8754cadd4f8SNickeau            $this->name = $qualifiedName; // hex is a also a name, the previous setHex overwrite the name
8764cadd4f8SNickeau            return $this;
8774cadd4f8SNickeau        }
8784cadd4f8SNickeau        LogUtility::msg("The color name ($name) is unknown");
8794cadd4f8SNickeau        return $this;
8804cadd4f8SNickeau
8814cadd4f8SNickeau    }
8824cadd4f8SNickeau
8834cadd4f8SNickeau    public
8844cadd4f8SNickeau    function getTransparency()
8854cadd4f8SNickeau    {
8864cadd4f8SNickeau        return $this->transparency;
8874cadd4f8SNickeau    }
8884cadd4f8SNickeau
8894cadd4f8SNickeau
8904cadd4f8SNickeau
8914cadd4f8SNickeau
8924cadd4f8SNickeau}
893