--- LibDataBroker-1.1 ---
local MAJOR, MINOR = "LibDataBroker-1.1", 4
local lib = LibStub:NewLibrary(MAJOR, MINOR)
if not lib then return end

lib.callbacks = lib.callbacks or LibStub("CallbackHandler-1.0"):New(lib)
lib.attributestorage = lib.attributestorage or {}
lib.namestorage = lib.namestorage or {}
lib.proxystorage = lib.proxystorage or {}

local attributestorage = lib.attributestorage
local namestorage = lib.namestorage
local proxystorage = lib.proxystorage
local callbacks = lib.callbacks

function lib:NewDataObject(name, dataobj)
    if proxystorage[name] then return end

    if dataobj then
        assert(type(dataobj) == "table", "Invalid dataobj, must be a table")
        attributestorage[name] = dataobj
    else
        attributestorage[name] = {}
    end

    local proxy = newproxy(true)
    local mt = getmetatable(proxy)
    mt.__index = attributestorage[name]
    mt.__newindex = function(self, key, value)
        attributestorage[name][key] = value
        callbacks:Fire("LibDataBroker_AttributeChanged_"..name, name, key, value, attributestorage[name])
        callbacks:Fire("LibDataBroker_AttributeChanged", name, key, value, attributestorage[name])
    end

    namestorage[name] = proxy
    proxystorage[name] = proxy

    callbacks:Fire("LibDataBroker_DataObjectCreated", name, proxy)
    return proxy
end

function lib:DataObjectIterator()
    return pairs(namestorage)
end

function lib:GetDataObjectByName(name)
    return proxystorage[name]
end

function lib:GetNameByDataObject(dataobj)
    for name, obj in pairs(namestorage) do
        if obj == dataobj then return name end
    end
end
