local addonname, addon = ...
local FRAME_INSET_TOP = 20 -- 위 여백 (타이틀 크기)
local FRAME_INSET_BOTTOM = 10 -- 아래 여백
local FRAME_INSET_LEFT = 5 -- 좌측 여백
local FRAME_INSET_RIGHT = 20 -- 우측 여백 (스크롤바크기 = -5)
local FRAME_INSET_HEADER = 15 -- 헤더 높이
local LIST_ITEM_NUMS = 16 -- 버튼갯수 추가적인 기입을 위해...
local LIST_NUMS = LIST_ITEM_NUMS - 3 -- 보여지는 버튼갯수
local LIST_HEIGHT = 18 -- 버튼높이
local CHILD_ITEM_NUMS = 8 -- 새창에 표시될 애드온 갯수
local UPDATE_RATE = 1 -- 갱신간격 *초
local ADDON_MEMORY_LIMIT = 30 -- 최대로 생각할 메모리 값 (mb) 색상정보때문에 필요

addon.loadedcount = 0
addon.totalmemory = 0
addon.totalmemorys = 0
addon.totalcpu = 0
addon.totalcpus = 0
addon.blzmemorys = 0
addon.blzmemory = 0
addon.loadedAddonList = {}
addon.profileStartTime = GetTime()
addon.newwindowaddon = {} -- 새창에 표시할 애드온

addon.OnUpdateFrame = CreateFrame("frame", nil, UIParent)
addon.OnUpdateFrame:Hide()
--###################################################################################################################--
local main = CreateFrame("frame", addonname.."MainFrame", UIParent)
addon.main = main
main.sort_name = "mem"
main.sort_reverse = false
main.listnums = LIST_ITEM_NUMS
main:Hide()
main.nextUpdate = 0
main:SetHeight(LIST_HEIGHT*LIST_ITEM_NUMS+FRAME_INSET_TOP+FRAME_INSET_HEADER+FRAME_INSET_BOTTOM)
main:SetPoint("CENTER")
main.scroll = CreateFrame("slider", main:GetName().."Scroll", main, "UIPanelScrollBarTemplate")
main.resize = CreateFrame("frame", nil, main)
local t
-- 상단 배경
--local t = main:CreateTexture(nil, 'border')
--t:SetPoint("topleft", main, "topleft", 3, -3)
--t:SetPoint("bottomright", main, "topright", -3, -FRAME_INSET_TOP)
--t:SetTexture(0, 0, 0, 1)

main.header = CreateFrame("frame", main:GetName().."Header", main)
main.header:SetPoint("topleft", main, "topleft", 5, -FRAME_INSET_TOP)
main.header:SetPoint("bottomright", main, "topright", -5, -FRAME_INSET_TOP+-FRAME_INSET_HEADER)
t = main:CreateTexture(nil, 'border')
t:SetAllPoints(main.header)
t:SetTexture(0.3, 0.3, 0.3, 0)

-- 메인프레임의 기본설정
table.insert(UISpecialFrames, main:GetName())
main.index = 1
main:SetToplevel(true)
main:SetPoint("CENTER")
main:EnableMouse(true)
main:EnableMouseWheel(true)
main:SetMovable(true)
main:SetClampedToScreen(true)
main:RegisterForDrag("LeftButton")
main:SetScript("OnDragStart", main.StartMoving)
main:SetScript("OnDragStop", main.StopMovingOrSizing)
main:SetBackdrop({
	bgFile="Interface\\Tooltips\\UI-Tooltip-Background", edgeFile="Interface\\Tooltips\\UI-Tooltip-Border",
	insets = {left = 4, right = 4, top = 4, bottom = 4}, tileSize = 16, edgeSize = 16, tile=true
})
main:SetBackdropBorderColor(0, 0, 0, 1)

main.dropdown = CreateFrame("frame", main:GetName().."Dropdown", main, "UIDropDownMenuTemplate")
main.close = CreateFrame("button", main:GetName().."Close", main)
main.close:SetPoint("TOPRIGHT", -5, -5)
main.close:SetNormalFontObject(GameFontHighlightSmall)
main.close:SetHighlightFontObject(GameFontNormalSmall)
main.close:SetSize(15, 15)
main.close:SetText("X")

main.option = CreateFrame("button", main:GetName().."Option", main)
main.option:SetPoint("TOPRIGHT", -25, -5)
main.option:SetNormalFontObject(GameFontHighlightSmall)
main.option:SetHighlightFontObject(GameFontNormalSmall)
main.option:SetSize(15, 15)
main.option:SetText("O")

main.scroll:SetValueStep(1)
main.scroll:SetPoint("topleft", main, "topright", -FRAME_INSET_RIGHT, -(FRAME_INSET_TOP+FRAME_INSET_HEADER+20))
main.scroll:SetPoint("bottomright", main, "bottomright", -5, FRAME_INSET_BOTTOM+15+(LIST_ITEM_NUMS-LIST_NUMS)*LIST_HEIGHT)
main.scroll:SetAlpha(0.4)

main.tooltipText = main:CreateFontString(nil, "overlay")
main.tooltipText:SetPoint("right", main.option, "left", -5, 0)
main.tooltipText:SetFontObject(GameFontDisable)

-- 스크립트 등록
local function onmousewheel(self, arg1, arg2)
	if type(arg2) ~= "number" then
		arg2 = math.floor(LIST_NUMS/2)
	end
	arg1 = -arg1*arg2
	local x = self.index
	self.index = math.max(1, math.min(addon.loadedcount-LIST_NUMS+1, self.index+ arg1))
	if x ~= self.index then
		self:Refresh()
	end
end

main.option:SetScript("OnClick", function(self)
	ToggleDropDownMenu(1, nil, main.dropdown, self:GetName(), 0, -10)
end)

main:SetScript("OnMouseWheel", onmousewheel)
main.scroll:SetScript("OnValueChanged", function(self, value)
	local value = math.floor(value)
	if main.index ~= value then
		main.index = value
		main:Refresh()
	end
end)

_G[main.scroll:GetName().."ScrollUpButton"]:SetScript("OnClick", function(self)   onmousewheel(main, 1, 1)  end)
_G[main.scroll:GetName().."ScrollDownButton"]:SetScript("OnClick", function(self) onmousewheel(main, -1, 1) end)
main.close:SetScript("OnClick", function(self) self:GetParent():Hide() end)

local function onclick_header(self)
	local parent = self:GetParent():GetParent()
	if parent.sort_name == self.key then
		parent.sort_reverse = not parent.sort_reverse
	else
		parent.sort_reverse = false
	end
	parent.sort_name = self.key
	addon.nextUpdate = 10
	if parent == addon.child then
		addon.child:Refresh()
	end
end
local function CreateHeaderButton(name, key, text, width, justifyH, parent, tooltipText)
	parent.xPosition = parent.xPosition or {_total = 0, _nocpu = 0}
	local t = CreateFrame("button", parent:GetName()..name, parent)
	t.key = key
	t:SetNormalFontObject(GameFontNormalSmall)
	t:SetHighlightFontObject(GameFontHighlightSmall)
	t:SetPoint("LEFT", parent.xPosition._total+FRAME_INSET_LEFT, 0)
	t.position = parent.xPosition._total
	parent.xPosition._total = parent.xPosition._total + width
	parent.xPosition[key] = name
	t:SetSize(width, FRAME_INSET_HEADER)
	t:SetText(text)
	t.justifyH = justifyH
	t:SetScript("OnClick", onclick_header)
	t:SetScript("OnEnter", function()main.tooltipText:SetText(tooltipText or "") end)
	t:SetScript("OnLeave", function()main.tooltipText:SetText("")end)
	if key:sub(1,3) ~= "cpu" then
		parent.xPosition._nocpu = parent.xPosition._nocpu + width
	end
end

CreateHeaderButton("HeaderButtonName", "name", "이름", 150, "left", main.header)
CreateHeaderButton("HeaderButtonMem", "mem", "메모리", 70, "right", main.header)
CreateHeaderButton("HeaderButtonMems", "mems", "메모리변화", 70, "right", main.header)
CreateHeaderButton("HeaderButtonCPUT", "cput", "전체점유(ms)", 70, "right", main.header, "애드온이 동작하는데 점유했던 전체시간")
CreateHeaderButton("HeaderButtonCPUs", "cpus", "점유변화(ms)", 70, "right", main.header, "1초간 cpu를 점유한 시간")
CreateHeaderButton("HeaderButtonCPUavr", "cpuavr", "점유평균(ms)", 70, "right", main.header, "경과시간동안 cpu를 점유한 평균시간")

local function OnClick_ListButton(self)
	if not IsControlKeyDown() then return end
	local name = self.name:GetText()
	if not addon.newwindowaddon[name] then
		addon.newwindowaddon[name] = true
		for k,v in ipairs(addon.loadedAddonList) do
			if v.name == name then
				table.insert(addon.newwindowaddon, v)
				break
			end
		end
		addon.child:Refresh()
	else
		addon.newwindowaddon[name] = nil
		for i,v in ipairs(addon.newwindowaddon) do
			if v.name == name then
				table.remove(addon.newwindowaddon, i)
				break
			end
		end
		if #addon.newwindowaddon == 0 then
			return addon.child:Hide()
		end
		addon.child:Refresh()
	end
	addon.child:Show()
end
local function createListButtonText(button, key, header)
	local t = button:CreateFontString(nil, "artwork")
	t:SetFontObject(GameFontHighlight)
	local x = _G[header:GetName()..header.xPosition[key]]
	t:SetSize(x:GetWidth(), LIST_HEIGHT)
	t:SetPoint("LEFT", x.position, 0)
	t:SetJustifyH(x.justifyH)
	button[key] = t
	return t
end
for i = 0, LIST_ITEM_NUMS-1 do
	local btn = CreateFrame("button", main:GetName().."ListButton"..i, main)
	btn:SetSize(main.header.xPosition._total, LIST_HEIGHT)
	btn:SetPoint("TOPLEFT", main.header, "bottomleft", FRAME_INSET_LEFT, -i*LIST_HEIGHT)
	btn:SetScript("OnClick", OnClick_ListButton)
	btn:SetScript("OnEnter", function() addon.main.tooltipText:SetText("Ctrl+클릭 : 새창에 표시/삭제") end)
	btn:SetScript("OnLeave", function() addon.main.tooltipText:SetText("") end)
	createListButtonText(btn, "name", main.header)
	createListButtonText(btn, "mem", main.header)
	createListButtonText(btn, "mems", main.header)
	createListButtonText(btn, "cpus", main.header)
	createListButtonText(btn, "cput", main.header)
	createListButtonText(btn, "cpuavr", main.header)
end



main:SetScript("OnShow", function(self)
	addon.OnUpdateFrame:Show()
	local bool = GetCVarBool("scriptProfile")
	local xPosition = self.header.xPosition
	local name = self.header:GetName()
	if bool then
		_G[name.."HeaderButtonCPUs"]:Show()
		_G[name.."HeaderButtonCPUT"]:Show()
		_G[name.."HeaderButtonCPUavr"]:Show()
		self:SetWidth(xPosition._total+FRAME_INSET_LEFT+25)
	else
		_G[name.."HeaderButtonCPUs"]:Hide()
		_G[name.."HeaderButtonCPUT"]:Hide()
		_G[name.."HeaderButtonCPUavr"]:Hide()
		self:SetWidth(xPosition._nocpu+FRAME_INSET_LEFT+25)
	end
	for i = 0, self.listnums-1 do
		local btn = _G[self:GetName().."ListButton"..i]
		if bool then
			btn:SetWidth(xPosition._total)
			btn.cpus:Show()
			btn.cput:Show()
			btn.cpuavr:Show()
		else
			btn:SetWidth(xPosition._nocpu)
			btn.cpus:Hide()
			btn.cput:Hide()
			btn.cpuavr:Hide()
		end
	end
end)

--###################################################################################################################--

addon.totalbutton = _G[main:GetName().."ListButton"..(LIST_NUMS+1)]
addon.blzbutton = _G[main:GetName().."ListButton"..(LIST_NUMS+2)]


local function SetTooltipPosition(self)
	addon.main:ClearAllPoints()
	local _, y = self:GetCenter()
	local _, uy = UIParent:GetCenter()
	if y > uy then
		addon.main:SetPoint("TOP", self, "BOTTOM", 0, -5)
	else
		addon.main:SetPoint("BOTTOM", self, "TOP", 0, 5)
	end
	addon.main:Show()
end

local function SetTooltipMode()
	addon.hideMainFrame = true
	addon.main.close:Hide()
	addon.main.option:Hide()
	addon.main:SetBackdropBorderColor(1, 1, 1, 1)
	addon.main:SetBackdropColor(0.09, 0.09, 0.19, 1)
end
local function SetWindowMode()
	addon.hideMainFrame = false
	addon.main.close:Show()
	addon.main.option:Show()
	addon.main:SetBackdropBorderColor(0, 0, 0, 1)
	addon.main:SetBackdropColor(0, 0, 0, 1)
end
local function OnDragStart(self)
	if IsShiftKeyDown() then 
		self:StartMoving()
		addon.startmoving = true
		if addon.hideMainFrame then
			addon.main:Hide()
		end
	end
end

local function OnDragStop(self)
	self:StopMovingOrSizing()
	addon.startmoving = nil
end
local function OnEnter(self)
	if addon.startmoving then
		return
	end
	addon.onEnterButton = true
	addon:UpdateAddons()
	if not addon.main:IsShown() then
		addon.nextUpdate = 10
		SetTooltipMode()
	end
	if addon.hideMainFrame then
		SetTooltipPosition(self)
	end
end
local function OnLeave(self)
	addon.onEnterButton = false
	if addon.hideMainFrame then
		addon.main:Hide()
	end
	SetWindowMode()
end
local function OnClick(self, button)
	if button == "LeftButton" then
		if addon.startmoving then
			return
		end
		if addon.hideMainFrame then
			SetWindowMode()
		else
			SetTooltipMode()
		end
		addon.main:Show()
	end
end
local function OnMouseWheel(self, ...)
	onmousewheel(main, ...)
end

local empty = {}
empty.text = ""
empty.notClickable = true
empty.notCheckable = true

UIDropDownMenu_Initialize(main.dropdown, function(self, level)
	local info
	if not level then
		return
	end

	info = UIDropDownMenu_CreateInfo()
	info.text = "실행중인 애드온 : "..addon.loadedcount.." 개"
	info.isTitle = true
	info.justifyH = "CENTER"
	info.notClickable = true
	info.notCheckable = true
	UIDropDownMenu_AddButton(info)

	UIDropDownMenu_AddButton(empty)
--[[
	info = UIDropDownMenu_CreateInfo()
	info.text = "숨긴 애드온 표시하기"
	info.notCheckable = true
	info.disabled = not (next(addon.hideaddon))
	info.func = function()wipe(addon.hideaddon)main.nextUpdate = 10 end
	UIDropDownMenu_AddButton(info)
--]]
	info = UIDropDownMenu_CreateInfo()
	info.text = "메모리 정리"
	info.notCheckable = true
	info.func = function()collectgarbage()end
	UIDropDownMenu_AddButton(info)

	local cvar = GetCVarBool("scriptProfile")
	
	if cvar then
		info = UIDropDownMenu_CreateInfo()
		info.text = "scriptProfile 초기화"
		info.func = ResetCPUUsage
		info.justifyH = "LEFT"
		info.notCheckable = true
		UIDropDownMenu_AddButton(info)
	end

	UIDropDownMenu_AddButton(empty)

	info = UIDropDownMenu_CreateInfo()
	info.text = "설정시 바로 UI가 재실행됩니다"
	info.justifyH = "CENTER"
	info.isTitle = true
	info.notCheckable = true
	UIDropDownMenu_AddButton(info)
	
	info = UIDropDownMenu_CreateInfo()
	info.text = "scriptProfile "..(cvar and "끄기" or "켜기")
	info.notCheckable = true
	info.func = function()
		SetCVar("scriptProfile", cvar and "0" or "1")
		ReloadUI()
	end
	UIDropDownMenu_AddButton(info)
end, "MENU")

local function sort_list(a, b, obj)
	local x = obj.sort_name
	if a[x] == b[x] then
		if obj.sort_reverse then
			return a.name > b.name
		else
			return a.name < b.name
		end
	end
	if obj.sort_reverse then
		return a[x] < b[x]
	end
	return a[x] > b[x]
end
local function sortList_main(a, b) return sort_list(a, b, addon.main) end

hooksecurefunc("ResetCPUUsage", function()
	for i,v in pairs(addon.list) do
		v.prevcpu = 0
	end
	addon.profileStartTime = GetTime()
end)

function addon:UpdateAddons()
	local sp = GetCVarBool("scriptProfile")
	if sp then
		UpdateAddOnCPUUsage()
	end
	UpdateAddOnMemoryUsage()

	self.loadedcount = 0
	self.totalcpu = 0
	self.totalcpus = 0
	self.totalmemory = 0
	self.totalmemorys = 0
	self.blzmemorys = self.blzmemory
	self.blzmemory = 0
	self.totalcpuavr = 0
	self.profileTime = GetTime() - self.profileStartTime

	wipe(self.loadedAddonList)
	for i,v in pairs(addon.list) do
		v.loaded = IsAddOnLoaded(v.idx)
		if v.loaded then
			self.loadedcount = self.loadedcount + 1
			table.insert(self.loadedAddonList, v)
			local prev = v.mem or 0
			v.mem = GetAddOnMemoryUsage(v.idx)
			v.mems = v.mem-prev
			self.totalmemory = self.totalmemory + v.mem
			self.totalmemorys = self.totalmemorys + v.mems
			if sp then
				prev = v.cput or 0
				v.cput = GetAddOnCPUUsage(v.idx)
				v.cpus = v.cput-prev
				v.cpuavr = v.cput / self.profileTime
				self.totalcpu = self.totalcpu + v.cput
				self.totalcpus = self.totalcpus + v.cpus
			end
		end
	end
	if sp then
		self.totalcpuavr = self.totalcpu / self.profileTime
	end
	self.blzmemory = collectgarbage("count") - self.totalmemory
	self.blzmemorys = self.blzmemory - self.blzmemorys
end
local function GetTotalMemoryText(v)
	return "|cFFFF%02X00%.2f |cFFAA8800mb", (1-v/(ADDON_MEMORY_LIMIT*1024))*255, v / 1024
end
local function GetMemoryText(v)
	if v > 1024*10 then
		return "|cFFFF0000%.2f |cFFAA8800mb", v / 1024
	elseif v > 1024*5 then
		return "|cFFFF8800%.2f |cFFAA8800mb", v / 1024
	elseif v > 1024 then
		return "|cFFFFCC00%.2f |cFFAA8800mb", v / 1024
	elseif v > 512 then
		return "|cFFFFFF00%.1f |cFF88CC00kb", v
	elseif v > 256 then
		return "|cFFAAFF00%.1f |cFF88CC00kb", v
	else
		return "|cFF00DD00%.1f |cFF88CC00kb", v
	end
end

local function GetMemorySText(v)
	if v == 0 then
		return "", ""
	elseif v > 1024 then
		return "|cFFFF0000%.1f mb", v / 1024
	elseif v > 0 then
		return "|cFFFF4400%.2f kb", v
	else
		return "|cFF44FF00%.2f kb", v
	end
end

function main:Refresh(childshown)
	table.sort(addon.loadedAddonList, sortList_main)
	local num = addon.loadedcount
	for i = 0, LIST_NUMS-1 do
		local btn = _G[self:GetName().."ListButton"..i]
		local idx = i + self.index
		local value = addon.loadedAddonList[idx]
		if num < idx then
			btn:Hide()
		else
			btn:Show()
			btn.name:SetText(value.name)
			btn.mem:SetFormattedText(GetMemoryText(value.mem))
			btn.mems:SetFormattedText(GetMemorySText(value.mems))
			if value.cpus == 0 then
				btn.cpus:SetText("")
			else
				btn.cpus:SetFormattedText("%.2f", value.cpus)
			end
			btn.cput:SetFormattedText("%.1f", value.cput)
			btn.cpuavr:SetFormattedText("%.2f", value.cpuavr or 0)
		end
	end
	local btn = addon.totalbutton

	btn.name:SetText("|cFFFFCC00전체 사용량")
	btn.mem:SetFormattedText(GetTotalMemoryText(addon.totalmemory))
	btn.mems:SetFormattedText(GetMemorySText(addon.totalmemorys))
	if addon.totalcpus == 0 then
		btn.cpus:SetText("")
	else
		btn.cpus:SetFormattedText("%.2f", addon.totalcpus or 0)
	end
	btn.cput:SetFormattedText("%.1f", addon.totalcpu or 0)
	btn.cpuavr:SetFormattedText("%.2f", addon.totalcpuavr or 0)

	btn = addon.blzbutton
	btn.name:SetText("|cFFFFCC00기본 UI")
	btn.mem:SetFormattedText(GetTotalMemoryText(addon.blzmemory))
	btn.mems:SetFormattedText(GetMemorySText(addon.blzmemorys))
	btn.cpus:SetText("|cFFFFCC00경과시간")
	btn.cpuavr:SetFormattedText("%d 초", addon.profileTime)

	self.scroll:SetMinMaxValues(1, math.max(1, num-LIST_NUMS+1))
	self.scroll:SetValue(self.index)
end
addon.nextUpdate = 0
addon.OnUpdateFrame:SetScript("OnUpdate", function(self, elapsed)
	addon.nextUpdate = addon.nextUpdate + elapsed
	if addon.nextUpdate >= UPDATE_RATE then
		addon.nextUpdate = 0
		local ms, cs = addon.main:IsShown(), addon.child:IsShown()
		if not (ms or cs) then return self:Hide() end

		addon:UpdateAddons()
		if ms then addon.main:Refresh() end
		if cs then addon.child:Refresh() end
	end
end)

-- 명령어
SlashCmdList.AMMCOMMAND = function(x)
	SetWindowMode()
	addon:UpdateAddons()
	addon.nextUpdate = 10;
	addon.main:Show()
end
SLASH_AMMCOMMAND1 = "/mem"
SLASH_AMMCOMMAND2 = "/ㅡ드"
SLASH_AMMCOMMAND3 = "/멤"

-- 버튼만들어 등록시 버튼위에서 마우스휠 움직일시 스크롤 동작
function addon:RegisterButton(button)
	button:EnableMouseWheel(true)
	button:SetMovable(true)
	button:RegisterForDrag("leftbutton")
	button:SetScript("OnEnter", OnEnter)
	button:SetScript("OnLeave", OnLeave)
	button:SetScript("OnClick", OnClick)
	button:SetScript("OnMouseWheel", OnMouseWheel)
	button:SetScript("OnDragStart", OnDragStart) 
	button:SetScript("OnDragStop", OnDragStop)
end

-- LDB 지원용 OnMouseWheel을, OnLeave의 어이없는 동작..ㅡ_ㅡ;
-- why? ... OnMouseWheel을 제대로 지원하는 것을 하나뿐이 못봤다. 그외에는 전부 정상작동안했다
-- OnClick에서 OnLeave가 호출된다.. 뭐냐 그건?
local ldb = LibStub and LibStub("LibDataBroker-1.1", 1)
if ldb then
	addon.ldb = ldb:NewDataObject(addonname, {
		type = "launcher",
		icon = [==[Interface\AddOns\Addon_Memory\icon.tga]==],
		label = addonname,
		--type = "data source",
		--text = "",
		OnClick = OnClick,
		OnEnter = function(self)
			if not self:GetScript("OnMouseWheel") then
				self:SetScript("OnMouseWheel", OnMouseWheel)
				self:EnableMouseWheel(true)
			end
			OnEnter(self)
		end,
		OnLeave = function(self, ...)
			if GetMouseFocus() == self then return end -- 이게 뭔짓이여...
			OnLeave(self, ...)
		end,
		OnMouseWheel = OnMouseWheel
	});
end
--=============================================================================================================

local child = CreateFrame("frame", addonname.."ChildFrame", UIParent)
addon.child = child
child.listnums = CHILD_ITEM_NUMS
child.sort_name = "mem"
child.sort_reverse = false
child:Hide()
child.nextUpdate = 0
child:SetHeight(LIST_HEIGHT*child.listnums+FRAME_INSET_TOP+FRAME_INSET_HEADER+FRAME_INSET_BOTTOM)
child:SetPoint("CENTER")
child.scroll = CreateFrame("slider", child:GetName().."Scroll", child, "UIPanelScrollBarTemplate")
child.resize = CreateFrame("frame", nil, child)
local t

child.header = CreateFrame("frame", child:GetName().."Header", child)
child.header:SetPoint("topleft", child, "topleft", 5, -FRAME_INSET_TOP)
child.header:SetPoint("bottomright", child, "topright", -5, -FRAME_INSET_TOP+-FRAME_INSET_HEADER)
t = child:CreateTexture(nil, 'border')
t:SetAllPoints(child.header)
t:SetTexture(0.3, 0.3, 0.3, 0)

-- 메인프레임의 기본설정
child.index = 1
child:SetToplevel(true)
child:SetFrameLevel(5)
child:SetPoint("TOP", main, "BOTTOM", 0, 0)
child:EnableMouse(true)
child:EnableMouseWheel(true)
child:SetMovable(true)
child:SetClampedToScreen(true)
child:RegisterForDrag("LeftButton")
child:SetScript("OnDragStart", child.StartMoving)
child:SetScript("OnDragStop", child.StopMovingOrSizing)
child:SetBackdrop({
	bgFile="Interface\\Tooltips\\UI-Tooltip-Background", edgeFile="Interface\\Tooltips\\UI-Tooltip-Border",
	insets = {left = 4, right = 4, top = 4, bottom = 4}, tileSize = 16, edgeSize = 16, tile=true
})
child:SetBackdropColor(0, 0, 0, 1)
child:SetBackdropBorderColor(0, 0, 0, 1)

child.close = CreateFrame("button", child:GetName().."Close", child)
child.close:SetPoint("TOPRIGHT", -5, -5)
child.close:SetNormalFontObject(GameFontHighlightSmall)
child.close:SetHighlightFontObject(GameFontNormalSmall)
child.close:SetSize(15, 15)
child.close:SetText("X")

child.scroll:SetValueStep(1)
child.scroll:SetPoint("topleft", child, "topright", -FRAME_INSET_RIGHT, -(FRAME_INSET_TOP+FRAME_INSET_HEADER+20))
child.scroll:SetPoint("bottomright", child, "bottomright", -5, FRAME_INSET_BOTTOM+15)
child.scroll:SetAlpha(0.4)

-- 스크립트 등록
local function onmousewheel(self, arg1, arg2)
	if type(arg2) ~= "number" then
		arg2 = math.floor(LIST_NUMS/2)
	end
	arg1 = -arg1*arg2
	local x = self.index
	self.index = math.max(1, math.min(#addon.newwindowaddon-child.listnums+1, self.index+ arg1))
	if x ~= self.index then
		self:Refresh()
	end
end

child:SetScript("OnMouseWheel", onmousewheel)
child.scroll:SetScript("OnValueChanged", function(self, value)
	local value = math.floor(value)
	if child.index ~= value then
		child.index = value
		child:Refresh()
	end
end)

_G[child.scroll:GetName().."ScrollUpButton"]:SetScript("OnClick", function(self)   onmousewheel(child, 1, 1)  end)
_G[child.scroll:GetName().."ScrollDownButton"]:SetScript("OnClick", function(self) onmousewheel(child, -1, 1) end)
child.close:SetScript("OnClick", function(self) self:GetParent():Hide() end)

CreateHeaderButton("HeaderButtonName", "name", "이름", 150, "left", child.header)
CreateHeaderButton("HeaderButtonMem", "mem", "메모리", 70, "right", child.header)
CreateHeaderButton("HeaderButtonMems", "mems", "메모리변화", 70, "right", child.header)
CreateHeaderButton("HeaderButtonCPUT", "cput", "전체점유(ms)", 70, "right", child.header)
CreateHeaderButton("HeaderButtonCPUs", "cpus", "점유변화(ms)", 70, "right", child.header)
CreateHeaderButton("HeaderButtonCPUavr", "cpuavr", "점유평균(ms)", 70, "right", child.header)

for i = 0, child.listnums-1 do
	local btn = CreateFrame("button", child:GetName().."ListButton"..i, child)
	btn:SetSize(child.header.xPosition._total, LIST_HEIGHT)
	btn:SetPoint("TOPLEFT", child.header, "bottomleft", FRAME_INSET_LEFT, -i*LIST_HEIGHT)
	createListButtonText(btn, "name", child.header)
	createListButtonText(btn, "mem", child.header)
	createListButtonText(btn, "mems", child.header)
	createListButtonText(btn, "cpus", child.header)
	createListButtonText(btn, "cput", child.header)
	createListButtonText(btn, "cpuavr", child.header)
end
child:SetScript("OnShow", function(self) main:GetScript("OnShow")(self) self.index = 1 self:Refresh() end)
child:SetScript("OnHide", function(self) wipe(addon.newwindowaddon) self:Hide() end)

local function sortList_child(a, b) return sort_list(a, b, addon.child) end

function child:Refresh()
	local newwindow = addon.newwindowaddon
	local num = #newwindow
	local name = self:GetName()
	table.sort(newwindow, sortList_child)
	for i = 0, self.listnums-1 do
		local btn = _G[name.."ListButton"..i]
		local idx = i + self.index
		local value = newwindow[idx]
		if num < idx then
			btn:Hide()
		else
			btn:Show()
			btn.name:SetText(value.name)
			btn.mem:SetFormattedText(GetMemoryText(value.mem))
			btn.mems:SetFormattedText(GetMemorySText(value.mems))
			if value.cpus == 0 then
				btn.cpus:SetText("")
			else
				btn.cpus:SetFormattedText("%.2f", value.cpus)
			end
			btn.cput:SetFormattedText("%.1f", value.cput)
			btn.cpuavr:SetFormattedText("%.2f", value.cpuavr or 0)
		end
	end
	self.scroll:SetMinMaxValues(1, math.max(1, num-self.listnums+1))
	self.scroll:SetValue(self.index)
end

	
main:RegisterEvent("VARIABLES_LOADED")
main:SetScript("OnEvent", function(self, event, ...)
	AddonMemoryLastSelect = AddonMemoryLastSelect or {}
	addon.newwindowaddon = AddonMemoryLastSelect
	for i,v in ipairs(addon.newwindowaddon) do
		addon.newwindowaddon[i] = nil
	end
	addon.list = {}
	local check = {}
	for i = 1, GetNumAddOns() do
		local name = GetAddOnInfo(i)
		table.insert(addon.list, {idx = i, mem = 0, mems = 0, cput = 0, cpus = 0, name = name})
		check[name] = true
		if addon.newwindowaddon[name] then
			table.insert(addon.newwindowaddon, addon.list[#addon.list])
		end
	end
	for name, value in pairs(addon.newwindowaddon) do
		if value == true and not check[name] then
			addon.newwindowaddon[name] = nil
		end
	end
	if (next(addon.newwindowaddon)) then
		child:Show()
	end
end)