# pylint: disable=C0111,R0903

"""Displays volume and mute status of PulseAudio devices.

Aliases: pasink, pasource
"""

import re

import bumblebee.util
import bumblebee.input
import bumblebee.output
import bumblebee.engine

ALIASES = [ "pasink", "pasource" ]

class Module(bumblebee.engine.Module):
    def __init__(self, engine, config):
        super(Module, self).__init__(engine, config,
            bumblebee.output.Widget(full_text=self.volume)
        )

        self._left = 0
        self._right = 0
        self._mono = 0
        self._mute = False
        channel = "sink" if self.name == "pasink" else "source"

        self._patterns = [
            { "expr": "Name:", "callback": (lambda line: False) },
            { "expr": "Mute:", "callback": (lambda line: self.mute(False if " no" in line.lower() else True)) },
            { "expr": "Volume:", "callback": self.getvolume },
        ]

        engine.input.register_callback(self, button=bumblebee.input.RIGHT_MOUSE, cmd="pavucontrol")
        engine.input.register_callback(self, button=bumblebee.input.LEFT_MOUSE,
            cmd="pactl set-{}-mute @DEFAULT_{}@ toggle".format(channel, channel.upper()))
        engine.input.register_callback(self, button=bumblebee.input.WHEEL_UP,
            cmd="pactl set-{}-volume @DEFAULT_{}@ +2%".format(channel, channel.upper()))
        engine.input.register_callback(self, button=bumblebee.input.WHEEL_DOWN,
            cmd="pactl set-{}-volume @DEFAULT_{}@ -2%".format(channel, channel.upper()))

    def mute(self, value):
        self._mute = value

    def getvolume(self, line):
        if "mono" in line:
            m = re.search(r'mono:.*\s*\/\s*(\d+)%', line)
            if m:
                self._mono = m.group(1)
        else:
            m = re.search(r'left:.*\s*\/\s*(\d+)%.*right:.*\s*\/\s*(\d+)%', line)
            if m:
                self._left = m.group(1)
                self._right = m.group(2)
        return True

    def _default_device(self):
        output = bumblebee.util.execute("pactl info")
        pattern = "Default Sink: " if self.name == "pasink" else "Default Source: "
        for line in output.split("\n"):
            if line.startswith(pattern):
                return line.replace(pattern, "")
        return "n/a"

    def volume(self, widget):
        if int(self._mono) > 0:
            return "{}%".format(self._mono)
        elif self._left == self._right:
            return "{}%".format(self._left)
        else:
            return "{}%/{}%".format(self._left, self._right)
        return "n/a"

    def update(self, widgets):
        channel = "sinks" if self.name == "pasink" else "sources"
        device = self._default_device()

        result = bumblebee.util.execute("pactl list {}".format(channel))
        found = False

        for line in result.split("\n"):
            if device in line:
                found = True
            if found == False:
                continue
            for pattern in self._patterns:
                if not pattern["expr"] in line:
                    continue
                if pattern["callback"](line) == False:
                    break

    def state(self, widget):
        if self._mute:
            return [ "warning", "muted" ]
        return [ "unmuted" ]

# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4

@@ -1000,16 +1000,17 @@
 ntrol%22)%0A
+%0A
         
@@ -1014,51 +1014,78 @@
    e
-ngine.input.register_callback(self
+vents = %5B%0A            %7B %22type%22: %22mute%22, %22action%22: %22toggle%22
 , 
+%22
 button
-=
+%22: 
 bumb
@@ -1106,16 +1106,18 @@
 FT_MOUSE
+ %7D
 ,%0A      
@@ -1126,138 +1126,142 @@
     
-cmd=%22pactl set-%7B%7D-mute @DEFAULT_%7B%7D@ toggle%22.format(channel, channel.upper()))%0A        engine.input.register_callback(self
+%7B %22type%22: %22volume%22, %22action%22: %22+2%25%22, %22button%22: bumblebee.input.WHEEL_UP %7D,%0A            %7B %22type%22: %22volume%22, %22action%22: %22-2%25%22
 , 
+%22
 button
-=
+%22: 
 bumb
@@ -1278,18 +1278,22 @@
 t.WHEEL_
-UP
+DOWN %7D
 ,%0A      
@@ -1298,89 +1298,44 @@
     
+%5D%0A%0A
     
-cmd=%22pactl set-%7B%7D-volume @DEFAULT_%7B%7D@ +2%25%22.format(channel, channel.upper()))%0A
+    for event in events:%0A    
     
@@ -1386,36 +1386,29 @@
 ton=
-bumblebee.input.WHEEL_DOWN,%0A
+event%5B%22button%22%5D,%0A    
     
@@ -1433,22 +1433,18 @@
  set-%7B%7D-
-volume
+%7B%7D
  @DEFAUL
@@ -1449,19 +1449,18 @@
 ULT_%7B%7D@ 
--2%25
+%7B%7D
 %22.format
@@ -1473,23 +1473,75 @@
 el, 
-channel.upper()
+event%5B%22type%22%5D,%0A                    channel.upper(), event%5B%22action%22%5D
 ))%0A%0A

Refactor callback registration