local awful = require("awful")
local pager = require("widgets.pager")
local beautiful = require("beautiful")
local gears = require("gears")
local spawn = require("awful.spawn")
local wibox = require("wibox")
local awmtk = require("awmtk")
local thumbnailer = require("thumbnail")
local widget = {}
local function ls(path)
    local ls_data = io.popen("ls -1 "..path)
    local output = {}
    if ls_data then
        ls_data:read("*a"):gsub("[^\n]+",function(capt) table.insert(output,capt) end)
        ls_data:close()
    else
        error("ls "..path.." failed.")
    end
    return output
end

local function worker(args)
    local args = args or {}
    assert(type(args["screen"]) ~= "nil","Screen not specified")
    assert(type(args["path"]) ~= "nil","Path to wallpapers folder not specified")
    --add an extra slash to path if there is none
    if not args["path"]:match("/$") then
        args["path"] = args["path"].."/"
    end
    --create local style
    local style = awmtk.style(awmtk.defaults,args.style or {},"wallpapers_")
    --set wallpaper
    local handler = io.open(global.config_dir.."/.wallpaper","r") 
    if handler then
        local wallpaper_path = handler:read("*a")
        gears.wallpaper.maximized(wallpaper_path,args["screen"])
    end
    local function update_last_wallpaper(s)
        local handler = io.open(global.config_dir.."/.wallpaper","w")
        handler:write(s)
        handler:close()
    end
    --read wallpapers from the wallpaper directory
    local image_list = ls(args["path"])
    for k,v in pairs(image_list) do
        if not (v:match("%.jpg$") or v:match("%.png$")) then
            image_list[k] = nil
        end
    end 
    --generate thumbnails to save up memory
    thumbnailer.generate(args["path"],args["path"]..".thumbnails",60)
    --style variables
    local button_bg = style.wallpapers_button_bg_focus
    local function new_wallpaper_button(image,s)
        local new_widget = style.button({
            image  = args["path"]..".thumbnails/"..image,
            resize = true,
            widget = wibox.widget.imagebox
        },{
            bg = button_bg,
            forced_height = style.wallpapers_button_height or 60,
            forced_width = style.wallpapers_button_width or 100
        },{
            function()
                gears.wallpaper.maximized(args["path"]..image,s)
                update_last_wallpaper(args["path"]..image)
            end
        })
        return new_widget
    end
    local copy_list = wibox.widget {
        layout = wibox.layout.grid,
        forced_num_cols = args.columns or 4,
        homogeneous     = true,
        expand = true,
        orientation = "vertical",
        spacing = style.wallpapers_container_spacing_vertical
    }
    local pager = pager(copy_list,{},((args.rows and args.columns) and args.rows*args.columns) or 20)
    for k,v in pairs(image_list) do
        local new_widget = new_wallpaper_button(v,args["screen"])
        table.insert(pager.list,new_widget)
    end
    pager:update()
    --create local substyle for pager buttons
    local style = awmtk.style(awmtk.defaults,args.style or {},"wallpapers_pager_")
    local popup = awful.popup(style.container(
        {   
            pager.page,
            {
                style.button({
                    layout = wibox.layout.fixed.vertical
                },{
                    forced_width = style.wallpapers_pager_button_size,
                    forced_height = style.wallpapers_pager_button_size,
                    shape = gears.shape.isosceles_triangle,
                    bg = style.wallpapers_pager_button_bg_focus
                },{
                    function()
                        pager:prev()
                    end
                }),
                style.button({
                    layout = wibox.layout.fixed.vertical
                },{
                    forced_width = style.wallpapers_pager_button_size,
                    forced_height = style.wallpapers_pager_button_size,
                    shape = function(cr,width,height)
                        gears.shape.transform(gears.shape.isosceles_triangle):rotate_at(width/2, height/2, math.pi)(cr,width,height)
                    end,
                    bg = style.wallpapers_pager_button_bg_focus
                },{
                    function()
                        pager:next()
                    end
                }),
                layout = wibox.layout.fixed.vertical,
                spacing = style.wallpapers_pager_container_spacing_vertical
            },
            layout = wibox.layout.fixed.horizontal,
            spacing = style.wallpapers_pager_container_spacing_horizontal
        },      
        {
            visible = false,
            ontop = true
        }
    ))
    local clip_widget = style.icon({
        image  = style["wallpapers_icon"],
        resize = true,
        widget = wibox.widget.imagebox
    },{
        bg = style.wallpapers_icon_bg_normal
    },{
        function()
            if popup.visible then
                popup.visible = not popup.visible
            else
                popup:move_next_to(mouse.current_widget_geometry)
            end
        end
    })
    return clip_widget
end

return setmetatable(widget, { __call = function(_, ...) return worker(...) end })
