"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.SmearSeriesDrawingProvider = void 0;
var Deleter_1 = require("../../../../Core/Deleter");
var HeightColorSettings_1 = require("../../../../types/HeightColorSettings");
var colorUtil_1 = require("../../../../utils/colorUtil");
var HeightColorUtils_1 = require("../../../../utils/HeightColorUtils");
var parseColor_1 = require("../../../../utils/parseColor");
var BaseSeriesDrawingProvider_1 = require("./BaseSeriesDrawingProvider");
var BaseDataSeries_1 = require("../../../Model/BaseDataSeries");
var NumberRange_1 = require("../../../../Core/NumberRange");
/**
 * Used internally - a drawing provider performs drawing for a {@link ISmearRenderableSeries} using
 * our WebAssembly WebGL rendering engine
 */
var SmearSeriesDrawingProvider = /** @class */ (function (_super) {
    __extends(SmearSeriesDrawingProvider, _super);
    /**
     * Creates an instance of the {@link SmearSeriesDrawingProvider}
     * @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 SmearSeriesDrawingProvider} which this drawing provider is attached to
     */
    function SmearSeriesDrawingProvider(webAssemblyContext, parentSeries, ySelector, zColorSelector, yColorSelector) {
        var _this = _super.call(this, webAssemblyContext, parentSeries, ySelector) || this;
        _this.valuesUpdateRequired = true;
        _this.args = new _this.webAssemblyContext.SCRTSmearSeriesParams();
        _this.colorSettings = new _this.webAssemblyContext.SCRTHeightColorSettings();
        _this.yColorSelector = yColorSelector !== null && yColorSelector !== void 0 ? yColorSelector : (function (ps) { return ps.getNativeXValues(); });
        _this.zColorSelector = zColorSelector !== null && zColorSelector !== void 0 ? zColorSelector : (function (ps) { return ps.getNativeYValues(); });
        return _this;
    }
    /**
     * @inheritDoc
     */
    SmearSeriesDrawingProvider.prototype.onAttachSeries = function () {
        _super.prototype.onAttachSeries.call(this);
        this.nativeDrawingProvider = new this.webAssemblyContext.SCRTSmearSeriesDrawingProvider();
        var _a = this.parentSeries, stroke = _a.stroke, strokeThickness = _a.strokeThickness, opacity = _a.opacity;
    };
    /**
     * @inheritDoc
     */
    SmearSeriesDrawingProvider.prototype.onDetachSeries = function () {
        _super.prototype.onDetachSeries.call(this);
        this.delete();
    };
    /**
     * @inheritDoc
     */
    SmearSeriesDrawingProvider.prototype.delete = function () {
        this.nativeDrawingProvider = (0, Deleter_1.deleteSafe)(this.nativeDrawingProvider);
        this.args = (0, Deleter_1.deleteSafe)(this.args);
        _super.prototype.delete.call(this);
    };
    /**
     * @inheritDoc
     */
    SmearSeriesDrawingProvider.prototype.draw = function (renderContext, renderPassData) {
        var _a;
        var pointSeries = renderPassData.pointSeries;
        //this.args.Reset();
        this.colorSettings.Reset();
        var isCategoryAxis = renderPassData.xCoordinateCalculator.isCategoryCoordinateCalculator;
        var xValues = pointSeries.xValues;
        var colorData = this.parentSeries.colorDataSeries;
        var xDrawValues = isCategoryAxis ? pointSeries.indexes : xValues;
        var yDrawValues = this.ySelector(pointSeries);
        var yColorValues = this.yColorSelector(colorData);
        var zColorValues = this.zColorSelector(colorData);
        this.args.SetX(xDrawValues);
        this.args.SetY(yDrawValues);
        var _b = this.getStartAndCount(renderPassData, xDrawValues), startIndex = _b.startIndex, count = _b.count;
        this.args.m_iStartIndex = startIndex;
        this.args.m_iCount = count;
        this.args.m_dYOffset = this.parentSeries.yOffset;
        this.args.smoothColors = this.parentSeries.smoothColors;
        if (count < 2)
            return;
        //logDoubleVector(zDrawValues, "", 0, 100);
        // Get indexRange for yColorValues based on y coordinate calc.
        var rangeStartTime = performance.now();
        var valuesRange = (0, BaseDataSeries_1.getWindowedYRange)(this.webAssemblyContext, pointSeries.xValues, pointSeries.yValues, isCategoryAxis
            ? new NumberRange_1.NumberRange(0, pointSeries.count - 1)
            : new NumberRange_1.NumberRange(renderPassData.xCoordinateCalculator.visibleMin, renderPassData.xCoordinateCalculator.visibleMax), true, isCategoryAxis, this.parentSeries.dataSeries.dataDistributionCalculator.isSortedAscending, this.parentSeries.dataSeries.dataDistributionCalculator.containsNaN);
        var colorCount = yColorValues.size();
        var yRange = new NumberRange_1.NumberRange(renderPassData.yCoordinateCalculator.visibleMin - valuesRange.max, renderPassData.yCoordinateCalculator.visibleMax - valuesRange.min);
        var colorIndicesRange = (0, BaseDataSeries_1.getIndicesRange)(this.webAssemblyContext, yColorValues, yRange, colorData.dataDistributionCalculator.isSortedAscending);
        //console.log("get color indicies", yRange, colorIndicesRange, performance.now() - rangeStartTime);
        // TODO check how this plays with colorsettings
        this.args.m_iColorStartIndex = Math.min(colorCount - 2, colorIndicesRange.min);
        this.args.m_iColorCount = Math.max(2, colorIndicesRange.diff + 1);
        if (this.parentSeries.colorSettings) {
            var colorStops = this.parentSeries.colorSettings.colorStops;
            (0, HeightColorUtils_1.validateColorStops)(this.parentSeries.colorSettings);
            for (var _i = 0, colorStops_1 = colorStops; _i < colorStops_1.length; _i++) {
                var colorStop = colorStops_1[_i];
                var colorNum = (0, parseColor_1.parseColorToUIntArgb)(colorStop.color);
                //console.log(colorStop.dataValue, colorStop.color, colorNum);
                this.colorSettings.AddColorStop(colorStop.dataValue, colorNum);
            }
            if (this.parentSeries.colorSettings.infraColor) {
                this.colorSettings.m_uiInfra = (0, parseColor_1.parseColorToUIntArgb)(this.parentSeries.colorSettings.infraColor);
            }
            if (this.parentSeries.colorSettings.ultraColor) {
                this.colorSettings.m_uiUltra = (0, parseColor_1.parseColorToUIntArgb)(this.parentSeries.colorSettings.ultraColor);
            }
            this.colorSettings.m_fMinHeight = colorStops[0].dataValue;
            this.colorSettings.m_fMaxHeight = colorStops[colorStops.length - 1].dataValue;
            this.colorSettings.m_bIsGradient =
                this.parentSeries.colorSettings.colorPickMode === HeightColorSettings_1.EColorPickMode.Interpolated;
            //this.args.interpolate = this.parentSeries.colorSettings.fillMode === EFillPaletteMode.GRADIENT;
            this.colorSettings.m_fMaxTextureSize = (_a = this.parentSeries.colorSettings.maxTextureSize) !== null && _a !== void 0 ? _a : 0;
            this.args.SetHeightColors(this.colorSettings);
            this.args.SetColorZvalues(zColorValues);
        }
        else if (this.parentSeries.paletteProvider) {
            // Stripped down paletteProvider logic as there is no pen or brush to manage
            var advancedPP = this.parentSeries.paletteProvider;
            var strokePaletteProvider = this.parentSeries.paletteProvider;
            var strokeColorArgb = (0, colorUtil_1.uintArgbColorMultiplyOpacity)((0, parseColor_1.parseColorToUIntArgb)(this.parentSeries.stroke), this.parentSeries.opacity);
            if (!this.palettingState.palettedColors) {
                this.palettingState.palettedColors = new this.webAssemblyContext.UIntVector();
            }
            var colorCount_1 = yColorValues.size();
            if (advancedPP.applyPaletting) {
                advancedPP.applyPaletting(this.palettingState, yColorValues, zColorValues, colorData.getNativeIndexes(), 0, colorCount_1);
                return;
            }
            // TODO detect if pallete should be recreated
            // this.shouldUpdatePalette(renderPassData, strokePaletteProvider, startIndex, count);
            // if (!this.palettingState.requiresUpdate) {
            //     return;
            // }
            this.palettingState.palettedColors.clear();
            this.palettingState.palettedColors.reserve(colorCount_1);
            if (strokePaletteProvider.overrideStrokeArgb) {
                for (var index = 0; index < colorCount_1; index++) {
                    var xValue = yColorValues.get(index);
                    var yValue = zColorValues.get(index);
                    var overrideColor = strokePaletteProvider.overrideStrokeArgb(xValue, yValue, index, this.parentSeries.opacity, colorData.getMetadataAt(index));
                    this.palettingState.palettedColors.push_back(overrideColor ? overrideColor : strokeColorArgb);
                }
            }
            else {
                //treat z values as raw colors
                for (var index = 0; index < colorCount_1; index++) {
                    this.palettingState.palettedColors.push_back(zColorValues.get(index));
                }
            }
            this.palettingState.requiresUpdate = false;
            this.args.SetColors(this.palettingState.palettedColors);
        }
        var nativeContext = renderContext.getNativeContext();
        // only do this if z values has changed
        //console.log("start", this.args.m_iColorStartIndex, "count", this.args.m_iColorCount);
        var timeStart = performance.now();
        this.nativeDrawingProvider.CreateSmearSeriesColorsTexture(yColorValues, renderPassData.yCoordinateCalculator.nativeCalculator, this.args);
        // console.log("Color tex ", performance.now() - timeStart);
        timeStart = performance.now();
        //if (this.valuesUpdateRequired) {
        // only do this if x/y values or coordinateCalcs have changed
        this.nativeDrawingProvider.CreateSmearSeriesValuesTexture(renderPassData.xCoordinateCalculator.nativeCalculator, renderPassData.yCoordinateCalculator.nativeCalculator, this.args);
        this.valuesUpdateRequired = false;
        //console.log("values tex ", performance.now() - timeStart);
        timeStart = performance.now();
        //}
        this.nativeDrawingProvider.DrawSmearSeries(nativeContext, this.args);
        //console.log("draw ", performance.now() - timeStart);
    };
    /**
     * @inheritDoc
     */
    SmearSeriesDrawingProvider.prototype.onDpiChanged = function (args) {
        _super.prototype.onDpiChanged.call(this, args);
    };
    /**
     * @inheritDoc
     */
    SmearSeriesDrawingProvider.prototype.onSeriesPropertyChange = function (propertyName) {
        _super.prototype.onSeriesPropertyChange.call(this, propertyName);
    };
    SmearSeriesDrawingProvider.prototype.seriesHasDataChanges = function () {
        this.valuesUpdateRequired = true;
    };
    SmearSeriesDrawingProvider.prototype.seriesHasColorChanges = function () {
        this.palettingState.requiresUpdate = true;
    };
    return SmearSeriesDrawingProvider;
}(BaseSeriesDrawingProvider_1.BaseSeriesDrawingProvider));
exports.SmearSeriesDrawingProvider = SmearSeriesDrawingProvider;
