#include "../helpers/entity.lua"
#include "../helpers/utils.lua"
#include "../helpers/string.lua"
#include "../helpers/timer.lua"
#include "../helpers/tablefr.lua"

pLimit = GetIntParam("limit", 0)
pPrioritiesLimit = GetIntParam("priorities_limit", 0)

function init()
    locs = FindLocations()
    if pLimit > 0 then
        table.shuffle(locs)
        table.trim(locs, pLimit)
    end

    locs = map(locs, function(loc)
        local cond = GetTagValue(loc, "cond"):gsub("\\_", " ")
        if cond ~= "" then
            -- need to make sure conditions are met, probably script should be initialized after some others
            if not loadstring([[return ]]..cond)() then
                return
            end
        end
        local xml
        if pPrioritiesLimit > 0 then
            xml = GetTagValue(loc, 'prio_xml'):gsub('\\_', ' ')
            pPrioritiesLimit = pPrioritiesLimit-1
        else
            xml = GetTagValue(loc, 'xml'):gsub('\\_', ' ')
        end
        return {
            loc,
            xml = xml,
            tr = GetLocationTransform(loc),
            allowStatic = GetTagValue(loc, 'allowStatic'):as_bool(),
            jointExisting = GetTagValue(loc, 'jointExisting'):as_bool(),
            delay = tonumber(GetTagValue(loc, 'spawnDelay')) or 0,
            lifetime = tonumber(GetTagValue(loc, 'spawnLifetime')),
            spawned = false,
    } end)
    locs.disabled = 0
    timer = 0
    maxTime = 0

    for i = 1, #locs do
        local loc = locs[i]
        loc.index = i
        if loc.delay == 0 then
            CallSpawn(loc)
        end
    end
end

function update(dt)
    timer_manager:Tick(dt)
    if disabled then return end

    timer = timer+dt
    for i = 1, #locs do
        local loc = locs[i]
        if timer >= loc.delay then
            CallSpawn(loc)
        end
    end

    if locs.disabled == #locs then
        if timer >= maxTime then
            cEntity:EnqueueDeletion()
            disabled = true
        end
    end
end

function CallSpawn(list)
    local location = list[1]
    if not list.spawned then
        local entities = Spawn(list.xml, list.tr, list.allowStatic, list.jointExisting)
        for i = 1, #entities do
            SetTag(entities[i], "customspawn")
        end

        if list.lifetime then
            maxTime = math.max(list.delay+list.lifetime, maxTime)
            timer_manager:CreateTimer('despawn-'..list.index, list.lifetime, false, batchDelete, entities)
        end

        cEntity:EnqueueDeletion(location)
        locs.disabled = locs.disabled+1
        list.spawned = true
    end
end

function batchDelete(list)
    for i = 1, #list do
        local entity = list[i]
        if IsHandleValid(entity) then
            Delete(entity)
        end
    end
end
