import { SourceType } from './source-type';
export class StreamingSource {
    constructor(graph, scene, context, element, type = SourceType.MasterSource) {
        this.graph = graph;
        this.scene = scene;
        this.context = context;
        this.element = element;
        this.type = type;
        this.position = {
            x: 0,
            y: 0,
            z: 0
        };
        this.init();
    }
    init() {
        this.node = this.context.createMediaElementSource(this.element);
        this.gain = this.context.createGain();
        this.createConnections();
        this.element.addEventListener('canplay', (event) => {
            this.canPlay = true;
            if (this.playOnAvailable) {
                this.play();
            }
        });
    }
    play(when = 0, offset = 0, duration = 0) {
        if (this.canPlay) {
            this.element.play();
        }
        this.playOnAvailable = true;
    }
    stop() {
        this.element.pause();
    }
    getVolume() {
        return this.element.volume;
    }
    setVolume(value) {
        this.element.volume = value;
    }
    getPlaybackRate() {
        return this.element.playbackRate;
    }
    setPlaybackRate(value) {
        this.element.playbackRate = value;
    }
    createConnections() {
        switch (this.type) {
            case SourceType.WorldSource:
                if (!this.sceneNode) {
                    this.sceneNode = this.scene.createSource();
                }
                this.node.connect(this.gain);
                this.gain.connect(this.sceneNode);
                break;
            default:
                this.node.connect(this.gain);
                this.graph.connectToMaster(this.gain);
                break;
        }
    }
    setPosition(x, y, z) {
        this.position = {
            x,
            y,
            z
        };
        if (this.sceneNode)
            this.sceneNode.setPosition(x, y, z);
    }
    destroy() {
        this.stop();
        this.element = null;
        this.graph = null;
        this.context = null;
        this.node = null;
        this.sceneNode = null;
        this.scene = null;
    }
    loop(value) {
        this.element.loop = true;
    }
    fadeIn(time) {
        this.gain.gain.setValueAtTime(0.0001, this.context.getContext().currentTime);
        if (!this.node) {
            this.play();
        }
        this.gain.gain.exponentialRampToValueAtTime(this.getVolume(), this.context.getContext().currentTime + time);
    }
    fadeOut(time) {
        this.gain.gain.setValueAtTime(this.getVolume(), this.context.getContext().currentTime);
        if (!this.node) {
            return;
        }
        this.gain.gain.exponentialRampToValueAtTime(0.0001, this.context.getContext().currentTime + time);
        setTimeout(() => this.stop(), time * 1000);
    }
}