/*!
 * Custom elements for Nanopore-Digital Web applications
 */
import { Host, Build, } from "@stencil/core";
import { h } from "../../utils/renderer";
import { animations, easings } from "./animations";
/**
 * Animate elements declaratively with [~100 baked-in presets](https://animate.style/), or make your own with custom keyframes.
 * Powered by the [Web Animations API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Animations_API).
 *
 * @version 6.0.0
 * @status stable
 *
 * @slot - The element to animate. Avoid slotting in more than one element, as subsequent ones will be ignored. To animate multiple elements, either wrap them in a single container or use multiple *nano-animation* elements.
 */
export class NanoAnimation {
    animation;
    hasStarted = false;
    defaultSlot;
    /** The name of the built-in animation to use. For custom animations, use the `keyframes` prop. */
    name = 'none';
    /**
     * Plays the animation. When omitted, the animation will be paused. This attribute will be automatically removed when
     * the animation finishes or gets canceled.
     */
    play = false;
    /** The number of milliseconds to delay the start of the animation. */
    delay = 0;
    /**
     * Determines the direction of playback as well as the behavior when reaching the end of an iteration.
     * [Learn more](https://developer.mozilla.org/en-US/docs/Web/CSS/animation-direction)
     */
    direction = 'normal';
    /** The number of milliseconds each iteration of the animation takes to complete. */
    duration = 1000;
    /**
     * The easing function to use for the animation. This can be a easing function or a custom easing function
     * such as `cubic-bezier(0, 1, .76, 1.14)`.
     */
    easing = 'ease';
    /** The number of milliseconds to delay after the active period of an animation sequence. */
    endDelay = 0;
    /** Sets how the animation applies styles to its target before and after its execution. */
    fill = 'auto';
    /** The number of iterations to run before the animation completes. Defaults to `Infinity`, which loops. */
    iterations = Infinity;
    /** The offset at which to start the animation, usually between 0 (start) and 1 (end). */
    iterationStart = 0;
    /** The keyframes to use for the animation. If this is set, `name` will be ignored. */
    keyframes;
    /**
     * Sets the animation's playback rate. The default is `1`, which plays the animation at a normal speed. Setting this
     * to `2`, for example, will double the animation's speed. A negative value can be used to reverse the animation. This
     * value can be changed without causing the animation to restart.
     */
    playbackRate = 1;
    /** Emitted when the animation is canceled. */
    nanoCancel;
    /** Emitted when the animation finishes. */
    nanoFinish;
    /** Emitted when the animation starts. */
    nanoStart;
    /** Gets and sets the current animation time. */
    get currentTime() {
        return this.animation?.currentTime ?? 0;
    }
    set currentTime(time) {
        if (this.animation) {
            this.animation.currentTime = time;
        }
    }
    connectedCallback() {
        this.createAnimation();
    }
    disconnectedCallback() {
        this.destroyAnimation();
    }
    handleAnimationFinish = () => {
        this.play = false;
        this.hasStarted = false;
        this.nanoFinish.emit();
    };
    handleAnimationCancel = () => {
        this.play = false;
        this.hasStarted = false;
        this.nanoCancel.emit();
    };
    handleSlotChange = () => {
        this.destroyAnimation();
        this.createAnimation();
    };
    async createAnimation() {
        if (!this.defaultSlot || Build.isServer)
            return;
        const easing = easings[this.easing] ?? this.easing;
        const keyframes = this.keyframes ??
            animations[this.name];
        const slot = this.defaultSlot;
        const element = slot.assignedElements()[0];
        if (!element || !keyframes) {
            return false;
        }
        this.destroyAnimation();
        this.animation = element.animate(keyframes, {
            delay: this.delay,
            direction: this.direction,
            duration: this.duration,
            easing,
            endDelay: this.endDelay,
            fill: this.fill,
            iterationStart: this.iterationStart,
            iterations: this.iterations,
        });
        this.animation.playbackRate = this.playbackRate;
        this.animation.addEventListener('cancel', this.handleAnimationCancel);
        this.animation.addEventListener('finish', this.handleAnimationFinish);
        if (this.play) {
            this.hasStarted = true;
            this.nanoStart.emit();
        }
        else {
            this.animation.pause();
        }
        return true;
    }
    destroyAnimation() {
        if (this.animation) {
            this.animation.cancel();
            this.animation.removeEventListener('cancel', this.handleAnimationCancel);
            this.animation.removeEventListener('finish', this.handleAnimationFinish);
            this.hasStarted = false;
        }
    }
    handleAnimationChange() {
        this.createAnimation();
    }
    handlePlayChange() {
        if (this.animation) {
            if (this.play && !this.hasStarted) {
                this.hasStarted = true;
                this.nanoStart.emit();
            }
            if (this.play) {
                this.animation.play();
            }
            else {
                this.animation.pause();
            }
            return true;
        }
        return false;
    }
    handlePlaybackRateChange() {
        if (this.animation) {
            this.animation.playbackRate = this.playbackRate;
        }
    }
    /** Clears all keyframe effects caused by this animation and aborts its playback. */
    async cancel() {
        this.animation?.cancel();
    }
    /** Sets the playback time to the end of the animation corresponding to the current playback direction. */
    async finish() {
        this.animation?.finish();
    }
    render() {
        return (h(Host, { key: '566f725817c91b577fc31a6eea9d5baecf3b481e', class: "nano-animation" }, h("slot", { key: '968e1c43d7e3a73d0662f8595ad08c3fa1a44044', ref: (slot) => {
                this.defaultSlot = slot;
            }, onSlotchange: this.handleSlotChange })));
    }
    static get is() { return "nano-animation"; }
    static get encapsulation() { return "shadow"; }
    static get styles() { return ":host {\n      display: contents;\n    }"; }
    static get properties() {
        return {
            "name": {
                "type": "string",
                "attribute": "name",
                "mutable": false,
                "complexType": {
                    "original": "AnimationName | 'none'",
                    "resolved": "\"flip\" | \"none\" | \"bounce\" | \"flash\" | \"headShake\" | \"heartBeat\" | \"jello\" | \"pulse\" | \"rubberBand\" | \"shake\" | \"shakeX\" | \"shakeY\" | \"swing\" | \"tada\" | \"wobble\" | \"backInDown\" | \"backInLeft\" | \"backInRight\" | \"backInUp\" | \"backOutDown\" | \"backOutLeft\" | \"backOutRight\" | \"backOutUp\" | \"bounceIn\" | \"bounceInDown\" | \"bounceInLeft\" | \"bounceInRight\" | \"bounceInUp\" | \"bounceOut\" | \"bounceOutDown\" | \"bounceOutLeft\" | \"bounceOutRight\" | \"bounceOutUp\" | \"fadeIn\" | \"fadeInBottomLeft\" | \"fadeInBottomRight\" | \"fadeInDown\" | \"fadeInDownBig\" | \"fadeInLeft\" | \"fadeInLeftBig\" | \"fadeInRight\" | \"fadeInRightBig\" | \"fadeInTopLeft\" | \"fadeInTopRight\" | \"fadeInUp\" | \"fadeInUpBig\" | \"fadeOut\" | \"fadeOutBottomLeft\" | \"fadeOutBottomRight\" | \"fadeOutDown\" | \"fadeOutDownBig\" | \"fadeOutLeft\" | \"fadeOutLeftBig\" | \"fadeOutRight\" | \"fadeOutRightBig\" | \"fadeOutTopLeft\" | \"fadeOutTopRight\" | \"fadeOutUp\" | \"fadeOutUpBig\" | \"flipInX\" | \"flipInY\" | \"flipOutX\" | \"flipOutY\" | \"lightSpeedInLeft\" | \"lightSpeedInRight\" | \"lightSpeedOutLeft\" | \"lightSpeedOutRight\" | \"rotateIn\" | \"rotateInDownLeft\" | \"rotateInDownRight\" | \"rotateInUpLeft\" | \"rotateInUpRight\" | \"rotateOut\" | \"rotateOutDownLeft\" | \"rotateOutDownRight\" | \"rotateOutUpLeft\" | \"rotateOutUpRight\" | \"slideInDown\" | \"slideInLeft\" | \"slideInRight\" | \"slideInUp\" | \"slideOutDown\" | \"slideOutLeft\" | \"slideOutRight\" | \"slideOutUp\" | \"hinge\" | \"jackInTheBox\" | \"rollIn\" | \"rollOut\" | \"zoomIn\" | \"zoomInDown\" | \"zoomInLeft\" | \"zoomInRight\" | \"zoomInUp\" | \"zoomOut\" | \"zoomOutDown\" | \"zoomOutLeft\" | \"zoomOutRight\" | \"zoomOutUp\"",
                    "references": {
                        "AnimationName": {
                            "location": "import",
                            "path": "./animation-interface",
                            "id": "src/components/animation/animation-interface.d.ts::AnimationName"
                        }
                    }
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "The name of the built-in animation to use. For custom animations, use the `keyframes` prop."
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "defaultValue": "'none'"
            },
            "play": {
                "type": "boolean",
                "attribute": "play",
                "mutable": true,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Plays the animation. When omitted, the animation will be paused. This attribute will be automatically removed when\nthe animation finishes or gets canceled."
                },
                "getter": false,
                "setter": false,
                "reflect": true,
                "defaultValue": "false"
            },
            "delay": {
                "type": "number",
                "attribute": "delay",
                "mutable": false,
                "complexType": {
                    "original": "number",
                    "resolved": "number",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "The number of milliseconds to delay the start of the animation."
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "defaultValue": "0"
            },
            "direction": {
                "type": "string",
                "attribute": "direction",
                "mutable": false,
                "complexType": {
                    "original": "PlaybackDirection",
                    "resolved": "\"alternate\" | \"alternate-reverse\" | \"normal\" | \"reverse\"",
                    "references": {
                        "PlaybackDirection": {
                            "location": "global",
                            "id": "global::PlaybackDirection"
                        }
                    }
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Determines the direction of playback as well as the behavior when reaching the end of an iteration.\n[Learn more](https://developer.mozilla.org/en-US/docs/Web/CSS/animation-direction)"
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "defaultValue": "'normal'"
            },
            "duration": {
                "type": "number",
                "attribute": "duration",
                "mutable": false,
                "complexType": {
                    "original": "number",
                    "resolved": "number",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "The number of milliseconds each iteration of the animation takes to complete."
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "defaultValue": "1000"
            },
            "easing": {
                "type": "string",
                "attribute": "easing",
                "mutable": false,
                "complexType": {
                    "original": "AnimationEasing",
                    "resolved": "\"linear\" | \"ease\" | \"easeIn\" | \"easeOut\" | \"easeInOut\" | \"easeInSine\" | \"easeOutSine\" | \"easeInOutSine\" | \"easeInQuad\" | \"easeOutQuad\" | \"easeInOutQuad\" | \"easeInCubic\" | \"easeOutCubic\" | \"easeInOutCubic\" | \"easeInQuart\" | \"easeOutQuart\" | \"easeInOutQuart\" | \"easeInQuint\" | \"easeOutQuint\" | \"easeInOutQuint\" | \"easeInExpo\" | \"easeOutExpo\" | \"easeInOutExpo\" | \"easeInCirc\" | \"easeOutCirc\" | \"easeInOutCirc\" | \"easeInBack\" | \"easeOutBack\" | \"easeInOutBack\"",
                    "references": {
                        "AnimationEasing": {
                            "location": "import",
                            "path": "./animation-interface",
                            "id": "src/components/animation/animation-interface.d.ts::AnimationEasing"
                        }
                    }
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "The easing function to use for the animation. This can be a easing function or a custom easing function\nsuch as `cubic-bezier(0, 1, .76, 1.14)`."
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "defaultValue": "'ease'"
            },
            "endDelay": {
                "type": "number",
                "attribute": "end-delay",
                "mutable": false,
                "complexType": {
                    "original": "number",
                    "resolved": "number",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "The number of milliseconds to delay after the active period of an animation sequence."
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "defaultValue": "0"
            },
            "fill": {
                "type": "string",
                "attribute": "fill",
                "mutable": false,
                "complexType": {
                    "original": "FillMode",
                    "resolved": "\"auto\" | \"backwards\" | \"both\" | \"forwards\" | \"none\"",
                    "references": {
                        "FillMode": {
                            "location": "global",
                            "id": "global::FillMode"
                        }
                    }
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Sets how the animation applies styles to its target before and after its execution."
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "defaultValue": "'auto'"
            },
            "iterations": {
                "type": "number",
                "attribute": "iterations",
                "mutable": false,
                "complexType": {
                    "original": "number",
                    "resolved": "number",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "The number of iterations to run before the animation completes. Defaults to `Infinity`, which loops."
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "defaultValue": "Infinity"
            },
            "iterationStart": {
                "type": "number",
                "attribute": "iteration-start",
                "mutable": false,
                "complexType": {
                    "original": "number",
                    "resolved": "number",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "The offset at which to start the animation, usually between 0 (start) and 1 (end)."
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "defaultValue": "0"
            },
            "keyframes": {
                "type": "unknown",
                "attribute": "keyframes",
                "mutable": false,
                "complexType": {
                    "original": "Keyframe[]",
                    "resolved": "Keyframe[]",
                    "references": {
                        "Keyframe": {
                            "location": "global",
                            "id": "global::Keyframe"
                        }
                    }
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "The keyframes to use for the animation. If this is set, `name` will be ignored."
                },
                "getter": false,
                "setter": false
            },
            "playbackRate": {
                "type": "number",
                "attribute": "playback-rate",
                "mutable": false,
                "complexType": {
                    "original": "number",
                    "resolved": "number",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Sets the animation's playback rate. The default is `1`, which plays the animation at a normal speed. Setting this\nto `2`, for example, will double the animation's speed. A negative value can be used to reverse the animation. This\nvalue can be changed without causing the animation to restart."
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "defaultValue": "1"
            },
            "currentTime": {
                "type": "number",
                "attribute": "current-time",
                "mutable": false,
                "complexType": {
                    "original": "CSSNumberish",
                    "resolved": "CSSNumericValue | number",
                    "references": {
                        "CSSNumberish": {
                            "location": "global",
                            "id": "global::CSSNumberish"
                        }
                    }
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Gets and sets the current animation time."
                },
                "getter": true,
                "setter": true,
                "reflect": false
            }
        };
    }
    static get states() {
        return {
            "defaultSlot": {}
        };
    }
    static get events() {
        return [{
                "method": "nanoCancel",
                "name": "nanoCancel",
                "bubbles": true,
                "cancelable": true,
                "composed": true,
                "docs": {
                    "tags": [],
                    "text": "Emitted when the animation is canceled."
                },
                "complexType": {
                    "original": "any",
                    "resolved": "any",
                    "references": {}
                }
            }, {
                "method": "nanoFinish",
                "name": "nanoFinish",
                "bubbles": true,
                "cancelable": true,
                "composed": true,
                "docs": {
                    "tags": [],
                    "text": "Emitted when the animation finishes."
                },
                "complexType": {
                    "original": "any",
                    "resolved": "any",
                    "references": {}
                }
            }, {
                "method": "nanoStart",
                "name": "nanoStart",
                "bubbles": true,
                "cancelable": true,
                "composed": true,
                "docs": {
                    "tags": [],
                    "text": "Emitted when the animation starts."
                },
                "complexType": {
                    "original": "any",
                    "resolved": "any",
                    "references": {}
                }
            }];
    }
    static get methods() {
        return {
            "cancel": {
                "complexType": {
                    "signature": "() => Promise<void>",
                    "parameters": [],
                    "references": {
                        "Promise": {
                            "location": "global",
                            "id": "global::Promise"
                        }
                    },
                    "return": "Promise<void>"
                },
                "docs": {
                    "text": "Clears all keyframe effects caused by this animation and aborts its playback.",
                    "tags": []
                }
            },
            "finish": {
                "complexType": {
                    "signature": "() => Promise<void>",
                    "parameters": [],
                    "references": {
                        "Promise": {
                            "location": "global",
                            "id": "global::Promise"
                        }
                    },
                    "return": "Promise<void>"
                },
                "docs": {
                    "text": "Sets the playback time to the end of the animation corresponding to the current playback direction.",
                    "tags": []
                }
            }
        };
    }
    static get watchers() {
        return [{
                "propName": "defaultSlot",
                "methodName": "createAnimation"
            }, {
                "propName": "name",
                "methodName": "handleAnimationChange"
            }, {
                "propName": "delay",
                "methodName": "handleAnimationChange"
            }, {
                "propName": "direction",
                "methodName": "handleAnimationChange"
            }, {
                "propName": "duration",
                "methodName": "handleAnimationChange"
            }, {
                "propName": "easing",
                "methodName": "handleAnimationChange"
            }, {
                "propName": "endDelay",
                "methodName": "handleAnimationChange"
            }, {
                "propName": "fill",
                "methodName": "handleAnimationChange"
            }, {
                "propName": "iterations",
                "methodName": "handleAnimationChange"
            }, {
                "propName": "iterationStart",
                "methodName": "handleAnimationChange"
            }, {
                "propName": "keyframes",
                "methodName": "handleAnimationChange"
            }, {
                "propName": "play",
                "methodName": "handlePlayChange"
            }, {
                "propName": "playbackRate",
                "methodName": "handlePlaybackRateChange"
            }];
    }
}
