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);
};
var __read = (this && this.__read) || function (o, n) {
    var m = typeof Symbol === "function" && o[Symbol.iterator];
    if (!m) return o;
    var i = m.call(o), r, ar = [], e;
    try {
        while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
    }
    catch (error) { e = { error: error }; }
    finally {
        try {
            if (r && !r.done && (m = i["return"])) m.call(i);
        }
        finally { if (e) throw e.error; }
    }
    return ar;
};
import { Container, DOM } from "aurelia-framework";
import { getLogger } from "aurelia-logging";
import { Config } from "../config";
export var UITether;
(function (UITether) {
    function tether(anchorEl, dropdownEl, config) {
        if (config === void 0) { config = TetherConfig; }
        return attach(anchorEl, dropdownEl, __assign(__assign({}, Config), config));
    }
    UITether.tether = tether;
    var TetherConfig = {
        anchorPosition: "bl",
        attachToViewport: false,
        position: "tl",
        resize: true
    };
    var logger = getLogger("UITether");
    function updatePosition(anchorEl, dropdownEl, scrollerEl, config) {
        var anchorRect = anchorEl.getBoundingClientRect();
        var dropdownRect = dropdownEl.getBoundingClientRect();
        var scrollerRect = scrollerEl.getBoundingClientRect();
        if (config.resize !== false) {
            dropdownEl.style.minWidth = anchorRect.width + "px";
        }
        var _a = __read(config.position.split(""), 2), posY = _a[0], posX = _a[1];
        var _b = __read(config.anchorPosition.split(""), 2), anchorY = _b[0], anchorX = _b[1];
        var rtl = isRtl(scrollerEl);
        var x = 0;
        var y = 0;
        var clientHeight = document.body.clientHeight;
        var clientWidth = document.body.clientWidth;
        var clientX = 0;
        var clientY = 0;
        if (!config.attachToViewport) {
            clientHeight = scrollerRect.bottom;
            clientWidth = scrollerRect.right;
            clientX = scrollerRect.left;
            clientY = scrollerRect.top;
        }
        if (anchorX === (rtl ? "r" : "l")) {
            x = anchorRect.left;
        }
        else if (anchorX === (rtl ? "l" : "r")) {
            x = anchorRect.right;
        }
        else if (anchorX === "c") {
            x = anchorRect.left + anchorRect.width / 2;
        }
        if (anchorY === "t") {
            y = anchorRect.top;
        }
        else if (anchorY === "b") {
            y = anchorRect.bottom;
        }
        else if (anchorY === "c") {
            y = anchorRect.top + anchorRect.height / 2;
        }
        if (posX === (rtl ? "l" : "r")) {
            x -= dropdownRect.width;
        }
        if (posX === "c") {
            x -= dropdownRect.width / 2;
        }
        if (posY === "b") {
            y -= dropdownRect.height;
        }
        if (posY === "c") {
            y -= dropdownRect.height / 2;
        }
        if (x + dropdownRect.width > clientWidth) {
            x = anchorRect.right - dropdownRect.width;
        }
        else if (x < clientX) {
            x = anchorRect.left;
        }
        if (y + dropdownRect.height > clientHeight) {
            y =
                posY === "t" && anchorY === "b" ? anchorRect.top - dropdownRect.height - 2 : anchorRect.bottom;
        }
        else if (y < clientY) {
            y =
                posY === "b" && anchorY === "t" ? anchorRect.bottom - dropdownRect.height : anchorRect.top;
        }
        if (!config.attachToViewport) {
            x -= scrollerRect.left - scrollerEl.scrollLeft + 2;
            y -= scrollerRect.top - scrollerEl.scrollTop + 1;
            if (rtl && scrollerEl.scrollHeight > scrollerEl.offsetHeight) {
                x -= 5;
            }
        }
        else {
            if (y < 0) {
                y = anchorY === "b" ? clientHeight - dropdownRect.height : 0;
            }
            else if (y + dropdownRect.height > clientHeight) {
                y = anchorY === "t" ? scrollerRect.bottom - dropdownRect.height : clientHeight - dropdownRect.height;
            }
        }
        dropdownEl.style.transform = "translate(".concat(x, "px, ").concat(y, "px)");
    }
    function scrollHandler(scrollCallbacks) {
        if (scrollCallbacks === void 0) { scrollCallbacks = new Set(); }
        scrollCallbacks.forEach(function (c) { return c(); });
    }
    function getParentScroller(el) {
        var styles = ["scroll", "auto"];
        el = el.parentElement;
        do {
            var style = window.getComputedStyle(el);
            if (styles.includes(style.overflow) ||
                styles.includes(style.overflowX) ||
                styles.includes(style.overflowY)) {
                return el;
            }
            el = el.parentElement;
        } while (el !== null);
        return null;
    }
    function initScroller(anchorEl, scrollCallback) {
        var scroller = getParentScroller(anchorEl) || document.body;
        if (!scroller.scrollHandler) {
            scroller.scrollHandler = function () { return scrollHandler(scroller.scrollCallbacks); };
            scroller.addEventListener("scroll", scroller.scrollHandler);
            scroller.scrollCallbacks = new Set();
        }
        scroller.scrollCallbacks.add(scrollCallback);
        return scroller;
    }
    function attach(anchorEl, dropdownEl, config) {
        if (dropdownEl == null)
            return;
        var container = Container.instance.get(Config).containerConfig.FloatingContainer;
        (config.attachToViewport) && container != null ? container.appendChild((dropdownEl === null || dropdownEl === void 0 ? void 0 : dropdownEl.parentElement) || dropdownEl) : fn();
        var scroller;
        var scrollCallback = function () {
            if (dropdownEl.parentElement.dataset.open) {
                setTimeout(function () {
                    updatePosition(anchorEl, dropdownEl, scroller, config);
                }, 50);
            }
        };
        scroller = initScroller(anchorEl, scrollCallback);
        return {
            dispose: function () {
                scroller.scrollCallbacks.delete(scrollCallback);
                if ((dropdownEl === null || dropdownEl === void 0 ? void 0 : dropdownEl.parentElement) === container) {
                    DOM.removeNode(dropdownEl);
                }
                else {
                    DOM.removeNode(dropdownEl.parentElement);
                }
            },
            updatePosition: function (newAnchorEl, newConfig) {
                if (newConfig === void 0) { newConfig = {}; }
                anchorEl = newAnchorEl || anchorEl;
                scroller = initScroller(anchorEl, scrollCallback);
                updatePosition(anchorEl, dropdownEl, scroller, __assign(__assign({}, config), newConfig));
            }
        };
    }
})(UITether || (UITether = {}));

//# sourceMappingURL=ui-tether.js.map
