"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 __());
    };
})();
var __assign = (this && this.__assign) || function () {
    __assign = Object.assign || function(t) {
        for (var s, i = 1, n = arguments.length; i < n; i++) {
            s = arguments[i];
            for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
                t[p] = s[p];
        }
        return t;
    };
    return __assign.apply(this, arguments);
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.PolarPointerAnnotation = void 0;
var AnchorPoint_1 = require("../../../types/AnchorPoint");
var StrokeLineJoin_1 = require("../../../types/PolarPointerAnnotation/StrokeLineJoin");
var SurfaceType_1 = require("../../../types/SurfaceType");
var DpiHelper_1 = require("../TextureManager/DpiHelper");
var ECoordinateMode_1 = require("./types/ECoordinateMode");
var annotationHelpers_1 = require("./annotationHelpers");
var constants_1 = require("./constants");
var EAnnotationType_1 = require("./types/EAnnotationType");
var SvgAnnotationBase_1 = require("./SvgAnnotationBase");
/**
 * A PolarPointerAnnotation presents an SVG pointer over the chart at 0, 0 coordinates
 */
var PolarPointerAnnotation = /** @class */ (function (_super) {
    __extends(PolarPointerAnnotation, _super);
    /**
     * Creates an instance of the {@link PolarPointerAnnotation}
     * @param options The {@link IPolarPointerAnnotationOptions} which contain optional parameters
     */
    function PolarPointerAnnotation(options) {
        var _this = this;
        var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2, _3, _4, _5, _6, _7;
        _this = _super.call(this, options) || this;
        /** @inheritDoc */
        _this.type = EAnnotationType_1.EAnnotationType.SVGPolarPointerAnnotation;
        /** @inheritDoc */
        _this.surfaceTypes = [SurfaceType_1.ESurfaceType.SciChartPolarSurfaceType];
        _this.isDirty = true;
        _this.isStrokeAboveCenterProperty = false;
        _this.strokeLineJoinProperty = StrokeLineJoin_1.EStrokeLineJoin.Miter;
        _this.getPointerStyleProxy = function (newStyle) {
            return new Proxy(newStyle, {
                set: function (target, key, value) {
                    //@ts-ignore
                    target[key] = value;
                    _this.isDirty = true;
                    _this.notifyPropertyChanged("pointerStyle");
                    return true;
                }
            });
        };
        _this.getPointerCenterStyleProxy = function (newStyle) {
            return new Proxy(newStyle, {
                set: function (target, key, value) {
                    //@ts-ignore
                    target[key] = value;
                    _this.isDirty = true;
                    _this.notifyPropertyChanged("pointerCenterStyle");
                    return true;
                }
            });
        };
        _this.getPointerArrowStyleProxy = function (newStyle) {
            return new Proxy(newStyle, {
                set: function (target, key, value) {
                    //@ts-ignore
                    target[key] = value;
                    _this.isDirty = true;
                    _this.notifyPropertyChanged("pointerArrowStyle");
                    return true;
                }
            });
        };
        _this.strokeLineJoinProperty = (_a = options === null || options === void 0 ? void 0 : options.strokeLineJoin) !== null && _a !== void 0 ? _a : _this.strokeLineJoinProperty;
        _this.isStrokeAboveCenterProperty = (_b = options === null || options === void 0 ? void 0 : options.isStrokeAboveCenter) !== null && _b !== void 0 ? _b : _this.isStrokeAboveCenterProperty;
        _this.pointerStyleProperty = _this.getPointerStyleProxy({
            baseSize: (_d = (_c = options === null || options === void 0 ? void 0 : options.pointerStyle) === null || _c === void 0 ? void 0 : _c.baseSize) !== null && _d !== void 0 ? _d : 0.1,
            stroke: (_f = (_e = options === null || options === void 0 ? void 0 : options.pointerStyle) === null || _e === void 0 ? void 0 : _e.stroke) !== null && _f !== void 0 ? _f : "black",
            strokeWidth: (_h = (_g = options === null || options === void 0 ? void 0 : options.pointerStyle) === null || _g === void 0 ? void 0 : _g.strokeWidth) !== null && _h !== void 0 ? _h : 3,
            fill: (_k = (_j = options === null || options === void 0 ? void 0 : options.pointerStyle) === null || _j === void 0 ? void 0 : _j.fill) !== null && _k !== void 0 ? _k : "gray",
            backExtensionSize: (_m = (_l = options === null || options === void 0 ? void 0 : options.pointerStyle) === null || _l === void 0 ? void 0 : _l.backExtensionSize) !== null && _m !== void 0 ? _m : 0
        });
        _this.pointerCenterStyleProperty = _this.getPointerCenterStyleProxy({
            size: (_p = (_o = options === null || options === void 0 ? void 0 : options.pointerCenterStyle) === null || _o === void 0 ? void 0 : _o.size) !== null && _p !== void 0 ? _p : 0,
            stroke: (_r = (_q = options === null || options === void 0 ? void 0 : options.pointerCenterStyle) === null || _q === void 0 ? void 0 : _q.stroke) !== null && _r !== void 0 ? _r : "black",
            strokeWidth: (_t = (_s = options === null || options === void 0 ? void 0 : options.pointerCenterStyle) === null || _s === void 0 ? void 0 : _s.strokeWidth) !== null && _t !== void 0 ? _t : 3,
            fill: (_v = (_u = options === null || options === void 0 ? void 0 : options.pointerCenterStyle) === null || _u === void 0 ? void 0 : _u.fill) !== null && _v !== void 0 ? _v : "gray"
        });
        _this.pointerArrowStyleProperty = _this.getPointerArrowStyleProxy({
            height: (_x = (_w = options === null || options === void 0 ? void 0 : options.pointerArrowStyle) === null || _w === void 0 ? void 0 : _w.height) !== null && _x !== void 0 ? _x : 0,
            width: (_z = (_y = options === null || options === void 0 ? void 0 : options.pointerArrowStyle) === null || _y === void 0 ? void 0 : _y.width) !== null && _z !== void 0 ? _z : 0,
            headDepth: (_1 = (_0 = options === null || options === void 0 ? void 0 : options.pointerArrowStyle) === null || _0 === void 0 ? void 0 : _0.headDepth) !== null && _1 !== void 0 ? _1 : 1,
            stroke: (_3 = (_2 = options === null || options === void 0 ? void 0 : options.pointerArrowStyle) === null || _2 === void 0 ? void 0 : _2.stroke) !== null && _3 !== void 0 ? _3 : "black",
            strokeWidth: (_5 = (_4 = options === null || options === void 0 ? void 0 : options.pointerArrowStyle) === null || _4 === void 0 ? void 0 : _4.strokeWidth) !== null && _5 !== void 0 ? _5 : 3,
            fill: (_7 = (_6 = options === null || options === void 0 ? void 0 : options.pointerArrowStyle) === null || _6 === void 0 ? void 0 : _6.fill) !== null && _7 !== void 0 ? _7 : "none"
        });
        return _this;
    }
    Object.defineProperty(PolarPointerAnnotation.prototype, "pointerStyle", {
        /**
         * Gets or sets the style of the pointer center circle as a {@link TPointerStyle} object
         * To customise the pointer fully, override getPointerStickSvg
         */
        get: function () {
            return this.pointerStyleProperty;
        },
        set: function (value) {
            var newStyle = __assign(__assign({}, this.pointerStyle), value);
            this.pointerStyleProperty = this.getPointerStyleProxy(newStyle);
            this.isDirty = true;
            this.notifyPropertyChanged("pointerStyle");
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(PolarPointerAnnotation.prototype, "pointerCenterStyle", {
        /**
         * Gets or sets the style of the pointer center circle as a {@link TPointerStyle} object
         * To customise the pointer center fully, override getPointerCenterSvg
         */
        get: function () {
            return this.pointerCenterStyleProperty;
        },
        set: function (value) {
            var newStyle = __assign(__assign({}, this.pointerCenterStyle), value);
            this.pointerCenterStyleProperty = this.getPointerCenterStyleProxy(newStyle);
            this.isDirty = true;
            this.notifyPropertyChanged("pointerCenterStyle");
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(PolarPointerAnnotation.prototype, "pointerArrowStyle", {
        /**
         * Gets or sets the style of the pointer arrow as a {@link TPointerArrowStyle} object
         * To customise the pointer arrow fully, override getPointerArrowSvg
         */
        get: function () {
            return this.pointerArrowStyleProperty;
        },
        set: function (value) {
            var newStyle = __assign(__assign({}, this.pointerArrowStyle), value);
            this.pointerArrowStyleProperty = this.getPointerArrowStyleProxy(newStyle);
            this.isDirty = true;
            this.notifyPropertyChanged("pointerArrowStyle");
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(PolarPointerAnnotation.prototype, "horizontalAnchorPoint", {
        get: function () {
            return AnchorPoint_1.EHorizontalAnchorPoint.Center;
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(PolarPointerAnnotation.prototype, "verticalAnchorPoint", {
        get: function () {
            return AnchorPoint_1.EVerticalAnchorPoint.Center;
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(PolarPointerAnnotation.prototype, "isStrokeAboveCenter", {
        /**
         * Whether the pointer stick should be above or below the center circle
         */
        get: function () {
            return this.isStrokeAboveCenterProperty;
        },
        set: function (value) {
            if (this.isStrokeAboveCenterProperty !== value) {
                this.isStrokeAboveCenterProperty = value;
                this.isDirty = true;
                this.notifyPropertyChanged("isStrokeAboveCenter");
            }
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(PolarPointerAnnotation.prototype, "strokeLineJoin", {
        /**
         * @description The SVG stroke-linejoin attribute specifies the shape to be used at the corners of paths or basic shapes when they are stroked.
         * @link https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/stroke-linejoin
         */
        get: function () {
            return this.strokeLineJoinProperty;
        },
        set: function (value) {
            if (this.strokeLineJoinProperty !== value) {
                this.strokeLineJoinProperty = value;
                this.isDirty = true;
                this.notifyPropertyChanged("strokeLineJoin");
            }
        },
        enumerable: false,
        configurable: true
    });
    PolarPointerAnnotation.prototype.getAngularAxis = function () {
        var xAxis = this.xAxis;
        var yAxis = this.yAxis;
        return xAxis.isAngular ? xAxis : yAxis;
    };
    PolarPointerAnnotation.prototype.getRadialAxis = function () {
        var xAxis = this.xAxis;
        var yAxis = this.yAxis;
        return xAxis.isAngular ? yAxis : xAxis;
    };
    /** This is called to get the svg string to use. Override this to customise the svg string for each render */
    PolarPointerAnnotation.prototype.getSvgString = function (annotation) {
        var angularAxis = this.getAngularAxis();
        var radialAxis = this.getRadialAxis();
        var _a = this.getState(), axisSize = _a.axisSize, startAngle = _a.startAngle, direction = _a.direction;
        var pointerLength;
        if (this.yCoordinateMode === ECoordinateMode_1.ECoordinateMode.Relative) {
            pointerLength = this.y1 * axisSize;
        }
        else if (this.yCoordinateMode === ECoordinateMode_1.ECoordinateMode.DataValue) {
            pointerLength = radialAxis.getCurrentCoordinateCalculator().getCoordinate(this.y1) / DpiHelper_1.DpiHelper.PIXEL_RATIO;
        }
        else {
            pointerLength = this.y1;
        }
        var rotationRadian;
        if (this.xCoordinateMode === ECoordinateMode_1.ECoordinateMode.DataValue) {
            rotationRadian = startAngle + angularAxis.getCurrentCoordinateCalculator().getCoordinate(this.x1);
        }
        else {
            rotationRadian = startAngle + direction * this.x1;
        }
        var scs = this.parentSurface;
        var centerPoint = annotationHelpers_1.annotationHelpers.convertPolarToCartesian(angularAxis, true, scs.webAssemblyContext2D, ECoordinateMode_1.ECoordinateMode.DataValue, 0, 0);
        this.state = { axisSize: axisSize, startAngle: startAngle, direction: direction, seriesViewRect: scs.seriesViewRect };
        var rotationDegrees = -(180 * rotationRadian) / Math.PI;
        var pointerWidth = this.pointerStyleProperty.baseSize * pointerLength;
        var centerSize = this.pointerCenterStyleProperty.size * pointerLength;
        var arrowHeight = this.pointerArrowStyleProperty.height * pointerLength;
        var arrowWidth = this.pointerArrowStyleProperty.width * pointerLength;
        var pointerStickSvg = this.getPointerStickSvg(pointerLength, pointerWidth, this.pointerStyleProperty.backExtensionSize);
        var pointerCenterSvg = this.getPointerCenterSvg(pointerLength, centerSize);
        var pointerArrowSvg = this.getPointerArrowSvg(pointerLength, arrowHeight, arrowWidth, this.pointerArrowStyleProperty.headDepth);
        var resSvg = this.isStrokeAboveCenterProperty
            ? pointerCenterSvg + pointerStickSvg + pointerArrowSvg
            : pointerStickSvg + pointerArrowSvg + pointerCenterSvg;
        var xTranslate = centerPoint.x + scs.seriesViewRect.left / DpiHelper_1.DpiHelper.PIXEL_RATIO - pointerLength;
        var yTranslate = centerPoint.y + scs.seriesViewRect.top / DpiHelper_1.DpiHelper.PIXEL_RATIO - pointerLength;
        var _b = scs.viewRect, rawWidth = _b.width, rawHeight = _b.height;
        var width = rawWidth / DpiHelper_1.DpiHelper.PIXEL_RATIO;
        var height = rawHeight / DpiHelper_1.DpiHelper.PIXEL_RATIO;
        var svgStr = "<svg height=\"".concat(height, "\" width=\"").concat(width, "\" viewBox=\"0 0 ").concat(width, " ").concat(height, "\">\n            <g id=\"pointer\" style=\"padding:100;\" transform=\"translate(").concat(xTranslate, " ").concat(yTranslate, ") rotate(").concat(rotationDegrees, " ").concat(pointerLength, " ").concat(pointerLength, ")\">\n                ").concat(resSvg, "\n            </g>\n        </svg>");
        return svgStr;
    };
    PolarPointerAnnotation.prototype.getPointerStickSvg = function (pointerLength, pointerWidth, backExtensionSize) {
        var _a;
        var size = pointerLength * 2;
        var halfStrokeWidth = Math.max((_a = this.pointerStyle.strokeWidth) !== null && _a !== void 0 ? _a : 1.5, 0);
        return "<path stroke-linejoin=".concat(this.strokeLineJoinProperty, "\n            d=\"\n                M").concat(size - halfStrokeWidth, " ").concat(pointerLength, "\n                L").concat(pointerLength - pointerLength * backExtensionSize, " ").concat(pointerLength - pointerWidth / 2, "\n                l0 ").concat(pointerWidth, "\n                L").concat(size - halfStrokeWidth, " ").concat(pointerLength, "Z\n            \" \n            fill=\"").concat(this.pointerStyleProperty.fill, "\"\n            stroke=\"").concat(this.pointerStyleProperty.stroke, "\"  \n            stroke-width=\"").concat(this.pointerStyleProperty.strokeWidth, "\"\n        />");
    };
    PolarPointerAnnotation.prototype.getPointerCenterSvg = function (pointerLength, centerSize) {
        return "<rect\n            x=\"".concat(pointerLength - centerSize / 2, "\" \n            y=\"").concat(pointerLength - centerSize / 2, "\"\n            width=").concat(centerSize, " \n            height=").concat(centerSize, "\n            rx=").concat(centerSize / 2, "\n            ry=").concat(centerSize / 2, "\n            stroke=").concat(this.pointerCenterStyleProperty.stroke, "\n            stroke-width=").concat(this.pointerCenterStyleProperty.strokeWidth, "\n            fill=").concat(this.pointerCenterStyleProperty.fill, "\n        />");
    };
    PolarPointerAnnotation.prototype.getPointerArrowSvg = function (pointerLength, height, width, headDepth) {
        var _a;
        var size = 2 * pointerLength;
        var halfStrokeWidth = Math.max((_a = this.pointerArrowStyleProperty.strokeWidth) !== null && _a !== void 0 ? _a : 1.5, 0);
        return "<path \n            stroke=\"".concat(this.pointerArrowStyleProperty.stroke, "\"\n            stroke-width=\"").concat(this.pointerArrowStyleProperty.strokeWidth, "\"\n            fill=\"").concat(this.pointerArrowStyleProperty.fill, "\"\n            stroke-linejoin=").concat(this.strokeLineJoinProperty, "\n            d=\"\n                M").concat(size - height / 2 - halfStrokeWidth, " ").concat(pointerLength - width / 2, "\n                l").concat(height / 2, " ").concat(width / 2, "\n                l-").concat(height / 2, " ").concat(width / 2, "\n                ").concat(headDepth === 0
            ? ""
            : "\n                    l".concat(((1 - headDepth) * height) / 2, " ").concat(-width / 2, "\n                    l").concat((-(1 - headDepth) * height) / 2, " ").concat(-width / 2, "Z\n                "), "\n            \" \n        />");
        // The `-5` from above line is to account for SVG line-join going outside the bounds
    };
    PolarPointerAnnotation.prototype.notifyPropertyChanged = function (propertyName) {
        if (propertyName === constants_1.PROPERTY.X_COORDINATE_MODE ||
            propertyName === constants_1.PROPERTY.Y_COORDINATE_MODE ||
            propertyName === constants_1.PROPERTY.X1 ||
            propertyName === constants_1.PROPERTY.Y1) {
            this.isDirty = true;
        }
        _super.prototype.notifyPropertyChanged.call(this, propertyName);
    };
    /** @inheritDoc */
    PolarPointerAnnotation.prototype.toJSON = function () {
        var json = _super.prototype.toJSON.call(this);
        var options = {
            isStrokeAboveCenter: this.isStrokeAboveCenter,
            pointerArrowStyle: this.pointerArrowStyle,
            pointerCenterStyle: this.pointerCenterStyle,
            pointerStyle: this.pointerStyle,
            strokeLineJoin: this.strokeLineJoin
        };
        Object.assign(json.options, options);
        return json;
    };
    /** @inheritDoc */
    PolarPointerAnnotation.prototype.getX1Coordinate = function (xCalc, yCalc) {
        return 0;
    };
    /** @inheritDoc */
    PolarPointerAnnotation.prototype.getY1Coordinate = function (xCalc, yCalc) {
        return 0;
    };
    PolarPointerAnnotation.prototype.getState = function () {
        var angularAxis = this.getAngularAxis();
        var radialAxis = this.getRadialAxis();
        // Adjust this for Inner radius
        var axisSize = radialAxis.getAxisSize(); // DpiHelper.PIXEL_RATIO;
        var direction = angularAxis.flippedCoordinates ? -1 : 1;
        var startAngle = angularAxis.startAngle;
        var seriesViewRect = this.parentSurface.seriesViewRect;
        return { axisSize: axisSize, startAngle: startAngle, direction: direction, seriesViewRect: seriesViewRect };
    };
    /** @inheritDoc */
    PolarPointerAnnotation.prototype.create = function (xCalc, yCalc, xCoordSvgTrans, yCoordSvgTrans) {
        var _a = this.getState(), axisSize = _a.axisSize, startAngle = _a.startAngle, direction = _a.direction, seriesViewRect = _a.seriesViewRect;
        if (!this.state ||
            axisSize !== this.state.axisSize ||
            startAngle !== this.state.startAngle ||
            direction !== this.state.direction ||
            seriesViewRect !== this.state.seriesViewRect) {
            this.isDirty = true;
        }
        if (this.svg && !this.isEditable && !this.isDirty) {
            this.calcAndSetAnnotationBorders(xCalc, yCalc);
            return;
        }
        if (this.isDirty || !this.svg || (this.svg && this.isSelected)) {
            if (this.svg) {
                this.clear();
            }
            var svg = annotationHelpers_1.annotationHelpers.createSvg(this.getSvgString(this), this.svgRoot, this.nextSibling);
            this.setSvg(svg);
            this.calcAndSetAnnotationBorders(xCalc, yCalc);
            this.updateAdornerInner();
            this.prevIsSelected = this.isSelected;
            this.isDirty = false;
        }
        else {
            this.calcAndSetAnnotationBorders(xCalc, yCalc);
        }
        if (this.prevIsSelected !== this.isSelected && this.svg && this.isEditable) {
            this.updateAdornerInner();
            this.prevIsSelected = this.isSelected;
        }
    };
    return PolarPointerAnnotation;
}(SvgAnnotationBase_1.SvgAnnotationBase));
exports.PolarPointerAnnotation = PolarPointerAnnotation;
