-- ==================================================================================================================== --
--															--
--	File			FriendlyFire.lua									--
--															--
--															--
--	Author			Zarnivoop					| Version	   :	 10.0.2 |	--
--										| Curse-Project-ID :	 694380 |	--
--										| License	   :	  MIT/X |	--
--															--
--											| Basis, thx	|		--
--															--
--															--
--				Baltha						| Version	   :	 11.2.0 |	--
--										| Curse-Project-ID :	1188318 |	--
--										| License	   :	  MIT/X |	--
--															--
--											| Revision	|		--
--															--
--															--
--	Path ( Revision )	"..\World of Warcraft\_retail_\Interface\AddOns\Skada\Misc\Changelog\ChangeLog.txt"	--
--															--
-- ==================================================================================================================== --


local _, Skada = ...


-- ==========================
-- | outer function : start |
-- ==========================
Skada:AddLoadableModule("Friendly Fire", "Shows damage done on players by friendly players.", function(Skada, L)


	if Skada.db.profile.modulesBlocked["Friendly Fire"] then return end


	local mod       = Skada:NewModule(L["Friendly Fire"])
	local playermod = Skada:NewModule(L["Friendly Fire"] .. " - " .. L["List of players damaged"])
	local spellmod  = Skada:NewModule(L["Friendly Fire"] .. " - " .. L["List of damaging spells"])


	local function log_ffdamage_done(set, dmg)

		local player = Skada:get_player(set, dmg.playerid, dmg.playername)


		if player then

			set.ffdamagedone = set.ffdamagedone + dmg.amount


			if not player.ffdamagedonespells[dmg.spellname] then

				player.ffdamagedonespells[dmg.spellname]   = {id = dmg.spellid, name = dmg.spellname, damage = 0}
			end


			if not player.ffdamagedonetargets[dmg.targetname] then

				player.ffdamagedonetargets[dmg.targetname] = {id = dmg.targetid, name = dmg.targetname, damage = 0}
			end


			player.ffdamagedone = player.ffdamagedone + dmg.amount


			local spell   = player.ffdamagedonespells[dmg.spellname]
			spell.damage  = spell.damage + dmg.amount


			local target  = player.ffdamagedonetargets[dmg.targetname]
			target.damage = target.damage + dmg.amount
		end
	end


	local dmg = {}


	local function SpellDamage(timestamp, eventtype, srcGUID, srcName, srcFlags, dstGUID, dstName, dstFlags, ...)

		if srcGUID == dstGUID then return end


		local spellId, spellName, spellSchool, amount, overkill, school, resist, block, absorb = ...


		dmg.playerid   = srcGUID
		dmg.playername = srcName

		dmg.spellid    = spellId
		dmg.spellname  = spellName

		dmg.targetid   = dstGUID
		dmg.targetname = dstName

		dmg.amount     = (amount or 0) + (overkill or 0) + (absorb or 0)


		log_ffdamage_done(Skada.current, dmg)
		log_ffdamage_done(Skada.total  , dmg)
	end




	local function SwingDamage(timestamp, eventtype, srcGUID, srcName, srcFlags, dstGUID, dstName, dstFlags, ...)

		if srcGUID == dstGUID then return end


		local amount, overkill, school, resist, block, absorb = ...


		dmg.playerid   = srcGUID
		dmg.playername = srcName
		dmg.spellid    = 6603


		-- ======================================================================
		-- | API   : C_Spell.GetSpellInfo					|
		-- | valid : + 11.0.0 / 4.4.1 / 1.15.4					|
		-- |									|
		-- | Returns nil if spell is not found.					|
		-- ======================================================================
		spellInfo = C_Spell.GetSpellInfo(dmg.spellid)


		if spellInfo then

			dmg.spellname  = spellInfo.name

			dmg.targetid   = dstGUID
			dmg.targetname = dstName

			dmg.amount     = (amount or 0) + (overkill or 0) + (absorb or 0)


			log_ffdamage_done(Skada.current, dmg)
			log_ffdamage_done(Skada.total  , dmg)
		end
	end




	function mod:Update(win, set)

		local max = 0
		local nr  = 1


		for i, player in ipairs(set.players) do

			if player.ffdamagedone > 0 then

				local d		= win.dataset[nr] or {}


				win.dataset[nr] = d


				d.label		= player.name
				d.value		= player.ffdamagedone

				d.valuetext	= Skada:FormatNumber(player.ffdamagedone) .. (" (%02.1f%%)"):format(player.ffdamagedone / set.ffdamagedone * 100)

				d.id		= player.id
				d.class		= player.class


				if player.ffdamagedone > max then max = player.ffdamagedone end


				nr = nr + 1
			end
		end

		win.metadata.maxvalue = max
	end




	function spellmod:Enter(win, id, label)

		spellmod.playerid = id
		spellmod.title    = label .. ": " .. L["Friendly Fire"] .. " (" .. L["spells"] .. ")"
	end




	function playermod:Enter(win, id, label)

		playermod.playerid = id
		playermod.title    = label .. ": " .. L["Friendly Fire"] .. " (" .. L["targets"] .. ")"
	end




	function spellmod:Update(win, set)

		local player = Skada:find_player(set, self.playerid)
		local nr     = 1


		if player then

			for spellname, spell in pairs(player.ffdamagedonespells) do

				local d         = win.dataset[nr] or {}


				win.dataset[nr] = d


				d.label		= spellname
				d.value		= spell.damage


				-- ======================================================================
				-- | API   : C_Spell.GetSpellInfo					|
				-- | valid : + 11.0.0 / 4.4.1 / 1.15.4					|
				-- |									|
				-- | Returns nil if spell is not found.					|
				-- ======================================================================
				local spellInfo = C_Spell.GetSpellInfo(spell.id)

				
				if spellInfo then

					icon	    = spellInfo.iconID

					d.icon	    = icon
					d.id	    = spellname
					d.spellid   = spell.id

					d.valuetext = Skada:FormatNumber(spell.damage) .. (" (%02.1f%%)"):format(spell.damage / player.ffdamagedone * 100)


					nr = nr + 1
				end
			end
		end

		win.metadata.maxvalue = player.ffdamagedone
	end



	function playermod:Update(win, set)

		local player = Skada:find_player(set, self.playerid)
		local nr     = 1


		if player then

			win.metadata.maxvalue = 0


			for targetname, target in pairs(player.ffdamagedonetargets) do

				local d         = win.dataset[nr] or {}


				win.dataset[nr] = d


				local ptgt	= Skada:find_player(set, target.id)


				if ptgt then
					d.class = ptgt.class
				else
					d.class = nil
				end


				d.label		= targetname
				d.value		= target.damage

				d.icon		= nil
				d.id		= targetname

				d.valuetext	= Skada:FormatNumber(target.damage) .. (" (%02.1f%%)"):format(target.damage / player.ffdamagedone * 100)


				win.metadata.maxvalue = math.max(win.metadata.maxvalue, d.value)


				nr = nr + 1
			end
		end
	end



	function mod:OnEnable()

			spellmod.metadata 		= {}
			playermod.metadata 		= {}


			mod.metadata 			= {click1 = spellmod, click2 = playermod, showspots = true, icon = "Interface\\Icons\\Inv_throwingknife_01"}


			Skada:RegisterForCL(SpellDamage, 'SPELL_DAMAGE'         , {dst_is_interesting_nopets = true, src_is_interesting_nopets = true})
			Skada:RegisterForCL(SpellDamage, 'SPELL_PERIODIC_DAMAGE', {dst_is_interesting_nopets = true, src_is_interesting_nopets = true})
			Skada:RegisterForCL(SpellDamage, 'SPELL_BUILDING_DAMAGE', {dst_is_interesting_nopets = true, src_is_interesting_nopets = true})
			Skada:RegisterForCL(SpellDamage, 'RANGE_DAMAGE'         , {dst_is_interesting_nopets = true, src_is_interesting_nopets = true})
			Skada:RegisterForCL(SwingDamage, 'SWING_DAMAGE'         , {dst_is_interesting_nopets = true, src_is_interesting_nopets = true})


			Skada:AddMode(self)
	end



	function mod:OnDisable()

		Skada:RemoveMode(self)
	end



	function mod:AddPlayerAttributes(player)

		if not player.ffdamagedone then

			player.ffdamagedone        = 0
			player.ffdamagedonespells  = {}
			player.ffdamagedonetargets = {}
		end
	end



	function mod:AddSetAttributes(set)

		if not set.ffdamagedone then set.ffdamagedone = 0 end
	end



	function mod:GetSetSummary(set)

		return Skada:FormatNumber(set.ffdamagedone)
	end


end)
-- ========================
-- | outer function : end |
-- ========================