/*!
 * Custom elements for Nanopore-Digital Web applications
 */
import { Build, Host, } from "@stencil/core";
import { h } from "../../utils/renderer";
/**
 * Utilities for displaying images; standard or background.
 *
 * @status deprecated
 * @version 1.0.0
 *
 * @slot - Main slot. Only relevant with `<nano-img background>`
 */
export class Img {
    io;
    _srcSet = {};
    host;
    loadSrc;
    loadError;
    hasLoaded = false;
    imgStates = null;
    _src;
    _srcChanged() {
        this.hasLoaded = false;
        this.addIO();
    }
    /** This attribute defines the alternative text describing the image.
     * Users will see this text displayed if the image URL is wrong, or if the image is not yet downloaded. */
    alt;
    /** The image URL. This attribute is mandatory for the `<img>` element. */
    src;
    srcChanged() {
        this._src = this.src;
    }
    /** Optional list string providing media sizes with corresponding image srcs.
     * i.e. show img-x at 300px wide. Format `srcSet="200w src/imgSmall.jpg, 500h src/imgMed.png"` */
    srcSet;
    srcSetChanged() {
        if (!this.srcSet)
            return;
        delete this._srcSet;
        this._srcSet = {};
        this.imgStates = this.srcSet
            .split(',')
            .map((bpSrc) => {
            const [bp, src] = bpSrc.split(' ').filter((bp) => bp.length);
            this._srcSet[bp] = { src: src, active: false };
            return bp;
        })
            .join(', ');
    }
    /** Render image lazily, when it comes into the browser viewport **/
    lazy = true;
    lazyChanged() {
        if (!this.lazy)
            this.load();
    }
    /** Render the image as a background image **/
    background;
    /** When the image is rendered as a background, and there is no preset dimensions of the component,
     * you can set how the component height will be set. Via image size or via the content **/
    autoHeight = 'content';
    /** Emitted when the img src has been set */
    nanoImgWillLoad;
    /** Emitted when the image has finished loading */
    nanoImgDidLoad;
    /** Emitted when the img fails to load */
    nanoImgError;
    addIO() {
        if (!this._src || this.hasLoaded)
            return;
        if (!this.lazy) {
            this.load();
            return;
        }
        if (typeof window !== 'undefined' &&
            'IntersectionObserver' in window) {
            this.removeIO();
            this.io = new IntersectionObserver((data) => {
                if (data[0].isIntersecting) {
                    this.load();
                    this.removeIO();
                }
            });
            this.io.observe(this.host);
        }
        else
            setTimeout(() => this.load(), 200);
    }
    load() {
        this.loadError = this.onError;
        this.loadSrc = this._src;
        this.nanoImgWillLoad.emit();
    }
    onLoad = () => {
        this.nanoImgDidLoad.emit();
        setTimeout(() => (this.hasLoaded = true), 50);
    };
    onError = () => {
        this.nanoImgError.emit();
    };
    onResize = (e) => {
        Object.entries(e.detail).forEach(([bp, active]) => {
            this._srcSet[bp].active = !!active;
        });
        // sort and find the highest sized matching image.
        const srcOpts = [];
        Object.keys(this._srcSet)
            .sort()
            .forEach((bp) => {
            if (this._srcSet[bp].active)
                srcOpts.push(this._srcSet[bp].src);
        });
        if (srcOpts.length)
            this._src = srcOpts.slice(-1)[0];
        // no matching image? Set back to default
        else
            this._src = this.src;
    };
    removeIO() {
        if (this.io) {
            this.io.disconnect();
            this.io = undefined;
        }
    }
    connectedCallback() {
        this.srcChanged();
        this.srcSetChanged();
        this.lazyChanged();
    }
    componentDidLoad() {
        this.addIO();
    }
    disconnectedCallback() {
        this.removeIO();
    }
    render() {
        const bgStyle = this.loadSrc
            ? { 'background-image': `url(${this.loadSrc})` }
            : {};
        return (h(Host, { key: 'f8774fc9ad6e94727378337c2f405a068a7c88fb', class: "nano-img" }, h("div", { key: '15ae3c8ea944c8f0eab8616194f44fc1033e8fe2', class: "img" }, h("div", { key: 'ec3f433ded23dcb7fc57e53b0ecaba789ba492e0', class: "img__loader n-loader-skeleton" }, "Loading"), !!this.background && (h("div", { key: '8f4e8c9d595a31b477b0ae3f9e135f6b5c3f0e69', class: {
                loaded: this.hasLoaded,
                img__bg: true,
                'no-height': this.autoHeight === 'image',
            }, style: bgStyle }, h("slot", { key: '29bab2a5c86b3dfe18db8936af77674c44d743d0' }))), h("img", { key: 'e6731b48ed137d97aa98e64dc55488d56724f672', class: {
                img__image: true,
                loaded: this.hasLoaded,
                hide: this.background,
                'no-height': this.autoHeight === 'content',
            }, decoding: "async", src: Build.isServer ? this.src : this.loadSrc, loading: Build.isServer && this.lazy ? 'lazy' : undefined, alt: this.alt, onLoad: this.onLoad, onError: this.loadError }), h("nano-resize-observe", { key: '0f1ce7d8b82adc19bfa459ff2adae708a4263c6e', class: "img__observer", onNanoResizeStateChange: this.onResize, states: this.imgStates }))));
    }
    static get is() { return "nano-img"; }
    static get encapsulation() { return "shadow"; }
    static get originalStyleUrls() {
        return {
            "$": ["img.scss"]
        };
    }
    static get styleUrls() {
        return {
            "$": ["img.css"]
        };
    }
    static get properties() {
        return {
            "alt": {
                "type": "string",
                "attribute": "alt",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "This attribute defines the alternative text describing the image.\nUsers will see this text displayed if the image URL is wrong, or if the image is not yet downloaded."
                },
                "getter": false,
                "setter": false,
                "reflect": false
            },
            "src": {
                "type": "string",
                "attribute": "src",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": true,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "The image URL. This attribute is mandatory for the `<img>` element."
                },
                "getter": false,
                "setter": false,
                "reflect": false
            },
            "srcSet": {
                "type": "string",
                "attribute": "src-set",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "Optional list string providing media sizes with corresponding image srcs.\ni.e. show img-x at 300px wide. Format `srcSet=\"200w src/imgSmall.jpg, 500h src/imgMed.png\"`"
                },
                "getter": false,
                "setter": false,
                "reflect": false
            },
            "lazy": {
                "type": "boolean",
                "attribute": "lazy",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Render image lazily, when it comes into the browser viewport *"
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "defaultValue": "true"
            },
            "background": {
                "type": "boolean",
                "attribute": "background",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "Render the image as a background image *"
                },
                "getter": false,
                "setter": false,
                "reflect": false
            },
            "autoHeight": {
                "type": "string",
                "attribute": "auto-height",
                "mutable": false,
                "complexType": {
                    "original": "'content' | 'image'",
                    "resolved": "\"content\" | \"image\"",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "When the image is rendered as a background, and there is no preset dimensions of the component,\nyou can set how the component height will be set. Via image size or via the content *"
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "defaultValue": "'content'"
            }
        };
    }
    static get states() {
        return {
            "loadSrc": {},
            "loadError": {},
            "hasLoaded": {},
            "imgStates": {},
            "_src": {}
        };
    }
    static get events() {
        return [{
                "method": "nanoImgWillLoad",
                "name": "nanoImgWillLoad",
                "bubbles": true,
                "cancelable": true,
                "composed": true,
                "docs": {
                    "tags": [],
                    "text": "Emitted when the img src has been set"
                },
                "complexType": {
                    "original": "void",
                    "resolved": "void",
                    "references": {}
                }
            }, {
                "method": "nanoImgDidLoad",
                "name": "nanoImgDidLoad",
                "bubbles": true,
                "cancelable": true,
                "composed": true,
                "docs": {
                    "tags": [],
                    "text": "Emitted when the image has finished loading"
                },
                "complexType": {
                    "original": "void",
                    "resolved": "void",
                    "references": {}
                }
            }, {
                "method": "nanoImgError",
                "name": "nanoImgError",
                "bubbles": true,
                "cancelable": true,
                "composed": true,
                "docs": {
                    "tags": [],
                    "text": "Emitted when the img fails to load"
                },
                "complexType": {
                    "original": "void",
                    "resolved": "void",
                    "references": {}
                }
            }];
    }
    static get elementRef() { return "host"; }
    static get watchers() {
        return [{
                "propName": "_src",
                "methodName": "_srcChanged"
            }, {
                "propName": "src",
                "methodName": "srcChanged"
            }, {
                "propName": "srcSet",
                "methodName": "srcSetChanged"
            }, {
                "propName": "lazy",
                "methodName": "lazyChanged"
            }];
    }
}
