/*---------------------------------------------------------------------------------------------
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
* See LICENSE.md in the project root for license terms and full copyright notice.
*--------------------------------------------------------------------------------------------*/
/** @packageDocumentation
 * @module WebGL
 */
import { ColorDef } from "@itwin/core-common";
function clamp(norm) {
    return Math.max(0, Math.min(1, norm));
}
function scale(norm) {
    return Math.floor(norm * 255 + 0.5);
}
export class FloatColor {
    _components;
    _tbgr;
    constructor(numComponents) {
        this._components = new Float32Array(numComponents);
        this._tbgr = 0;
    }
    get red() { return this._components[0]; }
    get green() { return this._components[1]; }
    get blue() { return this._components[2]; }
    get tbgr() { return this._tbgr; }
    get isWhite() { return 1.0 === this.red && 1.0 === this.green && 1.0 === this.blue; }
    setColorDef(def) {
        this.setTbgr(def.tbgr);
    }
    setRgbColor(rgb) {
        this.setTbgr((rgb.r | (rgb.g << 8) | (rgb.b << 16)) >>> 0);
    }
    setTbgr(tbgr) {
        tbgr = this.maskTbgr(tbgr);
        if (tbgr === this.tbgr)
            return;
        const c = ColorDef.getColors(tbgr);
        this.setComponents(c.r / 255, c.g / 255, c.b / 255, 1.0 - c.t / 255);
        this._tbgr = tbgr;
    }
    setRgbComponents(r, g, b) {
        this._components[0] = r;
        this._components[1] = g;
        this._components[2] = b;
    }
    setRgbaComponents(r, g, b, a) {
        r = clamp(r);
        g = clamp(g);
        b = clamp(b);
        a = clamp(a);
        const tbgr = (scale(r) | (scale(g) << 8) | (scale(b) << 16) | (scale(1 - a) << 24)) >>> 0;
        this._tbgr = this.maskTbgr(tbgr);
        this.setComponents(r, g, b, a);
    }
}
export class FloatRgb extends FloatColor {
    constructor() {
        super(3);
    }
    maskTbgr(tbgr) {
        return (tbgr & 0x00ffffff) >>> 0;
    }
    setComponents(r, g, b, _a) {
        this.setRgbComponents(r, g, b);
    }
    set(r, g, b) {
        this.setRgbaComponents(r, g, b, 1);
    }
    bind(uniform) {
        uniform.setUniform3fv(this._components);
    }
    static fromColorDef(def) {
        return FloatRgb.fromTbgr(def.tbgr);
    }
    static fromRgbColor(rgb) {
        return FloatRgb.from(rgb.r / 255, rgb.g / 255, rgb.b / 255);
    }
    static from(r, g, b) {
        const rgb = new FloatRgb();
        rgb.set(r, g, b);
        return rgb;
    }
    static fromTbgr(tbgr) {
        const rgb = new FloatRgb();
        rgb.setTbgr(tbgr);
        return rgb;
    }
}
export class FloatRgba extends FloatColor {
    constructor() {
        super(4);
        this._components[3] = 1.0;
    }
    maskTbgr(tbgr) {
        return tbgr;
    }
    setComponents(r, g, b, a) {
        this.setRgbComponents(r, g, b);
        this._components[3] = a;
    }
    set(r, g, b, a) {
        this.setRgbaComponents(r, g, b, a);
    }
    get alpha() { return this._components[3]; }
    set alpha(alpha) { this._components[3] = alpha; }
    get hasTranslucency() { return 1.0 !== this.alpha; }
    bind(uniform) {
        uniform.setUniform4fv(this._components);
    }
    static fromColorDef(def) {
        return FloatRgba.fromTbgr(def.tbgr);
    }
    static fromTbgr(tbgr) {
        const rgba = new FloatRgba();
        rgba.setTbgr(tbgr);
        return rgba;
    }
    static from(r, g, b, a) {
        const rgba = new FloatRgba();
        rgba.set(r, g, b, a);
        return rgba;
    }
    clone(out) {
        if (undefined === out)
            return FloatRgba.from(this.red, this.green, this.blue, this.alpha);
        out.set(this.red, this.green, this.blue, this.alpha);
        return out;
    }
}
//# sourceMappingURL=FloatRGBA.js.map