-- Change to variable

local TrickleDeleteScene = function(Obj, Time, timeMockLib)
	-- Used for testing
	local taskLib = timeMockLib or task
	RunService = timeMockLib or RunService

	-- Give the Object a PrimaryPart(and put it inside a Model)
	local Model = GiveObjectPrimaryPart(Obj)
	-- Move the Model far away so players don't see it unloading
	Model:SetPrimaryPartCFrame(CFrame.new(Vector3.new(20000, 300, math.random(-10000, 10000))))

	-- Set time to the default if no time is given
	Time = Time or DefaultTime

	-- Sort all descendants into two lists, and calculate how many instances are to be deleted.
	-- (We ignore Models and Folders during initial delete pass. These are all deleted together at the end. - (Unless they are a child of another instance which is deleted)
	local PriorityDelete = {}
	local RemainingToDelete = {}
	local TotalToDeleteNum = 0
	for _, Descendant in pairs(Obj:GetDescendants()) do
		if Descendant.ClassName ~= "Model" and Descendant.ClassName ~= "Folder" then
			if PriorityDeleteTypes[Descendant.ClassName] then
				PriorityDelete[#PriorityDelete + 1] = Descendant
			else
				RemainingToDelete[#RemainingToDelete + 1] = Descendant
			end
			TotalToDeleteNum += 1
		end
	end

	-- Setup variables for the next step
	local TimeTaken = 0
	local PriorityCleared = false
	local RemainingToDeleteCleared = false
	if TotalToDeleteNum > 50000 then
		warn("Deleting more than 50k instances can cause a buffer overflow!!")
	end
	Time = math.max(Time, TotalToDeleteNum / 10000) -- Deleting too many parts per frame causes the buffers to overflow.

	-- Delete all the items, first in the priority list and then the rest of the items.
	local LastDeleteGoal = 0
	local HeartbeatConnection
	HeartbeatConnection = RunService.Heartbeat:Connect(function(Delta)
		TimeTaken += Delta
		local DeleteGoal = (TimeTaken / Time) * TotalToDeleteNum
		local ToDeleteThisRound = math.ceil(DeleteGoal - LastDeleteGoal)
		LastDeleteGoal = DeleteGoal

		if not PriorityCleared then
			if #PriorityDelete <= 0 then
				PriorityCleared = true
			else
				PriorityCleared = DeleteAmountOfObjectsInTable(PriorityDelete, ToDeleteThisRound)
				if not PriorityCleared then
					return
				end
			end
		end

		if not RemainingToDeleteCleared then
			if #RemainingToDelete <= 0 then
				RemainingToDeleteCleared = true
				Model:Destroy()
				HeartbeatConnection:Disconnect()
			else
				RemainingToDeleteCleared = DeleteAmountOfObjectsInTable(RemainingToDelete, ToDeleteThisRound)
				if not RemainingToDeleteCleared then
					return
				else
					Model:Destroy()
					HeartbeatConnection:Disconnect()
				end
			end
		else
			Model:Destroy()
			HeartbeatConnection:Disconnect()
		end
	end)

	repeat
		taskLib.wait()
	until PriorityCleared
end

return TrickleDeleteScene
