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 __());
    };
})();
define(["require", "exports", "../core/Plugin", "../utils/classSet"], function (require, exports, Plugin_1, classSet_1) {
    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });
    var Tooltip = (function (_super) {
        __extends(Tooltip, _super);
        function Tooltip(opts) {
            var _this = _super.call(this, opts) || this;
            _this.messages = new Map();
            _this.opts = Object.assign({}, {
                placement: 'top',
                trigger: 'click',
            }, opts);
            _this.iconPlacedHandler = _this.onIconPlaced.bind(_this);
            _this.validatorValidatedHandler = _this.onValidatorValidated.bind(_this);
            _this.elementValidatedHandler = _this.onElementValidated.bind(_this);
            _this.documentClickHandler = _this.onDocumentClicked.bind(_this);
            return _this;
        }
        Tooltip.prototype.install = function () {
            var _a;
            this.tip = document.createElement('div');
            (0, classSet_1.default)(this.tip, (_a = {
                    'fv-plugins-tooltip': true
                },
                _a["fv-plugins-tooltip--".concat(this.opts.placement)] = true,
                _a));
            document.body.appendChild(this.tip);
            this.core
                .on('plugins.icon.placed', this.iconPlacedHandler)
                .on('core.validator.validated', this.validatorValidatedHandler)
                .on('core.element.validated', this.elementValidatedHandler);
            if ('click' === this.opts.trigger) {
                document.addEventListener('click', this.documentClickHandler);
            }
        };
        Tooltip.prototype.uninstall = function () {
            this.messages.clear();
            document.body.removeChild(this.tip);
            this.core
                .off('plugins.icon.placed', this.iconPlacedHandler)
                .off('core.validator.validated', this.validatorValidatedHandler)
                .off('core.element.validated', this.elementValidatedHandler);
            if ('click' === this.opts.trigger) {
                document.removeEventListener('click', this.documentClickHandler);
            }
        };
        Tooltip.prototype.onIconPlaced = function (e) {
            var _this = this;
            (0, classSet_1.default)(e.iconElement, {
                'fv-plugins-tooltip-icon': true,
            });
            switch (this.opts.trigger) {
                case 'hover':
                    e.iconElement.addEventListener('mouseenter', function (evt) { return _this.show(e.element, evt); });
                    e.iconElement.addEventListener('mouseleave', function (_evt) { return _this.hide(); });
                    break;
                case 'click':
                default:
                    e.iconElement.addEventListener('click', function (evt) { return _this.show(e.element, evt); });
                    break;
            }
        };
        Tooltip.prototype.onValidatorValidated = function (e) {
            if (!e.result.valid) {
                var elements = e.elements;
                var type = e.element.getAttribute('type');
                var ele = 'radio' === type || 'checkbox' === type ? elements[0] : e.element;
                var message = typeof e.result.message === 'string' ? e.result.message : e.result.message[this.core.getLocale()];
                this.messages.set(ele, message);
            }
        };
        Tooltip.prototype.onElementValidated = function (e) {
            if (e.valid) {
                var elements = e.elements;
                var type = e.element.getAttribute('type');
                var ele = 'radio' === type || 'checkbox' === type ? elements[0] : e.element;
                this.messages.delete(ele);
            }
        };
        Tooltip.prototype.onDocumentClicked = function (_e) {
            this.hide();
        };
        Tooltip.prototype.show = function (ele, e) {
            e.preventDefault();
            e.stopPropagation();
            if (!this.messages.has(ele)) {
                return;
            }
            (0, classSet_1.default)(this.tip, {
                'fv-plugins-tooltip--hide': false,
            });
            this.tip.innerHTML = "<div class=\"fv-plugins-tooltip__content\">".concat(this.messages.get(ele), "</div>");
            var icon = e.target;
            var targetRect = icon.getBoundingClientRect();
            var _a = this.tip.getBoundingClientRect(), height = _a.height, width = _a.width;
            var top = 0;
            var left = 0;
            switch (this.opts.placement) {
                case 'bottom':
                    top = targetRect.top + targetRect.height;
                    left = targetRect.left + targetRect.width / 2 - width / 2;
                    break;
                case 'bottom-left':
                    top = targetRect.top + targetRect.height;
                    left = targetRect.left;
                    break;
                case 'bottom-right':
                    top = targetRect.top + targetRect.height;
                    left = targetRect.left + targetRect.width - width;
                    break;
                case 'left':
                    top = targetRect.top + targetRect.height / 2 - height / 2;
                    left = targetRect.left - width;
                    break;
                case 'right':
                    top = targetRect.top + targetRect.height / 2 - height / 2;
                    left = targetRect.left + targetRect.width;
                    break;
                case 'top-left':
                    top = targetRect.top - height;
                    left = targetRect.left;
                    break;
                case 'top-right':
                    top = targetRect.top - height;
                    left = targetRect.left + targetRect.width - width;
                    break;
                case 'top':
                default:
                    top = targetRect.top - height;
                    left = targetRect.left + targetRect.width / 2 - width / 2;
                    break;
            }
            var scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0;
            var scrollLeft = window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft || 0;
            top = top + scrollTop;
            left = left + scrollLeft;
            this.tip.setAttribute('style', "top: ".concat(top, "px; left: ").concat(left, "px"));
        };
        Tooltip.prototype.hide = function () {
            (0, classSet_1.default)(this.tip, {
                'fv-plugins-tooltip--hide': true,
            });
        };
        return Tooltip;
    }(Plugin_1.default));
    exports.default = Tooltip;
});
