"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.XAxisDragModifier = void 0;
var CursorStyle_1 = require("../../types/CursorStyle");
var DragMode_1 = require("../../types/DragMode");
var translate_1 = require("../../utils/translate");
var AxisBase2D_1 = require("../Visuals/Axis/AxisBase2D");
var ChartModifierBase2D_1 = require("./ChartModifierBase2D");
var ChartModifierType_1 = require("../../types/ChartModifierType");
var PinchZoomModifier_1 = require("./PinchZoomModifier");
/**
 * The XAxisDragModifier provides scaling/panning behavior for X axis {@link AxisBase2D}
 * and pinch zoom support on mobile devices
 * within SciChart - High Performance {@link https://www.scichart.com/javascript-chart-features | JavaScript Charts}
 * @remarks
 *
 * To apply the XAxisDragModifier to a {@link SciChartSurface} and add scaling behavior,
 * use the following code:
 *
 * ```ts
 * sciChartSurface.chartModifiers.add(new XAxisDragModifier());
 * ```
 *
 * ---
 * 📚 Docs: {@link https://www.scichart.com/documentation/js/v4/2d-charts/chart-modifier-api/zooming-and-panning/x-axis-drag-modifier/}
 */
var XAxisDragModifier = /** @class */ (function (_super) {
    __extends(XAxisDragModifier, _super);
    /**
     * Creates an instance of a XAxisDragModifier
     * @param options optional parameters to pass to the XAxisDragModifier to configure it upon construction
     *
     * ---
     * 📚 Docs: {@link https://www.scichart.com/documentation/js/v4/2d-charts/chart-modifier-api/zooming-and-panning/x-axis-drag-modifier/}
     */
    function XAxisDragModifier(options) {
        var _this = this;
        var _a, _b;
        _this = _super.call(this, options) || this;
        _this.type = ChartModifierType_1.EChart2DModifierType.XAxisDrag;
        _this.dragMode = DragMode_1.EDragMode.Scaling;
        /**
         * Sets whether to enable pinch zoom behavior of {@link SciChartSurface} on touchscreen devices
         */
        _this.enableZoom = true;
        _this.isClickedOverXAxis = false;
        _this.isVerticalChart = false;
        _this.cursorStyle = CursorStyle_1.ECursorStyle.Default;
        _this.dragMode = (_a = options === null || options === void 0 ? void 0 : options.dragMode) !== null && _a !== void 0 ? _a : _this.dragMode;
        _this.enableZoom = (_b = options === null || options === void 0 ? void 0 : options.enableZoom) !== null && _b !== void 0 ? _b : _this.enableZoom;
        return _this;
    }
    /**
     * Not supported for {@link XAxisDragModifier}, use includeXAxis instead
     */
    XAxisDragModifier.prototype.includeYAxis = function (axis, isIncluded) {
        throw Error("method includeYAxis() is not supported for XAxisDragModifier, use includeXAxis() instead");
    };
    /**
     * Not supported for {@link XAxisDragModifier}, use getIncludedXAxis instead
     */
    XAxisDragModifier.prototype.getIncludedYAxis = function () {
        throw Error("method getIncludedYAxis() is not supported for XAxisDragModifier, use getIncludedXAxis() instead");
    };
    /** @inheritDoc */
    XAxisDragModifier.prototype.modifierMouseDown = function (args) {
        _super.prototype.modifierMouseDown.call(this, args);
        if (!this.isAttached) {
            throw new Error("Should not call XAxisDragModifier.modifierMouseDown if not attached");
        }
        if ((0, ChartModifierBase2D_1.testIsOverAxes)(this.getHorizontalXAxes(), args.mousePoint)) {
            // Horizontal chart
            this.isVerticalChart = false;
            this.startDragging(this.getHorizontalXAxes(), args);
        }
        else if ((0, ChartModifierBase2D_1.testIsOverAxes)(this.getVerticalXAxes(), args.mousePoint)) {
            // Vertical chart
            this.isVerticalChart = true;
            this.startDragging(this.getVerticalXAxes(), args);
        }
    };
    /** @inheritDoc */
    XAxisDragModifier.prototype.modifierMouseMove = function (args) {
        if (this.isClickedOverXAxis) {
            _super.prototype.modifierMouseMove.call(this, args);
            if (this.getIsActionAllowed(args)) {
                return;
            }
            if (this.pointFrom === undefined) {
                return;
            }
            if (this.dragMode === DragMode_1.EDragMode.Panning) {
                this.doPanning(args.mousePoint);
            }
            else if (this.dragMode === DragMode_1.EDragMode.Scaling) {
                this.doScaling(args.mousePoint);
            }
        }
        else {
            this.updateCursor(args.mousePoint);
        }
    };
    /** @inheritDoc */
    XAxisDragModifier.prototype.modifierMouseUp = function (args) {
        _super.prototype.modifierMouseUp.call(this, args);
        this.updateCursor(args.mousePoint);
        this.pointFrom = undefined;
        this.isClickedOverXAxis = false;
    };
    /** @inheritDoc */
    XAxisDragModifier.prototype.toJSON = function () {
        var json = _super.prototype.toJSON.call(this);
        var options = {
            dragMode: this.dragMode,
            enableZoom: this.enableZoom
        };
        Object.assign(json.options, options);
        return json;
    };
    XAxisDragModifier.prototype.getIsActionAllowed = function (args) {
        return this.enableZoom && _super.prototype.getIsActionAllowed.call(this, args);
    };
    XAxisDragModifier.prototype.performModifierAction = function (args) {
        var _this = this;
        var _a = Array.from(this.activePointerEvents.values()), firstTouchPoint = _a[0].mousePoint, secondTouchPoint = _a[1].mousePoint;
        var currentHorizontalTouchPointsDistance = Math.abs(firstTouchPoint.x - secondTouchPoint.x);
        var currentVerticalTouchPointsDistance = Math.abs(firstTouchPoint.y - secondTouchPoint.y);
        var zoomCenterMousePoint = this.getMiddlePoint(firstTouchPoint, secondTouchPoint);
        var anyUpdated = false;
        if (this.previousHorizontalTouchPointsDistance !== undefined &&
            this.previousVerticalTouchPointsDistance !== undefined) {
            var horizontalDistanceDiff = this.previousHorizontalTouchPointsDistance - currentHorizontalTouchPointsDistance;
            var translatedPoint_1 = (0, translate_1.translateFromCanvasToSeriesViewRect)(zoomCenterMousePoint, this.parentSurface.seriesViewRect, true);
            var activeXAxis = (0, ChartModifierBase2D_1.getActiveAxes)(this.getIncludedXAxis(), zoomCenterMousePoint);
            var horizontalFraction_1 = this.horizontalGrowFactor * horizontalDistanceDiff;
            activeXAxis.forEach(function (axis) {
                _this.growBy(translatedPoint_1, axis, horizontalFraction_1);
                anyUpdated = true;
            });
        }
        this.previousHorizontalTouchPointsDistance = currentHorizontalTouchPointsDistance;
        this.previousVerticalTouchPointsDistance = currentVerticalTouchPointsDistance;
        return anyUpdated;
    };
    XAxisDragModifier.prototype.updateCursor = function (mousePoint) {
        var canvas = this.parentSurface.getMainCanvas();
        if ((0, ChartModifierBase2D_1.testIsOverAxes)(this.getHorizontalXAxes(), mousePoint)) {
            if (this.cursorStyle !== CursorStyle_1.ECursorStyle.EW) {
                canvas.style.cursor = CursorStyle_1.ECursorStyle.EW;
                this.cursorStyle = CursorStyle_1.ECursorStyle.EW;
            }
        }
        else if ((0, ChartModifierBase2D_1.testIsOverAxes)(this.getVerticalXAxes(), mousePoint)) {
            if (this.cursorStyle !== CursorStyle_1.ECursorStyle.NS) {
                canvas.style.cursor = CursorStyle_1.ECursorStyle.NS;
                this.cursorStyle = CursorStyle_1.ECursorStyle.NS;
            }
        }
        else {
            if (this.cursorStyle !== CursorStyle_1.ECursorStyle.Default) {
                canvas.style.cursor = CursorStyle_1.ECursorStyle.Default;
                this.cursorStyle = CursorStyle_1.ECursorStyle.Default;
            }
        }
    };
    XAxisDragModifier.prototype.doPanning = function (mousePoint) {
        var pointTo = mousePoint;
        if (this.isVerticalChart) {
            var yDelta_1 = pointTo.y - this.pointFrom.y;
            this.activeAxes.forEach(function (x) {
                var delta = x.flippedCoordinates ? -yDelta_1 : yDelta_1;
                x.scroll(delta, AxisBase2D_1.EClipMode.None);
            });
        }
        else {
            var xDelta_1 = pointTo.x - this.pointFrom.x;
            this.activeAxes.forEach(function (x) {
                var delta = x.flippedCoordinates ? -xDelta_1 : xDelta_1;
                x.scroll(delta, AxisBase2D_1.EClipMode.None);
            });
        }
        this.pointFrom = pointTo;
    };
    XAxisDragModifier.prototype.doScaling = function (pointTo) {
        var _this = this;
        if (this.isVerticalChart) {
            this.activeAxes.forEach(function (axis, index) {
                var axisViewRect = axis.viewRect;
                var yFromTrans = (0, translate_1.translateFromCanvasToSeriesViewRectY)(_this.pointFrom.y, axisViewRect);
                var isMoreThanHalf = yFromTrans >= axisViewRect.height / 2;
                var yDelta = (pointTo.y - _this.pointFrom.y) / axisViewRect.height;
                axis.scale(_this.initialVisibleRanges[index], yDelta, isMoreThanHalf);
            });
        }
        else {
            this.activeAxes.forEach(function (axis, index) {
                var axisViewRect = axis.viewRect;
                var xFromTrans = (0, translate_1.translateFromCanvasToSeriesViewRectX)(_this.pointFrom.x, axisViewRect);
                var isMoreThanHalf = xFromTrans >= axisViewRect.width / 2;
                var xDelta = (pointTo.x - _this.pointFrom.x) / axisViewRect.width;
                axis.scale(_this.initialVisibleRanges[index], xDelta, isMoreThanHalf);
            });
        }
    };
    XAxisDragModifier.prototype.getHorizontalXAxes = function () {
        return this.getIncludedXAxis().filter(function (el) { return el.isHorizontalAxis; });
    };
    XAxisDragModifier.prototype.getVerticalXAxes = function () {
        return this.getIncludedXAxis().filter(function (el) { return !el.isHorizontalAxis; });
    };
    XAxisDragModifier.prototype.startDragging = function (axes, args) {
        this.isClickedOverXAxis = true;
        var activeAxes = (0, ChartModifierBase2D_1.getActiveAxes)(axes, args.mousePoint);
        var initialVisibleRanges = [];
        activeAxes.forEach(function (el) {
            initialVisibleRanges.push(el.visibleRange);
        });
        this.activeAxes = activeAxes;
        this.initialVisibleRanges = initialVisibleRanges;
        this.pointFrom = args.mousePoint;
        args.handled = true;
    };
    return XAxisDragModifier;
}(PinchZoomModifier_1.PinchZoomModifier));
exports.XAxisDragModifier = XAxisDragModifier;
