"use strict";
var _a;
Object.defineProperty(exports, "__esModule", { value: true });
exports.debounce = exports.addCancelSelectActionEventHandler = exports.clearElementChildren = exports.getScrollY = exports.getScrollX = exports.getFitStatus = exports.truncate = exports.truncateText = exports.stringToCssColor = exports.parseEnum = exports.getEnumValueByName = exports.parseBool = exports.parseNumber = exports.parseString = exports.appendChild = exports.generateUniqueId = exports.isMobileOS = exports.isInternetExplorer = void 0;
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
var Enums = require("./enums");
var Shared = require("./shared");
function isInternetExplorer() {
    // The documentMode property only exists in IE
    return window.document.documentMode !== undefined;
}
exports.isInternetExplorer = isInternetExplorer;
function isMobileOS() {
    var userAgent = window.navigator.userAgent;
    return (!!userAgent.match(/Android/i) || !!userAgent.match(/iPad/i) || !!userAgent.match(/iPhone/i));
}
exports.isMobileOS = isMobileOS;
/**
 * Generate a UUID prepended with "__ac-"
 */
function generateUniqueId() {
    return "__ac-" + Shared.UUID.generate();
}
exports.generateUniqueId = generateUniqueId;
function appendChild(node, child) {
    if (child) {
        node.appendChild(child);
    }
}
exports.appendChild = appendChild;
function parseString(obj, defaultValue) {
    return typeof obj === "string" ? obj : defaultValue;
}
exports.parseString = parseString;
function parseNumber(obj, defaultValue) {
    return typeof obj === "number" ? obj : defaultValue;
}
exports.parseNumber = parseNumber;
function parseBool(value, defaultValue) {
    if (typeof value === "boolean") {
        return value;
    }
    else if (typeof value === "string") {
        switch (value.toLowerCase()) {
            case "true":
                return true;
            case "false":
                return false;
            default:
                return defaultValue;
        }
    }
    return defaultValue;
}
exports.parseBool = parseBool;
function getEnumValueByName(enumType, name) {
    // eslint-disable-next-line guard-for-in
    for (var key in enumType) {
        var keyAsNumber = parseInt(key, 10);
        if (keyAsNumber >= 0) {
            var value = enumType[key];
            if (value && typeof value === "string" && value.toLowerCase() === name.toLowerCase()) {
                return keyAsNumber;
            }
        }
    }
    return undefined;
}
exports.getEnumValueByName = getEnumValueByName;
function parseEnum(enumType, name, defaultValue) {
    if (!name) {
        return defaultValue;
    }
    var enumValue = getEnumValueByName(enumType, name);
    return enumValue !== undefined ? enumValue : defaultValue;
}
exports.parseEnum = parseEnum;
function stringToCssColor(color) {
    if (color) {
        var regEx = /#([0-9A-F]{2})([0-9A-F]{2})([0-9A-F]{2})([0-9A-F]{2})?/gi;
        var matches = regEx.exec(color);
        if (matches && matches[4]) {
            var a = parseInt(matches[1], 16) / 255;
            var r = parseInt(matches[2], 16);
            var g = parseInt(matches[3], 16);
            var b = parseInt(matches[4], 16);
            return "rgba(" + r + "," + g + "," + b + "," + a + ")";
        }
    }
    return color;
}
exports.stringToCssColor = stringToCssColor;
function truncateWorker(element, maxHeight, fullText, truncateAt, lineHeight) {
    var fits = function () {
        // Allow a one pixel overflow to account for rounding differences
        // between browsers
        return maxHeight - element.scrollHeight >= -1.0;
    };
    if (fits()) {
        return;
    }
    var breakableIndices = findBreakableIndices(fullText);
    var lo = 0;
    var hi = breakableIndices.length;
    var bestBreakIdx = 0;
    // Do a binary search for the longest string that fits
    while (lo < hi) {
        var mid = Math.floor((lo + hi) / 2);
        truncateAt(fullText, breakableIndices[mid]);
        if (fits()) {
            bestBreakIdx = breakableIndices[mid];
            lo = mid + 1;
        }
        else {
            hi = mid;
        }
    }
    truncateAt(fullText, bestBreakIdx);
    // If we have extra room, try to expand the string letter by letter
    // (covers the case where we have to break in the middle of a long word)
    if (lineHeight && maxHeight - element.scrollHeight >= lineHeight - 1.0) {
        var idx = findNextCharacter(fullText, bestBreakIdx);
        while (idx < fullText.length) {
            truncateAt(fullText, idx);
            if (fits()) {
                bestBreakIdx = idx;
                idx = findNextCharacter(fullText, idx);
            }
            else {
                break;
            }
        }
        truncateAt(fullText, bestBreakIdx);
    }
}
function truncateText(element, maxHeight, lineHeight) {
    truncateWorker(element, maxHeight, element.innerText, function (text, idx) {
        element.innerText = text.substring(0, idx) + "...";
    }, lineHeight);
}
exports.truncateText = truncateText;
/**
 * {@link truncate} has been deprecated and is no longer in use internally. This policy passes
 * content through as it always has, which is _supposed_ to be dealing with text only (see {@link
 * TextBlock.truncateIfSupported}), but had a bug where it might actually pass through an element
 * for which innerHTML yielded actual HTML (since fixed).
 */
var ttDeprecatedPolicy = (typeof window === 'undefined') ? undefined : (_a = window.trustedTypes) === null || _a === void 0 ? void 0 : _a.createPolicy("adaptivecards#deprecatedExportedFunctionPolicy", {
    createHTML: function (value) { return value; }
});
/** @deprecated Use {@link truncateText} instead. */
function truncate(element, maxHeight, lineHeight) {
    truncateWorker(element, maxHeight, element.innerHTML, function (text, idx) {
        var _a;
        var truncatedString = text.substring(0, idx) + "...";
        var truncatedHTML = (_a = ttDeprecatedPolicy === null || ttDeprecatedPolicy === void 0 ? void 0 : ttDeprecatedPolicy.createHTML(truncatedString)) !== null && _a !== void 0 ? _a : truncatedString;
        element.innerHTML = truncatedHTML;
    }, lineHeight);
}
exports.truncate = truncate;
function findBreakableIndices(html) {
    var results = [];
    var idx = findNextCharacter(html, -1);
    while (idx < html.length) {
        if (html[idx] === " ") {
            results.push(idx);
        }
        idx = findNextCharacter(html, idx);
    }
    return results;
}
function findNextCharacter(html, currIdx) {
    currIdx += 1;
    // If we found the start of an HTML tag, keep advancing until we get
    // past it, so we don't end up truncating in the middle of the tag
    while (currIdx < html.length && html[currIdx] === "<") {
        while (currIdx < html.length && html[currIdx++] !== ">") {
            continue;
        }
    }
    return currIdx;
}
function getFitStatus(element, containerEnd) {
    var start = element.offsetTop;
    var end = start + element.clientHeight;
    if (end <= containerEnd) {
        return Enums.ContainerFitStatus.FullyInContainer;
    }
    else if (start < containerEnd) {
        return Enums.ContainerFitStatus.Overflowing;
    }
    else {
        return Enums.ContainerFitStatus.FullyOutOfContainer;
    }
}
exports.getFitStatus = getFitStatus;
function getScrollX() {
    return window.pageXOffset;
}
exports.getScrollX = getScrollX;
function getScrollY() {
    return window.pageYOffset;
}
exports.getScrollY = getScrollY;
function clearElementChildren(element) {
    while (element.firstChild) {
        element.removeChild(element.firstChild);
    }
}
exports.clearElementChildren = clearElementChildren;
function addCancelSelectActionEventHandler(element) {
    element.onclick = function (e) {
        e.preventDefault();
        e.cancelBubble = true;
    };
}
exports.addCancelSelectActionEventHandler = addCancelSelectActionEventHandler;
function debounce(fn, delay) {
    var timer;
    function debouncedFn() {
        var args = [];
        for (var _i = 0; _i < arguments.length; _i++) {
            args[_i] = arguments[_i];
        }
        if (timer) {
            clearTimeout(timer);
        }
        timer = setTimeout(function () {
            fn.apply(void 0, args);
        }, delay);
    }
    return debouncedFn;
}
exports.debounce = debounce;
//# sourceMappingURL=utils.js.map