------------------------------------------------------------------------------------------------------
-- Necrosis LdC
--
-- Créateur initial (US) : Infernal (http://www.revolvus.com/games/interface/necrosis/)
-- Implémentation de base (FR) : Tilienna Thorondor
-- Reprise du projet : Lomig & Nyx des Larmes de Cenarius, Kael'Thas
-- 
-- Skins et voix Françaises : Eliah, Ner'zhul
-- Version Allemande par Arne Meier
-- Remerciements spéciaux pour Sadyre (JoL)
-- Version 24.01.2006-5
------------------------------------------------------------------------------------------------------


------------------------------------------------------------------------------------------------------
-- FONCTIONS D'INSERTION
------------------------------------------------------------------------------------------------------

-- La table des timers est là pour ça !
function Necrosis_InsertTimerParTable(IndexTable, Target, LevelTarget, SpellGroup, SpellTimer)
	local tri = NECROSIS_SPELL_TABLE.Type[IndexTable];
	table.insert(SpellTimer.Name, tri, NECROSIS_SPELL_TABLE.Name[IndexTable]);
	table.insert(SpellTimer.Time, tri, NECROSIS_SPELL_TABLE.Length[IndexTable]);
	table.insert(SpellTimer.TimeMax, tri, floor(GetTime() + NECROSIS_SPELL_TABLE.Length[IndexTable]));
	table.insert(SpellTimer.Type, tri, NECROSIS_SPELL_TABLE.Type[IndexTable]);
	table.insert(SpellTimer.Target, tri, Target);
	table.insert(SpellTimer.TargetLevel, tri, LevelTarget);
	table.insert(SpellTimer.Group, tri, 0);
	SpellGroup, SpellTimer = Necrosis_Parsing(SpellGroup, SpellTimer);
	return SpellGroup, SpellTimer;
end

-- Et pour insérer le timer de pierres
function Necrosis_InsertTimerStone(Stone, start, duration, SpellGroup, SpellTimer)
	if Stone == "Healthstone" then
		table.insert(SpellTimer.Name, 2, NECROSIS_COOLDOWN.Healthstone);
		table.insert(SpellTimer.Time, 2, 180);
		table.insert(SpellTimer.TimeMax, 2, floor(GetTime() + 180));
		table.insert(SpellTimer.Type, 2, 2);
		table.insert(SpellTimer.Target, 2, "");
		table.insert(SpellTimer.TargetLevel, 2, "");
		table.insert(SpellTimer.Group, 2, 2);
	elseif Stone == "Spellstone" then
		table.insert(SpellTimer.Name, 2, NECROSIS_COOLDOWN.Spellstone);
		table.insert(SpellTimer.Time, 2, 30);
		table.insert(SpellTimer.TimeMax, 2, floor(GetTime() + 30));
		table.insert(SpellTimer.Type, 2, 2);
		table.insert(SpellTimer.Target, 2, "");
		table.insert(SpellTimer.TargetLevel, 2, "");
		table.insert(SpellTimer.Group, 2, 2);
	elseif Stone == "Soulstone" then
		table.insert(SpellTimer.Name, 1, NECROSIS_SPELL_TABLE.Name[11]);
		table.insert(SpellTimer.Time, 1, floor(duration - GetTime() + start));
		table.insert(SpellTimer.TimeMax, 1, floor(start + duration));
		table.insert(SpellTimer.Type, 1, NECROSIS_SPELL_TABLE.Type[11]);
		table.insert(SpellTimer.Target, 1,  "???");
		table.insert(SpellTimer.TargetLevel, 1, "");
		table.insert(SpellTimer.Group, 1, 1);
	end
	SpellGroup, SpellTimer = Necrosis_Parsing(SpellGroup, SpellTimer);
	return SpellGroup, SpellTimer;
end
------------------------------------------------------------------------------------------------------
-- FONCTIONS DE RETRAIT
------------------------------------------------------------------------------------------------------


-- Connaissant l'index du Timer dans la liste, on le supprime
function Necrosis_RetraitTimerParIndex(index, SpellTimer)
	if SpellTimer ~= nil then
		table.remove(SpellTimer.Name, index);
		table.remove(SpellTimer.Time, index);
		table.remove(SpellTimer.TimeMax, index);
		table.remove(SpellTimer.Type, index);
		table.remove(SpellTimer.Target, index);
		table.remove(SpellTimer.TargetLevel, index);
		table.remove(SpellTimer.Group, index);
	end
	return SpellTimer;
end

-- Si on veut supprimer spécifiquement un Timer...
function Necrosis_RetraitTimerParNom(name, SpellTimer)
	for index = 1, table.getn(SpellTimer.Name), 1 do
		if SpellTimer.Name[index] == name then
			SpellTimer = Necrosis_RetraitTimerParIndex(index, SpellTimer);
			break;
		end
	end
	return SpellTimer;
end

-- Fonction pour enlever les timers de combat lors de la regen
function Necrosis_RetraitTimerCombat(SpellGroup, SpellTimer)
	if SpellTimer.Name ~= nil then
		for index=1, table.getn(SpellTimer.Name), 1 do
			-- Si les cooldowns sont nominatifs, on enlève le nom
			if SpellTimer.Type[index] == 3 then
				SpellTimer.Target[index] = "";
				SpellTimer.TargetLevel[index] = "";
			end
			-- Enlevage des timers de combat
			if ((SpellTimer.Type[index] == 4) or (SpellTimer.Type[index] == 5)) then
				SpellTimer = Necrosis_RetraitTimerParIndex(index, SpellTimer);
			end
		end
	end

	if table.getn(SpellGroup.Name) == 3 then
		return SpellGroup, SpellTimer;
	end
	for index = 4, table.getn(SpellGroup.Name), 1 do
		table.remove(SpellGroup.Name);
		table.remove(SpellGroup.SubName);
		table.remove(SpellGroup.Visible);
	end
	return SpellGroup, SpellTimer;
end

------------------------------------------------------------------------------------------------------
-- FONCTIONS BOOLEENNES
------------------------------------------------------------------------------------------------------

function Necrosis_TimerExisteDeja(Nom, SpellTimer)
	for index = 1, table.getn(SpellTimer.Name), 1 do
		if SpellTimer.Name[index] == Nom then
			return true;
		end
	end
	return false;
end


------------------------------------------------------------------------------------------------------
-- FONCTIONS DE TRI
------------------------------------------------------------------------------------------------------

-- On définit les groupes de chaque Timer
function Necrosis_Parsing(SpellGroup, SpellTimer)
	
	local GroupeOK = false;
	for index = 1, table.getn(SpellTimer.Name), 1 do
		-- Si le timer est un timer fixe, on lui associe l'un des trois premiers groupes
		if SpellTimer.Type[index] == 1 or SpellTimer.Type[index] == 2 or SpellTimer.Type[index] == 3 then
			GroupeOK = true ;
			SpellTimer.Group[index] = SpellTimer.Type[index];
		else 
			-- Pour les autres sorts on regarde si le groupe existe déjà
			for i = 4, table.getn(SpellGroup.Name), 1 do
				if SpellTimer.Target[index] == SpellGroup.Name[i]
					and SpellTimer.TargetLevel[index] == SpellGroup.SubName[i]
					then
					GroupeOK = true;
					SpellTimer.Group[index] = i;
					break
				end
				GroupeOK = false;
			end
		end
		-- Si le groupe n'existe pas, on en crée un nouveau
		if not GroupeOK then
			table.insert(SpellGroup.Name, SpellTimer.Target[index]);
			table.insert(SpellGroup.SubName, SpellTimer.TargetLevel[index]);
			table.insert(SpellGroup.Visible, false);
			SpellTimer.Group[index] = table.getn(SpellGroup.Name);
		end
	end
	SpellTimer = Necrosis_Tri(SpellTimer);
	return SpellGroup, SpellTimer;
end

-- On trie les timers selon leur groupe
function Necrosis_Tri(SpellTimer)
	local Temporaire = {
		Name = nil,
		Time = nil,
		TimeMax = nil,
		Type = nil,
		Target = nil,
		TargetLevel = nil,
		Group = nil
	};

	for j = 2, table.getn(SpellTimer.Name), 1 do
		Temporaire.Name = SpellTimer.Name[j];
		Temporaire.Time = SpellTimer.Time[j];
		Temporaire.TimeMax = SpellTimer.TimeMax[j];
		Temporaire.Type = SpellTimer.Type[j];
		Temporaire.Target = SpellTimer.Target[j];
		Temporaire.TargetLevel = SpellTimer.TargetLevel[j];
		Temporaire.Group = SpellTimer.Group[j];

		local i = j - 1;
		while i > 0 and SpellTimer.Group[i] > Temporaire.Group do
			SpellTimer.Name[i+1] = SpellTimer.Name[i];
			SpellTimer.Time[i+1] = SpellTimer.Time[i];
			SpellTimer.TimeMax[i+1] = SpellTimer.TimeMax[i];
			SpellTimer.Type[i+1] = SpellTimer.Type[i];
			SpellTimer.Target[i+1] = SpellTimer.Target[i];
			SpellTimer.TargetLevel[i+1] = SpellTimer.TargetLevel[i];
			SpellTimer.Group[i+1] = SpellTimer.Group[i];

			i = i - 1;
		end
		SpellTimer.Name[i+1] = Temporaire.Name;
		SpellTimer.Time[i+1] = Temporaire.Time;
		SpellTimer.TimeMax[i+1] = Temporaire.TimeMax;
		SpellTimer.Type[i+1] = Temporaire.Type;
		SpellTimer.Target[i+1] = Temporaire.Target;
		SpellTimer.TargetLevel[i+1] = Temporaire.TargetLevel;
		SpellTimer.Group[i+1] = Temporaire.Group;
	end
	return SpellTimer;
end


------------------------------------------------------------------------------------------------------
-- FONCTIONS D'AFFICHAGE : CREATION DE LA CHAINE DE CARACTERE
------------------------------------------------------------------------------------------------------


function Necrosis_DisplayTimer(display, index, SpellGroup, SpellTimer, GraphicalTimer)
	if not SpellTimer.Name then
		return display, SpellGroup;
	end
	
	local minutes = 0;
	local seconds = 0;
	local affichage;
	
	-- Changement de la couleur suivant le temps restant	
	local percent = (floor(SpellTimer.TimeMax[index]-floor(GetTime())) / SpellTimer.Time[index])*100;
	local color = NecrosisTimerColor(percent);
	
	if not SpellGroup.Visible[SpellTimer.Group[index]]
		and SpellGroup.SubName[SpellTimer.Group[index]] ~= nil
		and SpellGroup.Name[SpellTimer.Group[index]] ~= nil then
		display = display.."<purple>-------------------------------\n"..SpellGroup.Name[SpellTimer.Group[index]].." "..SpellGroup.SubName[SpellTimer.Group[index]].."\n-------------------------------<close>\n";
		-- Crée le tableau qui servira aux timers graphiques
		table.insert(GraphicalTimer.texte, SpellGroup.Name[SpellTimer.Group[index]].." "..SpellGroup.SubName[SpellTimer.Group[index]]);
		table.insert(GraphicalTimer.TimeMax, 0);
		table.insert(GraphicalTimer.Time, 0);
		table.insert(GraphicalTimer.titre, true);
		table.insert(GraphicalTimer.temps, "");
		SpellGroup.Visible[SpellTimer.Group[index]] = true;
	end

	-- Mise en place d'un Chrono plutôt qu'un Compte à Rebours pour l'asservissement
	if SpellTimer.Name[index] == NECROSIS_SPELL_TABLE.Name[10] then
		seconds = floor(GetTime()) - (SpellTimer.TimeMax[index] - SpellTimer.Time[index]);
	else
		seconds = SpellTimer.TimeMax[index] - floor(GetTime());
	end
	minutes = floor(seconds/60);
	if (minutes > 0) then
		if (minutes > 9) then
			affichage = tostring(minutes)..":";
		else
			affichage = "0"..minutes..":"
		end
	else
		affichage = "0:";
	end
	seconds = mod(seconds, 60);
	if (seconds > 9) then
		affichage = affichage..seconds
	else
		affichage = affichage.."0"..seconds
	end
	display = display.."<white>"..affichage.." - <close>";

	-- Crée le tableau qui servira aux timers graphiques
	table.insert(GraphicalTimer.texte, SpellTimer.Name[index]);
	table.insert(GraphicalTimer.TimeMax, SpellTimer.TimeMax[index]);
	table.insert(GraphicalTimer.Time, SpellTimer.Time[index]);
	table.insert(GraphicalTimer.titre, false);
	table.insert(GraphicalTimer.temps, affichage);

	if NecrosisConfig.CountType == 3 then
		if SpellTimer.Name[index] == NECROSIS_SPELL_TABLE.Name[11] then
			if (minutes > 0) then
				NecrosisShardCount:SetText(minutes.." m");
			else
				NecrosisShardCount:SetText(seconds);
			end
		end
	end
	if NecrosisConfig.Circle == 2 then
		if SpellTimer.Name[index] == NECROSIS_SPELL_TABLE.Name[11] then
			if (minutes >= 16) then
				NecrosisButton:SetNormalTexture("Interface\\AddOns\\Necrosis\\UI\\Turquoise\\Shard"..minutes - 15);
			elseif minutes >= 1 or seconds >= 33 then
				NecrosisButton:SetNormalTexture("Interface\\AddOns\\Necrosis\\UI\\Orange\\Shard"..minutes + 1);
			else
				NecrosisButton:SetNormalTexture("Interface\\AddOns\\Necrosis\\UI\\Rose\\Shard"..seconds);
			end
		end
	end
	display = display..color..SpellTimer.Name[index].."<close><white>";
	if (SpellTimer.Type[index] == 1 or SpellTimer.Name[index] == NECROSIS_SPELL_TABLE.Name[16])
		and (SpellTimer.Target[index] ~= "")
		then
		display = display.." - "..SpellTimer.Target[index].."<close>\n";
	else
		display = display.."<close>\n";
	end
	-- Affichage des timers graphiques (si sélectionnés)
	if NecrosisConfig.Graphical then
		NecrosisAfficheTimer(GraphicalTimer);
	end

	return display, SpellGroup, GraphicalTimer;
end
