
import { EventDispatcher, Event } from "../2d/events";
import { Sound, InnerAudioContext } from "./Sound";
import { $popSoundChannel } from "./Sound";


export class SoundChannel extends EventDispatcher {
    /**
     * @private
     */
    $url: string;
    /**
     * @private
     */
    $loops: number;
    /**
     * @private
     */
    $startTime: number = 0;
    /**
     * @private
     */
    private audio: InnerAudioContext = null;

    //声音是否已经播放完成
    private isStopped: boolean = false;

    /**
     * @private
     */
    constructor(audio: InnerAudioContext) {
        super();
        audio.onEnded(this.onPlayEnd)
        // audio.addEventListener("ended", this.onPlayEnd);
        this.audio = audio;
    }

    private canPlay = (): void => {
        // this.audio.removeEventListener("canplay", this.canPlay);
        try {
            this.audio.currentTime = this.$startTime;
        }
        catch (e) {
        }
        finally {
            this.audio.play();
        }
    };

    $play(): void {
        if (this.isStopped) {
            return;
        }

        try {
            //this.audio.pause();
            this.audio.volume = this._volume;
            this.audio.currentTime = this.$startTime;
        }
        catch (e) {
            this.audio.onCanplay(() => { this.canPlay() })
            // this.audio.addEventListener("canplay", this.canPlay);
            return;
        }
        this.audio.play();
    }

    /**
     * @private
     */
    private onPlayEnd = () => {
        if (this.$loops == 1) {
            this.stop();

            this.dispatchEvent(Event.COMPLETE);
            return;
        }

        if (this.$loops > 0) {
            this.$loops--;
        }

        /////////////
        //this.audio.load();
        this.$play();
    };

    /**
     * @private
     * @inheritDoc
     */
    public stop() {
        if (!this.audio)
            return;

        if (!this.isStopped) {
            //用来管理所有声音用
            $popSoundChannel(this);
        }
        this.isStopped = true;

        let audio = this.audio;
        audio.onEnded(() => { })//暂时没有offEnded，所以置空试试
        audio.onCanplay(() => { })
        // audio.removeEventListener("ended", this.onPlayEnd);
        // audio.removeEventListener("canplay", this.canPlay);
        audio.volume = 0;
        this._volume = 0;
        this.audio = null;

        let url = this.$url;

        //延迟一定时间再停止，规避chrome报错
        setTimeout(function () {
            audio.pause();
            Sound.$recycle(url, audio);
        }, 200);
    }

    /**
     * @private
     */
    private _volume: number = 1;

    /**
     * @private
     * @inheritDoc
     */
    public get volume(): number {
        return this._volume;
    }

    /**
     * @inheritDoc
     */
    public set volume(value: number) {
        if (this.isStopped) {
            return;
        }
        this._volume = value;
        if (!this.audio)
            return;
        this.audio.volume = value;
    }

    /**
     * @private
     * @inheritDoc
     */
    public get position(): number {
        if (!this.audio)
            return 0;
        return this.audio.currentTime;
    }
}
