"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.IndexCoordinateCalculator = void 0;
var NumberRange_1 = require("../../../Core/NumberRange");
var CoordinateCalculatorBase_1 = require("./CoordinateCalculatorBase");
/**
 * Provides an implementation of Index {@link CoordinateCalculatorBase | Coordinate Calculator} which transforms
 * numeric data-values to pixel coordinates and vice versa using base values.
 * @remarks
 * SciChart's {@link https://www.scichart.com/javascript-chart-features | JavaScript Charts} perform conversion operations between
 * data-coordinates for all drawing and axis measurements.
 *
 * You can fetch a CoordinateCalculator instance by calling {@link AxisCore.getCurrentCoordinateCalculator}. This will return a unique calculator
 * for the current draw pass.
 *
 * You can convert pixel to data-coordinates and back by using the following code:
 * ```ts
 * const axis: AxisCore;
 * const calc = axis.getCurrentCoordinateCalculator();
 *
 * const pixel = calc.getCoordinate(1.23); // Gets the pixel coordinate for data-value 1.23
 * const dataValue = cald.getDataValue(pixel); // Performs the inverse operation to get data-value
 * ```
 *
 * Use the Coordinate calculators when drawing, placing markers, annotations or if you want to place a tooltip over the chart.
 */
var IndexCoordinateCalculator = /** @class */ (function (_super) {
    __extends(IndexCoordinateCalculator, _super);
    /**
     * Creates an instance of IndexCoordinateCalculator
     * @param webAssemblyContext The {@link TSciChart | SciChart 2D WebAssembly Context} or {@link TSciChart2D | SciChart 2D WebAssembly Context}
     * @param indexCalculator The index calculator, it is used to set base values
     * @param viewportDimension The size of the associated {@link AxisCore | Axis} at the time of drawing
     * @param visibleMin The {@link AxisCore.visibleRange}.min at the time of drawing
     * @param visibleMax The {@link AxisCore.visibleRange}.max at the time of drawing
     * @param indexMin The minimal visible index
     * @param indexMax The maximum visible index
     * @param offset A constant pixel offset used in coordinate calculations
     * @param viewportOffset
     */
    function IndexCoordinateCalculator(webAssemblyContext, indexCalculator, viewportDimension, visibleMin, visibleMax, indexMin, indexMax, offset, viewportOffset) {
        if (offset === void 0) { offset = 0; }
        if (viewportOffset === void 0) { viewportOffset = -1; }
        var _this = _super.call(this, webAssemblyContext, viewportDimension, visibleMin, visibleMax, offset, true) || this;
        var params = new webAssemblyContext.IndexCalculatorParams();
        params.SetIndexCalculator(indexCalculator);
        params.m_dViewportDimension = viewportDimension;
        params.m_dVisibleMin = visibleMin;
        params.m_dVisibleMax = visibleMax;
        params.m_dViewportOffset = viewportOffset;
        params.m_dCoordOffset = _this.offset;
        params.m_dIndexMin = indexMin;
        params.m_dIndexMax = indexMax;
        var cc = new webAssemblyContext.IndexCoordinateCalculator(params);
        params.delete();
        _this.nativeCalculator = cc;
        _this.indexCalculator = indexCalculator;
        _this.indexRange = new NumberRange_1.NumberRange(indexCalculator.GetIndex(visibleMin), indexCalculator.GetIndex(visibleMax));
        _this.dimensionOverMaxMinusMin = viewportDimension / (_this.indexRange.max - _this.indexRange.min);
        _this.minEdgeCoord = -_this.indexRange.min * _this.dimensionOverMaxMinusMin;
        return _this;
    }
    /** @inheritDoc */
    IndexCoordinateCalculator.prototype.getCoordinate = function (dataValue) {
        var index = this.indexCalculator.GetIndex(dataValue);
        return this.minEdgeCoord + index * this.dimensionOverMaxMinusMin + this.offset;
    };
    /** @inheritDoc */
    IndexCoordinateCalculator.prototype.getDataValue = function (coordinate) {
        var index = (coordinate - this.offset - this.minEdgeCoord) / this.dimensionOverMaxMinusMin;
        return this.indexCalculator.GetValue(index);
    };
    /** @inheritDoc */
    IndexCoordinateCalculator.prototype.translateBy = function (pixels, range) {
        // TODO: Move into native coordinateCalculator calculator
        var minCoord = this.getCoordinate(range.min) - pixels;
        var maxCoord = this.getCoordinate(range.max) - pixels;
        return new NumberRange_1.NumberRange(this.getDataValue(minCoord), this.getDataValue(maxCoord));
    };
    IndexCoordinateCalculator.prototype.transformIndexToData = function (index) {
        return this.indexCalculator.GetValue(index);
    };
    IndexCoordinateCalculator.prototype.transformDataToIndex = function (dataValue) {
        return this.indexCalculator.GetIndex(dataValue);
    };
    /** @inheritDoc */
    IndexCoordinateCalculator.prototype.zoomTranslateBy = function (minFraction, maxFraction, inputRange) {
        var minIndex = this.transformDataToIndex(inputRange.min);
        var maxIndex = this.transformDataToIndex(inputRange.max);
        var rangeDiff = maxIndex - minIndex;
        var isZeroRange = rangeDiff == 0;
        minIndex -= minFraction * (isZeroRange ? minIndex : rangeDiff);
        maxIndex += maxFraction * (isZeroRange ? maxIndex : rangeDiff);
        return maxIndex >= minIndex
            ? new NumberRange_1.NumberRange(this.transformIndexToData(minIndex), this.transformIndexToData(maxIndex))
            : new NumberRange_1.NumberRange(this.transformIndexToData(maxIndex), this.transformIndexToData(minIndex));
    };
    return IndexCoordinateCalculator;
}(CoordinateCalculatorBase_1.CoordinateCalculatorBase));
exports.IndexCoordinateCalculator = IndexCoordinateCalculator;
