local _G = _G
local tinsert = _G.table.insert

local tooltipIndex = 0
local frames = {}

local percent = "%.2f%%"

local function getNumShown()
	local count = 0
	for _, t in pairs(frames) do
		if t:IsShown() then
			count = count + 1
		end
	end
	return count
end

local function getValue(str)
	str = (str:GetText() or ""):trim()
	if str:find("(%d+)/(%d+)/(%d+)") then
		return 0
	elseif str:find("(%d+) %- (%d+)") then
		local v1, v2 = str:match("(%d+) %- (%d+)")
		return (tonumber(v1 or 0) + tonumber(v2 or 0)) / 2
	elseif str:find("(%d+)%.(%d+)%%") then
		local v1, v2 = str:match("(%d+)%.(%d+)%%")
		return tonumber(v1 or 0) + tonumber(v2 or 0) / 100
	else
		return tonumber(str) or 0
	end
end

local function linkOnEnter(self)
	for name, value in pairs(self.lineData) do
		value = getValue(value)
		for c, t in pairs(frames) do
			if t:IsShown() and t:GetID() ~= self:GetID() and t.lineData[name] then
				c = getValue(t.lineData[name])
				if value > c then
					t.lineData[name]:SetTextColor(1, 0.45, 0.45)
				elseif value < c then
					t.lineData[name]:SetTextColor(0, 1, 0)
				end
			end
		end
	end
end

local function linkOnLeave(self)
	for _, t in pairs(frames) do
		if t:IsShown() and t:GetID() ~= self:GetID() then
			for _, right in pairs(t.lineData) do
				right:SetTextColor(1, 1, 1)
			end
		end
	end
end

local function linkOnHide(self)
	self:ClearLines()
	self.linkIndex = nil
	self.lineIndex = 0
	for p in pairs(self.lineData) do
		self.lineData[p] = nil
	end
end

local function addline(tooltip, text1, text2, isWrap)
	tooltip.lineIndex = tooltip.lineIndex + 1
	if text2 then
		tooltip:AddDoubleLine(text1, text2, NORMAL_FONT_COLOR.r, NORMAL_FONT_COLOR.g, NORMAL_FONT_COLOR.b, 1, 1, 1, isWrap)
		tooltip.linkIndex = tooltip.linkIndex.."/"..text2
		tooltip.lineData[text1] = _G[tooltip:GetName().."TextRight"..tooltip.lineIndex]
	elseif text1 then
		tooltip:AddLine(text1, NORMAL_FONT_COLOR.r, NORMAL_FONT_COLOR.g, NORMAL_FONT_COLOR.b, isWrap)
	else
		tooltip:AddLine("  ")
	end
end

local function getLink()
	for _, f in pairs(frames) do
		if not f:IsShown() then
			return f
		end
	end
	tooltipIndex = tooltipIndex + 1
	local f = CreateFrame("GameTooltip", "InvenSimulatorUIStatLink"..tooltipIndex, UIParent, "GameTooltipTemplate")
	_G[f:GetName().."TextLeft1"]:SetFontObject("GameTooltipText")
	_G[f:GetName().."TextRight1"]:SetFontObject("GameTooltipText")
	GameTooltip_OnLoad(f)
	f:SetScale(0.9)
	f:SetID(tooltipIndex)
	f:SetPoint("CENTER", UIParent, "CENTER")
	f:SetFrameStrata("HIGH")
	f:SetToplevel(true)
	f:EnableMouse(true)
	f:SetMovable(true)
	f:SetPadding(16)
	f:RegisterForDrag("LeftButton")
	f:SetScript("OnDragStart", f.StartMoving)
	f:SetScript("OnDragStop", f.StopMovingOrSizing)
	f:SetScript("OnEnter", linkOnEnter)
	f:SetScript("OnLeave", linkOnLeave)
	f:SetScript("OnHide", linkOnHide)
	f:SetScript("OnTooltipSetDefaultAnchor", nil)
	f:SetScript("OnTooltipAddMoney", nil)
	f:SetScript("OnTooltipCleared", nil)
	f.closeButton = CreateFrame("Button", nil, f, "UIPanelCloseButton")
	f.closeButton:SetPoint("TOPRIGHT", 1, 0)
	f.Add = addline
	f.lineIndex = 0
	f.lineData = {}
	tinsert(UISpecialFrames, f:GetName())
	tinsert(frames, f)
	InvenSimulatorUI.frames[f] = true
	return f
end

local function addMeleeStat(self, f)
	f:Add()
	f:Add("주장비 공격력", ("%d - %d"):format(self.specTable["주장비 최소 공격력"], self.specTable["주장비 최대 공격력"]))
	f:Add("주장비 공격 속도", ("%.2f"):format(self.specTable["주장비 공격 속도"]))
	f:Add("주장비 초당 공격력", self.tooltipTable["공격력"][7])
	f:Add("주장비 숙련",  percent:format((self.specTable["숙련"] or 0) / 4))
	f:Add()
	if self.specTable["무기2 최소 공격력"] then
		f:Add("보조장비 공격력", ("%d - %d"):format(self.specTable["보조장비 최소 공격력"], self.specTable["보조장비 최대 공격력"]))
		f:Add("보조장비 공격 속도", ("%.2f"):format(self.specTable["보조장비 공격 속도"]))
		f:Add("보조장비 초당 공격력", self.tooltipTable["공격력"][15])
		f:Add("주장비 숙련",  percent:format((self.specTable["숙련2"] or self.specTable["숙련"] or 0) / 4))
		f:Add()
	end
	f:Add("근접 전투력", self.specTable["전투력"] or 0)
	f:Add("근접 치명타율", percent:format(self.specTable["치명타율"] or 0))
	local v1 = self.tooltipTable["적중도"][2]
	local _, v2, v3, _, _, _, _, v4, v5 = v1:match("(.+) (%d+)%.(%d+)%%(.+)\n(.+) (%d+) %((.+) (%d+)%.(%d+)%%")
	v2 = (v2 and v3) and (tonumber(v2) + tonumber(v3) / 100) or 0
	v3 = (v4 and v5) and (tonumber(v4) + tonumber(v5) / 100) or 0
	f:Add("근접 적중률", percent:format(v2))
	f:Add("근접 가속율", self.tooltipTable["속도"][2]:gsub("(.+)%+(%d+)%.(%d+)%%%)$", "%2.%3%%"), nil)
	f:Add("근접 방어구 관통률", percent:format(v3))
end

local function addRangedStat(self, f)
	if self.specTable["무기3 최소 공격력"] then
		f:Add()
		f:Add("원거리 장비 공격력", ("%d - %d"):format(self.specTable["원거리 장비 최소 공격력"], self.specTable["원거리 장비 최대 공격력"]))
		f:Add("원거리 장비 공격 속도", ("%.2f"):format(self.specTable["원거리 장비 공격 속도"]))
		f:Add("원거리 장비 초당 공격력", self.tooltipTable["원거리 공격력"][7])
		f:Add()
		f:Add("원거리 전투력", self.specTable["원거리 전투력"] or 0)
		f:Add("원거리 치명타율", percent:format(self.specTable["원거리 치명타율"] or 0))
		local v1, v2, _, v3, v4 = self.tooltipTable["원거리 적중도"][2]:match(" (%d+)%.(%d+)%%(.+) (%d+)%.(%d+)%%")
		f:Add("원거리 적중률", percent:format(tonumber(v1 or 0) + tonumber(v2 or 0) / 100))
		v1, v2 = self.tooltipTable["원거리 속도"][2]:match("(%d+)%.(%d+)%%")
		f:Add("원거리 가속율", percent:format(tonumber(v1 or 0) + tonumber(v2 or 0) / 100))
		f:Add("원거리 방어구 관통률", percent:format(tonumber(v3 or 0) + tonumber(v4 or 0) / 100))
	end
end

local function addSpellStat(self, f)
	f:Add()
	f:Add("주문 공격력", self.specTable["주문 공격력"] or 0)
	f:Add("주문 치유량", self.specTable["주문 치유량"] or 0)
	f:Add("주문 극대화율", percent:format(self.specTable["극대화율"] or 0))
	local v1, v2 = self.tooltipTable["주문 적중도"][2]:match("(%d+)%.(%d+)%%")
	f:Add("주문 적중률", percent:format(tonumber(v1 or 0) + tonumber(v2 or 0) / 100))
	v1, v2 = self.tooltipTable["주문 가속도"][2]:match("(%d+)%.(%d+)%%")
	f:Add("주문 시전 가속률", percent:format(tonumber(v1 or 0) + tonumber(v2 or 0) / 100))
	f:Add("주문 관통력", self.specTable["주문 관통력"] or 0)
	v1, _, v2 = self.tooltipTable["5초당 마나 회복량"][2]:match("5초마다 (%d+)(.+)5초마다 (%d+)")
	f:Add("비 시전 중 마나 회복량", v1 or 0)
	f:Add("시전 중 마나 회복량", v2 or 0)
end

local function addDefStat(self, f)
	f:Add()
	f:Add("방어도", self.specTable["방어도"] or 0)
	f:Add("방어 숙련", self.specTable["방어 숙련"] or 0)
	f:Add("탄력도", self.specTable["탄력도"] or 0)
	f:Add("회피율",  percent:format(self.specTable["회피율"] or 0))
	if self.specTable["무기 막기"] and self.specTable["무기 막기"] > 0 then
		f:Add("무기 막기율", percent:format(self.specTable["무기 막기"]))
	end
	if self.specTable["방패 막기"] and self.specTable["방패 막기"] > 0 then
		f:Add("방패 막기율", percent:format(self.specTable["방패 막기"]))
		f:Add("방패 피해 방어량", self.specTable["방패 피해 방어량"] or 0)
	end
end

function InvenSimulatorUI:ShowStatLink()
	if not self:IsShown() then return end
	local f = getLink()
	f.linkIndex = ""
	f:SetOwner(UIParent, "ANCHOR_PRESERVE")
	f:Add("|cffffffff인벤 시뮬레이터: 비교 툴팁"..f:GetID().."|r")
	f:Add("특성", ("%d/%d/%d"):format(InvenSimulatorTalentFrame:GetSpentPoints(1), InvenSimulatorTalentFrame:GetSpentPoints(2), InvenSimulatorTalentFrame:GetSpentPoints(3)), nil)
	f:Add("최대 생명력", self.specTable["생명력"] or 0)
	if self.hasMana then
		f:Add("최대 마나", self.specTable["마나"] or 0)
	end
	f:Add()
	f:Add("힘", self.specTable["힘"] or 0)
	f:Add("민첩성", self.specTable["민첩성"] or 0)
	f:Add("체력", self.specTable["체력"] or 0)
	f:Add("지능", self.specTable["지능"] or 0)
	f:Add("정신력", self.specTable["정신력"] or 0)
	if self.class == "전사" or self.class == "도적" or self.class == "죽음의 기사" then
		addMeleeStat(self, f)
		addRangedStat(self, f)
	elseif self.class == "사냥꾼" then
		addRangedStat(self, f)
		addMeleeStat(self, f)
	elseif self.class == "사제" or self.class == "마법사" or self.class == "흑마법사" then
		addSpellStat(self, f)
		addRangedStat(self, f)
	else
		addMeleeStat(self, f)
		addSpellStat(self, f)
	end
	addDefStat(self, f)
	for _, t in pairs(frames) do
		if t:IsShown() and f:GetID() ~= t:GetID() and f.linkIndex == t.linkIndex then
			return f:Hide()
		end
	end
	f:Show()
end