utils = utils or {}
utils.detail = utils.detail or {};

function utils.AssignDz(text_id)
	local dz = object.GetDamageZoneId(text_id);
	if not dz or dz < 0 then
		dz = nil;
	else
		object.ActivateDamageZone(true, dz);
	end
	return dz;
end

function utils.AssignFrames(text_id)
	local frm = object.GetFrameGroupId(text_id);
	if not frm or frm < 0 then
		return nil;
	else
		return frm;
	end
end

function utils.log_value(key,value,prefix)
	if key == "_G" then return end;
	prefix = prefix or "";
	log(prefix .. key .. "\t" .. tostring(value));
	if type(value) == "table" then
		local newprefix = prefix .. "\t";
		for k,v in pairs(value) do
			utils.log_value(k,v,newprefix);
		end
	end
end

function utils.CreateSubsystems()
	local s =
	{
		Run = utils.detail.run,
		AddPeriodic = utils.detail.add_periodic,
		RemovePeriodic = utils.detail.remove_periodic,
		UpdatePeriodic = utils.detail.update_periodic,
		AddOneTime = utils.detail.add_onetime,
		RemoveOneTime = utils.detail.remove_onetime,
		periodic = { },
		one_time = { },
	}
	return s;
end

function utils.detail.run(self)
	for _,v in pairs(self.periodic) do
		v:Run();
	end
	for k,v in pairs(self.one_time) do
		if v:Run() then self.one_time[k] = nil; end
	end
end

function utils.detail.run_periodic(self)
	self.counter = self.counter - 1;
	if self.counter <= 0 then
		self.counter = self.timeout;
		self:func();
	end
end

function utils.detail.add_periodic(self, Name, TimeOut, Func, InitialTime)
	if type(Func) ~= "function" then
		log("Incorrect function for AddPeriodic. (" .. Name .. ")");
		return;
	end
	if type(TimeOut) ~= "number" then
		log("Incorrect timeout for AddPeriodic. (" .. Name .. ")");
		return;
	end
	local o =
	{
		name = Name,
		timeout = TimeOut,
		counter = InitialTime or TimeOut,
		func = Func,
		Run = utils.detail.run_periodic,
	}
	self.periodic[Name] = o;
end

function utils.detail.remove_periodic(self, Name)
	self.periodic[Name] = nil;
end

function utils.detail.update_periodic(self, Name, Counter)
	self.periodic[Name].counter = Counter;
end

function utils.detail.run_onetime(self)
	self.counter = self.counter - 1;
	if self.counter <= 0 then
		self:func();
		return true;
	end
end

function utils.detail.add_onetime(self, Name, TimeOut, Func)
	if type(Func) ~= "function" then
		log("Incorrect function for AddOneTime. (" .. Name .. ")");
		return;
	end
	if type(TimeOut) ~= "number" then
		log("Incorrect timeout for AddOneTime. (" .. Name .. ")");
		return;
	end
	local o =
	{
		name = Name,
		counter = TimeOut,
		func = Func,
		Run = utils.detail.run_onetime,
	}
	self.one_time[Name] = o;
end

function utils.detail.remove_onetime(self, Name)
	self.one_time[Name] = nil;
end
