import { CubicEase, EasingFunction } from "../../Animations/easing.js";
import { Animation } from "../../Animations/animation.js";
/**
 * Animate camera property changes with an interpolation effect
 * @see https://doc.babylonjs.com/features/featuresDeepDive/behaviors/cameraBehaviors
 */
export class InterpolatingBehavior {
    /**
     * Gets the name of the behavior.
     */
    get name() {
        return "Interpolating";
    }
    /**
     * Initializes the behavior
     */
    constructor() {
        /**
         * The easing function to use for interpolation
         */
        this.easingFunction = new CubicEase();
        /**
         * The easing mode (default is EASINGMODE_EASEINOUT)
         */
        this.easingMode = EasingFunction.EASINGMODE_EASEINOUT;
        /**
         * Duration of the animation in milliseconds
         */
        this.transitionDuration = 450;
        this._attachedCamera = null;
        this._animatables = new Map();
        this.easingFunction.setEasingMode(this.easingMode);
    }
    /**
     * Initializes the behavior
     */
    init() {
        // Nothing to do on init
    }
    /**
     * Attaches the behavior to a camera
     * @param camera The camera to attach to
     */
    attach(camera) {
        this._attachedCamera = camera;
    }
    /**
     * Detaches the behavior from the camera
     */
    detach() {
        if (!this._attachedCamera) {
            return;
        }
        this.stopAllAnimations();
        this._attachedCamera = null;
    }
    get isInterpolating() {
        return this._animatables.size > 0;
    }
    /**
     * Stops and removes all animations
     */
    stopAllAnimations() {
        if (this._attachedCamera) {
            this._animatables.forEach((animatable) => animatable.stop());
        }
        this._animatables.clear();
        this._promiseResolve?.();
        this._promiseResolve = undefined;
    }
    updateProperties(properties) {
        properties.forEach((value, key) => {
            const animatable = this._animatables.get(key);
            animatable && (animatable.target = value);
        });
    }
    async animatePropertiesAsync(properties, transitionDuration = this.transitionDuration, easingFn = this.easingFunction) {
        const promise = new Promise((resolve) => {
            this._promiseResolve = resolve;
            this.stopAllAnimations();
            if (!this._attachedCamera) {
                this._promiseResolve = undefined;
                return resolve();
            }
            const camera = this._attachedCamera;
            const scene = camera.getScene();
            const checkClear = (animation) => {
                this._animatables.delete(animation);
                if (this._animatables.size === 0) {
                    this._promiseResolve = undefined;
                    resolve();
                }
            };
            properties.forEach((value, key) => {
                const animation = Animation.CreateAnimation(key, Animation.ANIMATIONTYPE_FLOAT, 60, easingFn);
                const animatable = Animation.TransitionTo(key, value, camera, scene, 60, animation, transitionDuration, () => checkClear(key));
                if (animatable) {
                    this._animatables.set(key, animatable);
                }
            });
        });
        return await promise;
    }
}
//# sourceMappingURL=interpolatingBehavior.js.map