"use strict";
var __extends = (this && this.__extends) || (function () {
    var extendStatics = function (d, b) {
        extendStatics = Object.setPrototypeOf ||
            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
            function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
        return extendStatics(d, b);
    };
    return function (d, b) {
        if (typeof b !== "function" && b !== null)
            throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
        extendStatics(d, b);
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    };
})();
var __assign = (this && this.__assign) || function () {
    __assign = Object.assign || function(t) {
        for (var s, i = 1, n = arguments.length; i < n; i++) {
            s = arguments[i];
            for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
                t[p] = s[p];
        }
        return t;
    };
    return __assign.apply(this, arguments);
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
var __generator = (this && this.__generator) || function (thisArg, body) {
    var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
    return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
    function verb(n) { return function (v) { return step([n, v]); }; }
    function step(op) {
        if (f) throw new TypeError("Generator is already executing.");
        while (g && (g = 0, op[0] && (_ = 0)), _) try {
            if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
            if (y = 0, t) op = [op[0] & 2, t.value];
            switch (op[0]) {
                case 0: case 1: t = op; break;
                case 4: _.label++; return { value: op[1], done: false };
                case 5: _.label++; y = op[1]; op = [0]; continue;
                case 7: op = _.ops.pop(); _.trys.pop(); continue;
                default:
                    if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
                    if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
                    if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
                    if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
                    if (t[2]) _.ops.pop();
                    _.trys.pop(); continue;
            }
            op = body.call(thisArg, _);
        } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
        if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
    }
};
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
    if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
        if (ar || !(i in from)) {
            if (!ar) ar = Array.prototype.slice.call(from, 0, i);
            ar[i] = from[i];
        }
    }
    return to.concat(ar || Array.prototype.slice.call(from));
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.SciChartSurface = exports.sciChartConfig = void 0;
var classFactory_1 = require("../../Core/classFactory");
var app_1 = require("../../constants/app");
var ISolidBrushCache_1 = require("../Drawing/ISolidBrushCache");
var WatermarkController_1 = require("./WatermarkController");
var EasingFunctions_1 = require("../../Core/Animations/EasingFunctions");
var BuildStamp_1 = require("../../Core/BuildStamp");
var Deleter_1 = require("../../Core/Deleter");
var Dictionary_1 = require("../../Core/Dictionary");
var EventHandler_1 = require("../../Core/EventHandler");
var ObservableArray_1 = require("../../Core/ObservableArray");
var Rect_1 = require("../../Core/Rect");
var Thickness_1 = require("../../Core/Thickness");
var AutoColorMode_1 = require("../../types/AutoColorMode");
var BaseType_1 = require("../../types/BaseType");
var SeriesType_1 = require("../../types/SeriesType");
var Size_1 = require("../../types/Size");
var ZoomState_1 = require("../../types/ZoomState");
var BatchRenderContext_1 = require("../Drawing/BatchRenderContext");
var RenderSurface_1 = require("../Drawing/RenderSurface");
var SolidBrushCache_1 = require("../Drawing/SolidBrushCache");
var LayoutManager_1 = require("../LayoutManager/LayoutManager");
var SciChartRenderer_1 = require("../Services/SciChartRenderer");
var AdornerLayer_1 = require("./Annotations/AdornerLayer");
var createMaster_1 = require("./createMaster");
var createSingle_1 = require("./createSingle");
var drawBorder_1 = require("./Helpers/drawBorder");
var NativeObject_1 = require("./Helpers/NativeObject");
var StackedColumnCollection_1 = require("./RenderableSeries/StackedColumnCollection");
var StackedMountainCollection_1 = require("./RenderableSeries/StackedMountainCollection");
var sciChartInitCommon_1 = require("./sciChartInitCommon");
var SciChartSurfaceBase_1 = require("./SciChartSurfaceBase");
var DpiHelper_1 = require("./TextureManager/DpiHelper");
var Point_1 = require("../../Core/Point");
var SciChartDefaults_1 = require("./SciChartDefaults");
var ChartTitleRenderer_1 = require("../Services/ChartTitleRenderer");
var TextStyle_1 = require("../../types/TextStyle");
var TextPosition_1 = require("../../types/TextPosition");
var Globals_1 = require("../../Core/Globals");
var LayoutManagerType_1 = require("../../types/LayoutManagerType");
var logger_1 = require("../../utils/logger");
var performance_1 = require("../../utils/performance");
var SurfaceType_1 = require("../../types/SurfaceType");
var ModifierType_1 = require("../../types/ModifierType");
var AxisAlignment_1 = require("../../types/AxisAlignment");
var font_1 = require("../../utils/font");
var SciChartSurfaceType_1 = require("../../types/SciChartSurfaceType");
var LabelCache_1 = require("./Axis/LabelProvider/LabelCache");
var defaultSciChartConfig = {
    wasmUrl: "scichart2d.wasm",
    wasmNoSimdUrl: undefined
};
exports.sciChartConfig = defaultSciChartConfig;
/**
 * @summary The {@link SciChartSurface} is the root 2D Chart control in SciChart's High Performance Real-time
 * {@link https://www.scichart.com/javascript-chart-features | JavaScript Chart Library}
 * @description
 * To create a chart using SciChart, declare a {@link SciChartSurface} using {@link SciChartSurface.create},
 * add X and Y axes to the {@link SciChartSurface.xAxes} {@link SciChartSurface.yAxes} collection.
 *
 * Next, add a series or chart type by adding a {@link BaseRenderableSeries} to the {@link SciChartSurface.renderableSeries} collection.
 *
 * You can add annotations and markers using the {@link SciChartSurface.annotations} property, and you can add zoom and pan behaviours,
 * tooltips and more by using the {@link SciChartSurface.chartModifiers} property.
 *
 * To redraw a {@link SciChartSurface} at any time, call {@link SciChartSurface.invalidateElement}, however all properties are reactive and the
 * chart will automatically redraw if data or properties change.
 * @remarks
 * It is possible to have more than one {@link SciChartSurface} on screen at the same time.
 * {@link SciChartSurface | SciChartSurfaces} scale to fit the parent DIV where they are hosted. Use CSS to position the DIV.
 */
var SciChartSurface = /** @class */ (function (_super) {
    __extends(SciChartSurface, _super);
    /**
     * Creates an instance of the {@link SciChartSurface}
     * @param webAssemblyContext The {@link TSciChart | SciChart 2D WebAssembly Context} containing native methods and
     * access to our WebGL2 Engine and WebAssembly numerical methods
     * @param options optional parameters of type {@link ISciChartSurfaceOptions} used to configure the {@link SciChartSurface}
     */
    function SciChartSurface(webAssemblyContext, options) {
        var _this = this;
        var _a, _b, _c, _d, _e, _f, _g, _j;
        _this = _super.call(this, webAssemblyContext, options === null || options === void 0 ? void 0 : options.canvases) || this;
        /**
         * Used internally - the {@link RenderContext2D} for drawing
         */
        //public renderContext2D: RenderContext2D;
        /**
         * An event handler which notifies its subscribers when a render operation starts for this specific surface (or sub-surface). Use this
         * to update elements of the chart for the current render.  Any updates made here will not trigger a subsequent render.
         */
        _this.preRender = new EventHandler_1.EventHandler();
        /**
         * An event handler which notifies its subscribers when a render operation starts ignoring the surface order. Use this
         * to update elements of the chart for the current render. Any updates made here will not trigger a subsequent render.
         */
        _this.preRenderAll = new EventHandler_1.EventHandler();
        // TODO make these properties internal only; or add some provider
        _this.stepBetweenLayers = 10;
        _this.isSubSurface = false;
        /**
         * Normally, native labels are drawn all at once at the end of the render cycle to improve performance.
         * In circumstances where you want to draw over the labels, eg with a subchart, set this true to have them drawn earlier.
         */
        _this.renderNativeAxisLabelsImmediately = false;
        /** The position of the watermark for trials and community licenses */
        _this.watermarkPosition = SciChartDefaults_1.SciChartDefaults.watermarkPosition;
        /** Set true to position the watermark relative to the overall canvas, rather than the series area.   */
        _this.watermarkRelativeToCanvas = false;
        _this.animationList = [];
        _this.titleStyleProperty = {
            fontSize: 60,
            fontFamily: (0, font_1.getDefaultFontName)(),
            color: SciChartSurfaceBase_1.SciChartSurfaceBase.DEFAULT_THEME.chartTitleColor,
            fontWeight: "normal",
            fontStyle: "normal",
            lineSpacing: 1.1,
            padding: Thickness_1.Thickness.fromString("10 4 10 4"),
            multilineAlignment: TextPosition_1.EMultiLineAlignment.Center,
            rotation: undefined,
            alignment: TextStyle_1.ETextAlignment.Center,
            position: TextStyle_1.ETitlePosition.Top,
            placeWithinChart: false,
            useNativeText: SciChartDefaults_1.SciChartDefaults.useNativeText
        };
        //function to create a proxy for the object, which traps the setter
        _this.getPaddingProxy = function (newPadding) {
            return new Proxy(newPadding, {
                set: function (target, key, value) {
                    //@ts-ignore
                    if (target[key] !== value) {
                        //@ts-ignore
                        target[key] = value;
                        _this.invalidateElement();
                    }
                    return true;
                }
            });
        };
        _this.paddingProperty = _this.getPaddingProxy(Thickness_1.Thickness.fromNumber(10));
        _this.zoomStateProperty = ZoomState_1.EZoomState.AtExtents;
        _this.viewportBorderProperty = {
            borderBottom: undefined,
            borderLeft: undefined,
            borderRight: undefined,
            borderTop: undefined,
            color: "#00000000",
            border: undefined
        };
        _this.canvasBorderProperty = {
            borderBottom: undefined,
            borderLeft: undefined,
            borderRight: undefined,
            borderTop: undefined,
            color: "#00000000",
            border: undefined
        };
        _this.subChartsProperty = [];
        _this.drawSeriesBehindAxisProperty = false;
        _this.autoColorModeProperty = AutoColorMode_1.EAutoColorMode.OnAddRemoveSeries;
        _this.autoColorRequired = true;
        _this.xCoordSvgTrans = 0;
        _this.yCoordSvgTrans = 0;
        _this.subChartCounterProperty = 1;
        _this.surfaceRenderOrderProperty = undefined;
        _this.resolvedSurfaceRenderOrder = 0;
        var canvasWidth = (_b = (_a = _this.domCanvas2D) === null || _a === void 0 ? void 0 : _a.width) !== null && _b !== void 0 ? _b : app_1.DEFAULT_WIDTH;
        var canvasHeight = (_d = (_c = _this.domCanvas2D) === null || _c === void 0 ? void 0 : _c.height) !== null && _d !== void 0 ? _d : app_1.DEFAULT_HEIGHT;
        _this.webAssemblyContext2D = webAssemblyContext;
        var mocks = options === null || options === void 0 ? void 0 : options.mocks;
        var initViewportSize = (_e = mocks === null || mocks === void 0 ? void 0 : mocks.initViewportSize) !== null && _e !== void 0 ? _e : (function (isCopyCanvas, w, h) {
            if (isCopyCanvas) {
                _this.changeMasterCanvasViewportSize(webAssemblyContext, w, h);
            }
            else {
                _this.changeWebGLCanvasViewportSize(webAssemblyContext, w, h);
            }
        });
        initViewportSize(!!_this.isCopyCanvasSurface, canvasWidth / DpiHelper_1.DpiHelper.PIXEL_RATIO, canvasHeight / DpiHelper_1.DpiHelper.PIXEL_RATIO);
        _this.invalidateElement = _this.invalidateElement.bind(_this);
        _this.onRenderSurfaceDraw = _this.onRenderSurfaceDraw.bind(_this);
        var viewportSize = _this.domCanvas2D
            ? new Size_1.Size(canvasWidth, canvasHeight)
            : new Size_1.Size(app_1.DEFAULT_WIDTH, app_1.DEFAULT_HEIGHT);
        _this.renderSurface = new RenderSurface_1.RenderSurface(webAssemblyContext, viewportSize, (_f = _this.domCanvas2D) === null || _f === void 0 ? void 0 : _f.id);
        _this.renderSurface.handleDraw = _this.onRenderSurfaceDraw;
        _this.sciChartRenderer = new SciChartRenderer_1.SciChartRenderer(_this);
        _this.chartTitleRendererProperty = new ChartTitleRenderer_1.ChartTitleRenderer(_this.webAssemblyContext2D);
        _this.layoutManager = new LayoutManager_1.LayoutManager();
        // TODO: remove this
        //if (this.domCanvas2D) {
        //     this.renderContext2D = new RenderContext2D(this.domCanvas2D);
        //}
        // Setup series
        _this.detachSeries = _this.detachSeries.bind(_this);
        _this.attachSeries = _this.attachSeries.bind(_this);
        _this.renderableSeries = new ObservableArray_1.ObservableArray();
        _this.renderableSeries.collectionChanged.subscribe(function (args) {
            var _a, _b;
            (_a = args.getOldItems()) === null || _a === void 0 ? void 0 : _a.forEach(_this.detachSeries);
            (_b = args.getNewItems()) === null || _b === void 0 ? void 0 : _b.forEach(_this.attachSeries);
        });
        // Setup axis
        _this.detachAxis = _this.detachAxis.bind(_this);
        _this.attachAxis = _this.attachAxis.bind(_this);
        _this.xAxes = new ObservableArray_1.ObservableArray();
        _this.yAxes = new ObservableArray_1.ObservableArray();
        var handler = function (args, isXAxis) {
            var _a, _b;
            (_a = args.getOldItems()) === null || _a === void 0 ? void 0 : _a.forEach(function (axis) {
                axis.visibleRangeChanged.unsubscribeAll();
                _this.detachAxis(axis);
            });
            (_b = args.getNewItems()) === null || _b === void 0 ? void 0 : _b.forEach(function (a) { return _this.attachAxis(a, isXAxis); });
        };
        _this.xAxes.collectionChanged.subscribe(function (arg) { return handler(arg, true); });
        _this.yAxes.collectionChanged.subscribe(function (arg) { return handler(arg, false); });
        _this.adornerLayer = new AdornerLayer_1.AdornerLayer(_this);
        var createSolidBrushCache = (_g = mocks === null || mocks === void 0 ? void 0 : mocks.createSolidBrushCache) !== null && _g !== void 0 ? _g : (function (ctx) { return new SolidBrushCache_1.SolidBrushCache(ctx); });
        _this.solidBrushCacheViewportBorder = createSolidBrushCache(webAssemblyContext);
        _this.solidBrushCacheCanvasBorder = createSolidBrushCache(webAssemblyContext);
        var createWatermarkController = (_j = mocks === null || mocks === void 0 ? void 0 : mocks.createWatermarkController) !== null && _j !== void 0 ? _j : (function (ctx) { return new WatermarkController_1.WatermarkController(ctx); });
        _this.watermarkController = createWatermarkController(webAssemblyContext);
        return _this;
    }
    /**
     * Creates a {@link SciChartSurface} and {@link TSciChart | WebAssembly Context} to occupy the div by element ID in your DOM.
     * @remarks This method is async and must be awaited
     * @param divElement The Div Element ID or reference where the {@link SciChartSurface} will reside
     * @param options Optional - Optional parameters for chart creation. See {@link I2DSurfaceOptions} for more details
     */
    SciChartSurface.create = function (divElement, options) {
        var mark = performance_1.PerformanceDebugHelper.mark(performance_1.EPerformanceMarkType.InitializationStart, { contextId: options === null || options === void 0 ? void 0 : options.id });
        options = SciChartSurface.resolveOptions(options);
        if (app_1.IS_TEST_ENV) {
            return this.createTest(divElement, options);
        }
        else {
            var surfaceConstructor = function (wasmContext, options) {
                return new SciChartSurface(wasmContext, options);
            };
            return (0, createMaster_1.createMultichart)(divElement, surfaceConstructor, options).then(function (result) {
                var _a, _b;
                result.sciChartSurface.applyOptions(options);
                performance_1.PerformanceDebugHelper.mark(performance_1.EPerformanceMarkType.InitializationEnd, {
                    parentContextId: (_a = result.sciChartSurface.domCanvas2D) === null || _a === void 0 ? void 0 : _a.id,
                    contextId: result.sciChartSurface.id,
                    relatedId: (_b = mark === null || mark === void 0 ? void 0 : mark.detail) === null || _b === void 0 ? void 0 : _b.relatedId
                });
                return result;
            });
        }
    };
    SciChartSurface.disposeSharedWasmContext = function () {
        if (Globals_1.sciChartDestinations.length === 0) {
            (0, createMaster_1.disposeMultiChart)();
        }
        _super.disposeSharedWasmContext.call(this);
    };
    /**
     * Performs a similar operation to {@link SciChartSurface.create} but uses a dedicated WebAssembly context for this chart, and draws directly to the target canvas
     * This provides better performance for a single chart, but there is a limit (16) to how many you can have on one page.
     * If you need large numbers of charts all updating at the same time, use this, together with {@link addSubChart} to create many charts on one surface.
     * @param divElement The Div Element ID or reference where the {@link SciChartSurface} will reside
     * @param options - optional parameters for chart creation. See {@link I2DSurfaceOptions} for more details
     */
    SciChartSurface.createSingle = function (divElement, options) {
        var mark = performance_1.PerformanceDebugHelper.mark(performance_1.EPerformanceMarkType.InitializationStart, { contextId: options === null || options === void 0 ? void 0 : options.id });
        options = SciChartSurface.resolveOptions(options);
        if (app_1.IS_TEST_ENV) {
            return this.createTest(divElement, options);
        }
        else {
            var surfaceConstructor = function (wasmContext, options) {
                return new SciChartSurface(wasmContext, options);
            };
            return (0, createSingle_1.createSingleInternal)(divElement, surfaceConstructor, options).then(function (result) {
                var _a, _b;
                result.sciChartSurface.applyOptions(options);
                performance_1.PerformanceDebugHelper.mark(performance_1.EPerformanceMarkType.InitializationEnd, {
                    parentContextId: (_a = result.sciChartSurface.domCanvas2D) === null || _a === void 0 ? void 0 : _a.id,
                    contextId: result.sciChartSurface.id,
                    relatedId: (_b = mark === null || mark === void 0 ? void 0 : mark.detail) === null || _b === void 0 ? void 0 : _b.relatedId
                });
                return result;
            });
        }
    };
    /**
     * Allows setting of web URL for Wasm files, in the case you are loading SciChart outside of npm/webpack environment.
     * Note the version number of wasm Url must match the version number of SciChart.js you are using.
     * To use the default CDN, just call SciChart.SciChartSurface.useWasmFromCDN();
     * @example
     * ```ts
     * import { libraryVersion } from "scichart/Core/BuildStamp";
     *
     * SciChart.SciChartSurface.configure({
     *  wasmUrl: `https://cdn.jsdelivr.net/npm/scichart@${libraryVersion}/_wasm/scichart2d.wasm`
     * });
     * ```
     * @param config
     */
    SciChartSurface.configure = function (config) {
        var _a, _b;
        exports.sciChartConfig.wasmUrl = (_a = config === null || config === void 0 ? void 0 : config.wasmUrl) !== null && _a !== void 0 ? _a : defaultSciChartConfig.wasmUrl;
        exports.sciChartConfig.wasmNoSimdUrl = (_b = config === null || config === void 0 ? void 0 : config.wasmNoSimdUrl) !== null && _b !== void 0 ? _b : defaultSciChartConfig.wasmNoSimdUrl;
    };
    /**
     * Tell SciChart to load the Wasm files from CDN, rather than expecting them to be served by the host server.
     * @deprecated the method name breaks [eslint react-hooks/rules-of-hooks](https://legacy.reactjs.org/docs/hooks-rules.html).
     * To avoid this error in React, use {@link loadWasmFromCDN} instead.
     *
     */
    SciChartSurface.useWasmFromCDN = function () {
        exports.sciChartConfig.wasmUrl = "https://cdn.jsdelivr.net/npm/scichart@".concat(BuildStamp_1.libraryVersion, "/_wasm/scichart2d.wasm");
        exports.sciChartConfig.wasmNoSimdUrl = "https://cdn.jsdelivr.net/npm/scichart@".concat(BuildStamp_1.libraryVersion, "/_wasm/scichart2d-nosimd.wasm");
    };
    /**
     * Tell SciChart to load the Wasm files from the local server, rather than from CDN.
     * @deprecated the method name breaks [eslint react-hooks/rules-of-hooks](https://legacy.reactjs.org/docs/hooks-rules.html).
     * To avoid this error in React, use {@link loadWasmLocal} instead.
     *
     */
    SciChartSurface.useWasmLocal = function () {
        SciChartSurface.configure(defaultSciChartConfig);
    };
    /**
     * Tell SciChart to load the Wasm files from CDN, rather than expecting them to be served by the host server.
     */
    SciChartSurface.loadWasmFromCDN = function () {
        return SciChartSurface.useWasmFromCDN();
    };
    /**
     * Tell SciChart to load the Wasm files from the local server, rather than from CDN.
     */
    SciChartSurface.loadWasmLocal = function () {
        return SciChartSurface.useWasmLocal();
    };
    SciChartSurface.isSubSurface = function (surface) {
        return surface.isSubSurface;
    };
    SciChartSurface.createTest = function (divElement, options) {
        var _a, _b;
        var canvases = sciChartInitCommon_1.default.initCanvas(divElement, (_a = options === null || options === void 0 ? void 0 : options.widthAspect) !== null && _a !== void 0 ? _a : 0, (_b = options === null || options === void 0 ? void 0 : options.heightAspect) !== null && _b !== void 0 ? _b : 0, sciChartInitCommon_1.default.ECanvasType.canvas2D);
        var mocks = {
            initViewportSize: function (_isCopyCanvas, _w, _h) { },
            createWatermarkController: function () { return new WatermarkController_1.MockWatermarkController(); },
            createSolidBrushCache: function () { return new ISolidBrushCache_1.MockSolidBrushCache(); },
        };
        var sciChartSurface = new SciChartSurface(exports.sciChartConfig.testWasm, { canvases: canvases, mocks: mocks });
        sciChartSurface.applyTheme(options === null || options === void 0 ? void 0 : options.theme);
        sciChartSurface.applyOptions(options);
        return new Promise(function (resolve) {
            return resolve({ wasmContext: sciChartSurface.webAssemblyContext2D, sciChartSurface: sciChartSurface });
        });
    };
    Object.defineProperty(SciChartSurface.prototype, "subChartCounter", {
        /**
         * @inheritDoc
         */
        get: function () {
            return this.subChartCounterProperty;
        },
        enumerable: false,
        configurable: true
    });
    /**
     * @inheritDoc
     */
    SciChartSurface.prototype.addSubChartInternal = function (subSurface) {
        var _a;
        if (this.isSubSurface) {
            throw new Error("Can not add subChart to subChart.");
        }
        this.subChartCounterProperty++;
        (_a = subSurface.mouseManager) === null || _a === void 0 ? void 0 : _a.unsubscribe();
        this.subChartsProperty.push(subSurface);
        this.onAttachSubSurface(subSurface);
        subSurface.setIsInitialized();
    };
    /**
     * Remove an existing subChart from a parent surface.  See {@link addSubChart}
     */
    SciChartSurface.prototype.removeSubChart = function (subChart) {
        var index = this.subChartsProperty.findIndex(function (s) { return s === subChart; });
        if (index > -1) {
            this.subChartsProperty.splice(index, 1);
            subChart.delete(true);
        }
    };
    Object.defineProperty(SciChartSurface.prototype, "subCharts", {
        /**
         * The list of subCharts on this surface.  See {@link addSubChart}
         */
        get: function () {
            return this.subChartsProperty;
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(SciChartSurface.prototype, "surfaceType", {
        /**
         * @inheritDoc
         */
        get: function () {
            return SurfaceType_1.ESurfaceType.SciChartSurfaceType;
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(SciChartSurface.prototype, "layoutManager", {
        /**
         * Used internally - gets or sets the {@link LayoutManager}
         */
        get: function () {
            return this.layoutManagerProperty;
        },
        set: function (value) {
            if (this.layoutManagerProperty) {
                this.layoutManagerProperty.sciChartSurface = undefined;
            }
            this.layoutManagerProperty = value;
            this.layoutManagerProperty.sciChartSurface = this;
            this.invalidateElement();
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(SciChartSurface.prototype, "chartTitleRenderer", {
        /**
         * @inheritDoc
         */
        get: function () {
            return this.chartTitleRendererProperty;
        },
        set: function (value) {
            var _a;
            (_a = this.chartTitleRendererProperty) === null || _a === void 0 ? void 0 : _a.delete();
            this.chartTitleRendererProperty = value;
            this.invalidateElement();
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(SciChartSurface.prototype, "dataLabelLayoutManager", {
        /**
         * Gets or sets the {@link ISeriesTextLayoutManager} for performing text layout across multiple series
         */
        get: function () {
            return this.dataLabelLayoutManagerProperty;
        },
        /**
         * Used internally - gets or sets the {@link ISeriesTextLayoutManager} for performing text layout across multiple series
         */
        set: function (value) {
            this.dataLabelLayoutManagerProperty = value;
            this.invalidateElement();
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(SciChartSurface.prototype, "title", {
        /**
         * Gets or sets the title for the SciChartSurface
         */
        get: function () {
            return this.titleProperty;
        },
        /**
         * Gets or sets the title for the SciChartSurface
         */
        set: function (value) {
            if (this.titleProperty !== value) {
                this.titleProperty = value;
                this.invalidateElement();
            }
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(SciChartSurface.prototype, "titleStyle", {
        /**
         * Gets or sets the title text style and placement for the SciChartSurface as {@link TChartTitleStyle}
         */
        get: function () {
            return this.titleStyleProperty;
        },
        /**
         * Gets or sets the title text style and placement for the SciChartSurface as {@link TChartTitleStyle}
         * @remarks if updating, should be set as an object (or partial object) of type {@link TChartTitleStyle},
         * instead of directly setting individual properties
         */
        set: function (value) {
            if (this.titleStyleProperty !== value) {
                this.titleStyleProperty = Object.assign({}, this.titleStyleProperty, value);
                this.invalidateElement();
            }
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(SciChartSurface.prototype, "padding", {
        /**
         * Gets or sets the Padding between the SciChartSurface and its inner elements, in order top, right, bottom, left
         */
        get: function () {
            return this.paddingProperty;
        },
        set: function (padding) {
            if (!Thickness_1.Thickness.areEqual(this.paddingProperty, padding)) {
                this.paddingProperty = this.getPaddingProxy(padding);
                this.invalidateElement();
            }
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(SciChartSurface.prototype, "adjustedPadding", {
        /**
         * Gets the adjusted padding between the SciChartSurface and its inner elements, in order top, right, bottom, left
         * Defines a resulting padding accordingly to DPI scaling.
         */
        get: function () {
            return DpiHelper_1.DpiHelper.adjustThickness(this.padding);
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(SciChartSurface.prototype, "debugRendering", {
        /**
         * Gets or sets a property whether rendering should be debugged. This will draw rectangles around key boxes and areas on the chart.
         * Used internally for development purposes
         */
        get: function () {
            return this.debugRenderingProperty;
        },
        /**
         * Gets or sets a property whether rendering should be debugged. This will draw rectangles around key boxes and areas on the chart.
         * Used internally for development purposes
         */
        set: function (debugRendering) {
            this.debugRenderingProperty = debugRendering;
            this.invalidateElement();
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(SciChartSurface.prototype, "autoColorMode", {
        /**
         * Gets or sets the {@link EAutoColorMode} which determines when resolution of AUTO_COLOR should occur
         */
        get: function () {
            return this.autoColorModeProperty;
        },
        /**
         * Gets or sets the {@link EAutoColorMode} which determines when resolution of AUTO_COLOR should occur
         */
        set: function (autoColorMode) {
            this.autoColorModeProperty = autoColorMode;
            if (autoColorMode !== AutoColorMode_1.EAutoColorMode.Never && !this.autoColorRequired) {
                this.autoColorRequired = true;
            }
            else if (autoColorMode === AutoColorMode_1.EAutoColorMode.Never) {
                this.autoColorRequired = false;
            }
            this.invalidateElement();
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(SciChartSurface.prototype, "isInvalidated", {
        get: function () {
            var _a;
            return (_a = this.sciChartRenderer) === null || _a === void 0 ? void 0 : _a.isInvalidated;
        },
        enumerable: false,
        configurable: true
    });
    /**
     * @inheritDoc
     */
    SciChartSurface.prototype.applyTheme = function (themeProvider) {
        // TODO move to base when title is implemented on 3d charts
        var previousThemeProvider = this.previousThemeProvider;
        if (this.titleStyle.color === previousThemeProvider.chartTitleColor) {
            this.titleStyle = { color: themeProvider.chartTitleColor };
        }
        _super.prototype.applyTheme.call(this, themeProvider);
        this.renderableSeries.asArray().forEach(function (rs) { return rs.applyTheme(themeProvider); });
        this.xAxes.asArray().forEach(function (axis) { return axis.applyTheme(themeProvider); });
        this.yAxes.asArray().forEach(function (axis) { return axis.applyTheme(themeProvider); });
    };
    /**
     * @inheritDoc
     */
    SciChartSurface.prototype.changeViewportSize = function (pixelWidth, pixelHeight) {
        logger_1.Logger.debug("changeViewportSize");
        if (!pixelWidth || !pixelHeight || this.isDeleted) {
            return;
        }
        // Changing the viewportSize
        var backBufferWidth = pixelWidth * DpiHelper_1.DpiHelper.PIXEL_RATIO;
        var backBufferHeight = pixelHeight * DpiHelper_1.DpiHelper.PIXEL_RATIO;
        this.renderSurface.viewportSize = new Size_1.Size(backBufferWidth, backBufferHeight);
        if (this.isCopyCanvasSurface) {
            this.changeMasterCanvasViewportSize(this.webAssemblyContext2D, pixelWidth, pixelHeight);
            if (this.domCanvas2D) {
                DpiHelper_1.DpiHelper.setSize(this.domCanvas2D, pixelWidth, pixelHeight);
            }
        }
        else {
            this.changeWebGLCanvasViewportSize(this.webAssemblyContext2D, pixelWidth, pixelHeight);
        }
        for (var _i = 0, _a = this.subChartsProperty; _i < _a.length; _i++) {
            var chart = _a[_i];
            chart.changeViewportSize(backBufferWidth, backBufferHeight);
        }
        // Bypass the isSuspended check, otherwise the chart will go blank if it is resized while suspended
        this.invalidateElement({ force: true });
    };
    /**
     * @inheritDoc
     */
    SciChartSurface.prototype.invalidateElement = function (options) {
        var _this = this;
        var _a, _b, _c;
        logger_1.Logger.debug("Invalidating ".concat((_a = this.id) !== null && _a !== void 0 ? _a : (_b = this.domChartRoot) === null || _b === void 0 ? void 0 : _b.id, ": force=").concat(options === null || options === void 0 ? void 0 : options.force, " isSuspended=").concat(this.isSuspended, " isInitialized=").concat(this.isInitialized, ". svgOnly: ").concat(options === null || options === void 0 ? void 0 : options.svgOnly, " isInvalidated: ").concat((_c = this.sciChartRenderer) === null || _c === void 0 ? void 0 : _c.isInvalidated));
        // When isSuspended (see suspendUpdates() function) ignore drawing
        if (!(options === null || options === void 0 ? void 0 : options.force) && (this.isSuspended || this.isDeleted || !this.isInitialized || !this.isWebGLContextActive)) {
            return;
        }
        performance_1.PerformanceDebugHelper.mark(this.sciChartRenderer.isInvalidated
            ? performance_1.EPerformanceMarkType.Invalidate
            : performance_1.EPerformanceMarkType.LeadingInvalidate, { contextId: this.id });
        if (options === null || options === void 0 ? void 0 : options.svgOnly) {
            if (this.sciChartRenderer.isInvalidated || this.sciChartRenderer.svgRenderRequestId) {
                return;
            }
            this.sciChartRenderer.svgRenderRequestId = requestAnimationFrame(function () {
                _this.sciChartRenderer.svgRenderRequestId = undefined;
                if (!_this.sciChartRenderer.isInvalidated) {
                    _this.sciChartRenderer.renderDomOnly();
                }
            });
        }
        else {
            if (this.sciChartRenderer.svgRenderRequestId) {
                cancelAnimationFrame(this.sciChartRenderer.svgRenderRequestId);
                this.sciChartRenderer.svgRenderRequestId = undefined;
            }
            if (!this.sciChartRenderer.isInvalidated) {
                var canvasId = this.domCanvas2D ? this.domCanvas2D.id : "undefinedCanvasId";
                this.sciChartRenderer.isInvalidated = this.renderSurface.invalidateElement(canvasId);
                this.redrawRequested.raiseEvent(this.sciChartRenderer.isInvalidated);
            }
        }
    };
    // Step_5: Get context and pass drawing to SciChartRenderer
    SciChartSurface.prototype.doDrawingLoop = function (context) {
        var _a;
        if (this.isDeleted)
            return;
        var mark = performance_1.PerformanceDebugHelper.mark(performance_1.EPerformanceMarkType.DrawingLoopStart, {
            contextId: this.id,
            parentContextId: SciChartSurface.isSubSurface(this) ? this.parentSurface.id : undefined,
            level: performance_1.EPerformanceDebugLevel.Verbose
        });
        context = context !== null && context !== void 0 ? context : this.renderSurface.getRenderContext();
        this.currentWebGlRenderContextProperty = context;
        try {
            var unlock = this.suspender.lock();
            try {
                if (this.autoColorRequired &&
                    ((this.themeProvider.strokePalette && this.themeProvider.strokePalette.length > 0) ||
                        (this.themeProvider.fillPalette && this.themeProvider.fillPalette.length > 0))) {
                    this.resolveAutoColors();
                    if (this.autoColorMode !== AutoColorMode_1.EAutoColorMode.Always) {
                        this.autoColorRequired = false;
                    }
                }
                if (!this.sciChartRenderer.domRenderRun) {
                    this.preRender.raiseEvent(context);
                }
            }
            catch (err) {
                if (err === null || err === void 0 ? void 0 : err.message) {
                    console.error(err === null || err === void 0 ? void 0 : err.message);
                }
                console.error(err);
            }
            finally {
                unlock();
            }
            this.sciChartRenderer.render(context);
            var isInvalidated = this.isInvalidated;
            performance_1.PerformanceDebugHelper.mark(isInvalidated ? performance_1.EPerformanceMarkType.Rendered : performance_1.EPerformanceMarkType.FullStateRendered, { contextId: this.id });
            this.rendered.raiseEvent(isInvalidated);
        }
        catch (err) {
            // @ts-ignore
            if (err.name === "BindingError") {
                console.error(err);
                console.warn("Binding errors can occur if a previous chart using the same div id was not deleted correctly, or if you try to share data or series between charts that use different webassembly contexts.");
                (0, NativeObject_1.freeCache)(this.webAssemblyContext2D).delete();
            }
            else if (this.domChartRoot) {
                console.error("Error from chart in div ".concat(this.domChartRoot.id, ":"), err);
            }
            else {
                // Surface the error for tests
                throw err;
            }
            this.renderError.raiseEvent(err);
        }
        performance_1.PerformanceDebugHelper.mark(performance_1.EPerformanceMarkType.DrawingLoopEnd, {
            contextId: this.id,
            parentContextId: SciChartSurface.isSubSurface(this) ? this.parentSurface.id : undefined,
            relatedId: (_a = mark === null || mark === void 0 ? void 0 : mark.detail) === null || _a === void 0 ? void 0 : _a.relatedId,
            level: performance_1.EPerformanceDebugLevel.Verbose
        });
    };
    /**
     * @inheritDoc
     */
    SciChartSurface.prototype.delete = function (clearHtml) {
        if (clearHtml === void 0) { clearHtml = true; }
        if (this.isDeleted) {
            try {
                if (process.env.NODE_ENV !== "production") {
                    console.warn("Trying to delete the surface with ID = \"".concat(this.id, ")\", which has already been deleted!"));
                }
            }
            catch (err) {
                console.warn(err);
            }
            return;
        }
        this.isDeletedProperty = true;
        if (this.sciChartRenderer.svgRenderRequestId) {
            cancelAnimationFrame(this.sciChartRenderer.svgRenderRequestId);
            this.sciChartRenderer.svgRenderRequestId = undefined;
        }
        for (var _i = 0, _a = this.subChartsProperty; _i < _a.length; _i++) {
            var chart = _a[_i];
            chart.delete(true);
        }
        this.subChartsProperty = [];
        if (this.layoutManagerProperty.type === LayoutManagerType_1.ELayoutManagerType.Synchronised) {
            if (this.layoutManagerProperty.verticalGroup) {
                this.layoutManagerProperty.verticalGroup.removeSurface(this);
            }
            if (this.layoutManagerProperty.horizontalGroup) {
                this.layoutManagerProperty.horizontalGroup.removeSurface(this);
            }
        }
        this.layoutManagerProperty.sciChartSurface = undefined;
        this.layoutManagerProperty = undefined;
        this.renderableSeries.asArray().forEach(function (rs) { return rs.delete(); });
        this.renderableSeries.clear(false);
        this.xAxes.asArray().forEach(function (xAxis) { return xAxis.delete(); });
        this.yAxes.asArray().forEach(function (yAxis) { return yAxis.delete(); });
        this.solidBrushCacheViewportBorder = (0, Deleter_1.deleteSafe)(this.solidBrushCacheViewportBorder);
        this.solidBrushCacheCanvasBorder = (0, Deleter_1.deleteSafe)(this.solidBrushCacheCanvasBorder);
        this.watermarkController = (0, Deleter_1.deleteSafe)(this.watermarkController);
        this.chartTitleRendererProperty = (0, Deleter_1.deleteSafe)(this.chartTitleRenderer);
        this.sciChartRenderer = undefined;
        this.renderSurface = undefined;
        this.clearRootElement(clearHtml);
        _super.prototype.delete.call(this);
    };
    /**
     * @inheritDoc
     */
    SciChartSurface.prototype.onDpiChanged = function (args) {
        var _a, _b;
        performance_1.PerformanceDebugHelper.mark(performance_1.EPerformanceMarkType.DpiChange, { contextId: this.id });
        logger_1.Logger.debug("onDpiChanged");
        this.renderableSeries.asArray().forEach(function (rs) { return rs.onDpiChanged(args); });
        this.xAxes.asArray().forEach(function (a) { return a.onDpiChanged(); });
        this.yAxes.asArray().forEach(function (a) { return a.onDpiChanged(); });
        // for subsurface the changeViewportSize is called as part of the changeViewportSize on the parent surface
        if (!this.isSubSurface) {
            // Force a viewport size change as size-changed may not fire when parent div has width, height
            this.changeViewportSize((_a = this.getMainCanvas()) === null || _a === void 0 ? void 0 : _a.clientWidth, (_b = this.getMainCanvas()) === null || _b === void 0 ? void 0 : _b.clientHeight);
        }
        _super.prototype.onDpiChanged.call(this, args);
    };
    /**
     * @inheritDoc
     */
    SciChartSurface.prototype.getXAxisById = function (axisId) {
        return this.xAxes.getById(axisId);
    };
    /**
     * @inheritDoc
     */
    SciChartSurface.prototype.getDefaultXAxis = function () {
        return this.xAxes.get(0);
    };
    /**
     * @inheritDoc
     */
    SciChartSurface.prototype.getYAxisById = function (axisId) {
        return this.yAxes.getById(axisId);
    };
    /**
     * @inheritDoc
     */
    SciChartSurface.prototype.getDefaultYAxis = function () {
        return this.yAxes.get(0);
    };
    /**
     * Update accumulated vectors for all stacked collections
     */
    SciChartSurface.prototype.updateStackedCollectionAccumulatedVectors = function () {
        var stackedCollection = this.renderableSeries.asArray().filter(function (el) { return el.isCollection; });
        stackedCollection.forEach(function (el) { return el.updateAccumulatedVectors(); });
    };
    /**
     * @summary Zooms the {@link SciChartSurface} in the X and Y direction to extents of all data (zoom to fit)
     * @description
     * @param animationDurationMs An optional animation duration. Default value is 0, which means 'no animation'
     * @param easingFunction An optional easing function for animations. See {@link TEasingFn} for a list of values
     * @param onCompleted the callback function
     */
    SciChartSurface.prototype.zoomExtents = function (animationDurationMs, easingFunction, onCompleted, xAxisSelectorFn, yAxisSelectorFn) {
        if (animationDurationMs === void 0) { animationDurationMs = 0; }
        if (easingFunction === void 0) { easingFunction = EasingFunctions_1.easing.outExpo; }
        if (onCompleted === void 0) { onCompleted = function () { }; }
        if (xAxisSelectorFn === void 0) { xAxisSelectorFn = function () { return true; }; }
        if (yAxisSelectorFn === void 0) { yAxisSelectorFn = function () { return true; }; }
        this.updateStackedCollectionAccumulatedVectors();
        var xSize = this.xAxes === undefined ? 0 : this.xAxes.size();
        var ySize = this.yAxes === undefined ? 0 : this.yAxes.size();
        if (xSize === 0 || ySize === 0) {
            throw new Error("Cannot ZoomExtents when XAxes or YAxes is undefined or empty");
        }
        // Update the VisibleRange of X Axes
        var xRanges = this.zoomExtentsXInternal(animationDurationMs, easingFunction, xAxisSelectorFn, onCompleted);
        // Now ZoomExtents on Y for N Y-axes
        this.zoomExtentsYInternal(xRanges, animationDurationMs, easingFunction, yAxisSelectorFn, onCompleted);
    };
    /**
     * @summary Zooms the {@link SciChartSurface} in the X direction to extents of all data (zoom to fit)
     * @description
     * @param animationDurationMs An optional animation duration. Default value is 0, which means 'no animation'
     * @param easingFunction An optional easing function for animations. See {@link TEasingFn} for a list of values
     */
    SciChartSurface.prototype.zoomExtentsX = function (animationDurationMs, easingFunction, axisSelectorFn) {
        if (animationDurationMs === void 0) { animationDurationMs = 0; }
        if (easingFunction === void 0) { easingFunction = EasingFunctions_1.easing.outExpo; }
        if (axisSelectorFn === void 0) { axisSelectorFn = function () { return true; }; }
        this.zoomExtentsXInternal(animationDurationMs, easingFunction, axisSelectorFn);
    };
    /**
     * @inheritDoc
     */
    SciChartSurface.prototype.zoomExtentsY = function (animationDurationMs, easingFunction, axisSelectorFn) {
        if (animationDurationMs === void 0) { animationDurationMs = 0; }
        if (easingFunction === void 0) { easingFunction = EasingFunctions_1.easing.outExpo; }
        if (axisSelectorFn === void 0) { axisSelectorFn = function () { return true; }; }
        this.zoomExtentsYInternal(undefined, animationDurationMs, easingFunction, axisSelectorFn);
    };
    /**
     * @inheritDoc
     */
    SciChartSurface.prototype.updateWatermark = function (left, bottom) {
        var _a;
        this.watermarkController.update(left, bottom, this.renderSurface.viewportSize.width, (_a = this.themeProvider) === null || _a === void 0 ? void 0 : _a.isLightBackground);
    };
    /**
     * Sets zoomStateProperty
     * @param zoomState
     */
    SciChartSurface.prototype.setZoomState = function (zoomState) {
        this.zoomStateProperty = zoomState;
    };
    Object.defineProperty(SciChartSurface.prototype, "zoomState", {
        /**
         * Gets zoomStateProperty
         */
        get: function () {
            return this.zoomStateProperty;
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(SciChartSurface.prototype, "viewportBorder", {
        /**
         * Gets or sets the SciChartSurface Viewport Border properties
         */
        get: function () {
            return this.viewportBorderProperty;
        },
        /**
         * Gets or sets the SciChartSurface Viewport Border properties
         */
        set: function (value) {
            this.viewportBorderProperty = __assign(__assign({}, this.viewportBorderProperty), value);
            this.notifyPropertyChanged("ViewportBorder");
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(SciChartSurface.prototype, "canvasBorder", {
        /**
         * Gets or sets the SciChartSurface Canvas Border properties
         */
        get: function () {
            return this.canvasBorderProperty;
        },
        /**
         * Gets or sets the SciChartSurface Canvas Border properties
         */
        set: function (value) {
            this.canvasBorderProperty = __assign(__assign({}, this.canvasBorderProperty), value);
            this.notifyPropertyChanged("canvasBorder");
        },
        enumerable: false,
        configurable: true
    });
    /**
     * Gets or sets the drawing order for surfaces and their subsurfaces.
     * This allows for a parent surface to draw over a subsurface.
     * This does not affect the drawing order of separate surfaces - use z-index on the container div to control that.
     */
    SciChartSurface.prototype.getSurfaceRenderOrder = function () {
        var _a;
        return (_a = this.surfaceRenderOrderProperty) !== null && _a !== void 0 ? _a : this.resolvedSurfaceRenderOrder;
    };
    /**
     * Gets or sets the drawing order for surfaces and their subsurfaces.
     * This allows for a parent surface to draw over a subsurface.
     * This does not affect the drawing order of separate surfaces - use z-index on the container div to control that.
     */
    SciChartSurface.prototype.setSurfaceRenderOrder = function (value) {
        if (this.surfaceRenderOrderProperty != value) {
            this.surfaceRenderOrderProperty = value;
            this.notifyPropertyChanged("surfaceRenderOrder");
        }
    };
    /**
     * Used internally - draws SciChartSurface borders
     */
    SciChartSurface.prototype.drawBorder = function (renderContext) {
        // Draw Viewport Border
        (0, drawBorder_1.drawBorder)(renderContext, this.webAssemblyContext2D, this.solidBrushCacheViewportBorder, this.seriesViewRect, this.clipRect, this.leftViewportBorder, this.topViewportBorder, this.rightViewportBorder, this.bottomViewportBorder, this.viewportBorder.color);
        // Draw Canvas Border
        var canvasSize = renderContext.viewportSize;
        var canvasBorderRect = SciChartSurface.isSubSurface(this)
            ? this.getSubChartRect()
            : Rect_1.Rect.create(this.leftCanvasBorder, this.topCanvasBorder, Math.floor(canvasSize.width - this.leftCanvasBorder - this.rightCanvasBorder), Math.floor(canvasSize.height - this.topCanvasBorder - this.bottomCanvasBorder));
        (0, drawBorder_1.drawBorder)(renderContext, this.webAssemblyContext2D, this.solidBrushCacheCanvasBorder, canvasBorderRect, this.clipRect, this.leftCanvasBorder, this.topCanvasBorder, this.rightCanvasBorder, this.bottomCanvasBorder, this.canvasBorder.color);
    };
    Object.defineProperty(SciChartSurface.prototype, "leftViewportBorder", {
        /**
         * Gets the SciChartSurface Viewport Left Border
         */
        get: function () {
            var _a, _b;
            return (_b = (_a = this.viewportBorder.borderLeft) !== null && _a !== void 0 ? _a : this.viewportBorder.border) !== null && _b !== void 0 ? _b : 0;
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(SciChartSurface.prototype, "rightViewportBorder", {
        /**
         * Gets the SciChartSurface Viewport Right Border
         */
        get: function () {
            var _a, _b;
            return (_b = (_a = this.viewportBorder.borderRight) !== null && _a !== void 0 ? _a : this.viewportBorder.border) !== null && _b !== void 0 ? _b : 0;
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(SciChartSurface.prototype, "topViewportBorder", {
        /**
         * Gets the SciChartSurface Viewport Top Border
         */
        get: function () {
            var _a, _b;
            return (_b = (_a = this.viewportBorder.borderTop) !== null && _a !== void 0 ? _a : this.viewportBorder.border) !== null && _b !== void 0 ? _b : 0;
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(SciChartSurface.prototype, "bottomViewportBorder", {
        /**
         * Gets the SciChartSurface Viewport Bottom Border
         */
        get: function () {
            var _a, _b;
            return (_b = (_a = this.viewportBorder.borderBottom) !== null && _a !== void 0 ? _a : this.viewportBorder.border) !== null && _b !== void 0 ? _b : 0;
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(SciChartSurface.prototype, "leftCanvasBorder", {
        /**
         * Gets the SciChartSurface Canvas Left Border
         */
        get: function () {
            var _a, _b;
            return (_b = (_a = this.canvasBorder.borderLeft) !== null && _a !== void 0 ? _a : this.canvasBorder.border) !== null && _b !== void 0 ? _b : 0;
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(SciChartSurface.prototype, "rightCanvasBorder", {
        /**
         * Gets the SciChartSurface Canvas Right Border
         */
        get: function () {
            var _a, _b;
            return (_b = (_a = this.canvasBorder.borderRight) !== null && _a !== void 0 ? _a : this.canvasBorder.border) !== null && _b !== void 0 ? _b : 0;
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(SciChartSurface.prototype, "topCanvasBorder", {
        /**
         * Gets the SciChartSurface Canvas Top Border
         */
        get: function () {
            var _a, _b;
            return (_b = (_a = this.canvasBorder.borderTop) !== null && _a !== void 0 ? _a : this.canvasBorder.border) !== null && _b !== void 0 ? _b : 0;
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(SciChartSurface.prototype, "bottomCanvasBorder", {
        /**
         * Gets the SciChartSurface Canvas Bottom Border
         */
        get: function () {
            var _a, _b;
            return (_b = (_a = this.canvasBorder.borderBottom) !== null && _a !== void 0 ? _a : this.canvasBorder.border) !== null && _b !== void 0 ? _b : 0;
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(SciChartSurface.prototype, "currentWebGlRenderContext", {
        get: function () {
            return this.currentWebGlRenderContextProperty;
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(SciChartSurface.prototype, "chartViewRect", {
        get: function () {
            var viewportSize = this.renderSurface.viewportSize;
            return new Rect_1.Rect(0, 0, viewportSize.width, viewportSize.height);
        },
        enumerable: false,
        configurable: true
    });
    /**
     * Used internally, updates background after switching between different SciChartSurfaces
     * @remarks INTERNAL USE. Check the {@link SciChartSurface.background} property for setting a background.
     */
    SciChartSurface.prototype.updateBackground = function (renderContext) {
        var _a;
        this.applySciChartBackground((_a = this.background) !== null && _a !== void 0 ? _a : this.themeProvider.sciChartBackground, renderContext);
    };
    /**
     * Is being called on each render, to run animations
     * @param timeElapsed
     */
    SciChartSurface.prototype.onAnimate = function (timeElapsed) {
        this.renderableSeries.asArray().forEach(function (rs) { return rs.onAnimate(timeElapsed); });
        // advance all animations in queue
        var remainingAnimations = [];
        for (var i = 0; i < this.animationList.length; i++) {
            var animation = this.animationList[i];
            if (!animation.isComplete) {
                animation.update(timeElapsed);
                if (!animation.isComplete) {
                    remainingAnimations.push(animation);
                }
            }
        }
        this.animationList = remainingAnimations;
    };
    /**
     * Gets the generic animations currently on the surface. Do not manipulate this array directly.
     * To add, use addAnimation.  To remove, find an animation and call .cancel() on it.
     */
    SciChartSurface.prototype.getAnimations = function () {
        return this.animationList;
    };
    /**
     * Add a {@link GenericAnimation} to the surface.
     * Multiple animations will be run in parallel, so if you want to run one after another, use the onCompleted callback
     * to add another animation after the first completes
     */
    SciChartSurface.prototype.addAnimation = function () {
        var _this = this;
        var animations = [];
        for (var _i = 0; _i < arguments.length; _i++) {
            animations[_i] = arguments[_i];
        }
        if (animations === undefined)
            return;
        animations.forEach(function (a) { return _this.animationList.push(a); });
        this.invalidateElement();
    };
    Object.defineProperty(SciChartSurface.prototype, "isRunningAnimation", {
        /**
         * Returns true if an animation is running
         */
        get: function () {
            for (var i = 0; i < this.renderableSeries.size(); i++) {
                if (this.renderableSeries.get(i).isRunningAnimation) {
                    return true;
                }
            }
            return this.animationList.some(function (a) { return !a.isComplete; });
        },
        enumerable: false,
        configurable: true
    });
    /**
     * Returns the seriesViewRect padding relative to the canvas
     * @param scaled If True returns scaled values, if False divided by {@link DpiHelper.PIXEL_RATIO}
     * Use not scaled values for SVG annotations and the Legend
     */
    SciChartSurface.prototype.getSeriesViewRectPadding = function (scaled) {
        if (scaled === void 0) { scaled = true; }
        if (!this.seriesViewRect) {
            throw new Error("Cannot get seriesViewRect before layout has ocurred. Move code that calls to be triggered by sciChartSurface.rendered");
        }
        var divider = scaled ? 1 : DpiHelper_1.DpiHelper.PIXEL_RATIO;
        var seriesViewRect = this.seriesViewRect;
        var left = seriesViewRect.left / divider;
        var top = seriesViewRect.top / divider;
        var right = (this.domCanvas2D.width - seriesViewRect.right) / divider;
        var bottom = (this.domCanvas2D.height - seriesViewRect.bottom) / divider;
        return new Thickness_1.Thickness(top, right, bottom, left);
    };
    /**
     * Calls resolveAutoColors on each series to resolve colors marked as auto based on the seriesColorPalette
     * To configure which series this applies to, set a filter funtion on {@link ScichartSurface.autoColorFilter}
     */
    SciChartSurface.prototype.resolveAutoColors = function () {
        var _this = this;
        var maxSeries = 0;
        if (this.autoColorFilter) {
            var stackedCollections = this.renderableSeries
                .asArray()
                .filter(function (el) { return el.isCollection && _this.autoColorFilter(el); });
            maxSeries = this.renderableSeries.asArray().filter(this.autoColorFilter).length - stackedCollections.length;
            for (var _i = 0, stackedCollections_1 = stackedCollections; _i < stackedCollections_1.length; _i++) {
                var sc = stackedCollections_1[_i];
                maxSeries += sc.asArray().filter(this.autoColorFilter).length;
            }
        }
        else {
            var stackedCollections = this.renderableSeries.asArray().filter(function (el) { return el.isCollection; });
            maxSeries = this.renderableSeries.size() - stackedCollections.length;
            for (var _a = 0, stackedCollections_2 = stackedCollections; _a < stackedCollections_2.length; _a++) {
                var sc = stackedCollections_2[_a];
                maxSeries += sc.size();
            }
        }
        var index = 0;
        for (var i = 0; i < this.renderableSeries.size(); i++) {
            var rs = this.renderableSeries.get(i);
            if (this.autoColorFilter && !this.autoColorFilter(rs))
                continue;
            if (rs.isCollection) {
                // Have to unroll this manually now to handle filtering
                for (var _b = 0, _c = rs.asArray(); _b < _c.length; _b++) {
                    var el = _c[_b];
                    if (this.autoColorFilter && !this.autoColorFilter(el))
                        continue;
                    el.resolveAutoColors(index, maxSeries, this.themeProvider);
                    index += 1;
                }
            }
            else {
                rs.resolveAutoColors(index, maxSeries, this.themeProvider);
                index += 1;
            }
        }
    };
    /**
     *
     * @param fontName Register a font to be used with native text.
     * @param url
     * @returns
     */
    SciChartSurface.prototype.registerFont = function (fontName, url) {
        return __awaiter(this, void 0, void 0, function () {
            var _this = this;
            return __generator(this, function (_a) {
                if (!fontName.includes(".")) {
                    fontName += ".ttf";
                }
                return [2 /*return*/, new Promise(function (resolve, reject) {
                        var callback = _this.webAssemblyContext2D.SCRTFileLoadCallbackInterface.implement({
                            OnLoadComplete: function (success, message) {
                                if (success) {
                                    resolve(true);
                                }
                                else {
                                    console.error("Failed to load ".concat(fontName, " from ").concat(url, ".  Error: ").concat(message));
                                    resolve(false);
                                }
                            }
                        });
                        _this.webAssemblyContext2D.SCRTRegisterFile(fontName, url, callback);
                    })];
            });
        });
    };
    /**
     * Used internally - sets SVG Canvas Translation
     * @param x
     * @param y
     */
    SciChartSurface.prototype.setCoordSvgTranslation = function (x, y) {
        this.xCoordSvgTrans = x;
        this.yCoordSvgTrans = y;
    };
    /**
     * Gets SVG Canvas Translation, used to draw on SVG Canvas using different clipping modes
     */
    SciChartSurface.prototype.getCoordSvgTranslation = function () {
        return new Point_1.Point(this.xCoordSvgTrans, this.yCoordSvgTrans);
    };
    SciChartSurface.prototype.getOptions = function () {
        var _a;
        var theme;
        if ("toJSON" in this.themeProvider) {
            // @ts-ignore
            theme = this.themeProvider.toJSON();
        }
        else {
            theme = this.themeProvider;
        }
        var options = {
            id: this.id,
            title: this.title,
            titleStyle: this.titleStyle,
            background: this.background,
            canvasBorder: this.canvasBorder,
            heightAspect: this.heightAspect,
            widthAspect: this.widthAspect,
            layoutManager: (_a = this.layoutManager) === null || _a === void 0 ? void 0 : _a.toJSON(),
            padding: this.padding,
            theme: theme,
            viewportBorder: this.viewportBorder,
            loader: this.loaderJson,
            drawSeriesBehindAxis: this.drawSeriesBehindAxis,
            disableAspect: this.disableAspect,
            createSuspended: this.createSuspended,
            autoColorMode: this.autoColorMode,
            touchAction: this.touchActionProperty,
            freezeWhenOutOfView: this.freezeWhenOutOfView
        };
        return options;
    };
    /**
     * Convert the object to a definition that can be serialized to JSON, or used directly with the builder api
     * @param excludeData if set true, data values will not be included in the json.
     */
    SciChartSurface.prototype.toJSON = function (excludeData) {
        if (excludeData === void 0) { excludeData = false; }
        var options = this.getOptions();
        var definition = {
            type: SciChartSurfaceType_1.ESciChartSurfaceType.Default2D,
            surface: options,
            xAxes: this.xAxes.asArray().map(function (axis) { return axis.toJSON(); }),
            yAxes: this.yAxes.asArray().map(function (axis) { return axis.toJSON(); }),
            series: this.renderableSeries.asArray().map(function (series) { return series.toJSON(excludeData); }),
            modifiers: this.chartModifiers.asArray().map(function (modifier) { return modifier.toJSON(); }),
            annotations: this.annotations.asArray().map(function (annotation) { return annotation.toJSON(); }),
            onCreated: this.onCreatedName,
            subCharts: this.subCharts.map(function (sc) { return sc.toJSON(false); }),
            createSingle: !this.isCopyCanvasSurface
        };
        return definition;
    };
    /**
     * Triggers the rerendering of the surface and after the chart rerendering is completed,
     * returns its serialized state retrieved with {@link SciChartSurface.toJSON}.
     *
     * @param excludeData - if set true, data values will not be included in the json.
     * @returns JSON-like object {@link ISciChart2DDefinition}
     */
    SciChartSurface.prototype.getNextState = function (excludeData) {
        if (excludeData === void 0) { excludeData = false; }
        return __awaiter(this, void 0, void 0, function () {
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0: return [4 /*yield*/, this.nextStateRender({ resumeBefore: true, invalidateOnResume: true, suspendAfter: true })];
                    case 1:
                        _a.sent();
                        return [2 /*return*/, this.toJSON(excludeData)];
                }
            });
        });
    };
    /**
     * Validates {@link SciChartSurface} and links {@link RenderableSeries} to axes
     * @returns List of errors if there are any
     */
    SciChartSurface.prototype.validateAndLink = function () {
        var errors = [];
        if (this.renderableSeries.size() > 0) {
            if (this.xAxes.size() === 0) {
                errors.push("Chart must have at least one X axis");
            }
            if (this.yAxes.size() === 0) {
                errors.push("Chart must have at least one Y axis");
            }
            this.renderableSeries.asArray().forEach(function (rs, i) {
                rs.linkAxes();
                var xAxis = rs.xAxis;
                if (!xAxis) {
                    errors.push("".concat(rs.type, ", index ").concat(i, ", id ").concat(rs.id, " references xAxisId ").concat(rs.xAxisId, " which does not exist on the surface"));
                }
                var yAxis = rs.yAxis;
                if (!yAxis) {
                    errors.push("".concat(rs.type, ", index ").concat(i, ", id ").concat(rs.id, " references yAxisId ").concat(rs.yAxisId, " which does not exist on the surface"));
                }
                if (xAxis && yAxis) {
                    if (xAxis.isVerticalChart &&
                        ![AxisAlignment_1.EAxisAlignment.Top, AxisAlignment_1.EAxisAlignment.Bottom].includes(yAxis.axisAlignment))
                        errors.push("For vertical chart (chart with X Axis alignment Left or Right) Y Axis alignment should be Top or Bottom, X Axis ID = ".concat(xAxis.id));
                    if ((0, AxisAlignment_1.getIsVertical)(xAxis.axisAlignment) && (0, AxisAlignment_1.getIsVertical)(yAxis.axisAlignment))
                        errors.push("Both x and y axes can't have vertical alignment");
                    if ((0, AxisAlignment_1.getIsHorizontal)(xAxis.axisAlignment) && (0, AxisAlignment_1.getIsHorizontal)(yAxis.axisAlignment))
                        errors.push("Both x and y axes can't have horizontal alignment");
                }
            });
        }
        return errors;
    };
    /**
     * Returns wasm Id
     */
    SciChartSurface.prototype.getWasmId = function () {
        return this.webAssemblyContext2D.canvas.id;
    };
    SciChartSurface.prototype.applyOptions = function (options) {
        _super.prototype.applyOptions.call(this, options);
        if (options === null || options === void 0 ? void 0 : options.layoutManager) {
            if (!("layoutChart" in options.layoutManager)) {
                options.layoutManager = (0, classFactory_1.createType)(BaseType_1.EBaseType.LayoutManager, options.layoutManager.type, null, options.layoutManager.options);
            }
            this.layoutManager = options.layoutManager;
        }
        if (options === null || options === void 0 ? void 0 : options.padding) {
            this.padding = options.padding;
        }
        if (options === null || options === void 0 ? void 0 : options.viewportBorder) {
            this.viewportBorder = options.viewportBorder;
        }
        if (options === null || options === void 0 ? void 0 : options.canvasBorder) {
            this.canvasBorder = options.canvasBorder;
        }
        if ((options === null || options === void 0 ? void 0 : options.loader) && "toJSON" in options.loader) {
            // @ts-ignore
            this.loaderJson = options.loader.toJSON();
        }
        else if ((options === null || options === void 0 ? void 0 : options.loader) === false) {
            // loader should be disabled
            this.loaderJson = false;
        }
        if (options === null || options === void 0 ? void 0 : options.drawSeriesBehindAxis) {
            this.drawSeriesBehindAxisProperty = options.drawSeriesBehindAxis;
        }
        if (options === null || options === void 0 ? void 0 : options.autoColorMode) {
            this.autoColorMode = options.autoColorMode;
        }
        if (options === null || options === void 0 ? void 0 : options.title) {
            this.title = options.title;
        }
        if (options === null || options === void 0 ? void 0 : options.titleStyle) {
            this.titleStyle = options.titleStyle;
        }
        if (options === null || options === void 0 ? void 0 : options.background) {
            this.background = options.background;
        }
        if (options === null || options === void 0 ? void 0 : options.touchAction) {
            this.touchActionProperty = options.touchAction;
        }
    };
    SciChartSurface.prototype.resolveSurfaceOrders = function () {
        var _a;
        if (this.isSubSurface) {
            throw new Error("resolveSurfaceOrders should only be called on a parent surface");
        }
        var surfaces = __spreadArray([this], this.subCharts.filter(function (s) { return s.isVisible; }), true);
        var orderedSurfaces = [];
        for (var _i = 0, surfaces_1 = surfaces; _i < surfaces_1.length; _i++) {
            var surface = surfaces_1[_i];
            surface.resolvedSurfaceRenderOrder = undefined;
            var resolvedOrder = (_a = surface.getSurfaceRenderOrder()) !== null && _a !== void 0 ? _a : orderedSurfaces.length;
            surface.resolvedSurfaceRenderOrder = resolvedOrder;
            orderedSurfaces.push(surface);
        }
        orderedSurfaces.sort(function (a, b) { return a.getSurfaceRenderOrder() - b.getSurfaceRenderOrder(); });
        return orderedSurfaces;
    };
    /**
     * @inheritDoc
     */
    SciChartSurface.prototype.detachChartModifier = function (chartModifier) {
        _super.prototype.detachChartModifier.call(this, chartModifier);
        this.subCharts.forEach(function (subChart) {
            chartModifier.onDetachSubSurface(subChart);
        });
    };
    /**
     * @inheritDoc
     */
    SciChartSurface.prototype.attachChartModifier = function (chartModifier) {
        _super.prototype.attachChartModifier.call(this, chartModifier);
        if (chartModifier.modifierType !== ModifierType_1.EModifierType.MultiChart2DModifier) {
            chartModifier.setParentSurface(this);
            chartModifier.invalidateParentCallback = this.invalidateElement;
            chartModifier.onAttach();
            this.subCharts.forEach(function (subChart) {
                chartModifier.onAttachSubSurface(subChart);
            });
            this.invalidateElement();
        }
    };
    /**
     * @inheritDoc
     */
    SciChartSurface.prototype.applySciChartBackground = function (background, renderContext) {
        var nativeContext = renderContext.getNativeContext();
        if (this.domChartRoot) {
            this.domChartRoot.style.background = background;
        }
        if (nativeContext) {
            nativeContext.SetClearColor(0, 0, 0, 0);
            nativeContext.Clear();
        }
    };
    /**
     * @inheritDoc
     */
    SciChartSurface.prototype.setClearAlphaParams = function (enabled, alpha) {
        this.webAssemblyContext2D.SCRTSetClearAlphaParams(enabled, alpha);
    };
    SciChartSurface.prototype.zoomExtentsYInternal = function (xRanges, animationDurationMs, easingFunction, axisSelectorFn, onCompleted) {
        if (animationDurationMs === void 0) { animationDurationMs = 0; }
        if (easingFunction === void 0) { easingFunction = EasingFunctions_1.easing.outExpo; }
        if (axisSelectorFn === void 0) { axisSelectorFn = function () { return true; }; }
        if (onCompleted === void 0) { onCompleted = function () { }; }
        this.yAxes.asArray().forEach(function (yAxis) {
            if (axisSelectorFn(yAxis)) {
                var yRange = yAxis.getWindowedYRange(xRanges);
                if (yRange) {
                    yAxis.animateVisibleRange(yRange, animationDurationMs, easingFunction, onCompleted);
                }
            }
        });
    };
    SciChartSurface.prototype.zoomExtentsXInternal = function (animationDurationMs, easingFunction, axisSelectorFn, onCompleted) {
        if (animationDurationMs === void 0) { animationDurationMs = 0; }
        if (easingFunction === void 0) { easingFunction = EasingFunctions_1.easing.outExpo; }
        if (axisSelectorFn === void 0) { axisSelectorFn = function () { return true; }; }
        if (onCompleted === void 0) { onCompleted = function () { }; }
        var xRanges = new Dictionary_1.Dictionary();
        this.xAxes.asArray().forEach(function (xAxis) {
            if (axisSelectorFn(xAxis)) {
                var maxXRange = xAxis.getMaximumRange();
                xAxis.animateVisibleRange(maxXRange, animationDurationMs, easingFunction, onCompleted);
                xRanges.add(xAxis.id, maxXRange);
            }
        });
        return xRanges;
    };
    // Step_4: Start drawing
    SciChartSurface.prototype.onRenderSurfaceDraw = function () {
        var _this = this;
        var _a, _b;
        var renderSurfaceDrawStartMark = performance_1.PerformanceDebugHelper.mark(performance_1.EPerformanceMarkType.RenderSurfaceDrawStart, {
            contextId: this.id
        });
        var unlock = this.suspender.lock();
        try {
            this.preRenderAll.raiseEvent();
        }
        finally {
            unlock();
        }
        if (this.subChartsProperty.length > 0) {
            var batchContext_1 = new BatchRenderContext_1.BatchRenderContext(this.webAssemblyContext2D, this.renderSurface.viewportSize, (_a = this.domCanvas2D) === null || _a === void 0 ? void 0 : _a.id);
            // this returns only visible surfaces, in render order
            var orderedSurfaces_1 = this.resolveSurfaceOrders();
            orderedSurfaces_1.forEach(function (chart, index) {
                if (index === orderedSurfaces_1.length - 1) {
                    // If this is the last surface, draw
                    batchContext_1.doDraw = true;
                }
                chart.doDrawingLoop(batchContext_1);
            });
        }
        else {
            this.doDrawingLoop();
        }
        this.renderedToWebGl.raiseEvent(this.sciChartRenderer.isInvalidated);
        if (!this.isCopyCanvasSurface) {
            this.renderedToDestination.raiseEvent(this.sciChartRenderer.isInvalidated);
        }
        // @ts-ignore access to private field
        if (this.painted.handlers.length > 0 || performance_1.PerformanceDebugHelper.enableDebug) {
            (0, performance_1.runAfterFramePaint)(function () {
                var _a;
                performance_1.PerformanceDebugHelper.mark(performance_1.EPerformanceMarkType.Painted, { contextId: _this.id });
                _this.painted.raiseEvent((_a = _this.sciChartRenderer) === null || _a === void 0 ? void 0 : _a.isInvalidated);
            });
        }
        this.currentWebGlRenderContextProperty = (0, Deleter_1.deleteSafe)(this.currentWebGlRenderContext);
        // TODO decide whether this is the best place to prune
        LabelCache_1.labelCache.pruneCache();
        performance_1.PerformanceDebugHelper.mark(performance_1.EPerformanceMarkType.RenderSurfaceDrawEnd, {
            contextId: this.id,
            relatedId: (_b = renderSurfaceDrawStartMark === null || renderSurfaceDrawStartMark === void 0 ? void 0 : renderSurfaceDrawStartMark.detail) === null || _b === void 0 ? void 0 : _b.relatedId
        });
    };
    SciChartSurface.prototype.detachSeries = function (renderableSeries) {
        if (renderableSeries.type === SeriesType_1.ESeriesType.StackedColumnSeries ||
            renderableSeries.type === SeriesType_1.ESeriesType.StackedMountainSeries) {
            return;
        }
        this.chartModifiers.asArray().forEach(function (cm) {
            cm.onDetachSeries(renderableSeries);
        });
        renderableSeries.onDetach();
        if (this.autoColorMode === AutoColorMode_1.EAutoColorMode.OnAddRemoveSeries) {
            this.autoColorRequired = true;
        }
        this.invalidateElement();
    };
    SciChartSurface.prototype.attachSeries = function (renderableSeries) {
        // If the user tries to add a stacked series, add it to a stacked collection, creating if necessary.
        if (renderableSeries.type === SeriesType_1.ESeriesType.StackedColumnSeries) {
            var col = this.renderableSeries
                .asArray()
                .find(function (rs) { return rs.type === SeriesType_1.ESeriesType.StackedColumnCollection; });
            if (!col) {
                col = new StackedColumnCollection_1.StackedColumnCollection(this.webAssemblyContext2D);
                //  Insert collection at old index to preserve z order
                var index = this.renderableSeries.asArray().findIndex(function (s) { return s === renderableSeries; });
                this.renderableSeries.insert(index, col);
            }
            col.add(renderableSeries);
            this.renderableSeries.remove(renderableSeries, false);
            return;
        }
        else if (renderableSeries.type === SeriesType_1.ESeriesType.StackedMountainSeries ||
            renderableSeries.type === SeriesType_1.ESeriesType.SmoothStackedMountainSeries) {
            var col = this.renderableSeries
                .asArray()
                .find(function (rs) { return rs.type === SeriesType_1.ESeriesType.StackedMountainCollection; });
            if (!col) {
                col = new StackedMountainCollection_1.StackedMountainCollection(this.webAssemblyContext2D);
                var index = this.renderableSeries.asArray().findIndex(function (s) { return s === renderableSeries; });
                this.renderableSeries.insert(index, col);
            }
            col.add(renderableSeries);
            this.renderableSeries.remove(renderableSeries, false);
        }
        if (!renderableSeries.isStacked || renderableSeries.isCollection) {
            renderableSeries.onAttach(this);
        }
        if (this.themeProviderProperty) {
            renderableSeries.applyTheme(this.themeProviderProperty);
        }
        this.chartModifiers.asArray().forEach(function (cm) {
            cm.onAttachSeries(renderableSeries);
        });
        if (this.autoColorMode === AutoColorMode_1.EAutoColorMode.OnAddRemoveSeries) {
            this.autoColorRequired = true;
        }
        this.invalidateElement();
    };
    SciChartSurface.prototype.detachAxis = function (axis) {
        axis.onDetach();
        this.invalidateElement();
    };
    SciChartSurface.prototype.checkAxisIdUniqueness = function (id, isXAxis) {
        if (isXAxis && !this.xAxes.checkIdUniqueness(id)) {
            console.error("The X axis Id ".concat(id, " is not unique"));
        }
        if (!isXAxis && !this.yAxes.checkIdUniqueness(id)) {
            console.error("The Y axis Id ".concat(id, " is not unique"));
        }
    };
    SciChartSurface.prototype.attachAxis = function (axis, isXAxis) {
        if (axis.invalidateParentCallback) {
            throw new Error("Invalid operation in sciChartSurface.attachAxis, this axis has already been attached to a SciChartSurface. Please detach it from a SciChartSurface before attaching to another");
        }
        this.checkAxisIdUniqueness(axis.id, isXAxis);
        var isPrimaryAxis = false;
        if (isXAxis && !this.xAxes.asArray().some(function (a) { return a.isPrimaryAxis; })) {
            isPrimaryAxis = true;
        }
        if (!isXAxis && !this.yAxes.asArray().some(function (a) { return a.isPrimaryAxis; })) {
            isPrimaryAxis = true;
        }
        axis.onAttach(this, isXAxis, isPrimaryAxis);
        if (this.themeProviderProperty) {
            axis.applyTheme(this.themeProviderProperty);
        }
        axis.invalidateParentCallback = this.invalidateElement;
        this.invalidateElement();
    };
    SciChartSurface.prototype.onAttachSubSurface = function (subSurface) {
        this.chartModifiers.asArray().forEach(function (modifier) {
            modifier.onAttachSubSurface(subSurface);
        });
    };
    SciChartSurface.prototype.onDetachSubSurface = function (subSurface) {
        this.chartModifiers.asArray().forEach(function (modifier) {
            modifier.onDetachSubSurface(subSurface);
        });
    };
    Object.defineProperty(SciChartSurface.prototype, "drawSeriesBehindAxis", {
        /**
         * Gets or sets the boolean flag for switching behaviour of Axises rendering
         */
        get: function () {
            return this.drawSeriesBehindAxisProperty;
        },
        /**
         * Gets or sets the boolean flag for switching behaviour of Axises rendering
         */
        set: function (value) {
            this.drawSeriesBehindAxisProperty = value;
            this.invalidateElement();
        },
        enumerable: false,
        configurable: true
    });
    return SciChartSurface;
}(SciChartSurfaceBase_1.SciChartSurfaceBase));
exports.SciChartSurface = SciChartSurface;
