#!/usr/bin/python3
import os, sys, gi
from shutil import which
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk

# JWM Kit - A set of Graphical Apps to simplify use of JWM (Joe's Window Manager) <https://codeberg.org/JWMKit/JWM_Kit>
# Copyright © 2020-2022 Calvin Kent McNabb <apps.jwmkit@gmail.com>
#
# This file is part of JWM Kit.
#
# JWM Kit is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License, version 2,
# as published by the Free Software Foundation.
#
# JWM Kit is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with JWM Kit.  If not, see <https://www.gnu.org/licenses/>.


#  help flag.
def get_help():
    print('''
Purpose: Control master volume levels by assigning JWM Kit Pop Volume to mouse actions and/or key bindings.
For example:
   * use mouse scroll wheel over a speaker icon to adjust volume and visually display levels
   * click on an icon to mute un-mute the master volume
   * create keyboard shortcuts like control + and control - to adjust volume
Note: This program depends on JWM Kit Pop Mixer and JWMKit Pop Muter

Usage: jwmkit_popvolume [option] [increment]

Avalible options:
 help\t\tdisplay this help
 sndio\t\tuse the sndio audio server (Default is ALSA)
 h\t\tadjust volume & report with a horizontal slider
 v\t\tadjust volume & report with a vertical slider
 t\t\tadjust volume & report with text only. No slider
 vhide\t\tadjust volume with no visual report displayed
 mute\t\tToggle mute and display an (un)mute icon
 mhide\t\tToggle mute with no visual report displayed

increments for use with the h, v, t, vhide options :
 +\t\tincrease volume
 -\t\tdecrease volume

Examples:
 jwmkit_popvolume h +\tturn up the volume and report with a horizontal slider
 jwmkit_popvolume mute\ttoggle mute and report with an icon
''')


def alsa_function():
    if mode == 'mute':
        os.system('amixer set Master toggle')
        if os.popen('pgrep "jwmkit_popmuter"').read() == '':
            os.system('jwmkit_popmuter')
    elif mode == 'vhide':
        os.system('amixer set Master 5%{}'.format(adjustment))
    elif mode == 'mhide':
        os.system('amixer set Master toggle')
    else:
        os.system('amixer set Master 5%{}'.format(adjustment))
        if os.popen('pgrep "jwmkit_popmixer*"').read() == '':
            os.system('jwmkit_popmixer {}'.format(mode))


def sndio_function():
    if mode == 'mute':
        os.system('sndioctl output.level=0')
        if os.popen('pgrep "jwmkit_popmuter"').read() == '':
            os.system('jwmkit_popmuter sndio')
    elif mode == 'vhide':
        os.system('sndioctl output.level={}0.05'.format(adjustment))
    elif mode == 'mhide':
        os.system('sndioctl output.level=0')
    else:
        os.system('sndioctl output.level={}0.05'.format(adjustment))
        if os.popen('pgrep "jwmkit_popmixer*"').read() == '':
            os.system('jwmkit_popmixer {}'.format(mode))


def update_value(slider, name):
    level = str(slider.get_value() / 100)
    os.system('sndioctl {}={}'.format(name, level))


class SndioMixer(Gtk.Window):

    def __init__(self):
        streams = os.popen('sndioctl').read().strip().split()
        streams = [s for s in streams if '.level=' in s]
        Gtk.Window.__init__(self, title="JWM Kit Mixer")
        self.set_position(Gtk.WindowPosition.MOUSE)
        self.set_decorated(False)
        self.set_default_size(200, 20)
        main_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=0)
        self.add(main_box)
        for stream in streams:
            stream = stream.split('=')
            label = stream[0].replace('.level', '')
            if '/' in label:
                label = label.split('/')[1]
            box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=0)
            audio_widget = Gtk.Scale.new_with_range(0, 0, 100, .5)
            audio_widget.set_digits(0)
            audio_widget.set_value(int(float(stream[1]) * 100))
            audio_widget.set_value_pos(Gtk.PositionType.RIGHT)
            audio_widget.set_property("width-request", 180)
            audio_widget.connect("value-changed", update_value, stream[0])
            box.pack_end(audio_widget, False, False, 0)
            box.pack_end(Gtk.Label(label=label), False, False, 5)
            main_box.pack_start(box, True, True, 0)


# process parameters
audio_server, mode, adjustment = 'alsa', '', ''

if len({'help', '-help', '--help'} & set(sys.argv)) > 0:
    get_help()
    os.sys.exit()

if len(sys.argv) >= 2:
    if sys.argv[1] == 'sndio':

        # If the sndio mixer is already run close it.
        pid = str(os.getpid())
        pids = os.popen('pgrep -f "jwmkit_popvolume sndio"').read()
        pids = str(pids).split('\n')
        if pid in pids:
            pids.remove(pid)
        pids = [id for id in pids if id]
        if pids:
            os.system("kill -s TERM " + pids[0])
            os.sys.exit()
        win = SndioMixer()
        win.set_resizable(False)
        win.show_all()
        Gtk.main()
    else:

        for ar in sys.argv:
            if ar.lower() in ('h', 'v', 't', 'mute', 'vhide', 'mhide'):
                mode = ar.lower()
            elif ar in ('+', '-'):
                adjustment = ar

        # display help if no mode is specifed
        if mode == '':
            get_help()
            os.sys.exit()

        #  use ALSA for master if available, if not use sndio
        #  sndio users will have both masters as the sndio master will still be available in the pop up mixer.

        if which('amixer') is not None:
            alsa_function()
        else:
            sndio_function()
