local BattleScheduler = {}

local totalSid = 0

function BattleScheduler:init()
	self.schedulerList = {}
    self.dirty = false
    self.timeScale = 1
    self.over = false
    if self.scheduleId then
		ModuleManager.BattleManager:unscheduleGlobal(self.scheduleId)
	end
    self.scheduleId = ModuleManager.BattleManager:scheduleGlobal(function(dt)
		self:update(dt)
	end, 0)
end

function BattleScheduler:update(dt)
    if #self.schedulerList == 0 then
        return
    end
    if self.dirty then
        self.dirty = false
        local count = #self.schedulerList
        for i = 1, count do
            if self.schedulerList[i].waitRemove then
                local newCount = i
                i = i + 1
                while i <= count do
                    if not self.schedulerList[i].waitRemove then
                        self.schedulerList[newCount] = self.schedulerList[i]
                        newCount = newCount + 1
                    end
                    i = i + 1
                end
                for j = 0, count - newCount do
                    table.remove(self.schedulerList)
                end
                break
            end
        end
    end
    local inter = dt*self.timeScale
    for _, info in ipairs(self.schedulerList) do
        info.tick = info.tick + inter
        if info.tick >= info.inter then
            info.tick = info.tick - info.inter
            info.waitRemove = true
            if info.func then
                local s = info.func(inter, dt)
                local stop = not info.rep or s
                if stop then
                    self.dirty = true
                else
                    info.waitRemove = false
                end
            else
                self.dirty = true
            end
        end
    end
end

function BattleScheduler:startSchedule(func, inter, rep)
    if self.over then
        return
    end
    totalSid = totalSid + 1
    local info = {sid = totalSid, inter = inter, tick = 0, func = func, rep = rep}
    table.insert(self.schedulerList, info)
    return info.sid
end

function BattleScheduler:scheduleGlobal(func, inter)
    return self:startSchedule(func, inter, true)
end

function BattleScheduler:performWithDelayGlobal(func, delay)
    return self:startSchedule(func, delay, false)
end

function BattleScheduler:unscheduleGlobal(sid)
    if self.over then
        return
    end
    for k, info in ipairs(self.schedulerList) do
        if info.sid == sid then
            info.waitRemove = true
            info.func = nil
            self.dirty = true
            break
        end
    end
end

function BattleScheduler:setTimeScale(timeScale)
    self.timeScale = timeScale
end

function BattleScheduler:clear()
	for i = 1, #self.schedulerList do
		table.remove(self.schedulerList)
	end
    self.dirty = false
    self.over = true
    self.timeScale = 1
    if self.scheduleId then
		ModuleManager.BattleManager:unscheduleGlobal(self.scheduleId)
		self.scheduleId = nil
	end
end

return BattleScheduler