/*---------------------------------------------------------------------------------------------
* 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, RenderMode } from "@itwin/core-common";
import { FloatRgba } from "./FloatRGBA";
import { LineCode } from "./LineCode";
/** Controls symbology of edges based on ViewFlags and HiddenLine.Settings. Typically these come from the Target's
 * RenderPlan, but a GraphicBranch may override those settings.
 * @internal
 */
export class EdgeSettings {
    /** The color applies to both hidden and visible edges. */
    _color = FloatRgba.fromColorDef(ColorDef.white);
    _colorOverridden = false;
    _visibleLineCode;
    _visibleWeight;
    _hiddenLineCode;
    _hiddenWeight;
    /** Controls how opaque a surface must be to be displayed in SolidFill or HiddenLine modes; or how opaque it must be to
     * block shadow-casting lights in SmoothShade mode.
     */
    _transparencyThreshold = 0;
    static create(hline) {
        const settings = new EdgeSettings();
        settings.init(hline);
        return settings;
    }
    init(hline) {
        this.clear();
        if (!hline)
            return;
        // The threshold is HiddenLine.Settings is a transparency value. Convert it to an alpha value and clamp to [0..1].
        let threshold = hline.transparencyThreshold;
        threshold = Math.min(1, Math.max(0, threshold));
        this._transparencyThreshold = 1.0 - threshold;
        const vis = hline.visible;
        if (vis.color) {
            this._colorOverridden = true;
            this._color.setColorDef(vis.color);
        }
        this._visibleLineCode = (undefined !== vis.pattern ? LineCode.valueFromLinePixels(vis.pattern) : undefined);
        this._visibleWeight = vis.width;
        // Hidden edge settings default to matching visible edge settings.
        const hid = hline.hidden;
        this._hiddenLineCode = undefined !== hid.pattern ? LineCode.valueFromLinePixels(hid.pattern) : this._visibleLineCode;
        this._hiddenWeight = undefined !== hid.width ? hid.width : this._visibleWeight;
        if (undefined !== this._hiddenWeight && undefined !== this._visibleWeight) {
            // Hidden edges cannot be wider than visible edges.
            this._hiddenWeight = Math.min(this._visibleWeight, this._hiddenWeight);
        }
    }
    computeOvrFlags(pass, vf) {
        // Edge overrides never apply in wireframe mode
        if (!this.isOverridden(vf))
            return 0 /* OvrFlags.None */;
        // Alpha always overridden - transparent edges only supported in wireframe mode.
        let flags = this.getColor(vf) ? (6 /* OvrFlags.Rgba */ | 1 /* OvrFlags.LineRgb */ | 8 /* OvrFlags.LineAlpha */) : (4 /* OvrFlags.Alpha */ | 8 /* OvrFlags.LineAlpha */);
        if (undefined !== this.getLineCode(pass, vf))
            flags |= 64 /* OvrFlags.LineCode */;
        if (undefined !== this.getWeight(pass, vf))
            flags |= 128 /* OvrFlags.Weight */;
        return flags;
    }
    get transparencyThreshold() {
        return this._transparencyThreshold;
    }
    getColor(vf) {
        return this._colorOverridden && this.isOverridden(vf) ? this._color : undefined;
    }
    getLineCode(pass, vf) {
        if (!this.isOverridden(vf))
            return undefined;
        return 9 /* RenderPass.HiddenEdge */ === pass ? this._hiddenLineCode : this._visibleLineCode;
    }
    getWeight(pass, vf) {
        if (!this.isOverridden(vf))
            return undefined;
        return 9 /* RenderPass.HiddenEdge */ === pass ? this._hiddenWeight : this._visibleWeight;
    }
    clear() {
        this._colorOverridden = false;
        this._visibleLineCode = this._visibleWeight = undefined;
        this._hiddenLineCode = this._hiddenWeight = undefined;
        this._transparencyThreshold = 0;
    }
    wantContrastingColor(renderMode) {
        return !this._colorOverridden && RenderMode.SolidFill === renderMode;
    }
    isOverridden(vf) {
        switch (vf.renderMode) {
            case RenderMode.Wireframe:
                return false; // edge overrides don't apply in wireframe mode
            case RenderMode.SmoothShade:
                return vf.visibleEdges;
            default:
                return true; // Edges always displayed in solid fill and hidden line modes
        }
    }
}
//# sourceMappingURL=EdgeSettings.js.map