-- This work is licensed under the Creative Commons Attribution-ShareAlike 3.0 Unported License.
-- To view a copy of this license, visit http://creativecommons.org/licenses/by-sa/3.0/
-- or send a letter to Creative Commons, 444 Castro Street, Suite 900, Mountain View, California, 94041, USA.

local MereHealingFrames, privateVars = ...

MereHealingFrames.Events = MereHealingFrames.Events or {}
MereHealingFrames.EventCounters = {}

local EventCounters = MereHealingFrames.EventCounters
function MereHealingFrames.Events.BumpEventCounter(EventName)
	EventCounters[EventName] = (EventCounters[EventName] or 0) + 1
end

local BumpEventCounter = MereHealingFrames.Events.BumpEventCounter

local RMUnits = MereHealingFrames.RaidManagement.Units
local updateUnitValues = MereHealingFrames.RaidManagement.playerInfo.UpdateUnitValues
local function cacheUpdate(updatedUnits, field, EventName)
    BumpEventCounter(EventName)
    return updateUnitValues(updatedUnits, field)
end

local function cacheUpdateAndRelay(updatedUnits, field, EventName)
    BumpEventCounter(EventName)

    for unitId, value in pairs(updatedUnits) do
        local playerInfo = RMUnits[unitId]
        if playerInfo then
            playerInfo:UpdateValueAndRelay(field, value)
        end
    end
end

function MereHealingFrames.Events.Available(handle, AvailableUnits)
	BumpEventCounter("Event.Unit.Availability.Full")

    for unitId, value in pairs(AvailableUnits) do
		local playerInfo = RMUnits[unitId]
		if playerInfo then
			playerInfo:UpdateDetails(value)
		end
	end
end

function MereHealingFrames.Events.Coords(handle, x, y, z)
    BumpEventCounter("Event.Unit.Detail.Coord")

    for unitId, value in pairs(x) do
        local playerInfo = RMUnits[unitId]
        if playerInfo then
            playerInfo:UpdateCoords(value, y[unitId], z[unitId])
        end
    end
end

function MereHealingFrames.Events.Radius(handle, radiusTable)
    BumpEventCounter("Event.Unit.Detail.Radius")

    for unitId, radius in pairs(radiusTable) do
        local playerInfo = RMUnits[unitId]
        if playerInfo then
            playerInfo:UpdateRadius(radius)
        end
    end
end

function MereHealingFrames.Events.BuffAdd (handle, unitId, buffs)
	BumpEventCounter("Event.Buff.Add")
	local playerInfo = RMUnits[unitId]
	if playerInfo then
		playerInfo.buffMgmt:BuffAdd(buffs)
	end
end

function MereHealingFrames.Events.BuffChange (handle, unitId, buffs)
	BumpEventCounter("Event.Buff.Change")
	local playerInfo = RMUnits[unitId]
	if playerInfo then
		playerInfo.buffMgmt:BuffChange(buffs)
	end
end

function MereHealingFrames.Events.BuffRemove (handle, unitId, buffs)
	BumpEventCounter("Event.Buff.Remove")
	local playerInfo = RMUnits[unitId]
	if playerInfo then
		playerInfo.buffMgmt:BuffRemove(buffs)
	end
end



MereHealingFrames.PostSecureCallbacks = {}

function MereHealingFrames.Events.SecureEnter ()
	BumpEventCounter("Event.System.Secure.Enter")

	MereHealingFrames.RaidManagement.EnterCombat()
	MereHealingFrames.Config.window:Secure()

	for layoutName, layout in pairs(MereHealingFrames.Layouts) do
		layout:SecureEnter()
	end
end

function MereHealingFrames.Events.SecureLeave ()
	BumpEventCounter("Event.System.Secure.Leave")

	for layoutName, layout in pairs(MereHealingFrames.Layouts) do
		layout:SecureLeave()
	end

	MereHealingFrames.Debug(1, "found %d callbacks coming out of secure", #MereHealingFrames.PostSecureCallbacks)
	for i, func in ipairs(MereHealingFrames.PostSecureCallbacks) do
		func()
	end
	MereHealingFrames.PostSecureCallbacks = {}

    for layoutName, layout in pairs(MereHealingFrames.Layouts) do
        layout:ProcessPendingLayoutChanges()
    end

	MereHealingFrames.RaidManagement.LeaveCombat()
end

function MereHealingFrames.Events.SoulSpecChange()
	BumpEventCounter("Event.TEMPORARY.Role")
	MereHealingFrames.Spells.UpdateCurrentSpellSet()
	MereHealingFrames.BuffSets.UpdateCurrentSet()
end

function MereHealingFrames.Events.AbilityAdd()
    BumpEventCounter("Event.Ability.New.Add")
    MereHealingFrames.Config.UI.AvailableSpecsNeedUpdating()
end


Command.Event.Attach(Event.Unit.Availability.Full, MereHealingFrames.Events.Available, "MereHealingFrames.Events.Available")
Command.Event.Attach(Event.Unit.Detail.Health,      function (handle, units) return cacheUpdate(units, "health", "Event.Unit.Detail.Health") end, "MereHealingFrames.Events.Health")
Command.Event.Attach(Event.Unit.Detail.HealthMax, 	function (handle, units) return cacheUpdate(units, "healthMax", "Event.Unit.Detail.HealthMax") end, "MereHealingFrames.Events.HealthMax")
Command.Event.Attach(Event.Unit.Detail.Mana, 		function (handle, units) return cacheUpdate(units, "mana", "Event.Unit.Detail.Mana") end, "MereHealingFrames.Events.Mana")
Command.Event.Attach(Event.Unit.Detail.ManaMax, 	function (handle, units) return cacheUpdate(units, "manaMax", "Event.Unit.Detail.ManaMax") end, "MereHealingFrames.Events.ManaMax")
Command.Event.Attach(Event.Unit.Detail.Energy, 		function (handle, units) return cacheUpdate(units, "energy", "Event.Unit.Detail.Energy") end, "MereHealingFrames.Events.Energy")
Command.Event.Attach(Event.Unit.Detail.EnergyMax, 	function (handle, units) return cacheUpdate(units, "energyMax", "Event.Unit.Detail.EnergyMax") end, "MereHealingFrames.Events.EnergyMax")
Command.Event.Attach(Event.Unit.Detail.Power, 		function (handle, units) return cacheUpdate(units, "power", "Event.Unit.Detail.Power") end, "MereHealingFrames.Events.Power")
--table.insert(Event.Unit.Detail.PowerMax, {MereHealingFrames.Events.PowerMax, "MereHealingFrames", "MereHealingFrames.Events.PowerMax"})
Command.Event.Attach(Event.Unit.Detail.Ready, 		function (handle, units) return cacheUpdate(units, "ready", "Event.Unit.Detail.Ready") end, "MereHealingFrames.Events.Ready")
Command.Event.Attach(Event.Unit.Detail.Role, 		function (handle, units) return cacheUpdateAndRelay(units, "role", "Event.Unit.Detail.Role") end, "MereHealingFrames.Events.Role")
Command.Event.Attach(Event.Unit.Detail.Aggro, 		function (handle, units) return cacheUpdate(units, "aggro", "Event.Unit.Detail.Aggro") end, "MereHealingFrames.Events.Aggro")
Command.Event.Attach(Event.Unit.Detail.Blocked, 	function (handle, units) return cacheUpdate(units, "blocked", "Event.Unit.Detail.Blocked")  end, "MereHealingFrames.Events.Blocked")
Command.Event.Attach(Event.Unit.Detail.Offline, 	function (handle, units) return cacheUpdate(units, "offline", "Event.Unit.Detail.Offline") end, "MereHealingFrames.Events.Offline")
Command.Event.Attach(Event.Unit.Detail.Afk, 		function (handle, units) return cacheUpdate(units, "afk", "Event.Unit.Detail.Afk") end, "MereHealingFrames.Events.Afk")
Command.Event.Attach(Event.Unit.Detail.Name, 		function (handle, units) return cacheUpdate(units, "name", "Event.Unit.Detail.Name") end, "MereHealingFrames.Events.Name")
-- actually did I use this as an indicator that the unit was loaded up?
--table.insert(Event.Unit.Detail.PlanarMax,	{ function (units) return cacheUpdate(units, "planarMax", "Event.Unit.Detail.PlanarMax") end, "MereHealingFrames", "MereHealingFrames.Events.PlanarMax"})
Command.Event.Attach(Event.Unit.Detail.Coord,       MereHealingFrames.Events.Coords, "MereHealingFrames.Events.Coord")
Command.Event.Attach(Event.Unit.Detail.Radius,      MereHealingFrames.Events.Radius, "MereHealingFrames.Events.Radius")
Command.Event.Attach(Event.Unit.Detail.Absorb, 		function (handle, units) return cacheUpdate(units, "absorb", "Event.Unit.Detail.Absorb") end, "MereHealingFrames.Events.Name")

Command.Event.Attach(Event.TEMPORARY.Role, MereHealingFrames.Events.SoulSpecChange, "MereHealingFrames.Events.SoulSpecChange")
Command.Event.Attach(Event.Ability.New.Add, MereHealingFrames.Events.AbilityAdd, "MereHealingFrames.Events.AbilityAdd")

Command.Event.Attach(Event.Buff.Add, MereHealingFrames.Events.BuffAdd, "MereHealingFrames.Events.BuffAdd")
Command.Event.Attach(Event.Buff.Change, MereHealingFrames.Events.BuffChange, "MereHealingFrames.Events.BuffChange")
Command.Event.Attach(Event.Buff.Remove, MereHealingFrames.Events.BuffRemove, "MereHealingFrames.Events.BuffRemove")

Command.Event.Attach(Event.System.Secure.Leave, MereHealingFrames.Events.SecureLeave, "MereHealingFrames.Events.SecureLeave")
Command.Event.Attach(Event.System.Secure.Enter, MereHealingFrames.Events.SecureEnter, "MereHealingFrames.Events.SecureEnter")