"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.LogarithmicAxis3D = void 0;
// tslint:disable-next-line:max-line-length
var LogarithmicCoordinateCalculator_1 = require("../../../Charting/Numerics/CoordinateCalculators/LogarithmicCoordinateCalculator");
var LogarithmicTickProvider_1 = require("../../../Charting/Numerics/TickProviders/LogarithmicTickProvider");
var LogarithmicDeltaCalculator_1 = require("../../../Charting/Visuals/Axis/DeltaCalculator/LogarithmicDeltaCalculator");
var LogarithmicLabelProvider_1 = require("../../../Charting/Visuals/Axis/LabelProvider/LogarithmicLabelProvider");
var LogarithmicAxis_1 = require("../../../Charting/Visuals/Axis/LogarithmicAxis");
var constants_1 = require("../../../Charting/Visuals/Axis/constants");
var EasingFunctions_1 = require("../../../Core/Animations/EasingFunctions");
var NumberRangeAnimator_1 = require("../../../Core/Animations/NumberRangeAnimator");
var NumberRange_1 = require("../../../Core/NumberRange");
var AxisType_1 = require("../../../types/AxisType");
var XyDirection_1 = require("../../../types/XyDirection");
var AxisBase3D_1 = require("./AxisBase3D");
/**
 * @summary A 3D Chart Logarithmic Numeric Axis type
 * @description A LogarithmicAxis3D uses logarithmic scaling of values to coordinates.
 * The axis can represent positive or negative values, but not both at the same time.
 * @remarks
 * Set a {@link LogarithmicAxis3D} on the {@link SciChart3DSurface.xAxis}, {@link SciChart3DSurface.yAxis}
 * or {@link SciChart3DSurface.zAxis} property.
 */
var LogarithmicAxis3D = /** @class */ (function (_super) {
    __extends(LogarithmicAxis3D, _super);
    /**
     * Creates an instance of a {@link LogarithmicAxis3D}
     * @param webAssemblyContext The {@link TSciChart3D | SciChart 3D WebAssembly Context} containing native methods and
     * access to our WebGL2 Engine and WebAssembly numerical methods
     * @param options optional parameters of type {@link ILogarithmicAxis3dOptions} to configure the axis
     */
    function LogarithmicAxis3D(webAssemblyContext, options) {
        var _this = this;
        var _a, _b, _c, _d, _e, _f;
        _this = _super.call(this, webAssemblyContext, options) || this;
        /**
         * @inheritDoc
         */
        _this.type = AxisType_1.EAxisType.LogarithmicAxis3D;
        _this.logBaseProperty = 10;
        _this.isNegativeProperty = false;
        _this.isHighPrecisionTicksProperty = true;
        _this.tickProvider = new LogarithmicTickProvider_1.LogarithmicTickProvider(_this.webAssemblyContext3D);
        _this.deltaCalculator = new LogarithmicDeltaCalculator_1.LogarithmicDeltaCalculator(_this.webAssemblyContext3D);
        _this.labelProvider =
            (_a = options === null || options === void 0 ? void 0 : options.labelProvider) !== null && _a !== void 0 ? _a : new LogarithmicLabelProvider_1.LogarithmicLabelProvider(options);
        _this.logBase = (_b = options === null || options === void 0 ? void 0 : options.logBase) !== null && _b !== void 0 ? _b : _this.logBaseProperty;
        _this.isNegativeProperty = (_c = options === null || options === void 0 ? void 0 : options.isNegative) !== null && _c !== void 0 ? _c : false;
        _this.isHighPrecisionTicks = (_d = options === null || options === void 0 ? void 0 : options.isHighPrecisionTicks) !== null && _d !== void 0 ? _d : _this.isHighPrecisionTicksProperty;
        _this.majorTickMode = (_e = options === null || options === void 0 ? void 0 : options.majorTickMode) !== null && _e !== void 0 ? _e : _this.majorTickMode;
        _this.minorTickMode = (_f = options === null || options === void 0 ? void 0 : options.minorTickMode) !== null && _f !== void 0 ? _f : _this.minorTickMode;
        // If user did not supply a visibleRange, replace the AxisCore default (0..10) with a log-friendly one
        if (!(options === null || options === void 0 ? void 0 : options.visibleRange)) {
            _this.visibleRange = _this.getDefaultNonZeroRange();
            _this.hasVisibleRangeSet = false;
        }
        // If no visibleRangeLimit provided, clamp to the positive or negative half-line
        if (!(options === null || options === void 0 ? void 0 : options.visibleRangeLimit)) {
            _this.visibleRangeLimit = _this.isNegativeProperty
                ? new NumberRange_1.NumberRange(-Infinity, -LogarithmicAxis_1.MIN_LOG_AXIS_VALUE)
                : new NumberRange_1.NumberRange(LogarithmicAxis_1.MIN_LOG_AXIS_VALUE, Infinity);
        }
        return _this;
    }
    Object.defineProperty(LogarithmicAxis3D.prototype, "logBase", {
        /**
         * Gets or sets the Logarithmic Base for the axis. Defaults to 10
         */
        get: function () {
            return this.logBaseProperty;
        },
        /**
         * Gets or sets the Logarithmic Base for the axis. Defaults to 10
         */
        set: function (logBase) {
            if (this.logBaseProperty !== logBase) {
                this.logBaseProperty = logBase;
                this.clearCoordCalcCache();
                this.updateProviders();
                this.notifyPropertyChanged(constants_1.PROPERTY.LOG_BASE);
            }
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(LogarithmicAxis3D.prototype, "isNegative", {
        /**
         * Gets or sets whether this axis shows negative values only (true) or positive values only (false)
         */
        get: function () {
            return this.isNegativeProperty;
        },
        set: function (isNegative) {
            this.isNegativeProperty = isNegative;
            this.visibleRangeLimit = isNegative
                ? new NumberRange_1.NumberRange(-Infinity, -LogarithmicAxis_1.MIN_LOG_AXIS_VALUE)
                : new NumberRange_1.NumberRange(LogarithmicAxis_1.MIN_LOG_AXIS_VALUE, Infinity);
            this.notifyPropertyChanged(constants_1.PROPERTY.IS_NEGATIVE);
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(LogarithmicAxis3D.prototype, "isHighPrecisionTicks", {
        get: function () {
            return this.isHighPrecisionTicksProperty;
        },
        set: function (value) {
            this.isHighPrecisionTicksProperty = value;
            this.updateProviders();
            this.notifyPropertyChanged(constants_1.PROPERTY.HIGH_PRECISION_TICKS);
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(LogarithmicAxis3D.prototype, "majorTickMode", {
        /**
         * Gets or sets the mode for Major ticks using {@link ELogarithmicMajorTickMode}
         */
        get: function () {
            return this.logTickProvider.majorTickMode;
        },
        set: function (mode) {
            this.logTickProvider.majorTickMode = mode;
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(LogarithmicAxis3D.prototype, "minorTickMode", {
        /**
         * Gets or sets the mode for minor ticks using {@link ELogarithmicMinorTickMode}
         */
        get: function () {
            return this.logTickProvider.minorTickMode;
        },
        set: function (mode) {
            this.logTickProvider.minorTickMode = mode;
        },
        enumerable: false,
        configurable: true
    });
    /**
     * @inheritDoc
     */
    LogarithmicAxis3D.prototype.getDefaultNonZeroRange = function () {
        var adj = this.isNegativeProperty ? -1 : 1;
        return new NumberRange_1.NumberRange(adj * Math.pow(this.logBase, -1), adj * Math.pow(this.logBase, 2));
    };
    /**
     * @inheritDoc
     */
    LogarithmicAxis3D.prototype.hasValidVisibleRange = function () {
        return _super.prototype.hasValidVisibleRange.call(this) && this.visibleRange.min * this.visibleRange.max > 0;
    };
    /**
     * @inheritDoc
     */
    LogarithmicAxis3D.prototype.animateVisibleRange = function (visibleRange, durationMs, easingFunction, onCompleted) {
        var _this = this;
        var _a;
        if (easingFunction === void 0) { easingFunction = EasingFunctions_1.easing.outCubic; }
        if (onCompleted === void 0) { onCompleted = function () { }; }
        if (durationMs <= 0) {
            this.visibleRange = visibleRange || this.visibleRange;
            onCompleted();
            return undefined;
        }
        (_a = this.visibleRangeAnimationToken) === null || _a === void 0 ? void 0 : _a.cancel();
        this.visibleRangeAnimationToken = NumberRangeAnimator_1.NumberRangeAnimator.animate(this.visibleRange, visibleRange, durationMs, function (range) {
            _this.visibleRange = range;
        }, function () {
            _this.visibleRangeAnimationToken = undefined;
            onCompleted();
        }, easingFunction, true);
        this.parentSurface.addAnimation(this.visibleRangeAnimationToken);
        return this.visibleRangeAnimationToken;
    };
    /**
     * @inheritDoc
     */
    LogarithmicAxis3D.prototype.getMaximumRange = function () {
        var _a, _b, _c, _d;
        var maximumRange;
        if (((_b = (_a = this.parentSurface) === null || _a === void 0 ? void 0 : _a.renderableSeries) === null || _b === void 0 ? void 0 : _b.size()) > 0) {
            var whichAxis = this.isXAxis
                ? AxisBase3D_1.EWhichAxis.xAxis
                : this.isYAxis
                    ? AxisBase3D_1.EWhichAxis.yAxis
                    : AxisBase3D_1.EWhichAxis.zAxis;
            maximumRange = this.getMaximumRangeAs(this.parentSurface.renderableSeries, whichAxis);
            if (maximumRange === null || maximumRange === void 0 ? void 0 : maximumRange.isZero()) {
                maximumRange = this.coerceZeroVisibleRange(maximumRange);
            }
            // Apply log-scaled growBy
            if (((_c = this.growBy) === null || _c === void 0 ? void 0 : _c.isDefined()) && maximumRange) {
                maximumRange = maximumRange.growByLog(this.growBy, this.logBase);
            }
            // Clip to visibleRangeLimit (keeps positive/negative-only constraint intact)
            if (this.visibleRangeLimit && maximumRange) {
                maximumRange = maximumRange.clip(this.visibleRangeLimit);
            }
        }
        var currentVisibleRange = ((_d = this.visibleRange) === null || _d === void 0 ? void 0 : _d.isDefined()) ? this.visibleRange : this.getDefaultNonZeroRange();
        return (maximumRange === null || maximumRange === void 0 ? void 0 : maximumRange.isDefined()) ? maximumRange : currentVisibleRange;
    };
    LogarithmicAxis3D.prototype.toJSON = function () {
        var json = _super.prototype.toJSON.call(this);
        var options = {
            logBase: this.logBase,
            isNegative: this.isNegative,
            majorTickMode: this.majorTickMode,
            minorTickMode: this.minorTickMode,
            isHighPrecisionTicks: this.isHighPrecisionTicks
        };
        Object.assign(json.options, options);
        return json;
    };
    /**
     * @inheritDoc
     */
    LogarithmicAxis3D.prototype.getCurrentCoordinateCalculatorInternal = function () {
        var min = this.visibleRange.min;
        var max = this.visibleRange.max;
        var size = this.getAxisSize();
        var direction = this.isXAxis ? XyDirection_1.EXyDirection.XDirection : XyDirection_1.EXyDirection.YDirection;
        var shouldFlip = !this.flippedCoordinatesProperty;
        return new LogarithmicCoordinateCalculator_1.LogarithmicCoordinateCalculator(this.webAssemblyContext3D, size, min, max, direction, this.logBase, shouldFlip);
    };
    Object.defineProperty(LogarithmicAxis3D.prototype, "logTickProvider", {
        get: function () {
            return this.tickProvider;
        },
        enumerable: false,
        configurable: true
    });
    LogarithmicAxis3D.prototype.updateProviders = function () {
        var logTickProvider = this.tickProvider;
        if (logTickProvider) {
            logTickProvider.logarithmicBase = this.logBase;
            logTickProvider.isHighPrecisionTicks = this.isHighPrecisionTicks;
        }
        var logDeltaCalculator = this.deltaCalculator;
        if (logDeltaCalculator) {
            logDeltaCalculator.logarithmicBase = this.logBase;
            logDeltaCalculator.isHighPrecisionTicks = this.isHighPrecisionTicks;
        }
        var logLabelProvider = this.labelProvider;
        if (logLabelProvider) {
            logLabelProvider.logarithmicBase = this.logBase;
        }
    };
    return LogarithmicAxis3D;
}(AxisBase3D_1.AxisBase3D));
exports.LogarithmicAxis3D = LogarithmicAxis3D;
