/**
 * DevExtreme (cjs/core/utils/shadow_dom.js)
 * Version: 23.2.6 (build 24140-0112)
 * Build date: Sun May 19 2024
 *
 * Copyright (c) 2012 - 2024 Developer Express Inc. ALL RIGHTS RESERVED
 * Read about DevExtreme licensing here: https://js.devexpress.com/Licensing/
 */
"use strict";
exports.addShadowDomStyles = addShadowDomStyles;
exports.getShadowElementsFromPoint = getShadowElementsFromPoint;
const DX_RULE_PREFIX = "dx-";
let ownerDocumentStyleSheet = null;

function createConstructedStyleSheet(rootNode) {
    try {
        return new CSSStyleSheet
    } catch (err) {
        const styleElement = rootNode.ownerDocument.createElement("style");
        rootNode.appendChild(styleElement);
        return styleElement.sheet
    }
}

function processRules(targetStyleSheet, styleSheets, needApplyAllStyles) {
    for (let i = 0; i < styleSheets.length; i++) {
        const sheet = styleSheets[i];
        try {
            for (let j = 0; j < sheet.cssRules.length; j++) {
                insertRule(targetStyleSheet, sheet.cssRules[j], needApplyAllStyles)
            }
        } catch (err) {}
    }
}

function insertRule(targetStyleSheet, rule, needApplyAllStyles) {
    var _rule$selectorText, _rule$cssRules, _rule$cssRules$, _rule$cssRules$$selec, _rule$name, _rule$style;
    const isDxRule = needApplyAllStyles || (null === (_rule$selectorText = rule.selectorText) || void 0 === _rule$selectorText ? void 0 : _rule$selectorText.includes("dx-")) || (null === (_rule$cssRules = rule.cssRules) || void 0 === _rule$cssRules ? void 0 : null === (_rule$cssRules$ = _rule$cssRules[0]) || void 0 === _rule$cssRules$ ? void 0 : null === (_rule$cssRules$$selec = _rule$cssRules$.selectorText) || void 0 === _rule$cssRules$$selec ? void 0 : _rule$cssRules$$selec.includes("dx-")) || (null === (_rule$name = rule.name) || void 0 === _rule$name ? void 0 : _rule$name.startsWith("dx-")) || "DXIcons" === (null === (_rule$style = rule.style) || void 0 === _rule$style ? void 0 : _rule$style.fontFamily);
    if (isDxRule) {
        targetStyleSheet.insertRule(rule.cssText, targetStyleSheet.cssRules.length)
    }
}

function addShadowDomStyles($element) {
    var _el$getRootNode;
    const el = $element.get(0);
    const root = null === (_el$getRootNode = el.getRootNode) || void 0 === _el$getRootNode ? void 0 : _el$getRootNode.call(el);
    if (!(null !== root && void 0 !== root && root.host)) {
        return
    }
    if (!ownerDocumentStyleSheet) {
        ownerDocumentStyleSheet = createConstructedStyleSheet(root);
        processRules(ownerDocumentStyleSheet, el.ownerDocument.styleSheets, false)
    }
    const currentShadowDomStyleSheet = createConstructedStyleSheet(root);
    processRules(currentShadowDomStyleSheet, root.styleSheets, true);
    root.adoptedStyleSheets = [ownerDocumentStyleSheet, currentShadowDomStyleSheet]
}

function isPositionInElementRectangle(element, x, y) {
    const rect = element.getBoundingClientRect();
    return rect && x >= rect.left && x < rect.right && y >= rect.top && y < rect.bottom
}

function createQueue() {
    let shiftIndex = 0;
    const items = [];
    return Object.defineProperties({
        push(item) {
            items.push(item);
            return this
        },
        shift() {
            shiftIndex++;
            return items[shiftIndex - 1]
        }
    }, {
        length: {
            get: function() {
                return items.length - shiftIndex
            },
            configurable: true,
            enumerable: true
        },
        items: {
            get: function() {
                return items
            },
            configurable: true,
            enumerable: true
        }
    })
}

function getShadowElementsFromPoint(x, y, root) {
    const elementQueue = createQueue().push(root);
    while (elementQueue.length) {
        const el = elementQueue.shift();
        for (let i = 0; i < el.childNodes.length; i++) {
            const childNode = el.childNodes[i];
            if (childNode.nodeType === Node.ELEMENT_NODE && isPositionInElementRectangle(childNode, x, y) && "none" !== getComputedStyle(childNode).pointerEvents) {
                elementQueue.push(childNode)
            }
        }
    }
    const result = elementQueue.items.reverse();
    result.pop();
    return result
}
