local addonName, addon = ...
local childName = addon['childName']
local child = addon[childName]
local db
local zzLDB = LibStub:GetLibrary("zzLDB")
local folder = addonName ~= childName  and format("Interface\\AddOns\\%s\\%s", addonName, childName) or format("Interface\\AddOns\\%s", childName)
local L = LibStub("AceLocale-3.0"):GetLocale(childName, true)
local ldbicon = LibStub:GetLibrary("LibDBIcon-1.0")
local GetNumAddOns = GetNumAddOns
local GetAddOnInfo = GetAddOnInfo
local GetAddOnMemoryUsage = GetAddOnMemoryUsage
local GetAddOnCPUUsage = GetAddOnCPUUsage
local replaces = {
	['Sunday'] = true,
	['Monday'] = true,
	['Tuesday'] = true,
	['Wednesday'] = true,
	['Thursday'] = true,
	['Friday'] = true,
	['Saturday'] = true,
	['January'] = true,
	['February'] = true,
	['March'] = true,
	['April'] = true,
	['May'] = true,
	['June'] = true,
	['July'] = true,
	['August'] = true,
	['September'] = true,
	['October'] = true,
	['November'] = true,
	['December'] = true,
}
local IsAddOnLoaded = IsAddOnLoaded
-- Fix Classic
local C_CVar = C_CVar or {
	GetCVarBool = function(value)
		return GetCVar(value) and true or false
	end
}
local GameTimeFrame_OnClick = GameTimeFrame_OnClick or function(self) TimeManagerClockButton:Click() end
-- End of Fix Classic

local function updateainfo()
	child['ainfo'] = child['ainfo'] or {}
	local ainfo = child['ainfo']
	wipe(ainfo)
	UpdateAddOnMemoryUsage()
	UpdateAddOnCPUUsage()
	local name, enabled, security, mem, cpu, _
	for i=1, GetNumAddOns() do
		mem = 0
		cpu = 0
		name, _, _, enabled, _, _, security = GetAddOnInfo(i)
		if(name and enabled and IsAddOnLoaded(i)) then
			mem = GetAddOnMemoryUsage(i)
			cpu = GetAddOnCPUUsage(i)
			ainfo[#ainfo+1] = {
				['name'] = name,
				['mem'] = mem,
				['cpu'] = cpu,
			}
		end
	end
end
local function OnClick(self, button)
	if(button == 'RightButton') then
		if(InterfaceOptionsFrame:IsVisible() and not InCombatLockdown()) then
			InterfaceOptionsFrame:Hide()
		else
			InterfaceOptionsFrame_OpenToCategory(childName)
			InterfaceOptionsFrame_OpenToCategory(childName) -- Twice because of a bug in InterfaceOptionsFrame_OpenToCategory
		end
	elseif(button == 'MiddleButton') then
		local pCPU = C_CVar.GetCVarBool("scriptProfile")
		if(pCPU) then
			pCPU = 0
		else
			pCPU = 1
		end
		C_CVar.SetCVar("scriptProfile", pCPU)
		print(L["CPU setting changed. Please Reload UI."])
		updateainfo()
	else
		if(IsShiftKeyDown()) then
			local db = addon['db']['global']['ldbicons']
			db[childName]['hide'] = not db[childName]['hide']
			if(ldbicon) then
				if(db[childName]['hide']) then
					ldbicon:Hide(childName)
				else
					ldbicon:Show(childName)
				end
			end
		elseif(IsControlKeyDown()) then
			print(L["garbagecollected"])
			collectgarbage("collect")
		else
			GameTimeFrame_OnClick(_G["GameTimeFrame"])
		end
	end
end
local function toggleColor(col,col1,col2)
	return col == col1 and col2 or col1
end
local function compute()
	local c = date(db['clockstring'])
	local d = date(db['datestring'])
	for k in pairs(replaces) do
		if(k ~= L[k]) then
			d = d:gsub(k, L[k])
		end
	end
	local h, w = select(3,GetNetStats())
	local l = db['latencystring']
	l = l:gsub("%%world", w)
	l = l:gsub("%%local", h)
	local f = db['fpsstring']
	f = f:gsub("%%fps",floor(GetFramerate()))
	return c,d,l,f
end
local function sortTab(a,b)
	return a['mem'] > b['mem']
end
local function sortTab2(a,b)
	return a['cpu'] > b['cpu']
end
local function OnTooltipShow(tip)
	local lastainfo = child['lastainfo'] or GetTime() - 1
	local ainfodelay = child['ainfodelay'] or 2
	if(GetTime() > lastainfo) then
		updateainfo()
		child['lastainfo'] = GetTime() + ainfodelay
	end
	local ainfo = child['ainfo']
	local c,d,l,f = compute()
	tip:AddLine(childName)
	local col = "00ff00"
	if(db['expert']) then
		tip:AddLine(child:colorize(d,col))
	else
		tip:AddLine(child:colorize(format("%s, %s.%s",L[date("%A")],date("%d"),L[date("%B")]),col))
	end
	col = toggleColor(col,"ffffff","00ff00")
	if(db["12-Hours"]) then
		tip:AddDoubleLine(child:colorize(L['Time'],col),child:colorize(date("%I:%M:%S"),toggleColor(col,"ffffff","00ff00")))
	else
		tip:AddDoubleLine(child:colorize(L['Time'],col),child:colorize(date("%H:%M:%S"),toggleColor(col,"ffffff","00ff00")))
	end
	col = toggleColor(col,"ffffff","00ff00")
	tip:AddDoubleLine(child:colorize(L['Latency'],col),child:colorize(format("%s ms",select(3,GetNetStats())),toggleColor(col,"ffffff","00ff00")))
	col = toggleColor(col,"ffffff","00ff00")
	tip:AddDoubleLine(child:colorize(L['FPS'],col),child:colorize(format("%i fps",floor(GetFramerate())),toggleColor(col,"ffffff","00ff00")))
	col = toggleColor(col,"ffffff","00ff00")
	tip:AddDoubleLine(child:colorize(L['AddOn Memory'],col),child:colorize(format("%i MB",floor(collectgarbage('count')/1024)),toggleColor(col,"ffffff","00ff00")))
	tip:AddLine(" ")
	tip:AddLine(L["AddOns"])
	sort(ainfo,sortTab)
	local sum,cnt = 0,0
	for _, v in ipairs(ainfo) do
		if(cnt<9) then
			tip:AddDoubleLine(child:colorize(v['name'],"00ffff"),format(L["%i kB"],v['mem']))
			cnt = cnt + 1
		end
		sum = sum + v['mem']
	end
	tip:AddDoubleLine(L['total'],format(L["%i kB"],format("%.2f",sum)))
	local pCPU = C_CVar.GetCVarBool("scriptProfile")
	if(pCPU) then
		tip:AddLine(" ")
		tip:AddLine(L["CPU"])
		sort(ainfo,sortTab2)
		sum,cnt = 0,0
		for _, v in ipairs(ainfo) do
			if(cnt<5) then
				tip:AddDoubleLine(child:colorize(v['name'],"00ffff"),format(L["%i ms"],v['cpu']))
				cnt = cnt + 1
			end
			sum = sum + v['cpu']
		end
		tip:AddDoubleLine(L['total'],format(L["%i ms"],format("%.2f",sum)))
	end
	tip:AddLine(" ")
	tip:AddLine(L['HINT4'])
	tip:AddLine(L["garbagecollect"])
	tip:AddLine(L['HINT3'])
	tip:AddLine(L['HINT5'])
end
local function OnDataUpdate()
	local line = childName
	if(db['expert']) then
		local c,d,l,f = compute()
		line = db['ldbstring']
		line = line:gsub("%%clock", child:colorize(c,db['clockcolor']))
		line = line:gsub("%%date", child:colorize(d,db['datecolor']))
		line = line:gsub("%%fps", child:colorize(f,db['fpscolor']))
		line = line:gsub("%%latency", child:colorize(l,db['latencycolor']))
	else
		line = ''
		if(db["showClock"]) then
			line = format("%s%s ", line, db["12-Hours"] and date("%I:%M") or date("%H:%M"))
		end
		if(db["showLatency"]) then
			line = format("%s%s", line, child:colorize(format("%s ms ",select(3,GetNetStats())), "ffff00"))
		end
		if(db["showFPS"]) then
			line = format("%s%s fps", line, floor(GetFramerate()))
		end
	end
	if(line ~= '') then
		child:OnText(childName, line)
	else
		child:OnText(childName, childName)
	end
	C_Timer.After(db['update'] or 2, OnDataUpdate)
end
function child:update()
	OnDataUpdate()
end
child['ldb'] = { -- https://github.com/tekkub/libdatabroker-1-1/wiki/Data-Specifications
	['type'] = 'data source', -- required: 'data source' or 'launcher'
	['text'] = childName, -- required/optional for launcher
	['icon'] = format("%s\\icon2.tga", folder), -- optional/required for launcher
	['OnClick'] = OnClick, -- optional/required for launcher
	['OnTooltipShow'] = OnTooltipShow, -- optional
}
local init = {
	Setup = function(self, childName, event)
--		print("setup ldb", childName, event)
		child.OnText = zzLDB.DefaultOnText
		db = child['db']
		C_Timer.After(db['update'], OnDataUpdate)
	end
}
addon.RegisterCallback(init, format("Init%s", childName), 'Setup', childName)