local y,w=...local O=w.DevTool function O.GetListenerFrame(y)if not y.listenerFrame then y.listenerFrame=CreateFrame("\070\114\097\109\101","\068\101\118\084\111\111\108\076\105\115\116\101\110\101\114\070\114\097\109\101",UIParent)end return y.listenerFrame end function O.StartMonitorEvent(O,y,w)if not y then return end local H=O:GetMonitoredEvent(y,w)if not H then H={event=y;unit=w,active=true}table.insert(O.db.profile.events,H)end local C=O:GetListenerFrame()local M=true if H.event=="\065\076\076"then C:RegisterAllEvents()elseif H.unit then M=pcall(C.RegisterUnitEvent,C,H.event,H.unit)if not M then O:Print("\070\097\105\108\101\100 \116\111 \114\101\103\105\115\116\101\114 \101\118\101\110\116\058 "..O.colors.lightblue:WrapTextInColorCode(H.event..(" "..H.unit)))end else M=pcall(C.RegisterEvent,C,H.event)if not M then O:Print("\070\097\105\108\101\100 \116\111 \114\101\103\105\115\116\101\114 \101\118\101\110\116\058 "..O.colors.lightblue:WrapTextInColorCode(H.event))end end if not M then for H,C in pairs(O.db.profile.events)do if C.event==y and(w and C.unit==w)then table.remove(O.db.profile.events,H)break elseif C.event==y and not w then table.remove(O.db.profile.events,H)break end end return else H.active=true end O:UpdateSideBarUI()local T=H.event if H.unit then T=T..(" "..tostring(H.unit))end O:Print(O.colors.green:WrapTextInColorCode("\083\116\097\114\116")..(" \101\118\101\110\116 \109\111\110\105\116\111\114\105\110\103\058 "..O.colors.lightblue:WrapTextInColorCode(T)))end function O.StopMonitorEvent(O,y,w)if not y then return end local H=O:GetMonitoredEvent(y,w)if H and H.active then local y=O:GetListenerFrame()H.active=false if H.event=="\065\076\076"then y:UnregisterAllEvents()for y,w in pairs(O.db.profile.events)do if w.active then O:StartMonitorEvent(w.event,w.unit)end end else y:UnregisterEvent(H.event)end O:UpdateSideBarUI()local w=H.event if H.unit then w=w..(" "..tostring(H.unit))end O:Print(O.colors.red:WrapTextInColorCode("\083\116\111\112")..(" \101\118\101\110\116 \109\111\110\105\116\111\114\105\110\103\058 "..O.colors.lightblue:WrapTextInColorCode(w)))end end function O.ToggleMonitorEvent(w,y)if y then if y.active then w:StopMonitorEvent(y.event,y.unit)else w:StartMonitorEvent(y.event,y.unit)end end end function O.SetMonitorEventScript(y)local w=y:GetListenerFrame()w:SetScript("\079\110\069\118\101\110\116",function(w,...)local O={...}local H=O[1]local C if#O>1 and(type(O[2])=="\115\116\114\105\110\103"and string.find(H,"\085\078\073\084"))then C=O[2]end if H=="\067\079\077\066\065\084\095\076\079\071\095\069\086\069\078\084\095\085\078\070\073\076\084\069\082\069\068"then O={H;CombatLogGetCurrentEventInfo()}end local M=y:GetMonitoredEvent("\065\076\076")if y:GetMonitoredEvent(H,C)or M and M.active then local w if#O==1 then w=O[1]else w=O end if C then y:AddData(w,date("\037\088")..(" "..(H..y.colors.gray:WrapTextInColorCode(" \040"..(C.."\041")))))else y:AddData(w,date("\037\088")..(" "..H))end end end)end function O.GetMonitoredEvent(O,y,w)if not O.db.profile.events then return end for O,H in pairs(O.db.profile.events)do if H.event==y and not H.unit then return H elseif H.event==y and(H.unit and(w and H.unit==w))then return H end end end
-- DevTool is a World of Warcraft® addon development tool.
-- Copyright (c) 2021-2024 Britt W. Yazel
-- Copyright (c) 2016-2021 Peter aka "Varren"
-- This code is licensed under the MIT license (see LICENSE for details)

local _, addonTable = ... --make use of the default addon namespace
local DevTool = addonTable.DevTool

-----------------------------------------------------------------------------------------------
--- EVENTS
-----------------------------------------------------------------------------------------------
function DevTool:GetListenerFrame()
	if not self.listenerFrame then
		self.listenerFrame = CreateFrame("Frame", "DevToolListenerFrame", UIParent);
	end
	return self.listenerFrame
end

function DevTool:StartMonitorEvent(event, unit)
	if not event then
		return
	end

	--handle to event in database
	local tEvent = self:GetMonitoredEvent(event, unit)

	if not tEvent then
		tEvent = { event = event, unit = unit, active = true }
		table.insert(self.db.profile.events, tEvent)
	end

	local frame = self:GetListenerFrame()

	local result = true

	if tEvent.event == "ALL" then
		frame:RegisterAllEvents()
	elseif tEvent.unit then
		--safety in case event doesn't exist
		result = pcall(frame.RegisterUnitEvent, frame, tEvent.event, tEvent.unit);
		if not result then
			self:Print("Failed to register event: " .. self.colors.lightblue:WrapTextInColorCode(tEvent.event .. " " .. tEvent.unit))
		end
	else
		--safety in case event doesn't exist
		result = pcall(frame.RegisterEvent, frame, tEvent.event);
		if not result then
			self:Print("Failed to register event: " .. self.colors.lightblue:WrapTextInColorCode(tEvent.event))
		end
	end

	--if event doesn't exist, we need to remove it from the database and the sidebar list
	if not result then
		for i, thisEvent in pairs(self.db.profile.events) do
			if thisEvent.event == event and unit and thisEvent.unit == unit then
				table.remove(self.db.profile.events, i)
				break
			elseif thisEvent.event == event and not unit then
				table.remove(self.db.profile.events, i)
				break
			end
		end
		return
	else
		--set event to active (tEvent is a handle to the database entry)
		tEvent.active = true
	end

	--refresh our sidebar view for any status changes
	self:UpdateSideBarUI()

	local eventName = tEvent.event
	if tEvent.unit then
		eventName = eventName .. " " .. tostring(tEvent.unit)
	end
	self:Print(self.colors.green:WrapTextInColorCode("Start") .. " event monitoring: " ..
			self.colors.lightblue:WrapTextInColorCode(eventName))
end

function DevTool:StopMonitorEvent(event, unit)
	if not event then
		return
	end
	local tEvent = self:GetMonitoredEvent(event, unit)

	if tEvent and tEvent.active then
		local frame = self:GetListenerFrame()
		tEvent.active = false
		if tEvent.event == "ALL" then
			frame:UnregisterAllEvents()
			for _, thisEvent in pairs(self.db.profile.events) do
				if thisEvent.active then
					self:StartMonitorEvent(thisEvent.event, thisEvent.unit)
				end
			end
		else
			frame:UnregisterEvent(tEvent.event)
		end

		--refresh our sidebar view for any status changes
		self:UpdateSideBarUI()

		local eventName = tEvent.event
		if tEvent.unit then
			eventName = eventName .. " " .. tostring(tEvent.unit)
		end

		self:Print(self.colors.red:WrapTextInColorCode("Stop") .. " event monitoring: " ..
				self.colors.lightblue:WrapTextInColorCode(eventName))
	end
end

function DevTool:ToggleMonitorEvent(tEvent)
	if tEvent then
		if tEvent.active then
			self:StopMonitorEvent(tEvent.event, tEvent.unit)
		else
			self:StartMonitorEvent(tEvent.event, tEvent.unit)
		end
	end
end

function DevTool:SetMonitorEventScript()
	local f = self:GetListenerFrame()

	f:SetScript("OnEvent", function(_, ...)
		local args = { ... }
		local event = args[1]
		local unit
		if #args > 1 and type(args[2]) == "string" and string.find(event, "UNIT") then
			unit = args[2]
		end

		--In 9.0 Blizzard removed the payload from COMBAT_LOG_EVENT_UNFILTERED
		--Intercept this event and manually query the info
		if event == "COMBAT_LOG_EVENT_UNFILTERED" then
			args = { event, CombatLogGetCurrentEventInfo() }
		end

		local showAllEvents = self:GetMonitoredEvent("ALL")
		if self:GetMonitoredEvent(event, unit) or (showAllEvents and showAllEvents.active) then
			local data
			if #args == 1 then
				data = args[1]
			else
				data = args
			end

			if unit then
				self:AddData(data, date("%X") .. " " .. event .. self.colors.gray:WrapTextInColorCode(" (" .. unit .. ")"))
			else
				self:AddData(data, date("%X") .. " " .. event)
			end
		end
	end);
end

function DevTool:GetMonitoredEvent(event, unit)
	if not self.db.profile.events then
		return
	end

	for _, thisEvent in pairs(self.db.profile.events) do

		if thisEvent.event == event and not thisEvent.unit then
			return thisEvent
		elseif thisEvent.event == event and thisEvent.unit and unit and thisEvent.unit == unit then
			return thisEvent
		end
	end
end
