
	local Details = 		_G.Details
	local Loc = LibStub("AceLocale-3.0"):GetLocale ( "Details" )
	local _
	local addonName, Details222 = ...

--[[global]] DETAILS_TOTALS_ONLYGROUP = true
--[[global]] DETAILS_SEGMENTID_OVERALL = -1
--[[global]] DETAILS_SEGMENTID_CURRENT = 0

--[[global]] DETAILS_COMBAT_AMOUNT_CONTAINERS = 4

--enum segments type
--[[global]] DETAILS_SEGMENTTYPE_GENERIC = 0

--[[global]] DETAILS_SEGMENTTYPE_OVERALL = 1

--[[global]] DETAILS_SEGMENTTYPE_DUNGEON_TRASH = 5
--[[global]] DETAILS_SEGMENTTYPE_DUNGEON_BOSS = 6

--[[global]] DETAILS_SEGMENTTYPE_RAID_TRASH = 7
--[[global]] DETAILS_SEGMENTTYPE_RAID_BOSS = 8

--[[global]] DETAILS_SEGMENTTYPE_MYTHICDUNGEON_GENERIC = 10
--[[global]] DETAILS_SEGMENTTYPE_MYTHICDUNGEON_TRASH = 11
--[[global]] DETAILS_SEGMENTTYPE_MYTHICDUNGEON_OVERALL = 12
--[[global]] DETAILS_SEGMENTTYPE_MYTHICDUNGEON_TRASHOVERALL = 13
--[[global]] DETAILS_SEGMENTTYPE_MYTHICDUNGEON_BOSS = 14

--[[global]] DETAILS_SEGMENTTYPE_PVP_ARENA = 20
--[[global]] DETAILS_SEGMENTTYPE_PVP_BATTLEGROUND = 21

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--local pointers
	local ipairs = ipairs -- lua local
	local pairs = pairs -- lua local
	local _bit_band = bit.band -- lua local
	local _date = date -- lua local
	local tremove = table.remove -- lua local
	local rawget = rawget
	local _math_max = math.max
	local floor = math.floor
	local GetTime = GetTime

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

	local classCombat 	=	Details.combate
	local classActorContainer = Details.container_combatentes
	local class_type_dano 	= Details.atributos.dano
	local class_type_cura		= Details.atributos.cura
	local class_type_e_energy 	= Details.atributos.e_energy
	local class_type_misc 	= Details.atributos.misc

	local REACTION_HOSTILE =	0x00000040
	local CONTROL_PLAYER =		0x00000100

	--local _tempo = time()
	local _tempo = GetTime()

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--api functions

	--combat (container type, actor name)
	Details.call_combate = function(self, class_type, name)
		local container = self[class_type]
		local index_mapa = container._NameIndexTable [name]
		local actor = container._ActorTable [index_mapa]
		return actor
	end
	classCombat.__call = Details.call_combate

	--get the start date and end date
	function classCombat:GetDate()
		return self.data_inicio, self.data_fim
	end

	--set the combat date
	function classCombat:SetDate (started, ended)
		if (started and type(started) == "string") then
			self.data_inicio = started
		end
		if (ended and type(ended) == "string") then
			self.data_fim = ended
		end
	end

	--return data for charts
	function classCombat:GetTimeData (name)
		return self.TimeData [name]
	end

	function classCombat:GetContainer (attribute)
		return self [attribute]
	end

	function classCombat:GetRoster()
		return self.raid_roster
	end

	function classCombat:InstanceType()
		return rawget(self, "instance_type")
	end

	function classCombat:IsTrash()
		return rawget(self, "is_trash")
	end

	function classCombat:GetDifficulty()
		return self.is_boss and self.is_boss.diff
	end

	function classCombat:GetEncounterCleuID()
		return self.is_boss and self.is_boss.id
	end

	function classCombat:GetBossInfo()
		return self.is_boss
	end

	function classCombat:GetPhases()
		return self.PhaseData
	end

	function classCombat:GetPvPInfo()
		return self.is_pvp
	end

	function classCombat:GetMythicDungeonInfo()
		return self.is_mythic_dungeon
	end

	function classCombat:GetMythicDungeonTrashInfo()
		return self.is_mythic_dungeon_trash
	end

	---return if the combat is a mythic dungeon segment and the run id
	---@return boolean
	---@return number
	function classCombat:IsMythicDungeon()
		local bIsMythicPlusSegment = self.is_mythic_dungeon_segment
		local runId = self.is_mythic_dungeon_run_id
		return bIsMythicPlusSegment, runId
	end

	function classCombat:IsMythicDungeonOverall()
		return self.is_mythic_dungeon and self.is_mythic_dungeon.OverallSegment
	end

	function classCombat:GetArenaInfo()
		return self.is_arena
	end

	function classCombat:GetDeaths()
		return self.last_events_tables
	end

	function classCombat:GetPlayerDeaths(deadPlayerName)
		local allDeaths = self:GetDeaths()
		local deaths = {}

		for i = 1, #allDeaths do
			local thisDeath = allDeaths[i]
			local thisPlayerName = thisDeath[3]
			if (deadPlayerName == thisPlayerName) then
				deaths[#deaths+1] = thisDeath
			end
		end

		return deaths
	end

	function classCombat:GetCombatId()
		return self.combat_id
	end

	function classCombat:GetCombatNumber()
		return self.combat_counter
	end

	function classCombat:GetAlteranatePower()
		return self.alternate_power
	end

	---return the amount of casts of a spells from an actor
	---@param self combat
	---@param actorName string
	---@param spellName string
	---@return number
	function classCombat:GetSpellCastAmount(actorName, spellName)
		return self.amountCasts[actorName] and self.amountCasts[actorName][spellName] or 0
	end

	---return the cast amount table
	---@param self combat
	---@param actorName string|nil
	---@return table
	function classCombat:GetSpellCastTable(actorName)
		if (actorName) then
			return self.amountCasts[actorName] or {}
		else
			return self.amountCasts
		end
	end

	---delete an actor from the spell casts amount
	---@param self combat
	---@param actorName string
	function classCombat:RemoveActorFromSpellCastTable(actorName)
		self.amountCasts[actorName] = nil
	end

	---return the uptime of a buff from an actor
	---@param actorName string
	---@param spellId number
	---@param auraType string|nil if nil get 'buff'
	---@return number
	function classCombat:GetSpellUptime(actorName, spellId, auraType)
		---@type actorcontainer
		local utilityContainer = self:GetContainer(DETAILS_ATTRIBUTE_MISC)
		---@type actor
		local actorObject = utilityContainer:GetActor(actorName)
		if (actorObject) then
			if (auraType) then
				---@type spellcontainer
				local buffUptimeContainer = actorObject:GetSpellContainer(auraType)
				if (buffUptimeContainer) then
					---@type spelltable
					local spellTable = buffUptimeContainer:GetSpell(spellId)
					if (spellTable) then
						return spellTable.uptime or 0
					end
				end
			else
				do --if not auraType passed, attempt to get the uptime from debuffs first, if it fails, get from buffs
					---@type spellcontainer
					local debuffContainer = actorObject:GetSpellContainer("debuff")
					if (debuffContainer) then
						---@type spelltable
						local spellTable = debuffContainer:GetSpell(spellId)
						if (spellTable) then
							return spellTable.uptime or 0
						end
					end
				end
				do
					---@type spellcontainer
					local buffContainer = actorObject:GetSpellContainer("buff")
					if (buffContainer) then
						---@type spelltable
						local spellTable = buffContainer:GetSpell(spellId)
						if (spellTable) then
							return spellTable.uptime or 0
						end
					end
				end
			end
		end
		return 0
	end

	--return the name of the encounter or enemy
	function classCombat:GetCombatName(try_find)
		if (self.is_pvp) then
			return self.is_pvp.name

		elseif (self.is_boss) then
			return self.is_boss.encounter

		elseif (self.is_mythic_dungeon_trash) then
			return self.is_mythic_dungeon_trash.ZoneName .. " (" .. Loc ["STRING_SEGMENTS_LIST_TRASH"] .. ")"

		elseif (rawget(self, "is_trash")) then
			return Loc ["STRING_SEGMENT_TRASH"]

		else
			if (self.enemy) then
				return self.enemy
			end
			if (try_find) then
				return Details:FindEnemy()
			end
		end
		return Loc ["STRING_UNKNOW"]
	end

	function classCombat:GetCombatType()
		--mythic dungeon
		local isMythicDungeon = self.is_mythic_dungeon_segment
		if (isMythicDungeon) then
			local isMythicDungeonTrash = self.is_mythic_dungeon_trash
			if (isMythicDungeonTrash) then
				return DETAILS_SEGMENTTYPE_MYTHICDUNGEON_TRASH
			else
				local isMythicDungeonOverall = self.is_mythic_dungeon and self.is_mythic_dungeon.OverallSegment
				local isMythicDungeonTrashOverall = self.is_mythic_dungeon and self.is_mythic_dungeon.TrashOverallSegment
				if (isMythicDungeonOverall) then
					return DETAILS_SEGMENTTYPE_MYTHICDUNGEON_OVERALL
				elseif (isMythicDungeonTrashOverall) then
					return DETAILS_SEGMENTTYPE_MYTHICDUNGEON_TRASHOVERALL
				end

				local bossEncounter =  self.is_boss
				if (bossEncounter) then
					return DETAILS_SEGMENTTYPE_MYTHICDUNGEON_BOSS
				end

				return DETAILS_SEGMENTTYPE_MYTHICDUNGEON_GENERIC
			end
		end

		--arena
		local arenaInfo = self.is_arena
		if (arenaInfo) then
			return DETAILS_SEGMENTTYPE_PVP_ARENA
		end

		--battleground
		local battlegroundInfo = self.is_pvp
		if (battlegroundInfo) then
			return DETAILS_SEGMENTTYPE_PVP_BATTLEGROUND
		end

		--dungeon or raid
		local instanceType = self.instance_type

		if (instanceType == "party") then
			local bossEncounter =  self.is_boss
			if (bossEncounter) then
				return DETAILS_SEGMENTTYPE_DUNGEON_BOSS
			else
				return DETAILS_SEGMENTTYPE_DUNGEON_TRASH
			end

		elseif (instanceType == "raid") then
			local bossEncounter =  self.is_boss
			if (bossEncounter) then
				return DETAILS_SEGMENTTYPE_RAID_BOSS
			else
				return DETAILS_SEGMENTTYPE_RAID_TRASH
			end
		end

		--overall data
		if (self == Details.tabela_overall) then
			return DETAILS_SEGMENTTYPE_OVERALL
		end

		return DETAILS_SEGMENTTYPE_GENERIC
	end

	--return a numeric table with all actors on the specific containter
	function classCombat:GetActorList (container)
		return self [container]._ActorTable
	end

	---return an actor object for the given container and actor name
	---@param container number
	---@param name string
	---@return actor|nil
	function classCombat:GetActor(container, name)
		local index = self[container] and self[container]._NameIndexTable[name]
		if (index) then
			return self[container]._ActorTable[index]
		end
		return nil
	end

	---return the combat time in seconds
	---@return number, number
	function classCombat:GetFormatedCombatTime()
		local combatTime = self:GetCombatTime()
		local minute, second = floor(combatTime / 60), floor(combatTime % 60)
		return minute, second
	end

	---return the amount of time the combat has elapsed
	---@return number
	function classCombat:GetCombatTime()
		if (self.end_time) then
			return _math_max (self.end_time - self.start_time, 0.1)
		elseif (self.start_time and Details.in_combat and self ~= Details.tabela_overall) then
			return _math_max (GetTime() - self.start_time, 0.1)
		else
			return 0.1
		end
	end

	function classCombat:GetStartTime()
		return self.start_time
	end
	function classCombat:SetStartTime(thisTime)
		self.start_time = thisTime
	end

	function classCombat:GetEndTime()
		return self.end_time
	end
	function classCombat:SetEndTime(thisTime)
		self.end_time = thisTime
	end

	---copy deaths from combat2 into combat1
	---if bMythicPlus is true it'll check if the death has mythic plus death time and use it instead of the normal death time
	---@param combat1 combat 
	---@param combat2 combat
	---@param bMythicPlus boolean
	function classCombat.CopyDeathsFrom(combat1, combat2, bMythicPlus)
		local deathsTable = combat1:GetDeaths()
		local deathsToCopy = combat2:GetDeaths()

		for i = 1, #deathsToCopy do
			local thisDeath = DetailsFramework.table.copy({}, deathsToCopy[i])

			if (bMythicPlus and thisDeath.mythic_plus) then
				thisDeath[6] = thisDeath.mythic_plus_dead_at_string
				thisDeath.dead_at = thisDeath.mythic_plus_dead_at
			end

			deathsTable[#deathsTable+1] = thisDeath
		end
	end

	--return the total of a specific attribute
	local power_table = {0, 1, 3, 6, 0, "alternatepower"}

	function classCombat:GetTotal(attribute, subAttribute, onlyGroup)
		if (attribute == 1 or attribute == 2) then
			if (onlyGroup) then
				return self.totals_grupo [attribute]
			else
				return self.totals [attribute]
			end

		elseif (attribute == 3) then
			if (subAttribute == 5) then --resources
				return self.totals.resources or 0
			end
			if (onlyGroup) then
				return self.totals_grupo [attribute] [power_table [subAttribute]]
			else
				return self.totals [attribute] [power_table [subAttribute]]
			end

		elseif (attribute == 4) then
			local subName = Details:GetInternalSubAttributeName (attribute, subAttribute)
			if (onlyGroup) then
				return self.totals_grupo [attribute] [subName]
			else
				return self.totals [attribute] [subName]
			end
		end

		return 0
	end

	---create an alternate power table for the given actor
	---@param actorName string
	---@return alternatepowertable
	function classCombat:CreateAlternatePowerTable(actorName)
		---@type alternatepowertable
		local alternatePowerTable = {last = 0, total = 0}
		self.alternate_power[actorName] = alternatePowerTable
		return alternatePowerTable
	end

	--delete an actor from the combat ~delete ~erase ~remove
	function classCombat:DeleteActor(attribute, actorName, removeDamageTaken, cannotRemap)
		local container = self[attribute]
		if (container) then

			local actorTable = container._ActorTable

			--store the index it was found
			local indexToDelete

			--get the object for the deleted actor
			local deletedActor = self(attribute, actorName)
			if (not deletedActor) then
				return
			else
				for i = 1, #actorTable do
					local actor = actorTable[i]
					if (actor.nome == actorName) then
						--print("Details: found the actor: ", actorName, actor.nome, i)
						indexToDelete = i
						break
					end
				end
			end

			for i = 1, #actorTable do
				--is this not the actor we want to remove?
				if (i ~= indexToDelete) then

					local actor = actorTable[i]
					if (not actor.isTank) then
						--get the damage dealt and remove
						local damageDoneToRemovedActor = (actor.targets[actorName]) or 0
						actor.targets[actorName] = nil
						actor.total = actor.total - damageDoneToRemovedActor
						actor.total_without_pet = actor.total_without_pet - damageDoneToRemovedActor

						--damage taken
						if (removeDamageTaken) then
							local hadDamageTaken = actor.damage_from[actorName]
							if (hadDamageTaken) then
								--query the deleted actor to know how much damage it applied to this actor
								local damageDoneToActor = (deletedActor.targets[actor.nome]) or 0
								actor.damage_taken = actor.damage_taken - damageDoneToActor
							end
						end

						--spells
						local spellsTable = actor.spells._ActorTable
						for spellId, spellTable in pairs(spellsTable) do
							local damageDoneToRemovedActor = (spellTable.targets[actorName]) or 0
							spellTable.targets[actorName] = nil
							spellTable.total = spellTable.total - damageDoneToRemovedActor
						end
					end
				end
			end

			if (indexToDelete) then
				local actorToDelete = self(attribute, actorName)
				local actorToDelete2 = container._ActorTable[indexToDelete]

				if (actorToDelete ~= actorToDelete2) then
					Details:Msg("error 0xDE8745")
				end

				local index = container._NameIndexTable[actorName]
				if (indexToDelete ~= index) then
					Details:Msg("error 0xDE8751")
				end

				--remove actor
				tremove(container._ActorTable, index)

				--remap
				if (not cannotRemap) then
					container:Remap()
				end
				return true
			end
		end
	end

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--internals

	function classCombat:CreateNewCombatTable()
		return classCombat:NovaTabela()
	end

	---class constructor
	---@param bTimeStarted boolean if true set the start time to now with GetTime
	---@param overallCombatObject combat
	---@param combatId number
	---@param ... unknown
	---@return combat
	function classCombat:NovaTabela(bTimeStarted, overallCombatObject, combatId, ...) --~init
		---@type combat
		local combatObject = {}

		combatObject[1] = classActorContainer:NovoContainer(Details.container_type.CONTAINER_DAMAGE_CLASS,	combatObject, combatId) --Damage
		combatObject[2] = classActorContainer:NovoContainer(Details.container_type.CONTAINER_HEAL_CLASS,	combatObject, combatId) --Healing
		combatObject[3] = classActorContainer:NovoContainer(Details.container_type.CONTAINER_ENERGY_CLASS,	combatObject, combatId) --Energies
		combatObject[4] = classActorContainer:NovoContainer(Details.container_type.CONTAINER_MISC_CLASS,	combatObject, combatId) --Misc
		combatObject[5] = classActorContainer:NovoContainer(Details.container_type.CONTAINER_DAMAGE_CLASS,	combatObject, combatId) --place holder for customs

		setmetatable(combatObject, classCombat)

		Details.combat_counter = Details.combat_counter + 1
		combatObject.combat_counter = Details.combat_counter

		--try discover if is a pvp combat
		local who_serial, who_name, who_flags, alvo_serial, alvo_name, alvo_flags = ...
		if (who_serial) then --aqui ir� identificar o boss ou o oponente
			if (alvo_name and _bit_band (alvo_flags, REACTION_HOSTILE) ~= 0) then --tentando pegar o inimigo pelo alvo
				combatObject.contra = alvo_name
				if (_bit_band (alvo_flags, CONTROL_PLAYER) ~= 0) then
					combatObject.pvp = true --o alvo � da fac��o oposta ou foi dado mind control
				end
			elseif (who_name and _bit_band (who_flags, REACTION_HOSTILE) ~= 0) then --tentando pegar o inimigo pelo who caso o mob � quem deu o primeiro hit
				combatObject.contra = who_name
				if (_bit_band (who_flags, CONTROL_PLAYER) ~= 0) then
					combatObject.pvp = true --o who � da fac��o oposta ou foi dado mind control
				end
			else
				combatObject.pvp = true --se ambos s�o friendly, seria isso um PVP entre jogadores da mesma fac��o?
			end
		end

		--start/end time (duration)
		combatObject.data_fim = 0
		combatObject.data_inicio = 0
		combatObject.tempo_start = _tempo

		---store trinket procs
		combatObject.trinketProcs = {}

		---store the amount of casts of each player
		---@type table<actorname, table<spellname, number>>
		combatObject.amountCasts = {}

		--record deaths
		combatObject.last_events_tables = {}

		--last events from players
		combatObject.player_last_events = {}

		--players in the raid
		combatObject.raid_roster = {}
		combatObject.raid_roster_indexed = {}

		--frags
		combatObject.frags = {}
		combatObject.frags_need_refresh = false

		--alternate power
		combatObject.alternate_power = {}

		--time data container
		combatObject.TimeData = Details:TimeDataCreateCombatTables()
		combatObject.PhaseData = {{1, 1}, damage = {}, heal = {}, damage_section = {}, heal_section = {}} --[1] phase number [2] phase started

		--for external plugin usage, these tables are guaranteed to be saved with the combat
		combatObject.spells_cast_timeline = {}
		combatObject.aura_timeline = {}
		combatObject.cleu_timeline = {}

		--cleu events
		combatObject.cleu_events = {
			n = 1 --event counter
		}

		--a tabela sem o tempo de inicio � a tabela descartavel do inicio do addon
		if (bTimeStarted) then
			--esta_tabela.start_time = _tempo
			combatObject.start_time = GetTime()
			combatObject.end_time = nil
		else
			combatObject.start_time = 0
			combatObject.end_time = nil
		end

		-- o container ir� armazenar as classes de dano -- cria um novo container de indexes de seriais de jogadores --par�metro 1 classe armazenada no container, par�metro 2 = flag da classe
		combatObject[1].need_refresh = true
		combatObject[2].need_refresh = true
		combatObject[3].need_refresh = true
		combatObject[4].need_refresh = true
		combatObject[5].need_refresh = true

		--isn't shadow deprecated?
		if (overallCombatObject) then --link � a tabela de combate do overall
			combatObject[1].shadow = overallCombatObject[1]
			combatObject[2].shadow = overallCombatObject[2]
			combatObject[3].shadow = overallCombatObject[3]
			combatObject[4].shadow = overallCombatObject[4]
		end

		combatObject.totals = {
			0, --dano
			0, --cura
			{--e_energy
				[0] = 0, --mana
				[1] = 0, --rage
				[3] = 0, --energy (rogues cat)
				[6] = 0, --runepower (dk)
				alternatepower = 0,
			},
			{--misc
				cc_break = 0, --armazena quantas quebras de CC
				ress = 0, --armazena quantos pessoas ele reviveu
				interrupt = 0, --armazena quantos interrupt a pessoa deu
				dispell = 0, --armazena quantos dispell esta pessoa recebeu
				dead = 0, --armazena quantas vezes essa pessia morreu
				cooldowns_defensive = 0, --armazena quantos cooldowns a raid usou
				buff_uptime = 0, --armazena quantos cooldowns a raid usou
				debuff_uptime = 0 --armazena quantos cooldowns a raid usou
			},

			--avoid using this values bellow, they aren't updated by the parser, only on demand by a user interaction.
				voidzone_damage = 0,
				frags_total = 0,
			--end
		}

		combatObject.totals_grupo = {
			0, --dano
			0, --cura
			{--e_energy
				[0] = 0, --mana
				[1] = 0, --rage
				[3] = 0, --energy (rogues cat)
				[6] = 0, --runepower (dk)
				alternatepower = 0,
			},
			{--misc
				cc_break = 0, --armazena quantas quebras de CC
				ress = 0, --armazena quantos pessoas ele reviveu
				interrupt = 0, --armazena quantos interrupt a pessoa deu
				dispell = 0, --armazena quantos dispell esta pessoa recebeu
				dead = 0, --armazena quantas vezes essa oessia morreu
				cooldowns_defensive = 0, --armazena quantos cooldowns a raid usou
				buff_uptime = 0,
				debuff_uptime = 0
			}
		}

		return combatObject
	end

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--core

	function classCombat:CreateLastEventsTable (player_name)
		local t = {}
		for i = 1, Details.deadlog_events do
			t [i] = {}
		end
		t.n = 1
		self.player_last_events [player_name] = t
		return t
	end

	--trava o tempo dos jogadores ap�s o t�rmino do combate.
	function classCombat:TravarTempos()
		if (self [1]) then
			for _, jogador in ipairs(self [1]._ActorTable) do --damage
				if (jogador:Iniciar()) then -- retorna se ele esta com o dps ativo
					jogador:TerminarTempo()
					jogador:Iniciar (false) --trava o dps do jogador
				else
					if (jogador.start_time == 0) then
						jogador.start_time = _tempo
					end
					if (not jogador.end_time) then
						jogador.end_time = _tempo
					end
				end
			end
		end
		if (self [2]) then
			for _, jogador in ipairs(self [2]._ActorTable) do --healing
				if (jogador:Iniciar()) then -- retorna se ele esta com o dps ativo
					jogador:TerminarTempo()
					jogador:Iniciar (false) --trava o dps do jogador
				else
					if (jogador.start_time == 0) then
						jogador.start_time = _tempo
					end
					if (not jogador.end_time) then
						jogador.end_time = _tempo
					end
				end
			end
		end
	end

	function classCombat:seta_data (tipo)
		if (tipo == Details._detalhes_props.DATA_TYPE_START) then
			self.data_inicio = _date ("%H:%M:%S")
		elseif (tipo == Details._detalhes_props.DATA_TYPE_END) then
			self.data_fim = _date ("%H:%M:%S")
		end
	end

	function classCombat:seta_tempo_decorrido()
		--self.end_time = _tempo
		self.end_time = GetTime()
	end

	function Details.refresh:r_combate (tabela_combate, shadow)
		setmetatable(tabela_combate, Details.combate)
		tabela_combate.__index = Details.combate
		tabela_combate.shadow = shadow
	end

	function Details.clear:c_combate (tabela_combate)
		--tabela_combate.__index = {}
		tabela_combate.__index = nil
		tabela_combate.__call = {}
		tabela_combate._combat_table = nil
		tabela_combate.shadow = nil
	end

	classCombat.__sub = function(combate1, combate2)

		if (combate1 ~= Details.tabela_overall) then
			return
		end

		--sub dano
			for index, actor_T2 in ipairs(combate2[1]._ActorTable) do
				local actor_T1 = combate1[1]:PegarCombatente (actor_T2.serial, actor_T2.nome, actor_T2.flag_original, true)
				actor_T1 = actor_T1 - actor_T2
				actor_T2:subtract_total (combate1)
			end
			combate1 [1].need_refresh = true

		--sub heal
			for index, actor_T2 in ipairs(combate2[2]._ActorTable) do
				local actor_T1 = combate1[2]:PegarCombatente (actor_T2.serial, actor_T2.nome, actor_T2.flag_original, true)
				actor_T1 = actor_T1 - actor_T2
				actor_T2:subtract_total (combate1)
			end
			combate1 [2].need_refresh = true

		--sub energy
			for index, actor_T2 in ipairs(combate2[3]._ActorTable) do
				local actor_T1 = combate1[3]:PegarCombatente (actor_T2.serial, actor_T2.nome, actor_T2.flag_original, true)
				actor_T1 = actor_T1 - actor_T2
				actor_T2:subtract_total (combate1)
			end
			combate1 [3].need_refresh = true

		--sub misc
			for index, actor_T2 in ipairs(combate2[4]._ActorTable) do
				local actor_T1 = combate1[4]:PegarCombatente (actor_T2.serial, actor_T2.nome, actor_T2.flag_original, true)
				actor_T1 = actor_T1 - actor_T2
				actor_T2:subtract_total (combate1)
			end
			combate1 [4].need_refresh = true

		--reduz o tempo
			combate1.start_time = combate1.start_time + combate2:GetCombatTime()

		--apaga as mortes da luta diminuida
			local amt_mortes =  #combate2.last_events_tables --quantas mortes teve nessa luta
			if (amt_mortes > 0) then
				for i = #combate1.last_events_tables, #combate1.last_events_tables-amt_mortes, -1 do
					tremove(combate1.last_events_tables, #combate1.last_events_tables)
				end
			end

		--frags
			for fragName, fragAmount in pairs(combate2.frags) do
				if (fragAmount) then
					if (combate1.frags [fragName]) then
						combate1.frags [fragName] = combate1.frags [fragName] - fragAmount
					else
						combate1.frags [fragName] = fragAmount
					end
				end
			end
			combate1.frags_need_refresh = true

		--alternate power
			local overallPowerTable = combate1.alternate_power
			for actorName, powerTable in pairs(combate2.alternate_power) do
				local power = overallPowerTable [actorName]
				if (power) then
					power.total = power.total - powerTable.total
				end
				combate2.alternate_power [actorName].last = 0
			end

		return combate1

	end

	---add combat2 data into combat1
	---@param combate1 combat
	---@param combate2 combat
	---@return combat
	classCombat.__add = function(combate1, combate2)
		local all_containers = {combate2 [class_type_dano]._ActorTable, combate2 [class_type_cura]._ActorTable, combate2 [class_type_e_energy]._ActorTable, combate2 [class_type_misc]._ActorTable}
		local custom_combat
		if (combate1 ~= Details.tabela_overall) then
			custom_combat = combate1
		end

		for class_type, actor_container in ipairs(all_containers) do
			for _, actor in ipairs(actor_container) do
				local shadow

				if (class_type == class_type_dano) then
					shadow = Details.atributo_damage:r_connect_shadow (actor, true, custom_combat)
				elseif (class_type == class_type_cura) then
					shadow = Details.atributo_heal:r_connect_shadow (actor, true, custom_combat)
				elseif (class_type == class_type_e_energy) then
					shadow = Details.atributo_energy:r_connect_shadow (actor, true, custom_combat)
				elseif (class_type == class_type_misc) then
					shadow = Details.atributo_misc:r_connect_shadow (actor, true, custom_combat)
				end

				shadow.boss_fight_component = actor.boss_fight_component or shadow.boss_fight_component
				shadow.fight_component = actor.fight_component or shadow.fight_component
				shadow.grupo = actor.grupo or shadow.grupo
			end
		end

		--alternate power
			local overallPowerTable = combate1.alternate_power
			for actorName, powerTable in pairs(combate2.alternate_power) do
				local alternatePowerTable = overallPowerTable[actorName]
				if (not alternatePowerTable) then
					alternatePowerTable = combate1:CreateAlternatePowerTable(actorName)
				end
				alternatePowerTable.total = alternatePowerTable.total + powerTable.total
				combate2.alternate_power[actorName].last = 0
			end

		--cast amount
			local combat1CastData = combate1.amountCasts
			for actorName, castData in pairs(combate2.amountCasts) do
				local playerCastTable = combat1CastData[actorName]
				if (not playerCastTable) then
					playerCastTable = {}
					combat1CastData[actorName] = playerCastTable
				end
				for spellName, amountOfCasts in pairs(castData) do
					local spellAmount = playerCastTable[spellName]
					if (not spellAmount) then
						spellAmount = 0
						playerCastTable[spellName] = spellAmount
					end
					playerCastTable[spellName] = spellAmount + amountOfCasts
				end
			end

		return combate1
	end

	function Details:UpdateCombat()
		_tempo = Details._tempo
	end
