import { ToastKind } from '../../enums/toast-kind.enum';
export class EdelToastgroupComponent {
    constructor() {
        this.toasts = [];
        this.duration = 10000;
        this.canClose = true;
        this.now = () => Date.now();
    }
    hostData() {
        return {
            class: 'toastgroup'
        };
    }
    render() {
        return [
            this.toasts.map(toast => (h("edel-toast", { kind: toast.kind, "no-close": !toast.options.canClose, onClose: toast.close }, toast.message))),
            h("slot", null)
        ];
    }
    cleanExpiredToasts() {
        const current = this.currentTimestamp();
        this.removeToastsWhere(toast => toast.options.expire !== 0 && toast.options.expire <= current, true);
    }
    good(message, options = {}) {
        return this.presentToast(ToastKind.good, message, options);
    }
    bad(message, options = {}) {
        return this.presentToast(ToastKind.bad, message, options);
    }
    info(message, options = {}) {
        return this.presentToast(ToastKind.info, message, options);
    }
    warning(message, options = {}) {
        return this.presentToast(ToastKind.warning, message, options);
    }
    componentDidLoad() {
        this.didLoad.emit(this);
    }
    presentToast(kind, message, options) {
        const closable = {
            message,
            kind,
            options: this.canonicalToastOptions(options),
            close: () => this.removeToast(closable)
        };
        this.toasts = [closable, ...this.toasts];
        this.scheduleCleanFor(closable);
        return closable;
    }
    currentTimestamp() {
        return this.now instanceof Function ? this.now() : this.now;
    }
    expiration(options) {
        const duration = typeof options.duration === 'number' ? options.duration : this.duration;
        if (duration === 0)
            return 0;
        const expire = typeof options.expire === 'number'
            ? options.expire
            : this.currentTimestamp() + duration;
        return expire;
    }
    scheduleCleanFor(closable) {
        if (this.now instanceof Function) {
            setTimeout(() => this.cleanExpiredToasts(), closable.options.expire - this.currentTimestamp());
        }
    }
    removeToast(closable) {
        this.removeToastsWhere(toast => toast === closable, false);
    }
    removeToastsWhere(predicate, expired) {
        this.toasts = this.toasts.filter(toast => {
            if (predicate(toast)) {
                toast.options.didClose(expired);
                return false;
            }
            else {
                return true;
            }
        });
    }
    canonicalToastOptions(options) {
        return {
            canClose: typeof options.canClose === 'boolean'
                ? options.canClose
                : this.canClose,
            expire: this.expiration(options),
            didClose: options.didClose || (() => void 0)
        };
    }
    static get is() { return "edel-toastgroup"; }
    static get properties() { return {
        "bad": {
            "method": true
        },
        "canClose": {
            "type": Boolean,
            "attr": "can-close"
        },
        "duration": {
            "type": Number,
            "attr": "duration"
        },
        "good": {
            "method": true
        },
        "info": {
            "method": true
        },
        "now": {
            "type": Number,
            "attr": "now",
            "watchCallbacks": ["cleanExpiredToasts"]
        },
        "toasts": {
            "state": true
        },
        "warning": {
            "method": true
        }
    }; }
    static get events() { return [{
            "name": "didLoad",
            "method": "didLoad",
            "bubbles": true,
            "cancelable": true,
            "composed": true
        }]; }
}
