# Copyright 2004-2011 Joe Wreschnig, Michael Urman, Steven Robertson,
#           2011-2014 Christoph Reiter
#           2020-2022 Nick Boultbee
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.

from gi.repository import Gtk

from quodlibet import config
from quodlibet import _
from quodlibet.qltk.ccb import ConfigCheckButton, ConfigSwitch
from quodlibet.qltk.entry import UndoEntry
from quodlibet.qltk.x import Button
from quodlibet.qltk import Icons
from quodlibet.util import connect_obj


class GstPlayerPreferences(Gtk.VBox):
    def __init__(self, player, debug=False):
        super().__init__(spacing=12)

        e = UndoEntry()
        e.set_tooltip_text(_("The GStreamer output pipeline used for "
                             "playback. Leave blank for the default pipeline. "
                             "If the pipeline contains a sink, "
                             "it will be used instead of the default one."))

        e.set_text(config.get('player', 'gst_pipeline'))

        def changed(entry):
            config.set('player', 'gst_pipeline', entry.get_text())

        e.connect('changed', changed)

        pipe_label = Gtk.Label(label=_('_Output pipeline:'))
        pipe_label.set_use_underline(True)
        pipe_label.set_mnemonic_widget(e)

        apply_button = Button(_("_Apply"), Icons.VIEW_REFRESH)

        def format_buffer(scale, value):
            # Translators: s = seconds
            return _("%.1f s") % value

        def scale_changed(scale):
            duration_msec = int(scale.get_value() * 1000)
            player._set_buffer_duration(duration_msec)

        duration = config.getfloat("player", "gst_buffer")
        scale = Gtk.HScale.new(Gtk.Adjustment(value=duration, lower=0.2, upper=10))
        scale.set_value_pos(Gtk.PositionType.LEFT)
        scale.set_show_fill_level(True)
        scale.connect('format-value', format_buffer)
        scale.connect('value-changed', scale_changed)

        buffer_label = Gtk.Label(label=_('_Buffer duration:'))
        buffer_label.set_use_underline(True)
        buffer_label.set_mnemonic_widget(scale)

        def rebuild_pipeline(*args):
            player._rebuild_pipeline()

        apply_button.connect('clicked', rebuild_pipeline)

        gapless_button = ConfigSwitch(
            _('Disable _gapless playback'),
            "player", "gst_disable_gapless", populate=True,
            tooltip=_("Disabling gapless playback can avoid track changing problems "
                      "with some GStreamer versions"))
        jack_button = ConfigSwitch(
            _('Use JACK for playback if available'),
            "player", "gst_use_jack", populate=True,
            tooltip=_("Uses `jackaudiosink` for playbin sink if it can be detected"))
        jack_connect = ConfigSwitch(
            _('Auto-connect to JACK output devices'),
            "player", "gst_jack_auto_connect",
            populate=True, tooltip=_("Tells `jackaudiosink` to auto-connect"))

        def _jack_activated(widget: ConfigCheckButton, *args) -> None:
            jack_connect.set_sensitive(widget.get_active())

        jack_button.connect("notify::active", _jack_activated)
        _jack_activated(jack_button, None)

        hb = self._create_pipeline_box(pipe_label, e, apply_button)
        self.pack_start(hb, False, False, 0)

        # Buffer
        hb = self._create_buffer_box(buffer_label, scale)
        self.pack_start(hb, False, False, 0)

        self.pack_start(gapless_button, False, False, 0)
        self.pack_start(jack_button, False, False, 0)
        self.pack_start(jack_connect, False, False, 0)

        if debug:
            def print_bin(player):
                player._print_pipeline()

            b = Button("Print Pipeline", Icons.DIALOG_INFORMATION)
            connect_obj(b, 'clicked', print_bin, player)
            hb = Gtk.Box(spacing=6)
            hb.pack_end(b, False, False, 0)
            self.pack_start(hb, False, False, 0)

    def _create_buffer_box(self, label: Gtk.Label, scale: Gtk.HScale):
        hb = Gtk.Box(spacing=6)
        hb.pack_start(label, False, False, 0)
        hb.pack_end(scale, True, True, 0)
        return hb

    def _create_pipeline_box(self, pipe_label: Gtk.Label, e: Gtk.Widget,
                             apply_button: Gtk.Button):
        hb = Gtk.Box(spacing=12)
        hb.pack_start(pipe_label, False, False, 0)
        hb.pack_start(e, True, True, 0)
        hb.pack_end(apply_button, False, False, 0)
        return hb
