import { uint8_to_float } from "../binary/uint8_to_float.js";
import { hex2rgb } from "./hex/hex2rgb.js";
import { hsv2rgb } from "./hsv/hsv2rgb.js";


const rgbRegEx = /rgb\(\s*([0-9]+(?:\.[0-9]*)?),\s*([0-9]+(?:\.[0-9]*)?),\s*([0-9]+(?:\.[0-9]*)?)\s*\)/;
const rgbaRegEx = /rgba\(\s*([0-9]+(?:\.[0-9]*)?),\s*([0-9]+(?:\.[0-9]*)?),\s*([0-9]+(?:\.[0-9]*)?),\s*([0-9]+(?:\.[0-9]*)?)\s*\)/;
const hsvRegEx = /hsv\(([0-9]+(?:\.[0-9]*)?),\s*([0-9]+(?:\.[0-9]*)?),\s*([0-9]+(?:\.[0-9]*)?)\)/;

/**
 * Parses most CSS-format colors
 * @param {string|number} c
 * @returns {number[]} Numeric array, values are in Uint8 range (0...255) for RGB and 0..1 for Alpha
 */
export function parse_color(c) {

    const result = [];

    const type_of_code = typeof c;

    let r, g, b, a = 1;

    if (type_of_code === "string") {
        const cL = c.toLowerCase();

        let match;

        if ((match = cL.match(rgbRegEx)) !== null) {

            r = parseFloat(match[1]);
            g = parseFloat(match[2]);
            b = parseFloat(match[3]);

        } else if ((match = cL.match(rgbaRegEx)) !== null) {

            r = parseFloat(match[1]);
            g = parseFloat(match[2]);
            b = parseFloat(match[3]);
            a = parseFloat(match[4]);

        } else if ((match = cL.match(hsvRegEx)) !== null) {

            const rgb = hsv2rgb(
                parseFloat(match[1]),
                parseFloat(match[2]),
                parseFloat(match[3])
            );

            r = rgb.r;
            g = rgb.g;
            b = rgb.b;

        } else if (cL.startsWith('#')) {

            const rgb = hex2rgb(cL);

            r = rgb.r;
            g = rgb.g;
            b = rgb.b;
            a = uint8_to_float(rgb.a);


        } else {
            throw new Error(`Failed to decode color string '${c}' `);
        }
    } else if (type_of_code === 'number') {

        r = c >> 16;
        g = (c >> 8) & 0xFF;
        b = (c) & 0xFF;

    } else {
        throw new Error(`Failed to decode color '${c}'`);
    }

    result[0] = r;
    result[1] = g;
    result[2] = b;
    result[3] = a;


    return result;
}

