/*---------------------------------------------------------------------------------------------
* 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 { desync, sync } from "./Sync";
const scratchRgb = new Float32Array(3);
const noOverrideRgb = new Float32Array([-1.0, -1.0, -1.0]);
/** Maintains uniform variable state associated with the Batch currently being drawn by a Target.
 * @internal
 */
export class BatchUniforms {
    constructor(target, batchState) {
        this._featureMode = 0 /* FeatureMode.None */;
        this.syncKey = 0;
        this._batchId = new Float32Array(4);
        this._scratchBytes = new Uint8Array(4);
        this._scratchUint32 = new Uint32Array(this._scratchBytes.buffer);
        this.state = batchState;
        this._target = target;
    }
    setCurrentBatch(batch) {
        desync(this);
        if (undefined !== batch)
            this.state.push(batch, false);
        else
            this.state.pop();
        const batchId = this.state.currentBatchId;
        this._scratchUint32[0] = batchId;
        this._batchId[0] = this._scratchBytes[0];
        this._batchId[1] = this._scratchBytes[1];
        this._batchId[2] = this._scratchBytes[2];
        this._batchId[3] = this._scratchBytes[3];
        const overrides = undefined !== batch ? batch.getOverrides(this._target) : undefined;
        this._overrides = (undefined !== overrides && overrides.anyOverridden) ? overrides : undefined;
        let sensors;
        if (undefined !== batch && this._target.wantThematicSensors) {
            const distanceCutoff = this._target.plan.thematic.sensorSettings.distanceCutoff;
            if (distanceCutoff > 0) // if we have a distance cutoff, we want to create per-batch sensor textures
                sensors = batch.getThematicSensors(this._target);
        }
        this._sensors = sensors;
        if (undefined !== this._overrides)
            this._featureMode = 2 /* FeatureMode.Overrides */;
        else if (0 !== batchId)
            this._featureMode = 1 /* FeatureMode.Pick */;
        else
            this._featureMode = 0 /* FeatureMode.None */;
        this._contours = undefined !== batch && this.wantContourLines ? batch.getContours(this._target) : undefined;
    }
    resetBatchState() {
        this.state.reset();
    }
    get featureMode() { return this._featureMode; }
    bindNumThematicSensors(uniform) {
        if (undefined !== this._sensors)
            this._sensors.bindNumSensors(uniform);
    }
    bindThematicSensors(uniform) {
        if (undefined !== this._sensors)
            this._sensors.bindTexture(uniform);
    }
    get wantContourLines() {
        const contours = this._target.plan.contours;
        return undefined !== contours && contours.displayContours && contours.groups.length > 0;
    }
    bindContourLUT(uniform) {
        // Note we can't use sync() here because a different texture may have been assigned to the desired texture unit
        if (undefined !== this._contours)
            this._contours.bindContourLUT(uniform);
    }
    bindContourLUTWidth(uniform) {
        if (!sync(this, uniform)) {
            if (undefined === this._contours)
                uniform.setUniform1ui(0);
            else
                this._contours.bindContourLUTWidth(uniform);
        }
    }
    bindLUT(uniform) {
        // Note we can't use sync() here because a different texture may have been assigned to the desired texture unit
        if (undefined !== this._overrides)
            this._overrides.bindLUT(uniform);
    }
    bindLUTParams(uniform) {
        if (undefined !== this._overrides && !sync(this, uniform))
            this._overrides.bindLUTParams(uniform);
    }
    bindUniformSymbologyFlags(uniform) {
        if (sync(this, uniform))
            return;
        if (undefined !== this._overrides)
            this._overrides.bindUniformSymbologyFlags(uniform);
        else
            uniform.setUniform1f(0);
    }
    bindBatchId(uniform) {
        if (!sync(this, uniform))
            uniform.setUniform4fv(this._batchId);
    }
    bindUniformColorOverride(uniform) {
        if (sync(this, uniform))
            return;
        if (undefined !== this._overrides) {
            const uo = this._overrides.getUniformOverrides();
            if (uo[0] & 2 /* OvrFlags.Rgb */) {
                scratchRgb[0] = uo[4] / 255.0;
                scratchRgb[1] = uo[5] / 255.0;
                scratchRgb[2] = uo[6] / 255.0;
                uniform.setUniform3fv(scratchRgb);
            }
            else {
                uniform.setUniform3fv(noOverrideRgb);
            }
        }
        else {
            uniform.setUniform3fv(noOverrideRgb);
        }
    }
    bindUniformTransparencyOverride(uniform) {
        if (sync(this, uniform))
            return;
        if (undefined !== this._overrides) {
            const uo = this._overrides.getUniformOverrides();
            if (uo[0] & 4 /* OvrFlags.Alpha */) {
                uniform.setUniform1f(uo[7] / 255.0);
            }
            else {
                uniform.setUniform1f(-1.0);
            }
        }
        else {
            uniform.setUniform1f(-1.0);
        }
    }
    bindUniformNonLocatable(uniform, ignoreNonLocatable) {
        if (sync(this, uniform))
            return;
        let nonLocatable = 0;
        if (!ignoreNonLocatable && undefined !== this._overrides) {
            const uo = this._overrides.getUniformOverrides();
            nonLocatable = (uo[0] & 32 /* OvrFlags.NonLocatable */) ? 1 : 0;
        }
        uniform.setUniform1i(nonLocatable);
    }
}
//# sourceMappingURL=BatchUniforms.js.map