local LDB = LibStub("LibDataBroker-1.1")
local is_init = false

local ADDONNAME = "Broker: Everything"


local LDB	= LibStub:GetLibrary("LibDataBroker-1.1")
LibQTip	= LibStub:GetLibrary("LibQTip-1.0")
L		= LibStub:GetLibrary( "AceLocale-3.0" ):GetLocale( ADDONNAME )

local RAID_CLASS_COLORS = CUSTOM_CLASS_COLORS or RAID_CLASS_COLORS
local tooltip = nil

Broker_Everything = CreateFrame("Frame")
Broker_Everything:RegisterEvent("ADDON_LOADED")

-- config
Broker_EverythingDB = {}

local Print = function (w, x)
	DEFAULT_CHAT_FRAME:AddMessage("|cFFFF0000Broker_Everything:|r|cFF00FF00" .. w .. ":|r " .. x)
end

--
-- text coloring
--
Broker_Everything.color = {
	className  = function(x, class)  -- When providing the class name.
		local classcol = RAID_CLASS_COLORS[class] or {["r"] = 1, ["g"] = 1, ["b"] = 0}
		return format("|cff%02x%02x%02x%s|r", classcol["r"]*255, classcol["g"]*255, classcol["b"]*255, x)
	end,
	
	red = function(x)
		return format("|cffc41f3b%s|r", x)
	end,

	brtred = function(x)
		return format("|cffff0000%s|r", x)
	end,

	orange = function(x)
		return format("|cffff7d0a%s|r", x)
	end,

	ltyellow = function(x)
		return format("|cfffff569%s|r", x)
	end,

	dkyellow = function(x)
		return format("|cFFFFCC00%s|r", x)
	end,

	ltblue = function(x)
		return format("|cff69ccf0%s|r", x)
	end,

	ltgreen = function(x)
		return format("|cffabd473%s|r", x)
	end,

	dkgreen = function(x)
		return format("|cff00ff00%s|r", x)
	end,

	grey = function(x)
		return format("|cff808080%s|r", x)
	end,

	class = function(x,c)
		local co = RAID_CLASS_COLORS[c]
		local r, g, b = floor(co.r * 255), floor(co.g * 255), floor(co.b * 255)
		return string.format("|cFF%02x%02x%02x%s|r", r, g, b, x)
	end,

	white = function(x)
		return format("|cffffffff%s|r", x)
	end,
}


--
-- update handling
--
local updateTab = {}
local updateFrame = nil
local updateMmpf = 0

local function UpdateHandler(self, elapsed)
	updateMmpf = updateMmpf + elapsed
	if updateMmpf < 1 then
		return
	end

	updateMmpf = 0

	for _, v in pairs(updateTab) do
		v.elapsed = v.elapsed + 1
		if v.elapsed > v.interval then
			v.elapsed = v.elapsed - v.interval
			v.func (v.arg)
		end
	end
end


local function RegisterForUpdates(func, arg, interval)
	func(arg)

	if not updateFrame then
		updateFrame = CreateFrame("Frame")
		updateFrame:SetScript("OnUpdate", UpdateHandler)
	end

	table.insert (updateTab, {
		func = func,
		arg = arg,
		interval = interval,
		elapsed = 0,
	})
end


local modules_init_later = {}
function Broker_Everything:Register(name, icon, init, event, events, click, tooltip, up, upi)
	if not is_init then
		table.insert(modules_init_later, {name, icon, init, event, events, click, tooltip, up, upi})
		return
	end


	if icon == 0 then icon = nil end
	if init == 0 then init = nil end
	if event == 0 then event = nil end
	if events == 0 then events = nil end
	if click == 0 then click = nil end
	if tooltip == 0 then tooltip = nil end

	local ret = {}
	
	if event then
		ret = CreateFrame("Frame")
	end

	local label = nil

	if Broker_EverythingDB.labels == 1 then
		label = "BE: " .. name
	end

	if init then
		init()
	end

	ret.obj = LDB:NewDataObject (name, {
		type = "data source",
		icon = icon,
		iconCoords = {0.05, 0.95, 0.05, 0.95},
		OnClick = click,
		OnTooltipShow = tooltip,
		label = label,
	})

	if event then
		for _, e in pairs(events) do
			ret:RegisterEvent(e)
		end

		ret:SetScript ("OnEvent", event)
		ret.eventfunc = event
	end

	if up then
		RegisterForUpdates(up, ret, upi)
	end

	if init then
		init(ret)
	end
end


function Broker_Everything:DoRegister()
	for _, v in ipairs(modules_init_later) do
		local w = "use_" .. v[1]:lower()

		if not Broker_EverythingDB[w] then
			Broker_EverythingDB[w] = 1
		end

		if Broker_EverythingDB[w] == 1 then
			self:Register(unpack (v))
		end
	end
	modules_init_later = nil
end


Broker_Everything:SetScript("OnEvent", function (self, e, n)
	if e == "ADDON_LOADED" and n == "Broker_Everything" then
		is_init = true

		if not Broker_EverythingDB.reset then
			Broker_EverythingDB = {}
			Broker_EverythingDB.reset = 1
			Print("Warning", "saved variables have been reset. sorry for the inconvenience!")
		end

		if not Broker_EverythingDB.labels then
			Broker_EverythingDB.labels = 0
		end

		self:DoRegister()
	end
end)


SlashCmdList["BROKER_EVERYTHING"] = function(cmd)
	local cmd, arg = strsplit(" ", cmd:lower(), 2)

	if cmd == "list" then
		Print("cfg", "Data feeds:")
		for k, v in pairs(Broker_EverythingDB) do
			if string.sub(k, 0, 4) == "use_" then
				Print("cfg", string.sub(k, -1 * (string.len(k) - 4)) .. " (" .. (v == 1 and Broker_Everything.color.dkgreen("enabled") or Broker_Everything.color.brtred("disabled")) .. ")")
			end
		end
		return
	end

	if cmd == "labels" then
		if Broker_EverythingDB.labels == 1 then
			Broker_EverythingDB.labels = 0
			Print("cfg", "labels disabled after reload.")
		else
			Broker_EverythingDB.labels = 1
			Print("cfg", "labels enabled after reload.")
		end
		return
	end

	if cmd == "max_addons" then
		Broker_EverythingDB.mem_max_addons = tonumber(arg)
		if Broker_EverythingDB.mem_max_addons > 0 then
			Print("cfg", "showing a maximum of " .. Broker_EverythingDB.mem_max_addons .. " addons.")
		else
			Print("cfg", "showing all addons.")
		end
		return
	end

	local w = "use_" .. cmd
	for k, v in pairs(Broker_EverythingDB) do
		if k == w then
			local x = Broker_EverythingDB[w]
			if x == 1 then
				Broker_EverythingDB[w] = 0
				Print("cfg", "disabling " .. cmd .. " on next reload.")
			else
				Broker_EverythingDB[w] = 1
				Print("cfg", "enabling " .. cmd .. " on next reload.")
			end
		end
	end
end


SLASH_BROKER_EVERYTHING1 = "/broker_everything"
SLASH_BROKER_EVERYTHING2 = "/be"

