local addonName, addon = ...

addon:RegisterDefaultSetting("tooltipIconSize", 20)
addon:RegisterDefaultSetting("tooltipAnchor", false)
addon:RegisterDefaultSetting("showToT", true)
addon:RegisterDefaultSetting("showTitle", true)
addon:RegisterDefaultSetting("showRaidIcon", true)
addon:RegisterDefaultSetting("showHealthBar", true)
addon:RegisterDefaultSetting("growDirection", 1)
addon:RegisterDefaultSetting("showSpellIcon", true)
addon:RegisterDefaultSetting("showItemIcon", true)

local colors, CLASS = CUSTOM_CLASS_COLORS or RAID_CLASS_COLORS, addon.CLASS
local tooltips = {
	GameTooltip,
	ItemRefTooltip,
	ShoppingTooltip1,
	ShoppingTooltip2,
	ShoppingTooltip3,
	WorldMapTooltip,
	--FriendsTooltip,
	--BNToastFrame.tooltip
}

--[[-----------------------------------------------------------------------------
ToolTip Anchoring
-------------------------------------------------------------------------------]]
local GUITTAnchor = CreateFrame('button', "GUITTAnchor", UIParent)
GUITTAnchor:SetWidth(200)
GUITTAnchor:SetHeight(20)
GUITTAnchor:EnableMouse(true)
GUITTAnchor:RegisterForClicks("AnyUp")
GUITTAnchor:SetFrameStrata("BACKGROUND")

local TTAnchorbg = GUITTAnchor:CreateTexture(nil, "BACKGROUND")
TTAnchorbg:SetTexture(0, 0, 0, .7)
TTAnchorbg:SetAllPoints(GUITTAnchor)

local TTAnchorTxt = GUITTAnchor:CreateFontString(nil, "ARTWORK")
TTAnchorTxt:SetFont([[Fonts\FRIZQT__.TTF]], 12)
TTAnchorTxt:SetText("ToolTip Anchor")
TTAnchorTxt:SetPoint("CENTER", GUITTAnchor, "CENTER")
TTAnchorTxt:SetTextColor(1, 1, 1, 1)
GUITTAnchor:SetScript("OnClick", function(self, button)
	if button == "RightButton" then
		GUITTAnchor:Hide()
	end
end)

local function OnEnter(self)
	GameTooltip:SetOwner(self, 'ANCHOR_TOP', 0, 1)
	GameTooltip:AddLine("|cffeda55fCtrl+LeftClick|r to move.", 0.2, 1, 0.2)
	GameTooltip:AddLine("|cffeda55fRightClick|r to hide.", 0.2, 1, 0.2)
	GameTooltip:Show()
end

GUITTAnchor:SetScript('OnEnter', OnEnter)
GUITTAnchor:SetScript('OnLeave', addon.HideTooltip)

function addon:TTGrowDirection()
	for _, tooltip in ipairs({ GameTooltip, ItemRefTooltip, ShoppingTooltip1, ShoppingTooltip2, ShoppingTooltip3, WorldMapTooltip }) 
	do
		if addon.settings.growDirection == 1 then -- Up-Right
			tooltip:ClearAllPoints()
			tooltip:SetPoint('BOTTOMLEFT', GUITTAnchor, 'TOPLEFT')
		elseif addon.settings.growDirection == 2 then -- Up-Left
			tooltip:ClearAllPoints()
			tooltip:SetPoint('BOTTOMRIGHT', GUITTAnchor, 'TOPRIGHT')
		elseif addon.settings.growDirection == 3 then -- Down-Right
			tooltip:ClearAllPoints()
			tooltip:SetPoint('TOPLEFT', GUITTAnchor, 'BOTTOMLEFT')
		elseif addon.settings.growDirection == 4 then -- Down-Left
			tooltip:ClearAllPoints()
			tooltip:SetPoint('TOPRIGHT', GUITTAnchor, 'BOTTOMRIGHT')
		elseif addon.settings.growDirection == 5 then -- Cenetered-Right
			tooltip:ClearAllPoints()
			tooltip:SetPoint('LEFT', GUITTAnchor, 'LEFT')
		elseif addon.settings.growDirection == 6 then -- Centered-Left
			tooltip:ClearAllPoints()
			tooltip:SetPoint('RIGHT', GUITTAnchor, 'RIGHT')
		elseif addon.settings.growDirection == 7 then -- True Centered
			tooltip:ClearAllPoints()
			tooltip:SetPoint('CENTER', GUITTAnchor, 'CENTER')
		end
	end
end


function addon:GAnchorToolTip()
	hooksecurefunc('GameTooltip_SetDefaultAnchor', function (tooltip, parent)
		if addon.settings.tooltipAnchor == true then
			tooltip:SetOwner(parent, 'ANCHOR_CURSOR')
			tooltip:ClearAllPoints()
		else
			tooltip:SetOwner(parent, 'ANCHOR_NONE')
			tooltip:ClearAllPoints()
			addon:TTGrowDirection()
		end
	end)
end

function addon:GSetAnchorPoint()
	if not addon.settings.movedFrames.GUITTAnchor then
		GUITTAnchor:ClearAllPoints()
		GUITTAnchor:SetPoint('BOTTOMLEFT', UIParent, 'BOTTOMLEFT', 35, 450)
	end
end

function addon:ShowTTAnchor()
	if not GUITTAnchor:IsShown() then
		GUITTAnchor:Show()
	elseif GUITTAnchor:IsShown() then
		GUITTAnchor:Hide()
	end
end

addon.RegisterEvent("ToolTips-Initialize", 'PLAYER_ENTERING_WORLD', function(self, event)
	addon.UnregisterEvent(self, event)
	addon:GAnchorToolTip()
	addon:GSetAnchorPoint()
	GUITTAnchor:Hide()
end)

--[[-----------------------------------------------------------------------------
ToolTip Skinning
-------------------------------------------------------------------------------]]
local function SkinTooltip(tooltip)
	
	tooltip:SetBackdrop{
		bgFile = [[Interface\AddOns\]] .. addonName .. [[\Media\MainBG]],
		edgeFile = [[Interface\AddOns\]] .. addonName .. [[\Media\HordeBorder]], edgeSize = 15,
	}
	tooltip:SetBackdropColor(0.09, 0.09, 0.19, 1)
end

for _, tooltip in ipairs({ GameTooltip, ItemRefTooltip, ShoppingTooltip1, ShoppingTooltip2, ShoppingTooltip3, WorldMapTooltip }) do
	SkinTooltip(tooltip)
end

--[[-----------------------------------------------------------------------------
ToolTip BackGround Color
-------------------------------------------------------------------------------]]
function addon:SetTTBGcolor()
	if UnitIsFriend("player", "mouseover") then
		GameTooltip:SetBackdropBorderColor(0.57, 0.85, 0.57, 1)
	end
end

--[[-----------------------------------------------------------------------------
ToolTip Class Coloring and stuff...
-------------------------------------------------------------------------------]]
local hex
do 
    local format = string.format
    hex = function(color)
        return format('|cff%02x%02x%02x', color.r * 255, color.g * 255, color.b * 255)
    end
end

local classification = {
    elite = "+",
    rare = " R",
    rareelite = " R+",
}

local function unitColor(unit)
    local color = { r=1, g=1, b=1 }
    if UnitIsPlayer(unit) then
        local _, class = UnitClass(unit)
        color = RAID_CLASS_COLORS[class]
        return color
    else
        local reaction = UnitReaction(unit, "player")
        if reaction then
            color = FACTION_BAR_COLORS[reaction]
            return color
        end
    end
    return color
end

function GameTooltip_UnitColor(unit)
    local color = unitColor(unit)
    return color.r, color.g, color.b
end

local function getTarget(unit)
    if UnitIsUnit(unit, "player") then
        return ("|cffff0000%s|r"):format("YOU")
    else
        return hex(unitColor(unit))..UnitName(unit).."|r"
    end
end

--[[-----------------------------------------------------------------------------
Add Raid Icons to tooltips
-------------------------------------------------------------------------------]]
local lastricon = 1
function addon:AddRaidIcon(self)
	if addon.settings.showRaidIcon then
		local name, unit = self:GetUnit()
		if unit then
			local text = GameTooltipTextLeft1:GetText()
			if text then
				local ricon = GetRaidTargetIndex(unit)
				if ricon then
					if lastricon ~= 1 then
						text = text:gsub("\124T.*\124t ", "")
					end
					lastricon = ricon
					if not text:find(ricon) then
						GameTooltipTextLeft1:SetText(("|t%s:%s|t %s"):format(ICON_LIST[ricon], addon.settings.tooltipIconSize / 10, text))
					GameTooltip:Show()
					end
				end
				if not ricon or ricon == nil then
					if lastricon ~= 1 then 
						text = text:gsub("\124T.*\124t ", "")
						GameTooltipTextLeft1:SetText(("%s"):format(text))
						lastricon = 1
						GameTooltip:Show()
					end
				end
			end
		end
	end
end

--[[-----------------------------------------------------------------------------
ToolTip Status Bars
-------------------------------------------------------------------------------]]
GameTooltipStatusBar:SetStatusBarTexture("Interface\\AddOns\\GrimUI\\Media\\BarTexture.tga")
local bg = GameTooltipStatusBar:CreateTexture(nil, "BACKGROUND")
bg:SetAllPoints(GameTooltipStatusBar)
bg:SetTexture("Interface\\AddOns\\GrimUI\\Media\\BarTexture.tga")
bg:SetVertexColor(0.5, 0.5, 0.5, 0.5)

local numberize = function(val)
    if (val >= 1e6) then
        return ("%.1fm"):format(val / 1e6)
    elseif (val >= 1e3) then
        return ("%.1fk"):format(val / 1e3)
    else
        return ("%d"):format(val)
    end
end

GameTooltipStatusBar:SetScript("OnValueChanged", function(self, value)
    if not value then
        return
    end
    local min, max = self:GetMinMaxValues()
    if (value < min) or (value > max) then
        return
    end
    local _, unit = GameTooltip:GetUnit()
    if unit then
        min, max = UnitHealth(unit), UnitHealthMax(unit)
        if not self.text then
            self.text = self:CreateFontString(nil, "OVERLAY")
            self.text:SetPoint("CENTER", GameTooltipStatusBar)
            self.text:SetFont("Interface\\AddOns\\GrimUI\\Media\\Font3.ttf", 10, "OUTLINE")
        end
        self.text:Show()
        local hp = numberize(min).." / "..numberize(max)
        self.text:SetText(hp)
    end
end)

function addon:ShowTTHealthBar(self)
	local name, unit = self:GetUnit()
	if addon.settings.showHealthBar then
		addon:ShowFrame("GameTooltipStatusBar")
		GameTooltipStatusBar:SetStatusBarColor(0, 0.9, 0)
		if GameTooltipStatusBar:IsShown() then
			self:AddLine(" ")
			GameTooltipStatusBar:ClearAllPoints()
			GameTooltipStatusBar:SetPoint("TOPLEFT", self:GetName().."TextLeft"..self:NumLines(), "TOPLEFT", 0, -4)
			GameTooltipStatusBar:SetPoint("TOPRIGHT", self, -10, 0)
		end
	else
		addon:HideFrame("GameTooltipStatusBar")
	end
	if UnitIsDeadOrGhost(unit) then
		if GameTooltipStatusBar:IsShown() then
			GameTooltipStatusBar:Hide()
            self:AddLine("|cffFF0000"..DEAD.."|r")
		end
	end
end

--[[-----------------------------------------------------------------------------
ToolTip Item Quality Border coloring
-------------------------------------------------------------------------------]]
function addon:ItemQualityBorder()
	for i=1, #tooltips do
        if not tooltips[i]["GetItem"] then return end
        local item = select(2, tooltips[i]:GetItem());
        if item then
            local quality = select(3, GetItemInfo(item));
            if quality then
                local r, g, b = GetItemQualityColor(quality);
                tooltips[i]:SetBackdropBorderColor(r, g, b);
            end
        end
    end
end

--[[-----------------------------------------------------------------------------
ToolTip Target of Target
-------------------------------------------------------------------------------]]
local targetting = ""
local TARGET_PREFIX = TARGET..":|cffffffff ";

function addon:AddTargetToTT(self)
	local name, unit = self:GetUnit()
	local unexists = UnitExists('mouseovertarget')
	if (unexists ~= 1) then return end 
	if not unit then return end
		--look for the existing line that starts with TARGET
	local targetLine
	local useExisting = false
	local text = GameTooltipTextLeft1:GetText()
	if text then
		local i = GameTooltip:NumLines()
			targetLine = _G["GameTooltipTextLeft"..i];
			if (targetLine:GetText():find(TARGET)) then
					--if we find it, we'll use it later instead of adding a new line
				useExisting = true
			end
	end

	targetting = UnitName("mouseovertarget")
	if unexists then
		--modify if they are targetting you
		if targetting == UnitName("player") then
			targetting = "<YOU>"
		end
		if (targetting ~= nil and targetting ~= "") then 
			--either use the existing line and set it's text, or add the new line of text
			if useExisting then
				targetLine:SetText(string.format("%s %s |r", TARGET_PREFIX, getTarget("mouseovertarget") ) )
			else
				GameTooltip:AddLine( string.format("%s %s |r", TARGET_PREFIX, getTarget("mouseovertarget") ) )
			end	
			GameTooltip:Show()
		end
	end
end

--[[-----------------------------------------------------------------------------
Add Spell and Item icons to tooltips
-------------------------------------------------------------------------------]] 
local function AddIcon(self, icon)
	if icon then
		local title = _G[self:GetName() .. 'TextLeft1']
		local text = title:GetText()
		if text and not text:find('|T' .. icon) then
			title:SetFormattedText("|T%s:%s|t %s", icon, addon.settings.tooltipIconSize, text)
		end
	end
end

local function OnTooltipSetItem(self)
	if addon.settings.showItemIcon then
		local _, link = self:GetItem()
		if link then
			AddIcon(self, GetItemIcon(link))
		end
	end
end

local function OnTooltipSetSpell(self)
	if addon.settings.showSpellIcon then
		if self:GetSpell() then
			local _, _, icon = GetSpellInfo(self:GetSpell())
			if icon then
				AddIcon(self, icon)
			end
		end
	end
end
--[[-----------------------------------------------------------------------------
Tooltip Show/Hide Player Titles
-------------------------------------------------------------------------------]]
function addon:ShowPlayerTitles(self)
	local name, unit = self:GetUnit()
	
	local title = UnitPVPName(unit) --returns name + selected title 
	if addon.settings.showTitle then
		local text = GameTooltipTextLeft1:GetText()
		if text then 
			GameTooltipTextLeft1:SetText(text) 
		end
	else
		local text = GameTooltipTextLeft1:GetText()
			title = title:gsub(name, "")
			text = text:gsub(title, "")
			GameTooltipTextLeft1:SetText(text) 
	end
end

--[[-----------------------------------------------------------------------------
Tooltip script hooks
-------------------------------------------------------------------------------]]
--OnTooltipSetUnit hook
GameTooltip:HookScript("OnTooltipSetUnit", function(self)
    local name, unit = self:GetUnit()
	if unit then
        addon:AddRaidIcon(self)
		local color = unitColor(unit)
        if UnitIsPlayer(unit) then
            self:AppendText((" |cff00cc00%s|r"):format(UnitIsAFK(unit) and CHAT_FLAG_AFK or UnitIsDND(unit) and CHAT_FLAG_DND or not UnitIsConnected(unit) and "<DC>" or ""))
			
			addon:ShowPlayerTitles(self)

            local unitGuild = GetGuildInfo(unit)
            local text2 = GameTooltipTextLeft2:GetText()
            if unitGuild and text2 and text2:find("^"..unitGuild) then	
                GameTooltipTextLeft2:SetTextColor(1, 0.1, 0.8)
            end
        end

        local level = UnitLevel(unit)
        if level then
            local unitClass = UnitIsPlayer(unit) and hex(color)..UnitClass(unit).."|r" or ""
            local creature = not UnitIsPlayer(unit) and UnitCreatureType(unit) or ""
            local diff = GetQuestDifficultyColor(level)

            if level == -1 then
                level = "|cffff0000??"
            end

            local classify = UnitClassification(unit)
            local textLevel = ("%s%s%s|r"):format(hex(diff), tostring(level), classification[classify] or "")

            for i=2, self:NumLines() do
                local tiptext = _G["GameTooltipTextLeft"..i]
                if tiptext:GetText():find(LEVEL) then
                    tiptext:SetText(("%s %s%s %s"):format(textLevel, creature, UnitRace(unit) or "", unitClass):trim())
                end

                if tiptext:GetText():find(PVP) then
                    tiptext:SetText(nil)
                end
            end
        end
		addon:ShowTTHealthBar(self)
	end
end)
--OnLoadHook
hooksecurefunc('GameTooltip_OnLoad', function()
	for _, tooltip in ipairs({ GameTooltip, ItemRefTooltip, ShoppingTooltip1, ShoppingTooltip2, ShoppingTooltip3, WorldMapTooltip }) do
		SkinTooltip(tooltip)
	end
end)

--OnUpdateHook
GameTooltip:HookScript("OnUpdate", function(self, ...)
	if addon.settings.showToT == true then
		addon:AddTargetToTT(self)
	end
	addon:SetTTBGcolor()
	addon:AddRaidIcon(self)
end)

--add icons to tooltips
_G['GameTooltip']:HookScript('OnTooltipSetItem', function(self)
	OnTooltipSetItem(self)
	addon:ItemQualityBorder()
end)

_G['ItemRefTooltip']:HookScript('OnTooltipSetItem', function(self)
	OnTooltipSetItem(self)
	addon:ItemQualityBorder()
end)

hooksecurefunc('GameTooltip_ShowCompareItem', function()
	for _, tooltip in ipairs({ ItemRefTooltip, ShoppingTooltip1, ShoppingTooltip2, ShoppingTooltip3}) do
		addon:ItemQualityBorder()
	end
end)

_G['GameTooltip']:HookScript('OnTooltipSetSpell', OnTooltipSetSpell)
_G['ItemRefTooltip']:HookScript('OnTooltipSetSpell', OnTooltipSetSpell)

