#!/usr/bin/env python3
import dbus
from gi.repository import AppIndicator3
from gi.repository import Gtk, GLib
import subprocess
import threading
import pulsectl  # Asegúrate de tener pulsectl instalado


class VolumeApplet:
    def __init__(self):
        self.app = 'volume-applet'
        # Define el icono inicial
        self.indicator = AppIndicator3.Indicator.new(
            self.app,
            "audio-volume-medium",  # Icono predeterminado
            AppIndicator3.IndicatorCategory.APPLICATION_STATUS
        )
        self.indicator.set_status(AppIndicator3.IndicatorStatus.ACTIVE)
        self.indicator.set_menu(self.create_menu())

        # Icono inicial basado en el volumen actual
        current_volume = self.get_current_volume()
        self.update_icon(current_volume)

        self.window = None  # Ventana de la barra de volumen

        # Iniciar el monitoreo de cambios de volumen en un hilo separado
        self.pulse = pulsectl.Pulse('volume-applet')
        self.pulse.event_mask_set('sink')  # Monitorea cambios en los sinks
        self.pulse.event_callback_set(self.on_pulse_event)
        self.monitor_thread = threading.Thread(
            target=self.pulse_event_listener, daemon=True)
        self.monitor_thread.start()

    def create_menu(self):
        menu = Gtk.Menu()

        # Agregar opción para abrir la barra de volumen vertical
        volume_item = Gtk.MenuItem(label="Ajustar Volumen")
        volume_item.connect("activate", self.show_volume_control)
        menu.append(volume_item)

        # Agregar opción para salir
        quit_item = Gtk.MenuItem(label="Salir")
        quit_item.connect("activate", Gtk.main_quit)
        menu.append(quit_item)

        menu.show_all()
        return menu

    def show_volume_control(self, source=None):
        if self.window:
            self.window.destroy()

        self.window = Gtk.Window(title="Control de Volumen")
        self.window.set_default_size(50, 200)  # Barra vertical
        self.window.set_border_width(10)

        # Configurar la barra de volumen en orientación vertical
        volume_scale = Gtk.Scale.new_with_range(
            Gtk.Orientation.VERTICAL, 0, 100, 1)
        volume_scale.set_value(self.get_current_volume())
        volume_scale.connect("value-changed", self.on_volume_changed)

        self.window.add(volume_scale)
        self.window.show_all()

    def on_volume_changed(self, scale):
        volume = int(scale.get_value())
        subprocess.run(["pamixer", "--set-volume", str(volume)])
        # Actualizar el icono y el tooltip en función del nuevo volumen
        self.update_icon(volume)

    def get_current_volume(self):
        try:
            result = subprocess.check_output(["pamixer", "--get-volume"])
            return int(result.strip())
        except subprocess.CalledProcessError:
            return 50  # Valor por defecto si pamixer falla

    def update_icon(self, volume):
        """Actualiza el icono y el tooltip basado en el nivel de volumen."""
        if volume == 0:
            icon_name = "volume-0.png"
        elif 1 <= volume <= 33:
            icon_name = "volume-1.png"
        elif 34 <= volume <= 66:
            icon_name = "volume-2.png"
        elif 67 <= volume <= 75:
            icon_name = "volume-3.png"
        else:
            icon_name = "volume-4.png"

        # Ruta completa del icono
        icon_path = f"/home/teraflops/Icons/{icon_name}"
        tooltip = f"Volumen Actual: {volume}%"

        self.indicator.set_icon_full(icon_path, tooltip)
        # Establecer el tooltip explícitamente
        self.indicator.set_title(tooltip)

    def pulse_event_listener(self):
        """Escucha eventos de PulseAudio en un hilo separado."""
        try:
            self.pulse.event_listen()
        except Exception as e:
            print(f"Error al escuchar eventos de PulseAudio: {e}")

    def on_pulse_event(self, event):
        """Callback para manejar eventos de PulseAudio."""
        if event.t == 'change':
            # Verifica si el cambio es relevante para el volumen
            if event.facility == 'sink':
                # Obtén el volumen actual
                current_volume = self.get_current_volume()
                # Actualiza el icono y el tooltip en el hilo principal
                GLib.idle_add(self.update_icon, current_volume)

    def __del__(self):
        if hasattr(self, 'pulse'):
            self.pulse.close()


def main():
    app = VolumeApplet()
    Gtk.main()


if __name__ == "__main__":
    main()
