--   This file is part of Reno desktop.
--
--  Reno desktop 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 3 of the License, or (at your option) any later version.
--
--  Reno desktop 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 Reno desktop. If not, see <https://www.gnu.org/licenses/>. 
--  Pulseaudio per-client volume setting
local awful = require("awful")
local gears = require("gears")
local wibox = require("wibox")
local awmtk2 = require("awmtk2")
local beautiful = require("beautiful")
local ask = require("asckey")

local test_pactl = os.execute("pactl --version")
local pactl_found = test_pactl
if _VERSION:match("5.1") then
    pactl_found = (test_pactl == 0)
end
local test_amixer = os.execute("amixer --version")
local amixer_found = test_amixer
if _VERSION:match("5.1") then
    amixer_found = (test_amixer == 0)
end
if (not (amixer_found or pactl_found)) then
    return function() end
end

local try_launch = "pavucontrol"
local function get_icon(percent)
    if percent >= 66 then
        return beautiful["volume-high-symbolic"]
    elseif percent >= 33 then
        return beautiful["volume-medium-symbolic"]
    elseif percent > 0 then
        return beautiful["volume-low-symbolic"]
    else
        return beautiful["volume-muted-symbolic"]
    end
end

return function(args)
    local style = awmtk2.create_style("volume",
        awmtk2.generic.oneline_widget, args.style,args.vertical)
    local templates = awmtk2.create_template_lib("volume",awmtk2.templates,args.templates)
    local t = awmtk2.build_templates(templates,style,args.vertical)
    local slider_part = wibox.widget(
        t.container({
            t.slider({
                minimum = 0,
                maximum = 100,
                id = "volume",
                value = -1
            }),
            layout = (args.vertical and wibox.layout.fixed.vertical) or
            wibox.layout.fixed.horizontal
        },{
            visible = false,
            id = "slidercontainer"
        })
    )
    local widget = wibox.widget({
        t.button(t.icon({
            image = get_icon(0),
            id = "volume_icon",
            resize = true,
        })),
        id = "volume_widget_root",
        layout = (args.vertical and wibox.layout.fixed.vertical) or
        wibox.layout.fixed.horizontal
    })
    local icon = widget:get_children_by_id("volume_icon")[1]
    local slider = slider_part:get_children_by_id("volume")[1]
    local container = slider_part:get_children_by_id("slidercontainer")[1]
    -- Alsa master handle
    args.device = args.device or "default"
    local update_timer = gears.timer {
        autostart = true,
        timeout = 0.5,
        call_now = true,
        callback = function()
            awful.spawn.easy_async_with_shell("amixer -D "..args.device.." sget Master",function(stdout)
                local volume_percent = stdout:match("%[(%d+)%%%]")
                volume_percent = tonumber(volume_percent)
                if not volume_percent then
                    return
                end
                slider.value = volume_percent
                if stdout:match("%[off%]") then
                    volume_percent = 0
                end
                icon.image = get_icon(volume_percent)
            end)
        end
    }
    slider:connect_signal("widget::redraw_needed",function()
        awful.spawn("amixer -D "..args.device.." sset Master "..slider.value.."%")
        update_timer:again()
        icon.image = get_icon(slider.value)
    end)
    icon:connect_signal("button::press",function(_,_,_,button)
        if button == 1 then
            container.visible = not container.visible
            local children = widget:get_children_by_id("volume_widget_root")[1]
            if container.visible then
                children:add(slider_part)
            else
                children:remove_widgets(slider_part)
            end
        end
        if button == 3 then
            awful.spawn.with_shell(args.mixer or try_launch)
        end
        if button == 4 then
            awful.spawn("amixer -D "..args.device.." sset Master 5%+")
        end
        if button == 5 then
            awful.spawn("amixer -D "..args.device.." sset Master 5%-")
        end
    end)
    root.keys(gears.table.join(
        root.keys(),
        ask.k(":root.volume_up",function()
            awful.spawn("amixer -D "..args.device.." sset Master 5%+")
        end,{description = "increase master volume",group = "widgets"}),
        ask.k(":root.volume_down",function()
            awful.spawn("amixer -D "..args.device.." sset Master 5%-")
        end,{description = "decrease master volume",group = "widgets"}),
        ask.k(":root.volume_mute",function()
            awful.spawn("amixer -D "..args.device.." sset Master toggle")
        end,{description = "mute master volume", group = "widgets"})
    ))
    return widget
end
