local awful = require("awful")
local gears = require("gears")
local menubar_utils = require("menubar.utils")
local wibox = require("wibox")
local beautiful = require("beautiful")
local awmtk = require("awmtk")
--because async ls just... fails. (read the comments below)
local function synchronous_ls(dir)
    local filenames = {}
    local handler = io.popen("ls -1 "..dir,"r")
    handler:read("*a"):gsub("[^\n]+",function(filename)
        table.insert(filenames,filename)
    end)
    return filenames
end
local function loader(options)
    local style = awmtk.style(awmtk.defaults,options.style or {},"launcher_")
    options = options or {}
    local button_bg_on = style.launcher_button_bg_focus
    local button_bg_off = style.launcher_button_bg_normal
    local userlinks = (
        --list_container function allows generating any kind of widget which supports the 
        --"add" method to add buttons.
        options.list_container and (
            wibox.widget(options.list_container())
        )
    ) or (
        (options.vertical == true) and
        wibox.widget {
            layout = wibox.layout.fixed.vertical,
            spacing = style.launcher_container_spacing or 4,
        }
    ) or (
        wibox.widget {
            layout = wibox.layout.fixed.horizontal,
            spacing = style.launcher_container_spacing or 4,
        }
    )
    --The following process **has** to be done synchronously.
    --This causes a (barely noticeable) slowdown while loading, but it prevents a race condition which causes crashes occasional crashes on slow devices.
    
    --specify a sensible path
    local programs_path = (options.links_dir or ((global and global.config_dir) or os.getenv("HOME").."/.awesome").."/links")
    --add a slash at the end if one isn't set
    local programs_path = programs_path..((not programs_path:match("/$")) and "/")
    local programs = synchronous_ls(programs_path)
    --remove everything that doesn't end with ".desktop" from file list
    for k,v in pairs(programs) do
        if not v:match("%.desktop$") then
            table.remove(programs,k)
        end
    end
    for k,v in pairs(programs) do
        --parse a desktop file
        local v = menubar_utils.parse_desktop_file(programs_path..v)
        if v then
            local temp_widget = style.button(
            {
                image = menubar_utils.lookup_icon_uncached(v.Icon),
                widget = wibox.widget.imagebox
            },{},{})
            awmtk.connect_buttons(temp_widget,{
                function()
                    local comm = v.Exec:gsub("(%s+)%%.(%s*)","%1%2")
                    awful.spawn(comm)
                    temp_widget:get_children_by_id("widget_background")[1].bg = button_bg_on
                end,
                release_1 = function()
                    temp_widget:get_children_by_id("widget_background")[1].bg = button_bg_off
                end
            })
            userlinks:add(temp_widget)
        end
    end
    return userlinks
    --end of loader function
end

return loader
