"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.ArcAnnotation = void 0;
var Guard_1 = require("../../../Core/Guard");
var Point_1 = require("../../../Core/Point");
var SurfaceType_1 = require("../../../types/SurfaceType");
var XyDirection_1 = require("../../../types/XyDirection");
var pointUtil_1 = require("../../../utils/pointUtil");
var Pen2DCache_1 = require("../../Drawing/Pen2DCache");
var NativeObject_1 = require("../Helpers/NativeObject");
var DpiHelper_1 = require("../TextureManager/DpiHelper");
var AnnotationBase_1 = require("./AnnotationBase");
var ECoordinateMode_1 = require("./types/ECoordinateMode");
var ArcAnnotationBase_1 = require("./ArcAnnotationBase");
var constants_1 = require("./constants");
var EAnnotationType_1 = require("./types/EAnnotationType");
var ArcAnnotation = /** @class */ (function (_super) {
    __extends(ArcAnnotation, _super);
    function ArcAnnotation(options) {
        var _this = this;
        var _a, _b;
        _this = _super.call(this, options) || this;
        _this.type = EAnnotationType_1.EAnnotationType.RenderContextArcAnnotation;
        _this.surfaceTypes = [SurfaceType_1.ESurfaceType.SciChartSurfaceType];
        _this.innerRadiusProperty = 0;
        _this.heightProperty = 0;
        if (_this.xCoordinateMode === ECoordinateMode_1.ECoordinateMode.Relative) {
            throw new Error("ECoordinateMode.Relative is not supported for ArcAnnotation use DataValue or Pixel mode");
        }
        if (_this.xCoordinateMode !== _this.yCoordinateMode) {
            throw new Error("xCoordinateMode and yCoordinateMode should be the same for ArcAnnotation");
        }
        _this.innerRadiusProperty = (_a = options === null || options === void 0 ? void 0 : options.innerRadius) !== null && _a !== void 0 ? _a : _this.innerRadiusProperty;
        _this.heightProperty = (_b = options === null || options === void 0 ? void 0 : options.height) !== null && _b !== void 0 ? _b : _this.heightProperty;
        return _this;
    }
    Object.defineProperty(ArcAnnotation.prototype, "innerRadius", {
        get: function () {
            return this.innerRadiusProperty;
        },
        set: function (value) {
            if (value !== this.innerRadiusProperty) {
                this.innerRadiusProperty = value;
                this.notifyPropertyChanged(constants_1.PROPERTY.INNER_RADIUS);
            }
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(ArcAnnotation.prototype, "height", {
        get: function () {
            return this.heightProperty;
        },
        set: function (value) {
            if (value !== this.heightProperty) {
                this.heightProperty = value;
                this.notifyPropertyChanged(constants_1.PROPERTY.HEIGHT);
            }
        },
        enumerable: false,
        configurable: true
    });
    ArcAnnotation.prototype.drawWithContext = function (renderContext, xCalc, yCalc, seriesViewRect, surfaceViewRect, chartViewRect) {
        Guard_1.Guard.notNull(renderContext, "renderContext");
        Guard_1.Guard.notNull(xCalc, "xCalc");
        Guard_1.Guard.notNull(yCalc, "yCalc");
        var strokePen = this.stroke && this.strokeThickness !== undefined ? (0, Pen2DCache_1.getWebGlPenFromCache)(this.strokePenCache) : undefined;
        // getResolvedCoordinate already respects isVertical
        var x1 = this.getResolvedCoordinate(xCalc, yCalc, this.x1, this.y1, true);
        var y1 = this.getResolvedCoordinate(xCalc, yCalc, this.x1, this.y1, false);
        var x2 = this.getResolvedCoordinate(xCalc, yCalc, this.x2, this.y2, true);
        var y2 = this.getResolvedCoordinate(xCalc, yCalc, this.x2, this.y2, false);
        var wasmContext = renderContext.webAssemblyContext;
        var vecArcs = (0, NativeObject_1.getVectorArcVertex)(wasmContext);
        var arc = (0, NativeObject_1.getArcVertex)(wasmContext);
        var annotationCenterX = this.getCircleCenterXCoordinate(xCalc, yCalc);
        var rotCenterX = annotationCenterX;
        var annotationCenterY = this.getCircleCenterYCoordinate(xCalc, yCalc);
        var rotCenterY = annotationCenterY;
        var _a = this.calcStartEndAngles(xCalc.isFlipped, yCalc.isFlipped), startAngle = _a.startAngle, endAngle = _a.endAngle;
        var arcParms = (0, NativeObject_1.getArcParams)(wasmContext, rotCenterX, rotCenterY, startAngle, endAngle, this.getRadius(xCalc, yCalc), this.getInnerRadius(xCalc, yCalc), this.getDrawMode(), this.getAspectRatio(xCalc, yCalc), this.strokeThickness);
        arc.MakeCircularArc(arcParms);
        vecArcs.push_back(arc);
        var clipRect = this.getClippingRect(this.clipping, seriesViewRect, surfaceViewRect, chartViewRect);
        renderContext.drawArcs(vecArcs, rotCenterX, rotCenterY, 0, clipRect, strokePen.scrtPen, this.getBrush(), seriesViewRect.left, seriesViewRect.top);
        this.setArcAnnotationBorders(x1, x2, annotationCenterX, y1, y2, annotationCenterY);
        this.updateAdornerInner();
    };
    ArcAnnotation.prototype.calcDragDistance = function (xyValues) {
        if (!this.prevValue) {
            this.prevValue = xyValues;
            return;
        }
        if (this.adornerDraggingPoint === AnnotationBase_1.EDraggingGripPoint.Body) {
            this.x1 = this.x1 - (this.prevValue.x - xyValues.x);
            this.x2 = this.x2 - (this.prevValue.x - xyValues.x);
            this.y1 = this.y1 - (this.prevValue.y - xyValues.y);
            this.y2 = this.y2 - (this.prevValue.y - xyValues.y);
        }
        else if (this.adornerDraggingPoint === AnnotationBase_1.EDraggingGripPoint.x1y1) {
            if (this.resizeDirections === XyDirection_1.EXyDirection.XDirection) {
                this.x1 -= this.prevValue.x - xyValues.x;
            }
            else if (this.resizeDirections === XyDirection_1.EXyDirection.YDirection) {
                this.y1 -= this.prevValue.y - xyValues.y;
            }
            else {
                this.x1 -= this.prevValue.x - xyValues.x;
                this.y1 -= this.prevValue.y - xyValues.y;
            }
        }
        else if (this.adornerDraggingPoint === AnnotationBase_1.EDraggingGripPoint.x2y2) {
            if (this.resizeDirections === XyDirection_1.EXyDirection.XDirection) {
                this.x2 -= this.prevValue.x - xyValues.x;
            }
            else if (this.resizeDirections === XyDirection_1.EXyDirection.YDirection) {
                this.y2 -= this.prevValue.y - xyValues.y;
            }
            else {
                this.x2 -= this.prevValue.x - xyValues.x;
                this.y2 -= this.prevValue.y - xyValues.y;
            }
        }
        if (this.adornerDraggingPoint === AnnotationBase_1.EDraggingGripPoint.x3y3) {
            var newHeight = (0, pointUtil_1.calcDistanceFromLineSegment)(xyValues.x, xyValues.y, this.x1, this.y1, this.x2, this.y2);
            var sign = (0, pointUtil_1.calcCrossProduct)(xyValues.x, xyValues.y, this.x1, this.y1, this.x2, this.y2) > 0 ? 1 : -1;
            this.height = sign * newHeight;
        }
        this.prevValue = xyValues;
    };
    ArcAnnotation.prototype.toJSON = function () {
        var json = _super.prototype.toJSON.call(this);
        var options = {
            innerRadius: this.innerRadius,
            height: this.height
        };
        Object.assign(json.options, options);
        return json;
    };
    /**
     * Hit-test annotation clicked
     * @param xCoord
     * @param yCoord
     * @returns
     */
    ArcAnnotation.prototype.checkIsClickedOnAnnotationInternal = function (xCoord, yCoord) {
        var _a = this.getArcAnnotationBorders(), x1 = _a.x1, x2 = _a.x2, y1 = _a.y1, y2 = _a.y2, xCenter = _a.xCenter, yCenter = _a.yCenter;
        if ((0, pointUtil_1.calcDistance)(xCoord, yCoord, x1, y1) <= constants_1.DISTANCE_TO_LINE * DpiHelper_1.DpiHelper.PIXEL_RATIO)
            return true;
        if ((0, pointUtil_1.calcDistance)(xCoord, yCoord, x2, y2) <= constants_1.DISTANCE_TO_LINE * DpiHelper_1.DpiHelper.PIXEL_RATIO)
            return true;
        if ((0, pointUtil_1.calcDistance)(xCoord, yCoord, xCenter, yCenter) <= constants_1.DISTANCE_TO_LINE)
            return true;
        var _b = this.getDataValuesFromCoordinates(xCoord, yCoord), xValue = _b.x, yValue = _b.y;
        var _c = this.getCircleCenterDataCoords(), xCenterDataValue = _c.x, yCenterDataValue = _c.y;
        var isWithInRadius = (0, pointUtil_1.calcDistance)(xValue, yValue, xCenterDataValue, yCenterDataValue) < this.calcDataRadius();
        var isWithInAngle = this.calcStartEndAngles(this.xAxis.getCurrentCoordinateCalculator().isFlipped, this.yAxis.getCurrentCoordinateCalculator().isFlipped, new Point_1.Point(xValue, yValue)).isHit;
        var isWithInSector = isWithInRadius && isWithInAngle;
        var isWithInTriangle = (0, pointUtil_1.testPointInTriangle)(xCoord, yCoord, x1, y1, x2, y2, xCenter, yCenter);
        return isWithInSector || isWithInTriangle;
    };
    ArcAnnotation.prototype.getCircleCenterDataCoords = function () {
        var lineSegmentCenterX = (this.x1 + this.x2) / 2;
        var lineSegmentCenterY = (this.y1 + this.y2) / 2;
        var diffX = this.x1 - this.x2;
        var diffY = this.y1 - this.y2;
        var lineSegmentLength = Math.sqrt(diffX * diffX + diffY * diffY);
        var normalVecX = diffY / lineSegmentLength;
        var normalVecY = -diffX / lineSegmentLength;
        var normalVecLength = this.height;
        var x = lineSegmentCenterX + normalVecX * normalVecLength;
        var y = lineSegmentCenterY + normalVecY * normalVecLength;
        return { x: x, y: y };
    };
    ArcAnnotation.prototype.getCircleCenterXCoordinate = function (xCalc, yCalc) {
        var circleCenter = this.getCircleCenterDataCoords();
        return this.getResolvedCoordinate(xCalc, yCalc, circleCenter.x, circleCenter.y, true);
    };
    ArcAnnotation.prototype.getCircleCenterYCoordinate = function (xCalc, yCalc) {
        var circleCenter = this.getCircleCenterDataCoords();
        return this.getResolvedCoordinate(xCalc, yCalc, circleCenter.x, circleCenter.y, false);
    };
    ArcAnnotation.prototype.calcDataRadius = function () {
        var diffX = this.x1 - this.x2;
        var diffY = this.y1 - this.y2;
        var halfLineSegmentLength = Math.sqrt(diffX * diffX + diffY * diffY) / 2;
        return Math.sqrt(halfLineSegmentLength * halfLineSegmentLength + this.height * this.height);
    };
    ArcAnnotation.prototype.getRadius = function (xCalc, yCalc) {
        var dataRadius = this.calcDataRadius();
        if (this.isDataValueMode()) {
            return this.isVerticalChart ? xCalc.getCoordWidth(dataRadius) : yCalc.getCoordWidth(dataRadius);
        }
        else {
            return dataRadius * DpiHelper_1.DpiHelper.PIXEL_RATIO;
        }
    };
    ArcAnnotation.prototype.getInnerRadius = function (xCalc, yCalc) {
        if (this.isLineMode) {
            return 0;
        }
        return this.getRadius(xCalc, yCalc) * this.innerRadius;
    };
    ArcAnnotation.prototype.getAspectRatio = function (xCalc, yCalc) {
        if (this.isDataValueMode()) {
            return this.isVerticalChart
                ? yCalc.getCoordWidth(1) / xCalc.getCoordWidth(1)
                : xCalc.getCoordWidth(1) / yCalc.getCoordWidth(1);
        }
        else {
            return 1;
        }
    };
    ArcAnnotation.prototype.calcStartEndAngles = function (xFlipped, yFlipped, testPoint) {
        var circleCenterDataCoords = this.getCircleCenterDataCoords();
        var startAngle = 0;
        var endAngle = 0;
        var testAngle = 0;
        var isXPositiveDir = false;
        var isYPositiveDir = false;
        if (this.isVerticalChart) {
            endAngle = Math.atan2(this.x1 - circleCenterDataCoords.x, this.y1 - circleCenterDataCoords.y);
            startAngle = Math.atan2(this.x2 - circleCenterDataCoords.x, this.y2 - circleCenterDataCoords.y);
            testAngle = testPoint
                ? Math.atan2(testPoint.x - circleCenterDataCoords.x, testPoint.y - circleCenterDataCoords.y)
                : 0;
            isXPositiveDir = !yFlipped;
            isYPositiveDir = xFlipped;
        }
        else {
            startAngle = Math.atan2(this.y1 - circleCenterDataCoords.y, this.x1 - circleCenterDataCoords.x);
            endAngle = Math.atan2(this.y2 - circleCenterDataCoords.y, this.x2 - circleCenterDataCoords.x);
            testAngle = testPoint
                ? Math.atan2(testPoint.y - circleCenterDataCoords.y, testPoint.x - circleCenterDataCoords.x)
                : 0;
            isXPositiveDir = !xFlipped;
            isYPositiveDir = yFlipped;
        }
        if (this.isDataValueMode()) {
            if (!isYPositiveDir) {
                var temp = startAngle;
                startAngle = 2 * Math.PI - endAngle;
                endAngle = 2 * Math.PI - temp;
                testAngle = 2 * Math.PI - testAngle;
            }
            if (!isXPositiveDir) {
                var temp = startAngle;
                startAngle = Math.PI - endAngle;
                endAngle = Math.PI - temp;
                testAngle = Math.PI - testAngle;
            }
        }
        else {
            var temp = startAngle;
            startAngle = 2 * Math.PI - endAngle;
            endAngle = 2 * Math.PI - temp;
            testAngle = 2 * Math.PI - testAngle;
        }
        return this.normalizeAnglesAndHitTest(startAngle, endAngle, testPoint ? testAngle : undefined);
    };
    ArcAnnotation.prototype.getDataValuesFromCoordinates = function (xCoord, yCoord) {
        var xRes = 0;
        var yRes = 0;
        if (this.isDataValueMode()) {
            var xCalc = this.xAxis.getCurrentCoordinateCalculator();
            var yCalc = this.yAxis.getCurrentCoordinateCalculator();
            xRes = xCalc.getDataValue(this.isVerticalChart ? yCoord : xCoord);
            yRes = yCalc.getDataValue(this.isVerticalChart ? xCoord : yCoord);
            return { x: xRes, y: yRes };
        }
        else {
            xRes = xCoord / DpiHelper_1.DpiHelper.PIXEL_RATIO;
            yRes = yCoord / DpiHelper_1.DpiHelper.PIXEL_RATIO;
            return this.isVerticalChart ? { x: yRes, y: xRes } : { x: xRes, y: yRes };
        }
    };
    return ArcAnnotation;
}(ArcAnnotationBase_1.ArcAnnotationBase));
exports.ArcAnnotation = ArcAnnotation;
