/*---------------------------------------------------------------------------------------------
* 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 { RenderMode } from "@itwin/core-common";
/** Flags used to control which shader program is used by a rendering Technique.
 * @internal
 */
export class TechniqueFlags {
    constructor(translucent = false) {
        this.numClipPlanes = 0;
        this.featureMode = 0 /* FeatureMode.None */;
        this.isEdgeTestNeeded = 0 /* IsEdgeTestNeeded.No */;
        this.isAnimated = 0 /* IsAnimated.No */;
        this.isInstanced = 0 /* IsInstanced.No */;
        this.isClassified = 0 /* IsClassified.No */;
        this.isShadowable = 0 /* IsShadowable.No */;
        this.isThematic = 0 /* IsThematic.No */;
        this.isWiremesh = 0 /* IsWiremesh.No */;
        this.positionType = "quantized";
        this.enableAtmosphere = 0 /* EnableAtmosphere.No */;
        this._isHilite = false;
        this.isTranslucent = translucent;
    }
    get hasClip() {
        return this.numClipPlanes > 0;
    }
    get usesQuantizedPositions() {
        return "quantized" === this.positionType;
    }
    init(target, pass, instanced, animated = 0 /* IsAnimated.No */, classified = 0 /* IsClassified.No */, shadowable = 0 /* IsShadowable.No */, thematic = 0 /* IsThematic.No */, wiremesh = 0 /* IsWiremesh.No */, posType = "quantized", enableAtmosphere = 0 /* EnableAtmosphere.No */) {
        const clipStack = target.uniforms.branch.clipStack;
        const numClipPlanes = clipStack.hasClip ? clipStack.textureHeight : 0;
        this.positionType = posType;
        if (10 /* RenderPass.Hilite */ === pass || 16 /* RenderPass.HiliteClassification */ === pass || 18 /* RenderPass.HilitePlanarClassification */ === pass) {
            const isClassified = (classified === 1 /* IsClassified.Yes */ && 18 /* RenderPass.HilitePlanarClassification */ === pass) ? 1 /* IsClassified.Yes */ : 0 /* IsClassified.No */;
            this.initForHilite(numClipPlanes, instanced, isClassified, posType);
        }
        else {
            this._isHilite = false;
            this.isTranslucent = 8 /* RenderPass.Translucent */ === pass;
            this.numClipPlanes = numClipPlanes;
            this.isAnimated = animated;
            this.isInstanced = instanced;
            this.isClassified = classified;
            this.isShadowable = shadowable;
            this.isThematic = thematic;
            this.isWiremesh = wiremesh;
            this.enableAtmosphere = enableAtmosphere;
            this.featureMode = target.uniforms.batch.featureMode;
            // Determine if we should use the shaders which support discarding surfaces in favor of their edges (and discarding non-planar surfaces in favor of coincident planar surfaces).
            // These are only useful if the geometry defines feature Ids.
            // In 3d, if we're only displaying surfaces or edges, not both, don't bother, unless forceSurfaceDiscard is true.
            this.isEdgeTestNeeded = this.hasFeatures ? (this.isClassified ? 0 /* IsEdgeTestNeeded.No */ : 1 /* IsEdgeTestNeeded.Yes */) : 0 /* IsEdgeTestNeeded.No */;
            if (!target.currentViewFlags.forceSurfaceDiscard && target.is3d && !target.isReadPixelsInProgress && this.isEdgeTestNeeded) {
                switch (target.currentViewFlags.renderMode) {
                    case RenderMode.Wireframe:
                        // We're only displaying edges (ignoring filled planar regions)
                        this.isEdgeTestNeeded = 0 /* IsEdgeTestNeeded.No */;
                        break;
                    case RenderMode.SmoothShade:
                        if (!target.currentViewFlags.visibleEdges && !target.wantAmbientOcclusion && pass !== 19 /* RenderPass.PlanarClassification */) {
                            // We're only displaying surfaces (ignoring filled planar regions).
                            // NB: Filled text (blanking region) is handled by adjusting the depth in the surface vertex shader.
                            this.isEdgeTestNeeded = 0 /* IsEdgeTestNeeded.No */;
                        }
                        break;
                    default:
                        // SolidFill and HiddenLine always display edges and surfaces.
                        break;
                }
            }
        }
    }
    reset(mode, instanced = 0 /* IsInstanced.No */, shadowable, thematic, posType) {
        this._isHilite = false;
        this.featureMode = mode;
        this.isTranslucent = false;
        this.isEdgeTestNeeded = 0 /* IsEdgeTestNeeded.No */;
        this.isAnimated = 0 /* IsAnimated.No */;
        this.isClassified = 0 /* IsClassified.No */;
        this.isInstanced = instanced;
        this.isShadowable = shadowable;
        this.isThematic = thematic;
        this.isWiremesh = 0 /* IsWiremesh.No */;
        this.positionType = posType;
        this.enableAtmosphere = 0 /* EnableAtmosphere.No */;
        this.numClipPlanes = 0;
    }
    get hasFeatures() { return 0 /* FeatureMode.None */ !== this.featureMode; }
    setAnimated(animated) { this.isAnimated = animated ? 1 /* IsAnimated.Yes */ : 0 /* IsAnimated.No */; }
    setInstanced(instanced) { this.isInstanced = instanced ? 1 /* IsInstanced.Yes */ : 0 /* IsInstanced.No */; }
    setClassified(classified) {
        this.isClassified = classified ? 1 /* IsClassified.Yes */ : 0 /* IsClassified.No */;
    }
    get isHilite() { return this._isHilite; }
    initForHilite(numClipPlanes, instanced, classified, posType) {
        this.featureMode = classified ? 0 /* FeatureMode.None */ : 2 /* FeatureMode.Overrides */;
        this._isHilite = true;
        this.isTranslucent = false;
        this.isEdgeTestNeeded = 0 /* IsEdgeTestNeeded.No */;
        this.isAnimated = 0 /* IsAnimated.No */;
        this.isInstanced = instanced;
        this.isClassified = classified;
        this.numClipPlanes = numClipPlanes;
        this.positionType = posType;
    }
    equals(other) {
        return this.numClipPlanes === other.numClipPlanes
            && this.featureMode === other.featureMode
            && this.isTranslucent === other.isTranslucent
            && this.isEdgeTestNeeded === other.isEdgeTestNeeded
            && this.isAnimated === other.isAnimated
            && this.isInstanced === other.isInstanced
            && this.isClassified === other.isClassified
            && this.isShadowable === other.isShadowable
            && this.isThematic === other.isThematic
            && this.isWiremesh === other.isWiremesh
            && this.positionType === other.positionType
            && this.enableAtmosphere === other.enableAtmosphere
            && this.isHilite === other.isHilite;
    }
    buildDescription() {
        const parts = [this.isTranslucent ? "Translucent" : "Opaque"];
        if (this.isInstanced)
            parts.push("Instanced");
        if (this.isEdgeTestNeeded)
            parts.push("EdgeTestNeeded");
        if (this.isAnimated)
            parts.push("Animated");
        if (this.isHilite)
            parts.push("Hilite");
        if (this.isClassified)
            parts.push("Classified");
        if (this.hasClip)
            parts.push("Clip");
        if (this.isShadowable)
            parts.push("Shadowable");
        if (this.isThematic)
            parts.push("Thematic");
        if (this.hasFeatures)
            parts.push(1 /* FeatureMode.Pick */ === this.featureMode ? "Pick" : "Overrides");
        if (this.isWiremesh)
            parts.push("Wiremesh");
        if (this.positionType === "unquantized")
            parts.push("Unquantized");
        if (this.enableAtmosphere)
            parts.push("EnableAtmosphere");
        return parts.join("-");
    }
    static fromDescription(description) {
        const flags = new TechniqueFlags(false);
        const parts = description.split("-");
        for (const part of parts) {
            switch (part) {
                case "Translucent":
                    flags.isTranslucent = true;
                    break;
                case "Instanced":
                    flags.isInstanced = 1 /* IsInstanced.Yes */;
                    break;
                case "EdgeTestNeeded":
                    flags.isEdgeTestNeeded = 1 /* IsEdgeTestNeeded.Yes */;
                    break;
                case "Animated":
                    flags.isAnimated = 1 /* IsAnimated.Yes */;
                    break;
                case "Hilite":
                    flags._isHilite = true;
                    break;
                case "Classified":
                    flags.isClassified = 1 /* IsClassified.Yes */;
                    break;
                case "Clip":
                    flags.numClipPlanes = 1;
                    break;
                case "Shadowable":
                    flags.isShadowable = 1 /* IsShadowable.Yes */;
                    break;
                case "Thematic":
                    flags.isThematic = 1 /* IsThematic.Yes */;
                    break;
                case "Wiremesh":
                    flags.isWiremesh = 1 /* IsWiremesh.Yes */;
                    break;
                case "Unquantized":
                    flags.positionType = "unquantized";
                    break;
                case "EnableAtmosphere":
                    flags.enableAtmosphere = 1 /* EnableAtmosphere.Yes */;
                    break;
                case "Pick":
                    flags.featureMode = 1 /* FeatureMode.Pick */;
                    break;
                case "Overrides":
                    flags.featureMode = 2 /* FeatureMode.Overrides */;
                    break;
            }
        }
        return flags;
    }
}
TechniqueFlags.defaults = new TechniqueFlags();
//# sourceMappingURL=TechniqueFlags.js.map