--- @class SpriteAtlas
--- @field tileSize integer
--- @field atlas love.Image
--- @field map table<string, love.Quad>
local spriteAtlas = {}
spriteAtlas.__index = spriteAtlas

--- @param path table
local function load(path)
    --- @type love.Image
    local atlas = path.atlas
    --- @type table
    local manifest = path.manifest

    local _spriteAtlas = {
        tileSize = manifest.tileSize,
        atlas = atlas,
        map = {}
    }
    manifest.tileSize = nil

    local layout = {}
    for group, ids in pairs(manifest) do
        for _, id in ipairs(ids) do
            if layout[id] then
                table.insert(layout[id], group)
            else
                layout[id] = { group }
            end
        end
    end

    local cnt = 0
    for y = 0, atlas:getHeight() - 1, _spriteAtlas.tileSize do
        for x = 0, atlas:getWidth() - 1, _spriteAtlas.tileSize do
            if layout[cnt] then
                for _, group in ipairs(layout[cnt]) do
                    print(x, y, _spriteAtlas.tileSize, atlas, false)
                    local quad = love.graphics.newQuad(x, y, _spriteAtlas.tileSize, _spriteAtlas.tileSize, atlas)

                    if _spriteAtlas.map[group] then
                        table.insert(_spriteAtlas.map[group], quad)
                    else
                        _spriteAtlas.map[group] = { quad }
                    end
                end
            end
            cnt = cnt + 1
        end
    end

    return setmetatable(_spriteAtlas, spriteAtlas)
end

--- Returns a random quad of the group
---
--- @param tag string
--- @return love.Quad
function spriteAtlas:pickQuad(tag)
    local group = self.map[tag]
    if group then
        return group[math.random(1, #group)]
    end

    print("[SpriteAtlas]: no tile with a tag '" .. tag .. "'")
    return love.graphics.newQuad(0, 0, self.tileSize, self.tileSize, self.atlas) --fallback
end

return { load = load }
