require "common.L5"
local selectedGame, errorMessage
local gameFolders = love.filesystem.getDirectoryItems("games")
local currentGame = 0
local games = {}

local function runHook(f, ...)
    if not f then return end
    local ok, err = xpcall(f, debug.traceback, ...)
    if not ok then
        errorMessage = err
    end
end


local function requireGame(gameFolder)
    local package = "games." .. gameFolder
    local ok, result = pcall(require, package)
    if not ok then
        table.insert(games, { package = package, name = "ERROR!", themes = {}, about = result , id = -math.huge})
    else
        result.package = package
        table.insert(games, result)
    end
end

local function reloadGame(offset)
    love.audio.stop()
    errorMessage = nil
    local game = games[1 + offset]
    local gamePackage = game.package
    package.loaded[game.package] = false
    local ok, result = pcall(require, gamePackage)
    if not ok then
        games[1 + offset] = { package = gamePackage, name = "ERROR!", themes = {}, about = result , id = -math.huge}
        if selectedGame then
            errorMessage = result
        end
    else
        result.package = gamePackage
        games[1 + offset] = result
    end
    
    if not errorMessage and selectedGame then
        selectedGame = games[1 + currentGame].game
        runHook(selectedGame.setup, selectedGame)
    end
end

for _, gameFolder in ipairs(gameFolders) do
    requireGame(gameFolder)
end

table.sort(games, function(a, b) return a.id < b.id end)

function setup()
    textSize(14)
    noStroke()
    noSmooth()
end

function draw()
    textAlign(LEFT, BOTTOM)
    background(0)
    fill(255)
    if errorMessage then
        text(errorMessage, 10, 10 + textHeight(), width)
    elseif selectedGame then
        return runHook(selectedGame.draw, selectedGame)
    else
        for i, game in ipairs(games) do
            if i == 1 + currentGame then
                text("> " .. game.name, 10, i * textHeight() + 10)
            else
                text(game.name, 10, i * textHeight() + 10)
            end
        end
        text(("%s\n\nThemes:\n%s"):format(games[1 + currentGame].about, table.concat(games[1 + currentGame].themes, ", ")), 400, textHeight() + 10, 300)
    end
end

function mousePressed()
    if selectedGame then 
        runHook(selectedGame.mousePressed, selectedGame)
    end
end

function keyPressed()
    if errorMessage then
        if key == "escape" then
            errorMessage = nil
            selectedGame = nil
            love.audio.stop()
        elseif key == "f5" then
            reloadGame(currentGame)
        end
    elseif selectedGame then
        runHook(selectedGame.keyPressed, selectedGame)
        if key == "escape" then
            love.audio.stop()
            selectedGame = nil
            size(800, 600)
        elseif key == "f5" then
            reloadGame(currentGame)
        end
    else
        if false then
        elseif key == "f5" then
            reloadGame(currentGame)
        elseif key == "escape" then
            love.event.quit()
        elseif key == "down" and not selectedGame then
            currentGame = (currentGame + 1) % #games
        elseif key == "up" and not selectedGame then
            currentGame = (currentGame + #games - 1) % #games
        elseif key == "return" or key == "space" and not selectedGame then
            selectedGame = games[1 + currentGame].game
            if selectedGame then
                return runHook(selectedGame.setup, selectedGame)
            end
        end
    end
end
