"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 __());
    };
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.StackedColumnCollection = void 0;
var Deleter_1 = require("../../../Core/Deleter");
var NumberRange_1 = require("../../../Core/NumberRange");
var SeriesType_1 = require("../../../types/SeriesType");
var BaseDataSeries_1 = require("../../Model/BaseDataSeries");
var SearchMode_1 = require("../../../types/SearchMode");
var RenderPassData_1 = require("../../Services/RenderPassData");
var BaseRenderableSeries_1 = require("./BaseRenderableSeries");
var BaseStackedCollection_1 = require("./BaseStackedCollection");
var constants_1 = require("./constants");
var XyPointSeriesWrapped_1 = require("../../Model/PointSeries/XyPointSeriesWrapped");
var StackedCollectionDataLabelProvider_1 = require("./DataLabels/StackedCollectionDataLabelProvider");
var DataPointWidthMode_1 = require("../../../types/DataPointWidthMode");
var performance_1 = require("../../../utils/performance");
var vectorToArray_1 = require("../../../utils/vectorToArray");
var XyyPointSeriesWrapped_1 = require("../../Model/PointSeries/XyyPointSeriesWrapped");
var StackedColumnSeriesDrawingProvider_1 = require("./DrawingProviders/StackedColumnSeriesDrawingProvider");
/**
 * @summary A {@link StackedColumnCollection} allows grouping multiple {@link StackedColumnRenderableSeries}
 * to create a JavaScript Stacked Column, 100 Stacked Column or Stacked Bar chart
 * @description
 * Multiple {@link StackedColumnRenderableSeries} are required to create a stacked column chart type in SciChart.
 * These are grouped with a {@link StackedColumnCollection}, which implements {@link IRenderableSeries} and may be added
 * directly to a {@link SciChartSurface.renderableSeries} collection.
 *
 * Code sample below for stacking above and below (vertical stacking)
 * ```ts
 * const stackedColumn0 = new StackedColumnRenderableSeries(wasmContext);
 * stackedColumn0.stackedGroupId = "group one"; // Same group ID means stack vertically
 * const stackedColumn1 = new StackedColumnRenderableSeries(wasmContext);
 * stackedColumn1.stackedGroupId = "group one"; // Same group ID means stack vertically
 * const stackedColumn2 = new StackedColumnRenderableSeries(wasmContext);
 * stackedColumn2.stackedGroupId = "group one"; // Same group ID means stack vertically
 * const stackedColumnCollection = new StackedColumnCollection(wasmContext);
 * stackedColumnCollection.add(stackedColumn0, stackedColumn1, stackedColumn2);
 *
 * sciChartSurface.renderableSeries.add(stackedColumnCollection);
 * ````
 *
 *  Code sample below for stacking side by side (horizontal stacking)
 * ```ts
 * const stackedColumn0 = new StackedColumnRenderableSeries(wasmContext);
 * stackedColumn0.stackedGroupId = "group one"; // Different group ID means stack horizontally
 * const stackedColumn1 = new StackedColumnRenderableSeries(wasmContext);
 * stackedColumn1.stackedGroupId = "group two"; // Different group ID means stack horizontally
 * const stackedColumn2 = new StackedColumnRenderableSeries(wasmContext);
 * stackedColumn2.stackedGroupId = "group three"; // Different group ID means stack horizontally
 * const stackedColumnCollection = new StackedColumnCollection(wasmContext);
 * stackedColumnCollection.add(stackedColumn0, stackedColumn1, stackedColumn2);
 *
 * sciChartSurface.renderableSeries.add(stackedColumnCollection);
 * ````
 * @remarks This type implements {@link IRenderableSeries} but it is not a renderable series, instead it wraps multiple
 * {@link StackedColumnRenderableSeries} to create a stacked column chart
 *
 * ---
 * 📚 Docs: {@link https://www.scichart.com/documentation/js/v4/2d-charts/chart-types/stacked-column-renderable-series/}
 */
var StackedColumnCollection = /** @class */ (function (_super) {
    __extends(StackedColumnCollection, _super);
    /**
     * Creates an instance of the {@link StackedColumnCollection}
     * @param webAssemblyContext The {@link TSciChart | SciChart WebAssembly Context} containing
     * native methods and access to our WebGL2 WebAssembly Drawing Engine
     * @param options Optional parameters of type {@link IStackedColumnCollectionOptions} to configure the series
     *
     * ---
     * 📚 Docs: {@link https://www.scichart.com/documentation/js/v4/2d-charts/chart-types/stacked-column-renderable-series/}
     */
    function StackedColumnCollection(webAssemblyContext, options) {
        var _this = this;
        var _a, _b, _c, _d, _e, _f;
        _this = _super.call(this, webAssemblyContext, options) || this;
        _this.type = SeriesType_1.ESeriesType.StackedColumnCollection;
        _this.seriesGroups = {};
        _this.dataPointWidthProperty = 0.5;
        _this.dataPointWidthModeProperty = DataPointWidthMode_1.EDataPointWidthMode.Relative;
        _this.zeroLineYProperty = 0;
        _this.separatePositiveNegativeStacksProperty = true;
        _this.dataPointWidthProperty = (_a = options === null || options === void 0 ? void 0 : options.dataPointWidth) !== null && _a !== void 0 ? _a : _this.dataPointWidthProperty;
        _this.dataPointWidthMode = (_b = options === null || options === void 0 ? void 0 : options.dataPointWidthMode) !== null && _b !== void 0 ? _b : _this.dataPointWidthModeProperty;
        _this.zeroLineYProperty = (_c = options === null || options === void 0 ? void 0 : options.zeroLineY) !== null && _c !== void 0 ? _c : _this.zeroLineYProperty;
        _this.spacingProperty = (_e = (_d = options === null || options === void 0 ? void 0 : options.spacing) !== null && _d !== void 0 ? _d : _this.spacingProperty) !== null && _e !== void 0 ? _e : 0;
        _this.separatePositiveNegativeStacksProperty = (_f = options === null || options === void 0 ? void 0 : options.separatePositiveNegativeStacks) !== null && _f !== void 0 ? _f : _this.separatePositiveNegativeStacksProperty;
        _this.getColumnWidth = _this.getColumnWidth.bind(_this);
        _this.detachChildSeries = _this.detachChildSeries.bind(_this);
        _this.attachChildSeries = _this.attachChildSeries.bind(_this);
        _this.collectionChanged.subscribe(function (arg) {
            var _a, _b;
            (_a = arg.getOldItems()) === null || _a === void 0 ? void 0 : _a.forEach(_this.detachChildSeries);
            (_b = arg.getNewItems()) === null || _b === void 0 ? void 0 : _b.forEach(_this.attachChildSeries);
        });
        // @ts-ignore
        _this.dataLabelProvider = new StackedCollectionDataLabelProvider_1.StackedCollectionDataLabelProvider();
        _this.dataLabelProviderProperty.onAttach(_this.webAssemblyContext, _this);
        return _this;
    }
    /** @inheritDoc */
    StackedColumnCollection.prototype.delete = function () {
        this.nativeDrawingProvider = (0, Deleter_1.deleteSafe)(this.nativeDrawingProvider);
        _super.prototype.delete.call(this);
    };
    /** @inheritDoc */
    StackedColumnCollection.prototype.updateAccumulatedVectors = function () {
        var _this = this;
        var dataValuesCount = this.getDataSeriesValuesCount();
        if (!this.isAccumulatedVectorDirty || !dataValuesCount) {
            return;
        }
        this.checkXValuesCorrect();
        this.isAccumulatedVectorDirty = false;
        this.clearAccumulatedVectors(dataValuesCount);
        // GROUP SERIES BY STACKED_GROUP_ID
        this.updateGroups();
        var seriesGroups = this.seriesGroups;
        var seriesGroupsCount = this.getGroupsCount();
        var seriesYViews = new Map();
        Object.keys(seriesGroups).forEach(function (key, groupIndex) {
            var seriesList = seriesGroups[key];
            seriesList.forEach(function (rs) {
                rs.setGroupsCount(seriesGroupsCount);
                rs.setGroupIndex(groupIndex);
            });
            seriesYViews.set(key, seriesList.map(function (rs) { return (0, vectorToArray_1.vectorToArrayViewF64)(rs.dataSeries.getNativeYValues(), _this.webAssemblyContext); }));
        });
        var _loop_1 = function (i) {
            this_1.accumulatedValues0.push_back(this_1.zeroLineY);
            Object.keys(seriesGroups).forEach(function (key) {
                var seriesList = seriesGroups[key];
                var yViews = seriesYViews.get(key);
                if (_this.separatePositiveNegativeStacksProperty) {
                    // Compute separate positive/negative totals for 100% normalization.
                    var positiveTotal_1 = 0;
                    var negativeTotal_1 = 0;
                    if (_this.isOneHundredPercent) {
                        yViews.forEach(function (yView) {
                            var y = yView[i];
                            if (y >= 0)
                                positiveTotal_1 += y;
                            else
                                negativeTotal_1 += y;
                        });
                    }
                    // Positive values stack upward from zeroLineY; negative values stack downward independently.
                    var positiveAccum_1 = _this.zeroLineY;
                    var negativeAccum_1 = _this.zeroLineY;
                    seriesList.forEach(function (rs, seriesIndex) {
                        var currentY = yViews[seriesIndex][i];
                        if (_this.isOneHundredPercent) {
                            currentY = currentY >= 0
                                ? (positiveTotal_1 !== 0 ? (currentY / positiveTotal_1) * 100 : 0)
                                : (negativeTotal_1 !== 0 ? (currentY / Math.abs(negativeTotal_1)) * 100 : 0);
                        }
                        if (currentY >= 0) {
                            rs.bottomAccumulatedValues.push_back(positiveAccum_1);
                            var top_1 = positiveAccum_1 + currentY;
                            rs.accumulatedValues.push_back(top_1);
                            positiveAccum_1 = top_1;
                        }
                        else {
                            var bottom = negativeAccum_1 + currentY;
                            rs.bottomAccumulatedValues.push_back(bottom);
                            rs.accumulatedValues.push_back(negativeAccum_1);
                            negativeAccum_1 = bottom;
                        }
                    });
                }
                else {
                    var sum_1;
                    if (_this.isOneHundredPercent) {
                        sum_1 = yViews.reduce(function (prev, yView) { return prev + yView[i]; }, 0);
                    }
                    var previous_1 = 0;
                    seriesList.forEach(function (rs, seriesIndex) {
                        var currentY = yViews[seriesIndex][i];
                        if (_this.isOneHundredPercent) {
                            currentY = (currentY * 100) / sum_1;
                        }
                        var current = previous_1 + currentY;
                        rs.accumulatedValues.push_back(current);
                        previous_1 = current;
                    });
                }
            });
        };
        var this_1 = this;
        for (var i = 0; i < dataValuesCount; i++) {
            _loop_1(i);
        }
    };
    /** @inheritDoc */
    StackedColumnCollection.prototype.draw = function (renderContext, renderPassData) {
        var _this = this;
        var _a, _b, _c, _d, _e, _f;
        if (this.canDraw) {
            this.updateHitTestProviders(renderPassData);
            if (!this.isEnoughDataToDraw()) {
                return;
            }
            var mark = performance_1.PerformanceDebugHelper.mark(performance_1.EPerformanceMarkType.DrawCollectionSeriesStart, {
                contextId: this.id,
                parentContextId: (_a = this.parentSurface) === null || _a === void 0 ? void 0 : _a.id,
                level: performance_1.EPerformanceDebugLevel.Verbose
            });
            var mark1 = performance_1.PerformanceDebugHelper.mark(performance_1.EPerformanceMarkType.AccumulatedVectorStart, {
                contextId: this.id,
                parentContextId: (_b = this.parentSurface) === null || _b === void 0 ? void 0 : _b.id,
                level: performance_1.EPerformanceDebugLevel.Verbose
            });
            this.updateAccumulatedVectors();
            performance_1.PerformanceDebugHelper.mark(performance_1.EPerformanceMarkType.AccumulatedVectorEnd, {
                contextId: this.id,
                parentContextId: (_c = this.parentSurface) === null || _c === void 0 ? void 0 : _c.id,
                relatedId: (_d = mark1 === null || mark1 === void 0 ? void 0 : mark1.detail) === null || _d === void 0 ? void 0 : _d.relatedId,
                level: performance_1.EPerformanceDebugLevel.Verbose
            });
            var firstDataSeries = this.getFirstSeries().dataSeries;
            if (firstDataSeries === null || firstDataSeries === void 0 ? void 0 : firstDataSeries.fifoCapacity) {
                throw new Error("Sorry, fifo is not currently supported for stacked series");
            }
            var seriesGroups_1 = this.seriesGroups;
            var stackedColumnsCount_1 = this.getGroupsCount();
            var columnWidth_1 = this.getColumnWidth(renderPassData.xCoordinateCalculator);
            Object.keys(seriesGroups_1).forEach(function (key, groupIndex) {
                var seriesArray = seriesGroups_1[key];
                var previousEl;
                seriesArray.forEach(function (el, seriesIndex) {
                    var _a;
                    var bottomVector = _this.separatePositiveNegativeStacksProperty
                        ? el.bottomAccumulatedValues
                        : seriesIndex === 0 ? _this.accumulatedValues0 : previousEl.accumulatedValues;
                    var topVector = el.accumulatedValues;
                    var ps = new XyyPointSeriesWrapped_1.XyyPointSeriesWrapped(el.dataSeries, el.accumulatedValues, bottomVector);
                    // pass topVector to dataLabelProvider for use as y position values
                    // Use the helper method to set data label provider properties
                    _this.setDataLabelProviderProperties(el.dataLabelProvider, topVector, groupIndex, stackedColumnsCount_1, columnWidth_1, _this.spacingProperty, _this.isOneHundredPercent);
                    el.dataLabelProvider.generateDataLabels(renderContext, new RenderPassData_1.RenderPassData((_a = el.dataSeries) === null || _a === void 0 ? void 0 : _a.getIndicesRange(_this.xAxis.visibleRange, _this.xAxis.isCategoryAxis), _this.xAxis.getCurrentCoordinateCalculator, _this.yAxis.getCurrentCoordinateCalculator, _this.xAxis.isVerticalChart, new XyPointSeriesWrapped_1.XyPointSeriesWrapped(el.dataSeries)));
                    var rpd = new StackedColumnSeriesDrawingProvider_1.StackedColumnRenderPassData(renderPassData.indexRange, renderPassData.getxCoordinateCalculator, renderPassData.getyCoordinateCalculator, renderPassData.isVerticalChart, columnWidth_1, stackedColumnsCount_1, groupIndex, _this.spacingProperty, ps, renderPassData.resamplingHash);
                    el.draw(renderContext, rpd);
                    // drawColumns(
                    //     this.webAssemblyContext,
                    //     renderContext,
                    //     xCoordinateCalculator,
                    //     yCoordinateCalculator,
                    //     isVerticalChart,
                    //     this.nativeDrawingProvider,
                    //     xValues,
                    //     bottomVector,
                    //     topVector,
                    //     el.getFillBrush(),
                    //     el.getStrokePen(),
                    //     viewRect,
                    //     columnWidth,
                    //     this.spacingProperty,
                    //     stackedColumnsCount,
                    //     groupIndex
                    // );
                    previousEl = el;
                });
            });
            performance_1.PerformanceDebugHelper.mark(performance_1.EPerformanceMarkType.DrawCollectionSeriesEnd, {
                contextId: this.id,
                parentContextId: (_e = this.parentSurface) === null || _e === void 0 ? void 0 : _e.id,
                relatedId: (_f = mark === null || mark === void 0 ? void 0 : mark.detail) === null || _f === void 0 ? void 0 : _f.relatedId,
                level: performance_1.EPerformanceDebugLevel.Verbose
            });
        }
    };
    /** @inheritDoc */
    StackedColumnCollection.prototype.getXRange = function () {
        if (!this.isEnoughDataToDraw()) {
            return new NumberRange_1.NumberRange();
        }
        var range = this.getFirstSeries().dataSeries.xRange;
        var count = this.getFirstSeries().dataSeries.count();
        // Range
        var additionalValue = this.dataPointWidth / 2;
        if (this.dataPointWidthMode === DataPointWidthMode_1.EDataPointWidthMode.Relative) {
            if (count > 1) {
                additionalValue = ((range.diff / (count - 1)) * this.dataPointWidth) / 2;
            }
            else {
                additionalValue = 0;
            }
        }
        if (this.dataPointWidthMode === DataPointWidthMode_1.EDataPointWidthMode.Absolute) {
            var cc = this.xAxis.getCurrentCoordinateCalculator();
            additionalValue = cc.getDataWidth(this.dataPointWidth) / 2;
        }
        return new NumberRange_1.NumberRange(range.min - additionalValue, range.max + additionalValue);
    };
    /** @inheritDoc */
    StackedColumnCollection.prototype.getYRange = function (xVisibleRange, isXCategoryAxis) {
        var _this = this;
        var yRange = _super.prototype.getYRange.call(this, xVisibleRange, isXCategoryAxis);
        if (this.separatePositiveNegativeStacksProperty) {
            // accumulatedValues only contains the tops; union with bottom accumulated values
            // so that negatively-stacked columns are included in the visible range.
            this.getVisibleSeries().forEach(function (rs) {
                var _a;
                var bottomSize = rs.bottomAccumulatedValues.size();
                if (bottomSize > 0 && bottomSize === ((_a = _this.getNativeXValues()) === null || _a === void 0 ? void 0 : _a.size())) {
                    var bottomRange = (0, BaseDataSeries_1.getWindowedYRange)(_this.webAssemblyContext, _this.getNativeXValues(), rs.bottomAccumulatedValues, xVisibleRange, true, isXCategoryAxis, rs.dataSeries.dataDistributionCalculator.isSortedAscending, true, SearchMode_1.ESearchMode.RoundUp, SearchMode_1.ESearchMode.RoundDown);
                    if (bottomRange) {
                        yRange = yRange.union(bottomRange);
                    }
                }
            });
        }
        return new NumberRange_1.NumberRange(Math.min(yRange.min, this.zeroLineY), Math.max(yRange.max, this.zeroLineY));
    };
    /** @inheritDoc */
    StackedColumnCollection.prototype.onAttach = function (scs) {
        _super.prototype.onAttach.call(this, scs);
        this.nativeDrawingProvider = new this.webAssemblyContext.SCRTStackedColumnSeriesDrawingProvider();
    };
    /** @inheritDoc */
    StackedColumnCollection.prototype.notifyPropertyChanged = function (propertyName) {
        _super.prototype.notifyPropertyChanged.call(this, propertyName);
        if (propertyName === constants_1.PROPERTY.DATA_SERIES ||
            propertyName === constants_1.PROPERTY.IS_VISIBLE ||
            propertyName === constants_1.PROPERTY.IS_ONE_HUNDRED_PERCENT ||
            propertyName === constants_1.PROPERTY.STACKED_GROUP_ID ||
            propertyName === constants_1.PROPERTY.SEPARATE_POSITIVE_NEGATIVE_STACKS) {
            this.isAccumulatedVectorDirty = true;
        }
    };
    /** @inheritDoc */
    StackedColumnCollection.prototype.hasDataSeriesValues = function () {
        return this.isEnoughDataToDraw();
    };
    /**
     * Called internally - gets the column width in pixels
     * @param xCoordinateCalculator The current XAxis {@link CoordinateCalculatorBase}
     */
    StackedColumnCollection.prototype.getColumnWidth = function (xCoordinateCalculator) {
        var widthFraction = this.dataPointWidth;
        var widthMode = this.dataPointWidthMode;
        var firstDataSeries = this.getFirstSeries().dataSeries;
        var isCategoryAxis = xCoordinateCalculator.isCategoryCoordinateCalculator;
        var xValues = isCategoryAxis ? firstDataSeries.getNativeIndexes() : firstDataSeries.getNativeXValues();
        var viewRect = this.parentSurface.seriesViewRect;
        var stackedColumnsCount = this.getGroupsCount();
        if (widthMode === DataPointWidthMode_1.EDataPointWidthMode.Range) {
            var range = xCoordinateCalculator.visibleMax - xCoordinateCalculator.visibleMin;
            // This treats dataPointWidth as "xRange per column"
            return ((xCoordinateCalculator.viewportDimension / range) * widthFraction) / stackedColumnsCount;
        }
        else if (widthMode === DataPointWidthMode_1.EDataPointWidthMode.Absolute) {
            return widthFraction / stackedColumnsCount;
        }
        else {
            return ((0, BaseRenderableSeries_1.getDataPointWidth)(xValues, xCoordinateCalculator, viewRect.width, widthFraction, isCategoryAxis, firstDataSeries.dataDistributionCalculator.isSortedAscending, this.webAssemblyContext) / stackedColumnsCount);
        }
    };
    /** @inheritDoc */
    StackedColumnCollection.prototype.toJSON = function (excludeData) {
        if (excludeData === void 0) { excludeData = false; }
        var json = _super.prototype.toJSON.call(this, excludeData);
        var options = {
            dataPointWidth: this.dataPointWidth,
            dataPointWidthMode: this.dataPointWidthMode,
            zeroLineY: this.zeroLineY,
            spacing: this.spacingProperty,
            separatePositiveNegativeStacks: this.separatePositiveNegativeStacksProperty
            // dataLabels: this.dataLabelProvider
        };
        Object.assign(json.options, options);
        return json;
    };
    Object.defineProperty(StackedColumnCollection.prototype, "dataPointWidth", {
        // PROPERTIES
        /**
         * Gets or sets the Datapoint width, as a fraction of available space from 0.0 - 1.0
         */
        get: function () {
            return this.dataPointWidthProperty;
        },
        /**
         * Gets or sets the Datapoint width, as a fraction of available space from 0.0 - 1.0
         */
        set: function (dataPointWidth) {
            this.dataPointWidthProperty = dataPointWidth;
            this.notifyPropertyChanged(constants_1.PROPERTY.DATA_POINT_WIDTH);
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(StackedColumnCollection.prototype, "dataPointWidthMode", {
        /**
         * Gets or sets the mode which determines how dataPointWidth is interpreted. Available values are {@link EDataPointWidthMode}.  Default Relative.
         */
        get: function () {
            return this.dataPointWidthModeProperty;
        },
        /**
         * Gets or sets the mode which determines how dataPointWidth is interpreted. Available values are {@link EDataPointWidthMode}.  Default Relative.
         */
        set: function (value) {
            this.dataPointWidthModeProperty = value;
            this.notifyPropertyChanged(constants_1.PROPERTY.DATA_POINT_WIDTH_MODE);
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(StackedColumnCollection.prototype, "zeroLineY", {
        /**
         * Gets or sets the Zero-line Y, the Y-value where the mountain crosses zero and inverts. Default is 0
         */
        get: function () {
            return this.zeroLineYProperty;
        },
        /**
         * Gets or sets the Zero-line Y, the Y-value where the mountain crosses zero and inverts. Default is 0
         */
        set: function (zeroLineY) {
            this.zeroLineYProperty = zeroLineY;
            this.notifyPropertyChanged(constants_1.PROPERTY.ZERO_LINE_Y);
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(StackedColumnCollection.prototype, "spacing", {
        /**
         * Gets the spacing between columns in pixels
         */
        get: function () {
            return this.spacingProperty;
        },
        /**
         * Sets the spacing between columns in pixels
         */
        set: function (spacing) {
            this.spacingProperty = spacing;
            this.notifyPropertyChanged(constants_1.PROPERTY.SPACING);
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(StackedColumnCollection.prototype, "separatePositiveNegativeStacks", {
        /**
         * When true (default), positive values stack upward from the zero line and negative values stack downward independently.
         * When false, all values accumulate continuously from the previous series top, preserving legacy behaviour.
         */
        get: function () {
            return this.separatePositiveNegativeStacksProperty;
        },
        /**
         * When true (default), positive values stack upward from the zero line and negative values stack downward independently.
         * When false, all values accumulate continuously from the previous series top, preserving legacy behaviour.
         */
        set: function (value) {
            this.separatePositiveNegativeStacksProperty = value;
            this.notifyPropertyChanged(constants_1.PROPERTY.SEPARATE_POSITIVE_NEGATIVE_STACKS);
        },
        enumerable: false,
        configurable: true
    });
    // PROTECTED
    // PRIVATE
    StackedColumnCollection.prototype.detachChildSeries = function (series) {
        series.onDetachFromParentCollection();
        this.isAccumulatedVectorDirty = true;
        this.invalidateParent();
    };
    StackedColumnCollection.prototype.attachChildSeries = function (series) {
        series.onAttachToParentCollection(this, this.getParentSurface, this.notifyPropertyChanged, this.getColumnWidth);
        this.isAccumulatedVectorDirty = true;
        this.invalidateParent();
    };
    StackedColumnCollection.prototype.checkXValuesCorrect = function () {
        var length = this.getDataSeriesValuesCount();
        this.getVisibleSeries().forEach(function (el) {
            var _a;
            if (!(((_a = el.dataSeries) === null || _a === void 0 ? void 0 : _a.count()) === length)) {
                throw Error("All stacked series in on collection should have the same amount of X Values");
            }
        });
    };
    StackedColumnCollection.prototype.setDataLabelProviderProperties = function (dataLabelProvider, topVector, groupIndex, groupSize, columnWidth, spacing, isOneHundredPercent) {
        dataLabelProvider.topVector = topVector;
        dataLabelProvider.groupIndex = groupIndex;
        dataLabelProvider.groupSize = groupSize;
        dataLabelProvider.columnWidth = columnWidth;
        dataLabelProvider.spacing = spacing;
        dataLabelProvider.isOneHundredPercent = isOneHundredPercent;
    };
    /**
     * @param numberOfElements - number of element expected is used for performance to reserve memory
     */
    StackedColumnCollection.prototype.clearAccumulatedVectors = function (numberOfElements) {
        this.accumulatedValues0.clear();
        this.accumulatedValues0.reserve(numberOfElements);
        this.asArray().forEach(function (el) {
            el.accumulatedValues.clear();
            el.accumulatedValues.reserve(numberOfElements);
            el.bottomAccumulatedValues.clear();
            el.bottomAccumulatedValues.reserve(numberOfElements);
        });
    };
    StackedColumnCollection.prototype.getLastVisibleSeries = function () {
        var lastItem = this.getVisibleSeries().slice(-1)[0];
        return lastItem;
    };
    /**
     * @description Group series by stackedGroupId
     */
    StackedColumnCollection.prototype.updateGroups = function () {
        var seriesGroups = {};
        this.getVisibleSeries().forEach(function (el) {
            var stackedColumnId = el.stackedGroupId;
            if (!seriesGroups[stackedColumnId]) {
                seriesGroups[stackedColumnId] = [];
            }
            seriesGroups[stackedColumnId].push(el);
        });
        this.seriesGroups = seriesGroups;
    };
    StackedColumnCollection.prototype.getGroupsCount = function () {
        return Object.keys(this.seriesGroups).length;
    };
    return StackedColumnCollection;
}(BaseStackedCollection_1.BaseStackedCollection));
exports.StackedColumnCollection = StackedColumnCollection;
/** @ignore */
var drawColumns = function (wasmContext, renderContext, xCoordinateCalculator, yCoordinateCalculator, isVerticalChart, nativeDrawingProvider, xValues, yValues, y1Values, fillBrush, strokePen, viewRect, columnWidth, spacing, stackedGroupCount, stackedGroupIndex) {
    var args = new wasmContext.SCRTStackedColumnDrawingParams();
    args.count = xValues.size();
    args.columnWidth = columnWidth <= 0 ? 1 : columnWidth;
    args.spacing = spacing;
    args.viewportWidth = viewRect.width;
    args.viewportHeight = viewRect.height;
    args.verticalChart = isVerticalChart;
    // TODO: fix stacked group
    args.stackedGroupCount = stackedGroupCount;
    args.stackedGroupIndex = stackedGroupIndex;
    args.forceShaderMethod = true;
    if (strokePen) {
        args.SetLinesPen(strokePen);
    }
    if (fillBrush) {
        args.SetFillBrush(fillBrush);
    }
    var nativeContext = renderContext.getNativeContext();
    args.SetNativeContext(nativeContext);
    args.SetXValues(xValues);
    args.SetYValues(y1Values);
    args.SetZValues(yValues);
    args.SetXCoordinateCalculator(xCoordinateCalculator.nativeCalculator);
    args.SetYCoordinateCalculator(yCoordinateCalculator.nativeCalculator);
    nativeDrawingProvider.DrawPointsVec(args);
    args.delete();
};
