"use strict";
/*---------------------------------------------------------------------------------------------
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
* See LICENSE.md in the project root for license terms and full copyright notice.
*--------------------------------------------------------------------------------------------*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.MockRender = void 0;
/** @packageDocumentation
 * @module Utils
 */
const core_bentley_1 = require("@itwin/core-bentley");
const core_geometry_1 = require("@itwin/core-geometry");
const core_common_1 = require("@itwin/core-common");
const IModelApp_1 = require("../IModelApp");
const ViewRect_1 = require("../common/ViewRect");
const PrimitiveBuilder_1 = require("../internal/render/PrimitiveBuilder");
const RenderGraphic_1 = require("./RenderGraphic");
const RenderSystem_1 = require("./RenderSystem");
const RenderTarget_1 = require("./RenderTarget");
const Symbols_1 = require("../common/internal/Symbols");
/** Contains extensible mock implementations of the various components of a RenderSystem, intended for use in tests.
 * Use these for tests instead of the default RenderSystem wherever possible because:
 *  (1) Electron has a bug on Windows in which it fails to obtain a WebGLRenderingContext when running inside a VM (e.g., during CI job); and
 *  (2) To decouple the logic which uses aspects of the RenderSystem from the full implementation.
 * Any and all of these types can be extended for the purposes of specific tests.
 * To use this:
 *  (1) If overriding anything in the implementation supplied herein, pass a SystemFactory function to MockRender.App.systemFactory.
 *  (2) Call MockRender.App.startup() instead of IModelApp.startup() before tests begin.
 *  (3) Likewise call MockRender.App.shutdown() when finished. This resets the SystemFactory to its default.
 * @note The APIs within this namespace are intended *strictly* for use with unit tests.
 * @internal
 */
var MockRender;
(function (MockRender) {
    var _a, _b;
    /** @internal */
    class Target extends RenderTarget_1.RenderTarget {
        constructor(_system) {
            super();
            this._system = _system;
            this[_a] = undefined;
        }
        get renderSystem() { return this._system; }
        get wantInvertBlackBackground() { return false; }
        get analysisFraction() { return 0; }
        set analysisFraction(_fraction) { }
        changeScene(_scene) { }
        changeDynamics(_dynamics) { }
        changeDecorations(_decs) { }
        changeRenderPlan(_plan) { }
        drawFrame(_sceneTime) { }
        updateViewRect() { return false; }
        readPixels(_rect, _selector, receiver, _excludeNonLocatable) { receiver(undefined); }
        get screenSpaceEffects() { return []; }
        set screenSpaceEffects(_effects) { }
    }
    _a = Symbols_1._implementationProhibited;
    MockRender.Target = Target;
    /** @internal */
    class OnScreenTarget extends Target {
        constructor(system, _canvas) {
            super(system);
            this._canvas = _canvas;
        }
        get viewRect() { return new ViewRect_1.ViewRect(0, 0, this._canvas.clientWidth, this._canvas.clientHeight); }
        setViewRect(_rect, _temp) { }
    }
    MockRender.OnScreenTarget = OnScreenTarget;
    /** @internal */
    class OffScreenTarget extends Target {
        constructor(system, _viewRect) {
            super(system);
            this._viewRect = _viewRect;
        }
        get viewRect() { return this._viewRect; }
        setViewRect(rect, _temp) { this._viewRect.setFrom(rect); }
    }
    MockRender.OffScreenTarget = OffScreenTarget;
    /** @internal */
    class Builder extends PrimitiveBuilder_1.PrimitiveBuilder {
        constructor(system, options) {
            super(system, options);
        }
    }
    MockRender.Builder = Builder;
    class Graphic extends RenderGraphic_1.RenderGraphic {
        constructor() { super(); }
        dispose() { }
        collectStatistics(_stats) { }
        unionRange() { }
    }
    MockRender.Graphic = Graphic;
    class List extends Graphic {
        constructor(graphics) {
            super();
            this.graphics = graphics;
        }
        dispose() {
            for (const graphic of this.graphics)
                (0, core_bentley_1.dispose)(graphic);
            this.graphics.length = 0;
        }
    }
    MockRender.List = List;
    class Branch extends Graphic {
        constructor(branch, transform, options) {
            super();
            this.branch = branch;
            this.transform = transform;
            this.options = options;
        }
        dispose() { this.branch.dispose(); }
    }
    MockRender.Branch = Branch;
    class Batch extends Graphic {
        constructor(graphic, featureTable, range) {
            super();
            this.graphic = graphic;
            this.featureTable = featureTable;
            this.range = range;
        }
        dispose() {
            (0, core_bentley_1.dispose)(this.graphic);
        }
    }
    MockRender.Batch = Batch;
    /** @internal */
    class Geometry {
        constructor(renderGeometryType) {
            this.renderGeometryType = renderGeometryType;
            this.noDispose = false;
            this.isInstanceable = true;
            this.isDisposed = false;
        }
        dispose() { this.isDisposed = true; }
        collectStatistics() { }
        computeRange() { return new core_geometry_1.Range3d(); }
    }
    MockRender.Geometry = Geometry;
    /** @internal */
    class AreaPattern {
        constructor() {
            this[_b] = "renderAreaPattern";
        }
        dispose() { }
        collectStatistics() { }
    }
    _b = Symbols_1._implementationProhibited;
    MockRender.AreaPattern = AreaPattern;
    class System extends RenderSystem_1.RenderSystem {
        get isValid() { return true; }
        dispose() { }
        get maxTextureSize() { return 4096; }
        constructor() { super(); }
        /** @internal */
        doIdleWork() { return false; }
        /** @internal */
        createTarget(canvas) { return new OnScreenTarget(this, canvas); }
        /** @internal */
        createOffscreenTarget(rect) { return new OffScreenTarget(this, rect); }
        createGraphic(options) {
            return new Builder(this, options);
        }
        createGraphicList(primitives) { return new List(primitives); }
        createGraphicBranch(branch, transform, options) { return new Branch(branch, transform, options); }
        createBatch(graphic, features, range) { return new Batch(graphic, features, range); }
        /** @internal */
        createMesh(_params) { return new Graphic(); }
        /** @internal */
        createPolyline(_params) { return new Graphic(); }
        /** @internal */
        createPointString(_params) { return new Graphic(); }
        /** @internal */
        createPointCloud(_args, _imodel) { return new Graphic(); }
        createRenderGraphic() { return new Graphic(); }
        /** @internal */
        createMeshGeometry() { return new Geometry("mesh"); }
        /** @internal */
        createPolylineGeometry() { return new Geometry("polyline"); }
        /** @internal */
        createPointStringGeometry() { return new Geometry("point-string"); }
        /** @internal */
        createAreaPattern() { return new AreaPattern(); }
        /** @internal */
        createGraphicFromTemplate() { return new Graphic(); }
    }
    MockRender.System = System;
    /** An implementation of IModelApp which uses a MockRender.System by default. */
    class App {
        static async startup(opts) {
            opts = opts ? opts : {};
            opts.renderSys = this.systemFactory();
            opts.localization = opts.localization ?? new core_common_1.EmptyLocalization();
            await IModelApp_1.IModelApp.startup(opts);
        }
        static async shutdown() {
            this.systemFactory = () => App.createDefaultRenderSystem();
            await IModelApp_1.IModelApp.shutdown();
        }
        static createDefaultRenderSystem() { return new System(); }
    }
    App.systemFactory = () => App.createDefaultRenderSystem();
    MockRender.App = App;
})(MockRender || (exports.MockRender = MockRender = {}));
//# sourceMappingURL=MockRender.js.map