local awful = require("awful")
local gears = require("gears")
local wibox = require("wibox")
local awmtk = require("awmtk")

return function(args)
    local style = awmtk.style(awmtk.defaults, args.style or {},"volume_")
    local device = args.device or "default"
    local icons = args.icons or {
        high = style.volume_icon_high,
        medium = style.volume_icon_medium,
        low = style.volume_icon_low,
        muted = style.volume_icon_muted,
    }
    local controls = args.controls or {
        "Master",
        "Headphone"
    }
    local function get_icon(percent)
        if percent >= 66 then
            return icons.high
        elseif percent >= 33 then
            return icons.medium
        elseif percent > 0 then
            return icons.low
        else
            return icons.muted
        end
    end
    local commands = args.commands or {
        get_master = "amixer -D "..device.." sget Master",
        set = "amixer -q -D "..device.." sset ",
        get = "amixer -D "..device.." sget "
    }
    local list = {
        layout = wibox.layout.fixed.vertical
    }
    for k,v in pairs(controls) do
        local widget = wibox.widget({
            {
                widget = wibox.widget.textbox,
                markup = v,
                ellipsize = "end",
                font = style.volume_font
            },
            {
                widget = wibox.widget.slider,
                id = "widget_slider",
                handle_width = style.volume_handle_width or 6,
                bar_height = style.volumer_bar_width or 5,
                bar_color = style.volume_bar_color or "#55CC60",
                bar_shape = style.bar_shape,
                handler_shape = style.handle_shape,
                value = 100,
            },
            layout = wibox.layout.fixed.vertical,
            spacing = style.volume_container_spacing_horizontal,
            forced_width = style.volume_slider_width or 180,
            forced_height = style.volume_slider_height or 40
        })
        local slider = widget:get_children_by_id("widget_slider")[1]
        awful.spawn.easy_async_with_shell(commands.get..v,function(out)
            local volume_percent = out:match("%[(%d+)%%%]") or ""
            volume_percent = tonumber(volume_percent)
            if not volume_percent then
                return
            end
            slider.value = volume_percent
        end)
        slider:connect_signal("widget::redraw_needed",function()
            awful.spawn(commands.set..v.." "..slider.value.."%")
        end)
        table.insert(list,widget)
    end
    local tweaker_popup = awful.popup(style.container(list,{
        visible = false,
        ontop = true
    }))
    local icon = style.icon({
        widget = wibox.widget.imagebox,
        image = icons.muted,
        id = "widget_icon"
    },{},{
        function()
            if mouse.current_widget_geometry and (not tweaker_popup.visible) then
                tweaker_popup:move_next_to(mouse.current_widget_geometry)
                tweaker_popup.visible = true
            else
                tweaker_popup.visible = false
            end
        end
    })
    gears.timer {
        autostart = true,
        timeout = 0.5,
        call_now = true,
        callback = function()
            awful.spawn.easy_async_with_shell(commands.get_master, function(out)
                local volume_percent = out:match("%[(%d+)%%%]") or ""
                volume_percent = tonumber(volume_percent)
                if not volume_percent then
                    return
                end
                icon:get_children_by_id("widget_icon")[1].image = get_icon(volume_percent)
            end)
        end
    }
    return icon
end
