"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.DomAnnotationBase = void 0;
var Point_1 = require("../../../Core/Point");
var AnchorPoint_1 = require("../../../types/AnchorPoint");
var AnnotationClippingMode_1 = require("../../../types/AnnotationClippingMode");
var pointUtil_1 = require("../../../utils/pointUtil");
var translate_1 = require("../../../utils/translate");
var SciChartDefaults_1 = require("../SciChartDefaults");
var DpiHelper_1 = require("../TextureManager/DpiHelper");
var AnnotationBase_1 = require("./AnnotationBase");
var annotationHelpers_1 = require("./annotationHelpers");
var constants_1 = require("./constants");
var DomAnnotationBase = /** @class */ (function (_super) {
    __extends(DomAnnotationBase, _super);
    /**
     * Creates an instance of an HtmlAnnotation
     * @param options Optional parameters of type {@link IHtmlCustomAnnotationOptions} used to configure the annotation on construction
     */
    function DomAnnotationBase(options) {
        var _this = this;
        var _a, _b, _c, _d, _e;
        _this = _super.call(this, options) || this;
        _this.isDomAnnotation = true;
        _this.isDeleted = false;
        _this.xCoordShiftProperty = 0;
        _this.yCoordShiftProperty = 0;
        _this.verticalAnchorPointProperty = AnchorPoint_1.EVerticalAnchorPoint.Top;
        _this.horizontalAnchorPointProperty = AnchorPoint_1.EHorizontalAnchorPoint.Left;
        _this.prevX1Coordinate = 0;
        _this.prevY1Coordinate = 0;
        _this.xCoordSvgTransProperty = 0;
        _this.yCoordSvgTransProperty = 0;
        _this.reDrawChartOnChange = false;
        _this.xCoordShiftProperty = (_a = options === null || options === void 0 ? void 0 : options.xCoordShift) !== null && _a !== void 0 ? _a : _this.xCoordShiftProperty;
        _this.yCoordShiftProperty = (_b = options === null || options === void 0 ? void 0 : options.yCoordShift) !== null && _b !== void 0 ? _b : _this.yCoordShiftProperty;
        _this.verticalAnchorPointProperty = (_c = options === null || options === void 0 ? void 0 : options.verticalAnchorPoint) !== null && _c !== void 0 ? _c : _this.verticalAnchorPointProperty;
        _this.horizontalAnchorPointProperty = (_d = options === null || options === void 0 ? void 0 : options.horizontalAnchorPoint) !== null && _d !== void 0 ? _d : _this.horizontalAnchorPointProperty;
        _this.reDrawChartOnChange = (_e = options === null || options === void 0 ? void 0 : options.reDrawChartOnChange) !== null && _e !== void 0 ? _e : SciChartDefaults_1.SciChartDefaults.alwaysRedrawFullChartOnSvgChange;
        return _this;
    }
    DomAnnotationBase.prototype.onAttach = function (scs) {
        _super.prototype.onAttach.call(this, scs);
        this.selectLayerRoot();
    };
    Object.defineProperty(DomAnnotationBase.prototype, "xCoordShift", {
        /**
         * Gets or sets an offset to shift X-coordinates
         */
        get: function () {
            return this.xCoordShiftProperty;
        },
        /**
         * Gets or sets an offset to shift X-coordinates
         */
        set: function (value) {
            if (this.xCoordShiftProperty !== value) {
                this.xCoordShiftProperty = value;
                this.notifyPropertyChanged(constants_1.PROPERTY.X_COORD_SHIFT);
            }
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(DomAnnotationBase.prototype, "yCoordShift", {
        /**
         * Gets or sets an offset to shift Y-coordinates
         */
        get: function () {
            return this.yCoordShiftProperty;
        },
        /**
         * Gets or sets an offset to shift Y-coordinates
         */
        set: function (value) {
            if (this.yCoordShiftProperty !== value) {
                this.yCoordShiftProperty = value;
                this.notifyPropertyChanged(constants_1.PROPERTY.Y_COORD_SHIFT);
            }
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(DomAnnotationBase.prototype, "verticalAnchorPoint", {
        /**
         * Gets or sets vertical anchor point
         */
        get: function () {
            return this.verticalAnchorPointProperty;
        },
        /**
         * Gets or sets vertical anchor point
         */
        set: function (value) {
            if (this.verticalAnchorPointProperty !== value) {
                this.verticalAnchorPointProperty = value;
                this.notifyPropertyChanged(constants_1.PROPERTY.VERTICAL_ANCHOR_POINT);
            }
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(DomAnnotationBase.prototype, "horizontalAnchorPoint", {
        /**
         * Gets or sets horizontal anchor point
         */
        get: function () {
            return this.horizontalAnchorPointProperty;
        },
        /**
         * Gets or sets horizontal anchor point
         */
        set: function (value) {
            if (this.horizontalAnchorPointProperty !== value) {
                this.horizontalAnchorPointProperty = value;
                this.notifyPropertyChanged(constants_1.PROPERTY.HORIZONTAL_ANCHOR_POINT);
            }
        },
        enumerable: false,
        configurable: true
    });
    DomAnnotationBase.prototype.suspendInvalidate = function () {
        _super.prototype.suspendInvalidate.call(this);
        //@ts-ignore
        this.invalidateState.xCoordShift = this.xCoordShift;
        //@ts-ignore
        this.invalidateState.yCoordShift = this.yCoordShift;
    };
    DomAnnotationBase.prototype.resumeInvalidate = function () {
        if (!this.invalidateState)
            return;
        if (this.isHidden !== this.invalidateState.isHidden ||
            this.x1 !== this.invalidateState.x1 ||
            this.y1 !== this.invalidateState.y1 ||
            //@ts-ignore
            this.xCoordShift !== this.invalidateState.xCoordShift ||
            //@ts-ignore
            this.yCoordShift !== this.invalidateState.yCoordShift) {
            if (this.invalidateParentCallback) {
                this.invalidateParentCallback({ svgOnly: !this.reDrawChartOnChange });
            }
        }
        this.invalidateState = undefined;
        _super.prototype.resumeInvalidate.call(this);
    };
    DomAnnotationBase.prototype.calcDragDistance = function (xyValues) {
        if (!this.prevValue) {
            this.prevValue = xyValues;
            return;
        }
        if (this.adornerDraggingPoint === AnnotationBase_1.EDraggingGripPoint.Body ||
            this.adornerDraggingPoint === AnnotationBase_1.EDraggingGripPoint.x1y1) {
            var x1 = this.x1 + this.applyPixelRatioToDragDist(xyValues.x - this.prevValue.x);
            var y1 = this.y1 + xyValues.y - this.prevValue.y;
            if (this.x2 !== undefined) {
                this.x2 = this.x2 + this.applyPixelRatioToDragDist(xyValues.x - this.prevValue.x);
            }
            if (this.y2 !== undefined) {
                this.y2 = this.y2 + xyValues.y - this.prevValue.y;
            }
            // fix for polar (0,0)
            if (this.parentSurface.isPolar && this.x1 === 0 && this.y1 === 0) {
                x1 = xyValues.x;
                y1 = xyValues.y;
            }
            this.x1 = x1;
            this.y1 = y1;
        }
        this.prevValue = xyValues;
    };
    /**
     * Gets the annotation borders in real, pixel coordinates relative to the master html element containing the surface.
     * @example
     * // Say we have a data-value of "15" on the chart's xAxis.
     * // Step 1: We calculate the screen coordinate of it via the coordinateCalculator (or take it from our stored annotationBorders property),
     * // Step 2: Multiply that value by DpiHelper.PIXEL_RATIO
     * // Step 3: Add the already-scaled {xCoordSvgTrans} value to get the real coordinate on the SVG canvas.
     *
     * @note This process is done for all 4 borders x1, x2, y1, y2.
     */
    DomAnnotationBase.prototype.getAnnotationBorders = function (ordered, notScaled) {
        var _a = _super.prototype.getAnnotationBorders.call(this, ordered, notScaled), x1 = _a.x1, x2 = _a.x2, y1 = _a.y1, y2 = _a.y2;
        return {
            x1: x1 + this.xCoordSvgTransProperty,
            x2: x2 + this.xCoordSvgTransProperty,
            y1: y1 + this.yCoordSvgTransProperty,
            y2: y2 + this.yCoordSvgTransProperty
        };
    };
    /**
     * Returns annotation borders for the {@link AdornerLayer} which has the size of the whole canvas
     * @param ordered flag to return x and y values in ascending order
     */
    DomAnnotationBase.prototype.getAdornerAnnotationBorders = function (ordered) {
        var _a = _super.prototype.getAdornerAnnotationBorders.call(this, ordered), x1 = _a.x1, x2 = _a.x2, y1 = _a.y1, y2 = _a.y2;
        return {
            x1: x1 + this.xCoordSvgTransProperty,
            x2: x2 + this.xCoordSvgTransProperty,
            y1: y1 + this.yCoordSvgTransProperty,
            y2: y2 + this.yCoordSvgTransProperty
        };
    };
    DomAnnotationBase.prototype.onDragStarted = function (args) {
        _super.prototype.onDragStarted.call(this, args);
        var _a = this.getAnnotationBorders(), x1 = _a.x1, x2 = _a.x2, y1 = _a.y1, y2 = _a.y2;
        var xyCoord1 = new Point_1.Point(x1, y1);
        var circleCenterX = x1;
        var circleCenterY = y1;
        var height = Math.abs((y1 - y2) / 2);
        var width = Math.abs((x1 - x2) / 2);
        if (this.verticalAnchorPoint === AnchorPoint_1.EVerticalAnchorPoint.Center) {
            circleCenterY = circleCenterY + height;
        }
        if (this.horizontalAnchorPoint === AnchorPoint_1.EHorizontalAnchorPoint.Center) {
            circleCenterX = circleCenterX + width;
        }
        var xyMousePoint = (0, translate_1.translateFromCanvasToSeriesViewRect)(new Point_1.Point(args.mousePoint.x, args.mousePoint.y), this.parentSurface.seriesViewRect, this.clipping !== AnnotationClippingMode_1.EAnnotationClippingMode.SeriesViewRect);
        if (!xyMousePoint) {
            return false;
        }
        if (xyCoord1 && this.canDragPoint(AnnotationBase_1.EDraggingGripPoint.x1y1)) {
            var dist = (0, pointUtil_1.calcDistance)(circleCenterX, circleCenterY, (0, translate_1.translateToNotScaled)(xyMousePoint.x), (0, translate_1.translateToNotScaled)(xyMousePoint.y));
            if (dist < this.annotationsGripsRadius) {
                this.adornerDraggingPoint = AnnotationBase_1.EDraggingGripPoint.x1y1;
                return true;
            }
        }
        if (this.canDragPoint(AnnotationBase_1.EDraggingGripPoint.Body) && this.clickToSelect(args)) {
            this.adornerDraggingPoint = AnnotationBase_1.EDraggingGripPoint.Body;
            return true;
        }
        return false;
    };
    /** @inheritDoc */
    DomAnnotationBase.prototype.delete = function () {
        this.isDeleted = true;
    };
    DomAnnotationBase.prototype.toJSON = function () {
        var json = _super.prototype.toJSON.call(this);
        var options = {
            xCoordShift: this.xCoordShift,
            yCoordShift: this.yCoordShift,
            verticalAnchorPoint: this.verticalAnchorPoint,
            horizontalAnchorPoint: this.horizontalAnchorPoint,
            reDrawChartOnChange: this.reDrawChartOnChange
        };
        Object.assign(json.options, options);
        return json;
    };
    DomAnnotationBase.prototype.checkIsClickedOnAnnotationInternal = function (x, y) {
        var _a = this.getAnnotationBorders(true), x1 = _a.x1, x2 = _a.x2, y1 = _a.y1, y2 = _a.y2;
        // For SVG annotations we need to use not scaled coordinates
        var notScaledX = x / DpiHelper_1.DpiHelper.PIXEL_RATIO + this.xCoordSvgTransProperty;
        var notScaledY = y / DpiHelper_1.DpiHelper.PIXEL_RATIO + this.yCoordSvgTransProperty;
        return (0, pointUtil_1.testIsInBounds)(notScaledX, notScaledY, x1, y2, x2, y1);
    };
    DomAnnotationBase.prototype.updateAdornerInner = function () {
        this.deleteAdorner();
        if (this.isSelected) {
            var _a = this.getAnnotationBorders(true), x1 = _a.x1, x2 = _a.x2, y1 = _a.y1, y2 = _a.y2;
            var svgString = this.svgStringAdornerTemplate(x1, y1, x2, y2);
            var clippedSvgString = this.applySvgClipping(svgString, this.adornerClipping);
            this.svgAdorner = annotationHelpers_1.annotationHelpers.createSvg(clippedSvgString, this.svgAdornerRoot);
        }
    };
    DomAnnotationBase.prototype.notifyPropertyChanged = function (propertyName) {
        if (propertyName === constants_1.PROPERTY.ANNOTATION_CANVAS) {
            this.selectLayerRoot();
        }
        if (this.invalidateParentCallback && !this.invalidateState) {
            this.invalidateParentCallback({ svgOnly: !this.reDrawChartOnChange });
        }
    };
    /**
     * Calculates and sets annotationBorders
     * @protected
     */
    DomAnnotationBase.prototype.calcAndSetAnnotationBorders = function (xCalc, yCalc) {
        var size = this.getSize();
        // check whether the underlying DOM element exists
        if (!size)
            return;
        var width = size.width, height = size.height;
        var _a = this.convertPolarToCartesian(this.getX1Coordinate(xCalc, yCalc), this.getY1Coordinate(xCalc, yCalc), true), x1Cartesian = _a.x, y1Cartesian = _a.y;
        var _b = this.convertPolarToCartesian(this.getX2Coordinate(xCalc, yCalc), this.getY2Coordinate(xCalc, yCalc), true), x2Cartesian = _b.x, y2Cartesian = _b.y;
        var borderX1 = x1Cartesian + this.xCoordShift;
        var borderY1 = y1Cartesian + this.yCoordShift;
        var borderX2 = borderX1 + width;
        var borderY2 = borderY1 + height;
        // TODO flipped
        if (this.isVerticalChart ? this.y2 === undefined : this.x2 === undefined) {
            var _c = calculateHorizontalAnchor(this.horizontalAnchorPoint, borderX1, borderX2, width), x1 = _c.x1, x2 = _c.x2;
            borderX1 = x1;
            borderX2 = x2;
        }
        else {
            borderX2 = x2Cartesian + this.xCoordShift;
        }
        if (this.isVerticalChart ? this.x2 === undefined : this.y2 === undefined) {
            var _d = calculateVerticalAnchor(this.verticalAnchorPoint, borderY1, borderY2, height), y1 = _d.y1, y2 = _d.y2;
            borderY1 = y1;
            borderY2 = y2;
        }
        else {
            borderY2 = y2Cartesian + this.yCoordShift;
        }
        this.setAnnotationBorders(borderX1, borderX2, borderY1, borderY2);
    };
    DomAnnotationBase.prototype.svgStringAdornerTemplate = function (x1, y1, x2, y2) {
        var circleCenterX = x1;
        var circleCenterY = y1;
        var height = Math.abs((y1 - y2) / 2);
        var width = Math.abs((x1 - x2) / 2);
        if (this.verticalAnchorPoint === AnchorPoint_1.EVerticalAnchorPoint.Center) {
            circleCenterY = circleCenterY + height;
        }
        if (this.horizontalAnchorPoint === AnchorPoint_1.EHorizontalAnchorPoint.Center) {
            circleCenterX = circleCenterX + width;
        }
        return "<svg xmlns=\"http://www.w3.org/2000/svg\">\n        <rect x=\"".concat(x1, "\" y=\"").concat(y1, "\" width=\"").concat(Math.abs(x1 - x2), "\" height=\"").concat(Math.abs(y1 - y2), "\" stroke=\"").concat(this.selectionBoxStroke, "\" stroke-width=\"").concat(this.selectionBoxThickness, "px\" fill=\"none\" />\n        ").concat(this.canDragPoint(AnnotationBase_1.EDraggingGripPoint.x1y1) ? this.getAnnotationGripSvg(circleCenterX, circleCenterY) : "", "\n      </svg>");
    };
    return DomAnnotationBase;
}(AnnotationBase_1.AnnotationBase));
exports.DomAnnotationBase = DomAnnotationBase;
function calculateVerticalAnchor(anchorPoint, y1, y2, height) {
    if (anchorPoint === AnchorPoint_1.EVerticalAnchorPoint.Bottom) {
        y2 = y1 - height;
    }
    if (anchorPoint === AnchorPoint_1.EVerticalAnchorPoint.Center) {
        y2 = y1 + height / 2;
        y1 = y1 - height / 2;
    }
    return { y1: y1, y2: y2 };
}
function calculateHorizontalAnchor(anchorPoint, x1, x2, width) {
    if (anchorPoint === AnchorPoint_1.EHorizontalAnchorPoint.Right) {
        x2 = x1 - width;
        return { x1: x2, x2: x1 };
    }
    if (anchorPoint === AnchorPoint_1.EHorizontalAnchorPoint.Center) {
        x2 = x1 + width / 2;
        x1 = x1 - width / 2;
    }
    return { x1: x1, x2: x2 };
}
