/**
 * pacem v0.51.10-faraday (https://js.pacem.it)
 * Copyright 2025 Pacem (https://pacem.it)
 * Licensed under Apache-2.0
 */
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var Pacem;
(function (Pacem) {
    var Components;
    (function (Components) {
        var Media;
        (function (Media) {
            let PacemAudioElement = class PacemAudioElement extends Components.PacemEventTarget {
                constructor() {
                    super(...arguments);
                    this._endedHandler = (e) => {
                        this.dispatchEvent(new Event('end'));
                    };
                    this._canPlayHandler = (e) => {
                        this.#canPlay = true;
                        this._autoplay();
                    };
                    this._canPlayThroughHandler = (e) => {
                        this.#canPlayThrough = true;
                        this._autoplay();
                    };
                }
                // TODO: structure a proper MediaElement hierarchy (share logic with a future VideoElement)
                /** @readonly */
                // @Watch({ converter: PropertyConverters.Boolean }) duration: number;
                #audio;
                #canPlay;
                #canPlayThrough;
                connectedCallback() {
                    super.connectedCallback();
                    const a = this.#audio = new Audio();
                    a.addEventListener('canplay', this._canPlayHandler, false);
                    a.addEventListener('ended', this._endedHandler, false);
                    a.addEventListener('canplaythrough', this._canPlayThroughHandler, false);
                }
                propertyChangedCallback(name, old, val, first) {
                    super.propertyChangedCallback(name, old, val, first);
                    if (!first) {
                        switch (name) {
                            case 'src':
                                this._init();
                                break;
                        }
                    }
                }
                viewActivatedCallback() {
                    super.viewActivatedCallback();
                    this._init();
                }
                disconnectedCallback() {
                    const a = this.#audio;
                    a.removeEventListener('ended', this._endedHandler, false);
                    a.removeEventListener('canplaythrough', this._canPlayThroughHandler, false);
                    a.removeEventListener('canplay', this._canPlayHandler, false);
                    super.disconnectedCallback();
                }
                play() {
                    // sudden exit when disabled
                    if (this.disabled) {
                        return Promise.reject('disabled');
                    }
                    return this.#audio.play().then(_ => {
                        this.dispatchEvent(new Event('start'));
                    }, e => {
                        this.dispatchEvent(new CustomEvent('error', { detail: e }));
                    });
                }
                pause() {
                    this.#audio.pause();
                }
                reset() {
                    this.#audio.load();
                }
                get _canPlay() {
                    return this.stream && this.#canPlay || this.#canPlayThrough;
                }
                _autoplay() {
                    if (this.autoplay) {
                        if (this._canPlay) {
                            this.play();
                        }
                    }
                }
                _init(src = this.src) {
                    const audio = this.#audio;
                    this.#canPlay =
                        this.#canPlayThrough = false;
                    audio.src = src;
                }
            };
            __decorate([
                Pacem.Watch({ emit: false, converter: Pacem.PropertyConverters.String })
            ], PacemAudioElement.prototype, "src", void 0);
            __decorate([
                Pacem.Watch({ emit: false, converter: Pacem.PropertyConverters.Boolean })
            ], PacemAudioElement.prototype, "stream", void 0);
            __decorate([
                Pacem.Watch({ emit: false, converter: Pacem.PropertyConverters.Boolean })
            ], PacemAudioElement.prototype, "autoplay", void 0);
            PacemAudioElement = __decorate([
                Pacem.CustomElement({ tagName: Pacem.P + '-audio' })
            ], PacemAudioElement);
            Media.PacemAudioElement = PacemAudioElement;
        })(Media = Components.Media || (Components.Media = {}));
    })(Components = Pacem.Components || (Pacem.Components = {}));
})(Pacem || (Pacem = {}));
var Pacem;
(function (Pacem) {
    var Components;
    (function (Components) {
        var Media;
        (function (Media) {
            const DEFAULT_FPS = 25;
            const DEFAULT_MIMETYPE = "video/mp4";
            const DEFAULT_AUDIO_BITS_PER_SEC = 128000;
            const DEFAULT_VIDEO_BITS_PER_SEC = 2500000;
            const MEDIA_RECORDER_EVENTS = ["start", "stop", "dataavailable", "pause", "resume", "error", "warning"];
            function isStream(obj) {
                if (obj instanceof HTMLCanvasElement) {
                    return true;
                }
                return 'captureStream' in obj && typeof obj['captureStream'] === 'function';
            }
            let PacemMediaRecorderElement = class PacemMediaRecorderElement extends Components.PacemEventTarget {
                constructor() {
                    super(...arguments);
                    this._recorderLifecycleHandler = (evt) => {
                        this.state = this.#recorder.state;
                        switch (evt.type) {
                            case 'start':
                                this.output = null;
                                break;
                            case 'stop':
                                this.flush();
                                break;
                            case 'dataavailable':
                                var evtb = evt;
                                this.#chunks.push(evtb.data);
                                break;
                        }
                    };
                    this.#recorder = null;
                    this.#chunks = [];
                }
                viewActivatedCallback() {
                    super.viewActivatedCallback();
                    this._setupMediaRecorder();
                }
                propertyChangedCallback(name, old, val, first) {
                    super.propertyChangedCallback(name, old, val, first);
                    if (!first) {
                        switch (name) {
                            case 'source':
                            case 'fps':
                            case 'mimeType':
                            case 'audioBitsPerSecond':
                            case 'videoBitsPerSecond':
                                this._setupMediaRecorder();
                                break;
                        }
                    }
                }
                disconnectedCallback() {
                    this._closeMediaRecorder();
                    super.disconnectedCallback();
                }
                #recorder;
                #chunks;
                _setupMediaRecorder(stream = this.source, options = {
                    mimeType: this.mimeType || DEFAULT_MIMETYPE,
                    audioBitsPerSecond: this.audioBitsPerSecond ?? DEFAULT_AUDIO_BITS_PER_SEC,
                    videoBitsPerSecond: this.videoBitsPerSecond ?? DEFAULT_VIDEO_BITS_PER_SEC
                }) {
                    this._closeMediaRecorder();
                    if (!Pacem.Utils.isNull(stream)) {
                        if (isStream(stream)) {
                            const fps = this.fps || DEFAULT_FPS;
                            stream = stream.captureStream(fps);
                        }
                        try {
                            this.#recorder = new MediaRecorder(stream, options);
                        }
                        catch (e) {
                            console.error(e);
                        }
                        const r = this.#recorder;
                        MEDIA_RECORDER_EVENTS.forEach(e => {
                            r.addEventListener(e, this._recorderLifecycleHandler, false);
                        });
                    }
                }
                _closeMediaRecorder() {
                    const r = this.#recorder;
                    if (!Pacem.Utils.isNull(r)) {
                        if (r.state !== 'inactive') {
                            r.stop();
                        }
                        MEDIA_RECORDER_EVENTS.forEach(e => {
                            r.removeEventListener(e, this._recorderLifecycleHandler, false);
                        });
                        this.#recorder = null;
                    }
                }
                flush() {
                    const blob = new Blob(this.#chunks, { 'type': this.mimeType || DEFAULT_MIMETYPE });
                    this.#chunks = [];
                    this.output = blob;
                }
                start() {
                    const r = this.#recorder;
                    if (!Pacem.Utils.isNull(r) && r.state === 'inactive') {
                        r.start();
                    }
                }
                stop() {
                    const r = this.#recorder;
                    if (!Pacem.Utils.isNull(r) && r.state !== 'inactive') {
                        r.stop();
                    }
                }
                resume() {
                    const r = this.#recorder;
                    if (!Pacem.Utils.isNull(r) && r.state === 'paused') {
                        r.start();
                    }
                }
                pause() {
                    const r = this.#recorder;
                    if (!Pacem.Utils.isNull(r) && r.state !== 'paused') {
                        r.pause();
                    }
                }
            };
            __decorate([
                Pacem.Watch({ emit: false, converter: Pacem.PropertyConverters.Element })
            ], PacemMediaRecorderElement.prototype, "source", void 0);
            __decorate([
                Pacem.Watch({ emit: false, converter: Pacem.PropertyConverters.Number })
            ], PacemMediaRecorderElement.prototype, "fps", void 0);
            __decorate([
                Pacem.Watch({ emit: false, converter: Pacem.PropertyConverters.String })
            ], PacemMediaRecorderElement.prototype, "mimeType", void 0);
            __decorate([
                Pacem.Watch({ emit: false, converter: Pacem.PropertyConverters.Number })
            ], PacemMediaRecorderElement.prototype, "audioBitsPerSecond", void 0);
            __decorate([
                Pacem.Watch({ emit: false, converter: Pacem.PropertyConverters.Number })
            ], PacemMediaRecorderElement.prototype, "videoBitsPerSecond", void 0);
            __decorate([
                Pacem.Watch({ converter: Pacem.PropertyConverters.String })
            ], PacemMediaRecorderElement.prototype, "state", void 0);
            __decorate([
                Pacem.Watch()
            ], PacemMediaRecorderElement.prototype, "output", void 0);
            PacemMediaRecorderElement = __decorate([
                Pacem.CustomElement({ tagName: Pacem.P + '-media-recorder' })
            ], PacemMediaRecorderElement);
            Media.PacemMediaRecorderElement = PacemMediaRecorderElement;
        })(Media = Components.Media || (Components.Media = {}));
    })(Components = Pacem.Components || (Pacem.Components = {}));
})(Pacem || (Pacem = {}));
