"use strict";
/*---------------------------------------------------------------------------------------------
* 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
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.PolylineGeometry = void 0;
const core_bentley_1 = require("@itwin/core-bentley");
const core_common_1 = require("@itwin/core-common");
const RenderMemory_1 = require("../RenderMemory");
const CachedGeometry_1 = require("./CachedGeometry");
const LineCode_1 = require("./LineCode");
const GL_1 = require("./GL");
const System_1 = require("./System");
const VertexLUT_1 = require("./VertexLUT");
/** @internal */
class PolylineGeometry extends CachedGeometry_1.LUTGeometry {
    get lutBuffers() { return this._buffers.buffers; }
    constructor(lut, buffers, params, viOrigin) {
        super(viOrigin);
        this.vertexParams = params.vertices.qparams;
        this._hasFeatures = core_common_1.FeatureIndexType.Empty !== params.vertices.featureIndexType;
        this.lineWeight = params.weight;
        this.lineCode = LineCode_1.LineCode.valueFromLinePixels(params.linePixels);
        this.type = params.type;
        this._isPlanar = params.isPlanar;
        this.lut = lut;
        this.numIndices = params.polyline.indices.length;
        this._buffers = buffers;
    }
    get isDisposed() { return this._buffers.isDisposed && this.lut.isDisposed; }
    dispose() {
        (0, core_bentley_1.dispose)(this.lut);
        (0, core_bentley_1.dispose)(this._buffers);
    }
    collectStatistics(stats) {
        this._buffers.collectStatistics(stats, RenderMemory_1.RenderMemory.BufferType.Polylines);
        stats.addVertexTable(this.lut.bytesUsed);
    }
    get isAnyEdge() { return core_common_1.PolylineTypeFlags.Normal !== this.type; }
    get isNormalEdge() { return core_common_1.PolylineTypeFlags.Edge === this.type; }
    get isOutlineEdge() { return core_common_1.PolylineTypeFlags.Outline === this.type; }
    get renderOrder() {
        if (this.isAnyEdge)
            return this.isPlanar ? 14 /* RenderOrder.PlanarEdge */ : 6 /* RenderOrder.Edge */;
        else
            return this.isPlanar ? 13 /* RenderOrder.PlanarLinear */ : 5 /* RenderOrder.Linear */;
    }
    _wantWoWReversal(_target) { return true; }
    get polylineBuffers() { return this._buffers; }
    _computeEdgePass(target, colorInfo) {
        const vf = target.currentViewFlags;
        if (core_common_1.RenderMode.SmoothShade === vf.renderMode && !vf.visibleEdges)
            return "none";
        // Only want to return Translucent for edges if rendering in Wireframe mode ###TODO: what about overrides?
        const isTranslucent = core_common_1.RenderMode.Wireframe === vf.renderMode && vf.transparency && colorInfo.hasTranslucency;
        return isTranslucent ? "translucent" : "opaque-linear";
    }
    getPass(target) {
        const vf = target.currentViewFlags;
        if (this.isEdge) {
            let pass = this._computeEdgePass(target, this.lut.colorInfo);
            // Only display the outline in wireframe if Fill is off...
            if ("none" !== pass && this.isOutlineEdge && core_common_1.RenderMode.Wireframe === vf.renderMode && vf.fill)
                pass = "none";
            return pass;
        }
        const isTranslucent = vf.transparency && this.lut.colorInfo.hasTranslucency;
        return isTranslucent ? "translucent" : "opaque-linear";
    }
    get techniqueId() { return 1 /* TechniqueId.Polyline */; }
    get isPlanar() { return this._isPlanar; }
    get isEdge() { return this.isAnyEdge; }
    get qOrigin() { return this.lut.qOrigin; }
    get qScale() { return this.lut.qScale; }
    get numRgbaPerVertex() { return this.lut.numRgbaPerVertex; }
    get hasFeatures() { return this._hasFeatures; }
    _getLineWeight(params) {
        return this.isEdge ? params.target.computeEdgeWeight(params.renderPass, this.lineWeight) : this.lineWeight;
    }
    _getLineCode(params) {
        return this.isEdge ? params.target.computeEdgeLineCode(params.renderPass, this.lineCode) : this.lineCode;
    }
    getColor(target) {
        return this.isEdge ? target.computeEdgeColor(this.lut.colorInfo) : this.lut.colorInfo;
    }
    _draw(numInstances, instanceBuffersContainer) {
        const gl = System_1.System.instance;
        const bufs = instanceBuffersContainer !== undefined ? instanceBuffersContainer : this._buffers.buffers;
        bufs.bind();
        gl.drawArrays(GL_1.GL.PrimitiveType.Triangles, 0, this.numIndices, numInstances);
        bufs.unbind();
    }
    static create(params, viewIndependentOrigin) {
        const lut = VertexLUT_1.VertexLUT.createFromVertexTable(params.vertices);
        if (undefined === lut)
            return undefined;
        const buffers = CachedGeometry_1.PolylineBuffers.create(params.polyline);
        if (undefined === buffers)
            return undefined;
        return new PolylineGeometry(lut, buffers, params, viewIndependentOrigin);
    }
}
exports.PolylineGeometry = PolylineGeometry;
//# sourceMappingURL=Polyline.js.map