<template>
    <component :is="tag" :class="bem({ active: invert ? !active : active })" :style="styleVars" />
</template>

<script>
import { cssEasings, keywordsToAnimationCssVars } from '../utils/animation.js';
//import gsap from 'gsap';

export default {
    name: 'px-animate',
    props: {
        tag: { type: String, default: 'div' },

        enabled: { type: Boolean, default: true },

        active: { type: Boolean, default: false },

        invert: { type: Boolean, default: false },

        /**
         * A string or object that reprensents the animation in it's active state (see animation.js
         * for details).
         */
        animation: { type: [String, Object], default: '' },

        /**
         * The duration of the animation in seconds.
         */
        duration: { type: Number, default: null },

        /**
         * The easing function to be used for the animation.
         */
        easing: { type: String, default: null },

        /**
         * A delay (in seconds) to wait before starting the animation once the active state is entered.
         */
        delay: { type: Number, default: null },

        /**
         * When true we animate the element if active on load, otherwise it behaves like CSS (where
         * we snap to the initial value). Only applies if active when loaded.
         */
        animateOnLoad: { type: Boolean, default: false },

        /**
         * An optional delay (in seconts) to wait before animating the element on load when
         * animateOnLoad is true.
         */
        animateOnLoadDelay: { type: Number, default: 0 },
    },
    // data() { return { b: 0 }; },
    computed: {
        styleVars() {
            if (!this.enabled || !this.animation?.length) {
                return null;
            }

            const ease = this.easing in cssEasings ? cssEasings[this.easing] : this.easing;

            const vars = keywordsToAnimationCssVars(this.animation, 'px-animate', {
                duration: this.duration !== null ? this.duration + 's' : null,
                delay: this.delay !== null ? this.delay + 's' : null,
                ease: ease !== null ? ease : null,
            });

            return vars;
        },
    },
    watch: {},
    mounted() {
        if (this.active) {
            if (this.animateOnLoad) {
                setTimeout(() => {
                    this.tween?.play();
                }, this.animateOnLoadDelay * 1000);
            } else {
                this.tween?.progress(1);
            }
        }
    },
    methods: {},
};
</script>

<style lang="scss">
@use '../styles/px.scss' as *;

.px-animate {
    transform-origin: center center;
    perspective: 1000px;

    @include transition(
        opacity visibility transform,
        var(--px-animate-duration, 0.75s),
        var(--px-animate-ease, ease-out)
    );

    &--active {
        opacity: var(--px-animate-opacity, 1);
        transform: var(--px-animate-transform, none);
        visibility: var(--px-animate-transform, initial);
    }
}
</style>
