"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.PolarBandSeriesDrawingProvider = void 0;
var Deleter_1 = require("../../../../../Core/Deleter");
var colorUtil_1 = require("../../../../../utils/colorUtil");
var number_1 = require("../../../../../utils/number");
var parseColor_1 = require("../../../../../utils/parseColor");
var vectorToArray_1 = require("../../../../../utils/vectorToArray");
var ValueName_1 = require("../../../../../types/ValueName");
var BrushCache_1 = require("../../../../Drawing/BrushCache");
var SciChartSurfaceBase_1 = require("../../../SciChartSurfaceBase");
var constants_1 = require("../../constants");
var BaseSeriesDrawingProvider_1 = require("../../DrawingProviders/BaseSeriesDrawingProvider");
var app_1 = require("../../../../../constants/app");
/**
 * Used internally - a drawing provider performs drawing for a {@link FastBandRenderableSeries} using
 * our WebAssembly WebGL rendering engine
 */
var PolarBandSeriesDrawingProvider = /** @class */ (function (_super) {
    __extends(PolarBandSeriesDrawingProvider, _super);
    /**
     * Creates an instance of the {@link BandSeriesDrawingProvider}
     * @param webAssemblyContext The {@link TSciChart | SciChart 2D WebAssembly Context} containing native methods and
     * access to our WebGL2 Engine and WebAssembly numerical methods
     * @param parentSeries the parent {@link BaseBandRenderableSeries} which this drawing provider is attached to
     */
    function PolarBandSeriesDrawingProvider(webAssemblyContext, parentSeries, ySelector, y1Selector) {
        var _this = _super.call(this, webAssemblyContext, parentSeries, ySelector) || this;
        _this.args = new _this.webAssemblyContext.SCRTPolarBandDrawingParams();
        _this.y1Selector = y1Selector !== null && y1Selector !== void 0 ? y1Selector : (function (ps) { return ps.y1Values; });
        _this.fillBrushCache = new BrushCache_1.BrushCache(webAssemblyContext);
        _this.fillBrushY1Cache = new BrushCache_1.BrushCache(webAssemblyContext);
        _this.neutralColorSCRTBrush = app_1.IS_TEST_ENV ? undefined : new webAssemblyContext.SCRTSolidBrush(app_1.NEUTRAL_COLOR, false);
        return _this;
    }
    /**
     * @inheritDoc
     */
    PolarBandSeriesDrawingProvider.prototype.onAttachSeries = function () {
        _super.prototype.onAttachSeries.call(this);
        this.nativeDrawingProvider = new this.webAssemblyContext.SCRTPolarBandSeriesDrawingProvider();
        this.onSeriesPropertyChange(constants_1.PROPERTY.FILL);
        if (this.parentSeries.fillY1 || this.parentSeries.fillLinearGradientY1) {
            this.onSeriesPropertyChange(constants_1.PROPERTY.FILL_Y1);
        }
    };
    /**
     * @inheritDoc
     */
    PolarBandSeriesDrawingProvider.prototype.onDetachSeries = function () {
        _super.prototype.onDetachSeries.call(this);
        this.delete();
    };
    /**
     * @inheritDoc
     */
    PolarBandSeriesDrawingProvider.prototype.delete = function () {
        this.nativeDrawingProvider = (0, Deleter_1.deleteSafe)(this.nativeDrawingProvider);
        this.args = (0, Deleter_1.deleteSafe)(this.args);
        this.fillBrushCache = (0, Deleter_1.deleteSafe)(this.fillBrushCache);
        this.fillBrushY1Cache = (0, Deleter_1.deleteSafe)(this.fillBrushY1Cache);
        this.neutralColorSCRTBrush = (0, Deleter_1.deleteSafe)(this.neutralColorSCRTBrush);
        _super.prototype.delete.call(this);
    };
    /**
     * @inheritDoc
     */
    PolarBandSeriesDrawingProvider.prototype.draw = function (renderContext, renderPassData) {
        var _a, _b;
        var pointSeries = renderPassData.pointSeries;
        var containsNaN = this.parentSeries.dataSeries.dataDistributionCalculator.containsNaN;
        this.args.Reset();
        // this.args.lineGaps = containsNaN
        //     ? this.parentSeries.drawNaNAs === ELineDrawMode.DiscontinuousLine
        //         ? this.webAssemblyContext.SCRTLineGapMode.DrawGaps
        //         : this.webAssemblyContext.SCRTLineGapMode.CloseGaps
        //     : this.webAssemblyContext.SCRTLineGapMode.Default;
        var fillBrush = (0, BrushCache_1.getScrtBrushFromCache)(this.fillBrushCache);
        var fillBrushY1 = (0, BrushCache_1.getScrtBrushFromCache)(this.fillBrushY1Cache);
        var hasFillPaletteProvider = this.parentSeries.hasFillPaletteProvider();
        // For paletted series, we must pass NEUTRAL_COLOR brush
        if (hasFillPaletteProvider) {
            this.args.SetFillBrush(this.neutralColorSCRTBrush);
            this.args.SetFillBrush1(this.neutralColorSCRTBrush);
        }
        else {
            if (fillBrush)
                this.args.SetFillBrush(fillBrush);
            if (fillBrushY1)
                this.args.SetFillBrush1(fillBrushY1);
        }
        var isCategoryAxis = renderPassData.xCoordinateCalculator.isCategoryCoordinateCalculator;
        var xValues = pointSeries.xValues;
        var _c = this.parentSeries.dataSeries, fifoCapacity = _c.fifoCapacity, fifoSweeping = _c.fifoSweeping, fifoSweepingGap = _c.fifoSweepingGap;
        var fifoStartIndex = pointSeries.fifoStartIndex;
        var xDrawValues = isCategoryAxis ? pointSeries.indexes : xValues;
        var yDrawValues = this.ySelector(pointSeries);
        var y1DrawValues = this.y1Selector(pointSeries);
        var _d = this.getStartAndCount(renderPassData, xDrawValues), startIndex = _d.startIndex, count = _d.count;
        this.args.count = count;
        this.args.startIndex = startIndex;
        if (fifoCapacity > 0 && fifoSweeping && fifoCapacity === this.parentSeries.dataSeries.count()) {
            this.args.count = fifoStartIndex;
        }
        var xAxis = this.parentSeries.xAxis;
        this.args.SetCoordinateTransform(xAxis.getTransform());
        this.args.SetXValues(xDrawValues);
        this.args.SetYValues(yDrawValues);
        if (y1DrawValues) {
            this.args.SetZValues(y1DrawValues);
        }
        else {
            this.args.zeroLineY = (_a = this.parentSeries.zeroLineY) !== null && _a !== void 0 ? _a : 0;
        }
        // Paletting per point
        this.applyFillFillPaletting(this.parentSeries.fill, fillBrush, this.parentSeries.fillY1, fillBrushY1, this.parentSeries.opacity, startIndex, count, pointSeries, xDrawValues, yDrawValues);
        this.args.SetPalettedColors(this.palettingState.palettedColors);
        this.args.scaleGradientToYRange = (_b = this.parentSeries.scaleGradientToYRange) !== null && _b !== void 0 ? _b : false;
        this.args.isSmoothColors = this.palettingState.gradientPaletting;
        var nativeContext = renderContext.getNativeContext();
        this.args.SetNativeContext(nativeContext);
        this.args.SetXCoordinateCalculator(renderPassData.xCoordinateCalculator.nativeCalculator);
        this.args.SetYCoordinateCalculator(renderPassData.yCoordinateCalculator.nativeCalculator);
        this.nativeDrawingProvider.DrawPoints(this.args);
        if (fifoCapacity > 0 && fifoSweeping && fifoCapacity === this.parentSeries.dataSeries.count()) {
            this.args.startIndex = Math.min(yDrawValues.size(), fifoStartIndex + fifoSweepingGap);
            this.args.count = Math.max(0, yDrawValues.size() - fifoStartIndex - fifoSweepingGap);
            if (this.args.count > 0) {
                this.nativeDrawingProvider.DrawPoints(this.args);
            }
        }
    };
    PolarBandSeriesDrawingProvider.prototype.applyFillFillPaletting = function (fill, fillBrush, filly1, fillBrushy1, opacity, startIndex, drawCount, pointSeries, xValues, yValues) {
        var _a;
        var hasFillPaletteProvider = this.parentSeries.hasFillPaletteProvider();
        var fillPaletteProvider = this.parentSeries.paletteProvider;
        if (hasFillPaletteProvider) {
            var fillColor = void 0;
            var fillColory1 = void 0;
            var hasOpacity = opacity !== undefined;
            fillColor =
                fill && hasOpacity
                    ? (0, colorUtil_1.uintArgbColorMultiplyOpacity)((0, parseColor_1.parseColorToUIntArgb)(fill), 1)
                    : app_1.NEUTRAL_COLOR;
            fillColory1 =
                filly1 && hasOpacity
                    ? (0, colorUtil_1.uintArgbColorMultiplyOpacity)((0, parseColor_1.parseColorToUIntArgb)(filly1), 1)
                    : app_1.NEUTRAL_COLOR;
            if (isNaN(fillColor)) {
                throw Error("updatePalette(): fillColor " + fillColor + " cannot be converted to a valid color");
            }
            if (isNaN(fillColory1)) {
                throw Error("updatePalette(): fillColor for y1 " + fillColory1 + " cannot be converted to a valid color");
            }
            if (!this.palettingState.palettedColors) {
                this.palettingState.palettedColors = new this.webAssemblyContext.UIntVector();
            }
            this.palettingState.paletteTextureCache.reset();
            this.palettingState.palettedColors.resize(drawCount * 2, 0);
            // Override fill colors
            var hashCode = 0;
            var dataSeries = this.parentSeries.dataSeries;
            var dsCount = dataSeries.count();
            var hasPSIndexes = pointSeries && pointSeries.indexes.size() > 0;
            var indexView = (0, vectorToArray_1.vectorToArrayViewF64)(pointSeries === null || pointSeries === void 0 ? void 0 : pointSeries.indexes, this.webAssemblyContext);
            var xView = (0, vectorToArray_1.vectorToArrayViewF64)(xValues, this.webAssemblyContext);
            var yView = (0, vectorToArray_1.vectorToArrayViewF64)(yValues, this.webAssemblyContext);
            var paletteView = (0, vectorToArray_1.vectorToArrayViewUi32)(this.palettingState.palettedColors, this.webAssemblyContext);
            // Create otherValues map for additional data series values
            var otherValues = new Map();
            for (var _i = 0, _b = dataSeries.valueNames; _i < _b.length; _i++) {
                var valueName = _b[_i];
                if (valueName !== ValueName_1.EValueName.Y) {
                    otherValues.set(valueName, (0, vectorToArray_1.vectorToArrayViewF64)(dataSeries.getYValuesByName(valueName), this.webAssemblyContext));
                }
            }
            var paletteIndex = 0;
            for (var index = startIndex; index < startIndex + drawCount; index++) {
                var originalDataIndex = hasPSIndexes ? indexView[index] : index;
                if (originalDataIndex < 0)
                    originalDataIndex = 0;
                else if (originalDataIndex >= dsCount)
                    originalDataIndex = dsCount - 1;
                var xValue = xView[index];
                var yValue = yView[index];
                var metaData = dataSeries.getMetadataAt(originalDataIndex);
                var overrideFillColor = fillPaletteProvider.overrideFillArgb(xValue, yValue, originalDataIndex, opacity, metaData, otherValues);
                paletteView[paletteIndex] = (0, colorUtil_1.uintArgbColorToAbgr)(overrideFillColor !== null && overrideFillColor !== void 0 ? overrideFillColor : fillColor);
                paletteIndex++;
                paletteView[paletteIndex] = (0, colorUtil_1.uintArgbColorToAbgr)(overrideFillColor !== null && overrideFillColor !== void 0 ? overrideFillColor : fillColory1);
                paletteIndex++;
                hashCode = (0, number_1.numericHashCode)(hashCode, overrideFillColor);
            }
        }
        else {
            this.palettingState.paletteTextureCache.reset();
            (_a = this.palettingState.palettedColors) === null || _a === void 0 ? void 0 : _a.clear();
        }
        // Due to pass-by-pointer limitations of WASM binding, we pass an empty vector rather than null
        if (!this.palettingState.palettedColors) {
            this.palettingState.palettedColors = new this.webAssemblyContext.UIntVector();
        }
        // Set gradient for the fill color
        this.palettingState.gradientPaletting = this.isGradientFillPaletting(this.parentSeries);
    };
    /**
     * @inheritDoc
     */
    PolarBandSeriesDrawingProvider.prototype.onSeriesPropertyChange = function (propertyName) {
        _super.prototype.onSeriesPropertyChange.call(this, propertyName);
        var _a = this.parentSeries, fill = _a.fill, fillY1 = _a.fillY1, opacity = _a.opacity, fillLinearGradient = _a.fillLinearGradient, fillLinearGradientY1 = _a.fillLinearGradientY1, parentSurface = _a.parentSurface;
        var textureHeightRatio = (parentSurface === null || parentSurface === void 0 ? void 0 : parentSurface.isCopyCanvasSurface)
            ? parentSurface.domCanvas2D.height / SciChartSurfaceBase_1.SciChartSurfaceBase.domMasterCanvas.height
            : 1;
        var textureWidthRatio = (parentSurface === null || parentSurface === void 0 ? void 0 : parentSurface.isCopyCanvasSurface)
            ? parentSurface.domCanvas2D.width / SciChartSurfaceBase_1.SciChartSurfaceBase.domMasterCanvas.width
            : 1;
        if (propertyName === constants_1.PROPERTY.FILL ||
            propertyName === constants_1.PROPERTY.OPACITY ||
            propertyName === constants_1.PROPERTY.FILL_LINEAR_GRADIENT) {
            (0, BrushCache_1.createBrushInCache)(this.fillBrushCache, fill, opacity, textureHeightRatio, textureWidthRatio, fillLinearGradient);
        }
        if (propertyName === constants_1.PROPERTY.FILL_Y1 ||
            propertyName === constants_1.PROPERTY.OPACITY ||
            propertyName === constants_1.PROPERTY.FILL_LINEAR_GRADIENT) {
            (0, BrushCache_1.createBrushInCache)(this.fillBrushY1Cache, fillY1, opacity, textureHeightRatio, textureWidthRatio, fillLinearGradientY1);
        }
    };
    return PolarBandSeriesDrawingProvider;
}(BaseSeriesDrawingProvider_1.BaseSeriesDrawingProvider));
exports.PolarBandSeriesDrawingProvider = PolarBandSeriesDrawingProvider;
