/*
 * Copyright (C) 2016-2020 Kano Computing Ltd.
 * License: http://www.gnu.org/licenses/gpl-2.0.txt GNU General Public License v2
 */
import { EventEmitter } from '@kano/common/index.js';
export class SamplePlayer {
    constructor(ctx, buffer, destination, opts) {
        this._volume = 0.4;
        this.paused = true;
        this.playing = true;
        this.source = null;
        this.pausedAt = null;
        this.startedAt = null;
        this._onDidEnd = new EventEmitter();
        this._onDidStart = new EventEmitter();
        this._onDidPause = new EventEmitter();
        this.ctx = ctx;
        this.opts = Object.assign({
            loop: false,
        }, opts);
        this.buffer = buffer;
        this.gainControl = this.ctx.createGain();
        this.gainControl.connect(destination);
        this.output = this.gainControl;
        this.volume = 0.4;
    }
    get onDidEnd() { return this._onDidEnd.event; }
    get onDidStart() { return this._onDidStart.event; }
    get onDidPause() { return this._onDidPause.event; }
    set volume(v) {
        this._volume = Math.max(0, Math.min(1, v));
        this.gainControl.gain.value = this._volume;
    }
    play(time = 0) {
        this.paused = false;
        this.playing = true;
        this.source = this.ctx.createBufferSource();
        this.source.loop = this.opts.loop;
        this.source.buffer = this.buffer;
        this.source.connect(this.output);
        this.source.onended = () => {
            if (this.paused) {
                return;
            }
            this._onDidEnd.fire();
            this.stop();
        };
        if (this.pausedAt) {
            this.startedAt = Date.now() - this.pausedAt;
            this.source.start(time, this.pausedAt / 1000);
        }
        else {
            this.startedAt = Date.now();
            this.source.start(time);
        }
        this._onDidStart.fire();
    }
    pause() {
        if (this.source) {
            this.source.stop(0);
        }
        this.pausedAt = Date.now() - this.startedAt;
        this.paused = true;
        this.playing = false;
        this._onDidPause.fire();
    }
    stop() {
        this.pause();
        this.playing = false;
        this.pausedAt = null;
        this._onDidEnd.fire();
    }
    toggle() {
        if (this.playing) {
            this.pause();
        }
        else {
            this.play();
        }
    }
}
//# sourceMappingURL=sample-player.js.map