import { AudioListener as ThreeAudioListener } from "three";
import { Application } from "../engine/engine_application.js";
import { Camera } from "./Camera.js";
import { Behaviour, GameObject } from "./Component.js";
/**
 * The [AudioListener](https://engine.needle.tools/docs/api/AudioListener) represents a listener that can hear audio sources in the scene.
 * This component creates and manages a Three.js {@link three#AudioListener}, automatically connecting it
 * to the main camera or a Camera in the parent hierarchy.
 *
 * @summary Receives audio in the scene and outputs it to speakers
 * @category Multimedia
 * @group Components
 */
export class AudioListener extends Behaviour {
    /**
     * Gets the existing Three.js {@link three#AudioListener} instance or creates a new one if it doesn't exist.
     * This listener is responsible for capturing audio in the 3D scene.
     * @returns The {@link three#AudioListener} instance
     */
    get listener() {
        if (this._listener == null)
            this._listener = new ThreeAudioListener();
        return this._listener;
    }
    _listener = null;
    /**
     * Registers for interaction events and initializes the audio listener
     * when this component is enabled.
     * @internal
     */
    onEnable() {
        Application.registerWaitForInteraction(this.onInteraction);
        this.addListenerIfItExists();
    }
    /**
     * Cleans up event registrations and removes the audio listener
     * when this component is disabled.
     * @internal
     */
    onDisable() {
        Application.unregisterWaitForInteraction(this.onInteraction);
        this.removeListenerIfItExists();
    }
    onInteraction = () => {
        if (this.destroyed)
            return;
        const listener = this.listener;
        if (listener == null)
            return;
        this.addListenerIfItExists();
    };
    addListenerIfItExists() {
        const listener = this._listener;
        if (!listener)
            return;
        // if the listener is already parented to some object dont change it
        if (listener?.parent)
            return;
        const cam = this.context.mainCameraComponent || GameObject.getComponentInParent(this.gameObject, Camera);
        if (cam?.threeCamera) {
            cam.threeCamera.add(listener);
        }
        else {
            this.gameObject.add(listener);
        }
        // connect the listeners audio nodes
        if (!listener.filter) {
            listener.gain.connect(listener.context.destination);
        }
        else {
            listener.gain.connect(listener.filter);
            listener.filter.connect(listener.context.destination);
        }
    }
    removeListenerIfItExists() {
        const listener = this._listener;
        if (!listener)
            return;
        listener.removeFromParent();
        // disconnect the listeners audio nodes
        if (listener.filter) {
            listener.filter.disconnect();
        }
        if (listener.gain) {
            listener.gain.disconnect();
        }
    }
}
//# sourceMappingURL=AudioListener.js.map