"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.DEFAULT_STYLE = void 0;
const speech_1 = require("../../../../../api/speech");
const element_1 = require("../../../../../client/element");
const pointerdown_1 = require("../../../../../client/event/pointer/pointerdown");
const pointerup_1 = require("../../../../../client/event/pointer/pointerup");
const parentElement_1 = require("../../../../../client/platform/web/parentElement");
const Component_1 = require("../../../component/app/IconButton/Component");
exports.DEFAULT_STYLE = {
    touchAction: 'none',
};
const specNameGrammar = (__system) => {
    const { specs } = __system;
    const token_set = new Set();
    for (let id in specs) {
        const spec = specs[id];
        const { name = '' } = spec;
        const name_tokens = name.split(' ');
        for (const name_token of name_tokens) {
            token_set.add(name_token);
        }
    }
    const tokens = Array.from(token_set).sort();
    return (0, speech_1.grammarsFrom)(__system, tokens);
};
class MicrophoneButton extends element_1.Element {
    constructor($props, $system) {
        super($props, $system);
        this._recording = false;
        this._on_pointer_down = (event, _event) => {
            const { disabled } = this.$props;
            if (disabled) {
                return;
            }
            const { pointerId } = event;
            this.setPointerCapture(pointerId);
            const unlisten_pointer_up = this.addEventListener((0, pointerup_1.makePointerUpListener)(() => {
                const { pointerId } = event;
                this.releasePointerCapture(pointerId);
                unlisten_pointer_up();
                this.stop();
            }));
            this.start();
        };
        this._on_transcript = (transcript) => {
            if (this.$unit) {
                this.$unit.$setPinData({
                    type: 'output',
                    pinId: 'transcript',
                    data: `"${transcript}"`,
                });
            }
            this.dispatchEvent('transcript', transcript);
        };
        this._on_err = (err) => { };
        const { className, style = {}, opt = {
            grammars: undefined,
            lang: 'en-us',
            maxAlternatives: 1,
            continuous: false,
            interimResults: true,
        }, disabled = false, tabIndex, } = this.$props;
        const icon_button = new Component_1.default({
            icon: 'mic',
            className,
            style: Object.assign(Object.assign({}, exports.DEFAULT_STYLE), style),
            activeColor: 'rgb(201,64,49)',
            disabled,
            title: 'microphone',
        }, this.$system);
        icon_button.addEventListener((0, pointerdown_1.makePointerDownListener)(this._on_pointer_down));
        this._icon_button = icon_button;
        let speech_recorder = null;
        try {
            if (!opt.grammars) {
                opt.grammars = specNameGrammar($system);
            }
        }
        catch (err) {
            //
        }
        try {
            speech_recorder = new speech_1.SpeechRecorder(this.$system, opt);
        }
        catch (err) {
            //
        }
        this._speech_recorder = speech_recorder;
        if (this._speech_recorder) {
            this._speech_recorder.addListener('transcript', this._on_transcript);
            this._speech_recorder.addListener('err', this._on_err);
        }
        const $element = (0, parentElement_1.default)($system);
        this.$unbundled = false;
        this.$primitive = true;
        this.$element = $element;
        this.$slot = icon_button.$slot;
        this.setSubComponents({
            icon_button,
        });
        this.registerRoot(icon_button);
    }
    onPropChanged(prop, current) {
        if (prop === 'style') {
            this._icon_button.setProp('style', Object.assign(Object.assign({}, exports.DEFAULT_STYLE), current));
        }
        else if (prop === 'disabled') {
            this._icon_button.setProp('disabled', current);
        }
    }
    start() {
        // console.log('MicrophoneButton', 'start')
        this._recording = true;
        this._icon_button.setProp('active', true);
        try {
            this._speech_recorder && this._speech_recorder.start();
        }
        catch (_a) {
            // swallow
        }
    }
    stop() {
        // console.log('MicrophoneButton', 'stop')
        this._icon_button.setProp('active', false);
        this._speech_recorder && this._speech_recorder.stop();
        this._recording = false;
    }
    recording() {
        return this._recording;
    }
}
exports.default = MicrophoneButton;
//# sourceMappingURL=Component.js.map