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;
};
import Adw from 'gi://Adw';
import GObject from 'gi://GObject';
import Gio from 'gi://Gio';
import Gtk from 'gi://Gtk';
import { gettext as _ } from 'resource:///org/gnome/Shell/Extensions/js/extensions/prefs.js';
import { registerClass } from '../../common/gjs.js';
import { Icon } from '../../common/icons.js';
import { Sound, SoundManager } from '../../common/sound.js';
import { makeResettable } from '../utils.js';
let SoundVolumeRow = class SoundVolumeRow extends Adw.PreferencesRow {
    slider;
    constructor() {
        super({
            activatable: false,
        });
        const box = new Gtk.Box({
            css_classes: ['header'],
        });
        this.child = box;
        box.append(new Gtk.Image({
            icon_name: Icon.Volume,
            margin_start: 6,
            margin_end: 6,
        }));
        this.slider = new Gtk.Scale({
            valign: Gtk.Align.CENTER,
            hexpand: true,
            draw_value: true,
            value_pos: Gtk.PositionType.RIGHT,
            digits: 0,
            adjustment: new Gtk.Adjustment({ lower: -20, upper: 20, step_increment: 1, value: 0 }),
        });
        box.append(this.slider);
        this.slider.add_mark(0, Gtk.PositionType.BOTTOM, null);
        this.slider.set_format_value_func((_slider, value) => {
            const sign = value >= 0 ? '+' : '';
            return ` ${sign}${value} dB`;
        });
        const separator = new Gtk.Separator({
            orientation: Gtk.Orientation.VERTICAL,
            margin_top: 9,
            margin_bottom: 9,
            margin_start: 6,
        });
        box.append(separator);
        const resetButton = new Gtk.Button({
            icon_name: Icon.Undo,
            valign: Gtk.Align.CENTER,
            css_classes: ['flat'],
            sensitive: false,
        });
        box.append(resetButton);
        resetButton.connect('clicked', () => (this.slider.adjustment.value = 0));
        this.slider.adjustment.connect('notify::value', () => (resetButton.sensitive = this.slider.adjustment.value !== 0));
    }
};
SoundVolumeRow = __decorate([
    registerClass()
], SoundVolumeRow);
let CheckRow = class CheckRow extends Adw.ActionRow {
    _value;
    _checkButton;
    constructor(title, value, group) {
        super({
            title: title,
            activatable: true,
        });
        this._value = value;
        this._checkButton = new Gtk.CheckButton();
        this.add_prefix(this._checkButton);
        this.set_activatable_widget(this._checkButton);
        if (group) {
            this._checkButton.group = group._checkButton;
        }
    }
    get active() {
        return this._checkButton.active;
    }
    set active(value) {
        this._checkButton.active = value;
    }
    get value() {
        return this._value;
    }
};
CheckRow = __decorate([
    registerClass({
        Properties: {
            active: GObject.ParamSpec.boolean('active', null, null, GObject.ParamFlags.READWRITE, false),
        },
    })
], CheckRow);
let SoundChooserPage = class SoundChooserPage extends Adw.NavigationPage {
    _soundManager;
    _sound = Sound.None;
    _volumeRow;
    _rows;
    constructor(soundManager) {
        super({
            title: _('Sound'),
        });
        this._soundManager = soundManager;
        const toolbarView = new Adw.ToolbarView();
        toolbarView.add_top_bar(new Adw.HeaderBar());
        this.child = toolbarView;
        const page = new Adw.PreferencesPage();
        toolbarView.content = page;
        // Volume row
        const volumeGroup = new Adw.PreferencesGroup();
        page.add(volumeGroup);
        this._volumeRow = new SoundVolumeRow();
        volumeGroup.add(this._volumeRow);
        this.bind_property('volume', this._volumeRow.slider.adjustment, 'value', GObject.BindingFlags.BIDIRECTIONAL);
        // Sound chooser
        const soundChooser = new Adw.PreferencesGroup();
        page.add(soundChooser);
        // None
        const noneRow = new CheckRow(_('None'), Sound.None);
        noneRow.active = true;
        this._rows = {
            [Sound.None]: noneRow,
            [Sound.Click]: new CheckRow(_('Click'), Sound.Click, noneRow),
            [Sound.Hum]: new CheckRow(_('Hum'), Sound.Hum, noneRow),
            [Sound.String]: new CheckRow(_('String'), Sound.String, noneRow),
            [Sound.Swing]: new CheckRow(_('Swing'), Sound.Swing, noneRow),
            [Sound.Message]: new CheckRow(_('Message'), Sound.Message, noneRow),
            [Sound.MessageNewInstant]: new CheckRow(_('Message New Instant'), Sound.MessageNewInstant, noneRow),
            [Sound.Bell]: new CheckRow(_('Bell'), Sound.Bell, noneRow),
            [Sound.DialogWarning]: new CheckRow(_('Dialog Warning'), Sound.DialogWarning, noneRow),
        };
        for (const [sound, row] of Object.entries(this._rows)) {
            row.visible = sound === Sound.None || soundManager.hasSound(sound);
            row.connect('activated', this.toggled.bind(this));
            soundChooser.add(row);
        }
    }
    get sound() {
        return this._sound;
    }
    set sound(value) {
        this._sound = value;
        const row = this._rows[value];
        row.active = true;
        this.notify('sound');
    }
    get volume() {
        return this._volumeRow.slider.get_value();
    }
    set volume(value) {
        this._volumeRow.slider.set_value(value);
        this.notify('volume');
    }
    toggled(row) {
        if (row.active) {
            this.sound = row.value;
            this._soundManager.playSound(row.value, this.volume);
        }
    }
};
SoundChooserPage = __decorate([
    registerClass({
        Properties: {
            sound: GObject.ParamSpec.string('sound', null, null, GObject.ParamFlags.READWRITE, Sound.None),
            volume: GObject.ParamSpec.double('volume', null, null, GObject.ParamFlags.READWRITE, -20, 20, 0),
        },
    })
], SoundChooserPage);
let FeedbackSettings = class FeedbackSettings extends Adw.PreferencesGroup {
    _soundManager;
    _soundChooserPage;
    _soundLabel;
    constructor(prefs, window) {
        super({
            title: _('Feedback'),
        });
        const showIndicator = new Adw.SwitchRow({
            title: _('Show Indicator'),
            subtitle: _('Show an indicator on the top panel'),
        });
        this.add(showIndicator);
        const showContentIndicator = new Adw.SwitchRow({
            title: _('Show Clipboard Content in Indicator'),
            subtitle: _('Show the current clipboard content in the indicator'),
        });
        this.add(showContentIndicator);
        showIndicator.bind_property('active', showContentIndicator, 'sensitive', null);
        this.connect('map', () => (showContentIndicator.sensitive = showIndicator.active));
        const wiggleIndicator = new Adw.SwitchRow({
            title: _('Wiggle Indicator'),
            subtitle: _('Wiggle the indicator when a clipboard item is copied'),
        });
        this.add(wiggleIndicator);
        const sendNotification = new Adw.SwitchRow({
            title: _('Send Notification'),
            subtitle: _('Send a notification when a clipboard item is copied'),
        });
        this.add(sendNotification);
        const playSound = new Adw.ActionRow({
            title: _('Sound'),
            subtitle: _('Sound to play when a clipboard item is copied'),
            activatable: true,
            sensitive: false,
        });
        this.add(playSound);
        this._soundLabel = new Gtk.Label({
            label: _('None'),
            margin_end: 8,
            css_classes: ['dim-label'],
        });
        playSound.add_suffix(this._soundLabel);
        playSound.add_suffix(new Gtk.Image({ icon_name: Icon.Next }));
        playSound.connect('activated', () => this._soundChooserPage && window.push_subpage(this._soundChooserPage));
        // Bind properties
        const settings = prefs.getSettings();
        settings.bind('show-indicator', showIndicator, 'active', Gio.SettingsBindFlags.DEFAULT);
        settings.bind('show-content-indicator', showContentIndicator, 'active', Gio.SettingsBindFlags.DEFAULT);
        settings.bind('wiggle-indicator', wiggleIndicator, 'active', Gio.SettingsBindFlags.DEFAULT);
        settings.bind('send-notification', sendNotification, 'active', Gio.SettingsBindFlags.DEFAULT);
        makeResettable(playSound, settings, 'sound', 'volume');
        // Check if GSound is installed
        this.connect('notify::gsound', async () => {
            if (this.gsound) {
                const GSound = (await import('gi://GSound')).default;
                this._soundManager = new SoundManager(GSound, prefs);
                this._soundChooserPage = new SoundChooserPage(this._soundManager);
                settings.bind('sound', this._soundChooserPage, 'sound', Gio.SettingsBindFlags.DEFAULT);
                settings.bind('volume', this._soundChooserPage, 'volume', Gio.SettingsBindFlags.DEFAULT);
                this._soundChooserPage.connect('notify::sound', this.updateSoundLabel.bind(this));
                this.updateSoundLabel();
                playSound.sensitive = true;
            }
        });
        this.connect('destroy', () => this._soundManager?.destroy());
    }
    updateSoundLabel() {
        if (!this._soundChooserPage)
            return;
        this._soundLabel.label = (() => {
            switch (this._soundChooserPage.sound) {
                case Sound.None:
                    return _('None');
                case Sound.Click:
                    return _('Click');
                case Sound.Hum:
                    return _('Hum');
                case Sound.String:
                    return _('String');
                case Sound.Swing:
                    return _('Swing');
                case Sound.Message:
                    return _('Message');
                case Sound.MessageNewInstant:
                    return _('Message New Instant');
                case Sound.Bell:
                    return _('Bell');
                case Sound.DialogWarning:
                    return _('Dialog Warning');
            }
        })();
    }
};
FeedbackSettings = __decorate([
    registerClass({
        Properties: {
            gsound: GObject.ParamSpec.boolean('gsound', null, null, GObject.ParamFlags.READWRITE, false),
        },
    })
], FeedbackSettings);
export { FeedbackSettings };
