local TOOLTIP_SCALE = 1.0		-- 툴팁 크기: 0 ~ 1.0 까지 숫자 ex) 0.95
local TOOLTIP_ESC_HIDE = true		-- ESC키로 툴팁 닫기: (예) true (아니오) false
local TOOLTIP_SHOW_ID = false		-- 아이템 ID를 제외한 아이디값 보기
local TOOLTIP_SHOW_ICON = true		-- 툴팁 아이콘 포시
local TOOLTIP_SCREENSHOT_MODE = false

local BlueItemLink = CreateFrame("Frame")
BlueItemLink:SetScript("OnEvent", function(self, event, ...) self[event](self, ...) end)

local _G = _G
local unpack = _G.unpack
local select = _G.select
local gsub = _G.gsub
local format = _G.format
local strmatch = _G.strmatch
local strfind = _G.strfind
local tonumber = _G.tonumber
local GetTime = _G.GetTime
local IsModifiedClick = _G.IsModifiedClick
local IsAltKeyDown = _G.IsAltKeyDown
local IsControlKeyDown = _G.IsControlKeyDown
local IsShiftKeyDown = _G.IsShiftKeyDown
local CreateFrame = _G.CreateFrame
local GetItemIcon = _G.GetItemIcon
local GetScreenWidth = _G.GetScreenWidth
local GetItemInfo = _G.GetItemInfo
local GetSpellLink = _G.GetSpellLink
local GetSpellInfo = _G.GetSpellInfo
local DressUpItemLink = _G.DressUpItemLink
local check, ref, index, item1, item2, side, linkID, linkID2, addID, fs, ws, px, py, icon
local addMethod = TOOLTIP_SHOW_ID and { "GetEnchantID", "GetSpellID", "GetQuestID", "GetAchievementID", "GetTalentID" } or {}

local enchantLink = "|cffffd000|H%s|h[%s]|h|r"
local questLink = "|cff808080|H%s|h[%s]|h|r"
local talentLink = "|cff4e96f7|H%s|h[%s]|h|r"
local achievementLink = "|cffffff00|H%s|h[%s]|h|r"

function BlueItemLink:OnInit()
	self.ref = {}
	self.linked = {}
	ItemRefTooltip.Show = ItemRefTooltip.Hide
	ItemRefTooltip.SetHyperlink = self.SetRefLink
	ItemRefTooltip.SetTrainerService = self.SetTrainerService
end

function BlueItemLink:SetRefLink(link)
	if not link then return end
	ref = nil
	for i = 1, #BlueItemLink.ref do
		if BlueItemLink.ref[i]:IsVisible() then
			if BlueItemLink.ref[i].HyperLink == link then
				BlueItemLink.ref[i].forceUpdate = nil
				BlueItemLink.ref[i]:Hide()
				return
			end
		elseif not ref then
			ref = BlueItemLink.ref[i]
		end
	end
	if not ref then
		index = #BlueItemLink.ref + 1
		ref = CreateFrame("GameTooltip", "BlueItemLink"..index, UIParent, "GameTooltipTemplate")
		if index == 1 then
			BlueItemLinkDB = (BlueItemLinkDB == nil or (BlueItemLinkDB and BlueItemLinkDB.profiles)) and {} or BlueItemLinkDB
			BlueItemLink.Hook_SetHyperlink = ref.SetHyperlink
		end
		ref:SetScale(TOOLTIP_SCALE)
		ref:SetPadding(16)
		ref:SetID(index)
		if TOOLTIP_SCREENSHOT_MODE then
			TOOLTIP_SHOW_ICON = false
			if index == 1 then
				ref:SetPoint("TOPLEFT", UIParent, "TOPLEFT", 10, -10)
			elseif index == 2 then
				ref:SetPoint("TOPRIGHT", UIParent, "TOPLEFT", 566, -10)
			elseif mod(index, 2) == 1 then
				ref:SetPoint("TOPLEFT", BlueItemLink.ref[index - 2], "BOTTOMLEFT", 0, -1)
			else
				ref:SetPoint("TOPRIGHT", BlueItemLink.ref[index - 2], "BOTTOMRIGHT", 0, -1)
			end
		else
			if BlueItemLinkDB[index] then
				fs = ref:GetEffectiveScale()
				ref:SetPoint("TOPLEFT", UIParent, "TOPLEFT", BlueItemLinkDB[index][1] / fs, BlueItemLinkDB[index][2] / fs)
			else
				ref:SetPoint("CENTER", UIParent, "CENTER")
			end
		end
		ref:EnableMouse(true)
		ref:SetMovable(true)
		ref:RegisterForDrag("LeftButton")
		ref:SetFrameStrata("HIGH")
		ref:SetFrameLevel(GameTooltip:GetFrameLevel() + index * 2)
		ref:SetWidth(128)
		ref:SetHeight(64)
		ref.closeButton = CreateFrame("Button", nil, ref)
		ref.closeButton:SetWidth(32)
		ref.closeButton:SetHeight(32)
		ref.closeButton:SetPoint("TOPRIGHT", ref, "TOPRIGHT", 1, 1)
		ref.closeButton:SetScript("OnClick", BlueItemLink.CloseButtonOnClick)
		ref.closeButton:SetNormalTexture("Interface\\Buttons\\UI-Panel-MinimizeButton-Up")
		ref.closeButton:SetPushedTexture("Interface\\Buttons\\UI-Panel-MinimizeButton-Down")
		ref.closeButton:SetHighlightTexture("Interface\\Buttons\\UI-Panel-MinimizeButton-Highlight", "ADD")
		ref.icon = ref:CreateTexture(nil, "OVERLAY")
		ref.icon:SetWidth(40)
		ref.icon:SetHeight(40)
		ref.icon:SetPoint("TOPRIGHT", ref, "TOPLEFT", 1, -3)
		ref:SetScript("OnDragStart", BlueItemLink.OnDragStart)
		ref:SetScript("OnDragStop", BlueItemLink.OnDragStop)
		ref:SetScript("OnTooltipSetItem", BlueItemLink.OnTooltipSetItem)
		ref:SetScript("OnTooltipSetSpell", BlueItemLink.OnTooltipSetSpell)
		ref:SetScript("OnHide", BlueItemLink.OnHide)
		ref:SetScript("OnUpdate", BlueItemLink.OnUpdate)
		ref:SetScript("OnEnter", BlueItemLink.OnEnter)
		ref:SetScript("OnLeave", BlueItemLink.OnLeave)
		ref:SetScript("OnMouseDown", BlueItemLink.OnClick)
		ref.SetHyperlink = BlueItemLink.SetHyperlink
		ref.firstText = _G["BlueItemLink"..index.."TextLeft1"]
		GameTooltip_OnLoad(ref)
		BlueItemLink.ref[index] = ref
		if TOOLTIP_ESC_HIDE then
			tinsert(UISpecialFrames, "BlueItemLink"..index)
		end
		if TOOLTIP_SHOW_ID then
			for _, v in pairs(addMethod) do
				if BlueItemLink[v] then
					ref[v] = BlueItemLink[v]
				end
			end
		end
	end
	ref.forceUpdate = nil
	ref:SetHyperlink(link)
end

function BlueItemLink:SetHyperlink(link)
	self.icon:SetTexture()
	self.HyperLink = link
	self:SetOwner(UIParent, "ANCHOR_PRESERVE")
	GameTooltip.SetHyperlink(self, link)
	if TOOLTIP_SHOW_ID then
		addID = self:GetEnchantID() or self:GetQuestID() or self:GetSpellID() or self:GetAchievementID() or self:GetTalentID() or nil
		if addID then
			self:AddLine(addID)
		end
	end
	self:Show()
end

function BlueItemLink:OnTooltipSetItem(...)
	if self.HyperLink and not BlueItemLink.linked[self.HyperLink] then
		BlueItemLink.linked[self.HyperLink] = true
		self.updateTimer = GetTime() + 1.5
	end
	if TOOLTIP_SHOW_ICON then
		self.icon:SetTexture(GetItemIcon(self.HyperLink))
	end
	GameTooltip:GetScript("OnTooltipSetItem")(self, ...)
end

function BlueItemLink:OnTooltipSetSpell(...)
	if TOOLTIP_SHOW_ICON and self.HyperLink and strmatch(self.HyperLink, "spell:(%d+)") then
		icon = select(3, GetSpellInfo(strmatch(self.HyperLink, "spell:(%d+)")))
		if icon== nil or icon== "" or icon== "Interface\\Icons\\Temp" then
			icon= "Interface\\Icons\\Spell_Holy_GreaterHeal"
		end
		self.icon:SetTexture(icon)
	end
end

function BlueItemLink:OnUpdate()
	if self.HyperLink then
		if not self.isMoving and self.updateTimer and self.updateTimer < GetTime() then
			self.updateTimer = nil
			self.forceUpdate = true
			self:SetHyperlink(self.HyperLink)
		end
		if self:GetItem() and not ChatFrameEditBox:IsVisible() then
			if self.isEnter and not self.isCompare and IsModifiedClick("COMPAREITEMS") then
				self.isCompare = true
				BlueItemLink:SetCompareItem(self)
			elseif self.isCompare and (not IsModifiedClick("COMPAREITEMS") or not self.isEnter) then
				self.isCompare = nil
				ShoppingTooltip1:Hide()
				ShoppingTooltip2:Hide()
			end
		end
	end
end

function BlueItemLink:GetItemID(link)
	linkID = strmatch(link, "item:(%d+)")
	if linkID then
		return tonumber(linkID)
	end
	linkID = strmatch(link, "enchant:(%d+)")
	if linkID then
		return -tonumber(linkID)
	end
	return nil
end

function BlueItemLink:OnClick()
	if self.HyperLink and not self.isMoving then
		if BlueItemInfo2 and IsAltKeyDown() and BlueItemLink:GetItemID(self.HyperLink) then
			BlueItemInfo2:AddFavoriteItem(BlueItemLink:GetItemID(self.HyperLink))
		elseif BlueItemInfo2 and IsControlKeyDown() and IsShiftKeyDown() and BlueItemLink:GetItemID(self.HyperLink) then
			BlueItemInfo2:AddMemo(BlueItemLink:GetItemID(self.HyperLink))
		elseif IsModifiedClick("CHATLINK") then
			if self:GetItem() and AuctionFrame and AuctionFrame:IsVisible() and BrowseName:IsVisible() then
				BrowseName:SetText(self:GetItem().."")
			elseif self:GetItem() then
				ChatFrameEditBox:Show()
				ChatFrameEditBox:Insert(select(2, self:GetItem()))
			elseif strfind(self.HyperLink, "enchant:(%d+)") then
				ChatFrameEditBox:Show()
				ChatFrameEditBox:Insert(format(enchantLink, self.HyperLink, gsub(self.firstText:GetText(), "마법부여: ", "")))
			elseif strfind(self.HyperLink, "quest:(%d+)") then
				ChatFrameEditBox:Show()
				ChatFrameEditBox:Insert(format(questLink, self.HyperLink, self.firstText:GetText()))
			elseif strfind(self.HyperLink, "spell:(%d+)") then
				ChatFrameEditBox:Show()
				ChatFrameEditBox:Insert(GetSpellLink(strmatch(self.HyperLink, "spell:(%d+)")))
			elseif strfind(self.HyperLink, "talent:(%d+)") then
				ChatFrameEditBox:Show()
				ChatFrameEditBox:Insert(format(talentLink, self.HyperLink, self.firstText:GetText()))
			elseif strfind(self.HyperLink, "achievement:(%d+)") then
				ChatFrameEditBox:Show()
				ChatFrameEditBox:Insert(format(achievementLink, self.HyperLink, self.firstText:GetText()))
			else
				ChatFrameEditBox:Show()
				ChatFrameEditBox:Insert(self.HyperLink)
			end
		elseif IsModifiedClick("DRESSUP") and (strfind(self.HyperLink, "item:") or strfind(self.HyperLink, "enchant:")) then
			DressUpItemLink(self.HyperLink)
		end
	end
end

function BlueItemLink:OnEnter()
	self.isEnter = true
end

function BlueItemLink:OnLeave()
	self.isEnter = nil
end

function BlueItemLink:CloseButtonOnClick()
	self.forceUpdate = nil
	self:GetParent():Hide()
end

function BlueItemLink:OnDragStart()
	self.isMoving = true
	self:StartMoving()
end

function BlueItemLink:OnDragStop()
	self.isMoving = nil
	self:StopMovingOrSizing()
	fs, ws = self:GetEffectiveScale(), UIParent:GetEffectiveScale()
	BlueItemLinkDB[self:GetID()] = { self:GetLeft() * fs, self:GetTop() * fs - UIParent:GetTop() * ws }

end

function BlueItemLink:OnHide()
	if not self.forceUpdate then
		self.HyperLink = nil
	end
	self.isCompare = nil
	self.isEnter = nil
	self.isMoving = nil
	self.updateTimer = nil
end

function BlueItemLink:SetCompareItem(tooltip)
	if tooltip.HyperLink == nil then return end
	item1, item2 = nil
	if ( ShoppingTooltip1:SetHyperlinkCompareItem(tooltip.HyperLink, 1) ) then
		item1 = true
	end
	if ( ShoppingTooltip2:SetHyperlinkCompareItem(tooltip.HyperLink, 2) ) then
		item2 = true
	end
	side = ((GetScreenWidth() - tooltip:GetRight()) < tooltip:GetLeft()) and 1 or 2
	if item1 then
		ShoppingTooltip1:SetOwner(tooltip, "ANCHOR_NONE")
		ShoppingTooltip1:ClearAllPoints()
		if side == 1 then
			ShoppingTooltip1:SetPoint("TOPRIGHT", tooltip, "TOPLEFT", 0, -45)
		else
			ShoppingTooltip1:SetPoint("TOPLEFT", tooltip, "TOPRIGHT", 0, -10)
		end
		ShoppingTooltip1:SetHyperlinkCompareItem(tooltip.HyperLink, 1)
		ShoppingTooltip1:Show()
		if item2 then
			ShoppingTooltip2:SetOwner(ShoppingTooltip1, "ANCHOR_NONE")
			ShoppingTooltip2:ClearAllPoints()
			if side == 1 then
				ShoppingTooltip2:SetPoint("TOPRIGHT", "ShoppingTooltip1", "TOPLEFT", 0, 0)
			else
				ShoppingTooltip2:SetPoint("TOPLEFT", "ShoppingTooltip1", "TOPRIGHT", 0, 0)
			end
			ShoppingTooltip2:SetHyperlinkCompareItem(tooltip.HyperLink, 2)
			ShoppingTooltip2:Show()
		end
	end
end

if TOOLTIP_SHOW_ID then
	function BlueItemLink:GetEnchantID()
		linkID = strmatch(self.HyperLink or "*", "enchant:(%d+)")
		return linkID and ("조제법ID: "..linkID) or nil
	end

	function BlueItemLink:GetQuestID()
		linkID = strmatch(self.HyperLink or "*", "quest:(%d+)")
		return linkID and ("퀘스트ID: "..linkID) or nil
	end

	function BlueItemLink:GetSpellID()
		linkID = strmatch(self.HyperLink or "*", "spell:(%d+)")
		return linkID and ("주문ID: "..linkID) or nil
	end

	function BlueItemLink:GetAchievementID()
		linkID = strmatch(self.HyperLink or "*", "achievement:(%d+)")
		return linkID and ("업적ID: "..linkID) or nil
	end

	function BlueItemLink:GetTalentID()
		linkID, linkID2 = strmatch(self.HyperLink or "*", "talent:(%d+):(%d+)") or strmatch(self.HyperLink or "*", "talent:(%d+)")
		return linkID and ("특성ID: "..linkID..(linkID2 and (":"..linkID2) or "")) or nil
	end
end

BlueItemLink:OnInit()