-- 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.PlayerEventManager = MereHealingFrames.PlayerEventManager or {}

local NextPlayerEventSetId = 0

local PlayerEventFactoryBucket = {}

function MereHealingFrames.PlayerEventManager.NewEvents()
    if #PlayerEventFactoryBucket ~= 0 then
        return table.remove(PlayerEventFactoryBucket)
    else
        return MereHealingFrames.PlayerEventManager.PlayerEvents:new({})
    end
end

function MereHealingFrames.PlayerEventManager.OldEvents(playerEvents)
    playerEvents:ResetEvents()
    return table.insert(PlayerEventFactoryBucket, playerEvents)
end

MereHealingFrames.PlayerEventManager.PlayerEvents = {}

function MereHealingFrames.PlayerEventManager.PlayerEvents:new()
    local this = {}

    setmetatable(this, self)
    self.__index = self

    this.Functions = {}
    this.Events = {}
    this:HookEvents()

    return this
end

function MereHealingFrames.PlayerEventManager.PlayerEvents:HookEvents()
    local PlayerEventSetId = NextPlayerEventSetId
    NextPlayerEventSetId = NextPlayerEventSetId + 1

    local EventSetName = 'PlayerEvents.EventSet' .. PlayerEventSetId
    self.EventSetName = EventSetName

    for EventName, EventDetails in pairs(MereHealingFrames.PlayerEventDB.EventDB) do
        local EventPath = EventSetName .. '.' .. EventName
        local caller, handle = Utility.Event.Create("MereHealingFrames", EventPath)
        self.Functions[EventName] = caller
        self.Events[EventName] = handle
    end

    self.EventTable = Event.MereHealingFrames[EventSetName]
end

function MereHealingFrames.PlayerEventManager.PlayerEvents:ResetEvents()
    -- I so hope this isn't expensive...
    for eventName, eventHandle in pairs(self.Events) do
        local hookedEvents = Inspect.Event.List(eventHandle)
        for _, eventDetail in ipairs(hookedEvents) do
            MereHealingFrames.Debug(5, "Detaching from event %s, label %s", eventName, eventDetail.label)
            Command.Event.Detach(eventHandle, eventDetail.handler, eventDetail.label, eventDetail.priority, eventDetail.owner)
        end
    end
end