
--Damage Class
--a damage object is created inside an actor container
--an actor container is created inside a combat object
--combat objects has 4 actor containers: damage, healing, energy, utility
--these containers are indexed within the combat object table: combatObject[1] = damage container, combatObject[2] = healing container, combatObject[3] = energy container, combatObject[4] = utility container


--damage object
	local Details = _G.Details
	local Loc = LibStub("AceLocale-3.0"):GetLocale ( "Details" )
	local Translit = LibStub("LibTranslit-1.0")
	local gump = Details.gump
	local _ = nil
	local detailsFramework = DetailsFramework
	local addonName, Details222 = ...

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--local pointers

	local format = string.format --lua local
	local _math_floor = math.floor --lua local
	local _table_sort = table.sort --lua local
	local tinsert = table.insert --lua local
	local setmetatable = setmetatable --lua local
	local _getmetatable = getmetatable --lua local
	local ipairs = ipairs --lua local
	local pairs = pairs --lua local
	local _math_min = math.min --lua local
	local _math_max = math.max --lua local
	local abs = math.abs --lua local
	local bitBand = bit.band --lua local
	local unpack = unpack --lua local
	local type = type --lua local
	local GameTooltip = GameTooltip --api local
	local IsInRaid = IsInRaid --api local
	local IsInGroup = IsInGroup --api local

	local GetSpellInfo = GetSpellInfo --api local
	local _GetSpellInfo = Details.getspellinfo --details api
	local stringReplace = Details.string.replace --details api

	--show more information about spells
	local debugmode = false

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--constants

	local spellContainerClass	= 	Details.container_habilidades
	local damageClass	=	Details.atributo_damage
	local atributo_misc		=	Details.atributo_misc
	local container_damage	=	Details.container_type.CONTAINER_DAMAGE_CLASS

	local modo_GROUP = Details.modos.group
	local modo_ALL = Details.modos.all

	local class_type = Details.atributos.dano

	local ToKFunctions = Details.ToKFunctions
	local SelectedToKFunction = ToKFunctions[1]

	local UsingCustomLeftText = false
	local UsingCustomRightText = false

	local FormatTooltipNumber = ToKFunctions[8]
	local TooltipMaximizedMethod = 1

	--local CLASS_ICON_TCOORDS = _G.CLASS_ICON_TCOORDS
	local is_player_class = Details.player_class

	Details.tooltip_key_overlay1 = {1, 1, 1, .2}
	Details.tooltip_key_overlay2 = {1, 1, 1, .5}

	Details.tooltip_key_size_width = 24
	Details.tooltip_key_size_height = 10

	local enemies_background = {value = 100, color = {0.1960, 0.1960, 0.1960, 0.8697}, texture = "Interface\\AddOns\\Details\\images\\bar_background2"}

	local headerColor = {1, 0.9, 0.0, 1}

	local breakdownWindowFrame = Details.BreakdownWindowFrame
	local keyName

	local OBJECT_TYPE_PLAYER =	0x00000400

	local ntable = {} --temp
	local vtable = {} --temp
	local tooltip_void_zone_temp = {} --temp
	local bs_table = {} --temp
	local bs_index_table = {} --temp
	local bs_tooltip_table
	local frags_tooltip_table

	local tooltip_temp_table = {}

	local OBJECT_TYPE_FRIENDLY_NPC 	=	0x00000A18

	local ignoredEnemyNpcsTable = Details.IgnoredEnemyNpcsTable

	--damage mixin
	local damageClassMixin = {}

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--exported functions

function Details:CreateActorLastEventTable() --[[exported]]
		local t = { {}, {}, {}, {}, {}, {}, {}, {} }
		t.n = 1
	return t
end

function damageClass:CreateFFTable(targetName) --[[exported]]
	local newTable = {total = 0, spells = {}}
	self.friendlyfire[targetName] = newTable
	return newTable
end

function Details:CreateActorAvoidanceTable(noOverall) --[[exported]]
	if (noOverall) then
		local avoidanceTable = {["ALL"] = 0, ["DODGE"] = 0, ["PARRY"] = 0, ["HITS"] = 0, ["ABSORB"] = 0, --quantas vezes foi dodge, parry, quandos hits tomou, quantos absorbs teve
			["FULL_HIT"] = 0, ["FULL_ABSORBED"] = 0, ["PARTIAL_ABSORBED"] = 0, --full hit full absorbed and partial absortion
			["FULL_HIT_AMT"] = 0, ["PARTIAL_ABSORB_AMT"] = 0, ["ABSORB_AMT"] = 0, ["FULL_ABSORB_AMT"] = 0, --amounts
			["BLOCKED_HITS"] = 0, ["BLOCKED_AMT"] = 0, --amount of hits blocked - amout of damage mitigated
		}
		return avoidanceTable
	else
		local avoidanceTable = {
			overall = {["ALL"] = 0, ["DODGE"] = 0, ["PARRY"] = 0, ["HITS"] = 0, ["ABSORB"] = 0, --quantas vezes foi dodge, parry, quandos hits tomou, quantos absorbs teve
			["FULL_HIT"] = 0, ["FULL_ABSORBED"] = 0, ["PARTIAL_ABSORBED"] = 0, --full hit full absorbed and partial absortion
			["FULL_HIT_AMT"] = 0, ["PARTIAL_ABSORB_AMT"] = 0, ["ABSORB_AMT"] = 0, ["FULL_ABSORB_AMT"] = 0, --amounts
			["BLOCKED_HITS"] = 0, ["BLOCKED_AMT"] = 0, --amount of hits blocked - amout of damage mitigated
		}
		}
		return avoidanceTable
	end
end

function Details.SortGroup(container, keyName2) --[[exported]]
	keyName = keyName2
	return _table_sort(container, Details.SortKeyGroup)
end

function Details.SortKeyGroup (table1, table2) --[[exported]]
	if (table1.grupo and table2.grupo) then
		return table1[keyName] > table2[keyName]

	elseif (table1.grupo and not table2.grupo) then
		return true

	elseif (not table1.grupo and table2.grupo) then
		return false

	else
		return table1[keyName] > table2[keyName]
	end
end


function Details.SortKeySimple(table1, table2) --[[exported]]
	return table1[keyName] > table2[keyName]
end

---sort by real time dps
---@param actor1 actor
---@param actor2 actor
---@return boolean
function Details.SortByRealTimeDps(actor1, actor2)
	return (actor1.last_dps_realtime or 0) > (actor2.last_dps_realtime or 0)
end


function Details:ContainerSort (container, amount, keyName2) --[[exported]]
	keyName = keyName2
	_table_sort(container,  Details.SortKeySimple)

	if (amount) then
		for i = amount, 1, -1 do --de tr�s pra frente
			if (container[i][keyName] < 1) then
				amount = amount-1
			else
				break
			end
		end

		return amount
	end
end

---return true if the actor is a friendly npc
---@return boolean
function Details:IsFriendlyNpc() --[[exported]]
	local flag = self.flag_original
	if (flag) then
		if (bitBand(flag, 0x00000008) ~= 0) then
			if (bitBand(flag, 0x00000010) ~= 0) then
				if (bitBand(flag, 0x00000800) ~= 0) then
					return true
				end
			end
		end
	end
	return false
end

function Details:IsEnemy() --[[exported]]
	if (self.flag_original) then
		if (bitBand(self.flag_original, 0x00000060) ~= 0) then
			local npcId = Details:GetNpcIdFromGuid(self.serial)
			if (ignoredEnemyNpcsTable[npcId]) then
				return false
			end
			return true
		end
	end
	return false
end

function Details:GetSpellList() --[[exported]]
	return self.spells._ActorTable
end


function Details:GetTimeInCombat(petOwner) --[[exported]]
	if (petOwner) then
		if (Details.time_type == 1 or not petOwner.grupo) then
			return self:Tempo()
		elseif (Details.time_type == 2 or Details.use_realtimedps) then
			return self:GetCombatTime()
		end
	else
		if (Details.time_type == 1) then
			return self:Tempo()
		elseif (Details.time_type == 2 or Details.use_realtimedps) then
			return self:GetCombatTime()
		end
	end
end


--enemies(sort function)
local sortEnemies = function(t1, t2)
	local a = bitBand(t1.flag_original, 0x00000060)
	local b = bitBand(t2.flag_original, 0x00000060)

	if (a ~= 0 and b ~= 0) then
		local npcid1 = Details:GetNpcIdFromGuid(t1.serial)
		local npcid2 = Details:GetNpcIdFromGuid(t2.serial)

		if (not ignoredEnemyNpcsTable[npcid1] and not ignoredEnemyNpcsTable[npcid2]) then
			return t1.damage_taken > t2.damage_taken

		elseif (ignoredEnemyNpcsTable[npcid1] and not ignoredEnemyNpcsTable[npcid2]) then
			return false

		elseif (not ignoredEnemyNpcsTable[npcid1] and ignoredEnemyNpcsTable[npcid2]) then
			return true
		else
			return t1.damage_taken > t2.damage_taken
		end

	elseif (a ~= 0 and b == 0) then
		return true

	elseif (a == 0 and b ~= 0) then
		return false
	end

	return false
end

function Details:ContainerSortEnemies (container, amount, keyName2) --[[exported]]
	keyName = keyName2

	_table_sort(container, sortEnemies)

	local total = 0

	for index, player in ipairs(container) do
		local npcid1 = Details:GetNpcIdFromGuid(player.serial)
		--p rint (player.nome, npcid1, ignored_enemy_npcs [npcid1])
		if (bitBand(player.flag_original, 0x00000060) ~= 0 and not ignoredEnemyNpcsTable [npcid1]) then --� um inimigo
			total = total + player [keyName]
		else
			amount = index-1
			break
		end
	end

	return amount, total
end

function Details:TooltipForCustom (barra) --[[exported]]
	GameCooltip:AddLine(Loc ["STRING_LEFT_CLICK_SHARE"])
	return true
end

--[[ Void Zone Sort]]
local void_zone_sort = function(t1, t2)
	if (t1.damage == t2.damage) then
		return t1.nome <= t2.nome
	else
		return t1.damage > t2.damage
	end
end


function Details.Sort1(table1, table2) --[[exported]]
	return table1[1] > table2[1]
end

function Details.Sort2(table1, table2) --[[exported]]
	return table1[2] > table2[2]
end

function Details.Sort3(table1, table2) --[[exported]]
	return table1[3] > table2[3]
end

function Details.Sort4(table1, table2) --[[exported]]
	return table1[4] > table2[4]
end

function Details.Sort4Reverse(table1, table2) --[[exported]]
	if (not table2) then
		return true
	end
	return table1[4] < table2[4]
end

function Details:GetTextColor(instanceObject, textSide)
	local actorObject = self
	textSide = textSide or "left"

	local bUseClassColor = false
	if (textSide == "left") then
		bUseClassColor = instanceObject.row_info.textL_class_colors
	elseif (textSide == "right") then
		bUseClassColor = instanceObject.row_info.textR_class_colors
	end

	if (bUseClassColor) then
		local actorClass = actorObject.classe or "UNKNOW"
		if (actorClass == "UNKNOW") then
			return unpack(instanceObject.row_info.fixed_text_color)
		else
			return unpack(Details.class_colors[actorClass])
		end
	else
		return unpack(instanceObject.row_info.fixed_text_color)
	end
end

function Details:GetBarColor(actor) --[[exported]]
	actor = actor or self

	if (actor.monster) then
		return unpack(Details.class_colors.ENEMY)

	elseif (actor.customColor) then
		return unpack(actor.customColor)

	elseif (actor.spellicon) then
		return 0.729, 0.917, 1

	elseif (actor.owner) then
		return unpack(Details.class_colors[actor.owner.classe or "UNKNOW"])

	elseif (actor.arena_team and Details.color_by_arena_team) then
		if (actor.arena_team == 0) then
			return unpack(Details.class_colors.ARENA_GREEN)
		else
			return unpack(Details.class_colors.ARENA_YELLOW)
		end

	else
		if (not is_player_class[actor.classe] and actor.flag_original and bitBand(actor.flag_original, 0x00000020) ~= 0) then --neutral
			return unpack(Details.class_colors.NEUTRAL)

		elseif (actor.color) then
			return unpack(actor.color)

		else
			return unpack(Details.class_colors[actor.classe or "UNKNOW"])
		end
	end
end

function Details:GetSpellLink(spellid) --[[exported]]
	if (type(spellid) ~= "number") then
		return spellid
	end

	if (spellid == 1) then --melee
		return GetSpellLink(6603)

	elseif (spellid == 2) then --autoshot
		return GetSpellLink(75)

	elseif (spellid > 10) then
		return GetSpellLink(spellid)
	else
		local spellname = _GetSpellInfo(spellid)
		return spellname
	end
end

function Details:GameTooltipSetSpellByID(spellId) --[[exported]]
	if (spellId == 1) then
		GameTooltip:SetSpellByID(6603)

	elseif (spellId == 2) then
		GameTooltip:SetSpellByID(75)

	elseif (spellId > 10) then
		GameTooltip:SetSpellByID(spellId)

	else
		GameTooltip:SetSpellByID(spellId)
	end
end

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--class ~constructor

	---create a new actorObject and set the metatable to the actor prototype
	---this function is called from within an actorContainer when it needs to create a new actorObject for a new actor
	---actorObject is a ordinary table with the actor attributes and a metatable to inherit the functions from Details object
	---@return table
	function damageClass:NovaTabela() --create new actorObject
		local alphabetical = Details:GetOrderNumber()

		--constructor: creates a table with the actor attributes and then set the metatable to the actor prototype
		local newDamageActor = {
			--type of the actor
			tipo = class_type,

			--total: amount of damage done
			total = alphabetical,
			total_extra = 0,
			--totalabsorbed: amount of damage done absorbed by shields
			totalabsorbed = alphabetical,
			--total_without_pet: amount of damage done without pet damage
			total_without_pet = alphabetical,
			--custom: used by custom scripts, works more like a cache
			custom = 0,

			--damage_taken: amount of damage the actor took during the combat
			damage_taken = alphabetical,
			--damage_from: table with actor names as keys and boolean true as value
			damage_from = {},

			--dps_started: is false until this actor does damage
			dps_started = false,
			--last_event: the time when the actor as last edited by a damage effect: suffered damage, did damage
			last_event = 0,
			--on_hold: if the actor is idle, doing nothing during combat, on_hold is true
			on_hold = false,
			--delay: the time when the actor went idle
			delay = 0,
			--caches
			last_value = nil,
			last_dps = 0, --cache of the latest dps value calculated for this actor
			last_dps_realtime = 0, --cache of the latest real time dps value calculated for this actor
			--start_time: the time when the actor started to do damage
			start_time = 0,
			--end_time: the time when the actor stopped to do damage
			end_time = nil,

			--table indexed with pet names
			pets = {},
			--table where key is the raid target flags and the value is the damage done to that target
			raid_targets = {},

			--friendlyfire_total: amount of damage done to friendly players
			friendlyfire_total = 0,
			--friendlyfire: table where key is a player name and value is a table with .total: damage inflicted and .spells a table with spell names as keys and damage done as value
			friendlyfire = {},

			--targets: table where key is the target name (actor name) and the value is the amount of damage done to that target
			targets = {},
			--spells: spell container
			spells = spellContainerClass:NovoContainer(container_damage)
		}

		setmetatable(newDamageActor, damageClass)
		detailsFramework:Mixin(newDamageActor, Details222.Mixins.ActorMixin)
		detailsFramework:Mixin(newDamageActor, damageClassMixin)

		return newDamageActor
	end


-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--special cases

	---calculate real time dps for each actor within the passed table
	---@param tableWithActors actor[]
	---@return number
	function damageClass:RefreshDpsRealTime(tableWithActors)
		local totalRealTime = 0
		local timeSample = Details222.CurrentDPS.GetTimeSample()

		for _, actorObject in ipairs(tableWithActors) do
			---@cast actorObject actordamage
			---@type details_currentdps_actorcache
			local realTimeDPS = Details222.CurrentDPS.Cache[actorObject.serial]
			if (realTimeDPS) then
				realTimeDPS = realTimeDPS.totalDamage / timeSample
				actorObject.last_dps_realtime = realTimeDPS
				totalRealTime = totalRealTime + realTimeDPS
			end
		end

		return totalRealTime
	end

	--dps (calculate dps for actors)
	---@param tableWithActors table
	---@param combatTime combattime
	---@return number, number
	function damageClass:ContainerRefreshDps(tableWithActors, combatTime)
		local total = 0
		local totalRealTime = 0

		local bIsEffectiveTime = Details.time_type == 2
		local bOrderDpsByRealTime = Details.CurrentDps.CanSortByRealTimeDps()
		local timeSample = Details222.CurrentDPS.GetTimeSample()

		if (bIsEffectiveTime or not Details:CaptureGet("damage")) then
			for _, actorObject in ipairs(tableWithActors) do
				---@cast actorObject actordamage
				if (actorObject.grupo) then
					actorObject.last_dps = actorObject.total / combatTime
				else
					actorObject.last_dps = actorObject.total / actorObject:Tempo()
				end

				if (bOrderDpsByRealTime) then
					---@type details_currentdps_actorcache
					local realTimeDPS = Details222.CurrentDPS.Cache[actorObject.serial]
					if (realTimeDPS) then
						realTimeDPS = realTimeDPS.totalDamage / timeSample
						actorObject.last_dps_realtime = realTimeDPS
						totalRealTime = totalRealTime + realTimeDPS
					end
				end

				total = total + actorObject.last_dps
			end
		else
			for _, actorObject in ipairs(tableWithActors) do
				actorObject.last_dps = actorObject.total / actorObject:Tempo()
				total = total + actorObject.last_dps

				if (bOrderDpsByRealTime) then
					local realTimeDPS = Details222.CurrentDPS.Cache[actorObject.serial] or 0
					actorObject.last_dps_realtime = realTimeDPS
					totalRealTime = totalRealTime + realTimeDPS
				end
			end
		end

		return total, totalRealTime
	end

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--damage taken by spell

	local byspell_tooltip_background = {value = 100, color = {0.1960, 0.1960, 0.1960, 0.9097}, texture = [[Interface\AddOns\Details\images\bar_background_dark]]}

	function Details:ToolTipBySpell (instance, tabela, thisLine, keydown)

		local GameCooltip = GameCooltip
		local combat = instance.showing
		local from_spell = tabela [1] --spellid
		local from_spellname
		if (from_spell) then
			from_spellname = select(1, GetSpellInfo(from_spell))
		end

		--get a list of all damage actors
		local AllDamageCharacters = combat:GetActorList (DETAILS_ATTRIBUTE_DAMAGE)

		--hold the targets
		local Targets = {}
		local total = 0
		local top = 0

		local is_custom_spell = false
		for _, spellcustom in ipairs(Details.savedCustomSpells) do
			if (spellcustom[1] == from_spell) then
				is_custom_spell = true
			end
		end

		for index, character in ipairs(AllDamageCharacters) do

			if (is_custom_spell) then
				for playername, ff_table in pairs(character.friendlyfire) do
					if (ff_table.spells [from_spell]) then
						local damage_actor = combat (1, playername)
						local heal_actor = combat (2, playername)

						if ((damage_actor or heal_actor) and ( (damage_actor and damage_actor:IsPlayer()) or (heal_actor and heal_actor:IsPlayer()))) then

							local got

							for index, t in ipairs(Targets) do
								if (t[1] == playername) then
									t[2] = t[2] + ff_table.spells [from_spell]
									total = total + ff_table.spells [from_spell]
									if (t[2] > top) then
										top = t[2]
									end
									got = true
									break
								end
							end

							if (not got) then
								Targets [#Targets+1] = {playername, ff_table.spells [from_spell]}
								total = total + ff_table.spells [from_spell]
								if (ff_table.spells [from_spell] > top) then
									top = ff_table.spells [from_spell]
								end
							end
						end
					end
				end
			else
				for playername, ff_table in pairs(character.friendlyfire) do
					for spellid, amount in pairs(ff_table.spells) do
						local spellname = select(1, GetSpellInfo(spellid))
						if (spellname == from_spellname) then
							local damage_actor = combat (1, playername)
							local heal_actor = combat (2, playername)
							if ((damage_actor or heal_actor) and ( (damage_actor and damage_actor:IsPlayer()) or (heal_actor and heal_actor:IsPlayer()))) then
								local got
								for index, t in ipairs(Targets) do
									if (t[1] == playername) then
										t[2] = t[2] + amount
										total = total + amount
										if (t[2] > top) then
											top = t[2]
										end
										got = true
										break
									end
								end

								if (not got) then
									Targets [#Targets+1] = {playername, amount}
									total = total + amount
									if (amount > top) then
										top = amount
									end
								end
							end
						end
					end
				end
			end

			--search actors which used the spell shown in the bar
			local spell = character.spells._ActorTable [from_spell]

			if (spell) then
				for targetname, amount in pairs(spell.targets) do

					local got = false
					local damage_actor = combat (1, targetname)
					local heal_actor = combat (2, targetname)

					if ( (damage_actor or heal_actor) and ( (damage_actor and damage_actor:IsPlayer()) or (heal_actor and heal_actor:IsPlayer()) ) ) then
						for index, t in ipairs(Targets) do
							if (t[1] == targetname) then
								t[2] = t[2] + amount
								total = total + amount
								if (t[2] > top) then
									top = t[2]
								end
								got = true
								break
							end
						end

						if (not got) then
							Targets [#Targets+1] = {targetname, amount}
							total = total + amount
							if (amount > top) then
								top = amount
							end
						end
					end
				end
			end

			if (not is_custom_spell) then
				for spellid, spell in pairs(character.spells._ActorTable) do
					if (spellid ~= from_spell) then
						local spellname = select(1, GetSpellInfo(spellid))
						if (spellname == from_spellname) then
							for targetname, amount in pairs(spell.targets) do

								local got = false
								local damage_actor = combat (1, targetname)
								local heal_actor = combat (2, targetname)

								if ( (damage_actor or heal_actor) and ( (damage_actor and damage_actor:IsPlayer()) or (heal_actor and heal_actor:IsPlayer()) ) ) then
									for index, t in ipairs(Targets) do
										if (t[1] == targetname) then
											t[2] = t[2] + amount
											total = total + amount
											if (t[2] > top) then
												top = t[2]
											end
											got = true
											break
										end
									end

									if (not got) then
										Targets [#Targets+1] = {targetname, amount}
										total = total + amount
										if (amount > top) then
											top = amount
										end
									end
								end
							end
						end
					end
				end
			end
		end

		table.sort (Targets, Details.Sort2)
		bs_tooltip_table = Targets
		bs_tooltip_table.damage_total = total

		--Details:FormatCooltipForSpells()
		GameCooltip:SetOption("StatusBarTexture", "Interface\\AddOns\\Details\\images\\bar_serenity")

		local spellname, _, spellicon = select(1, _GetSpellInfo(from_spell))
		--GameCooltip:AddLine(spellname .. " " .. Loc ["STRING_CUSTOM_ATTRIBUTE_DAMAGE"], nil, nil, headerColor, nil, 10)
		--GameCooltip:AddIcon (spellicon, 1, 1, 14, 14, 0.078125, 0.921875, 0.078125, 0.921875)
		--GameCooltip:AddIcon ([[Interface\AddOns\Details\images\key_shift]], 1, 2, Details.tooltip_key_size_width, Details.tooltip_key_size_height, 0, 1, 0, 0.640625, Details.tooltip_key_overlay2)
		--Details:AddTooltipHeaderStatusbar (1, 1, 1, 0.5)

		local top = Targets[1] and Targets[1][2]

		local iconSize = Details.DefaultTooltipIconSize
		GameCooltip:SetOption("AlignAsBlizzTooltip", false)
		GameCooltip:SetOption("AlignAsBlizzTooltipFrameHeightOffset", -6)
		GameCooltip:SetOption("YSpacingMod", -6)
		Details:AddRoundedCornerToTooltip()

		for index, t in ipairs(Targets) do
			GameCooltip:AddLine(Details:GetOnlyName(t[1]), Details:ToK(t[2]) .. " (" .. format("%.1f", t[2]/total*100) .. "%)")
			local class, _, _, _, _, r, g, b = Details:GetClass(t[1])

			GameCooltip:AddStatusBar (t[2]/top*100, 1, r, g, b, 0.8, false,  byspell_tooltip_background)

			if (class) then
				local specID = Details:GetSpec(t[1])
				if (specID) then
					local texture, l, r, t, b = Details:GetSpecIcon (specID, false)
					GameCooltip:AddIcon (texture, 1, 1, iconSize, iconSize, l, r, t, b)
				else
					local texture, l, r, t, b = Details:GetClassIcon(class)
					GameCooltip:AddIcon ("Interface\\AddOns\\Details\\images\\classes_small_alpha", 1, 1,iconSize,iconSize, l, r, t, b)
				end

			elseif (t[1] == Loc ["STRING_TARGETS_OTHER1"]) then
				GameCooltip:AddIcon ("Interface\\AddOns\\Details\\images\\classes_small_alpha", 1, 1,iconSize,iconSize, 0.25, 0.49609375, 0.75, 1)
			end
		end

		GameCooltip:AddLine(" ")
		Details:AddTooltipReportLineText()

		GameCooltip:SetOwner(thisLine)
		GameCooltip:Show()
	end

	local function RefreshBarraBySpell (tabela, barra, instancia)
		damageClass:AtualizarBySpell (tabela, tabela.minha_barra, barra.colocacao, instancia)
	end

	local on_switch_DTBS_show = function(instance)
		instance:TrocaTabela(instance, true, 1, 8)
		return true
	end

	local DTBS_search_code = [[
		---@type combat, table, instance
		local combatObject, instanceContainer, instanceObject = ...

		--declade the values to return
		local totalDamage, topDamage, amount = 0, 0, 0

		---@type {key1: actorname, key2: number, key3: actor}[]
		local damageTakenFrom = {}

		local spellId = @SPELLID@
		local spellName
		if (spellId) then
			spellName = select(1, GetSpellInfo(spellId))
		end

		---@type actorcontainer
		local damageContainer = combatObject:GetContainer(DETAILS_ATTRIBUTE_DAMAGE)
		---@type actorcontainer
		local healContainer = combatObject:GetContainer(DETAILS_ATTRIBUTE_HEAL)

		local bIsCustomSpell = false
		for _, customSpellObject in ipairs(Details.savedCustomSpells) do
			if (customSpellObject[1] == spellId) then
				bIsCustomSpell = true
			end
		end

		for index, actorObject in damageContainer:ListActors() do
			---@cast actorObject actordamage

			--> handle friendly fire spell damage taken
			if (actorObject:IsPlayer()) then
				if (bIsCustomSpell) then --if the spell has been modified, check only by its spellId, as it can't get other spells with the same name
					for playerName, friendlyFireTable in pairs(actorObject.friendlyfire) do
						---@cast friendlyFireTable friendlyfiretable
						if (friendlyFireTable.spells[spellId]) then
							---@type actordamage
							local damageActor = damageContainer:GetActor(playerName)
							---@type actorheal
							local healingActor = healContainer:GetActor(playerName)

							if ((damageActor and damageActor:IsPlayer()) or (healingActor and healingActor:IsPlayer())) then
								local got

								for index, damageTakenTable in ipairs(damageTakenFrom) do
									if (damageTakenTable[1] == playerName) then
										damageTakenTable[2] = damageTakenTable[2] + friendlyFireTable.spells[spellId]
										if (damageTakenTable[2] > topDamage) then
											topDamage = damageTakenTable[2]
										end
										got = true
										break
									end
								end

								if (not got) then
									---@type {key1: actorname, key2: number, key3: actor}
									local damageTakenTable = {playerName, friendlyFireTable.spells[spellId], damageActor or healingActor}
									damageTakenFrom[#damageTakenFrom+1] = damageTakenTable
									if (friendlyFireTable.spells[spellId] > topDamage) then
										topDamage = friendlyFireTable.spells[spellId]
									end
								end
							end
						end
					end
				else
					for playerName, friendlyFireTable in pairs(actorObject.friendlyfire) do
						---@cast friendlyFireTable friendlyfiretable
						for ffSpellId, damageAmount in pairs(friendlyFireTable.spells) do
							local ffSpellName = select(1, GetSpellInfo(ffSpellId))
							if (ffSpellName == spellName) then
								---@type actordamage
								local damageActor = damageContainer:GetActor(playerName)
								---@type actorheal
								local healingActor = healContainer:GetActor(playerName)

								if ((damageActor and damageActor:IsPlayer()) or (healingActor and healingActor:IsPlayer())) then
									local got
									for index, damageTakenTable in ipairs(damageTakenFrom) do
										if (damageTakenTable[1] == playerName) then
											damageTakenTable[2] = damageTakenTable[2] + damageAmount
											if (damageTakenTable[2] > topDamage) then
												topDamage = damageTakenTable[2]
											end
											got = true
											break
										end
									end

									if (not got) then
										---@type {key1: actorname, key2: number, key3: actor}
										local damageTakenTable = {playerName, damageAmount, damageActor or healingActor}
										damageTakenFrom[#damageTakenFrom+1] = damageTakenTable
										if (damageAmount > topDamage) then
											topDamage = damageAmount
										end
									end
								end
							end
						end
					end
				end
			end

			--> handle regular damage taken from spells
			---@type spelltable
			local spellTable = actorObject:GetSpell(spellId)

			if (spellTable) then
				for targetName, damageAmount in pairs(spellTable.targets) do
					local got = false

					---@type actordamage
					local damageActor = damageContainer:GetActor(targetName)
					---@type actorheal
					local healingActor = healContainer:GetActor(targetName)

					if ((damageActor and damageActor:IsPlayer()) or (healingActor and healingActor:IsPlayer())) then
						for index, damageTakenTable in ipairs(damageTakenFrom) do
							if (damageTakenTable[1] == targetName) then
								damageTakenTable[2] = damageTakenTable[2] + damageAmount
								if (damageTakenTable[2] > topDamage) then
									topDamage = damageTakenTable[2]
								end
								got = true
								break
							end
						end

						if (not got) then
							---@type {key1: actorname, key2: number, key3: actor}
							local damageTakenTable = {targetName, damageAmount, damageActor or healingActor}
							damageTakenFrom[#damageTakenFrom+1] = damageTakenTable
							if (damageAmount > topDamage) then
								topDamage = damageAmount
							end
						end
					end
				end
			end

			if (not bIsCustomSpell) then
				for thisSpellId, spellTable in pairs(actorObject.spells._ActorTable) do
					if (thisSpellId ~= spellId) then --this is invalid
						local spellname = select(1, GetSpellInfo(thisSpellId))
						if (spellname == spellName) then
							for targetName, damageAmount in pairs(spellTable.targets) do
								local got = false

								---@type actordamage
								local damageActor = damageContainer:GetActor(targetName)
								---@type actorheal
								local healingActor = healContainer:GetActor(targetName)

								if ((damageActor and damageActor:IsPlayer()) or (healingActor and healingActor:IsPlayer())) then
									for index, damageTakenTable in ipairs(damageTakenFrom) do
										if (damageTakenTable[1] == targetName) then
											damageTakenTable[2] = damageTakenTable[2] + damageAmount
											if (damageTakenTable[2] > topDamage) then
												topDamage = damageTakenTable[2]
											end
											got = true
											break
										end
									end

									if (not got) then
										---@type {key1: actorname, key2: number, key3: actor}
										local damageTakenTable = {targetName, damageAmount, damageActor or healingActor}
										damageTakenFrom[#damageTakenFrom+1] = damageTakenTable
										if (damageAmount > topDamage) then
											topDamage = damageAmount
										end
									end
								end
							end
						end
					end
				end
			end
		end

		table.sort(damageTakenFrom, Details.Sort2)

		for index, damageTakenTable in ipairs(damageTakenFrom) do
			instanceContainer:AddValue(damageTakenTable[3], damageTakenTable[2]) --actorObject, amountDamage
			totalDamage = totalDamage + damageTakenTable[2] --amountDamage
			amount = amount + 1
		end

		return totalDamage, topDamage, amount
	]]

	local function ShowDTBSInWindow (spell, instance) --for hold shift key and click, show players which took damage from this spell
		local spellname, _, icon = _GetSpellInfo(spell [1])
		local custom_name = spellname .. " - " .. Loc ["STRING_CUSTOM_DTBS"] .. ""

		--check if already exists
		for index, CustomObject in ipairs(Details.custom) do
			if (CustomObject:GetName() == custom_name) then
				--fix for not saving funcs on logout
				if (not CustomObject.OnSwitchShow) then
					CustomObject.OnSwitchShow = on_switch_DTBS_show
				end
				return instance:TrocaTabela(instance.segmento, 5, index)
			end
		end

		--create a custom for this spell
		local new_custom_object = {
			name = custom_name,
			icon = icon,
			attribute = false,
			author = Details.playername,
			desc = spellname .. " " .. Loc ["STRING_CUSTOM_DTBS"],
			source = false,
			target = false,
			script = false,
			tooltip = false,
			temp = true,
			notooltip = true,
			OnSwitchShow = on_switch_DTBS_show,
		}

		local new_code = DTBS_search_code
		new_code = new_code:gsub("@SPELLID@", spell [1])
		new_custom_object.script = new_code

		tinsert(Details.custom, new_custom_object)
		setmetatable(new_custom_object, Details.atributo_custom)
		new_custom_object.__index = Details.atributo_custom

		return instance:TrocaTabela(instance.segmento, 5, #Details.custom)
	end

	local DTBS_format_name = function(player_name) return Details:GetOnlyName(player_name) end
	local DTBS_format_amount = function(amount) return Details:ToK(amount) .. " (" .. format("%.1f", amount / bs_tooltip_table.damage_total * 100) .. "%)" end

	function damageClass:ReportSingleDTBSLine (spell, instance, ShiftKeyDown, ControlKeyDown)
		if (ControlKeyDown) then
			local spellname, _, spellicon = _GetSpellInfo(spell[1])
			return Details:OpenAuraPanel (spell[1], spellname, spellicon)
		elseif (ShiftKeyDown) then
			return ShowDTBSInWindow (spell, instance)
		end

		local spelllink = Details:GetSpellLink(spell [1])
		local report_table = {"Details!: " .. Loc ["STRING_CUSTOM_DTBS"] .. " " .. spelllink}

		Details:FormatReportLines(report_table, bs_tooltip_table, DTBS_format_name, DTBS_format_amount)

		return Details:Reportar(report_table, {_no_current = true, _no_inverse = true, _custom = true})
	end

	function damageClass:AtualizarBySpell(tabela, whichRowLine, colocacao, instance)
		tabela ["byspell"] = true --marca que esta tabela � uma tabela de frags, usado no controla na hora de montar o tooltip
		local thisLine = instance.barras [whichRowLine] --pega a refer�ncia da barra na janela

		if (not thisLine) then
			print("DEBUG: problema com <instance.thisLine> "..whichRowLine .. " " .. colocacao)
			return
		end

		thisLine.minha_tabela = tabela

		local spellName, _, spellIcon = _GetSpellInfo(tabela[1])

		tabela.nome = spellName --evita dar erro ao redimencionar a janela
		tabela.minha_barra = whichRowLine
		thisLine.colocacao = colocacao

		if (not _getmetatable (tabela)) then
			setmetatable(tabela, {__call = RefreshBarraBySpell})
			tabela._custom = true
		end

		local total = instance.showing.totals.by_spell
		local porcentagem

		if (instance.row_info.percent_type == 1) then
			porcentagem = format("%.1f", tabela [2] / total * 100)

		elseif (instance.row_info.percent_type == 2) then
			porcentagem = format("%.1f", tabela [2] / instance.top * 100)
		end

		thisLine.lineText1:SetText(colocacao .. ". " .. spellName)

		local bars_show_data = instance.row_info.textR_show_data

		local spell_damage = tabela[2] -- spell_damage passar por uma ToK function, precisa ser number
		if (not bars_show_data [1]) then
			spell_damage = tabela[2] --damage taken by spell n�o tem PS, ent�o � obrigado a passar o dano total
		end

		if (not bars_show_data[3]) then
			porcentagem = ""
		else
			porcentagem = porcentagem .. "%"
		end

		local bars_brackets = instance:GetBarBracket()

		if (instance.use_multi_fontstrings) then
			instance:SetInLineTexts(thisLine, "", (spell_damage and SelectedToKFunction(_, spell_damage) or ""), porcentagem)
		else
			thisLine.lineText4:SetText((spell_damage and SelectedToKFunction(_, spell_damage) or "") .. bars_brackets[1] .. porcentagem .. bars_brackets[2])
		end

		thisLine.lineText1:SetTextColor(1, 1, 1, 1)
		thisLine.lineText2:SetTextColor(1, 1, 1, 1)
		thisLine.lineText3:SetTextColor(1, 1, 1, 1)
		thisLine.lineText4:SetTextColor(1, 1, 1, 1)

		thisLine.lineText1:SetSize(thisLine:GetWidth() - thisLine.lineText4:GetStringWidth() - 20, 15)

		if (colocacao == 1) then
			thisLine:SetValue(100)
		else
			thisLine:SetValue(tabela[2] / instance.top * 100)
		end

		if (thisLine.hidden or thisLine.fading_in or thisLine.faded) then
			Details.FadeHandler.Fader(thisLine, "out")
		end

		if (instance.row_info.texture_class_colors) then
			if (tabela [3] > 1) then
				local r, g, b = Details:GetSpellSchoolColor(tabela[3])
				thisLine.textura:SetVertexColor(r, g, b)
			else
				local r, g, b = Details:GetSpellSchoolColor(0)
				thisLine.textura:SetVertexColor(r, g, b)
			end
		end

		thisLine.icone_classe:SetTexture(spellIcon)
		thisLine.icone_classe:SetTexCoord(0.078125, 0.921875, 0.078125, 0.921875)
		thisLine.icone_classe:SetVertexColor(1, 1, 1)
		if(thisLine.mouse_over and not instance.baseframe.isMoving) then
			local classIcon = thisLine:GetClassIcon()
			thisLine.iconHighlight:SetTexture(classIcon:GetTexture())
			thisLine.iconHighlight:SetTexCoord(classIcon:GetTexCoord())
			thisLine.iconHighlight:SetVertexColor(classIcon:GetVertexColor())
		end

	end

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--frags

	function Details:ToolTipFrags (instancia, frag, thisLine, keydown)

		local name = frag [1]
		local GameCooltip = GameCooltip

		--mantendo a fun��o o mais low level poss�vel
		local damage_container = instancia.showing [1]

		local frag_actor = damage_container._ActorTable [damage_container._NameIndexTable [ name ]]

		if (frag_actor) then

			local damage_taken_table = {}

			local took_damage_from = frag_actor.damage_from
			local total_damage_taken = frag_actor.damage_taken
			local total = 0

			for aggressor, _ in pairs(took_damage_from) do

				local damager_actor = damage_container._ActorTable [damage_container._NameIndexTable [ aggressor ]]

				if (damager_actor and not damager_actor.owner) then --checagem por causa do total e do garbage collector que n�o limpa os names que deram dano
					local target_amount = damager_actor.targets [name]
					if (target_amount) then
						damage_taken_table [#damage_taken_table+1] = {aggressor, target_amount, damager_actor.classe}
						total = total + target_amount
					end
				end
			end

			_table_sort(damage_taken_table, Details.Sort2)

			local iconSize = Details.DefaultTooltipIconSize
			GameCooltip:SetOption("AlignAsBlizzTooltip", false)
			GameCooltip:SetOption("AlignAsBlizzTooltipFrameHeightOffset", -6)
			GameCooltip:SetOption("YSpacingMod", -6)
			Details:AddRoundedCornerToTooltip()

			--Details:AddTooltipSpellHeaderText (Loc ["STRING_DAMAGE_FROM"], headerColor, #damage_taken_table, [[Interface\Addons\Details\images\icons]], 0.126953125, 0.1796875, 0, 0.0546875)
			--Details:AddTooltipHeaderStatusbar (1, 1, 1, 0.5)
			--GameCooltip:AddIcon ([[Interface\AddOns\Details\images\key_shift]], 1, 2, Details.tooltip_key_size_width, Details.tooltip_key_size_height, 0, 1, 0, 0.640625, Details.tooltip_key_overlay2)

			local min = 6
			local ismaximized = false
			--always maximized
			if (true or keydown == "shift" or TooltipMaximizedMethod == 2 or TooltipMaximizedMethod == 3) then
				min = 99
				ismaximized = true
			end

			if (ismaximized) then
				--GameCooltip:AddIcon ([[Interface\AddOns\Details\images\key_shift]], 1, 2, Details.tooltip_key_size_width, Details.tooltip_key_size_height, 0, 1, 0, 0.640625, Details.tooltip_key_overlay2)
			else
				--GameCooltip:AddIcon ([[Interface\AddOns\Details\images\key_shift]], 1, 2, Details.tooltip_key_size_width, Details.tooltip_key_size_height, 0, 1, 0, 0.640625, Details.tooltip_key_overlay1)
			end

			local top = damage_taken_table[1] and damage_taken_table[1][2]
			frags_tooltip_table = damage_taken_table
			frags_tooltip_table.damage_total = total

			local lineHeight = Details.tooltip.line_height

			if (#damage_taken_table > 0) then
				for i = 1, math.min (min, #damage_taken_table) do
					local t = damage_taken_table [i]

					GameCooltip:AddLine(Details:GetOnlyName(t[1]), FormatTooltipNumber (_, t[2]) .. " (" .. format("%.1f", t[2] / total * 100) .. "%)")
					local classe = t[3]
					if (not classe) then
						classe = "UNKNOW"
					end

					if (classe == "UNKNOW") then
						GameCooltip:AddIcon ("Interface\\LFGFRAME\\LFGROLE_BW", nil, nil, iconSize, iconSize, .25, .5, 0, 1)
					else

						local specID = Details:GetSpec(t[1])
						if (specID) then
							local texture, l, r, t, b = Details:GetSpecIcon (specID, false)
							GameCooltip:AddIcon (texture, 1, 1, iconSize, iconSize, l, r, t, b)
						else
							GameCooltip:AddIcon ([[Interface\AddOns\Details\images\classes_small_alpha]], nil, nil, iconSize, iconSize, unpack(Details.class_coords [classe]))
						end
					end

					local _, _, _, _, _, r, g, b = Details:GetClass(t[1])
					GameCooltip:AddStatusBar (t[2] / top * 100, 1, r, g, b, 1, false, enemies_background)
				end
			else
				GameCooltip:AddLine(Loc ["STRING_NO_DATA"], nil, 1, "white")
				GameCooltip:AddIcon (instancia.row_info.icon_file, nil, nil, 14, 14, unpack(Details.class_coords ["UNKNOW"]))
			end

			GameCooltip:AddLine(" ")
			Details:AddTooltipReportLineText()

			GameCooltip:SetOption("StatusBarTexture", "Interface\\AddOns\\Details\\images\\bar_serenity")
			GameCooltip:ShowCooltip()
		end
	end

	local function RefreshBarraFrags (tabela, barra, instancia)
		damageClass:AtualizarFrags(tabela, tabela.minha_barra, barra.colocacao, instancia)
	end

	function damageClass:AtualizarFrags(tabela, whichRowLine, colocacao, instancia)

		tabela ["frags"] = true --marca que esta tabela � uma tabela de frags, usado no controla na hora de montar o tooltip
		local thisLine = instancia.barras [whichRowLine] --pega a refer�ncia da barra na janela

		if (not thisLine) then
			print("DEBUG: problema com <instancia.thisLine> "..whichRowLine.." "..rank)
			return
		end

		local previousData = thisLine.minha_tabela

		thisLine.minha_tabela = tabela

		tabela.nome = tabela [1] --evita dar erro ao redimencionar a janela
		tabela.minha_barra = whichRowLine
		thisLine.colocacao = colocacao

		if (not _getmetatable (tabela)) then
			setmetatable(tabela, {__call = RefreshBarraFrags})
			tabela._custom = true
		end

		local total = instancia.showing.totals.frags_total
		local porcentagem

		if (instancia.row_info.percent_type == 1) then
			porcentagem = format("%.1f", tabela [2] / total * 100)
		elseif (instancia.row_info.percent_type == 2) then
			porcentagem = format("%.1f", tabela [2] / instancia.top * 100)
		end

		thisLine.lineText1:SetText(colocacao .. ". " .. tabela [1])

		local bars_show_data = instancia.row_info.textR_show_data
		local bars_brackets = instancia:GetBarBracket()

		local total_frags = tabela [2]
		if (not bars_show_data [1]) then
			total_frags = ""
		end
		if (not bars_show_data [3]) then
			porcentagem = ""
		else
			porcentagem = porcentagem .. "%"
		end

		--
		if (instancia.use_multi_fontstrings) then
			instancia:SetInLineTexts(thisLine, "", total_frags, porcentagem)
		else
			thisLine.lineText4:SetText(total_frags .. bars_brackets[1] .. porcentagem .. bars_brackets[2])
		end

		thisLine.lineText1:SetSize(thisLine:GetWidth() - thisLine.lineText4:GetStringWidth() - 20, 15)

		if (colocacao == 1) then
			thisLine:SetValue(100)
		else
			thisLine:SetValue(tabela [2] / instancia.top * 100)
		end

		thisLine.lineText1:SetTextColor(1, 1, 1, 1)
		thisLine.lineText4:SetTextColor(1, 1, 1, 1)

		if (thisLine.hidden or thisLine.fading_in or thisLine.faded) then
			Details.FadeHandler.Fader(thisLine, "out")
		end

		Details:SetBarColors(thisLine, instancia, unpack(Details.class_colors [tabela [3]]))

		if (tabela [3] == "UNKNOW" or tabela [3] == "UNGROUPPLAYER" or tabela [3] == "ENEMY") then
			thisLine.icone_classe:SetTexture([[Interface\AddOns\Details\images\classes_plus]])
			thisLine.icone_classe:SetTexCoord(0.50390625, 0.62890625, 0, 0.125)
			thisLine.icone_classe:SetVertexColor(1, 1, 1)
		else
			thisLine.icone_classe:SetTexture(instancia.row_info.icon_file)
			thisLine.icone_classe:SetTexCoord(unpack(Details.class_coords [tabela [3]]))
			thisLine.icone_classe:SetVertexColor(1, 1, 1)
		end

		if (thisLine.mouse_over and not instancia.baseframe.isMoving) then --precisa atualizar o tooltip
			--gump:UpdateTooltip(whichRowLine, thisLine, instancia)if(thisLine.mouse_over and not instancia.baseframe.isMoving) then
			local classIcon = thisLine:GetClassIcon()
			thisLine.iconHighlight:SetTexture(classIcon:GetTexture())
			thisLine.iconHighlight:SetTexCoord(classIcon:GetTexCoord())
			thisLine.iconHighlight:SetVertexColor(classIcon:GetVertexColor())
		end

	end

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--void zones
	local on_switch_AVZ_show = function(instance)
		instance:TrocaTabela(instance, true, 1, 7)
		return true
	end

	local AVZ_search_code = [[
		--get the parameters passed
		local combat, instance_container, instance = ...
		--declade the values to return
		local total, top, amount = 0, 0, 0

		local actor_name = "@ACTORNAME@"
		local actor = combat (4, actor_name)

		if (not actor) then
			return 0, 0, 0
		end

		local damage_actor = combat (1, actor.damage_twin)

		local habilidade
		local alvos

		if (damage_actor) then
			habilidade = damage_actor.spells._ActorTable [actor.damage_spellid]
		end
		if (habilidade) then
			alvos = habilidade.targets
		end

		local container = actor.debuff_uptime_targets
		local tooltip_void_zone_temp = {}

		for target_name, debuff_table in pairs(container) do
			if (alvos) then
				local damage_alvo = alvos [target_name]
				if (damage_alvo) then
					debuff_table.damage = damage_alvo
				else
					debuff_table.damage = 0
				end
			else
				debuff_table.damage = 0
			end
		end

		local i = 1
		for target_name, debuff_table in pairs(container) do
			local t = tooltip_void_zone_temp [i]
			if (not t) then
				t = {}
				tinsert(tooltip_void_zone_temp, t)
			end

			local target_actor = combat (1, target_name) or combat (2, target_name) or combat (4, target_name)
			t[1] = target_name
			t[2] = debuff_table.damage
			t[3] = debuff_table
			t[4] = target_actor

			i = i + 1
		end

		--sort no container:
		table.sort (tooltip_void_zone_temp, Details.sort_tooltip_void_zones)

		for index, t in ipairs(tooltip_void_zone_temp) do
			instance_container:AddValue (t[4], t[2])

			local custom_actor = instance_container:GetActorTable(t[4])
			custom_actor.uptime = t[3].uptime

			total = total + t[2]
			amount = amount + 1
			if (t[2] > top) then
				top = t[2]
			end
		end

		return total, top, amount
	]]

	local AVZ_total_code = [[
		local value, top, total, combat, instance, custom_actor = ...
		local uptime = custom_actor.uptime or 0

		local minutos, segundos = floor(uptime / 60), floor(uptime % 60)
		if (minutos > 0) then
			uptime = "" .. minutos .. "m " .. segundos .. "s" .. ""
		else
			uptime = "" .. segundos .. "s" .. ""
		end

		return Details:ToK2(value) .. " - " .. uptime .. " "
	]]

	local function ShowVoidZonesInWindow (actor, instance)

		local spellid = tooltip_void_zone_temp.spellid

		local spellname, _, icon = _GetSpellInfo(spellid)
		local custom_name = spellname .. " - " .. Loc ["STRING_ATTRIBUTE_DAMAGE_DEBUFFS_REPORT"] .. ""

		--check if already exists
		for index, CustomObject in ipairs(Details.custom) do
			if (CustomObject:GetName() == custom_name) then
				--fix for not saving funcs on logout
				if (not CustomObject.OnSwitchShow) then
					CustomObject.OnSwitchShow = on_switch_AVZ_show
				end
				return instance:TrocaTabela(instance.segmento, 5, index)
			end
		end

		--create a custom for this spell
		local new_custom_object = {
			name = custom_name,
			icon = icon,
			attribute = false,
			author = Details.playername,
			desc = spellname .. " " .. Loc ["STRING_ATTRIBUTE_DAMAGE_DEBUFFS_REPORT"],
			source = false,
			target = false,
			script = false,
			tooltip = false,
			temp = true,
			notooltip = true,
			OnSwitchShow = on_switch_AVZ_show,
		}

		local new_code = AVZ_search_code
		new_code = new_code:gsub("@ACTORNAME@", actor.nome)
		new_custom_object.script = new_code

		local new_total_code = AVZ_total_code
		new_total_code = new_total_code:gsub("@ACTORNAME@", actor.nome)
		new_total_code = new_total_code:gsub("@SPELLID@", spellid)
		new_custom_object.total_script = new_total_code

		tinsert(Details.custom, new_custom_object)
		setmetatable(new_custom_object, Details.atributo_custom)
		new_custom_object.__index = Details.atributo_custom

		return instance:TrocaTabela(instance.segmento, 5, #Details.custom)
	end

	function damageClass:ReportSingleVoidZoneLine (actor, instance, ShiftKeyDown, ControlKeyDown)

		local spellid = tooltip_void_zone_temp.spellid

		if (ControlKeyDown) then
			local spellname, _, spellicon = _GetSpellInfo(spellid)
			return Details:OpenAuraPanel (spellid, spellname, spellicon)
		elseif (ShiftKeyDown) then
			return ShowVoidZonesInWindow (actor, instance)
		end

		local spelllink = Details:GetSpellLink(spellid)
		local report_table = {"Details!: " .. spelllink .. " " .. Loc ["STRING_ATTRIBUTE_DAMAGE_DEBUFFS_REPORT"]}

		local t = {}
		for index, void_table in ipairs(tooltip_void_zone_temp) do
			--ir� reportar dano zero tamb�m
			if (void_table[1] and type(void_table[1]) == "string" and void_table[2] and void_table[3] and type(void_table[3]) == "table") then
				local actor_table = {Details:GetOnlyName(void_table[1])}
				local m, s = _math_floor(void_table[3].uptime / 60), _math_floor(void_table[3].uptime % 60)
				if (m > 0) then
					actor_table [2] = FormatTooltipNumber (_, void_table[3].damage) .. " (" .. m .. "m " .. s .. "s" .. ")"
				else
					actor_table [2] = FormatTooltipNumber (_, void_table[3].damage) .. " (" .. s .. "s" .. ")"
				end
				t [#t+1] = actor_table
			end
		end

		Details:FormatReportLines (report_table, t)

		return Details:Reportar (report_table, {_no_current = true, _no_inverse = true, _custom = true})
	end

	local sort_tooltip_void_zones = function(tabela1, tabela2)
		if (tabela1 [2] > tabela2 [2]) then
			return true
		elseif (tabela1 [2] == tabela2 [2]) then
			if (tabela1[1] ~= "" and tabela2[1] ~= "") then
				return tabela1 [3].uptime > tabela2 [3].uptime
			elseif (tabela1[1] ~= "") then
				return true
			elseif (tabela2[1] ~= "") then
				return false
			end
		else
			return false
		end
	end
	Details.sort_tooltip_void_zones = sort_tooltip_void_zones


	function Details:ToolTipVoidZones (instancia, actor, barra, keydown)

		local damage_actor = instancia.showing[1]:PegarCombatente (_, actor.damage_twin)
		local habilidade
		local alvos

		if (damage_actor) then
			habilidade = damage_actor.spells._ActorTable [actor.damage_spellid]
		end

		if (habilidade) then
			alvos = habilidade.targets
		end

		local container = actor.debuff_uptime_targets

		for target_name, debuff_table in pairs(container) do
			if (alvos) then
				local damage_alvo = alvos [target_name]
				if (damage_alvo) then
					debuff_table.damage = damage_alvo
				else
					debuff_table.damage = 0
				end
			else
				debuff_table.damage = 0
			end
		end

		for i = 1, #tooltip_void_zone_temp do
			local t = tooltip_void_zone_temp [i]
			t[1] = ""
			t[2] = 0
			t[3] = 0
		end

		local i = 1
		for target_name, debuff_table in pairs(container) do
			local t = tooltip_void_zone_temp [i]
			if (not t) then
				t = {}
				tinsert(tooltip_void_zone_temp, t)
			end

			t[1] = target_name
			t[2] = debuff_table.damage
			t[3] = debuff_table

			i = i + 1
		end

		--sort no container:
		_table_sort(tooltip_void_zone_temp, sort_tooltip_void_zones)

		--monta o cooltip
		local GameCooltip = GameCooltip

		local spellname, _, spellicon = _GetSpellInfo(actor.damage_spellid)
		--Details:AddTooltipSpellHeaderText (spellname .. " " .. Loc ["STRING_VOIDZONE_TOOLTIP"], headerColor, #tooltip_void_zone_temp, spellicon, 0.078125, 0.921875, 0.078125, 0.921875)
		--Details:AddTooltipHeaderStatusbar (1, 1, 1, 0.5)
		--GameCooltip:AddIcon ([[Interface\AddOns\Details\images\key_shift]], 1, 2, Details.tooltip_key_size_width, Details.tooltip_key_size_height, 0, 1, 0, 0.640625, Details.tooltip_key_overlay2)

		--for target_name, debuff_table in pairs(container) do
		local first = tooltip_void_zone_temp [1] and tooltip_void_zone_temp [1][3]
		if (type(first) == "table") then
			first = first.damage
		end

		tooltip_void_zone_temp.spellid = actor.damage_spellid
		tooltip_void_zone_temp.current_actor = actor

		local iconSize = Details.DefaultTooltipIconSize
		GameCooltip:SetOption("AlignAsBlizzTooltip", false)
		GameCooltip:SetOption("AlignAsBlizzTooltipFrameHeightOffset", -6)
		GameCooltip:SetOption("YSpacingMod", -6)
		Details:AddRoundedCornerToTooltip()

		--local lineHeight = Details.tooltip.line_height

		for index, t in ipairs(tooltip_void_zone_temp) do

			if (t[3] == 0) then
				break
			end

			local debuff_table = t[3]

			local minutos, segundos = _math_floor(debuff_table.uptime / 60), _math_floor(debuff_table.uptime % 60)
			if (minutos > 0) then
				GameCooltip:AddLine(Details:GetOnlyName(t[1]), FormatTooltipNumber (_, debuff_table.damage) .. " (" .. minutos .. "m " .. segundos .. "s" .. ")")
			else
				GameCooltip:AddLine(Details:GetOnlyName(t[1]), FormatTooltipNumber (_, debuff_table.damage) .. " (" .. segundos .. "s" .. ")")
			end

			local classe = Details:GetClass(t[1])
			if (classe) then
				local specID = Details:GetSpec(t[1])
				if (specID) then
					local texture, l, r, t, b = Details:GetSpecIcon (specID, false)
					GameCooltip:AddIcon (texture, 1, 1, iconSize, iconSize, l, r, t, b)
				else
					GameCooltip:AddIcon ([[Interface\AddOns\Details\images\classes_small_alpha]], nil, nil, iconSize, iconSize, unpack(Details.class_coords [classe]))
				end
			else
				GameCooltip:AddIcon ("Interface\\LFGFRAME\\LFGROLE_BW", nil, nil, iconSize, iconSize, .25, .5, 0, 1)
			end

			local _, _, _, _, _, r, g, b = Details:GetClass(t[1])
			if (first == 0) then
				first = 0.0000000001
			end
			GameCooltip:AddStatusBar (debuff_table.damage / first * 100, 1, r, g, b, 1, false, enemies_background)
			--Details:AddTooltipBackgroundStatusbar()

		end

		GameCooltip:AddLine(" ")
		Details:AddTooltipReportLineText()

		GameCooltip:SetOption("StatusBarTexture", "Interface\\AddOns\\Details\\images\\bar_serenity")

		GameCooltip:ShowCooltip()

	end

	local function RefreshBarraVoidZone (tabela, barra, instancia)
		tabela:AtualizarVoidZone (tabela.minha_barra, barra.colocacao, instancia)
	end

	function atributo_misc:AtualizarVoidZone (whichRowLine, colocacao, instancia)
		--pega a refer�ncia da barra na janela
		local thisLine = instancia.barras[whichRowLine]

		if (not thisLine) then
			print("DEBUG: problema com <instancia.thisLine> "..whichRowLine.." "..rank)
			return
		end

		self._refresh_window = RefreshBarraVoidZone

		local previousData = thisLine.minha_tabela

		thisLine.minha_tabela = self

		self.minha_barra = whichRowLine
		thisLine.colocacao = colocacao

		local total = instancia.showing.totals.voidzone_damage

		local combat_time = instancia.showing:GetCombatTime()
		local dps = _math_floor(self.damage / combat_time)

		local formated_damage = SelectedToKFunction(_, self.damage)
		local formated_dps = SelectedToKFunction(_, dps)

		local porcentagem

		if (instancia.row_info.percent_type == 1) then
			total = max(total, 0.0001)
			porcentagem = format("%.1f", self.damage / total * 100)

		elseif (instancia.row_info.percent_type == 2) then
			local top = max(instancia.top, 0.0001)
			porcentagem = format("%.1f", self.damage / top * 100)
		end

		local bars_show_data = instancia.row_info.textR_show_data
		local bars_brackets = instancia:GetBarBracket()
		local bars_separator = instancia:GetBarSeparator()

		if (not bars_show_data [1]) then
			formated_damage = ""
		end

		if (not bars_show_data [2]) then
			formated_dps = ""
		end

		if (not bars_show_data [3]) then
			porcentagem = ""
		else
			porcentagem = porcentagem .. "%"
		end

		local rightText = formated_damage .. bars_brackets[1] .. formated_dps .. bars_separator .. porcentagem .. bars_brackets[2]
		if (UsingCustomRightText) then
			thisLine.lineText4:SetText(stringReplace(instancia.row_info.textR_custom_text, formated_damage, formated_dps, porcentagem, self, instancia.showing, instancia, rightText))
		else
			if (instancia.use_multi_fontstrings) then
				instancia:SetInLineTexts(thisLine, formated_damage, formated_dps, porcentagem)
			else
				thisLine.lineText4:SetText(rightText)
			end
		end

		thisLine.lineText1:SetText(colocacao .. ". " .. self.nome)
		thisLine.lineText1:SetSize(thisLine:GetWidth() - thisLine.lineText4:GetStringWidth() - 20, 15)

		thisLine.lineText1:SetTextColor(1, 1, 1, 1)
		thisLine.lineText4:SetTextColor(1, 1, 1, 1)

		thisLine:SetValue(100)

		if (thisLine.hidden or thisLine.fading_in or thisLine.faded) then
			Details.FadeHandler.Fader(thisLine, "out")
		end

		local _, _, icon = GetSpellInfo(self.damage_spellid)
		local spellSchoolColor = Details.spells_school[self.spellschool] and Details.spells_school[self.spellschool].decimals
		if (not spellSchoolColor) then
			spellSchoolColor = Details.spells_school[1]
		end

		Details:SetBarColors(thisLine, instancia, unpack(spellSchoolColor))

		thisLine.icone_classe:SetTexture(icon)
		thisLine.icone_classe:SetTexCoord(0.078125, 0.921875, 0.078125, 0.921875)
		thisLine.icone_classe:SetVertexColor(1, 1, 1)

		if (thisLine.mouse_over and not instancia.baseframe.isMoving) then
			local classIcon = thisLine:GetClassIcon()
			thisLine.iconHighlight:SetTexture(classIcon:GetTexture())
			thisLine.iconHighlight:SetTexCoord(classIcon:GetTexCoord())
			thisLine.iconHighlight:SetVertexColor(classIcon:GetVertexColor())
			--need call a refresh function
		end
	end

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--main refresh function

---@param instanceObject instance
---@param combatObject combat
---@param bForceUpdate boolean
---@param bExportData boolean
function damageClass:RefreshWindow(instanceObject, combatObject, bForceUpdate, bExportData)
	---@type actorcontainer
	local damageContainer = combatObject[class_type] --o que esta sendo mostrado -> [1] - dano [2] - cura --pega o container com ._NameIndexTable ._ActorTable

	--not have something to show
	if (#damageContainer._ActorTable < 1) then
		if (Details.debug and false) then
			Details.showing_ActorTable_Timer = Details.showing_ActorTable_Timer or 0
			if (time() > Details.showing_ActorTable_Timer) then
				Details:Msg("(debug) nothing to show -> #showing._ActorTable < 1")
				Details.showing_ActorTable_Timer = time() + 5
			end
		end

		--colocado isso recentemente para fazer as barras de dano sumirem na troca de atributo
		return Details:HideBarsNotInUse(instanceObject, damageContainer), "", 0, 0
	end

	--total
	local total = 0
	--top actor #1
	instanceObject.top = 0

	local isUsingCache = false
	local subAttribute = instanceObject.sub_atributo
	local actorTableContent = damageContainer._ActorTable
	local amount = #actorTableContent
	local windowMode = instanceObject.modo

	--pega qual a sub key que ser� usada --sub keys
	if (bExportData) then
		if (type(bExportData) == "boolean") then
			if (subAttribute == 1) then --DAMAGE DONE
				keyName = "total"

			elseif (subAttribute == 2) then --DPS
				keyName = "last_dps"

			elseif (subAttribute == 3) then --DAMAGE TAKEN
				keyName = "damage_taken"
				if (Details.damage_taken_everything) then
					windowMode = modo_ALL
				end

			elseif (subAttribute == 4) then --FRIENDLY FIRE
				keyName = "friendlyfire_total"

			elseif (subAttribute == 5) then --FRAGS
				keyName = "frags"

			elseif (subAttribute == 6) then --ENEMIES
				keyName = "enemies"

			elseif (subAttribute == 7) then --AURAS VOIDZONES
				keyName = "voidzones"

			elseif (subAttribute == 8) then --BY SPELL
				keyName = "damage_taken_by_spells"
			end
		else
			keyName = bExportData.key
			windowMode = bExportData.modo
		end

	elseif (instanceObject.atributo == 5) then --custom
		keyName = "custom"
		total = combatObject.totals [instanceObject.customName]

	else
		if (subAttribute == 1) then --DAMAGE DONE
			keyName = "total"

		elseif (subAttribute == 2) then --DPS
			keyName = "last_dps"

		elseif (subAttribute == 3) then --DAMAGE TAKEN
			keyName = "damage_taken"
			if (Details.damage_taken_everything) then
				windowMode = modo_ALL
			end

		elseif (subAttribute == 4) then --FRIENDLY FIRE
			keyName = "friendlyfire_total"

		elseif (subAttribute == 5) then --FRAGS
			keyName = "frags"

		elseif (subAttribute == 6) then --ENEMIES
			keyName = "enemies"

		elseif (subAttribute == 7) then --AURAS VOIDZONES
			keyName = "voidzones"

		elseif (subAttribute == 8) then --BY SPELL
			keyName = "damage_taken_by_spells"
		end
	end

	if (keyName == "frags") then
		local frags = instanceObject.showing.frags
		local frags_total_kills = 0
		local index = 0

		for fragName, fragAmount in pairs(frags) do
			local fragged_actor = damageContainer._NameIndexTable [fragName] --get index
			if (fragged_actor) then
				fragged_actor = damageContainer._ActorTable [fragged_actor] --get object
				if (fragged_actor) then
					index = index + 1
					local actor_classe = fragged_actor.classe

					if (fragged_actor and fragged_actor.monster) then
						actor_classe = "ENEMY"
					elseif (not actor_classe) then
						actor_classe = "UNGROUPPLAYER"
					end

					if (ntable [index]) then
						ntable [index] [1] = fragName
						ntable [index] [2] = fragAmount
						ntable [index] [3] = actor_classe
					else
						ntable [index] = {fragName, fragAmount, actor_classe}
					end

					frags_total_kills = frags_total_kills + fragAmount
				end
			end
		end

		local tsize = #ntable
		if (index < tsize) then
			for i = index+1, tsize do
				ntable [i][2] = 0
			end
		end

		instanceObject.top = 0
		if (tsize > 0) then
			_table_sort(ntable, Details.Sort2)
			instanceObject.top = ntable [1][2]
		end

		total = index

		if (bExportData) then
			local export = {}
			for i = 1, index do
				export [i] = {ntable[i][1], ntable[i][2], ntable[i][3]}
			end
			return export
		end

		if (total < 1) then
			instanceObject:EsconderScrollBar()
			return Details:EndRefresh(instanceObject, total, combatObject, damageContainer) --retorna a tabela que precisa ganhar o refresh
		end

		combatObject.totals.frags_total = frags_total_kills

		instanceObject:RefreshScrollBar(total)

		local whichRowLine = 1
		local lineContainer = instanceObject.barras

		for i = instanceObject.barraS[1], instanceObject.barraS[2], 1 do
			damageClass:AtualizarFrags(ntable[i], whichRowLine, i, instanceObject)
			whichRowLine = whichRowLine+1
		end

		return Details:EndRefresh(instanceObject, total, combatObject, damageContainer) --retorna a tabela que precisa ganhar o refresh

	elseif (keyName == "damage_taken_by_spells") then
		local bs_index, total = 0, 0
		Details:Destroy(bs_index_table)

		local combat = combatObject
		local AllDamageCharacters = combat:GetActorList (DETAILS_ATTRIBUTE_DAMAGE)

		--do a loop amoung the actors
		for index, character in ipairs(AllDamageCharacters) do

			--is the actor a player?
			if (character:IsPlayer()) then

				for source_name, _ in pairs(character.damage_from) do

					local source = combat (1, source_name)

					if (source) then
						--came from an enemy
						if (not source:IsPlayer()) then

							local AllSpells = source:GetSpellList()
							for spellid, spell in pairs(AllSpells) do
								local on_player = spell.targets [character.nome]

								if (on_player and on_player >= 1) then

									local spellname = _GetSpellInfo(spellid)
									if (spellname) then
										local has_index = bs_index_table [spellname]
										local this_spell
										if (has_index) then
											this_spell = bs_table [has_index]
										else
											bs_index = bs_index + 1
											this_spell = bs_table [bs_index]
											if (this_spell) then
												this_spell [1] = spellid
												this_spell [2] = 0
												this_spell [3] = spell.spellschool or Details.spell_school_cache [select(1, GetSpellInfo(spellid))] or 1
												bs_index_table [spellname] = bs_index
											else
												this_spell = {spellid, 0, spell.spellschool or Details.spell_school_cache [select(1, GetSpellInfo(spellid))] or 1}
												bs_table [bs_index] = this_spell
												bs_index_table [spellname] = bs_index
											end
										end
										this_spell [2] = this_spell [2] + on_player
										total = total + on_player
									else
										error("error - no spell id for DTBS " .. spellid)
									end
								end
							end

						elseif (source:IsGroupPlayer()) then -- friendly fire

							local AllSpells = source.friendlyfire [character.nome] and source.friendlyfire [character.nome].spells
							if (AllSpells) then -- se n�o existir pode ter vindo de um pet, talvez
								for spellid, on_player in pairs(AllSpells) do
									if (on_player and on_player >= 1) then

										local spellname = _GetSpellInfo(spellid)
										if (spellname) then
											local has_index = bs_index_table [spellname]
											local this_spell
											if (has_index) then
												this_spell = bs_table [has_index]
											else
												bs_index = bs_index + 1
												this_spell = bs_table [bs_index]
												if (this_spell) then
													this_spell [1] = spellid
													this_spell [2] = 0
													this_spell [3] = Details.spell_school_cache [select(1, GetSpellInfo(spellid))] or 1
													bs_index_table [spellname] = bs_index
												else
													this_spell = {spellid, 0, Details.spell_school_cache [select(1, GetSpellInfo(spellid))] or 1}
													bs_table [bs_index] = this_spell
													bs_index_table [spellname] = bs_index
												end
											end
											this_spell [2] = this_spell [2] + on_player
											total = total + on_player
										else
											error("error - no spell id for DTBS friendly fire " .. spellid)
										end
									end
								end
							end
						end
					end
				end
			end
		end

		local tsize = #bs_table
		if (bs_index < tsize) then
			for i = bs_index+1, tsize do
				bs_table [i][2] = 0
			end
		end

		instanceObject.top = 0
		if (tsize > 0) then
			_table_sort(bs_table, Details.Sort2)
			instanceObject.top = bs_table [1][2]
		end

		local total2 = bs_index

		if (bExportData) then
			local export = {}
			for i = 1, bs_index do
				-- spellid, total, spellschool
				export [i] = {spellid = bs_table[i][1], damage = bs_table[i][2], spellschool = bs_table[i][3]}
			end
			return total, "damage", instanceObject.top, bs_index, export
		end

		if (bs_index < 1) then
			instanceObject:EsconderScrollBar()
			return Details:EndRefresh(instanceObject, bs_index, combatObject, damageContainer) --retorna a tabela que precisa ganhar o refresh
		end

		combatObject.totals.by_spell = total

		instanceObject:RefreshScrollBar(bs_index)

		local whichRowLine = 1
		local lineContainer = instanceObject.barras

		for i = instanceObject.barraS[1], instanceObject.barraS[2], 1 do
			damageClass:AtualizarBySpell (bs_table[i], whichRowLine, i, instanceObject)
			whichRowLine = whichRowLine+1
		end

		return Details:EndRefresh(instanceObject, bs_index, combatObject, damageContainer)

	elseif (keyName == "voidzones") then
		local index = 0
		local misc_container = combatObject [4]
		local voidzone_damage_total = 0

		for _, actor in ipairs(misc_container._ActorTable) do
			if (actor.boss_debuff) then
				index = index + 1

				--pega no container de dano o actor respons�vel por aplicar o debuff
				local twin_damage_actor = damageContainer._NameIndexTable [actor.damage_twin] or damageContainer._NameIndexTable ["[*] " .. actor.damage_twin]

				if (twin_damage_actor) then
					local index = twin_damage_actor
					twin_damage_actor = damageContainer._ActorTable [twin_damage_actor]

					local spell = twin_damage_actor.spells._ActorTable [actor.damage_spellid]

					if (spell) then

						--fix spell, sometimes there is two spells with the same name, one is the cast and other is the debuff
						if (spell.total == 0 and not actor.damage_spellid_fixed) then
							local curname = _GetSpellInfo(actor.damage_spellid)
							for spellid, spelltable in pairs(twin_damage_actor.spells._ActorTable) do
								if (spelltable.total > spell.total) then
									local name = _GetSpellInfo(spellid)
									if (name == curname) then
										actor.damage_spellid = spellid
										spell = spelltable
									end
								end
							end
							actor.damage_spellid_fixed = true
						end

						actor.damage = spell.total
						voidzone_damage_total = voidzone_damage_total + spell.total

					elseif (not actor.damage_spellid_fixed) then --not
						--fix spell, if the spellid passed for debuff uptime is actully the spell id of a ability and not if the aura it self
						actor.damage_spellid_fixed = true
						local found = false
						for spellid, spelltable in pairs(twin_damage_actor.spells._ActorTable) do
							local name = _GetSpellInfo(spellid)
							if (actor.damage_twin:find(name)) then
								actor.damage = spelltable.total
								voidzone_damage_total = voidzone_damage_total + spelltable.total
								actor.damage_spellid = spellid
								found = true
								break
							end
						end

						if (not found) then
							actor.damage = 0
						end
					else
						actor.damage = 0
					end
				else
					actor.damage = 0
				end

				vtable [index] = actor
			end
		end

		local tsize = #vtable
		if (index < tsize) then
			for i = index+1, tsize do
				vtable [i] = nil
			end
		end

		if (tsize > 0 and vtable[1]) then
			_table_sort(vtable, void_zone_sort)
			instanceObject.top = vtable [1].damage
		end
		total = index

		if (bExportData) then
			for _, t in ipairs(vtable) do
				t.report_name = Details:GetSpellLink(t.damage_spellid)
			end
			return voidzone_damage_total, "damage", instanceObject.top, total, vtable, "report_name"
		end

		if (total < 1) then
			instanceObject:EsconderScrollBar()
			return Details:EndRefresh(instanceObject, total, combatObject, damageContainer) --retorna a tabela que precisa ganhar o refresh
		end

		combatObject.totals.voidzone_damage = voidzone_damage_total

		instanceObject:RefreshScrollBar(total)

		local whichRowLine = 1
		local lineContainer = instanceObject.barras

		for i = instanceObject.barraS[1], instanceObject.barraS[2], 1 do
			vtable[i]:AtualizarVoidZone (whichRowLine, i, instanceObject)
			whichRowLine = whichRowLine+1
		end

		return Details:EndRefresh(instanceObject, total, combatObject, damageContainer) --retorna a tabela que precisa ganhar o refresh

	else
	--/run Details:Dump(Details:GetCurrentCombat():GetActor(1, "Injured Steelspine 1"))
		if (keyName == "enemies") then
			amount, total = Details:ContainerSortEnemies (actorTableContent, amount, "damage_taken")

			--remove actors with zero damage taken
			local newAmount = 0
			for i = 1, #actorTableContent do
				if (actorTableContent[i].damage_taken < 1) then
					newAmount = i-1
					break
				end
			end

			--if all units shown are enemies and all have damage taken, check if newAmount is zero and #conteudo has value bigger than 0
			if (newAmount == 0 and #actorTableContent > 0) then
				amount = amount
			else
				amount = newAmount
			end

			--keyName = "damage_taken"
			--result of the first actor
			instanceObject.top = actorTableContent[1] and actorTableContent[1][keyName]

		elseif (windowMode == DETAILS_MODE_ALL) then --mostrando ALL
			--faz o sort da categoria e retorna o amount corrigido
			if (subAttribute == 2) then
				local combat_time = instanceObject.showing:GetCombatTime()
				total = damageClass:ContainerRefreshDps(actorTableContent, combat_time)
			else
				--pega o total ja aplicado na tabela do combate
				total = combatObject.totals[class_type]
			end

			amount = Details:ContainerSort(actorTableContent, amount, keyName)

			--grava o total
			instanceObject.top = actorTableContent[1][keyName]

		elseif (windowMode == DETAILS_MODE_GROUP) then --mostrando GROUP
			if (Details.in_combat and instanceObject.segmento == 0 and not bExportData) then
				isUsingCache = true
			end

			if (isUsingCache) then
				actorTableContent = Details.cache_damage_group

				if (#actorTableContent < 1) then
					if (Details.debug and false) then
						Details.showing_ActorTable_Timer2 = Details.showing_ActorTable_Timer2 or 0
						if (time() > Details.showing_ActorTable_Timer2) then
							Details:Msg("(debug) nothing to show -> #conteudo < 1 (using cache)")
							Details.showing_ActorTable_Timer2 = time()+5
						end
					end

					return Details:HideBarsNotInUse(instanceObject, damageContainer), "", 0, 0
				end

				local bOrderDpsByRealTime = Details.CurrentDps.CanSortByRealTimeDps()

				if (subAttribute == 2) then --dps
					local combatTime = combatObject:GetCombatTime()
					local realTimeTotal = 0
					total, realTimeTotal = damageClass:ContainerRefreshDps(actorTableContent, combatTime)

					if (bOrderDpsByRealTime) then
						total = realTimeTotal
					end

				elseif (subAttribute == 1) then --damage done
					if (bOrderDpsByRealTime) then
						total = damageClass:RefreshDpsRealTime(actorTableContent)
					end
				end

				if (bOrderDpsByRealTime) then
					_table_sort(actorTableContent, Details.SortByRealTimeDps)

					if (actorTableContent[1]["last_dps_realtime"] < 1) then
						amount = 0
					else
						instanceObject.top = actorTableContent[1].last_dps_realtime
						amount = #actorTableContent
					end
				else
					_table_sort(actorTableContent, Details.SortKeySimple)
					if (actorTableContent[1][keyName] < 1) then
						amount = 0
					else
						instanceObject.top = actorTableContent[1][keyName]
						amount = #actorTableContent
					end

					if (subAttribute ~= 2) then --other than dps because dps already did the iteration and the total is already calculated
						for i = 1, amount do
							total = total + actorTableContent[i][keyName]
						end
					end
				end
			else
				if (subAttribute == 2) then --dps
					local combatTime = combatObject:GetCombatTime()
					damageClass:ContainerRefreshDps(actorTableContent, combatTime)
				end
				_table_sort(actorTableContent, Details.SortKeyGroup)
			end

			--
			if (not isUsingCache) then
				for index, player in ipairs(actorTableContent) do
					if (player.grupo) then --� um player e esta em grupo
						if (player[keyName] < 1) then --dano menor que 1, interromper o loop
							amount = index - 1
							break
						end

						total = total + player[keyName]
					else
						amount = index-1
						break
					end
				end

				instanceObject.top = actorTableContent[1] and actorTableContent[1][keyName]
			end

		end
	end

	--refaz o mapa do container
	if (not isUsingCache) then
		damageContainer:remapear()
	end

	if (bExportData) then
		return total, keyName, instanceObject.top, amount
	end

	if (amount < 1) then --n�o h� barras para mostrar
		if (bForceUpdate) then
			if (instanceObject.modo == 2) then --group
				for i = 1, instanceObject.rows_fit_in_window  do
					Details.FadeHandler.Fader(instanceObject.barras [i], "in", Details.fade_speed)
				end
			end
		end
		instanceObject:EsconderScrollBar() --precisaria esconder a scroll bar

		if (Details.debug and false) then
			Details.showing_ActorTable_Timer2 = Details.showing_ActorTable_Timer2 or 0
			if (time() > Details.showing_ActorTable_Timer2) then
				Details:Msg("(debug) nothing to show -> amount < 1")
				Details.showing_ActorTable_Timer2 = time()+5
			end
		end

		return Details:EndRefresh(instanceObject, total, combatObject, damageContainer) --retorna a tabela que precisa ganhar o refresh
	end

	instanceObject:RefreshScrollBar(amount)

	local whichRowLine = 1
	local lineContainer = instanceObject.barras
	local percentageType = instanceObject.row_info.percent_type
	local barsShowData = instanceObject.row_info.textR_show_data
	local barsBrackets = instanceObject:GetBarBracket()
	local barsSeparator = instanceObject:GetBarSeparator()
	local baseframe = instanceObject.baseframe
	local useAnimations = Details.is_using_row_animations and (not baseframe.isStretching and not bForceUpdate and not baseframe.isResizing)

	if (total == 0) then
		total = 0.00000001
	end

	local myPos
	local following = instanceObject.following.enabled and subAttribute ~= 6

	if (following) then
		if (isUsingCache) then
			local pname = Details.playername
			for i, actor in ipairs(actorTableContent) do
				if (actor.nome == pname) then
					myPos = i
					break
				end
			end
		else
			myPos = damageContainer._NameIndexTable [Details.playername]
		end
	end

	local combatTime = instanceObject.showing:GetCombatTime()
	UsingCustomLeftText = instanceObject.row_info.textL_enable_custom_text
	UsingCustomRightText = instanceObject.row_info.textR_enable_custom_text

	local useTotalBar = false
	if (instanceObject.total_bar.enabled) then
		useTotalBar = true

		if (instanceObject.total_bar.only_in_group and (not IsInGroup() and not IsInRaid())) then
			useTotalBar = false
		end

		if (subAttribute > 4) then --enemies, frags, void zones
			useTotalBar = false
		end
	end

	if (subAttribute == 2) then --dps
		instanceObject.player_top_dps = actorTableContent [1].last_dps
		instanceObject.player_top_dps_threshold = instanceObject.player_top_dps - (instanceObject.player_top_dps * 0.65)
	end

	local totalBarIsShown

	if (instanceObject.bars_sort_direction == 1) then --top to bottom
		if (useTotalBar and instanceObject.barraS[1] == 1) then
			whichRowLine = 2
			local iterLast = instanceObject.barraS[2]
			if (iterLast == instanceObject.rows_fit_in_window) then
				iterLast = iterLast - 1
			end

			local row1 = lineContainer [1]
			row1.minha_tabela = nil
			row1.lineText1:SetText(Loc ["STRING_TOTAL"])

			if (instanceObject.use_multi_fontstrings) then
				row1.lineText2:SetText("")
				row1.lineText3:SetText(Details:ToK2(total))
				row1.lineText4:SetText(Details:ToK(total / combatTime))
			else
				row1.lineText4:SetText(Details:ToK2(total) .. " (" .. Details:ToK(total / combatTime) .. ")")
			end

			row1:SetValue(100)
			local r, g, b = unpack(instanceObject.total_bar.color)
			row1.textura:SetVertexColor(r, g, b)
			row1.icone_classe:SetTexture(instanceObject.total_bar.icon)
			row1.icone_classe:SetTexCoord(0.0625, 0.9375, 0.0625, 0.9375)

			Details.FadeHandler.Fader(row1, "out")
			totalBarIsShown = true

			if (following and myPos and myPos+1 > instanceObject.rows_fit_in_window and instanceObject.barraS[2] < myPos+1) then
				for i = instanceObject.barraS[1], iterLast-1, 1 do
					if (actorTableContent[i]) then
						actorTableContent[i]:RefreshLine(instanceObject, lineContainer, whichRowLine, i, total, subAttribute, bForceUpdate, keyName, combatTime, percentageType, useAnimations, barsShowData, barsBrackets, barsSeparator)
						whichRowLine = whichRowLine+1
					end
				end
				actorTableContent[myPos]:RefreshLine(instanceObject, lineContainer, whichRowLine, myPos, total, subAttribute, bForceUpdate, keyName, combatTime, percentageType, useAnimations, barsShowData, barsBrackets, barsSeparator)
				whichRowLine = whichRowLine+1
			else
				for i = instanceObject.barraS[1], iterLast, 1 do
					if (actorTableContent[i]) then
						actorTableContent[i]:RefreshLine(instanceObject, lineContainer, whichRowLine, i, total, subAttribute, bForceUpdate, keyName, combatTime, percentageType, useAnimations, barsShowData, barsBrackets, barsSeparator)
						whichRowLine = whichRowLine+1
					end
				end
			end

		else
			if (following and myPos and myPos > instanceObject.rows_fit_in_window and instanceObject.barraS[2] < myPos) then
				for i = instanceObject.barraS[1], instanceObject.barraS[2]-1, 1 do
					if (actorTableContent[i]) then
						actorTableContent[i]:RefreshLine(instanceObject, lineContainer, whichRowLine, i, total, subAttribute, bForceUpdate, keyName, combatTime, percentageType, useAnimations, barsShowData, barsBrackets, barsSeparator)
						whichRowLine = whichRowLine+1
					end
				end

				actorTableContent[myPos]:RefreshLine(instanceObject, lineContainer, whichRowLine, myPos, total, subAttribute, bForceUpdate, keyName, combatTime, percentageType, useAnimations, barsShowData, barsBrackets, barsSeparator)
				whichRowLine = whichRowLine+1
			else
				for i = instanceObject.barraS[1], instanceObject.barraS[2], 1 do
					if (actorTableContent[i]) then

						actorTableContent[i]:RefreshLine(instanceObject, lineContainer, whichRowLine, i, total, subAttribute, bForceUpdate, keyName, combatTime, percentageType, useAnimations, barsShowData, barsBrackets, barsSeparator)
						whichRowLine = whichRowLine+1
					end
				end
			end
		end

	elseif (instanceObject.bars_sort_direction == 2) then --bottom to top
		if (useTotalBar and instanceObject.barraS[1] == 1) then
			whichRowLine = 2
			local iter_last = instanceObject.barraS[2]
			if (iter_last == instanceObject.rows_fit_in_window) then
				iter_last = iter_last - 1
			end

			local row1 = lineContainer [1]
			row1.minha_tabela = nil
			row1.lineText1:SetText(Loc ["STRING_TOTAL"])

			if (instanceObject.use_multi_fontstrings) then
				row1.lineText2:SetText("")
				row1.lineText3:SetText(Details:ToK2(total))
				row1.lineText4:SetText(Details:ToK(total / combatTime))
			else
				row1.lineText4:SetText(Details:ToK2(total) .. " (" .. Details:ToK(total / combatTime) .. ")")
			end

			row1:SetValue(100)
			local r, g, b = unpack(instanceObject.total_bar.color)
			row1.textura:SetVertexColor(r, g, b)

			row1.icone_classe:SetTexture(instanceObject.total_bar.icon)
			row1.icone_classe:SetTexCoord(0.0625, 0.9375, 0.0625, 0.9375)

			Details.FadeHandler.Fader(row1, "out")
			totalBarIsShown = true

			if (following and myPos and myPos+1 > instanceObject.rows_fit_in_window and instanceObject.barraS[2] < myPos+1) then
				actorTableContent[myPos]:RefreshLine(instanceObject, lineContainer, whichRowLine, myPos, total, subAttribute, bForceUpdate, keyName, combatTime, percentageType, useAnimations, barsShowData, barsBrackets, barsSeparator)
				whichRowLine = whichRowLine+1
				for i = iter_last-1, instanceObject.barraS[1], -1 do
					if (actorTableContent[i]) then
						actorTableContent[i]:RefreshLine(instanceObject, lineContainer, whichRowLine, i, total, subAttribute, bForceUpdate, keyName, combatTime, percentageType, useAnimations, barsShowData, barsBrackets, barsSeparator)
						whichRowLine = whichRowLine+1
					end
				end
			else
				for i = iter_last, instanceObject.barraS[1], -1 do
					if (actorTableContent[i]) then
						actorTableContent[i]:RefreshLine(instanceObject, lineContainer, whichRowLine, i, total, subAttribute, bForceUpdate, keyName, combatTime, percentageType, useAnimations, barsShowData, barsBrackets, barsSeparator)
						whichRowLine = whichRowLine+1
					end
				end
			end
		else
			if (following and myPos and myPos > instanceObject.rows_fit_in_window and instanceObject.barraS[2] < myPos) then
				actorTableContent[myPos]:RefreshLine(instanceObject, lineContainer, whichRowLine, myPos, total, subAttribute, bForceUpdate, keyName, combatTime, percentageType, useAnimations, barsShowData, barsBrackets, barsSeparator)
				whichRowLine = whichRowLine+1
				for i = instanceObject.barraS[2]-1, instanceObject.barraS[1], -1 do
					if (actorTableContent[i]) then
						actorTableContent[i]:RefreshLine(instanceObject, lineContainer, whichRowLine, i, total, subAttribute, bForceUpdate, keyName, combatTime, percentageType, useAnimations, barsShowData, barsBrackets, barsSeparator)
						whichRowLine = whichRowLine+1
					end
				end
			else
				for i = instanceObject.barraS[2], instanceObject.barraS[1], -1 do
					if (actorTableContent[i]) then
						actorTableContent[i]:RefreshLine(instanceObject, lineContainer, whichRowLine, i, total, subAttribute, bForceUpdate, keyName, combatTime, percentageType, useAnimations, barsShowData, barsBrackets, barsSeparator)
						whichRowLine = whichRowLine+1
					end
				end
			end
		end

	end

	if (totalBarIsShown) then
		instanceObject:RefreshScrollBar(amount + 1)
	else
		instanceObject:RefreshScrollBar(amount)
	end

	if (useAnimations) then
		instanceObject:PerformAnimations(whichRowLine - 1)
	end

	--beta, hidar barras n�o usadas durante um refresh for�ado
	if (bForceUpdate) then
		if (instanceObject.modo == 2) then --group
			for i = whichRowLine, instanceObject.rows_fit_in_window  do
				Details.FadeHandler.Fader(instanceObject.barras [i], "in", Details.fade_speed)
			end
		end
	end

	Details.LastFullDamageUpdate = Details._tempo

	instanceObject:AutoAlignInLineFontStrings()

	return Details:EndRefresh(instanceObject, total, combatObject, damageContainer) --retorna a tabela que precisa ganhar o refresh
end

--[[exported]] function Details:AutoAlignInLineFontStrings()

	--if this instance is using in line texts, check the min distance and the length of strings to make them more spread appart
	if (self.use_multi_fontstrings and self.use_auto_align_multi_fontstrings) then
		local maxStringLength_StringFour = 0
		local maxStringLength_StringThree = 0
		local profileOffsetString3 = self.fontstrings_text3_anchor
		local profileOffsetString2 = self.fontstrings_text2_anchor
		local profileYOffset = self.row_info.text_yoffset

		Details.CacheInLineMaxDistance = Details.CacheInLineMaxDistance or {}
		Details.CacheInLineMaxDistance[self:GetId()] = Details.CacheInLineMaxDistance[self:GetId()] or {[2] = profileOffsetString2, [3] = profileOffsetString3}

		--space between string4 and string3 (usually dps is 4 and total value is 3)
		for lineId = 1, self:GetNumLinesShown() do
			local thisLine = self:GetLine(lineId)

			--check strings 3 and 4
			if (thisLine.lineText4:GetText() ~= "" and thisLine.lineText3:GetText() ~= "") then
				--the length of the far right string determines the space between it and the next string in the left
				local stringLength = thisLine.lineText4:GetStringWidth()
				maxStringLength_StringFour = stringLength > maxStringLength_StringFour and stringLength or maxStringLength_StringFour
			end

			--check strings 2 and 3
			if (thisLine.lineText2:GetText() ~= "" and thisLine.lineText3:GetText() ~= "") then
				--the length of the middle string determines the space between it and the next string in the left
				local stringLength = thisLine.lineText3:GetStringWidth()
				maxStringLength_StringThree = stringLength > maxStringLength_StringThree and stringLength or maxStringLength_StringThree
			end
		end

		--if the length bigger than the min distance? calculate for string4 to string3 distance
		if ((maxStringLength_StringFour > 0) and (maxStringLength_StringFour + 5 > profileOffsetString3)) then
			local newOffset = maxStringLength_StringFour + 5

			--check if the current needed min distance is bigger than the distance stored in the cache
			local currentCacheMaxValue = Details.CacheInLineMaxDistance[self:GetId()][3]
			if (currentCacheMaxValue < newOffset) then
				currentCacheMaxValue = newOffset
				Details.CacheInLineMaxDistance[self:GetId()][3] = currentCacheMaxValue
			else
				--if not, use the distance value cached to avoid jittering in the string
				newOffset = currentCacheMaxValue
			end

			--update the lines
			for lineId = 1, self:GetNumLinesShown() do
				local thisLine = self:GetLine(lineId)
				thisLine.lineText3:SetPoint("right", thisLine.statusbar, "right", -newOffset, profileYOffset)
			end
		end

		--check if there's length in the third string, also the third string cannot have a length if the second string is empty
		if (maxStringLength_StringThree > 0) then
			local newOffset = maxStringLength_StringThree + maxStringLength_StringFour + 14
			if (newOffset >= profileOffsetString2) then
				--check if the current needed min distance is bigger than the distance stored in the cache
				local currentCacheMaxValue = Details.CacheInLineMaxDistance[self:GetId()][2]
				if (currentCacheMaxValue < newOffset) then
					currentCacheMaxValue = newOffset
					Details.CacheInLineMaxDistance[self:GetId()][2] = currentCacheMaxValue
				else
					--if not, use the distance value cached to avoid jittering in the string
					newOffset = currentCacheMaxValue
				end

				--update the lines
				for lineId = 1, self:GetNumLinesShown() do
					local thisLine = self:GetLine(lineId)
					thisLine.lineText2:SetPoint("right", thisLine.statusbar, "right", -newOffset, profileYOffset)
				end
			end
		end

		--reduce the size of the actor name string based on the total size of all strings in the right side
		for lineId = 1, self:GetNumLinesShown() do
			local thisLine = self:GetLine(lineId)

			--check if there's something showing in this line
			--check if the line is shown and if the text exists for sanitization
			if (thisLine.minha_tabela and thisLine:IsShown() and thisLine.lineText1:GetText()) then
				local playerNameFontString = thisLine.lineText1
				local text2 = thisLine.lineText2
				local text3 = thisLine.lineText3
				local text4 = thisLine.lineText4

				local totalWidth = text2:GetStringWidth() + text3:GetStringWidth() + text4:GetStringWidth()
				totalWidth = totalWidth + 40 - self.fontstrings_text_limit_offset

				DetailsFramework:TruncateTextSafe(playerNameFontString, self.cached_bar_width - totalWidth) --this avoid truncated strings with ...

				--these commented lines are for to create a cache and store the name already truncated there to safe performance
					--local truncatedName = playerNameFontString:GetText()
					--local actorObject = thisLine.minha_tabela
					--actorObject.name_cached = truncatedName
					--actorObject.name_cached_time = GetTime()
			end
		end
	end
end

--handle internal details! events
local eventListener = Details:CreateEventListener()
eventListener:RegisterEvent("COMBAT_PLAYER_ENTER", function()
	if (Details.CacheInLineMaxDistance) then
		Details:Destroy(Details.CacheInLineMaxDistance)

		for i = 1, 10 do
			C_Timer.After(i, function()
				Details:Destroy(Details.CacheInLineMaxDistance)
			end)
		end
	end
end)

local classColor_Red, classColor_Green, classColor_Blue

-- ~texts
--[[exported]] function Details:SetInLineTexts(thisLine, valueText, perSecondText, percentText)
	--set defaults
	local instance = self
	valueText = valueText or ""
	perSecondText = perSecondText or ""
	percentText = percentText or ""

	if ((Details.use_realtimedps or (Details.combat_log.evoker_show_realtimedps and Details.playerspecid == 1473)) and Details.in_combat) then --real time
		if (thisLine:GetActor()) then
			local actorSerial = thisLine:GetActor().serial
			local currentDps = Details.CurrentDps.GetCurrentDps(actorSerial)
			if (currentDps and currentDps > 0) then
				currentDps = Details:ToK2(currentDps)
			end
			perSecondText = currentDps
		end
	end

	--check if the instance is showing total, dps and percent
	local instanceSettings = instance.row_info
	if (not instanceSettings.textR_show_data[3]) then --percent text disabled on options panel
		local attributeId = instance:GetDisplay()
		if (attributeId ~= 5) then --not custom
			percentText = ""
		end
	end

	--parse information
	if (percentText ~= "") then --has percent text
		thisLine.lineText4:SetText(percentText)

		if (perSecondText ~= "") then --has dps?
			thisLine.lineText3:SetText(perSecondText) --set dps
			thisLine.lineText2:SetText(valueText) --set amount
		else
			thisLine.lineText3:SetText(valueText) --set amount
			thisLine.lineText2:SetText("") --clear
		end
	else --no percent text
		if (perSecondText ~= "") then --has dps and no percent
			thisLine.lineText4:SetText(perSecondText) --set dps
			thisLine.lineText3:SetText(valueText) --set amount
			thisLine.lineText2:SetText("") --clear
		else --no dps and not percent
			thisLine.lineText4:SetText(valueText) --set dps
			thisLine.lineText3:SetText("") --clear
			thisLine.lineText2:SetText("") --clear
		end
	end
end

-- ~atualizar ~barra ~update
function damageClass:RefreshLine(instanceObject, lineContainer, whichRowLine, rank, total, subAttribute, bForceRefresh, keyName, combatTime, percentageType, bUseAnimations, bars_show_data, bars_brackets, bars_separator)
	local thisLine = lineContainer[whichRowLine]

	if (not thisLine) then
		print("DEBUG: problema com <instance.thisLine> "..whichRowLine.." "..rank)
		return
	end

	local previousData = thisLine.minha_tabela
	thisLine.minha_tabela = self --store references
	self.minha_barra = thisLine --store references

	thisLine.colocacao = rank
	self.colocacao = rank

	local damageTotal = self.total --total damage of this actor
	local dps
	local percentString
	local percentNumber

	--calc the percent amount base on the percent type
	if (percentageType == 1) then
		percentString = format("%.1f", self[keyName] / total * 100)

	elseif (percentageType == 2) then
		percentString = format("%.1f", self[keyName] / instanceObject.top * 100)
	end

	local currentCombat = instanceObject:GetCombat()

	if (currentCombat:GetCombatType() == DETAILS_SEGMENTTYPE_MYTHICDUNGEON_OVERALL) then
		if (Details.mythic_plus.mythicrun_time_type == 1) then
			--total time in combat, activity time
			combatTime = currentCombat:GetCombatTime()
		elseif (Details.mythic_plus.mythicrun_time_type == 2) then
			--elapsed time of the run
			combatTime = currentCombat:GetRunTime()
		end

		dps = damageTotal / combatTime
		self.last_dps = dps
	else
		--calculate the actor dps
		if ((Details.time_type == 2 and self.grupo) or not Details:CaptureGet("damage") or instanceObject.segmento == -1 or Details.use_realtimedps) then
			if (Details.use_realtimedps and Details.in_combat) then
				local currentDps = self.last_dps_realtime
				if (currentDps) then
					dps = currentDps
				end
			end

			if (not dps) then
				if (instanceObject.segmento == -1 and combatTime == 0) then
					local actor = currentCombat(1, self.nome)
					if (actor) then
						local combatTime = actor:Tempo()
						dps = damageTotal / combatTime
						self.last_dps = dps
					else
						dps = damageTotal / combatTime
						self.last_dps = dps
					end
				else
					dps = damageTotal / combatTime
					self.last_dps = dps
				end
			end
		else
			if (not self.on_hold) then
				dps = damageTotal/self:Tempo() --calcula o dps deste objeto
				self.last_dps = dps --salva o dps dele
			else
				if (self.last_dps == 0) then --n�o calculou o dps dele ainda mas entrou em standby
					dps = damageTotal/self:Tempo()
					self.last_dps = dps
				else
					dps = self.last_dps
				end
			end
		end
	end

	--right text
	if (subAttribute == 1) then --damage done
		dps = _math_floor(dps)
		local formatedDamage = SelectedToKFunction(_, damageTotal)
		local formatedDps = SelectedToKFunction(_, dps)
		thisLine.ps_text = formatedDps

		if (not bars_show_data[1]) then
			formatedDamage = ""
		end

		if (not bars_show_data[2]) then
			formatedDps = ""
		end

		if (not bars_show_data[3]) then
			percentString = ""
		else
			percentString = percentString .. "%"
		end

		local rightText = formatedDamage .. bars_brackets[1] .. formatedDps .. bars_separator .. percentString .. bars_brackets[2]

		if (UsingCustomRightText) then
			thisLine.lineText4:SetText(stringReplace(instanceObject.row_info.textR_custom_text, formatedDamage, formatedDps, percentString, self, instanceObject.showing, instanceObject, rightText))
		else
			if (instanceObject.use_multi_fontstrings) then
				instanceObject:SetInLineTexts(thisLine, formatedDamage, formatedDps, percentString)
			else
				thisLine.lineText4:SetText(rightText)
			end
		end

		if (Details.CurrentDps.CanSortByRealTimeDps()) then
			percentNumber = _math_floor((self.last_dps_realtime / instanceObject.top) * 100)
		else
			percentNumber = _math_floor((damageTotal/instanceObject.top) * 100)
		end

	elseif (subAttribute == 2) then --dps
		local raw_dps = dps
		dps = _math_floor(dps)

		local formated_damage = SelectedToKFunction(_, damageTotal)
		local formated_dps = SelectedToKFunction(_, dps)
		thisLine.ps_text = formated_dps

		local diff_from_topdps

		if (rank > 1) then
			diff_from_topdps = instanceObject.player_top_dps - raw_dps
		end

		local rightText
		if (diff_from_topdps) then
			local threshold = diff_from_topdps / instanceObject.player_top_dps_threshold * 100
			if (threshold < 100) then
				threshold = abs(threshold - 100)
			else
				threshold = 5
			end

			local rr, gg, bb = Details:percent_color ( threshold )

			rr, gg, bb = Details:hex (_math_floor(rr*255)), Details:hex (_math_floor(gg*255)), "28"
			local color_percent = "" .. rr .. gg .. bb .. ""

			if (not bars_show_data [1]) then
				formated_dps = ""
			end
			if (not bars_show_data [2]) then
				color_percent = ""
			else
				color_percent = bars_brackets[1] .. "|cFFFF4444-|r|cFF" .. color_percent .. SelectedToKFunction(_, _math_floor(diff_from_topdps)) .. "|r" .. bars_brackets[2]
			end

			rightText = formated_dps .. color_percent

		else
			local icon = "  |TInterface\\GROUPFRAME\\UI-Group-LeaderIcon:14:14:0:0:16:16:0:16:0:16|t "
			if (not bars_show_data [1]) then
				formated_dps = ""
			end
			if (not bars_show_data [2]) then
				icon = ""
			end

			rightText = formated_dps .. icon
		end

		if (UsingCustomRightText) then
			thisLine.lineText4:SetText(stringReplace(instanceObject.row_info.textR_custom_text, formated_dps, formated_damage, percentString, self, instanceObject.showing, instanceObject, rightText))
		else
			if (instanceObject.use_multi_fontstrings) then
				--instance:SetInLineTexts(thisLine, formated_damage, formated_dps, porcentagem)
				instanceObject:SetInLineTexts(thisLine, rightText)
			else
				thisLine.lineText4:SetText(rightText)
			end
		end

		percentNumber = _math_floor((dps/instanceObject.top) * 100)

	elseif (subAttribute == 3) then --damage taken
		local dtps = self.damage_taken / combatTime

		local formated_damage_taken = SelectedToKFunction(_, self.damage_taken)
		local formated_dtps = SelectedToKFunction(_, dtps)
		thisLine.ps_text = formated_dtps

		if (not bars_show_data [1]) then
			formated_damage_taken = ""
		end
		if (not bars_show_data [2]) then
			formated_dtps = ""
		end
		if (not bars_show_data [3]) then
			percentString = ""
		else
			percentString = percentString .. "%"
		end

		local rightText = formated_damage_taken .. bars_brackets[1] .. formated_dtps .. bars_separator .. percentString .. bars_brackets[2]
		if (UsingCustomRightText) then
			thisLine.lineText4:SetText(stringReplace(instanceObject.row_info.textR_custom_text, formated_damage_taken, formated_dtps, percentString, self, instanceObject.showing, instanceObject, rightText))
		else
			if (instanceObject.use_multi_fontstrings) then
				instanceObject:SetInLineTexts(thisLine, formated_damage_taken, formated_dtps, percentString)
			else
				thisLine.lineText4:SetText(rightText)
			end
		end

		percentNumber = _math_floor((self.damage_taken/instanceObject.top) * 100)

	elseif (subAttribute == 4) then --friendly fire
		local formated_friendly_fire = SelectedToKFunction(_, self.friendlyfire_total)

		if (not bars_show_data [1]) then
			formated_friendly_fire = ""
		end
		if (not bars_show_data [3]) then
			percentString = ""
		else
			percentString = percentString .. "%"
		end

		local rightText = formated_friendly_fire .. bars_brackets[1] .. percentString ..  bars_brackets[2]
		if (UsingCustomRightText) then
			thisLine.lineText4:SetText(stringReplace(instanceObject.row_info.textR_custom_text, formated_friendly_fire, "", percentString, self, instanceObject.showing, instanceObject, rightText))
		else
			if (instanceObject.use_multi_fontstrings) then
				instanceObject:SetInLineTexts(thisLine, "", formated_friendly_fire, percentString)
			else
				thisLine.lineText4:SetText(rightText)
			end
		end
		percentNumber = _math_floor((self.friendlyfire_total/instanceObject.top) * 100)

	elseif (subAttribute == 6) then --enemies
		local dtps = self.damage_taken / combatTime

		local formatedDamageTaken = SelectedToKFunction(_, self.damage_taken)
		local formatedDtps = SelectedToKFunction(_, dtps)
		thisLine.ps_text = formatedDtps

		if (not bars_show_data [1]) then
			formatedDamageTaken = ""
		end
		if (not bars_show_data [2]) then
			formatedDtps = ""
		end
		if (not bars_show_data [3]) then
			percentString = ""
		else
			percentString = percentString .. "%"
		end

		local rightText = formatedDamageTaken .. bars_brackets[1] .. formatedDtps .. bars_separator .. percentString .. bars_brackets[2]
		if (UsingCustomRightText) then
			thisLine.lineText4:SetText(stringReplace(instanceObject.row_info.textR_custom_text, formatedDamageTaken, formatedDtps, percentString, self, instanceObject.showing, instanceObject, rightText))
		else
			if (instanceObject.use_multi_fontstrings) then
				instanceObject:SetInLineTexts(thisLine, formatedDamageTaken, formatedDtps, percentString)
			else
				thisLine.lineText4:SetText(rightText)
			end
		end

		percentNumber = _math_floor((self.damage_taken/instanceObject.top) * 100)
	end

	--need tooltip update?
	if (thisLine.mouse_over and not instanceObject.baseframe.isMoving) then
		gump:UpdateTooltip(whichRowLine, thisLine, instanceObject)
	end

	if (self.need_refresh) then
		self.need_refresh = false
		bForceRefresh = true
	end

	classColor_Red, classColor_Green, classColor_Blue = self:GetBarColor()

	return self:RefreshLineValue(thisLine, instanceObject, previousData, bForceRefresh, percentNumber, bUseAnimations, total, instanceObject.top)
end

---show an extra statusbar on the line, after the main statusbar
---@param thisLine table
---@param amount valueamount
---@param extraAmount valueamount
---@param totalAmount valueamount
---@param topAmount valueamount
---@param instanceObject instance
---@param onEnterFunc function?
---@param onLeaveFunc function?
function Details:ShowExtraStatusbar(thisLine, amount, extraAmount, totalAmount, topAmount, instanceObject, onEnterFunc, onLeaveFunc)
	local extraStatusbar = thisLine.extraStatusbar
	if (extraAmount and extraAmount > 0 and instanceObject.atributo == 1 and instanceObject.sub_atributo == 1) then
		local initialOffset = 0
		local icon_offset_x, icon_offset_y = unpack(instanceObject.row_info.icon_offset)

		local bIsUsingBarStartAfterIcon = instanceObject.row_info.start_after_icon
		if (bIsUsingBarStartAfterIcon) then
			initialOffset = thisLine.icone_classe:GetWidth() + icon_offset_x
		end

		local statusBarWidth = thisLine.statusbar:GetWidth()
		local percent = amount / topAmount
		local fillTheGapWidth = percent * 4

		local startExtraStatusbarOffset = percent * statusBarWidth
		local extraStatusbarWidth = statusBarWidth * (extraAmount / topAmount)

		extraStatusbar:ClearAllPoints()
		extraStatusbar:SetHeight(thisLine:GetHeight())

		if (bIsUsingBarStartAfterIcon) then
			extraStatusbar:SetPoint("topleft", thisLine.icone_classe, "topright", startExtraStatusbarOffset - fillTheGapWidth, 0)
		else
			extraStatusbar:SetPoint("topleft", thisLine, "topleft", (statusBarWidth * percent) - fillTheGapWidth, 0)
		end

		--check if the extra bar will be bigger than the window
		local windowWidth = instanceObject:GetSize()
		local lineWidth = thisLine:GetWidth() * (amount/topAmount)
		local maxExtraBarWidth = windowWidth - lineWidth - initialOffset

		if (extraStatusbarWidth > maxExtraBarWidth) then
			extraStatusbarWidth = maxExtraBarWidth
		end

		extraStatusbar:SetWidth(extraStatusbarWidth)
		extraStatusbar:SetFrameLevel(thisLine:GetFrameLevel() + 1)

		extraStatusbar.OnEnterCallback = onEnterFunc
		extraStatusbar.OnLeaveCallback = onLeaveFunc

		if (Details.combat_log.calc_evoker_damage) then
			extraStatusbar:SetAlpha(0.2)
			extraStatusbar.defaultAlpha = 0.2
		else
			extraStatusbar:SetAlpha(0.7)
			extraStatusbar.defaultAlpha = 0.7
		end
		extraStatusbar:Show()
	else
		extraStatusbar:Hide()
	end
end

--when the script detect the extrastatusbar need to be show, it will call this function
local handleShowExtraStatusbar = function(thisLine, self, instance, previousData, isForceRefresh, percent, bUseAnimations, totalValue, topValue)
	if (self.spec == 1473 and self.augmentedSpellsContainer) then
		--prepare the extra bar to show the damage prediction to augmented evoker
		local onEnterFunc = damageClass.PredictedAugSpellsOnEnter
		local onLeaveFunc = damageClass.PredictedAugSpellsOnLeave

		Details:ShowExtraStatusbar(thisLine, self.total, self.total_extra, totalValue, topValue, instance, onEnterFunc, onLeaveFunc)
		thisLine.extraStatusbar.augmentedSpellsContainer = self.augmentedSpellsContainer

		thisLine.extraStatusbar.actorName = self:Name()

		---@cast instance instance
		thisLine.extraStatusbar.instanceId = instance:GetId()
	else
		Details:ShowExtraStatusbar(thisLine, self.total, self.total_extra, totalValue, topValue, instance)
	end
end

function Details:RefreshLineValue(thisLine, instance, previousData, isForceRefresh, percent, bUseAnimations, totalValue, topValue) --[[exported]]
	thisLine.extraStatusbar:Hide()

	if (thisLine.colocacao == 1) then
		thisLine.animacao_ignorar = true

		if (not previousData or previousData ~= thisLine.minha_tabela or isForceRefresh) then
			thisLine:SetValue(100)

			if (thisLine.hidden or thisLine.fading_in or thisLine.faded) then
				Details.FadeHandler.Fader(thisLine, "out")
			end

			return self:RefreshBarra(thisLine, instance)
		else
			return
		end
	else
		if (thisLine.hidden or thisLine.fading_in or thisLine.faded) then
			--setando o valor  mesmo com anima��es pq o barra esta hidada com o value do �ltimo actor que ela mostrou
			if (bUseAnimations and self.spec ~= 1473) then
				thisLine.animacao_fim = percent
				thisLine:SetValue(percent)
			else
				thisLine:SetValue(percent)
				thisLine.animacao_ignorar = true
			end

			Details.FadeHandler.Fader(thisLine, "out")

			if (self.total_extra and self.total_extra > 0) then
				if (self.spec == 1473) then
					if (Details.combat_log.calc_evoker_damage) then
						handleShowExtraStatusbar(thisLine, self, instance, previousData, isForceRefresh, percent, bUseAnimations, totalValue, topValue)
					end
				else
					handleShowExtraStatusbar(thisLine, self, instance, previousData, isForceRefresh, percent, bUseAnimations, totalValue, topValue)
				end
			end

			return self:RefreshBarra(thisLine, instance)
		else
			--agora esta comparando se a tabela da barra � diferente da tabela na atualiza��o anterior
			if (not previousData or previousData ~= thisLine.minha_tabela or isForceRefresh) then --aqui diz se a barra do jogador mudou de posi��o ou se ela apenas ser� atualizada
				if (bUseAnimations and self.spec ~= 1473) then
					thisLine.animacao_fim = percent
				else
					thisLine:SetValue(percent)
					thisLine.animacao_ignorar = true
				end

				thisLine.last_value = percent --reseta o ultimo valor da barra

				if (self.total_extra and self.total_extra > 0) then
					if (self.spec == 1473) then
						if (Details.combat_log.calc_evoker_damage) then
							handleShowExtraStatusbar(thisLine, self, instance, previousData, isForceRefresh, percent, bUseAnimations, totalValue, topValue)
						end
					else
						handleShowExtraStatusbar(thisLine, self, instance, previousData, isForceRefresh, percent, bUseAnimations, totalValue, topValue)
					end
				end

				return self:RefreshBarra(thisLine, instance)

			elseif (percent ~= thisLine.last_value) then
				--apenas atualizar
				if (bUseAnimations and self.spec ~= 1473) then
					thisLine.animacao_fim = percent
				else
					thisLine:SetValue(percent)
				end
				thisLine.last_value = percent

				if (self.total_extra and self.total_extra > 0) then
					if (self.spec == 1473) then
						if (Details.combat_log.calc_evoker_damage) then
							handleShowExtraStatusbar(thisLine, self, instance, previousData, isForceRefresh, percent, bUseAnimations, totalValue, topValue)
						end
					else
						Details:ShowExtraStatusbar(thisLine, self.total, self.total_extra, totalValue, topValue, instance)
					end
				end

				return self:RefreshBarra(thisLine, instance)
			else
				if (self.total_extra and self.total_extra > 0) then
					if (self.spec == 1473) then
						if (Details.combat_log.calc_evoker_damage) then
							handleShowExtraStatusbar(thisLine, self, instance, previousData, isForceRefresh, percent, bUseAnimations, totalValue, topValue)
						end
					else
						handleShowExtraStatusbar(thisLine, self, instance, previousData, isForceRefresh, percent, bUseAnimations, totalValue, topValue)
					end
				end
			end
		end
	end
end

local setLineTextSize = function(line, instance)
	if (instance.bars_inverted) then
		line.lineText4:SetSize(instance.cached_bar_width - line.lineText1:GetStringWidth() - 20, 15)
	else
		line.lineText1:SetSize(instance.cached_bar_width - line.lineText4:GetStringWidth() - 20, 15)
	end
end


function Details:SetBarLeftText(bar, instance, enemy, arenaEnemy, arenaAlly, usingCustomLeftText) --[[exported]]
	local barNumber = ""
	if (instance.row_info.textL_show_number) then
		barNumber = bar.colocacao .. ". "
	end

	if (instance.row_info.textL_translit_text) then
		if (not self.transliteratedName) then
			--translate cyrillic alphabet to western alphabet by Vardex (https://github.com/Vardex May 22, 2019)
			self.transliteratedName = Translit:Transliterate(self.displayName, "!")
		end
		self.displayName = self.transliteratedName or self.displayName
	end

	if (enemy) then
		if (arenaEnemy) then
			if (instance.row_info.show_arena_role_icon) then
				--show arena role icon
				local sizeOffset = instance.row_info.arena_role_icon_size_offset
				local leftText = barNumber .. "|TInterface\\LFGFRAME\\UI-LFG-ICON-ROLES:" .. (instance.row_info.height + sizeOffset)..":"..(instance.row_info.height + sizeOffset) .. ":0:0:256:256:" .. Details.role_texcoord [self.role or "NONE"] .. "|t " .. self.displayName
				if (usingCustomLeftText) then
					bar.lineText1:SetText(stringReplace(instance.row_info.textL_custom_text, bar.colocacao, self.displayName, "|TInterface\\LFGFRAME\\UI-LFG-ICON-ROLES:" .. (instance.row_info.height + sizeOffset)..":"..(instance.row_info.height + sizeOffset) .. ":0:0:256:256:" .. Details.role_texcoord [self.role or "NONE"] .. "|t ", self, instance.showing, instance, leftText))
				else
					bar.lineText1:SetText(leftText)
				end
			else
				--don't show arena role icon
				local leftText = barNumber .. self.displayName
				if (usingCustomLeftText) then
					bar.lineText1:SetText(stringReplace(instance.row_info.textL_custom_text, bar.colocacao, self.displayName, " ", self, instance.showing, instance, leftText))
				else
					bar.lineText1:SetText(leftText)
				end
			end
		else
			if (instance.row_info.show_faction_icon) then
				local sizeOffset = instance.row_info.faction_icon_size_offset
				if (Details.faction_against == "Horde") then
					local leftText = barNumber .. "|TInterface\\AddOns\\Details\\images\\icones_barra:" .. (instance.row_info.height + sizeOffset)..":"..(instance.row_info.height + sizeOffset) .. ":0:0:256:32:0:32:0:32|t"..self.displayName
					if (usingCustomLeftText) then
						bar.lineText1:SetText(stringReplace(instance.row_info.textL_custom_text, bar.colocacao, self.displayName, "|TInterface\\AddOns\\Details\\images\\icones_barra:" .. (instance.row_info.height + sizeOffset)..":"..(instance.row_info.height + sizeOffset) .. ":0:0:256:32:0:32:0:32|t", self, instance.showing, instance, leftText))
					else
						bar.lineText1:SetText(leftText) --seta o texto da esqueda -- HORDA
					end
				else --alliance
					local leftText = barNumber .. "|TInterface\\AddOns\\Details\\images\\icones_barra:" .. (instance.row_info.height + sizeOffset)..":"..(instance.row_info.height + sizeOffset) .. ":0:0:256:32:32:64:0:32|t"..self.displayName
					if (usingCustomLeftText) then
						bar.lineText1:SetText(stringReplace(instance.row_info.textL_custom_text, bar.colocacao, self.displayName, "|TInterface\\AddOns\\Details\\images\\icones_barra:" .. (instance.row_info.height + sizeOffset)..":"..(instance.row_info.height + sizeOffset) .. ":0:0:256:32:32:64:0:32|t", self, instance.showing, instance, leftText))
					else
						bar.lineText1:SetText(leftText) --seta o texto da esqueda -- ALLY
					end
				end
			else
				--don't show faction icon
				local leftText = barNumber .. self.displayName
				if (usingCustomLeftText) then
					bar.lineText1:SetText(stringReplace(instance.row_info.textL_custom_text, bar.colocacao, self.displayName, " ", self, instance.showing, instance, leftText))
				else
					bar.lineText1:SetText(leftText)
				end
			end
		end
	else
		if (arenaAlly and instance.row_info.show_arena_role_icon) then
			local sizeOffset = instance.row_info.arena_role_icon_size_offset
			local leftText = barNumber .. "|TInterface\\LFGFRAME\\UI-LFG-ICON-ROLES:" .. (instance.row_info.height + sizeOffset)..":"..(instance.row_info.height + sizeOffset) .. ":0:0:256:256:" .. Details.role_texcoord [self.role or "NONE"] .. "|t " .. self.displayName
			if (usingCustomLeftText) then
				bar.lineText1:SetText(stringReplace(instance.row_info.textL_custom_text, bar.colocacao, self.displayName, "|TInterface\\LFGFRAME\\UI-LFG-ICON-ROLES:" .. (instance.row_info.height + sizeOffset)..":"..(instance.row_info.height + sizeOffset) .. ":0:0:256:256:" .. Details.role_texcoord [self.role or "NONE"] .. "|t ", self, instance.showing, instance, leftText))
			else
				bar.lineText1:SetText(leftText)
			end
		else
			local leftText = barNumber .. self.displayName
			if (usingCustomLeftText) then
				bar.lineText1:SetText(stringReplace(instance.row_info.textL_custom_text, bar.colocacao, self.displayName, "", self, instance.showing, instance, leftText))
			else
				bar.lineText1:SetText(leftText) --seta o texto da esqueda
			end
		end
	end

	setLineTextSize (bar, instance)
end

function Details:SetBarColors(bar, instance, r, g, b, a) --[[exported]] --~colors
	a = a or 1

	local bUseClassColor = instance.row_info.texture_class_colors

	if (self.customColor) then
		bar.textura:SetVertexColor(r, g, b, a)

	elseif (bUseClassColor) then
		if (self.classe == "UNGROUPPLAYER") then
			if (self.spec) then
				local specId, specName, specDescription, specIcon, specRole, specClass = DetailsFramework.GetSpecializationInfoByID(self.spec)
				if (specClass) then
					self.classe = specClass
				end
			end
		end
		bar.textura:SetVertexColor(r, g, b, a)
	else
		r, g, b, a = unpack(instance.row_info.fixed_texture_color)
		bar.textura:SetVertexColor(r, g, b, a)
	end

	if (instance.row_info.texture_background_class_color) then
		bar.background:SetVertexColor(r, g, b, a)
	end

	if (instance.row_info.textL_class_colors) then
		local textColor_Red, textColor_Green, textColor_Blue = self:GetTextColor(instance, "left")
		bar.lineText1:SetTextColor(textColor_Red, textColor_Green, textColor_Blue) --the r, g, b color passed are the color used on the bar, so if the bar is not using class color, the text is painted with the fixed color for the bar
	end

	if (instance.row_info.textR_class_colors) then
		local textColor_Red, textColor_Green, textColor_Blue = self:GetTextColor(instance, "right")
		bar.lineText2:SetTextColor(textColor_Red, textColor_Green, textColor_Blue)
		bar.lineText3:SetTextColor(textColor_Red, textColor_Green, textColor_Blue)
		bar.lineText4:SetTextColor(textColor_Red, textColor_Green, textColor_Blue)
	end

	if (instance.row_info.backdrop.use_class_colors) then
		--get the alpha from the border color
		local alpha = instance.row_info.backdrop.color[4]
		if (not bUseClassColor) then
			r, g, b = self:GetClassColor()
		end
		bar.lineBorder:SetVertexColor(r, g, b, alpha)
	end
end

---set the icon of the actor spec, class, pet, enemy, custom icom, spellicon, etc.
---@param self actor
---@param texture texture
---@param instance instance
---@param class string
function Details:SetClassIcon(texture, instance, class) --[[exported]] --~icons
	local customIcon
	if (Details.immersion_unit_special_icons) then
		customIcon = Details.Immersion.GetIcon(self.aID)
	end

	--set the size offset of the icon
	local iconSizeOffset = instance.row_info.icon_size_offset
	local iconSize = instance.row_info.height
	local newIconSize = iconSize + iconSizeOffset
	texture:SetSize(newIconSize, newIconSize)

	if (customIcon) then
		texture:SetTexture(customIcon[1])
		texture:SetTexCoord(unpack(customIcon[2]))
		texture:SetVertexColor(1, 1, 1)

	elseif (self.spellicon) then
		texture:SetTexture(self.spellicon)
		texture:SetTexCoord(0.078125, 0.921875, 0.078125, 0.921875)

	elseif (class == "UNKNOW") then
		texture:SetTexture([[Interface\AddOns\Details\images\classes_plus]])
		texture:SetTexCoord(0.50390625, 0.62890625, 0, 0.125)
		texture:SetVertexColor(1, 1, 1)

	elseif (class == "UNGROUPPLAYER") then
		if (self.spec) then
			if (instance and instance.row_info.use_spec_icons) then
				if (self.spec and Details.class_specs_coords[self.spec]) then
					texture:SetTexture(instance.row_info.spec_file)
					texture:SetTexCoord(unpack(Details.class_specs_coords[self.spec]))
					texture:SetVertexColor(1, 1, 1)
					return
				end
			end
		end

		local localizedClass, englishClass
		if (self.serial ~= "") then
			localizedClass, englishClass = GetPlayerInfoByGUID(self.serial)
		end

		if (englishClass) then
			texture:SetTexture(instance.row_info.icon_file or [[Interface\AddOns\Details\images\classes_small]])
			texture:SetTexCoord(unpack(Details.class_coords[englishClass]))
			texture:SetVertexColor(1, 1, 1)
			return
		end

		if (self.enemy) then
			if (Details.faction_against == "Horde") then
				texture:SetTexture("Interface\\ICONS\\Achievement_Character_Troll_Male")
				texture:SetTexCoord(0.05, 0.95, 0.05, 0.95)
			else
				texture:SetTexture("Interface\\ICONS\\Achievement_Character_Nightelf_Female")
				texture:SetTexCoord(0.05, 0.95, 0.05, 0.95)
			end
		else
			if (Details.faction_against == "Horde") then
				texture:SetTexture("Interface\\ICONS\\Achievement_Character_Nightelf_Female")
				texture:SetTexCoord(0.05, 0.95, 0.05, 0.95)
			else
				texture:SetTexture("Interface\\ICONS\\Achievement_Character_Troll_Male")
				texture:SetTexCoord(0.05, 0.95, 0.05, 0.95)
			end
		end

		texture:SetVertexColor(1, 1, 1)

	elseif (class == "PET") then
		texture:SetTexture(instance and instance.row_info.icon_file or [[Interface\AddOns\Details\images\classes_small]])
		texture:SetTexCoord(0.25, 0.49609375, 0.75, 1)
		classColor_Red, classColor_Green, classColor_Blue = DetailsFramework:ParseColors(classColor_Red, classColor_Green, classColor_Blue)
		texture:SetVertexColor(classColor_Red, classColor_Green, classColor_Blue)

	else
		if (instance and instance.row_info.use_spec_icons) then
			if (self.spec and Details.class_specs_coords[self.spec]) then
				texture:SetTexture(instance.row_info.spec_file)
				texture:SetTexCoord(unpack(Details.class_specs_coords[self.spec]))
				texture:SetVertexColor(1, 1, 1)
			else
				texture:SetTexture(instance.row_info.icon_file or [[Interface\AddOns\Details\images\classes_small]])
				texture:SetTexCoord(unpack(Details.class_coords[class]))
				texture:SetVertexColor(1, 1, 1)
			end
		else
			texture:SetTexture(instance and instance.row_info.icon_file or [[Interface\AddOns\Details\images\classes_small]])
			texture:SetTexCoord(unpack(Details.class_coords[class]))
			texture:SetVertexColor(1, 1, 1)
		end
	end
end


function Details:RefreshBarra(thisLine, instance, fromResize) --[[exported]]
	local class, enemy, arenaEnemy, arenaAlly = self.classe, self.enemy, self.arena_enemy, self.arena_ally

	if (not class) then
		Details:Msg("Warning, actor without a class:", self.nome, self.flag_original, self.serial)
		self.classe = "UNKNOW"
		class = "UNKNOW"
	end

	if (fromResize) then
		classColor_Red, classColor_Green, classColor_Blue = self:GetBarColor()
	end

	--icon
	self:SetClassIcon(thisLine.icone_classe, instance, class)

	if(thisLine.mouse_over) then
		local classIcon = thisLine:GetClassIcon()
		thisLine.iconHighlight:SetTexture(classIcon:GetTexture())
		thisLine.iconHighlight:SetTexCoord(classIcon:GetTexCoord())
		thisLine.iconHighlight:SetVertexColor(classIcon:GetVertexColor())
	end

	--texture color
	self:SetBarColors(thisLine, instance, classColor_Red, classColor_Green, classColor_Blue)

	--left text
	self:SetBarLeftText(thisLine, instance, enemy, arenaEnemy, arenaAlly, UsingCustomLeftText)
end

---comment
---@param self table extraStatusbar frame
function damageClass.PredictedAugSpellsOnEnter(self)
	if (Details.show_aug_predicted_spell_damage) then
		---@type spellcontainer
		local spellContainer = self.augmentedSpellsContainer

		GameCooltip:Preset(2)
		---@type instance
		local instanceObject = Details:GetInstance(self.instanceId)
		---@type combat
		local combatObject = instanceObject:GetCombat()

		for spellId, spellTable in spellContainer:ListSpells() do
			local spellName, _, spellTexture = GetSpellInfo(spellId)
			if (spellName) then
				GameCooltip:AddLine(spellName, Details:Format(spellTable.total))
				GameCooltip:AddIcon(spellTexture, 1, 1, 14, 14)

				local spellsAugmented = {}

				--the damage sources are added into the targets table for recycling
				---@type table<actorname, valueamount>
				local sources = spellTable.targets
				for sourceName, sourceAmount in pairs(sources) do
					spellsAugmented[#spellsAugmented+1] = {sourceName, sourceAmount}
				end

				table.sort(spellsAugmented, Details.Sort2)

				for i = 1, math.min(#spellsAugmented, 5) do
					local sourceName, sourceAmount = unpack(spellsAugmented[i])
					GameCooltip:AddLine(sourceName, Details:Format(sourceAmount), 1, "yellow", "yellow", 10)
					local actorObject = combatObject:GetActor(1, sourceName)
					if (actorObject) then
						local actorIcon = Details:GetActorIcon(actorObject)
						if (actorIcon) then
							GameCooltip:AddIcon(actorIcon.texture, 1, 1, 14, 14, actorIcon.coords.left, actorIcon.coords.right, actorIcon.coords.top, actorIcon.coords.bottom)
						else
							GameCooltip:AddIcon([[Interface\COMMON\Indicator-Gray]], 1, 1, 14, 14)
						end
					end
				end

				GameCooltip:AddLine(" ")
				GameCooltip:AddIcon("", 1, 1, 5, 5)
			end
		end
	else
		---@type instance
		local instanceObject = Details:GetInstance(self.instanceId)
		---@type combat
		local combatObject = instanceObject:GetCombat()

		local combatTime = combatObject:GetCombatTime()

		---@type actorname
		local actorName = self.actorName

		---@type actorcontainer
		local utilityContainer = combatObject:GetContainer(DETAILS_ATTRIBUTE_MISC)

		---@type table<spellid, table<spellid, number, actorname, actorname, class, boolean>>
		local buffUptimeTable = {}

		local CONST_SPELLID_EBONMIGHT = 395152
		local CONST_SPELLID_PRESCIENCE = 410089
		local CONST_SPELLID_BLACKATTUNEMENT = 403264
		local CONST_SPELLID_BLISTERING_SCALES = 360827

		---@type actor[]
		local augmentationEvokers = {}

		--prescience and ebon might updatime on each actor
		for _, actorObject in utilityContainer:ListActors() do
			---@type spellcontainer
			local receivedBuffs = actorObject.received_buffs_spells

			--check if the actor is an augmentation evoker
			if (actorObject.spec == 1473) then
				augmentationEvokers[#augmentationEvokers+1] = actorObject
			end

			if (receivedBuffs and actorObject:IsPlayer() and actorObject:IsGroupPlayer()) then
				for sourceNameSpellId, spellTable in receivedBuffs:ListSpells() do
					local sourceName, spellId = strsplit("@", sourceNameSpellId)
					if (sourceName == actorName) then
						spellId = tonumber(spellId)
						local spellName, _, spellIcon = Details.GetSpellInfo(spellId)

						if (spellName and spellId) then
							sourceName = detailsFramework:RemoveRealmName(sourceName)
							local targetName = actorObject:Name()
							targetName = detailsFramework:RemoveRealmName(targetName)

							local uptime = spellTable.uptime or 0
							local bCanShowOnTooltip = true
							buffUptimeTable[spellId] = buffUptimeTable[spellId] or {}
							table.insert(buffUptimeTable[spellId], {spellId, uptime, sourceName, targetName, actorObject:Class(), bCanShowOnTooltip})
						end
					end
				end
			end
		end

		for spellId, buffTable in pairs(buffUptimeTable) do
			local totalUptime = 0
			for i = 1, #buffTable do
				totalUptime = totalUptime + buffTable[i][2]
			end
			table.sort(buffTable, Details.Sort2)
		end

		Details:FormatCooltipForSpells()
		Details:AddTooltipSpellHeaderText(Loc ["STRING_SPELLS"], headerColor, #buffUptimeTable, Details.tooltip_spell_icon.file, unpack(Details.tooltip_spell_icon.coords))
		Details:AddTooltipHeaderStatusbar(.1, .1, .1, 0.834)

		local iconSize = 22
		local iconBorderInfo = Details.tooltip.icon_border_texcoord

		--add the total combat time into the tooltip
		local combatTimeMinutes, combatTimeSeconds = math.floor(combatTime / 60), math.floor(combatTime % 60)
		GameCooltip:AddLine("Combat Time", combatTimeMinutes .. "m " .. combatTimeSeconds .. "s" .. " (" .. format("%.1f", 100) .. "%)")
		GameCooltip:AddIcon([[Interface\TARGETINGFRAME\UnitFrameIcons]], nil, nil, iconSize, iconSize, iconBorderInfo.L, iconBorderInfo.R, iconBorderInfo.T, iconBorderInfo.B)
		Details:AddTooltipBackgroundStatusbar(false, 100, true, "darkgreen")

		GameCooltip:AddLine("", "")
		GameCooltip:AddIcon("", nil, nil, 1, 1)

		local ebonMightTable = buffUptimeTable[CONST_SPELLID_EBONMIGHT][1]
		if (ebonMightTable) then
			local uptime = ebonMightTable[2]
			local spellName, _, spellIcon = _GetSpellInfo(CONST_SPELLID_EBONMIGHT)
			local uptimePercent = uptime / combatTime * 100
			local sourceName = ebonMightTable[3]

			if (uptime <= combatTime) then
				local minutes, seconds = math.floor(uptime / 60), math.floor(uptime % 60)
				if (minutes > 0) then
					GameCooltip:AddLine(spellName, minutes .. "m " .. seconds .. "s" .. " (" .. format("%.1f", uptimePercent) .. "%)")
					Details:AddTooltipBackgroundStatusbar(false, uptimePercent, true, sourceName and "darkgreen")
				else
					GameCooltip:AddLine(spellName, seconds .. "s" .. " (" .. format("%.1f", uptimePercent) .. "%)")
					Details:AddTooltipBackgroundStatusbar(false, uptimePercent, true, sourceName and "darkgreen")
				end

				GameCooltip:AddIcon(spellIcon, nil, nil, iconSize, iconSize, iconBorderInfo.L, iconBorderInfo.R, iconBorderInfo.T, iconBorderInfo.B)
			end
		end

		GameCooltip:AddLine("", "")
		GameCooltip:AddIcon("", nil, nil, 1, 1)

		for i = 1, #augmentationEvokers do --black attunement
			local actorObject = augmentationEvokers[i]
			if (actorObject:Name() == actorName) then
				local buffUptimeSpellContainer = actorObject:GetSpellContainer("buff")
				if (buffUptimeSpellContainer) then
					local spellTable = buffUptimeSpellContainer:GetSpell(403264)
					if (spellTable) then
						local uptime = spellTable.uptime
						local spellName, _, spellIcon = _GetSpellInfo(CONST_SPELLID_BLACKATTUNEMENT)
						local uptimePercent = uptime / combatTime * 100

						if (uptime <= combatTime) then
							local minutes, seconds = math.floor(uptime / 60), math.floor(uptime % 60)
							if (minutes > 0) then
								GameCooltip:AddLine(spellName, minutes .. "m " .. seconds .. "s" .. " (" .. format("%.1f", uptimePercent) .. "%)")
								Details:AddTooltipBackgroundStatusbar(false, uptimePercent, true, "darkgreen")
							else
								GameCooltip:AddLine(spellName, seconds .. "s" .. " (" .. format("%.1f", uptimePercent) .. "%)")
								Details:AddTooltipBackgroundStatusbar(false, uptimePercent, true, "darkgreen")
							end

							GameCooltip:AddIcon(spellIcon, nil, nil, iconSize, iconSize, iconBorderInfo.L, iconBorderInfo.R, iconBorderInfo.T, iconBorderInfo.B)
						end
					end

					local spellTable = buffUptimeSpellContainer:GetSpell(CONST_SPELLID_BLISTERING_SCALES)
					if (spellTable) then
						local uptime = spellTable.uptime
						local spellName, _, spellIcon = _GetSpellInfo(CONST_SPELLID_BLISTERING_SCALES)
						local uptimePercent = uptime / combatTime * 100

						if (uptime <= combatTime) then
							local minutes, seconds = math.floor(uptime / 60), math.floor(uptime % 60)
							if (minutes > 0) then
								GameCooltip:AddLine(spellName, minutes .. "m " .. seconds .. "s" .. " (" .. format("%.1f", uptimePercent) .. "%)")
								Details:AddTooltipBackgroundStatusbar(false, uptimePercent, true, "darkgreen")
							else
								GameCooltip:AddLine(spellName, seconds .. "s" .. " (" .. format("%.1f", uptimePercent) .. "%)")
								Details:AddTooltipBackgroundStatusbar(false, uptimePercent, true, "darkgreen")
							end

							GameCooltip:AddIcon(spellIcon, nil, nil, iconSize, iconSize, iconBorderInfo.L, iconBorderInfo.R, iconBorderInfo.T, iconBorderInfo.B)
						end
					end
				end
			end
		end

		GameCooltip:AddLine("", "")
		GameCooltip:AddIcon("", nil, nil, 1, 1)

		--add the buff uptime into the tooltip
		local allPrescienceTargets = buffUptimeTable[CONST_SPELLID_PRESCIENCE]
		if (allPrescienceTargets and #allPrescienceTargets > 0) then
			for i = 1, math.min(30, #allPrescienceTargets) do
				local uptimeTable = allPrescienceTargets[i]

				local spellId = uptimeTable[1]
				local uptime = uptimeTable[2]
				local sourceName = uptimeTable[3]
				local targetName = uptimeTable[4]
				local targetClass = uptimeTable[5]
				local bCanShow = uptimeTable[6]

				local uptimePercent = uptime / combatTime * 100

				if (uptime > 0 and uptimePercent < 99.5 and bCanShow) then
					local spellName, _, spellIcon = _GetSpellInfo(spellId)

					if (sourceName) then
						targetName = detailsFramework:AddClassColorToText(targetName, targetClass)
						targetName = detailsFramework:AddClassIconToText(targetName, targetName, targetClass)
						spellName = spellName .. " [" .. targetName .. "]"
					end

					if (uptime <= combatTime) then
						local minutes, seconds = math.floor(uptime / 60), math.floor(uptime % 60)
						if (minutes > 0) then
							GameCooltip:AddLine(spellName, minutes .. "m " .. seconds .. "s" .. " (" .. format("%.1f", uptimePercent) .. "%)")
							Details:AddTooltipBackgroundStatusbar(false, uptimePercent, true, sourceName and "darkgreen")
						else
							GameCooltip:AddLine(spellName, seconds .. "s" .. " (" .. format("%.1f", uptimePercent) .. "%)")
							Details:AddTooltipBackgroundStatusbar(false, uptimePercent, true, sourceName and "darkgreen")
						end

						GameCooltip:AddIcon(spellIcon, nil, nil, iconSize, iconSize, iconBorderInfo.L, iconBorderInfo.R, iconBorderInfo.T, iconBorderInfo.B)
					end
				end
			end
		else
			GameCooltip:AddLine(Loc ["STRING_NO_SPELL"])
		end

		local evokerObject = combatObject:GetActor(DETAILS_ATTRIBUTE_MISC, actorName)

		GameCooltip:AddLine(" ")
		GameCooltip:AddIcon(" ", 1, 1, 10, 10)

		if (evokerObject) then
			GameCooltip:AddLine("Prescience Uptime by Amount of Applications")
			local prescienceData = evokerObject.cleu_prescience_time

			if (prescienceData) then
				prescienceData = prescienceData.stackTime
				local totalTimeWithPrescienceUp = 0

				for amountOfPrescienceApplied, time in ipairs(prescienceData) do
					totalTimeWithPrescienceUp = totalTimeWithPrescienceUp + time
				end

				for amountOfPrescienceApplied, time in ipairs(prescienceData) do
					if (time > 0) then
						local uptimePercent = time / combatTime * 100
						local timeString = detailsFramework:IntegerToTimer(time)
						GameCooltip:AddLine("Presciece Applied: " .. amountOfPrescienceApplied, timeString .. " (" .. format("%.1f", uptimePercent) .. "%)")
						--5199639 prescience icon
						GameCooltip:AddIcon([[Interface\AddOns\Details\images\spells\prescience_time]], nil, nil, iconSize, iconSize)
						Details:AddTooltipBackgroundStatusbar(false, time/totalTimeWithPrescienceUp*100, true, "green")
					end
				end
			end
		end

		--iterate among all the actors and find which one are healers, then get the amount of mana the evoker restored for that healer
		---@type actorcontainer
		local resourcesContainer = combatObject:GetContainer(DETAILS_ATTRIBUTE_ENERGY)
		local manaRestoredToHealers = {}

		for index, actorObject in resourcesContainer:ListActors() do
			if (actorObject.spec == 1473) then --this is an aug evoker
				local spellContainer = actorObject:GetSpellContainer("spell")
				--local spellContainer = actorObject.spells
				if (spellContainer) then
					local sourceOfMagic = spellContainer:GetSpell(372571)
					if (sourceOfMagic) then
						for targetName, restoredAmount in pairs(sourceOfMagic.targets) do
							manaRestoredToHealers[#manaRestoredToHealers+1] = {targetName, restoredAmount}
						end
					end
				end
			end
		end

		if (#manaRestoredToHealers > 0) then
			GameCooltip:AddLine(" ")
			GameCooltip:AddIcon(" ", 1, 1, 10, 10)
			GameCooltip:AddLine("Mana Restored to Healers:")

			table.sort(manaRestoredToHealers, Details.Sort2)

			for i = 1, math.min(10, #manaRestoredToHealers) do
				local targetName, restoredAmount = unpack(manaRestoredToHealers[i])
				local targetActorObject = combatObject(DETAILS_ATTRIBUTE_ENERGY, targetName)

				if (targetActorObject) then
					local targetClass = targetActorObject:GetActorClass()
					local targetName = detailsFramework:AddClassColorToText(targetName, targetClass)
					targetName = detailsFramework:AddClassIconToText(targetName, targetName, targetClass)

					GameCooltip:AddLine(targetName, Details:Format(restoredAmount))

					local spellIcon = GetSpellTexture(372571)
					GameCooltip:AddIcon(spellIcon, nil, nil, iconSize, iconSize, iconBorderInfo.L, iconBorderInfo.R, iconBorderInfo.T, iconBorderInfo.B)
					Details:AddTooltipBackgroundStatusbar(false, 100, true, "dodgerblue")
				end
			end
		end
	end

	GameCooltip:AddLine("feature under test, can't disable atm")
	GameCooltip:AddIcon([[Interface\BUTTONS\UI-GROUPLOOT-PASS-DOWN]], nil, nil, 16, 16)

	--GameCooltip:SetOption("LeftBorderSize", -5)
	--GameCooltip:SetOption("RightBorderSize", 5)
	--GameCooltip:SetOption("RightTextMargin", 0)
	GameCooltip:SetOption("VerticalOffset", 0)
	--GameCooltip:SetOption("AlignAsBlizzTooltip", true)
	GameCooltip:SetOption("AlignAsBlizzTooltipFrameHeightOffset", 0)
	GameCooltip:SetOption("LineHeightSizeOffset", 0)
	GameCooltip:SetOption("VerticalPadding", 0)

	GameCooltip:ShowCooltip(self, "tooltip")
end

function damageClass.PredictedAugSpellsOnLeave(self)
	GameCooltip:Hide()
	--extraStatusbar.defaultAlpha
end

--------------------------------------------- // TOOLTIPS // ---------------------------------------------

---------TOOLTIPS BIFURCA��O
-- ~tooltip
function damageClass:ToolTip (instance, numero, barra, keydown)
	--seria possivel aqui colocar o icone da classe dele?

	if (instance.atributo == 5) then --custom
		return self:TooltipForCustom(barra)
	else
		if (instance.sub_atributo == 1 or instance.sub_atributo == 2) then --damage done or Dps or enemy
			return self:ToolTip_DamageDone(instance, numero, barra, keydown)

		elseif (instance.sub_atributo == 3) then --damage taken
			return self:ToolTip_DamageTaken(instance, numero, barra, keydown)

		elseif (instance.sub_atributo == 6) then --enemies
			return self:ToolTip_Enemies(instance, numero, barra, keydown)

		elseif (instance.sub_atributo == 4) then --friendly fire
			return self:ToolTip_FriendlyFire(instance, numero, barra, keydown)
		end
	end
end

--tooltip locals
local r, g, b
local barAlha = .6

---------DAMAGE DONE & DPS

function damageClass:ToolTip_DamageDone (instancia, numero, barra, keydown)
	local owner = self.owner
	if (owner and owner.classe) then
		r, g, b = unpack(Details.class_colors [owner.classe])
	else
		if (not Details.class_colors [self.classe]) then
			return print("Details!: error class not found:", self.classe, "for", self.nome)
		end
		r, g, b = unpack(Details.class_colors [self.classe])
	end

	local combatObject = instancia:GetShowingCombat()

	--habilidades
	local icon_size = Details.tooltip.icon_size
	local icon_border = Details.tooltip.icon_border_texcoord

	do
		--TOP HABILIDADES

			--get variables
			--local ActorDamage = self.total_without_pet --mostrando os pets no tooltip
			local ActorDamage = self.total
			local ActorDamageWithPet = self.total
			if (ActorDamage == 0) then
				ActorDamage = 0.00000001
			end

			local ActorSkillsContainer = self.spells._ActorTable
			local ActorSkillsSortTable = {}

			local reflectionSpells = {}

			--get time type
			local meu_tempo
			if (Details.time_type == 1 or not self.grupo) then
				meu_tempo = self:Tempo()
			elseif (Details.time_type == 2 or Details.use_realtimedps) then
				meu_tempo = instancia.showing:GetCombatTime()
			end

			--add actor spells
			for _spellid, _skill in pairs(ActorSkillsContainer) do
				ActorSkillsSortTable [#ActorSkillsSortTable+1] = {_spellid, _skill.total, _skill.total/meu_tempo}
				if (_skill.isReflection) then
					reflectionSpells[#reflectionSpells+1] = _skill
				end
			end

			--add actor pets
			for petIndex, petName in ipairs(self:Pets()) do
				local petActor = instancia.showing[class_type]:PegarCombatente (nil, petName)
				if (petActor) then
					for _spellid, _skill in pairs(petActor:GetActorSpells()) do
						ActorSkillsSortTable [#ActorSkillsSortTable+1] = {_spellid, _skill.total, _skill.total/meu_tempo, petName:gsub((" <.*"), "")}
					end
				end
			end
			--sort
			table.sort(ActorSkillsSortTable, Details.Sort2)

		--TOP INIMIGOS
			--get variables
			local ActorTargetsSortTable = {}

			--add
			for targetName, amount in pairs(self.targets) do
				local targetActorObject = combatObject(DETAILS_ATTRIBUTE_DAMAGE, targetName)
				local npcId = targetActorObject and targetActorObject.aID
				npcId = tonumber(npcId or 0)
				ActorTargetsSortTable[#ActorTargetsSortTable+1] = {targetName, amount, npcId}
			end
			--sort
			table.sort(ActorTargetsSortTable, Details.Sort2)

			--tooltip stuff
			local tooltip_max_abilities = Details.tooltip.tooltip_max_abilities

			local is_maximized = false
			if (keydown == "shift" or TooltipMaximizedMethod == 2 or TooltipMaximizedMethod == 3) then
				tooltip_max_abilities = 99
				is_maximized = true
			end

		--MOSTRA HABILIDADES
			--Details:AddTooltipSpellHeaderText (Loc ["STRING_SPELLS"], headerColor, #ActorSkillsSortTable, Details.tooltip_spell_icon.file, unpack(Details.tooltip_spell_icon.coords))

			if (is_maximized) then
				--highlight shift key
				--GameCooltip:AddIcon ([[Interface\AddOns\Details\images\key_shift]], 1, 2, Details.tooltip_key_size_width, Details.tooltip_key_size_height, 0, 1, 0, 0.640625, Details.tooltip_key_overlay2)
				--Details:AddTooltipHeaderStatusbar (r, g, b, 1)
			else
				--GameCooltip:AddIcon ([[Interface\AddOns\Details\images\key_shift]], 1, 2, Details.tooltip_key_size_width, Details.tooltip_key_size_height, 0, 1, 0, 0.640625, Details.tooltip_key_overlay1)
				--Details:AddTooltipHeaderStatusbar (r, g, b, barAlha)
			end

			GameCooltip:SetOption("AlignAsBlizzTooltip", false)
			GameCooltip:SetOption("YSpacingMod", -6)
			local iconSize = Details.DefaultTooltipIconSize

			local topAbility = ActorSkillsSortTable [1] and ActorSkillsSortTable [1][2] or 0.0001

			if (#ActorSkillsSortTable > 0) then
				for i = 1, _math_min(tooltip_max_abilities, #ActorSkillsSortTable) do

					local SkillTable = ActorSkillsSortTable [i]

					local spellID = SkillTable [1]
					local totalDamage = SkillTable [2]
					local totalDPS = SkillTable [3]
					local petName = SkillTable [4]

					local nome_magia, _, icone_magia = _GetSpellInfo(spellID)
					if (petName) then
						if (not nome_magia) then
							spellID = spellID or "spellId?"
							nome_magia = "|cffffaa00" .. spellID .. " " .. " (|cFFCCBBBB" .. petName .. "|r)"
						else
							nome_magia = nome_magia .. " (|cFFCCBBBB" .. petName .. "|r)"
						end
					end

					local percent = format("%.1f", totalDamage/ActorDamage*100)
					if (string.len(percent) < 4) then
						percent = percent  .. "0"
					end

					if (instancia.sub_atributo == 1 or instancia.sub_atributo == 6) then
						GameCooltip:AddLine(nome_magia, FormatTooltipNumber (_, totalDamage) .."   ("..percent.."%)")
					else
						GameCooltip:AddLine(nome_magia, FormatTooltipNumber (_, _math_floor(totalDPS)) .."   ("..percent.."%)")
					end

					GameCooltip:AddIcon (icone_magia, nil, nil, iconSize, iconSize, icon_border.L, icon_border.R, icon_border.T, icon_border.B)
					Details:AddTooltipBackgroundStatusbar (false, totalDamage/topAbility*100)
				end
			else
				GameCooltip:AddLine(Loc ["STRING_NO_SPELL"])
			end

		--spell reflected
			if (#reflectionSpells > 0) then
				--small blank space
				Details:AddTooltipSpellHeaderText ("", headerColor, 1, false, 0.1, 0.9, 0.1, 0.9, true) --add a space
				Details:AddTooltipSpellHeaderText ("Spells Reflected", headerColor, 1, select(3, _GetSpellInfo(reflectionSpells[1].id)), 0.1, 0.9, 0.1, 0.9) --localize-me
				Details:AddTooltipHeaderStatusbar (r, g, b, barAlha)

				for i = 1, #reflectionSpells do
					local _spell = reflectionSpells[i]
					local extraInfo = _spell.extra
					for spellId, damageDone in pairs(extraInfo) do
						local spellName, _, spellIcon = _GetSpellInfo(spellId)

						if (spellName) then
							GameCooltip:AddLine(spellName, FormatTooltipNumber (_, damageDone) .. " (" .. _math_floor(damageDone / self.total * 100) .. "%)")
							Details:AddTooltipBackgroundStatusbar (false, damageDone / self.total * 100)
							GameCooltip:AddIcon (spellIcon, 1, 1, iconSize, iconSize, 0.1, 0.9, 0.1, 0.9)
						end
					end
				end
			end

		--targets (enemies)
			local topEnemy = ActorTargetsSortTable[1] and ActorTargetsSortTable[1][2] or 0
			if (instancia.sub_atributo == 1 or instancia.sub_atributo == 6) then
				--small blank space
				Details:AddTooltipSpellHeaderText("", headerColor, 1, false, 0.1, 0.9, 0.1, 0.9, true)

				Details:AddTooltipSpellHeaderText(Loc ["STRING_TARGETS"], headerColor, #ActorTargetsSortTable, [[Interface\Addons\Details\images\icons]], 0, 0.03125, 0.126953125, 0.15625)

				local max_targets = Details.tooltip.tooltip_max_targets
				local is_maximized = false
				if (keydown == "ctrl" or TooltipMaximizedMethod == 2 or TooltipMaximizedMethod == 4) then
					max_targets = 99
					is_maximized = true
				end

				if (is_maximized) then
					--highlight
					GameCooltip:AddIcon([[Interface\AddOns\Details\images\key_ctrl]], 1, 2, Details.tooltip_key_size_width, Details.tooltip_key_size_height, 0, 1, 0, 0.640625, Details.tooltip_key_overlay2)
					Details:AddTooltipHeaderStatusbar(r, g, b, 1)
				else
					GameCooltip:AddIcon([[Interface\AddOns\Details\images\key_ctrl]], 1, 2, Details.tooltip_key_size_width, Details.tooltip_key_size_height, 0, 1, 0, 0.640625, Details.tooltip_key_overlay1)
					Details:AddTooltipHeaderStatusbar(r, g, b, barAlha)
				end

				for i = 1, math.min(max_targets, #ActorTargetsSortTable) do
					local enemyTable = ActorTargetsSortTable[i]
					GameCooltip:AddLine(enemyTable[1], FormatTooltipNumber(_, enemyTable[2]) .." ("..format("%.1f", enemyTable[2] / ActorDamageWithPet * 100).."%)")

					local portraitTexture-- = Details222.Textures.GetPortraitTextureForNpcID(enemyTable[3]) --disabled atm
					if (portraitTexture) then
						GameCooltip:AddIcon(portraitTexture, 1, 1, icon_size.W, icon_size.H)
					else
						GameCooltip:AddIcon([[Interface\PetBattles\PetBattle-StatIcons]], nil, nil, icon_size.W, icon_size.H, 0, 0.5, 0, 0.5, {.7, .7, .7, 1}, nil, true)
					end

					Details:AddTooltipBackgroundStatusbar(false, enemyTable[2] / topEnemy * 100)
				end
			end
	end

	--PETS
	local instance = instancia
	local combatObject = instance:GetShowingCombat()

	local myPets = self.pets
	if (#myPets > 0) then --teve ajudantes
		local petAmountWithSameName = {} --armazena a quantidade de pets iguais
		local petDamageTable = {} --armazena o dano total de cada objeto

		--small blank space
		Details:AddTooltipSpellHeaderText("", headerColor, 1, false, 0.1, 0.9, 0.1, 0.9, true)

		for index, petName in ipairs(myPets) do
			if (not petAmountWithSameName[petName]) then
				petAmountWithSameName[petName] = 1
				local damageContainer = combatObject:GetContainer(DETAILS_ATTRIBUTE_DAMAGE)
				local petActorObject = damageContainer:GetActor(petName)

				if (petActorObject) then
					local petDamageDone = petActorObject.total_without_pet
					local petSpells = petActorObject:GetSpellList()
					local petSpellsSorted = {}

					--local timeInCombat = petActorObject:GetTimeInCombat(self)
					local timeInCombat = 0
					if (Details.time_type == 1 or not self.grupo) then
						timeInCombat = petActorObject:Tempo()
					elseif (Details.time_type == 2 or Details.use_realtimedps) then
						timeInCombat = petActorObject:GetCombatTime()
					end

					petDamageTable[#petDamageTable+1] = {petName, petActorObject.total_without_pet, petActorObject.total_without_pet / timeInCombat}

					for spellId, spellTable in pairs(petSpells) do
						local spellName, rank, spellIcon = _GetSpellInfo(spellId)
						tinsert(petSpellsSorted, {spellId, spellTable.total, spellTable.total / petDamageDone * 100, {spellName, rank, spellIcon}})
					end

					table.sort(petSpellsSorted, Details.Sort2)

					local petTargets = {}
					petSpells = petActorObject.targets
					for targetName, spellDamageDone in pairs(petSpells) do
						tinsert(petTargets, {targetName, spellDamageDone, spellDamageDone / petDamageDone * 100})
					end
					table.sort(petTargets,Details.Sort2)
				end
			else
				petAmountWithSameName[petName] = petAmountWithSameName[petName] + 1
			end
		end

		local petHeaderAdded = false

		table.sort(petDamageTable, Details.Sort2)

		local ismaximized = false
		if (keydown == "alt" or TooltipMaximizedMethod == 2 or TooltipMaximizedMethod == 5) then
			ismaximized = true
		end

		local topPetDamageDone = petDamageTable[1] and petDamageTable[1][2] or 0

		for index, damageTable in ipairs(petDamageTable) do
			if (damageTable [2] > 0 and (index <= Details.tooltip.tooltip_max_pets or ismaximized)) then
				if (not petHeaderAdded) then
					petHeaderAdded = true
					Details:AddTooltipSpellHeaderText(Loc ["STRING_PETS"], headerColor, #petDamageTable, [[Interface\COMMON\friendship-heart]], 0.21875, 0.78125, 0.09375, 0.6875)

					if (ismaximized) then
						GameCooltip:AddIcon ([[Interface\AddOns\Details\images\key_alt]], 1, 2, Details.tooltip_key_size_width, Details.tooltip_key_size_height, 0, 1, 0, 0.640625, Details.tooltip_key_overlay2)
						Details:AddTooltipHeaderStatusbar(r, g, b, 1)
					else
						GameCooltip:AddIcon ([[Interface\AddOns\Details\images\key_alt]], 1, 2, Details.tooltip_key_size_width, Details.tooltip_key_size_height, 0, 1, 0, 0.640625, Details.tooltip_key_overlay1)
						Details:AddTooltipHeaderStatusbar(r, g, b, barAlha)
					end
				end

				local petName = damageTable[1]
				local petDamageDone = damageTable[2]
				local petDPS = damageTable[3]

				petName = damageTable[1]:gsub(("%s%<.*"), "")
				if (instancia.sub_atributo == 1) then
					GameCooltip:AddLine(petName, FormatTooltipNumber(_, petDamageDone) .. " (" .. math.floor(petDamageDone/self.total*100) .. "%)")
				else
					GameCooltip:AddLine(petName, FormatTooltipNumber(_, math.floor(petDPS)) .. " (" .. math.floor(petDamageDone/self.total*100) .. "%)")
				end

				Details:AddTooltipBackgroundStatusbar(false, petDamageDone / topPetDamageDone * 100)

				GameCooltip:AddIcon([[Interface\AddOns\Details\images\classes_small_alpha]], 1, 1, icon_size.W, icon_size.H, 0.25/2, 0.49609375/2, 0.75/2, 1/2)
			end
		end
	end

	--~Phases
	local segment = instancia:GetShowingCombat()
	if (segment and self.grupo) then
		local bossInfo = segment:GetBossInfo()
		local phasesInfo = segment:GetPhases()
		if (bossInfo and phasesInfo) then
			if (#phasesInfo > 1) then

				--small blank space
				Details:AddTooltipSpellHeaderText ("", headerColor, 1, false, 0.1, 0.9, 0.1, 0.9, true)

				Details:AddTooltipSpellHeaderText ("Damage by Encounter Phase", headerColor, 1, [[Interface\Garrison\orderhall-missions-mechanic8]], 11/64, 53/64, 11/64, 53/64) --localize-me
				Details:AddTooltipHeaderStatusbar (r, g, b, barAlha)

				local playerPhases = {}
				local totalDamage = 0

				for phase, playersTable in pairs(phasesInfo.damage) do --each phase

					local allPlayers = {} --all players for this phase
					for playerName, amount in pairs(playersTable) do
						tinsert(allPlayers, {playerName, amount})
						totalDamage = totalDamage + amount
					end
					table.sort (allPlayers, function(a, b) return a[2] > b[2] end)

					local myRank = 0
					for i = 1, #allPlayers do
						if (allPlayers [i] [1] == self.nome) then
							myRank = i
							break
						end
					end

					tinsert(playerPhases, {phase, playersTable [self.nome] or 0, myRank, (playersTable [self.nome] or 0) / totalDamage * 100})
				end

				table.sort (playerPhases, function(a, b) return a[1] < b[1] end)

				for i = 1, #playerPhases do
					--[1] Phase Number [2] Amount Done [3] Rank [4] Percent
					GameCooltip:AddLine("|cFFF0F0F0Phase|r " .. playerPhases [i][1], FormatTooltipNumber (_, playerPhases [i][2]) .. " (|cFFFFFF00#" .. playerPhases [i][3] ..  "|r, " .. format("%.1f", playerPhases [i][4]) .. "%)")
					GameCooltip:AddIcon ([[Interface\Garrison\orderhall-missions-mechanic9]], 1, 1, 14, 14, 11/64, 53/64, 11/64, 53/64)
					Details:AddTooltipBackgroundStatusbar()
				end
			end
		end
	end

	return true
end

local on_switch_show_enemies = function(instance)
	instance:TrocaTabela(instance, true, 1, 6)
	return true
end

local on_switch_show_frags = function(instance)
	instance:TrocaTabela(instance, true, 1, 5)
	return true
end

local ENEMIES_format_name = function(player) if (player == 0) then return false end return Details:GetOnlyName(player.nome) end
local ENEMIES_format_amount = function(amount) if (amount <= 0) then return false end return Details:ToK(amount) .. " (" .. format("%.1f", amount / tooltip_temp_table.damage_total * 100) .. "%)" end

function damageClass:ReportEnemyDamageTaken (actor, instance, ShiftKeyDown, ControlKeyDown, fromFrags)

	--can open the breakdown window now
	--this function is deprecated

	if (ShiftKeyDown) then
		local inimigo = actor.nome
		local custom_name = inimigo .. " -" .. Loc ["STRING_CUSTOM_ENEMY_DT"]

		--procura se j� tem um custom:
		for index, CustomObject in ipairs(Details.custom) do
			if (CustomObject:GetName() == custom_name) then
				--fix for not saving funcs on logout
				if (not CustomObject.OnSwitchShow) then
					CustomObject.OnSwitchShow = fromFrags and on_switch_show_frags or on_switch_show_enemies
				end
				return instance:TrocaTabela(instance.segmento, 5, index)
			end
		end

		--criar um custom para este actor.
		local new_custom_object = {
			name = custom_name,
			icon = [[Interface\ICONS\Pet_Type_Undead]],
			attribute = "damagedone",
			author = Details.playername,
			desc = inimigo .. " Damage Taken",
			source = "[raid]",
			target = inimigo,
			script = false,
			tooltip = false,
			temp = true,
			OnSwitchShow = fromFrags and on_switch_show_frags or on_switch_show_enemies,
		}

		tinsert(Details.custom, new_custom_object)
		setmetatable(new_custom_object, Details.atributo_custom)
		new_custom_object.__index = Details.atributo_custom

		return instance:TrocaTabela(instance.segmento, 5, #Details.custom)
	end

	if (true) then return end

	local report_table = {"Details!: " .. actor.nome .. " - " .. Loc ["STRING_ATTRIBUTE_DAMAGE_TAKEN"]}

	Details:FormatReportLines (report_table, tooltip_temp_table, ENEMIES_format_name, ENEMIES_format_amount)

	return Details:Reportar (report_table, {_no_current = true, _no_inverse = true, _custom = true})
end

local FRAGS_format_name = function(player_name) return Details:GetOnlyName(player_name) end
local FRAGS_format_amount = function(amount) return Details:ToK(amount) .. " (" .. format("%.1f", amount / frags_tooltip_table.damage_total * 100) .. "%)" end

function damageClass:ReportSingleFragsLine (frag, instance, ShiftKeyDown, ControlKeyDown)
	if (not frags_tooltip_table) then --some cases a friendly object is getting threat as neutral, example is Druid's Efflorescense
		return
	end

	if (ShiftKeyDown) then
		return damageClass:ReportEnemyDamageTaken (frag, instance, ShiftKeyDown, ControlKeyDown, true)
	end

	local report_table = {"Details!: " .. frag [1] .. " - " .. Loc ["STRING_ATTRIBUTE_DAMAGE_TAKEN"]}

	Details:FormatReportLines (report_table, frags_tooltip_table, FRAGS_format_name, FRAGS_format_amount)

	return Details:Reportar (report_table, {_no_current = true, _no_inverse = true, _custom = true})
end

---@param self actor
---@param instanceObject instance
function damageClass:ToolTip_Enemies(instanceObject, numero, barra, keydown)
	--check if the actor has an owner, if it does, it's a pet
	local ownerObject = self.owner
	if (ownerObject and ownerObject.classe) then
		r, g, b = unpack(Details.class_colors[ownerObject.classe])
	else
		r, g, b = unpack(Details.class_colors[self.classe])
	end

	local combatObject = instanceObject:GetCombat()
	local enemyName = self:Name()

	Details:Destroy(tooltip_temp_table) --fix for translit bug report, 'player' is nil

	--enemy damage taken
	local i = 1
	local damageTaken = 0
	---@type actorcontainer
	local damageContainer = combatObject:GetContainer(DETAILS_ATTRIBUTE_DAMAGE)

	---@type number, actor
	for idx, actor in damageContainer:ListActors() do
		if (actor:IsGroupPlayer() and actor.targets[enemyName]) then
			---@type table<actor, number>
			local agressorsTable = tooltip_temp_table[i]

			if (not agressorsTable) then
				tooltip_temp_table[i] = {}
				agressorsTable = tooltip_temp_table[i]
			end

			agressorsTable[1] = actor
			agressorsTable[2] = (actor.targets[enemyName]) or 0
			damageTaken = damageTaken + agressorsTable[2]

			i = i + 1
		end
	end

	for o = i, #tooltip_temp_table do
		local t = tooltip_temp_table[o]
		t[2] = 0
		t[1] = 0
	end

	_table_sort(tooltip_temp_table, Details.Sort2)

	--build the tooltip
	local top = (tooltip_temp_table[1] and tooltip_temp_table[1][2]) or 0
	tooltip_temp_table.damage_total = damageTaken

	local iconSize = Details.DefaultTooltipIconSize
	GameCooltip:SetOption("AlignAsBlizzTooltip", false)
	GameCooltip:SetOption("YSpacingMod", -6)

	for o = 1, i-1 do
		local actorAggressor = tooltip_temp_table[o][1]
		local damageDone = tooltip_temp_table[o][2]
		local playerName = Details:GetOnlyName(actorAggressor:name())

		GameCooltip:AddLine(playerName .. " ", FormatTooltipNumber (_, damageDone) .." (" .. format("%.1f", (damageDone / damageTaken) * 100) .. "%)")

		local classe = actorAggressor:class()
		if (not classe) then
			classe = "UNKNOW"
		end

		if (classe == "UNKNOW") then
			GameCooltip:AddIcon("Interface\\LFGFRAME\\LFGROLE_BW", nil, nil, iconSize, iconSize, .25, .5, 0, 1)
		else
			local specID = actorAggressor.spec
			if (specID) then
				local texture, l, r, t, b = Details:GetSpecIcon(specID, false)
				GameCooltip:AddIcon(texture, 1, 1, iconSize, iconSize, l, r, t, b)
			else
				GameCooltip:AddIcon(instanceObject.row_info.icon_file, nil, nil, iconSize, iconSize, unpack(Details.class_coords [classe]))
			end
		end

		local r, g, b = unpack(Details.class_colors[classe])
		GameCooltip:AddStatusBar(damageDone/top*100, 1, r, g, b, 1, false, enemies_background)
	end

	GameCooltip:SetOption("StatusBarTexture", "Interface\\AddOns\\Details\\images\\bar_serenity")

	--damage done and heal
	GameCooltip:AddLine(" ")
	GameCooltip:AddLine(Loc ["STRING_ATTRIBUTE_DAMAGE_ENEMIES_DONE"], FormatTooltipNumber (_, _math_floor(self.total)))
	local half = 0.00048828125
	GameCooltip:AddIcon (instanceObject:GetSkinTexture(), 1, 1, 14, 14, 0.005859375 + half, 0.025390625 - half, 0.3623046875, 0.3818359375)
	GameCooltip:AddStatusBar (0, 1, r, g, b, 1, false, enemies_background)

	local heal_actor = instanceObject.showing (2, self.nome)
	if (heal_actor) then
		GameCooltip:AddLine(Loc ["STRING_ATTRIBUTE_HEAL_ENEMY"], FormatTooltipNumber (_, _math_floor(heal_actor.heal_enemy_amt)))
	else
		GameCooltip:AddLine(Loc ["STRING_ATTRIBUTE_HEAL_ENEMY"], 0)
	end
	GameCooltip:AddIcon (instanceObject:GetSkinTexture(), 1, 1, 14, 14, 0.037109375 + half, 0.056640625 - half, 0.3623046875, 0.3818359375)
	GameCooltip:AddStatusBar (0, 1, r, g, b, 1, false, enemies_background)

	GameCooltip:AddLine(" ")
	Details:AddTooltipReportLineText()

	return true
end

---------DAMAGE TAKEN
function damageClass:ToolTip_DamageTaken(instance, numero, barra, keydown)
	--if the object has a owner, it's a pet
	local owner = self.owner
	if (owner and owner.classe) then
		r, g, b = unpack(Details.class_colors[owner.classe])
	else
		r, g, b = unpack(Details.class_colors[self.classe])
	end

	local damageTakenFrom = self.damage_from
	local totalDamageTaken = self.damage_taken
	local actorName = self:Name()

	local combatObject = instance:GetShowingCombat()
	local damageContainer = combatObject:GetContainer(DETAILS_ATTRIBUTE_DAMAGE)

	---@type {key1:actorname, key2:valueamount, key3:class, key4:actor}
	local damageTakenDataSorted = {}
	local mainAttribute, subAttribute = instance:GetDisplay()

	if (subAttribute == DETAILS_SUBATTRIBUTE_ENEMIES) then
		for _, actorObject in damageContainer:ListActors() do
			if (actorObject:IsGroupPlayer() and actorObject.targets[actorName]) then
				damageTakenDataSorted [#damageTakenDataSorted+1] = {
					actorName,
					actorObject.targets[actorName],
					actorObject:Class(),
					actorObject
				}
			end
		end
	else
		for enemyName, _ in pairs(damageTakenFrom) do --who damaged the player
			--get the aggressor
			local enemyActorObject = damageContainer:GetActor(enemyName)
			if (enemyActorObject) then
				---@type {key1:actorname, key2:valueamount, key3:class, key4:actor}
				local damageTakenTable
				local damageInflictedByThisEnemy = enemyActorObject.targets[actorName]

				if (damageInflictedByThisEnemy) then
					if (enemyActorObject:IsPlayer() or enemyActorObject:IsNeutralOrEnemy()) then
						damageTakenTable = {enemyName, damageInflictedByThisEnemy, enemyActorObject:Class(), enemyActorObject}
						damageTakenDataSorted[#damageTakenDataSorted+1] = damageTakenTable
					end
				end

				--special cases - monk stagger
				if (enemyName == actorName and self:Class() == "MONK") then
					local friendlyFire = enemyActorObject.friendlyfire[enemyName]
					if (friendlyFire and friendlyFire.total > 0) then
						local staggerDamage = friendlyFire.spells[124255] or 0
						if (staggerDamage > 0) then
							if (damageTakenTable) then
								damageTakenTable[2] = damageTakenTable[2] + staggerDamage
							else
								damageTakenDataSorted[#damageTakenDataSorted+1] = {enemyName, staggerDamage, "MONK", enemyActorObject}
							end
						end
					end
				end
			end
		end
	end

	local maxDataAllowed = #damageTakenDataSorted
	if (maxDataAllowed > 10) then
		maxDataAllowed = 10
	end

	local bIsMaximized = false
	if (keydown == "shift" or TooltipMaximizedMethod == 2 or TooltipMaximizedMethod == 3 or instance.sub_atributo == 6 or Details.damage_taken_everything) then
		maxDataAllowed = #damageTakenDataSorted
		bIsMaximized = true
	end

	if (subAttribute == DETAILS_SUBATTRIBUTE_ENEMIES) then
		--Details:AddTooltipSpellHeaderText(Loc ["STRING_DAMAGE_TAKEN_FROM"], headerColor, #damageTakenDataSorted, [[Interface\Buttons\UI-MicroStream-Red]], 0.1875, 0.8125, 0.15625, 0.78125)
	else
		--Details:AddTooltipSpellHeaderText(Loc ["STRING_FROM"], headerColor, #damageTakenDataSorted, [[Interface\Addons\Details\images\icons]], 0.126953125, 0.1796875, 0, 0.0546875)
	end

	if (bIsMaximized) then
		--highlight
		--GameCooltip:AddIcon([[Interface\AddOns\Details\images\key_shift]], 1, 2, Details.tooltip_key_size_width, Details.tooltip_key_size_height, 0, 1, 0, 0.640625, Details.tooltip_key_overlay2)
		--if (subAttribute == DETAILS_SUBATTRIBUTE_ENEMIES) then
		--	GameCooltip:AddStatusBar(100, 1, 0.7, g, b, 1)
		--else
		--	Details:AddTooltipHeaderStatusbar(r, g, b, 1)
		--end
	else
		--GameCooltip:AddIcon([[Interface\AddOns\Details\images\key_shift]], 1, 2, Details.tooltip_key_size_width, Details.tooltip_key_size_height, 0, 1, 0, 0.640625, Details.tooltip_key_overlay1)
		--if (subAttribute == DETAILS_SUBATTRIBUTE_ENEMIES) then
		--	GameCooltip:AddStatusBar(100, 1, 0.7, 0, 0, barAlha)
		--else
		--	Details:AddTooltipHeaderStatusbar(r, g, b, barAlha)
		--end
	end

	--local iconSize = Details.tooltip.icon_size
	local iconBorderTexCoord = Details.tooltip.icon_border_texcoord

	GameCooltip:SetOption("AlignAsBlizzTooltip", false)
	GameCooltip:SetOption("AlignAsBlizzTooltipFrameHeightOffset", -6)
	GameCooltip:SetOption("YSpacingMod", -6)
	local iconSize = Details.DefaultTooltipIconSize

	-- create a full list of incoming damage, before adding any lines to the tooltip, so we can sort them appropriately

	---@class cooltip_icon
	---@field key1 textureid
	---@field key2 number 1 for main tooltip frame, 2 for the secondary frame
	---@field key3 number 1 for the left side, 2 for the right size
	---@field key4 width
	---@field key5 height
	---@field key6 coordleft
	---@field key7 coordright
	---@field key8 coordtop
	---@field key9 coordbottom

	---@type {key1:valueamount, key2:table<string, string>, key3:cooltip_icon}
	local lines_to_add = {}

	for i = 1, maxDataAllowed do
		local enemyActorObject = damageTakenDataSorted[i][4]

		--only shows damage from enemies or from the player it self
		--the player it self can only be placed on the list by the iteration above
		--the iteration doesnt check friendly fire for all actors, only a few cases like Monk Stagger

		if (enemyActorObject:IsNeutralOrEnemy() or enemyActorObject:Name() == self:Name()) then
			---@type {key1:spellid, key2:valueamount, key:actorname}
			local spellTargetDamageList = {}

			for spellId, spellTable in pairs(enemyActorObject.spells._ActorTable) do
				local damageOnTarget = spellTable.targets[self:Name()]
				if (damageOnTarget) then
					tinsert(spellTargetDamageList, {spellId, damageOnTarget, enemyActorObject:Name()})
				end
			end

			--friendly fire
			local friendlyFire = enemyActorObject.friendlyfire[self:Name()]
			if (friendlyFire) then
				for spellId, valueAmount in pairs(friendlyFire.spells) do
					table.insert(spellTargetDamageList, {spellId, valueAmount, enemyActorObject:Name()})
				end
			end

			for _, spell in ipairs(spellTargetDamageList) do
				local spellId, valueAmount, thisActorName = unpack(spell)

				local spellName, _, spellIcon = _GetSpellInfo(spellId)
				local addTextArgs = {spellName .. " (|cFFFFFF00" .. thisActorName .. "|r)", Details:Format(valueAmount) .. " (" .. string.format("%.1f", (valueAmount / totalDamageTaken) * 100) .. "%)"}
				---@type cooltip_icon
				local addIconArgs = {spellIcon, 1, 1, iconSize, iconSize, iconBorderTexCoord.L, iconBorderTexCoord.R, iconBorderTexCoord.T, iconBorderTexCoord.B}

				tinsert(lines_to_add, {
					valueAmount,
					addTextArgs,
					addIconArgs
				})
			end
		else
			---@type actorname, valueamount, class, actor
			local thisAggrossorTable = damageTakenDataSorted[i]
			local actorName = thisAggrossorTable[1]
			local amount = thisAggrossorTable[2]
			local class = thisAggrossorTable[3]
			local actorObject = thisAggrossorTable[4]

			---@type {key1:actorname, key2:string, key3:nil, key4:color}
			local addLineArgs
			---@type cooltip_icon
			local addIconArgs

			local aggressorName = Details:GetOnlyName(actorName)
			if (bIsMaximized and actorName:find(Details.playername)) then
				addLineArgs = {aggressorName, Details:Format(amount) .. " ("..string.format("%.1f", (amount / totalDamageTaken) * 100) .. "%)", nil, "yellow"}
			else
				addLineArgs = {aggressorName, Details:Format(amount) .. " ("..string.format("%.1f", (amount / totalDamageTaken) * 100) .. "%)"}
			end

			if (not class) then
				class = "UNKNOW"
			end

			if (class == "UNKNOW") then
				addIconArgs = {"Interface\\LFGFRAME\\LFGROLE_BW", nil, nil, iconSize, iconSize, .25, .5, 0, 1}
			else
				addIconArgs= {instance.row_info.icon_file, nil, nil, iconSize, iconSize, unpack(Details.class_coords [class])}
			end
			tinsert(lines_to_add, {amount, addLineArgs, addIconArgs})
		end
	end

	table.sort(lines_to_add, Details.Sort1)

	for _, line in ipairs(lines_to_add) do
		GameCooltip:AddLine(unpack(line[2]))
		GameCooltip:AddIcon(unpack(line[3]))
		Details:AddTooltipBackgroundStatusbar()
	end

	if (subAttribute == DETAILS_SUBATTRIBUTE_ENEMIES) then
		GameCooltip:AddLine(" ")
		GameCooltip:AddLine(Loc ["STRING_ATTRIBUTE_DAMAGE_DONE"], FormatTooltipNumber (_, _math_floor(self.total)))
		local half = 0.00048828125
		GameCooltip:AddIcon (instance:GetSkinTexture(), 1, 1, iconSize, iconSize, 0.005859375 + half, 0.025390625 - half, 0.3623046875, 0.3818359375)
		Details:AddTooltipBackgroundStatusbar()

		local heal_actor = instance.showing (2, self.nome)
		if (heal_actor) then
			GameCooltip:AddLine(Loc ["STRING_ATTRIBUTE_HEAL_DONE"], FormatTooltipNumber (_, _math_floor(heal_actor.heal_enemy_amt)))
		else
			GameCooltip:AddLine(Loc ["STRING_ATTRIBUTE_HEAL_DONE"], 0)
		end
		GameCooltip:AddIcon (instance:GetSkinTexture(), 1, 1, iconSize, iconSize, 0.037109375 + half, 0.056640625 - half, 0.3623046875, 0.3818359375)
		Details:AddTooltipBackgroundStatusbar()
	end

	return true
end

---------FRIENDLY FIRE
function damageClass:ToolTip_FriendlyFire (instancia, numero, barra, keydown)

	local owner = self.owner
	if (owner and owner.classe) then
		r, g, b = unpack(Details.class_colors [owner.classe])
	else
		r, g, b = unpack(Details.class_colors [self.classe])
	end

	local FriendlyFire = self.friendlyfire
	local FriendlyFireTotal = self.friendlyfire_total
	local combat = instancia:GetShowingCombat()

	local tabela_do_combate = instancia.showing
	local showing = tabela_do_combate [class_type]

	local icon_size = Details.tooltip.icon_size
	local icon_border = Details.tooltip.icon_border_texcoord
	local lineHeight = Details.tooltip.line_height

	local DamagedPlayers = {}
	local Skills = {}

	for target_name, ff_table in pairs(FriendlyFire) do
		local actor = combat (1, target_name)
		if (actor) then
			DamagedPlayers [#DamagedPlayers+1] = {target_name, ff_table.total, actor.classe}
			for spellid, amount in pairs(ff_table.spells) do
				Skills [spellid] = (Skills [spellid] or 0) + amount
			end
		end
	end

	_table_sort(DamagedPlayers, Details.Sort2)

	Details:AddTooltipSpellHeaderText (Loc ["STRING_TARGETS"], headerColor, #DamagedPlayers, Details.tooltip_target_icon.file, unpack(Details.tooltip_target_icon.coords))

	local ismaximized = false
	if (keydown == "shift" or TooltipMaximizedMethod == 2 or TooltipMaximizedMethod == 3) then
		GameCooltip:AddIcon ([[Interface\AddOns\Details\images\key_shift]], 1, 2, Details.tooltip_key_size_width, Details.tooltip_key_size_height, 0, 1, 0, 0.640625, Details.tooltip_key_overlay2)
		Details:AddTooltipHeaderStatusbar (r, g, b, 1)
		ismaximized = true
	else
		GameCooltip:AddIcon ([[Interface\AddOns\Details\images\key_shift]], 1, 2, Details.tooltip_key_size_width, Details.tooltip_key_size_height, 0, 1, 0, 0.640625, Details.tooltip_key_overlay1)
		Details:AddTooltipHeaderStatusbar (r, g, b, barAlha)
	end

	local max_abilities = Details.tooltip.tooltip_max_abilities
	if (ismaximized) then
		max_abilities = 99
	end

	for i = 1, _math_min(max_abilities, #DamagedPlayers) do
		local classe = DamagedPlayers[i][3]
		if (not classe) then
			classe = "UNKNOW"
		end

		GameCooltip:AddLine(Details:GetOnlyName(DamagedPlayers[i][1]), FormatTooltipNumber (_, DamagedPlayers[i][2]).." ("..format("%.1f", DamagedPlayers[i][2]/FriendlyFireTotal*100).."%)")
		GameCooltip:AddIcon ("Interface\\AddOns\\Details\\images\\espadas", nil, nil, lineHeight, lineHeight)
		Details:AddTooltipBackgroundStatusbar()

		if (classe == "UNKNOW") then
			GameCooltip:AddIcon ("Interface\\AddOns\\Details\\images\\classes_small", nil, nil, lineHeight, lineHeight, unpack(Details.class_coords ["UNKNOW"]))
		else
			local specID = Details:GetSpec(DamagedPlayers[i][1])
			if (specID) then
				local texture, l, r, t, b = Details:GetSpecIcon (specID, false)
				GameCooltip:AddIcon (texture, 1, 1, lineHeight, lineHeight, l, r, t, b)
			else
				GameCooltip:AddIcon ("Interface\\AddOns\\Details\\images\\classes_small", nil, nil, lineHeight, lineHeight, unpack(Details.class_coords [classe]))
			end
		end

	end

	Details:AddTooltipSpellHeaderText (Loc ["STRING_SPELLS"], headerColor, 1, Details.tooltip_spell_icon.file, unpack(Details.tooltip_spell_icon.coords))

	local ismaximized = false
	if (keydown == "ctrl" or TooltipMaximizedMethod == 2 or TooltipMaximizedMethod == 4) then
		GameCooltip:AddIcon ([[Interface\AddOns\Details\images\key_ctrl]], 1, 2, Details.tooltip_key_size_width, Details.tooltip_key_size_height, 0, 1, 0, 0.640625, Details.tooltip_key_overlay2)
		Details:AddTooltipHeaderStatusbar (r, g, b, 1)
		ismaximized = true
	else
		GameCooltip:AddIcon ([[Interface\AddOns\Details\images\key_ctrl]], 1, 2, Details.tooltip_key_size_width, Details.tooltip_key_size_height, 0, 1, 0, 0.640625, Details.tooltip_key_overlay1)
		Details:AddTooltipHeaderStatusbar (r, g, b, barAlha)
	end

	local max_abilities2 = Details.tooltip.tooltip_max_abilities
	if (ismaximized) then
		max_abilities2 = 99
	end

	--spells usadas no friendly fire
	local SpellsInOrder = {}
	for spellID, amount in pairs(Skills) do
		SpellsInOrder [#SpellsInOrder+1] = {spellID, amount}
	end
	_table_sort(SpellsInOrder, Details.Sort2)

	for i = 1, _math_min(max_abilities2, #SpellsInOrder) do
		local nome, _, icone = _GetSpellInfo(SpellsInOrder[i][1])
		GameCooltip:AddLine(nome, FormatTooltipNumber (_, SpellsInOrder[i][2]).." ("..format("%.1f", SpellsInOrder[i][2]/FriendlyFireTotal*100).."%)")
		GameCooltip:AddIcon (icone, nil, nil, icon_size.W, icon_size.H, icon_border.L, icon_border.R, icon_border.T, icon_border.B)
		Details:AddTooltipBackgroundStatusbar()
	end

	return true
end


--------------------------------------------- // JANELA DETALHES // ---------------------------------------------


---------DETALHES BIFURCA��O ~detalhes ~detailswindow ~bi
function damageClass:MontaInfo()
	if (breakdownWindowFrame.sub_atributo == 1 or breakdownWindowFrame.sub_atributo == 2 or breakdownWindowFrame.sub_atributo == 6) then --damage done & dps
		return self:MontaInfoDamageDone() --has new code for the new destails window | left scroll and 6 blocks implemented
	elseif (breakdownWindowFrame.sub_atributo == 3) then --damage taken
		return self:MontaInfoDamageTaken() --has new code for the new destails window | left and right scrolls implemented
	elseif (breakdownWindowFrame.sub_atributo == 4) then --friendly fire
		return self:MontaInfoFriendlyFire() --has new code for the new destails window | left scroll implemeneted (need to implemente the right scroll yet)
	end
end

---------DETALHES bloco da direita BIFURCA��O
function damageClass:MontaDetalhes (spellid, barra, instancia) --these functions were used to fill the 5 blocks from the old breakdown window
	if (breakdownWindowFrame.sub_atributo == 1 or breakdownWindowFrame.sub_atributo == 2) then
		return self:MontaDetalhesDamageDone (spellid, barra, instancia) --deprecated

	elseif (breakdownWindowFrame.sub_atributo == 3) then
		return self:MontaDetalhesDamageTaken (spellid, barra, instancia)

	elseif (breakdownWindowFrame.sub_atributo == 4) then
		return self:MontaDetalhesFriendlyFire (spellid, barra, instancia)

	elseif (breakdownWindowFrame.sub_atributo == 6) then
		if (bitBand(self.flag_original, 0x00000400) ~= 0) then --� um jogador
			return self:MontaDetalhesDamageDone (spellid, barra, instancia) --deprecated
		end
		return self:MontaDetalhesEnemy (spellid, barra, instancia)
	end
end

local friendlyFireSpellSourcesHeadersAllowed = {icon = true, name = true, rank = true, amount = true, persecond = true, percent = true}
---when hovering over the player name in the breakdown window, this function will be called to build a the list of spells used to inflict damage on that player
---@param friendlyFireAggressorActor actordamage
---@param targetName string
function damageClass.BuildFriendlySpellListFromAgressor(friendlyFireAggressorActor, targetName)
	---@type combat
	local combatObject = Details:GetCombatFromBreakdownWindow()

	---@type friendlyfiretable
	local friendlyFireTable = friendlyFireAggressorActor.friendlyfire[targetName]

	local totalDamage = friendlyFireTable.total
	local spellsUsed = friendlyFireTable.spells

	--create the table which will be returned with the data
	---@type {topValue: number, totalValue: number, headersAllowed: table, combatTime: number}
	local resultTable = {topValue = 0, totalValue = totalDamage, headersAllowed = friendlyFireSpellSourcesHeadersAllowed, combatTime = combatObject:GetCombatTime()}

	--iterate among the spells used by the aggressorActor
	for spellId, amountDamage in pairs(spellsUsed) do
		--add the spell to the list
		local spellName = GetSpellInfo(spellId)
		resultTable[#resultTable+1] = {spellId = spellId, total = amountDamage, petName = "", spellScholl = Details.spell_school_cache[spellName] or 1}
	end

	return resultTable
end

------ Friendly Fire
local friendlyFireHeadersAllowed = {icon = true, name = true, rank = true, amount = true, persecond = true, percent = true}
---build the friendly fire list, the list contains players who were damaged by this actor.
function damageClass:MontaInfoFriendlyFire() --~friendlyfire ~friendly ~ff
	---@type actordamage
	local actorObject = self
	---@type instance
	local instance = breakdownWindowFrame.instancia
	---@type combat
	local combatObject = instance:GetCombat()
	---@type string
	local actorName = actorObject:Name()

	---@type number
	local friendlyFireTotal = actorObject.friendlyfire_total
	---@type table<string, friendlyfiretable>
	local damagedPlayers = actorObject.friendlyfire --players which got hit by this actor
	---@type actorcontainer
	local damageContainer = combatObject:GetContainer(class_type)

	local resultTable = {}

	for targetName, friendlyFireTable in pairs(damagedPlayers) do
		local amountOfFriendlyFire = friendlyFireTable.total
		if (amountOfFriendlyFire > 0) then
			---@type actordamage this is an actor who was damaged by the friendly fire of the actorObject
			local targetActorObject = damageContainer:GetActor(targetName)
			if (targetActorObject) then
				---@type texturetable
				local iconTable = Details:GetActorIcon(targetActorObject)

				---@type {name: string, amount: number, icon: texturetable, class: string}
				local ffTable = {name = targetName, total = amountOfFriendlyFire, icon = iconTable, class = targetActorObject:Class()}

				resultTable[#resultTable+1] = ffTable
			end
		end
	end

	resultTable.totalValue = friendlyFireTotal
	resultTable.combatTime = combatObject:GetCombatTime()
	resultTable.headersAllowed = friendlyFireHeadersAllowed

	Details222.BreakdownWindow.SendGenericData(resultTable, actorObject, combatObject, instance)

	if true then return end
	do
		local instancia = breakdownWindowFrame.instancia
		local combat = instancia:GetShowingCombat()
		local barras = breakdownWindowFrame.barras1
		local barras2 = breakdownWindowFrame.barras2
		local barras3 = breakdownWindowFrame.barras3

		local FriendlyFireTotal = self.friendlyfire_total

		local DamagedPlayers = {}
		local Skills = {}

		for target_name, ff_table in pairs(self.friendlyfire) do

			local actor = combat (1, target_name)
			if (actor) then
				tinsert(DamagedPlayers, {target_name, ff_table.total, ff_table.total / FriendlyFireTotal * 100, actor.classe})

				for spellid, amount in pairs(ff_table.spells) do
					Skills [spellid] = (Skills [spellid] or 0) + amount
				end
			end
		end

		_table_sort(DamagedPlayers, Details.Sort2)

		local amt = #DamagedPlayers
		gump:JI_AtualizaContainerBarras (amt)

		local FirstPlaceDamage = DamagedPlayers [1] and DamagedPlayers [1][2] or 0

		for index, tabela in ipairs(DamagedPlayers) do
			local barra = barras [index]

			if (not barra) then
				barra = gump:CriaNovaBarraInfo1 (instancia, index)
				barra.textura:SetStatusBarColor(1, 1, 1, 1)
				barra.on_focus = false
			end

			if (not breakdownWindowFrame.mostrando_mouse_over) then
				if (tabela[1] == self.detalhes) then --tabela [1] = NOME = NOME que esta na caixa da direita
					if (not barra.on_focus) then --se a barra n�o tiver no foco
						barra.textura:SetStatusBarColor(129/255, 125/255, 69/255, 1)
						barra.on_focus = true
						if (not breakdownWindowFrame.mostrando) then
							breakdownWindowFrame.mostrando = barra
						end
					end
				else
					if (barra.on_focus) then
						barra.textura:SetStatusBarColor(1, 1, 1, 1) --volta a cor antiga
						barra:SetAlpha(.9) --volta a alfa antiga
						barra.on_focus = false
					end
				end
			end

			if (index == 1) then
				barra.textura:SetValue(100)
			else
				barra.textura:SetValue(tabela[2]/FirstPlaceDamage*100)
			end

			barra.lineText1:SetText(index .. instancia.divisores.colocacao .. Details:GetOnlyName(tabela[1])) --seta o texto da esqueda
			barra.lineText4:SetText(Details:comma_value (tabela[2]) .. " (" .. format("%.1f", tabela[3]) .."%)") --seta o texto da direita

			local classe = tabela[4]
			if (not classe) then
				classe = "MONSTER"
			end

			barra.icone:SetTexture(breakdownWindowFrame.instancia.row_info.icon_file)

			if (Details.class_coords [classe]) then
				barra.icone:SetTexCoord(unpack(Details.class_coords [classe]))
			else
				barra.icone:SetTexture("")
			end

			local color = Details.class_colors [classe]
			if (color) then
				barra.textura:SetStatusBarColor(unpack(color))
			else
				barra.textura:SetStatusBarColor(1, 1, 1)
			end

			barra.minha_tabela = self
			barra.show = tabela[1]
			barra:Show()

			if (self.detalhes and self.detalhes == barra.show) then
				self:MontaDetalhes (self.detalhes, barra, instancia)
			end
		end

		local SkillTable = {}
		for spellid, amt in pairs(Skills) do
			local nome, _, icone = _GetSpellInfo(spellid)
			SkillTable [#SkillTable+1] = {nome, amt, amt/FriendlyFireTotal*100, icone}
		end

		_table_sort(SkillTable, Details.Sort2)

		amt = #SkillTable
		if (amt < 1) then
			return
		end

		gump:JI_AtualizaContainerAlvos (amt)

		FirstPlaceDamage = SkillTable [1] and SkillTable [1][2] or 0

		for index, tabela in ipairs(SkillTable) do
			local barra = barras2 [index]

			if (not barra) then
				barra = gump:CriaNovaBarraInfo2 (instancia, index)
				barra.textura:SetStatusBarColor(1, 1, 1, 1)
			end

			if (index == 1) then
				barra.textura:SetValue(100)
			else
				barra.textura:SetValue(tabela[2]/FirstPlaceDamage*100)
			end

			barra.lineText1:SetText(index..instancia.divisores.colocacao..tabela[1]) --seta o texto da esqueda
			barra.lineText4:SetText(Details:comma_value (tabela[2]) .." (" ..format("%.1f", tabela[3]) .. ")") --seta o texto da direita
			barra.icone:SetTexture(tabela[4])

			barra.minha_tabela = nil --desativa o tooltip

			barra:Show()
		end
	end
end

local damageTakenSpellSourcesHeadersAllowed = {icon = true, name = true, rank = true, amount = true, persecond = true, percent = true}
function damageClass.BuildDamageTakenSpellListFromAgressor(targetActor, aggressorActor)
	--target actor name
	local targetActorName = targetActor:Name()

	---@type combat
	local combatObject = Details:GetCombatFromBreakdownWindow()

	--get the list of spells from the aggressorActor and check each one to see if it was casted on the targetActor
	---@type spellcontainer
	local spellContainer = aggressorActor:GetSpellContainer("spell")

	--create the table which will be returned with the data
	---@type {topValue: number, totalValue: number, headersAllowed: table, combatTime: number}
	local resultTable = {topValue = 0, totalValue = 0, headersAllowed = damageTakenSpellSourcesHeadersAllowed, combatTime = combatObject:GetCombatTime()}

	for spellId, spellTable in spellContainer:ListSpells() do
		---@cast spellTable spelltable
		for targetName, amount in pairs(spellTable.targets) do
			if (targetName == targetActorName) then
				--add the spell to the list
				resultTable[#resultTable+1] = {spellId = spellId, total = amount, petName = "", spellScholl = spellTable.spellschool}
				resultTable.totalValue = resultTable.totalValue + amount
			end
		end
	end

	--iterate among the pets of the aggressorActor and get the spells casted by them
	---@type table<number, actorname>
	local petTable = aggressorActor.pets

	for i = 1, #petTable do
		local petName = petTable[i]
		local petActorObject = combatObject:GetActor(DETAILS_ATTRIBUTE_DAMAGE, petName)
		if (petActorObject) then
			---@type spellcontainer
			local petSpellContainer = petActorObject:GetSpellContainer("spell")

			for spellId, spellTable in petSpellContainer:ListSpells() do
				for targetName, amount in pairs(spellTable.targets) do
					if (targetName == targetActorName) then
						--add the spell to the list
						resultTable[#resultTable+1] = {spellId = spellId, total = amount, petName = petName, spellScholl = spellTable.spellschool}
						resultTable.totalValue = resultTable.totalValue + amount
					end
				end
			end
		end
	end

	return resultTable
end

------ Damage Taken
local damageTakenHeadersAllowed = {icon = true, name = true, rank = true, amount = true, persecond = true, percent = true}
function damageClass:MontaInfoDamageTaken()
	---@type actordamage
	local actorObject = self
	---@type instance
	local instance = breakdownWindowFrame.instancia
	---@type combat
	local combatObject = instance:GetCombat()
	---@type string
	local actorName = actorObject:Name()

	---@type number
	local damageTakenTotal = actorObject.damage_taken
	---@type table<string, boolean>
	local damageTakenFrom = actorObject.damage_from
	---@type actorcontainer
	local damageContainer = combatObject:GetContainer(class_type)

	local resultTable = {}

	---@type string
	for aggressorName in pairs(damageTakenFrom) do
		local aggressorActor = damageContainer:GetActor(aggressorName)
		if (aggressorActor) then
			---@type table<string, number>
			local targets = aggressorActor:GetTargets()
			---@type number|nil
			local amountOfDamage = targets[actorName]
			if (amountOfDamage) then
				---@type texturetable
				local iconTable = Details:GetActorIcon(aggressorActor)

				---@type {name: string, amount: number, icon: texturetable}
				local damageTakenTable = {name = aggressorName, total = amountOfDamage, icon = iconTable, class = aggressorActor:Class()}

				resultTable[#resultTable+1] = damageTakenTable
			end
		end
	end

	resultTable.totalValue = damageTakenTotal
	resultTable.combatTime = combatObject:GetCombatTime()
	resultTable.headersAllowed = damageTakenHeadersAllowed

	Details222.BreakdownWindow.SendGenericData(resultTable, actorObject, combatObject, instance)
end

--[[exported]] function Details:UpdadeInfoBar(row, index, spellId, name, value, formattedValue, max, percent, icon, detalhes, texCoords, spellSchool, class)
	if (index == 1) then
		row.textura:SetValue(100)
	else
		max = math.max(max, 0.001)
		row.textura:SetValue(value / max * 100)
	end

	if (type(index) == "number") then
		if (debugmode) then
			row.lineText1:SetText(index .. ". " .. name .. " (" .. spellId .. ")")
		else
			row.lineText1:SetText(index .. ". " .. name)
		end
	else
		row.lineText1:SetText(name)
	end

	row.lineText1.text = row.lineText1:GetText()

	if (formattedValue) then
		row.lineText4:SetText(formattedValue .. " (" .. format("%.1f", percent) .."%)")
	end

	row.lineText1:SetSize(row:GetWidth() - row.lineText4:GetStringWidth() - 40, 15)

	if (icon) then
		row.icone:SetTexture(icon)
		if (icon == "Interface\\AddOns\\Details\\images\\classes_small") then
			row.icone:SetTexCoord(0.25, 0.49609375, 0.75, 1)
		else
			row.icone:SetTexCoord(0, 1, 0, 1)
		end
	else
		row.icone:SetTexture("")
	end

	if (not row.IconUpBorder) then
		row.IconUpBorder = CreateFrame("frame", nil, row,"BackdropTemplate")
		row.IconUpBorder:SetAllPoints(row.icone)
		row.IconUpBorder:SetBackdrop({edgeFile = [[Interface\Buttons\WHITE8X8]], edgeSize = 1})
		row.IconUpBorder:SetBackdropBorderColor(0, 0, 0, 0.75)
	end

	if (texCoords) then
		row.icone:SetTexCoord(unpack(texCoords))
	else
		local iconBorder = Details.tooltip.icon_border_texcoord
		row.icone:SetTexCoord(iconBorder.L, iconBorder.R, iconBorder.T, iconBorder.B)
	end

	row.minha_tabela = self
	row.show = spellId
	row:Show()

	if (spellSchool) then
		local schoolColor = Details.spells_school[spellSchool]
		if (schoolColor and schoolColor.decimals) then
			row.textura:SetStatusBarColor(schoolColor.decimals[1], schoolColor.decimals[2], schoolColor.decimals[3])
		else
			row.textura:SetStatusBarColor(1, 1, 1)
		end

	elseif (class) then
		local color = Details.class_colors[class]
		if (color and class ~= "UNKNOW") then
			row.textura:SetStatusBarColor(unpack(color))
		else
			row.textura:SetStatusBarColor(1, 1, 1)
		end
	else
		if (spellId == 98021) then --spirit linkl
			row.textura:SetStatusBarColor(1, 0.4, 0.4)
		else
			row.textura:SetStatusBarColor(1, 1, 1)
		end
	end

	if (detalhes and self.detalhes and self.detalhes == spellId and breakdownWindowFrame.showing == index) then
		self:MontaDetalhes(row.show, row, breakdownWindowFrame.instancia)
	end
end

--lock into a line after clicking on it
--[[exported]] function Details:FocusLock(row, spellId) --will be deprecated
	if (not breakdownWindowFrame.mostrando_mouse_over) then
		if (spellId == self.detalhes) then --tabela [1] = spellid = spellid que esta na caixa da direita
			if (not row.on_focus) then --se a barra n�o tiver no foco
				row.textura:SetStatusBarColor(129/255, 125/255, 69/255, 1)
				row.on_focus = true
				if (not breakdownWindowFrame.mostrando) then
					breakdownWindowFrame.mostrando = row
				end
			end
		else
			if (row.on_focus) then
				row.textura:SetStatusBarColor(1, 1, 1, 1) --volta a cor antiga
				row:SetAlpha(.9) --volta a alfa antiga
				row.on_focus = false
			end
		end
	end
end

local wipeSpellCache = function() --deprecated
	Details:Destroy(Details222.PlayerBreakdown.DamageSpellsCache)
end

local addToSpellCache = function(unitGUID, spellName, spellTable) --deprecated
	local unitSpellCache = Details222.PlayerBreakdown.DamageSpellsCache[unitGUID]
	if (not unitSpellCache) then
		unitSpellCache = {}
		Details222.PlayerBreakdown.DamageSpellsCache[unitGUID] = unitSpellCache
	end

	local spellCache = Details222.PlayerBreakdown.DamageSpellsCache[unitGUID][spellName]
	if (not spellCache) then
		spellCache = {}
		Details222.PlayerBreakdown.DamageSpellsCache[unitGUID][spellName] = spellCache
	end

	table.insert(spellCache, spellTable)
end

local getSpellDetails = function(unitGUID, spellName) --deprecated
	local unitCachedSpells = Details222.PlayerBreakdown.DamageSpellsCache[unitGUID]
	local spellsTableForSpellName = unitCachedSpells and unitCachedSpells[spellName]

	if (spellsTableForSpellName) then --should always be valid
		if (#spellsTableForSpellName > 1) then
			local t = spellsTableForSpellName
			local spellId = t[1].id
			local newSpellTable = Details222.DamageSpells.CreateSpellTable(spellId)

			newSpellTable.n_min = 99999999
			newSpellTable.c_min = 99999999
			newSpellTable.n_max = 0
			newSpellTable.c_max = 0

			for i = 1, #t do
				for key, value in pairs(t[i]) do
					if (type(value) == "number") then
						if (key == "n_min" or key == "c_min") then
							if (value < newSpellTable[key]) then
								newSpellTable[key] = value
							end

						elseif (key == "n_max" or key == "c_max") then
							if (value > newSpellTable[key]) then
								newSpellTable[key] = value
							end

						elseif (key ~= "id" and key ~= "spellschool") then
							newSpellTable[key] = (newSpellTable[key] or 0) + value
						end
					end
				end
			end

			return newSpellTable
		else
			--there's only one table, so return the first
			return spellsTableForSpellName[1]
		end
	end
end


--[=[
	current: passando todas as spells para o breakdown, até mesmo as spells que não tem merge é enviado a spell total e a a spellTable logo em seguida
	isso forma uma array com o dobro do tamanho e spells duplicadas

	passar as spells repetidas em uma segunda array?

	não passar nada e deixar o sistema aprender sozinho, como o sistema vai saber que precisa por uma arrow na linha? (para expandi-la)


--]=]

------ Damage Done & Dps
function damageClass:MontaInfoDamageDone() --I guess this fills the list of spells in the topleft scrollBar in the summary tab
	--the goal of this function is to build a list of spells the actor used and send the data to Details! which will delivery to the summary tab actived
	--so the script only need to build the list of spells and send it to Details!
	---@type actor
	local actorObject = self
	---@type instance
	local instance = breakdownWindowFrame.instancia
	---@type combat
	local combatObject = instance:GetCombat()
	---@type number
	local diff = combatObject:GetDifficulty()
	---@type string
	local playerName = actorObject:Name()

	local attribute, subAttribute = instance:GetDisplay()

	--guild ranking on a boss
	--check if is a raid encounter and if is heroic or mythic
	do
		if (diff and (diff == 15 or diff == 16)) then
			local db = Details.OpenStorage()
			if (db) then
				local bestRank, encounterTable = Details.storage:GetBestFromPlayer(diff, combatObject:GetBossInfo().id, "damage", playerName, true)
				if (bestRank) then
					--discover which are the player position in the guild rank
					local playerTable, onEncounter, rankPosition = Details.storage:GetPlayerGuildRank (diff, combatObject:GetBossInfo().id, "damage", playerName, true)
					local text1 = playerName .. " Guild Rank on " .. (combatObject:GetBossInfo().name or "") .. ": |cFFFFFF00" .. (rankPosition or "x") .. "|r Best Dps: |cFFFFFF00" .. Details:ToK2((bestRank[1] or 0) / encounterTable.elapsed) .. "|r (" .. encounterTable.date:gsub(".*%s", "") .. ")"
					breakdownWindowFrame:SetStatusbarText (text1, 10, "gray")
				else
					breakdownWindowFrame:SetStatusbarText()
				end
			else
				breakdownWindowFrame:SetStatusbarText()
			end
		else
			breakdownWindowFrame:SetStatusbarText()
		end
	end

	---@type breakdownspelldatalist
	local breakdownSpellDataList = {}

	---@type number
	local totalDamageWithoutPet = actorObject.total_without_pet
	---@type number
	local actorTotal = actorObject.total
	---@type table<number, spelltable>
	local actorSpells = actorObject:GetSpellList()

	wipeSpellCache()

	--get time
	local actorCombatTime
	if (Details.time_type == 1 or not actorObject.grupo) then
		actorCombatTime = actorObject:Tempo()
	elseif (Details.time_type == 2 or Details.use_realtimedps) then
		actorCombatTime = breakdownWindowFrame.instancia.showing:GetCombatTime()
	end

	--actor spells
	---@type table<string, number>
	local alreadyAdded = {}

	local bShouldMergePlayerSpells = Details.breakdown_spell_tab.nest_players_spells_with_same_name

	---@type number, spelltable
	for spellId, spellTable in pairs(actorSpells) do
		spellTable.ChartData = nil --~ChartData

		---@type string
		local spellName = _GetSpellInfo(spellId)

		if (spellName) then
			---@type number in which index the spell with the same name was stored
			local index = alreadyAdded[spellName]
			if (index and bShouldMergePlayerSpells) then
				---@type spelltableadv
				local bkSpellData = breakdownSpellDataList[index]

				bkSpellData.spellTables[#bkSpellData.spellTables+1] = spellTable

				---@type bknesteddata
				local nestedData = {spellId = spellId, spellTable = spellTable, actorName = "", value = 0}
				bkSpellData.nestedData[#bkSpellData.nestedData+1] = nestedData
				bkSpellData.bCanExpand = true
			else
				---@type spelltableadv
				local bkSpellData = {
					id = spellId,
					spellschool = spellTable.spellschool,
					bIsExpanded = Details222.BreakdownWindow.IsSpellExpanded(spellId),
					bCanExpand = false,

					spellTables = {spellTable},
					nestedData = {{spellId = spellId, spellTable = spellTable, actorName = "", value = 0}},
				}

				detailsFramework:Mixin(bkSpellData, Details.SpellTableMixin)
				breakdownSpellDataList[#breakdownSpellDataList+1] = bkSpellData
				alreadyAdded[spellName] = #breakdownSpellDataList
			end
		end
	end

	--pets spells
	local bShouldMergeSpellsWithThePet = Details.breakdown_spell_tab.nest_pet_spells_by_caster
	local bShouldMergePetSpells = Details.breakdown_spell_tab.nest_pet_spells_by_name

	local actorPets = actorObject:GetPets()
	for _, petName in ipairs(actorPets) do
		---@type actor
		local petActor = combatObject(DETAILS_ATTRIBUTE_DAMAGE, petName)
		if (petActor) then --PET
			--get the amount of spells the pet used, if the pet used only one there`s no reason to nest one spell with the pet
			local petSpellContainer = petActor:GetSpellContainer("spell")

			if (bShouldMergeSpellsWithThePet and petSpellContainer:HasTwoOrMoreSpells()) then
				---@type spelltableadv
				local bkSpellData = {
					bIsActorHeader = true, --tag this spelltable as an actor header, when the actor is the header it will nest the spells use by this actor
					actorName = petName,
					npcId = petActor.aID,
					id = 0,
					spellschool = 0,
					bIsExpanded = Details222.BreakdownWindow.IsSpellExpanded(petName),
					spellTables = {}, --populated below with the spells the pet used
					nestedData = {}, --there's none data here in the main bar as the first bar is the pet name
					bCanExpand = true,
					actorIcon = [[Interface\AddOns\Details\images\pets\pet_icon_1]],
				}
				detailsFramework:Mixin(bkSpellData, Details.SpellTableMixin)

				--output
				breakdownSpellDataList[#breakdownSpellDataList+1] = bkSpellData

				--fill here the spellTables using the actor abilities
				--all these spells belong to the current actor in the loop
				for spellId, spellTable in petSpellContainer:ListSpells() do
					local spellName, _, spellIcon = GetSpellInfo(spellId)
					if (spellName) then
						bkSpellData.spellTables[#bkSpellData.spellTables+1] = spellTable
						---@type bknesteddata
						local nestedData = {spellId = spellId, spellTable = spellTable, actorName = petName, value = 0, bIsActorHeader = true} --value to be defined
						bkSpellData.nestedData[#bkSpellData.nestedData+1] = nestedData
					end
				end
			else
				local spells = petActor:GetSpellList()
				--all these spells belong to the current pet in the loop
				for spellId, spellTable in pairs(spells) do
					---@cast spellId number
					---@cast spellTable spelltable

					spellTable.ChartData = nil
					--PET
					---@type string
					local spellName = _GetSpellInfo(spellId)
					if (spellName) then
						---@type number in which index the spell with the same name was stored
						local index = alreadyAdded[spellName]
						if (index and bShouldMergePetSpells) then --PET
							---@type spelltableadv
							local bkSpellData = breakdownSpellDataList[index]

							bkSpellData.spellTables[#bkSpellData.spellTables+1] = spellTable

							---@type bknesteddata
							local nestedData = {spellId = spellId, spellTable = spellTable, actorName = petName, value = 0}
							bkSpellData.nestedData[#bkSpellData.nestedData+1] = nestedData
							bkSpellData.bCanExpand = true
						else --PET
							---@type spelltableadv
							local bkSpellData = {
								id = spellId,
								actorName = petName,
								npcId = petActor.aID,
								spellschool = spellTable.spellschool,
								bIsExpanded = Details222.BreakdownWindow.IsSpellExpanded(spellId),
								bCanExpand = false,

								spellTables = {spellTable},
								nestedData = {{spellId = spellId, spellTable = spellTable, actorName = petName, value = 0}},
							}

							detailsFramework:Mixin(bkSpellData, Details.SpellTableMixin)
							breakdownSpellDataList[#breakdownSpellDataList+1] = bkSpellData
							alreadyAdded[spellName] = #breakdownSpellDataList
						end
					end
				end
			end
		end
	end

	--copy the keys from the spelltable and add them to the spelltableadv
	--repeated spells will be summed
	for i = 1, #breakdownSpellDataList do
		---@type spelltableadv
		local bkSpellData = breakdownSpellDataList[i]
		Details.SpellTableMixin.SumSpellTables(bkSpellData.spellTables, bkSpellData)
		--Details:Destroy(bkSpellData, "spellTables") --temporary fix for BuildSpellTargetFromBreakdownSpellData, that function need to use bkSpellData.nestedData
	end

	breakdownSpellDataList.totalValue = actorTotal
	breakdownSpellDataList.combatTime = actorCombatTime

	Details:Destroy(alreadyAdded)

	--send to the breakdown window
	Details222.BreakdownWindow.SendSpellData(breakdownSpellDataList, actorObject, combatObject, instance)

	--targets

	---an array of breakdowntargettable
	---@type breakdowntargettablelist
	local targetList = {}

	local targetTotalValue = 0

	local targetsTable = self:GetTargets()
	for targetName, amount in pairs(targetsTable) do
		---@class breakdowntargettable
		local bkTargetData = {
			name = targetName,
			total = amount,
			overheal = 0,
		}
		targetTotalValue = targetTotalValue + amount
		tinsert(targetList, bkTargetData)
	end

	targetList.totalValue = targetTotalValue
	targetList.combatTime = actorCombatTime

	Details222.BreakdownWindow.SendTargetData(targetList, actorObject, combatObject, instance)

	if 1 then return end

	--to be deprecated and removed:

	--gump:JI_AtualizaContainerBarras (#actorSpellsSorted + 1)

	local max_ = breakdownSpellDataList[1] and breakdownSpellDataList[1][2] or 0 --dano que a primeiro magia vez
	local barra

	--aura bar
	if (false) then --disabled for now
		barra = allLines [1]
		if (not barra) then
			barra = gump:CriaNovaBarraInfo1 (instance, 1)
		end
		self:UpdadeInfoBar(barra, "", -51, "Auras", max_, false, max_, 100, [[Interface\BUTTONS\UI-GroupLoot-DE-Up]], true, nil, nil)
		barra.textura:SetStatusBarColor(Details.gump:ParseColors("purple"))
	end

	--spell bars
	for index, tabela in ipairs(breakdownSpellDataList) do

		--index = index + 1 --with the aura bar
		index = index
		barra = allLines [index]
		if (not barra) then
			barra = gump:CriaNovaBarraInfo1 (instance, index)
		end

		barra.other_actor = tabela [6]

		local name = tabela[4]

		if (breakdownWindowFrame.sub_atributo == 2) then
			local formated_value = SelectedToKFunction(_, _math_floor(tabela[2]/actorCombatTime))
			self:UpdadeInfoBar(barra, index, tabela[1], name, tabela[2], formated_value, max_, tabela[3], tabela[5], true, nil, tabela [7])
		else
			local formated_value = SelectedToKFunction(_, _math_floor(tabela[2]))
			self:UpdadeInfoBar(barra, index, tabela[1], name, tabela[2], formated_value, max_, tabela[3], tabela[5], true, nil, tabela [7])
		end

		self:FocusLock(barra, tabela[1])
	end

	--targets
	if (instance.sub_atributo == DETAILS_SUBATTRIBUTE_ENEMIES) then
		local totalDamageTaken = self.damage_taken
		local damageTakenFrom = self.damage_from
		local combatObject = instance:GetShowingCombat()
		local damageContainer = combatObject:GetContainer(DETAILS_ATTRIBUTE_DAMAGE)
		local barras = breakdownWindowFrame.barras2
		local enemyTable = {}
		local targetName = self:Name()

		local enemyActorObject
		for enemyName in pairs(damageTakenFrom) do
			enemyActorObject = damageContainer:GetActor(enemyName)
			if (enemyActorObject) then
				local damageDoneToTarget = enemyActorObject.targets[targetName]
				if (damageDoneToTarget) then
					local npcId = DetailsFramework:GetNpcIdFromGuid(enemyActorObject:GetGUID())
					enemyTable[#enemyTable+1] = {enemyName, damageDoneToTarget, damageDoneToTarget / totalDamageTaken * 100, enemyActorObject:Class(), npcId}
				end
			end
		end

		local enemyAmount = #enemyTable

		if (enemyAmount < 1) then
			return true
		end

		gump:JI_AtualizaContainerAlvos(enemyAmount)

		table.sort(enemyTable, Details.Sort2)

		local topDamage = enemyTable[1] and enemyTable[1][2] or 0

		local thisLine
		for index, thisEnemyTable in ipairs(enemyTable) do
			thisLine = barras[index]

			if (not thisLine) then --se a barra n�o existir, criar ela ent�o
				thisLine = gump:CriaNovaBarraInfo2 (instance, index)
				thisLine.textura:SetStatusBarColor(1, 1, 1, 1) --isso aqui � a parte da sele��o e descele��o
			end

			if (index == 1) then
				thisLine.textura:SetValue(100)
			else
				thisLine.textura:SetValue(thisEnemyTable[2] / topDamage * 100)
			end

			thisLine.lineText1:SetText(index .. ". " .. Details:GetOnlyName(thisEnemyTable[1])) --left text
			thisLine.lineText4:SetText(Details:comma_value (thisEnemyTable[2]) .. " (" .. format("%.1f", thisEnemyTable[3]) .. "%)") --right text

			thisLine.icone:SetTexture([[Interface\AddOns\Details\images\classes_small_alpha]]) --class icon

			local texCoords = Details.class_coords[thisEnemyTable[4]]
			if (not texCoords) then
				texCoords = Details.class_coords["UNKNOW"]
			end
			thisLine.icone:SetTexCoord(unpack(texCoords))

			local color = Details.class_colors[thisEnemyTable[4]]
			if (color) then
				thisLine.textura:SetStatusBarColor(unpack(color))
			else
				thisLine.textura:SetStatusBarColor(1, 1, 1)
			end

			Details:name_space_info(thisLine)

			if (thisLine.mouse_over) then --atualizar o tooltip
				if (thisLine.isAlvo) then
					GameTooltip:Hide()
					GameTooltip:SetOwner(thisLine, "ANCHOR_TOPRIGHT")
					if (not thisLine.minha_tabela:MontaTooltipDamageTaken(thisLine, index)) then
						return
					end
					GameTooltip:Show()
				end
			end

			thisLine.minha_tabela = self --grava o jogador na tabela
			thisLine.nome_inimigo = thisEnemyTable[1] --salva o nome do inimigo na barra --isso � necess�rio?

			-- no rank do spell id colocar o que?
			thisLine.spellid = "enemies"

			thisLine:Show() --mostra a barra
		end
	else
		local combatObject = instance:GetShowingCombat()
		local damageContainer = combatObject:GetContainer(DETAILS_ATTRIBUTE_DAMAGE)
		local allActorTargets = {}

		--table with actor names and damage done which the player caused damage to
		local targetsTable = self.targets
		for targetName, damageDone in pairs(targetsTable) do
			tinsert(allActorTargets, {targetName, damageDone, damageDone / totalDamageWithoutPet * 100})
		end

		table.sort(allActorTargets, Details.Sort2)

		local enemyAmount = #allActorTargets
		if (enemyAmount < 1) then
			return
		end

		gump:JI_AtualizaContainerAlvos(enemyAmount)

		local topDamage = allActorTargets[1] and allActorTargets[1][2] or 0

		local barra
		for index, targetTable in ipairs(allActorTargets) do
			barra = breakdownWindowFrame.barras2[index]

			if (not barra) then
				barra = gump:CriaNovaBarraInfo2(instance, index)
				barra.textura:SetStatusBarColor(1, 1, 1, 1)
			end

			if (index == 1) then
				barra.textura:SetValue(100)
			else
				barra.textura:SetValue(targetTable[2] / topDamage * 100)
			end

			local targetName = targetTable[1]
			local targetActorObject = damageContainer:GetActor(targetName)

			if (targetActorObject) then
				local npcId = DetailsFramework:GetNpcIdFromGuid(targetActorObject:GetGUID())
				local portraitTexture -- = Details222.Textures.GetPortraitTextureForNpcID(npcId) disabled
				if (portraitTexture) then
					Details222.Textures.FormatPortraitAsTexture(portraitTexture, barra.icone)
				else
					targetActorObject:SetClassIcon(barra.icone, instance, targetActorObject.classe)
				end
			else
				barra.icone:SetTexture([[Interface\AddOns\Details\images\classes_small_alpha]]) --CLASSE
				local texCoords = Details.class_coords ["ENEMY"]
				barra.icone:SetTexCoord(unpack(texCoords))
			end

			barra.textura:SetStatusBarColor(1, 0.8, 0.8)
			barra.textura:SetStatusBarColor(1, 1, 1, 1)

			barra.lineText1:SetText(index .. ". " .. Details:GetOnlyName(targetName))

			if (breakdownWindowFrame.sub_atributo == 2) then
				barra.lineText4:SetText(Details:comma_value ( _math_floor(targetTable[2]/actorCombatTime)) .. " (" .. format("%.1f", targetTable[3]) .. "%)")
			else
				barra.lineText4:SetText(SelectedToKFunction(_, targetTable[2]) .." (" .. format("%.1f", targetTable[3]) .. "%)")
			end

			if (barra.mouse_over) then --atualizar o tooltip
				if (barra.isAlvo) then
					if (not barra.minha_tabela:MontaTooltipAlvos (barra, index, instance)) then
						return
					end
				end
			end

			barra.minha_tabela = self --grava o jogador na tabela
			barra.nome_inimigo = targetTable [1] --salva o nome do inimigo na barra --isso � necess�rio?

			-- no rank do spell id colocar o que?
			barra.spellid = targetTable[5]
			barra:Show()
		end
	end
end


------ Detalhe Info Friendly Fire
function damageClass:MontaDetalhesFriendlyFire (nome, barra)

	local barras = breakdownWindowFrame.barras3
	local instancia = breakdownWindowFrame.instancia

	local tabela_do_combate = breakdownWindowFrame.instancia.showing
	local showing = tabela_do_combate [class_type] --o que esta sendo mostrado -> [1] - dano [2] - cura --pega o container com ._NameIndexTable ._ActorTable

	local friendlyfire = self.friendlyfire

	local ff_table = self.friendlyfire [nome] --assumindo que nome � o nome do Alvo que tomou dano // bastaria pegar a tabela de habilidades dele
	if (not ff_table) then
		return
	end
	local total = ff_table.total

	local minhas_magias = {}

	for spellid, amount in pairs(ff_table.spells) do --da foreach em cada spellid do container
		local nome, _, icone = _GetSpellInfo(spellid)
		tinsert(minhas_magias, {spellid, amount, amount / total * 100, nome, icone})
	end

	_table_sort(minhas_magias, Details.Sort2)

	local max_ = minhas_magias[1] and minhas_magias[1][2] or 0 --dano que a primeiro magia vez
	local lastIndex = 1
	local barra
	for index, tabela in ipairs(minhas_magias) do
		lastIndex = index
		barra = barras [index]

		if (not barra) then --se a barra n�o existir, criar ela ent�o
			barra = gump:CriaNovaBarraInfo3 (instancia, index)
			barra.textura:SetStatusBarColor(1, 1, 1, 1) --isso aqui � a parte da sele��o e descele��o
		end

		barra.show = tabela[1]

		if (index == 1) then
			barra.textura:SetValue(100)
		else
			barra.textura:SetValue(tabela[2]/max_*100) --muito mais rapido...
		end

		barra.lineText1:SetText(index..instancia.divisores.colocacao..tabela[4]) --seta o texto da esqueda
		barra.lineText4:SetText(Details:comma_value (tabela[2]) .. " " .. instancia.divisores.abre .. format("%.1f", tabela[3]) .. "%" .. instancia.divisores.fecha) --seta o texto da direita

		barra.icone:SetTexture(tabela[5])
		barra.icone:SetTexCoord(0, 1, 0, 1)

		barra:Show() --mostra a barra

		if (index == 15) then
			break
		end
	end

	for i = lastIndex+1, #barras do
		barras[i]:Hide()
	end

end

-- detalhes info enemies
function damageClass:MontaDetalhesEnemy (spellid, barra)

	local container = breakdownWindowFrame.instancia.showing[1]
	local barras = breakdownWindowFrame.barras3
	local instancia = breakdownWindowFrame.instancia

	local other_actor = barra.other_actor
	if (other_actor) then
		self = other_actor
	end

	if (barra.lineText1:IsTruncated()) then
		Details:CooltipPreset(2)
		GameCooltip:SetOption("FixedWidth", nil)
		GameCooltip:AddLine(barra.lineText1.text)
		GameCooltip:SetOwner(barra, "bottomleft", "topleft", 5, -10)
		GameCooltip:ShowCooltip()
	end

	local spell = self.spells:PegaHabilidade (spellid)

	local targets = spell.targets
	local target_pool = {}

	for target_name, amount in pairs(targets) do
		local classe
		local this_actor = breakdownWindowFrame.instancia.showing (1, target_name)
		if (this_actor) then
			classe = this_actor.classe or "UNKNOW"
		else
			classe = "UNKNOW"
		end

		target_pool [#target_pool+1] = {target_name, amount, classe}
	end

	_table_sort(target_pool, Details.Sort2)

	local max_ = target_pool [1] and target_pool [1][2] or 0

	local lastIndex = 1
	local barra
	for index, tabela in ipairs(target_pool) do
		lastIndex = index
		barra = barras [index]

		if (not barra) then --se a barra n�o existir, criar ela ent�o
			barra = gump:CriaNovaBarraInfo3 (instancia, index)
			barra.textura:SetStatusBarColor(1, 1, 1, 1) --isso aqui � a parte da sele��o e descele��o
		end

		barra.show = tabela[1]

		if (index == 1) then
			barra.textura:SetValue(100)
		else
			barra.textura:SetValue(tabela[2]/max_*100) --muito mais rapido...
		end

		barra.lineText1:SetText(index .. ". " .. Details:GetOnlyName(tabela [1])) --seta o texto da esqueda
		Details:name_space_info (barra)

		if (spell.total > 0) then
			barra.lineText4:SetText(Details:comma_value (tabela[2]) .." (".. format("%.1f", tabela[2] / spell.total * 100) .."%)") --seta o texto da direita
		else
			barra.lineText4:SetText(tabela[2] .." (0%)") --seta o texto da direita
		end

		local texCoords = Details.class_coords [tabela[3]]
		if (not texCoords) then
			texCoords = Details.class_coords ["UNKNOW"]
		end

		local color = Details.class_colors [tabela[3]]
		if (color) then
			barra.textura:SetStatusBarColor(unpack(color))
		else
			barra.textura:SetStatusBarColor(1, 1, 1, 1)
		end

		barra.icone:SetTexture("Interface\\AddOns\\Details\\images\\classes_small_alpha")
		barra.icone:SetTexCoord(unpack(texCoords))

		barra:Show() --mostra a barra

		if (index == 15) then
			break
		end
	end

	for i = lastIndex+1, #barras do
		barras[i]:Hide()
	end


end

------ Detalhe Info Damage Taken
function damageClass:MontaDetalhesDamageTaken (nome, barra)

	local barras = breakdownWindowFrame.barras3
	local instancia = breakdownWindowFrame.instancia

	local tabela_do_combate = breakdownWindowFrame.instancia.showing
	local showing = tabela_do_combate [class_type] --o que esta sendo mostrado -> [1] - dano [2] - cura --pega o container com ._NameIndexTable ._ActorTable

	local este_agressor = showing._ActorTable[showing._NameIndexTable[nome]]

	if (not este_agressor ) then
		return
	end

	local conteudo = este_agressor.spells._ActorTable --pairs[] com os IDs das magias

	local actor = breakdownWindowFrame.jogador.nome

	local total = este_agressor.targets [actor] or 0

	local minhas_magias = {}

	for spellid, tabela in pairs(conteudo) do --da foreach em cada spellid do container
		local este_alvo = tabela.targets [actor]
		if (este_alvo) then --esta magia deu dano no actor
			local spell_nome, rank, icone = _GetSpellInfo(spellid)
			tinsert(minhas_magias, {spellid, este_alvo, este_alvo/total*100, spell_nome, icone})
		end
	end

	_table_sort(minhas_magias, Details.Sort2)

	--local amt = #minhas_magias
	--gump:JI_AtualizaContainerBarras (amt)

	local max_ = minhas_magias[1] and minhas_magias[1][2] or 0 --dano que a primeiro magia vez

	local lastIndex = 1
	local barra
	for index, tabela in ipairs(minhas_magias) do
		lastIndex = index
		barra = barras [index]

		if (not barra) then --se a barra n�o existir, criar ela ent�o
			barra = gump:CriaNovaBarraInfo3 (instancia, index)
			barra.textura:SetStatusBarColor(1, 1, 1, 1) --isso aqui � a parte da sele��o e descele��o
		end

		barra.show = tabela[1]

		if (index == 1) then
			barra.textura:SetValue(100)
		else
			barra.textura:SetValue(tabela[2]/max_*100)
		end

		barra.lineText1:SetText(index .. "." .. tabela[4]) --seta o texto da esqueda
		Details:name_space_info (barra)

		barra.lineText4:SetText(Details:comma_value (tabela[2]) .." ".. instancia.divisores.abre ..format("%.1f", tabela[3]) .."%".. instancia.divisores.fecha) --seta o texto da direita

		barra.icone:SetTexture(tabela[5])
		barra.icone:SetTexCoord(0, 1, 0, 1)

		barra:Show() --mostra a barra

		if (index == 15) then
			break
		end
	end

	for i = lastIndex+1, #barras do
		barras[i]:Hide()
	end

end

------ Detalhe Info Damage Done e Dps
--local defenses_table = {c = {117/255, 58/255, 0/255}, p = 0}
--local normal_table = {c = {255/255, 180/255, 0/255, 0.5}, p = 0}
--local critical_table = {c = {249/255, 74/255, 45/255, 0.5}, p = 0}

local defenses_table = {c = {1, 1, 1, 0.5}, p = 0}
local normal_table = {c = {1, 1, 1, 0.5}, p = 0}
local critical_table = {c = {1, 1, 1, 0.5}, p = 0}

local data_table = {}
local t1, t2, t3, t4 = {}, {}, {}, {}

local function FormatSpellString(str)
	return (string.gsub(str, "%d+", function(spellID)
				local name, _, icon = GetSpellInfo(spellID);
				return string.format("|T%s:16|t", icon);
			end));
end


local MontaDetalhesBuffProcs = function(actor, row, instance)

	instance = instance or breakdownWindowFrame.instancia

	local spec = actor.spec
	if (spec) then
		local mainAuras = Details.important_auras [spec]
		if (mainAuras) then
			local miscActor = instance:GetShowingCombat():GetActor(4, actor:name())
			if (miscActor and miscActor.buff_uptime_spells) then
				--get the auras
				local added = 0
				for i = 1, #mainAuras do
					local spellID = mainAuras [i]
					local spellObject = miscActor.buff_uptime_spells._ActorTable [spellID]
					if (spellObject) then
						local spellName, spellIcon = GetSpellInfo(spellID)
						local spellUptime = spellObject.uptime
						local spellApplies = spellObject.appliedamt
						local spellRefreshes = spellObject.refreshamt

						gump:SetaDetalheInfoTexto(i, 100, FormatSpellString ("" .. spellID .. " " .. spellName), "Activations: " .. spellApplies, " ", "Refreshes: " .. spellRefreshes, " ", "Uptime: " .. spellUptime .. "s")
						added = added + 1
					end
				end

				for i = added + 1, 5 do
					gump:HidaDetalheInfo (i)
				end

				return
			end
		end
	end

	for i = 1, 5 do
		gump:HidaDetalheInfo (i)
	end
end

---called from the spell breakdown when a spellbar is hovered over
---@param spellBar breakdownspellbar
---@param spellBlockContainer breakdownspellblockframe
---@param blockIndex number
---@param summaryBlock breakdownspellblock
---@param spellId number
---@param combatTime number
---@param actorName string
---@param spellTable spelltableadv
---@param trinketData trinketdata
---@param combatObject combat
function damageClass:BuildSpellDetails(spellBar, spellBlockContainer, blockIndex, summaryBlock, spellId, combatTime, actorName, spellTable, trinketData, combatObject)
	---@type number
	local totalHits = spellTable.counter

	--damage section showing damage done sub section
	blockIndex = blockIndex + 1

	do --update the texts in the summary block
		local blockLine1, blockLine2, blockLine3 = summaryBlock:GetLines()

		local totalCasts = spellBar.amountCasts > 0 and spellBar.amountCasts or "(?)"
		blockLine1.leftText:SetText(Loc ["STRING_CAST"] .. ": " .. totalCasts) --total amount of casts

		local trinketProcs = combatObject:GetTrinketProcsForPlayer(actorName)

		if (trinketData[spellId] and trinketProcs) then
			local trinketProcData = trinketProcs[actorName]
			if (trinketProcData) then
				local trinketProc = trinketProcData[spellId]
				if (trinketProc) then
					blockLine1.leftText:SetText("Procs: " .. trinketProc.total)
				end
			end

		elseif (Details.GetItemSpellInfo(spellId)) then
			blockLine1.leftText:SetText("Uses: " .. totalCasts)
		end

		blockLine1.rightText:SetText(Loc ["STRING_HITS"]..": " .. totalHits) --hits and uptime

		blockLine2.leftText:SetText(Loc ["STRING_DAMAGE"]..": " .. Details:Format(spellTable.total)) --total damage
		blockLine2.rightText:SetText(Details:GetSpellSchoolFormatedName(spellTable.spellschool)) --spell school

		blockLine3.leftText:SetText(Loc ["STRING_AVERAGE"] .. ": " .. Details:Format(spellBar.average)) --average damage
		if (spellBar.perSecond and spellBar.perSecond > 0) then
			blockLine3.rightText:SetText(Loc ["STRING_DPS"] .. ": " .. Details:CommaValue(spellBar.perSecond)) --dps
		else
			blockLine3.rightText:SetText(Loc ["STRING_DPS"] .. ": " .. Details:CommaValue(spellTable.total / combatTime)) --dps
		end
	end

	local emporwerSpell = spellTable.e_total
	if (emporwerSpell) then
		local empowerLevelSum = spellTable.e_total --total sum of empower levels
		local empowerAmount = spellTable.e_amt --amount of casts with empower
		local empowerAmountPerLevel = spellTable.e_lvl --{[1] = 4; [2] = 9; [3] = 15}
		local empowerDamagePerLevel = spellTable.e_dmg --{[1] = 54548745, [2] = 74548745}

		---@type breakdownspellblock
		local empowerBlock = spellBlockContainer:GetBlock(blockIndex)
		blockIndex = blockIndex + 1

		local level1AverageDamage = "0"
		local level2AverageDamage = "0"
		local level3AverageDamage = "0"
		local level4AverageDamage = "0"
		local level5AverageDamage = "0"

		if (empowerDamagePerLevel[1]) then
			level1AverageDamage = Details:Format(empowerDamagePerLevel[1] / empowerAmountPerLevel[1])
		end
		if (empowerDamagePerLevel[2]) then
			level2AverageDamage = Details:Format(empowerDamagePerLevel[2] / empowerAmountPerLevel[2])
		end
		if (empowerDamagePerLevel[3]) then
			level3AverageDamage = Details:Format(empowerDamagePerLevel[3] / empowerAmountPerLevel[3])
		end
		if (empowerDamagePerLevel[4]) then
			level4AverageDamage = Details:Format(empowerDamagePerLevel[4] / empowerAmountPerLevel[4])
		end
		if (empowerDamagePerLevel[5]) then
			level5AverageDamage = Details:Format(empowerDamagePerLevel[5] / empowerAmountPerLevel[5])
		end

		empowerBlock:Show()
		empowerBlock:SetValue(100)

		empowerBlock.sparkTexture:SetPoint("left", empowerBlock, "left", empowerBlock:GetWidth() + Details.breakdown_spell_tab.blockspell_spark_offset, 0)
		empowerBlock:SetColor(0.200, 0.576, 0.498, 0.6)

		local blockLine1, blockLine2, blockLine3 = empowerBlock:GetLines()
		blockLine1.leftText:SetText("Spell Empower Average Level: " .. string.format("%.2f", empowerLevelSum / empowerAmount))

		if (level1AverageDamage ~= "0") then
			blockLine2.leftText:SetText("#1 Avg: " .. level1AverageDamage .. " (" .. (empowerAmountPerLevel[1] or 0) .. ")")
		end

		if (level2AverageDamage ~= "0") then
			blockLine2.centerText:SetText("#2 Avg: " .. level2AverageDamage .. " (" .. (empowerAmountPerLevel[2] or 0) .. ")")
		end

		if (level3AverageDamage ~= "0") then
			blockLine2.rightText:SetText("#3 Avg: " .. level3AverageDamage .. " (" .. (empowerAmountPerLevel[3] or 0) .. ")")
		end

		if (level4AverageDamage ~= "0") then
			blockLine3.leftText:SetText("#4 Avg: " .. level4AverageDamage .. " (" .. (empowerAmountPerLevel[4] or 0) .. ")")
		end

		if (level5AverageDamage ~= "0") then
			blockLine3.rightText:SetText("#5 Avg: " .. level5AverageDamage .. " (" .. (empowerAmountPerLevel[5] or 0) .. ")")
		end
	end

	--check if there's normal hits and build the block
	---@type number
	local normalHitsAmt = spellTable.n_amt

	if (normalHitsAmt > 0) then
		---@type breakdownspellblock
		local normalHitsBlock = spellBlockContainer:GetBlock(blockIndex)
		normalHitsBlock:Show()
		blockIndex = blockIndex + 1

		local percent = normalHitsAmt / math.max(totalHits, 0.0001) * 100
		normalHitsBlock:SetValue(percent)
		normalHitsBlock.sparkTexture:SetPoint("left", normalHitsBlock, "left", percent / 100 * normalHitsBlock:GetWidth() + Details.breakdown_spell_tab.blockspell_spark_offset, 0)

		local blockLine1, blockLine2, blockLine3 = normalHitsBlock:GetLines()
		blockLine1.leftText:SetText(Loc ["STRING_NORMAL_HITS"])
		blockLine1.rightText:SetText(normalHitsAmt .. " [|cFFC0C0C0" .. string.format("%.1f", normalHitsAmt / math.max(totalHits, 0.0001) * 100) .. "%|r]")

		blockLine2.leftText:SetText(Loc ["STRING_MINIMUM_SHORT"] .. ": " .. Details:CommaValue(spellTable.n_min))
		blockLine2.rightText:SetText(Loc ["STRING_MAXIMUM_SHORT"] .. ": " .. Details:CommaValue(spellTable.n_max))

		local normalAverage = spellTable.n_total / math.max(normalHitsAmt, 0.0001)
		blockLine3.leftText:SetText(Loc ["STRING_AVERAGE"] .. ": " .. Details:CommaValue(normalAverage))

		local tempo = (combatTime * spellTable.n_total) / math.max(spellTable.total, 0.001)
		local normalAveragePercent = spellBar.average / normalAverage * 100
		local normalTempoPercent = normalAveragePercent * tempo / 100
		blockLine3.rightText:SetText(Loc ["STRING_DPS"] .. ": " .. Details:CommaValue(spellTable.n_total / normalTempoPercent))
	end

	---@type number
	local criticalHitsAmt = spellTable.c_amt
	if (criticalHitsAmt > 0) then
		---@type breakdownspellblock
		local critHitsBlock = spellBlockContainer:GetBlock(blockIndex)
		critHitsBlock:Show()
		blockIndex = blockIndex + 1

		local percent = Details.SpellTableMixin.GetCritPercent(spellTable)
		critHitsBlock:SetValue(percent)
		critHitsBlock.sparkTexture:SetPoint("left", critHitsBlock, "left", percent / 100 * critHitsBlock:GetWidth() + Details.breakdown_spell_tab.blockspell_spark_offset, 0)

		local blockLine1, blockLine2, blockLine3 = critHitsBlock:GetLines()
		blockLine1.leftText:SetText(Loc ["STRING_CRITICAL_HITS"])
		blockLine1.rightText:SetText(criticalHitsAmt .. " [|cFFC0C0C0" .. string.format("%.1f", criticalHitsAmt / math.max(totalHits, 0.0001) * 100) .. "%|r]")

		blockLine2.leftText:SetText(Loc ["STRING_MINIMUM_SHORT"] .. ": " .. Details:CommaValue(spellTable.c_min))
		blockLine2.rightText:SetText(Loc ["STRING_MAXIMUM_SHORT"] .. ": " .. Details:CommaValue(spellTable.c_max))

		local critAverage = Details.SpellTableMixin.GetCritAverage(spellTable)
		blockLine3.leftText:SetText(Loc ["STRING_AVERAGE"] .. ": " .. Details:CommaValue(critAverage))

		local tempo = (combatTime * spellTable.c_total) / math.max(spellTable.total, 0.001)
		local critAveragePercent = spellBar.average / critAverage * 100
		local critTempoPercent = critAveragePercent * tempo / 100
		blockLine3.rightText:SetText(Loc ["STRING_DPS"] .. ": " .. Details:CommaValue(spellTable.c_total / critTempoPercent))
	end

	--missing hits
	local semiDodgeAmount = spellTable.g_amt + spellTable.b_amt --glancing and blocking
	local fullDodgeAmount = spellTable["DODGE"] or 0
	local parryAmount = spellTable["PARRY"] or 0
	local missedHitsAmount = spellTable["MISS"] or 0

	local hitErrorsAmount = parryAmount + fullDodgeAmount + missedHitsAmount

	if (semiDodgeAmount > 0 or hitErrorsAmount > 0) then
		---@type breakdownspellblock
		local defensesBlock = spellBlockContainer:GetBlock(blockIndex)
		defensesBlock:Show()
		blockIndex = blockIndex + 1

		local percent = (semiDodgeAmount + hitErrorsAmount) / spellTable.counter * 100
		defensesBlock:SetValue(percent)
		defensesBlock.sparkTexture:SetPoint("left", defensesBlock, "left", percent / 100 * defensesBlock:GetWidth() + Details.breakdown_spell_tab.blockspell_spark_offset, 0)

		local blockLine1, blockLine2, blockLine3 = defensesBlock:GetLines()
		blockLine1.leftText:SetText(Loc ["STRING_DEFENSES"])
		blockLine1.rightText:SetText((semiDodgeAmount + hitErrorsAmount) .. " / " .. format("%.1f", percent) .. "%")

		if (missedHitsAmount > 0) then
			blockLine2.leftText:SetText("Miss" .. ": " .. missedHitsAmount)
		end
		if (parryAmount > 0) then
			blockLine2.centerText:SetText(Loc ["STRING_PARRY"] .. ": " .. parryAmount)
		end
		if (fullDodgeAmount > 0) then
			blockLine2.rightText:SetText(Loc ["STRING_DODGE"] .. ": " .. fullDodgeAmount)
		end
		if (spellTable.b_amt > 0) then
			blockLine3.leftText:SetText(Loc ["STRING_BLOCKED"] .. ": " .. spellTable.b_amt)
		end
		if (spellTable.g_amt > 0) then
			blockLine3.rightText:SetText(Loc ["STRING_GLANCING"] .. ": " .. spellTable.g_amt)
		end
	end

--[=[ percent
	Loc ["STRING_GLANCING"] .. ": " .. math.floor(spellTable.g_amt / spellTable.counter * 100) .. "%"
	Loc ["STRING_BLOCKED"] .. ": " .. math.floor(spellTable.b_amt / spellTable.counter * 100) .. "%"
--]=]


	if (trinketData[spellId]) then
		---@type trinketdata
		local trinketInfo = trinketData[spellId]

		local minTime = trinketInfo.minTime
		local maxTime = trinketInfo.maxTime
		local average = trinketInfo.averageTime

		---@type breakdownspellblock
		local trinketBlock = spellBlockContainer:GetBlock(blockIndex)
		trinketBlock:Show()
		trinketBlock:SetValue(100)
		trinketBlock.sparkTexture:SetPoint("left", trinketBlock, "left", trinketBlock:GetWidth() + Details.breakdown_spell_tab.blockspell_spark_offset, 0)
		blockIndex = blockIndex + 1

		local blockLine1, blockLine2, blockLine3 = trinketBlock:GetLines()
		blockLine1.leftText:SetText("Trinket Info")

		blockLine1.rightText:SetText("PPM: " .. string.format("%.2f", average / 60))
		if (minTime == 9999999) then
			blockLine2.leftText:SetText("Min Time: " .. _G["UNKNOWN"])
		else
			blockLine2.leftText:SetText("Min Time: " .. math.floor(minTime))
		end
		blockLine2.rightText:SetText("Max Time: " .. math.floor(maxTime))
	end
end

--this build p the 6 rectangle boxes in the right side of the breakdown window summary tab
function damageClass:MontaDetalhesDamageDone (spellId, spellLine, instance) --this should be ~deprecated with the new breakdown tab

	print("MontaDetalhesDamageDone - deprecated", debugstack())

	local spellTable
	if (spellLine.other_actor) then
		spellTable = spellLine.other_actor.spells._ActorTable [spellId]
		--self = spellLine.other_actor
	else
		spellTable = self.spells._ActorTable [spellId]
	end

	if (spellId == -51) then
		return MontaDetalhesBuffProcs(self, spellLine, instance)
	end

	if (not spellTable) then
		return
	end

	local spellName, _, icone = _GetSpellInfo(spellId)

	local bShouldMergePlayerAbilities = Details.merge_player_abilities
	local bShouldMergePetAbilities = Details.merge_pet_abilities

	if (bShouldMergePlayerAbilities or bShouldMergePetAbilities) then
		local mergedSpellTable = getSpellDetails(self:GetGUID(), spellName) --it's not merging
		if (mergedSpellTable) then
			spellTable = mergedSpellTable
		end
	end

	Details.BreakdownWindowFrame.spell_icone:SetTexture(icone)

	local total = self.total

	local meu_tempo
	if (Details.time_type == 1 or not self.grupo) then
		meu_tempo = self:Tempo()

	elseif (Details.time_type == 2 or Details.use_realtimedps) then
		meu_tempo = breakdownWindowFrame.instancia.showing:GetCombatTime()
	end

	local total_hits = spellTable.counter

	local index = 1
	local data = data_table

	Details:Destroy(t1)
	Details:Destroy(t2)
	Details:Destroy(t3)
	Details:Destroy(t4)
	Details:Destroy(data)

	--GERAL
		local media = 0
		if (total_hits > 0) then
			media = spellTable.total/total_hits
		end

		local this_dps = nil
		if (spellTable.counter > spellTable.c_amt) then
			this_dps = Loc ["STRING_DPS"] .. ": " .. Details:comma_value (spellTable.total/meu_tempo)
		else
			this_dps = Loc ["STRING_DPS"] .. ": " .. Loc ["STRING_SEE_BELOW"]
		end

		local spellschool, schooltext = spellTable.spellschool, ""
		if (spellschool) then
			local t = Details.spells_school [spellschool]
			if (t and t.name) then
				schooltext = t.formated
			end
		end

		local hits_string = "" .. total_hits
		local cast_string = Loc ["STRING_CAST"] .. ": "

		local misc_actor = breakdownWindowFrame.instancia.showing (4, self:name())
		if (misc_actor) then
			local uptime_spellid = spellTable.id
			local debuff_uptime = misc_actor.debuff_uptime_spells and misc_actor.debuff_uptime_spells._ActorTable [uptime_spellid] and misc_actor.debuff_uptime_spells._ActorTable [uptime_spellid].uptime
			if (debuff_uptime) then
				hits_string = hits_string .. "  |cFFDDDD44(" .. _math_floor(debuff_uptime / breakdownWindowFrame.instancia.showing:GetCombatTime() * 100) .. "% uptime)|r"
			end

			local amountOfCasts = breakdownWindowFrame.instancia.showing:GetSpellCastAmount(self:Name(), spellName)
			if (amountOfCasts == 0) then
				amountOfCasts = "(|cFFFFFF00?|r)"
			end
			cast_string = cast_string .. amountOfCasts
		end

		if (spellTable.e_total) then
			cast_string = Loc ["STRING_CAST"] .. ": " .. "|cFFFFFF00" .. spellTable.e_total .. "|r"
		end

		gump:SetaDetalheInfoTexto( index, 100,
			cast_string,
			Loc ["STRING_DAMAGE"]..": "..Details:ToK(spellTable.total),
			schooltext, --offhand,
			Loc ["STRING_AVERAGE"] .. ": " .. Details:comma_value (media),
			this_dps,
			Loc ["STRING_HITS"]..": " .. hits_string
		)

	--NORMAL
		local normal_hits = spellTable.n_amt
		if (normal_hits > 0) then
			local normal_dmg = spellTable.n_total
			local media_normal = normal_dmg/normal_hits
			local T = (meu_tempo*normal_dmg)/ max(spellTable.total, 0.001)
			local P = media/media_normal*100
			T = P*T/100

			normal_table.p = normal_hits/total_hits*100

			data[#data+1] = t1

			t1[1] = spellTable.n_amt
			t1[2] = normal_table
			t1[3] = Loc ["STRING_NORMAL_HITS"]
			t1[4] = Loc ["STRING_MINIMUM_SHORT"] .. ": " .. Details:comma_value (spellTable.n_min)
			t1[5] = Loc ["STRING_MAXIMUM_SHORT"] .. ": " .. Details:comma_value (spellTable.n_max)
			t1[6] = Loc ["STRING_AVERAGE"] .. ": " .. Details:comma_value (media_normal)
			t1[7] = Loc ["STRING_DPS"] .. ": " .. Details:comma_value (normal_dmg/T)
			t1[8] = normal_hits .. " [|cFFC0C0C0" .. format("%.1f", normal_hits/max(total_hits, 0.0001)*100) .. "%|r]"
			t1[9] = ""
		end

	--CRITICO
		if (spellTable.c_amt > 0) then
			local media_critico = spellTable.c_total/spellTable.c_amt
			local T = (meu_tempo*spellTable.c_total)/spellTable.total
			local P = media/max(media_critico, 0.0001)*100
			T = P*T/100
			local crit_dps = spellTable.c_total/T
			if (not crit_dps) then
				crit_dps = 0
			end

			critical_table.p = spellTable.c_amt/total_hits*100

			data[#data+1] = t2

			t2[1] = spellTable.c_amt
			t2[2] = critical_table
			t2[3] = Loc ["STRING_CRITICAL_HITS"]
			t2[4] = Loc ["STRING_MINIMUM_SHORT"] .. ": " .. Details:comma_value (spellTable.c_min)
			t2[5] = Loc ["STRING_MAXIMUM_SHORT"] .. ": " .. Details:comma_value (spellTable.c_max)
			t2[6] = Loc ["STRING_AVERAGE"] .. ": " .. Details:comma_value (media_critico)
			t2[7] = Loc ["STRING_DPS"] .. ": " .. Details:comma_value (crit_dps)
			t2[8] = spellTable.c_amt .. " [|cFFC0C0C0" .. format("%.1f", spellTable.c_amt/total_hits*100) .. "%|r]"
			t2[9] = ""
		end

	--Outros erros: GLACING, resisted, blocked, absorbed
		local outros_desvios = spellTable.g_amt + spellTable.b_amt
		local parry = spellTable ["PARRY"] or 0
		local dodge = spellTable ["DODGE"] or 0
		local misses = spellTable ["MISS"] or 0

		local erros = parry + dodge + misses

		if (outros_desvios > 0 or erros > 0) then
			local porcentagem_defesas = (outros_desvios + erros) / total_hits * 100

			data[#data+1] = t3
			defenses_table.p = porcentagem_defesas

			t3[1] = outros_desvios+erros
			t3[2] = defenses_table
			t3[3] = Loc ["STRING_DEFENSES"]
			t3[4] = Loc ["STRING_GLANCING"] .. ": " .. _math_floor(spellTable.g_amt/spellTable.counter*100) .. "%"
			t3[5] = Loc ["STRING_PARRY"] .. ": " .. parry
			t3[6] = Loc ["STRING_DODGE"] .. ": " .. dodge
			t3[7] = Loc ["STRING_BLOCKED"] .. ": " .. _math_floor(spellTable.b_amt/spellTable.counter*100)
			t3[8] = (outros_desvios+erros) .. " / " .. format("%.1f", porcentagem_defesas) .. "%"
			t3[9] = "MISS" .. ": " .. misses
		end

	--~empowered
	if (spellTable.e_total) then
		local empowerLevelSum = spellTable.e_total --total sum of empower levels
		local empowerAmount = spellTable.e_amt --amount of casts with empower
		local empowerAmountPerLevel = spellTable.e_lvl --{[1] = 4; [2] = 9; [3] = 15}
		local empowerDamagePerLevel = spellTable.e_dmg --{[1] = 54548745, [2] = 74548745}

		data[#data+1] = t4

		local level1AverageDamage = "0"
		local level2AverageDamage = "0"
		local level3AverageDamage = "0"
		local level4AverageDamage = "0"
		local level5AverageDamage = "0"

		if (empowerDamagePerLevel[1]) then
			level1AverageDamage = Details:ToK(empowerDamagePerLevel[1] / empowerAmountPerLevel[1])
		end
		if (empowerDamagePerLevel[2]) then
			level2AverageDamage = Details:ToK(empowerDamagePerLevel[2] / empowerAmountPerLevel[2])
		end
		if (empowerDamagePerLevel[3]) then
			level3AverageDamage = Details:ToK(empowerDamagePerLevel[3] / empowerAmountPerLevel[3])
		end
		if (empowerDamagePerLevel[4]) then
			level4AverageDamage = Details:ToK(empowerDamagePerLevel[4] / empowerAmountPerLevel[4])
		end
		if (empowerDamagePerLevel[5]) then
			level5AverageDamage = Details:ToK(empowerDamagePerLevel[5] / empowerAmountPerLevel[5])
		end

		t4[1] = 0
		t4[2] = {p = 100, c = {0.200, 0.576, 0.498, 0.6}}
		t4[3] = "Spell Empower Average Level: " .. format("%.2f", empowerLevelSum / empowerAmount)
		t4[4] = ""
		t4[5] = ""
		t4[6] = ""
		t4[10] = ""
		t4[11] = ""

		if (level1AverageDamage ~= "0") then
			t4[4] = "Level 1 Avg: " .. level1AverageDamage .. " (" .. (empowerAmountPerLevel[1] or 0) .. ")"
		end

		if (level2AverageDamage ~= "0") then
			t4[6] = "Level 2 Avg: " .. level2AverageDamage .. " (" .. (empowerAmountPerLevel[2] or 0) .. ")"
		end

		if (level3AverageDamage ~= "0") then
			t4[11] = "Level 3 Avg: " .. level3AverageDamage .. " (" .. (empowerAmountPerLevel[3] or 0) .. ")"
		end

		if (level4AverageDamage ~= "0") then
			t4[10] = "Level 4 Avg: " .. level4AverageDamage .. " (" .. (empowerAmountPerLevel[4] or 0) .. ")"
		end

		if (level5AverageDamage ~= "0") then
			t4[5] = "Level 5 Avg: " .. level5AverageDamage .. " (" .. (empowerAmountPerLevel[5] or 0) .. ")"
		end
	end

	--Details:BuildPlayerDetailsSpellChart()
	--DetailsPlayerDetailSmallChart.ShowChart (Details.BreakdownWindowFrame.grupos_detalhes [5].bg, info.instancia.showing, info.instancia.showing.cleu_events, self.nome, false, spellid, 1, 2, 3, 4, 5, 6, 7, 8, 15)

	--spell damage chart
	--events: 1 2 3 4 5 6 7 8 15
	local spellTable = spellTable

	local blockId = 6

	if false then --debug the stuff for the chart damage done in the 6th spellblock
		--GetBlockIndex doesn't exists anymore
		local thatRectangle66 = Details222.BreakdownWindow.GetBlockIndex(blockId)
		thatRectangle66 = thatRectangle66:GetFrame()

		--hide all textures created
		if (thatRectangle66.ChartTextures) then
			for i = 1, #thatRectangle66.ChartTextures do
				thatRectangle66.ChartTextures[i]:Hide()
			end
		end

		local chartData = Details222.TimeCapture.GetChartDataFromSpell(spellTable)
		if (chartData and instance) then
			local width, height = thatRectangle66:GetSize()
			--reset which texture is the next to be used
			thatRectangle66.nextChartTextureId = 1

			local amountOfTimeStamps = 12

			if (not thatRectangle66.timeStamps) then
				thatRectangle66.timeStamps = {}
				for i = 1, amountOfTimeStamps do
					thatRectangle66.timeStamps[i] = thatRectangle66:CreateFontString(nil, "overlay", "GameFontNormal")
					thatRectangle66.timeStamps[i]:SetPoint("topleft", thatRectangle66, "topleft", 2 + (i - 1) * (width / amountOfTimeStamps), -2)
					DetailsFramework:SetFontSize(thatRectangle66.timeStamps[i], 9)
				end
			end

			if (not thatRectangle66.bloodLustIndicators) then
				thatRectangle66.bloodLustIndicators = {}
				for i = 1, 5 do
					local thisIndicator = thatRectangle66:CreateTexture(nil, "artwork", nil, 4)
					thisIndicator:SetColorTexture(0.0980392, 0.0980392, 0.439216)
					thatRectangle66.bloodLustIndicators[#thatRectangle66.bloodLustIndicators+1] = thisIndicator
				end
			end

			for i = 1, #thatRectangle66.bloodLustIndicators do
				thatRectangle66.bloodLustIndicators[i]:Hide()
			end

			if (not thatRectangle66.ChartTextures) then
				thatRectangle66.ChartTextures = {}
				function thatRectangle66:GetChartTexture()
					local thisTexture = thatRectangle66.ChartTextures[thatRectangle66.nextChartTextureId]
					if (not thisTexture) then
						thisTexture = thatRectangle66:CreateTexture(nil, "artwork", nil, 5)
						thisTexture:SetColorTexture(1, 1, 1, 0.65)
						thatRectangle66.ChartTextures[thatRectangle66.nextChartTextureId] = thisTexture
					end
					thatRectangle66.nextChartTextureId = thatRectangle66.nextChartTextureId + 1

					return thisTexture
				end
			end

			--elapsed combat time
			local combatObject = instance:GetShowingCombat()
			local combatTime = math.floor(combatObject:GetCombatTime())
			thatRectangle66.timeStamps[1]:SetText(DetailsFramework:IntegerToTimer(0))
			for i = 2, #thatRectangle66.timeStamps do
				local timePerSegment = combatTime / #thatRectangle66.timeStamps
				thatRectangle66.timeStamps[i]:SetText(DetailsFramework:IntegerToTimer(i * timePerSegment))
			end
			--compute the width oif each texture
			local textureWidth = width / combatTime
			--compute the max height of a texture can have
			local maxValue = 0
			local numData = 0

			--need to put the data in order FIRST
			--each damage then need to be parsed

			local dataInOrder = {}

			local CONST_INDEX_TIMESTAMP = 1
			local CONST_INDEX_DAMAGEDONE = 2
			local CONST_INDEX_EVENTDAMAGE = 3

			for timeStamp, value in pairs(chartData) do
				dataInOrder[#dataInOrder+1] = {timeStamp, value}
				dataInOrder[#dataInOrder+1] = {timeStamp, value}
				dataInOrder[#dataInOrder+1] = {timeStamp, value}
				numData = numData + 1
			end

			table.sort(dataInOrder, function(t1, t2)  return t1[CONST_INDEX_TIMESTAMP] < t2[CONST_INDEX_TIMESTAMP] end)
			local damageDoneByTime = dataInOrder

			--parser the damage done
			local currentTotalDamage = 0

			for i = 1, #damageDoneByTime do
				local damageEvent = damageDoneByTime[i]

				local atTime = damageEvent[CONST_INDEX_TIMESTAMP]
				local totalDamageUntilHere = damageEvent[CONST_INDEX_DAMAGEDONE] --raw damage

				local spellDamage = totalDamageUntilHere - currentTotalDamage
				currentTotalDamage = currentTotalDamage + spellDamage

				damageEvent[CONST_INDEX_EVENTDAMAGE] = spellDamage

				maxValue = math.max(spellDamage, maxValue)
			end

			--build the chart
			for i = 1, #damageDoneByTime do
			--for timeStamp, value in pairs(chartData) do --as it is pairs the data is scattered
				local damageEvent = damageDoneByTime[i]
				local timeStamp = damageEvent[CONST_INDEX_TIMESTAMP]
				local damageDone = damageEvent[CONST_INDEX_EVENTDAMAGE]

				local thisTexture = thatRectangle66:GetChartTexture()
				thisTexture:SetWidth(textureWidth)

				local texturePosition = textureWidth * timeStamp

				thisTexture:SetPoint("bottomleft", thatRectangle66, "bottomleft", 1 + texturePosition, 1)

				local percentFromPeak = damageDone / maxValue --normalized
				thisTexture:SetHeight(math.min(percentFromPeak * height, height - 15))
				thisTexture:Show()
			end

			--show bloodlust indicators, member .bloodlust is not guarantted
			if (combatObject.bloodlust) then
				--bloodlust not being added into the combat object, probably a bug on Parser
				local bloodlustDuration = 40
				for i = 1, #combatObject.bloodlust do
					thatRectangle66.bloodLustIndicators[i]:Show()
					thatRectangle66.bloodLustIndicators[i]:SetAlpha(0.46)
					thatRectangle66.bloodLustIndicators[i]:SetSize(bloodlustDuration / combatTime * width, height - 2)
					thatRectangle66.bloodLustIndicators[i]:SetPoint("bottomleft", thatRectangle66, "bottomleft", 0, 0)
				end
			end

			DetailsBreakdownWindow_DetalheInfoBG_bg_end6:Hide()
			thatRectangle66:SetShown(true)
		end
	end

	_table_sort(data, Details.Sort1)

	for index, tabela in ipairs(data) do
		gump:SetaDetalheInfoTexto(index+1, tabela[2], tabela[3], tabela[4], tabela[5], tabela[6], tabela[7], tabela[8], tabela[9], tabela[10], tabela[11], tabela[12])
	end

	for i = #data+2, 5 do
		gump:HidaDetalheInfo(i)
	end
end

function Details:BuildPlayerDetailsSpellChart()
	local playerDetailSmallChart = DetailsPlayerDetailSmallChart

	if (not playerDetailSmallChart) then

		playerDetailSmallChart = CreateFrame("frame", "DetailsPlayerDetailSmallChart", breakdownWindowFrame,"BackdropTemplate")
		DetailsFramework:ApplyStandardBackdrop(playerDetailSmallChart)
		playerDetailSmallChart.Lines = {}

		for i = 1, 200 do
			local texture = playerDetailSmallChart:CreateTexture(nil, "artwork")
			texture:SetColorTexture(1, 1, 1, 1)
			tinsert(playerDetailSmallChart.Lines, texture)
		end

		--Details.BreakdownWindowFrame.grupos_detalhes [index]
		function playerDetailSmallChart.ShowChart (parent, combatObject, cleuData, playerName, targetName, spellId, ...)
			local tokenIdList = {}
			local eventList = {}

			--build the list of tokens
			for i = 1, select("#", ... ) do
				local tokenId = select(i, ...)
				tokenIdList [tokenId] = true
			end

			--check which lines can be added
			local index = 1
			local peakValue = 0

			for i = 1, cleuData.n -1 do
				local event = cleuData [i]
				if (event [2]) then --index 2 = token
					local playerNameFilter = playerName and playerName == event [3]
					local targetNameFilter = targetName and targetName == event [4]
					local spellIdFilter = spellId and spellId == event [5]

					if (playerNameFilter or targetNameFilter or spellIdFilter) then
						eventList [index] = cleuData [i]
						if (peakValue < cleuData [i] [6]) then
							peakValue = cleuData [i] [6]
						end
						index = index + 1
					end
				end
			end

			--200 lines, adjust the mini chart
			playerDetailSmallChart:SetPoint("topleft", parent, "topleft")
			playerDetailSmallChart:SetPoint("bottomright", parent, "bottomright")

			--update lines
			local width = playerDetailSmallChart:GetWidth()
			local combatTime = combatObject:GetCombatTime()
			local secondsPerBar = combatTime / 200
			local barWidth = width / 200
			local barHeight = playerDetailSmallChart:GetHeight()

			local currentTime = eventList [1][1]
			local currentIndex = 1
			local eventAmount = #eventList

			for i = 1, #playerDetailSmallChart.Lines do
				playerDetailSmallChart.Lines [i]:SetWidth(width / 200)
				playerDetailSmallChart.Lines [i]:SetHeight(1)

				for o = currentIndex, eventAmount do
					if (eventList [o][1] <= currentTime + secondsPerBar or eventList [o][1] >= currentTime) then
						playerDetailSmallChart.Lines [i]:SetPoint("bottomleft", playerDetailSmallChart, "bottomleft", barWidth  * (i - 1), 0)
						playerDetailSmallChart.Lines [i]:SetWidth(barWidth)
						playerDetailSmallChart.Lines [i]:SetHeight(eventList [o][6] / peakValue * barHeight)
					else
						currentIndex = o
						break
					end
				end

				currentTime = currentTime + secondsPerBar
			end
		end
	end
end

function damageClass:MontaTooltipDamageTaken (thisLine, index)
	local aggressor = breakdownWindowFrame.instancia.showing [1]:PegarCombatente (_, thisLine.nome_inimigo)
	local container = aggressor.spells._ActorTable
	local habilidades = {}

	local total = 0

	for spellid, spell in pairs(container) do
		for target_name, amount in pairs(spell.targets) do
			if (target_name == self.nome) then
				total = total + amount
				habilidades [#habilidades+1] = {spellid, amount}
			end
		end
	end

	_table_sort(habilidades, Details.Sort2)

	GameTooltip:AddLine(index..". "..thisLine.nome_inimigo)
	GameTooltip:AddLine(Loc ["STRING_DAMAGE_TAKEN_FROM2"]..":")
	GameTooltip:AddLine(" ")

	for index, tabela in ipairs(habilidades) do
		local nome, _, icone = _GetSpellInfo(tabela[1])
		if (index < 8) then
			GameTooltip:AddDoubleLine (index..". |T"..icone..":0|t "..nome, Details:comma_value (tabela[2]).." ("..format("%.1f", tabela[2]/total*100).."%)", 1, 1, 1, 1, 1, 1)
		else
			GameTooltip:AddDoubleLine (index..". "..nome, Details:comma_value (tabela[2]).." ("..format("%.1f", tabela[2]/total*100).."%)", .65, .65, .65, .65, .65, .65)
		end
	end

	return true
	--GameTooltip:AddDoubleLine (meus_danos[i][4][1]..": ", meus_danos[i][2].." (".._cstr("%.1f", meus_danos[i][3]).."%)", 1, 1, 1, 1, 1, 1)

end

function damageClass:MontaTooltipAlvos (thisLine, index, instancia) --~deprecated

	local inimigo = thisLine.nome_inimigo
	local habilidades = {}
	local total = self.total
	local i = 1

	Details:FormatCooltipForSpells()
	GameCooltip:SetOwner(thisLine, "bottom", "top", 4, -2)
	GameCooltip:SetOption("MinWidth", _math_max (230, thisLine:GetWidth()*0.98))

	for spellid, spell in pairs(self.spells._ActorTable) do
		if (spell.isReflection) then
			for target_name, amount in pairs(spell.targets) do
				if (target_name == inimigo) then
					for reflectedSpellId, amount in pairs(spell.extra) do
						local spellName, _, spellIcon = _GetSpellInfo(reflectedSpellId)
						local t = habilidades [i]
						if (not t) then
							habilidades [i] = {}
							t = habilidades [i]
						end

						t[1], t[2], t[3] = spellName .. " (|cFFCCBBBBreflected|r)", amount, spellIcon
						i = i + 1
					end
				end
			end
		else
			for target_name, amount in pairs(spell.targets) do
				if (target_name == inimigo) then
					local nome, _, icone = _GetSpellInfo(spellid)

					local t = habilidades [i]
					if (not t) then
						habilidades [i] = {}
						t = habilidades [i]
					end

					t[1], t[2], t[3] = nome, amount, icone
					i = i + 1
				end
			end
		end
	end

	--add pets
	for _, PetName in ipairs(self.pets) do
		local PetActor = instancia.showing (class_type, PetName)
		if (PetActor) then
			local PetSkillsContainer = PetActor.spells._ActorTable
			for _spellid, _skill in pairs(PetSkillsContainer) do

				local alvos = _skill.targets
				for target_name, amount in pairs(alvos) do
					if (target_name == inimigo) then

						local t = habilidades [i]
						if (not t) then
							habilidades [i] = {}
							t = habilidades [i]
						end

						local nome, _, icone = _GetSpellInfo(_spellid)
						t[1], t[2], t[3] = nome .. " (" .. PetName:gsub((" <.*"), "") .. ")", amount, icone

						i = i + 1
					end
				end
			end
		end
	end

	_table_sort(habilidades, Details.Sort2)

	--get time type
	local meu_tempo
	if (Details.time_type == 1 or not self.grupo) then
		meu_tempo = self:Tempo()
	elseif (Details.time_type == 2 or Details.use_realtimedps) then
		meu_tempo = breakdownWindowFrame.instancia.showing:GetCombatTime()
	end

	local is_dps = breakdownWindowFrame.instancia.sub_atributo == 2

	if (is_dps) then
		Details:AddTooltipSpellHeaderText (Loc ["STRING_DAMAGE_DPS_IN"] .. ":", {1, 0.9, 0.0, 1}, 1, Details.tooltip_spell_icon.file, unpack(Details.tooltip_spell_icon.coords))
		Details:AddTooltipHeaderStatusbar (1, 1, 1, 1)

	else
		Details:AddTooltipSpellHeaderText (Loc ["STRING_DAMAGE_FROM"] .. ":", {1, 0.9, 0.0, 1}, 1, Details.tooltip_spell_icon.file, unpack(Details.tooltip_spell_icon.coords))
		Details:AddTooltipHeaderStatusbar (1, 1, 1, 1)
	end

	local icon_size = Details.tooltip.icon_size
	local icon_border = Details.tooltip.icon_border_texcoord

	local topSpellDamage = habilidades[1] and habilidades[1][2]

	if (topSpellDamage) then
		for index, tabela in ipairs(habilidades) do
			if (tabela [2] < 1) then
				break
			end

			if (is_dps) then
				--GameCooltip:AddDoubleLine (index..". |T"..tabela[3]..":0|t "..tabela[1], Details:comma_value ( _math_floor(tabela[2] / meu_tempo) ).." (".._cstr("%.1f", tabela[2]/total*100).."%)", 1, 1, 1, 1, 1, 1)
				GameCooltip:AddLine(tabela[1], Details:comma_value ( _math_floor(tabela[2] / meu_tempo) ).." ("..format("%.1f", tabela[2]/total*100).."%)")
			else
				--GameCooltip:AddDoubleLine (index..". |T"..tabela[3]..":0|t " .. tabela[1], SelectedToKFunction(_, tabela[2]) .. " (".._cstr("%.1f", tabela[2]/total*100).."%)", 1, 1, 1, 1, 1, 1)
				GameCooltip:AddLine(tabela[1], SelectedToKFunction(_, tabela[2]) .. " ("..format("%.1f", tabela[2]/total*100).."%)")
			end

			GameCooltip:AddIcon (tabela[3], nil, nil, icon_size.W + 4, icon_size.H + 4, icon_border.L, icon_border.R, icon_border.T, icon_border.B)
			Details:AddTooltipBackgroundStatusbar (false, tabela[2] / topSpellDamage * 100)
		end
	end

	GameCooltip:Show()

	return true
end

--controls the activity time of the actor
function damageClass:GetOrChangeActivityStatus(activityStatus)
	if (activityStatus == nil) then
		--if no value passed, return the current activity status
		return self.dps_started

	elseif (activityStatus) then
		self.dps_started = true
		Details222.TimeMachine.AddActor(self)

	else
		self.dps_started = false
		Details222.TimeMachine.RemoveActor(self)
	end
end

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--core functions

	--clear cache tables when resetting data
		function damageClass:ClearCacheTables()
			for i = #ntable, 1, -1 do
				ntable [i] = nil
			end

			for i = #vtable, 1, -1 do
				vtable [i] = nil
			end

			for i = #bs_table, 1, -1 do
				bs_table [i] = nil
			end

			if (bs_tooltip_table) then
				Details:Destroy(bs_tooltip_table)
			end

			if (frags_tooltip_table) then
				Details:Destroy(frags_tooltip_table)
			end

			Details:Destroy(bs_index_table)
			Details:Destroy(tooltip_temp_table)
			Details:Destroy(tooltip_void_zone_temp)
		end

	--atualize a funcao de abreviacao
		function damageClass:UpdateSelectedToKFunction()
			SelectedToKFunction = ToKFunctions [Details.ps_abbreviation]
			FormatTooltipNumber = ToKFunctions [Details.tooltip.abbreviation]
			TooltipMaximizedMethod = Details.tooltip.maximize_method
			headerColor = Details.tooltip.header_text_color
		end

	--diminui o total das tabelas do combate
		function damageClass:subtract_total (combat_table)
			combat_table.totals [class_type] = combat_table.totals [class_type] - self.total
			if (self.grupo) then
				combat_table.totals_grupo [class_type] = combat_table.totals_grupo [class_type] - self.total
			end
		end
		function damageClass:add_total (combat_table)
			combat_table.totals [class_type] = combat_table.totals [class_type] + self.total
			if (self.grupo) then
				combat_table.totals_grupo [class_type] = combat_table.totals_grupo [class_type] + self.total
			end
		end

	---sum the passed actor into a combat, if the combat isn't passed, it will use the overall combat
	---the function returns the actor that was created of found in the combat passed
	---@param actorObject actor
	---@param bRefreshActor boolean|nil
	---@param combatObject combat|nil
	---@return actor
	function damageClass:AddToCombat(actorObject, bRefreshActor, combatObject)
		--check if there's a custom combat, if not just use the overall container
		combatObject = combatObject or Details.tabela_overall --same as Details:GetCombat(DETAILS_SEGMENTID_OVERALL)

		--check if the combatObject has an actor with the same name, if not, just create one new
		local actorContainer = combatObject[DETAILS_ATTRIBUTE_DAMAGE] --same as combatObject:GetContainer(DETAILS_ATTRIBUTE_DAMAGE)
		local overallActor = actorContainer._ActorTable[actorContainer._NameIndexTable[actorObject.nome]] --same as actorContainer:GetActor(actorObject:Name())

		if (not overallActor) then
			overallActor = actorContainer:GetOrCreateActor(actorObject.serial, actorObject.nome, actorObject.flag_original, true)
			overallActor.classe = actorObject.classe
			overallActor:SetSpecId(actorObject.spec)
			overallActor.isTank = actorObject.isTank
			overallActor.pvp = actorObject.pvp
			overallActor.boss = actorObject.boss
			overallActor.start_time = time() - 3
			overallActor.end_time = time()
		end

		overallActor.displayName = actorObject.displayName or actorObject.nome
		overallActor.boss_fight_component = actorObject.boss_fight_component or overallActor.boss_fight_component
		overallActor.fight_component = actorObject.fight_component or overallActor.fight_component
		overallActor.grupo = actorObject.grupo or overallActor.grupo

		--check if need to restore meta tables and indexes for this actor
		if (bRefreshActor) then
			--this call will reenable the metatable, __index and set the metatable on the .spells container
			Details.refresh:r_atributo_damage(actorObject)
		end

		--elapsed time
		local endTime = actorObject.end_time
		if (not actorObject.end_time) then
			endTime = time()
		end

		local tempo = endTime - actorObject.start_time
		overallActor.start_time = overallActor.start_time - tempo

		--pets (add unique pet names)
		for _, petName in ipairs(actorObject.pets) do --same as actorObject:GetPets()
			DetailsFramework.table.addunique(overallActor.pets, petName)
		end

		---@cast actorObject actordamage

		--sum total damage
		overallActor.total = overallActor.total + actorObject.total
		overallActor.total_extra = overallActor.total_extra + actorObject.total_extra
		overallActor.totalabsorbed = overallActor.totalabsorbed + actorObject.totalabsorbed

		--sum total damage without pet
		overallActor.total_without_pet = overallActor.total_without_pet + actorObject.total_without_pet

		--sum total damage taken
		overallActor.damage_taken = overallActor.damage_taken + actorObject.damage_taken

		--sum friendly fire
		overallActor.friendlyfire_total = overallActor.friendlyfire_total + actorObject.friendlyfire_total

		--sum total damage on the combatObject passed
		combatObject.totals[1] = combatObject.totals[1] + actorObject.total
		if (actorObject.grupo) then
			combatObject.totals_grupo[1] = combatObject.totals_grupo[1] + actorObject.total
		end

		--copy damage taken from
		for aggressorName, _ in pairs(actorObject.damage_from) do
			overallActor.damage_from[aggressorName] = true
		end

		--copy targets
		for targetName, amount in pairs(actorObject.targets) do
			overallActor.targets[targetName] = (overallActor.targets[targetName] or 0) + amount
		end

		--copy raid targets
		for flag, amount in pairs(actorObject.raid_targets) do
			overallActor.raid_targets = overallActor.raid_targets or {}
			overallActor.raid_targets[flag] = (overallActor.raid_targets[flag] or 0) + amount
		end

		---@type spellcontainer
		local overallSpellsContainer = overallActor.spells --same as overallActor:GetSpellContainer("spell")

		--copy spell table
		for spellId, spellTable in pairs(actorObject.spells._ActorTable) do --same as overallSpellsContainer:GetRawSpellTable()
			--var name has 'overall' but this function accepts any combat table
			local overallSpellTable = overallSpellsContainer:GetOrCreateSpell(spellId, true)

			--sum spell targets
			for targetName, amount in pairs(spellTable.targets) do
				overallSpellTable.targets[targetName] = (overallSpellTable.targets[targetName] or 0) + amount
			end

			--refresh and add extra values
			for extraSpellId, amount in pairs(spellTable.extra) do
				overallSpellTable.extra[extraSpellId] = (overallSpellTable.extra[extraSpellId] or 0) + amount
			end

			overallSpellTable.spellschool = spellTable.spellschool

			--sum all values of the spelltable which can be summed
			for key, value in pairs(spellTable) do
				if (type(value) == "number") then
					if (key ~= "id" and key ~= "spellschool") then
						if (not overallSpellTable [key]) then
							overallSpellTable [key] = 0
						end

						if (key == "n_min" or key == "c_min") then
							if (overallSpellTable [key] > value) then
								overallSpellTable [key] = value
							end
						elseif (key == "n_max" or key == "c_max") then
							if (overallSpellTable [key] < value) then
								overallSpellTable [key] = value
							end
						else
							overallSpellTable [key] = overallSpellTable [key] + value
						end
					end

				--empowered spells
				elseif(key == "e_dmg" or key == "e_lvl") then
					if (not overallSpellTable[key]) then
						overallSpellTable[key] = {}
					end
					for empowermentLevel, empowermentValue in pairs(spellTable[key]) do
						overallSpellTable[key][empowermentLevel] = empowermentValue
					end
				end
			end
		end

		if (actorObject.augmentedSpellsContainer) then
			local overallAugmentedSpellsContainer = overallActor.augmentedSpellsContainer or spellContainerClass:CreateSpellContainer(Details.container_type.CONTAINER_DAMAGE_CLASS)
			overallActor.augmentedSpellsContainer = overallAugmentedSpellsContainer

			for spellId, spellTable in pairs(actorObject.augmentedSpellsContainer._ActorTable) do --same as actorObject.augmentedSpellsContainer:GetRawSpellTable()
				local overallSpellTable = overallAugmentedSpellsContainer:GetOrCreateSpell(spellId, true)
				overallSpellTable.total = overallSpellTable.total + spellTable.total
				for targetName, amount in pairs(spellTable.targets) do
					overallSpellTable.targets[targetName] = (overallSpellTable.targets[targetName] or 0) + amount
				end
			end
		end

		--copy the friendly fire container
		for targetName, friendlyFireTable in pairs(actorObject.friendlyfire) do
			--get or create the friendly fire table in the overall data
			local friendlyFireOverall = overallActor.friendlyfire[targetName] or overallActor:CreateFFTable(targetName)
			--sum the total
			friendlyFireOverall.total = friendlyFireOverall.total + friendlyFireTable.total
			--sum spells
			for friendlyFireSpellId, amount in pairs(friendlyFireTable.spells) do
				friendlyFireOverall.spells[friendlyFireSpellId] = (friendlyFireOverall.spells[friendlyFireSpellId] or 0) + amount
			end
		end

		return overallActor
	end

--actor 1 is who will receive the sum from actor2
function Details.SumDamageActors(actor1, actor2, actorContainer) --not called anywhere, can be deprecated
	--general
	actor1.total = actor1.total + actor2.total
	actor1.damage_taken = actor1.damage_taken + actor2.damage_taken
	actor1.totalabsorbed = actor1.totalabsorbed + actor2.totalabsorbed
	actor1.total_without_pet = actor1.total_without_pet + actor2.total_without_pet
	actor1.friendlyfire_total = actor1.friendlyfire_total + actor2.friendlyfire_total

	--damage taken from
	for actorName in pairs(actor2.damage_from) do
		actor1.damage_from[actorName] = true

		--add the damage done to actor2 into the damage done to target1
		if (actorContainer) then
			--get the actor that caused the damage on actor2
			local actorObject = actorContainer:GetActor(actorName)
			if (actorObject) then
				local damageToActor2 = (actorObject.targets[actor2.nome]) or 0
				actorObject.targets[actor1.nome] = (actorObject.targets[actor1.nome] or 0) + damageToActor2
			end
		end
	end

	--targets
	for actorName, damageDone in pairs(actor2.targets) do
		actor1.targets[actorName] = (actor1.targets[actorName] or 0) + damageDone
	end

	--pets
	for i = 1, #actor2.pets do
		DetailsFramework.table.addunique(actor1.pets, actor2.pets[i])
	end

	--raid targets
	for raidTargetFlag, damageDone in pairs(actor2.raid_targets) do
		actor1.raid_targets[raidTargetFlag] = (actor1.raid_targets[raidTargetFlag] or 0) + damageDone
	end

	--friendly fire
	for actorName, ffTable in pairs(actor2.friendlyfire) do
		actor1.friendlyfire[actorName] = actor1.friendlyfire[actorName] or actor1:CreateFFTable(actorName)
		actor1.friendlyfire[actorName].total = actor1.friendlyfire[actorName].total + ffTable.total

		for spellId, damageDone in pairs(ffTable.spells) do
			actor1.friendlyfire[actorName].spells[spellId] = (actor1.friendlyfire[actorName].spells[spellId] or 0) + damageDone
		end
	end

	--spells
	local ignoredKeys = {
		id = true,
		spellschool =  true,
	}

	local actor1Spells = actor1.spells
	for spellId, spellTable in pairs(actor2.spells._ActorTable) do

		local actor1Spell = actor1Spells:GetOrCreateSpell(spellId, true, "DAMAGE_DONE")

		--genetal spell attributes
		for key, value in pairs(spellTable) do
			if (type(value) == "number") then
				if (not ignoredKeys[key]) then
					if (key == "n_min" or key == "c_min") then
						if (actor1Spell[key] > value) then
							actor1Spell[key] = value
						end
					elseif (key == "n_max" or key == "c_max") then
						if (actor1Spell[key] < value) then
							actor1Spell[key] = value
						end
					else
						actor1Spell[key] = actor1Spell[key] + value
					end
				end
			end
		end

		--spell targets
		for targetName, damageDone in pairs(spellTable) do
			actor1Spell.targets[targetName] = (actor1Spell.targets[targetName] or 0) + damageDone
		end
	end
end


damageClass.__add = function(tabela1, tabela2)

	--tempo decorrido
		local tempo = (tabela2.end_time or time()) - tabela2.start_time
		tabela1.start_time = tabela1.start_time - tempo

	--total de dano
		tabela1.total = tabela1.total + tabela2.total
		tabela1.totalabsorbed = tabela1.totalabsorbed + tabela2.totalabsorbed
	--total de dano sem o pet
		tabela1.total_without_pet = tabela1.total_without_pet + tabela2.total_without_pet
	--total de dano que o cara levou
		tabela1.damage_taken = tabela1.damage_taken + tabela2.damage_taken
	--total do friendly fire causado
		tabela1.friendlyfire_total = tabela1.friendlyfire_total + tabela2.friendlyfire_total

	--soma o damage_from
		for nome, _ in pairs(tabela2.damage_from) do
			tabela1.damage_from [nome] = true
		end

		--pets (add unique pet names)
		for _, petName in ipairs(tabela2.pets) do
			local hasPet = false
			for i = 1, #tabela1.pets do
				if (tabela1.pets[i] == petName) then
					hasPet = true
					break
				end
			end

			if (not hasPet) then
				tabela1.pets [#tabela1.pets+1] = petName
			end
		end

	--soma os containers de alvos
		for target_name, amount in pairs(tabela2.targets) do
			tabela1.targets [target_name] = (tabela1.targets [target_name] or 0) + amount
		end

	--soma o container de raid targets
		for flag, amount in pairs(tabela2.raid_targets) do
			tabela1.raid_targets [flag] = (tabela1.raid_targets [flag] or 0) + amount
		end

	--soma o container de habilidades
		for spellid, habilidade in pairs(tabela2.spells._ActorTable) do
			--pega a habilidade no primeiro ator
			local habilidade_tabela1 = tabela1.spells:PegaHabilidade (spellid, true, "SPELL_DAMAGE", false)

			--soma os alvos
			for target_name, amount in pairs(habilidade.targets) do
				habilidade_tabela1.targets[target_name] = (habilidade_tabela1.targets [target_name] or 0) + amount
			end

			--soma os extras
			for spellId, amount in pairs(habilidade.extra) do
				habilidade_tabela1.extra = (habilidade_tabela1.extra [spellId] or 0) + amount
			end

			--soma os valores da habilidade
			for key, value in pairs(habilidade) do
				if (type(value) == "number") then
					if (key ~= "id" and key ~= "spellschool") then
						if (not habilidade_tabela1 [key]) then
							habilidade_tabela1 [key] = 0
						end

						if (key == "n_min" or key == "c_min") then
							if (habilidade_tabela1 [key] > value) then
								habilidade_tabela1 [key] = value
							end
						elseif (key == "n_max" or key == "c_max") then
							if (habilidade_tabela1 [key] < value) then
								habilidade_tabela1 [key] = value
							end
						else
							habilidade_tabela1 [key] = habilidade_tabela1 [key] + value
						end

					end
				elseif(key == "e_dmg" or key == "e_lvl") then
					if (not habilidade_tabela1[key]) then
						habilidade_tabela1[key] = {}
					end
					for empowermentLevel, empowermentValue in pairs(habilidade[key]) do
						habilidade_tabela1[key][empowermentLevel] = habilidade_tabela1[key][empowermentValue] or 0 + empowermentValue
					end
				end
			end
		end

	--soma o container de friendly fire
		for target_name, ff_table in pairs(tabela2.friendlyfire) do
			--pega o ator ff no ator principal
			local friendlyFire_tabela1 = tabela1.friendlyfire [target_name] or tabela1:CreateFFTable (target_name)
			--soma o total
			friendlyFire_tabela1.total = friendlyFire_tabela1.total + ff_table.total

			--soma as habilidades
			for spellid, amount in pairs(ff_table.spells) do
				friendlyFire_tabela1.spells [spellid] = (friendlyFire_tabela1.spells [spellid] or 0) + amount
			end
		end

	return tabela1
end

damageClass.__sub = function(tabela1, tabela2)

	--tempo decorrido
		local tempo = (tabela2.end_time or time()) - tabela2.start_time
		tabela1.start_time = tabela1.start_time + tempo

	--total de dano
		tabela1.total = tabela1.total - tabela2.total
		tabela1.totalabsorbed = tabela1.totalabsorbed - tabela2.totalabsorbed

	--total de dano sem o pet
		tabela1.total_without_pet = tabela1.total_without_pet - tabela2.total_without_pet
	--total de dano que o cara levou
		tabela1.damage_taken = tabela1.damage_taken - tabela2.damage_taken
	--total do friendly fire causado
		tabela1.friendlyfire_total = tabela1.friendlyfire_total - tabela2.friendlyfire_total

	--reduz os containers de alvos
		for target_name, amount in pairs(tabela2.targets) do
			local alvo_tabela1 = tabela1.targets [target_name]
			if (alvo_tabela1) then
				tabela1.targets [target_name] = tabela1.targets [target_name] - amount
			end
		end

	--reduz o container de raid targets
		for flag, amount in pairs(tabela2.raid_targets) do
			if (tabela1.raid_targets [flag]) then
				tabela1.raid_targets [flag] = _math_max (tabela1.raid_targets [flag] - amount, 0)
			end
		end

	--reduz o container de habilidades
		for spellid, habilidade in pairs(tabela2.spells._ActorTable) do
			--get the spell from the first actor
			local habilidade_tabela1 = tabela1.spells:PegaHabilidade (spellid, true, "SPELL_DAMAGE", false)

			--subtract targets
			for target_name, amount in pairs(habilidade.targets) do
				local alvo_tabela1 = habilidade_tabela1.targets [target_name]
				if (alvo_tabela1) then
					habilidade_tabela1.targets [target_name] = habilidade_tabela1.targets [target_name] - amount
				end
			end

			--subtract extra table
			for spellId, amount in pairs(habilidade.extra) do
				local extra_tabela1 = habilidade_tabela1.extra [spellId]
				if (extra_tabela1) then
					habilidade_tabela1.extra [spellId] = habilidade_tabela1.extra [spellId] - amount
				end
			end

			--subtrai os valores da habilidade
			for key, value in pairs(habilidade) do
				if (type(value) == "number") then
					if (key ~= "id" and key ~= "spellschool") then
						if (not habilidade_tabela1 [key]) then
							habilidade_tabela1 [key] = 0
						end
						if (key == "n_min" or key == "c_min") then
							if (habilidade_tabela1 [key] > value) then
								habilidade_tabela1 [key] = value
							end
						elseif (key == "n_max" or key == "c_max") then
							if (habilidade_tabela1 [key] < value) then
								habilidade_tabela1 [key] = value
							end
						else
							habilidade_tabela1 [key] = habilidade_tabela1 [key] - value
						end
					end
				end
			end
		end

	--reduz o container de friendly fire
		for target_name, ff_table in pairs(tabela2.friendlyfire) do
			--pega o ator ff no ator principal
			local friendlyFire_tabela1 = tabela1.friendlyfire [target_name]
			if (friendlyFire_tabela1) then
				friendlyFire_tabela1.total = friendlyFire_tabela1.total - ff_table.total
				for spellid, amount in pairs(ff_table.spells) do
					if (friendlyFire_tabela1.spells [spellid]) then
						friendlyFire_tabela1.spells [spellid] = friendlyFire_tabela1.spells [spellid] - amount
					end
				end
			end
		end

	return tabela1
end

function Details.refresh:r_atributo_damage(actorObject)
	detailsFramework:Mixin(actorObject, Details222.Mixins.ActorMixin)
	detailsFramework:Mixin(actorObject, damageClassMixin)

	setmetatable(actorObject, Details.atributo_damage)
	actorObject.__index = Details.atributo_damage

	--restore metatable for the spell container
	Details.refresh:r_container_habilidades(actorObject.spells)
	if (actorObject.augmentedSpellsContainer) then
		Details.refresh:r_container_habilidades(actorObject.augmentedSpellsContainer)
	end
end

function Details.clear:c_atributo_damage (este_jogador)
	este_jogador.__index = nil
	este_jogador.links = nil
	este_jogador.minha_barra = nil

	Details.clear:c_container_habilidades (este_jogador.spells)
end


--[[
	--enemy damage done
	i = 1
	local enemy = combat (1, enemy_name)
	if (enemy) then

		local damage_done = 0

		--get targets
		for target_name, amount in pairs(enemy.targets) do
			local player = combat (1, target_name)
			if (player and player.grupo) then
				local t = tooltip_temp_table [i]
				if (not t) then
					tooltip_temp_table [i] = {}
					t = tooltip_temp_table [i]
				end
				t [1] = player
				t [2] = amount
				damage_done = damage_done + amount
				i = i + 1
			end
		end

		--first clenup
		for o = i, #tooltip_temp_table do
			local t = tooltip_temp_table [o]
			t[2] = 0
			t[1] = 0
		end

		_table_sort(tooltip_temp_table, Details.Sort2)

		--enemy damage taken
		Details:AddTooltipSpellHeaderText (Loc ["STRING_ATTRIBUTE_DAMAGE"], headerColor, i-1, true)
		GameCooltip:AddIcon ([=[Interface\Buttons\UI-MicroStream-Green]=], 2, 1, 14, 14, 0.1875, 0.8125, 0.15625, 0.78125)
		GameCooltip:AddIcon ([=[Interface\AddOns\Details\images\key_shift]=], 2, 2, Details.tooltip_key_size_width, Details.tooltip_key_size_height, 0, 1, 0, 0.640625, Details.tooltip_key_overlay2)
		GameCooltip:AddStatusBar (100, 2, 0.7, g, b, 1)

		--build the tooltip
		for o = 1, i-1 do

			local player = tooltip_temp_table [o][1]
			local total = tooltip_temp_table [o][2]
			local player_name = player:name()

			if (player_name:find(Details.playername)) then
				GameCooltip:AddLine(player_name .. ": ", FormatTooltipNumber (_, total) .. " (" .. _cstr ("%.1f", (total / damage_done) * 100) .. "%)", 2, "yellow")
			else
				GameCooltip:AddLine(player_name .. ": ", FormatTooltipNumber (_, total) .." (" .. _cstr ("%.1f", (total / damage_done) * 100) .. "%)", 2)
			end

			local classe = player:class()
			if (not classe) then
				classe = "UNKNOW"
			end
			if (classe == "UNKNOW") then
				GameCooltip:AddIcon ("Interface\\LFGFRAME\\LFGROLE_BW", 2, nil, 14, 14, .25, .5, 0, 1)
			else
				GameCooltip:AddIcon (instancia.row_info.icon_file, 2, nil, 14, 14, _unpack(Details.class_coords [classe]))
			end
			Details:AddTooltipBackgroundStatusbar (2)

		end

	end

	--clean up
	for o = 1, #tooltip_temp_table do
		local t = tooltip_temp_table [o]
		t[2] = 0
		t[1] = 0
	end
--]]
