import { h, Host } from "@stencil/core";
export class LoadingIndicator {
    constructor() {
        this.clipInnerElement = false;
        /**
         * The description that will be set as the aria-label of the loading indicator when not using a visible label.
         */
        this.description = "Loading";
        /**
         * If `true`, when linear, the full-width variant (i.e. without a border radius) will be displayed.
         */
        this.fullWidth = false;
        /**
         * The time in milliseconds before the label changes.
         */
        this.labelDuration = 8000;
        /**
         * The maximum value that the progress value can take.
         * Used to calculate the proportional width of the progress bar.
         */
        this.max = 100;
        /**
         * The minimum value that the progress value can take.
         * Used to calculate the proportional width of the progress bar.
         */
        this.min = 0;
        /**
         * If `true`, the element will display as black and white.
         */
        this.monochrome = false;
        /**
         * The size of the loading indicator.
         */
        this.size = "medium";
        /**
         * The type of indicator, either linear or circular.
         */
        this.type = "circular";
        /**
         * Sets the theme color to the dark or light theme color. "inherit" will set the color based on the system settings or ic-theme component.
         */
        this.theme = "inherit";
        this.updateCircularProgressMeter = () => {
            if (!this.indeterminate && this.circularMeter) {
                this.circularMeter.style.setProperty("--progress-value", String(this.progress));
            }
        };
        this.getLabel = (labelIndex, setLabel) => {
            return new Promise(() => {
                this.interval = setInterval(() => {
                    if (labelIndex < this.labelList.length - 1) {
                        labelIndex++;
                    }
                    else {
                        labelIndex = 0;
                    }
                    setLabel(this.labelList[labelIndex]);
                }, this.labelDuration);
            });
        };
        this.getLabelVariant = () => {
            var _a;
            let variant = "h4";
            const width = (_a = this.outerElement) === null || _a === void 0 ? void 0 : _a.offsetWidth;
            if (this.size === "small" ||
                (width && this.type === "circular" && width < 60)) {
                variant = "label";
            }
            else if (this.size === "large" ||
                (width && this.type === "circular" && width >= 120)) {
                variant = "h2";
            }
            return variant;
        };
        // Sets the circular indicator line width - accounting for the circle size being altered using the CSS custom property
        this.setCircleLineWidth = () => {
            const compactStepCircularLineWidth = this.el.classList.contains("compact-step-progress-indicator")
                ? 40
                : 0;
            const toastDismissTimerCircularLineWidth = this.el.classList.contains("toast-dismiss-timer")
                ? 20
                : 0;
            if (this.outerElement) {
                const { offsetWidth: width } = this.outerElement;
                if (width ||
                    compactStepCircularLineWidth ||
                    toastDismissTimerCircularLineWidth) {
                    this.circularLineWidth =
                        (compactStepCircularLineWidth ||
                            toastDismissTimerCircularLineWidth ||
                            width) * 0.1;
                    this.circularDiameter =
                        compactStepCircularLineWidth ||
                            toastDismissTimerCircularLineWidth ||
                            width;
                    this.outerElement.style.setProperty("--circular-line-width", `${this.circularLineWidth}px`);
                }
            }
        };
        this.setLinearDeterminateWidth = () => {
            const max = this.max;
            const min = this.min;
            if (!this.innerElement)
                return;
            // Ensure progress cannot be out of bounds
            if (this.progress) {
                const progress = Math.min(max, Math.max(min, this.progress));
                const proportion = (progress - min) / (max - min);
                this.clipInnerElement = proportion > 0.5;
                if (this.clipInnerElement) {
                    this.innerElement.classList.remove("clip");
                }
                else {
                    this.innerElement.classList.add("clip");
                }
                this.innerElement.style.setProperty("--linear-width", `${proportion * 100}%`);
            }
        };
        this.calcOuterClass = () => {
            let cls = `ic-loading-${this.type}-outer`;
            cls += this.indeterminate ? " indeterminate" : " determinate";
            return cls;
        };
        this.updateLabel = () => {
            if (this.label !== undefined) {
                if (typeof this.label === "string") {
                    this.indicatorLabel = this.label;
                }
                else {
                    this.labelList = this.label;
                    const labelIndex = 0;
                    this.indicatorLabel = this.labelList[labelIndex];
                    if (this.labelList.length > 1) {
                        this.getLabel(labelIndex, (label) => {
                            this.indicatorLabel = label;
                        });
                    }
                }
            }
        };
        this.setCircleXY = () => {
            if (this.circularDiameter > 0) {
                const r = this.circularDiameter / 2;
                const x = r;
                const y = r;
                const nextRadius = r - this.circularLineWidth / 2;
                this.setDashSteps(nextRadius);
                return { x, y, r: nextRadius };
            }
            return { x: 0, y: 0, r: 0 };
        };
        this.setDashSteps = (radius) => {
            const dashArray = 2 * Math.PI * radius;
            if (this.circularMeter) {
                this.circularMeter.style.setProperty("--stroke-dasharray", `${dashArray}px`);
                if (!this.indeterminate && this.progress) {
                    const min = this.min;
                    const max = this.max;
                    const progress = Math.min(Math.max(this.progress, min), max);
                    const proportion = -1 - (progress - min) / (max - min);
                    this.circularMeter.style.setProperty("--circular-steps-max", String(this.max));
                    this.circularMeter.style.setProperty("--stroke-dashoffset", `${proportion * dashArray}px`);
                }
            }
        };
    }
    watchPropHandler() {
        this.updateLabel();
    }
    watchProgressHandler() {
        if (this.type === "circular") {
            this.updateCircularProgressMeter();
        }
    }
    disconnectedCallback() {
        clearInterval(this.interval);
    }
    componentWillLoad() {
        this.indeterminate = this.progress === undefined;
        this.updateLabel();
        this.el.setAttribute("exportparts", "ic-loading-container");
    }
    componentDidLoad() {
        var _a;
        if (this.type === "circular") {
            this.setCircleLineWidth();
            this.circularMeter = (_a = this.el.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelector(".ic-loading-circular-svg circle:nth-child(2)");
            this.updateCircularProgressMeter();
        }
        if (Number(this.progress) >= 0 && this.type === "linear") {
            this.setLinearDeterminateWidth();
        }
    }
    componentWillUpdate() {
        this.indeterminate = this.progress === undefined;
    }
    componentDidUpdate() {
        if (Number(this.progress) >= 0 && this.type === "linear") {
            this.setLinearDeterminateWidth();
        }
    }
    render() {
        const { theme, label, description, size, fullWidth, innerLabel, monochrome, } = this;
        const { x, y, r } = this.setCircleXY();
        return (h(Host, { key: 'af8aecb7e2feb45574ce1dbce238e24ece0a7c14', class: {
                [`ic-theme-${theme}`]: theme !== "inherit",
                "ic-loading-indicator-label": !!label,
                "ic-loading-indicator-full-width": !!fullWidth,
                "inner-label": !!innerLabel,
                "ic-loading-indicator-monochrome": !!monochrome,
            } }, h("div", { key: '46a3bbc13400779a3aa92324f84b2a0515a34a64', class: "ic-loading-container", part: "ic-loading-container" }, h("div", { key: 'ff16f2f3f71e2338834eb1852f5b362332517a09', ref: (el) => (this.outerElement = el), class: this.calcOuterClass(), role: "progressbar", "aria-labelledby": this.label && this.size !== "icon" && "ic-loading-label", "aria-label": description, "aria-valuenow": this.progress, "aria-valuemin": this.min, "aria-valuemax": this.max }, h("div", { key: '4c0937928bd38982462ad36d6df98ecd5729b64e', ref: (el) => (this.innerElement = el), class: `ic-loading-${this.type}-inner` }, this.innerLabel &&
            this.innerLabel !== undefined &&
            this.size === "small" && (h("ic-typography", { key: '13c9dbbead841cf7995caefc63bb86d8c0e40d2d', variant: "subtitle-small", class: "inner-text" }, this.innerLabel)), this.type === "circular" && (h("svg", { key: '12decbb0441c22e9c0f7f82b8c7737b24c44bf01', class: "ic-loading-circular-svg", viewBox: `0 0 ${this.circularDiameter || 0} ${this.circularDiameter || 0}` }, h("circle", { key: '96ba0e0a054be9be9f707903ae8d8075ab92b360', cx: `${x}`, cy: `${y}`, r: `${r}` }), h("circle", { key: 'b986b1626971075e86063a898948df490856cd3d', cx: `${x}`, cy: `${y}`, r: `${r}` }))))), label && size !== "icon" && (h("ic-typography", { key: '5d3ceea4f339006c6389a99ea52befaea885988a', id: "ic-loading-label", class: "ic-loading-label", role: "status", variant: this.getLabelVariant() }, h("p", { key: '5dfc851559b8ef4fb2b4fca4a002d87ad1b52d43' }, this.indicatorLabel))))));
    }
    static get is() { return "ic-loading-indicator"; }
    static get encapsulation() { return "shadow"; }
    static get originalStyleUrls() {
        return {
            "$": ["ic-loading-indicator.css"]
        };
    }
    static get styleUrls() {
        return {
            "$": ["ic-loading-indicator.css"]
        };
    }
    static get properties() {
        return {
            "description": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string | undefined",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "The description that will be set as the aria-label of the loading indicator when not using a visible label."
                },
                "getter": false,
                "setter": false,
                "attribute": "description",
                "reflect": false,
                "defaultValue": "\"Loading\""
            },
            "fullWidth": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean | undefined",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "If `true`, when linear, the full-width variant (i.e. without a border radius) will be displayed."
                },
                "getter": false,
                "setter": false,
                "attribute": "full-width",
                "reflect": true,
                "defaultValue": "false"
            },
            "innerLabel": {
                "type": "number",
                "mutable": false,
                "complexType": {
                    "original": "number",
                    "resolved": "number | undefined",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [{
                            "name": "internal",
                            "text": "The step number of a compact step, managed by ic-step."
                        }],
                    "text": ""
                },
                "getter": false,
                "setter": false,
                "attribute": "inner-label",
                "reflect": false
            },
            "labelDuration": {
                "type": "number",
                "mutable": false,
                "complexType": {
                    "original": "number",
                    "resolved": "number | undefined",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "The time in milliseconds before the label changes."
                },
                "getter": false,
                "setter": false,
                "attribute": "label-duration",
                "reflect": false,
                "defaultValue": "8000"
            },
            "max": {
                "type": "number",
                "mutable": false,
                "complexType": {
                    "original": "number",
                    "resolved": "number | undefined",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "The maximum value that the progress value can take.\nUsed to calculate the proportional width of the progress bar."
                },
                "getter": false,
                "setter": false,
                "attribute": "max",
                "reflect": false,
                "defaultValue": "100"
            },
            "min": {
                "type": "number",
                "mutable": false,
                "complexType": {
                    "original": "number",
                    "resolved": "number | undefined",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "The minimum value that the progress value can take.\nUsed to calculate the proportional width of the progress bar."
                },
                "getter": false,
                "setter": false,
                "attribute": "min",
                "reflect": false,
                "defaultValue": "0"
            },
            "monochrome": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean | undefined",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "If `true`, the element will display as black and white."
                },
                "getter": false,
                "setter": false,
                "attribute": "monochrome",
                "reflect": false,
                "defaultValue": "false"
            },
            "size": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "IcLoadingSizes",
                    "resolved": "\"icon\" | \"large\" | \"medium\" | \"small\" | undefined",
                    "references": {
                        "IcLoadingSizes": {
                            "location": "import",
                            "path": "./ic-loading-indicator.types",
                            "id": "src/components/ic-loading-indicator/ic-loading-indicator.types.tsx::IcLoadingSizes"
                        }
                    }
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "The size of the loading indicator."
                },
                "getter": false,
                "setter": false,
                "attribute": "size",
                "reflect": true,
                "defaultValue": "\"medium\""
            },
            "type": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "IcLoadingTypes",
                    "resolved": "\"circular\" | \"linear\" | undefined",
                    "references": {
                        "IcLoadingTypes": {
                            "location": "import",
                            "path": "./ic-loading-indicator.types",
                            "id": "src/components/ic-loading-indicator/ic-loading-indicator.types.tsx::IcLoadingTypes"
                        }
                    }
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "The type of indicator, either linear or circular."
                },
                "getter": false,
                "setter": false,
                "attribute": "type",
                "reflect": true,
                "defaultValue": "\"circular\""
            },
            "label": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string | string[]",
                    "resolved": "string | string[] | undefined",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "The label to be displayed beneath the loading indicator.\nDisplay a changing label by supplying an array of messages."
                },
                "getter": false,
                "setter": false,
                "attribute": "label",
                "reflect": false
            },
            "progress": {
                "type": "number",
                "mutable": false,
                "complexType": {
                    "original": "number",
                    "resolved": "number | undefined",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "The current amount of progress made.\nIf not provided, component acts as an indeterminate loading indicator."
                },
                "getter": false,
                "setter": false,
                "attribute": "progress",
                "reflect": false
            },
            "theme": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "IcThemeMode",
                    "resolved": "\"dark\" | \"inherit\" | \"light\" | undefined",
                    "references": {
                        "IcThemeMode": {
                            "location": "import",
                            "path": "../../utils/types",
                            "id": "src/utils/types.ts::IcThemeMode"
                        }
                    }
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "Sets the theme color to the dark or light theme color. \"inherit\" will set the color based on the system settings or ic-theme component."
                },
                "getter": false,
                "setter": false,
                "attribute": "theme",
                "reflect": false,
                "defaultValue": "\"inherit\""
            }
        };
    }
    static get states() {
        return {
            "circularDiameter": {},
            "circularLineWidth": {},
            "indeterminate": {},
            "indicatorLabel": {},
            "clipInnerElement": {}
        };
    }
    static get elementRef() { return "el"; }
    static get watchers() {
        return [{
                "propName": "label",
                "methodName": "watchPropHandler"
            }, {
                "propName": "progress",
                "methodName": "watchProgressHandler"
            }];
    }
}
//# sourceMappingURL=ic-loading-indicator.js.map
