"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.HtmlCustomAnnotation = void 0;
var EAnnotationLayer_1 = require("./types/EAnnotationLayer");
var EAnnotationType_1 = require("./types/EAnnotationType");
var DomAnnotationBase_1 = require("./DomAnnotationBase");
var constants_1 = require("./constants");
var Size_1 = require("../../../types/Size");
var SurfaceType_1 = require("../../../types/SurfaceType");
/**
 * An annotation which exposes an html element placed at the defined coordinates, which you can fill with any html.
 */
var HtmlCustomAnnotation = /** @class */ (function (_super) {
    __extends(HtmlCustomAnnotation, _super);
    /**
     * Creates an instance of an HtmlCustomAnnotation
     * @param options Optional parameters of type {@link IHtmlCustomAnnotationOptions} used to configure the annotation on construction
     */
    function HtmlCustomAnnotation(options) {
        var _this = _super.call(this, options) || this;
        _this.type = EAnnotationType_1.EAnnotationType.HtmlCustomAnnotation;
        _this.isSvgAnnotation = false;
        _this.isDomAnnotation = true;
        _this.surfaceTypes = [
            SurfaceType_1.ESurfaceType.SciChartSurfaceType,
            SurfaceType_1.ESurfaceType.SciChartPolarSurfaceType
        ];
        _this.create();
        return _this;
    }
    HtmlCustomAnnotation.prototype.onAttach = function (scs) {
        _super.prototype.onAttach.call(this, scs);
        this.attachToLayerRoot();
    };
    HtmlCustomAnnotation.prototype.onDetach = function () {
        _super.prototype.onDetach.call(this);
        this.layerRoot.removeChild(this.htmlElement.parentElement);
    };
    Object.defineProperty(HtmlCustomAnnotation.prototype, "htmlElement", {
        get: function () {
            return this.htmlElementProperty;
        },
        enumerable: false,
        configurable: true
    });
    /**
     * Updates the annotation position, with the {@link CoordinateCalculatorBase | Coordinate Calculators} passed in
     * @param xCalc The XAxis {@link CoordinateCalculatorBase | CoordinateCalculator} applied to this annotation
     * @param yCalc The YAxis {@link CoordinateCalculatorBase | CoordinateCalculator} applied to this annotation
     * @param xCoordSvgTrans X-coordinate translation which is needed to use root element having the whole chart size
     * @param yCoordSvgTrans Y-coordinate translation which is needed to use root element having the whole chart size
     */
    HtmlCustomAnnotation.prototype.update = function (xCalc, yCalc, xCoordSvgTrans, yCoordSvgTrans) {
        var _this = this;
        this.xCoordSvgTransProperty = xCoordSvgTrans;
        this.yCoordSvgTransProperty = yCoordSvgTrans;
        this.calcAndSetAnnotationBorders(xCalc, yCalc);
        var _a = this.getAnnotationBorders(), x1 = _a.x1, x2 = _a.x2, y1 = _a.y1, y2 = _a.y2;
        this.htmlElementProperty.parentElement.style.opacity = this.opacity.toString();
        if (isNaN(x1) || isNaN(y1) || !isFinite(x1) || !isFinite(y1)) {
            this.htmlElementProperty.parentElement.style.visibility = "hidden";
        }
        else {
            this.htmlElementProperty.parentElement.style.visibility = this.isHidden ? "hidden" : "visible";
            this.htmlElementProperty.style.left = "".concat(x1, "px");
            this.htmlElementProperty.style.top = "".concat(y1, "px");
            if (this.x2 !== undefined || this.y2 !== undefined) {
                if (this.isVerticalChart ? this.y2 !== undefined : this.x2 !== undefined) {
                    this.htmlElementProperty.style.width = "".concat(x2 - x1, "px");
                }
                if (this.isVerticalChart ? this.x2 !== undefined : this.y2 !== undefined) {
                    this.htmlElementProperty.style.height = "".concat(y2 - y1, "px");
                }
                // recalculate borders in case of layout shift
                this.calcAndSetAnnotationBorders(xCalc, yCalc);
                var _b = this.getAnnotationBorders(), updatedX1 = _b.x1, updatedY1 = _b.y1;
                this.htmlElementProperty.style.left = "".concat(updatedX1, "px");
                this.htmlElementProperty.style.top = "".concat(updatedY1, "px");
            }
        }
        this.updateAdornerInner();
        if (!this.resizeObserver) {
            this.resizeObserver = new ResizeObserver(function (entries) {
                var _a;
                var measuredSize = _this.measure();
                // TODO potentially it would be more efficient to use size data from entry.
                // But it seems like it differs to getBoundingClientRect when there is device scaling applied
                // const {width, height} = entries[0].contentRect
                // const measuredSize = new Size(width, height)
                if (!Size_1.Size.isEqual(_this.sizeProperty, measuredSize)) {
                    _this.sizeProperty = measuredSize;
                    (_a = _this.invalidateParentCallback) === null || _a === void 0 ? void 0 : _a.call(_this, { svgOnly: !_this.reDrawChartOnChange });
                }
            });
            this.resizeObserver.observe(this.htmlElement, { box: "border-box" });
        }
    };
    HtmlCustomAnnotation.prototype.delete = function () {
        var _a, _b;
        (_b = (_a = this.resizeObserver) === null || _a === void 0 ? void 0 : _a.disconnect) === null || _b === void 0 ? void 0 : _b.call(_a);
        _super.prototype.delete.call(this);
    };
    /**
     * Called to create the Dom Element right before it is added to the parent chart
     */
    HtmlCustomAnnotation.prototype.create = function () {
        if (this.htmlElementProperty) {
            return;
        }
        var annotationContainer = document.createElement("div");
        annotationContainer.id = "sciChartHtmlAnnotationContainer_".concat(this.id);
        annotationContainer.className = "sciChartHtmlAnnotationContainer";
        annotationContainer.style.position = "absolute";
        this.htmlElementProperty = annotationContainer;
    };
    Object.defineProperty(HtmlCustomAnnotation.prototype, "layerRoot", {
        /**
         * Gets the {@link HTMLElement} at the root of this annotation
         */
        get: function () {
            return this.layerRootProperty;
        },
        enumerable: false,
        configurable: true
    });
    HtmlCustomAnnotation.prototype.attachToLayerRoot = function () {
        if (!this.layerRoot) {
            return;
        }
        var annotationWrapper = document.createElement("div");
        annotationWrapper.style.visibility = "hidden";
        var clipPath = this.getClipPath(this.clipping);
        if (clipPath) {
            annotationWrapper.style.clipPath = clipPath;
        }
        annotationWrapper.appendChild(this.htmlElement);
        this.layerRoot.appendChild(annotationWrapper);
    };
    HtmlCustomAnnotation.prototype.selectLayerRoot = function () {
        var _a, _b, _c;
        if (this.annotationLayer === EAnnotationLayer_1.EAnnotationLayer.AboveChart) {
            this.layerRootProperty = (_a = this.parentSurface) === null || _a === void 0 ? void 0 : _a.domDivContainer;
        }
        else if (this.annotationLayer === EAnnotationLayer_1.EAnnotationLayer.BelowChart) {
            // default to foreground for back compatibility
            this.layerRootProperty = (_b = this.parentSurface) === null || _b === void 0 ? void 0 : _b.domDivContainer;
        }
        else if (this.annotationLayer === EAnnotationLayer_1.EAnnotationLayer.Background) {
            this.layerRootProperty = (_c = this.parentSurface) === null || _c === void 0 ? void 0 : _c.domSeriesBackground;
        }
        else {
            throw new Error("Unexpected annotationLayer value: \"".concat(this.annotationLayer, "!\""));
        }
    };
    HtmlCustomAnnotation.prototype.notifyPropertyChanged = function (propertyName) {
        var _a, _b;
        if (propertyName === constants_1.PROPERTY.ANNOTATION_CANVAS) {
            (_b = (_a = this.layerRoot) === null || _a === void 0 ? void 0 : _a.removeChild) === null || _b === void 0 ? void 0 : _b.call(_a, this.htmlElement.parentElement);
            _super.prototype.notifyPropertyChanged.call(this, propertyName);
            this.attachToLayerRoot();
            return;
        }
        _super.prototype.notifyPropertyChanged.call(this, propertyName);
    };
    HtmlCustomAnnotation.prototype.getSize = function () {
        if (!this.htmlElementProperty) {
            return undefined;
        }
        if (!this.sizeProperty) {
            this.sizeProperty = this.measure();
        }
        return this.sizeProperty;
    };
    HtmlCustomAnnotation.prototype.measure = function () {
        var _a = this.htmlElementProperty.getBoundingClientRect(), width = _a.width, height = _a.height;
        return new Size_1.Size(width, height);
    };
    return HtmlCustomAnnotation;
}(DomAnnotationBase_1.DomAnnotationBase));
exports.HtmlCustomAnnotation = HtmlCustomAnnotation;
