local addonName, addon = ...

local colors, CLASS = CUSTOM_CLASS_COLORS or RAID_CLASS_COLORS, addon.CLASS

local GrimTargetFrame = CreateFrame("Frame", addonName .. "TargetFrame", UIParent, "SecureUnitButtonTemplate")

--[[-----------------------------------------------------------------------------
Configure Bliz Target Frame
-------------------------------------------------------------------------------]]
function addon:ConfigureBlizTargetFrame()
	if addon.settings.hideBlizTargetFrame then
		addon:HideFrame('TargetFrame')
	else
		TargetFrame.Show = TargetFrame:Show()
		TargetFrame:RegisterEvent("PLAYER_TARGET_CHANGED")
		TargetFrame:RegisterEvent("UNIT_HEALTH")
		TargetFrame:RegisterEvent("UNIT_LEVEL")
		TargetFrame:RegisterEvent("UNIT_FACTION")
		TargetFrame:RegisterEvent("UNIT_CLASSIFICATION_CHANGED")
		TargetFrame:RegisterEvent("UNIT_AURA")
		TargetFrame:RegisterEvent("PLAYER_FLAGS_CHANGED")
		TargetFrame:RegisterEvent("PLAYER_FOCUS_CHANGED")
	
		if UnitExists("target") then TargetFrame:Show() end
		TargetFrame.UnregisterEvent = addon.DoNothing
	end
end

addon.RegisterEvent("TargetFrame-Initialize", 'PLAYER_ENTERING_WORLD', function(self, event)
	addon.UnregisterEvent(self, event)

	addon:ConfigureBlizTargetFrame()
end)

--[[-----------------------------------------------------------------------------
Target Unit DropDown Menu Function
-------------------------------------------------------------------------------]]
local showmenu = function() 
	ToggleDropDownMenu(1, nil, TargetFrameDropDown, "cursor", 0, 0) 
end

--[[-----------------------------------------------------------------------------
Target Name Coloring get functions
-------------------------------------------------------------------------------]]
local function getTarget(unit)
    if UnitIsUnit(unit, "player") then
        return ("|cffff0000%s|r"):format("YOU")
    else
        return GCHex(addon:unitColor(unit))..UnitName(unit).."|r"
    end
end

local function getTargetNoU(unit)
	return GCHex(addon:unitColor(unit))..UnitName(unit).."|r"
end

--[[-----------------------------------------------------------------------------
Main Target Frame Setup
-------------------------------------------------------------------------------]]
GrimTargetFrame:SetFrameStrata("BACKGROUND") 
GrimTargetFrame:SetFrameLevel(4) 
GrimTargetFrame:SetWidth(230) 
GrimTargetFrame:SetHeight(180) 
GrimTargetFrame:SetPoint("BOTTOM", UIParent, "BOTTOM", 0, 138)
GrimTargetFrame:RegisterEvent("PLAYER_ENTERING_WORLD")
GrimTargetFrame:RegisterEvent("PLAYER_TARGET_CHANGED")
GrimTargetFrame:RegisterEvent("PARTY_MEMBERS_CHANGED")
GrimTargetFrame:SetAttribute('unit', 'target')
RegisterUnitWatch(GrimTargetFrame)

--[[-----------------------------------------------------------------------------
3D Model Frame
-------------------------------------------------------------------------------]]
local targetModelFrame = CreateFrame('PlayerModel', "targetModelFrame", GrimTargetFrame)
targetModelFrame:RegisterEvent("PLAYER_ENTERING_WORLD")
targetModelFrame:RegisterEvent("PLAYER_ALIVE")
targetModelFrame:RegisterEvent("UNIT_MODEL_CHANGED", "target")
targetModelFrame:RegisterEvent("PLAYER_LEAVE_COMBAT")
targetModelFrame:RegisterEvent("PLAYER_REGEN_ENABLED")
targetModelFrame:RegisterEvent("PLAYER_TARGET_CHANGED")
targetModelFrame:RegisterEvent("UNIT_PORTRAIT_UPDATE", "target")
targetModelFrame:SetHeight(170)
targetModelFrame:SetWidth(145)
targetModelFrame:SetPoint("CENTER", GrimTargetFrame, "CENTER", 0, -15)
targetModelFrame:SetFrameStrata("HIGH")

targetModelFrame:SetScript("OnEvent", function(self)
    if "PLAYER_TARGET_CHANGED" then 
	self:ClearModel()
	end
	targetModelFrame:SetUnit("target")
    self:RefreshUnit()
end)

local targetModelClickFrame = CreateFrame('Button', "targetModelClickFrame", GrimTargetFrame, "SecureUnitButtonTemplate")
targetModelClickFrame:SetAllPoints("targetModelFrame")
targetModelClickFrame:SetFrameStrata("HIGH")
targetModelClickFrame:SetFrameLevel("6")
targetModelClickFrame:RegisterForClicks("AnyUp")
targetModelClickFrame:SetAttribute("unit", "target")
targetModelClickFrame:SetAttribute("*type1", "target")
targetModelClickFrame.menu = showmenu
targetModelClickFrame.unit = "target"
targetModelClickFrame:SetAttribute("*type2", "menu")
targetModelClickFrame:SetScript("OnEnter", UnitFrame_OnEnter)
targetModelClickFrame:SetScript("OnLeave", UnitFrame_OnLeave)

--[[-----------------------------------------------------------------------------
Targeting Sounds
-------------------------------------------------------------------------------]]
local GrimTargetSounds = CreateFrame("Frame", nil, UIParent)
GrimTargetSounds:RegisterEvent("PLAYER_TARGET_CHANGED")

GrimTargetSounds:SetScript("OnEvent", function(self)
	local unitexists = UnitExists("target")
	
	if unitexists == 1 then
		PlaySound("igCreatureNeutralSelect");
	elseif unitexists == nil then
		PlaySound("INTERFACESOUND_LOSTTARGETUNIT");
	end
end)

local eliteRareEvent = CreateFrame("Frame", nil, UIParent)
eliteRareEvent:RegisterEvent("PLAYER_TARGET_CHANGED")
eliteRareEvent:RegisterEvent("UNIT_CLASSIFICATION_CHANGED")
eliteRareEvent:RegisterEvent("UNIT_DYNAMIC_FLAGS")

local eliteRareFrame = CreateFrame("Frame", "eliteRareFrame", nil)
eliteRareFrame.textureL = eliteRareFrame:CreateTexture(left)
eliteRareFrame.textureL:SetPoint("BOTTOMLEFT", GrimTargetFrame, "TOPLEFT", 9, -26)
eliteRareFrame.textureL:SetHeight(32)
eliteRareFrame.textureL:SetWidth(30)
eliteRareFrame.textureR = eliteRareFrame:CreateTexture(right)
eliteRareFrame.textureR:SetPoint("BOTTOMRIGHT", GrimTargetFrame, "TOPRIGHT", -9, -26)
eliteRareFrame.textureR:SetHeight(32)
eliteRareFrame.textureR:SetWidth(30)
eliteRareFrame:SetFrameStrata("HIGH") 
eliteRareFrame:SetFrameLevel(5) 

eliteRareEvent:SetScript("OnEvent", function(self) 

	local classification = UnitClassification("target")
	
	if classification == "elite" or classification == "worldboss" then
		eliteRareFrame.textureR:SetTexture([[Interface\AddOns\]] .. addonName .. [[\Media\Elite]])
		eliteRareFrame.textureR:SetTexCoord(1, 0, 0, 1)
		eliteRareFrame.textureL:SetTexture([[Interface\AddOns\]] .. addonName .. [[\Media\Elite]])
	elseif classification == "rare" then
		eliteRareFrame.textureR:SetTexture([[Interface\AddOns\]] .. addonName .. [[\Media\Rare]])
		eliteRareFrame.textureR:SetTexCoord(1, 0, 0, 1)
		eliteRareFrame.textureL:SetTexture([[Interface\AddOns\]] .. addonName .. [[\Media\Rare]])
	elseif classification == "rareelite" then
		eliteRareFrame.textureR:SetTexture([[Interface\AddOns\]] .. addonName .. [[\Media\Rare]])
		eliteRareFrame.textureR:SetTexCoord(1, 0, 0, 1)
		eliteRareFrame.textureL:SetTexture([[Interface\AddOns\]] .. addonName .. [[\Media\Elite]])
	elseif classification == "worldboss" then
		eliteRareFrame.textureR:SetTexture([[Interface\AddOns\]] .. addonName .. [[\Media\Elite]])
		eliteRareFrame.textureR:SetTexCoord(1, 0, 0, 1)
		eliteRareFrame.textureL:SetTexture([[Interface\AddOns\]] .. addonName .. [[\Media\Elite]])
	else
		eliteRareFrame.textureR:SetTexture(nil)
		eliteRareFrame.textureL:SetTexture(nil)
	end
end)

-- PVP Icon Start
local targPvpIconEvent = CreateFrame("Frame", nil, UIParent)
targPvpIconEvent:RegisterEvent("ADDON_LOADED")
targPvpIconEvent:RegisterEvent("UNIT_FACTION") 
targPvpIconEvent:RegisterEvent("PLAYER_TARGET_CHANGED")

targPvpIconFrame = CreateFrame("Frame", "TargPvpIconFrame", GrimTargetFrame)
targPvpIconFrame:SetPoint("TOPRIGHT", GrimTargetFrame, "TOPRIGHT", -40, -24)
targPvpIconFrame:SetHeight(33)
targPvpIconFrame:SetWidth(33)
targPvpIconFrame.texture = targPvpIconFrame:CreateTexture()
targPvpIconFrame.texture:SetAllPoints(targPvpIconFrame)
targPvpIconFrame:SetFrameLevel(8)
targPvpIconFrame:SetFrameStrata("MEDIUM")
targPvpIconEvent:SetScript("OnEvent", function(self) 
    
    local englishFaction, localizedFaction = UnitFactionGroup("target")
    if englishFaction == "Alliance" then    
		targPvpIconFrame.texture:SetTexture("Interface\\GroupFrame\\UI-Group-PVP-Alliance.blp")
    elseif englishFaction == "Horde" then
		targPvpIconFrame.texture:SetTexture("Interface\\GroupFrame\\UI-Group-PVP-Horde.blp")
    end
    
    local ispvp = UnitIsPVP("target")
   
    if ispvp == 1 then
		targPvpIconFrame:Show()
    else
		targPvpIconFrame:Hide()
    end
end)

-- Raid target icon start
local targRaidIconFrame = CreateFrame("Frame", "targRaidIconFrame", GrimTargetFrame)
targRaidIconFrame:RegisterEvent("PLAYER_ENTERING_WORLD")
targRaidIconFrame:RegisterEvent("RAID_TARGET_UPDATE") 
targRaidIconFrame:RegisterEvent("PLAYER_TARGET_CHANGED")
targRaidIconFrame:SetPoint("TOPRIGHT", GrimTargetFrame, "TOPRIGHT", -45, -54)
targRaidIconFrame:SetHeight(33)
targRaidIconFrame:SetWidth(33)
targRaidIconFrame:SetFrameStrata("HIGH")
targRaidIconFrame:SetFrameLevel(9)

-- Raid target icon function
function addon:TargetRaidIconUpdate(self)
	TargetFrameTextureFrameRaidTargetIcon:SetParent(GrimTargetFrame)
	TargetFrameTextureFrameRaidTargetIcon:SetAllPoints(targRaidIconFrame)
	TargetFrameTextureFrameRaidTargetIcon:SetDrawLayer("OVERLAY")
	
end

targRaidIconFrame:SetScript("OnEvent", function(self) 
    addon:TargetRaidIconUpdate(self)
end)

-- health bar start
local TargetHealthEvents = CreateFrame("Frame", nil, UIParent)
TargetHealthEvents:RegisterEvent("PLAYER_ENTERING_WORLD")
TargetHealthEvents:RegisterEvent("UNIT_HEALTH", "target")
TargetHealthEvents:RegisterEvent("UNIT_AURA", "target")
TargetHealthEvents:RegisterEvent("UNIT_MAXHEALTH", "target")
TargetHealthEvents:RegisterEvent("PLAYER_TARGET_CHANGED")


local GUI_TargetHealth = CreateFrame('Button', "GUI_TargetHealth", GrimTargetFrame, "SecureActionButtonTemplate")
GUI_TargetHealth:SetHeight(110)
GUI_TargetHealth:SetWidth(36)
GUI_TargetHealth:SetPoint("TOPLEFT", GrimTargetFrame, "TOPLEFT", -2, -34)

GUI_TargetHealth:SetBackdrop{ 
		bgFile = nil, 
		edgeFile = [[Interface\DialogFrame\UI-DialogBox-Border]], tile = false, tileSize = 0, edgeSize = 5, 
		insets = { left = 0, right = 0, top = 0, bottom = 0 } 
	}

GUI_TargetHealth:SetBackdropBorderColor(0, 0, 0, 1)
GUI_TargetHealth:SetFrameStrata("BACKGROUND")
GUI_TargetHealth:SetFrameLevel("3")
GUI_TargetHealth:RegisterForClicks("AnyUp")
GUI_TargetHealth:SetAttribute("unit", "target")
GUI_TargetHealth:SetAttribute("*type1", "target")


GUI_TargetHealth.menu = showmenu
GUI_TargetHealth.unit = "target"
GUI_TargetHealth:SetAttribute("*type2", "menu")
GUI_TargetHealth:SetScript("OnEnter", UnitFrame_OnEnter)
GUI_TargetHealth:SetScript("OnLeave", UnitFrame_OnLeave)

local healthBar = CreateFrame("StatusBar", nil, GUI_TargetHealth, "TextStatusBar")
healthBar:SetWidth(34)
healthBar:SetHeight(109)
healthBar:SetPoint("CENTER", GUI_TargetHealth, "CENTER", 0, 0)
healthBar:SetStatusBarTexture([[Interface\AddOns\]] .. addonName .. [[\Media\VBarTexture]])

healthBar:SetOrientation("VERTICAL")
healthBar:SetFrameStrata("BACKGROUND")
healthBar:SetFrameLevel("2")

local percentHText = GUI_TargetHealth:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
percentHText:SetPoint("TOP", GUI_TargetHealth, "TOP", 0, -1)
percentHText:SetTextColor(1, 1, 1, 1)
percentHText:SetFont([[Interface\AddOns\]] .. addonName .. [[\Media\Font1.ttf]], 11)

-- Mana Bar Start
local TargetManaEvents = CreateFrame("Frame", nil, UIParent)
TargetManaEvents:RegisterEvent("PLAYER_ENTERING_WORLD")
TargetManaEvents:RegisterEvent("UNIT_HEALTH")
TargetManaEvents:RegisterEvent("PLAYER_LEVEL_UP")
TargetManaEvents:RegisterEvent("UNIT_MANA")
TargetManaEvents:RegisterEvent("UNIT_AURA")
TargetManaEvents:RegisterEvent("UNIT_DISPLAYPOWER")
TargetManaEvents:RegisterEvent("UNIT_ENERGY")
TargetManaEvents:RegisterEvent("UNIT_MAXENERGY")
TargetManaEvents:RegisterEvent("UNIT_MAXMANA")
TargetManaEvents:RegisterEvent("UNIT_MAXRUNICPOWER")
TargetManaEvents:RegisterEvent("UNIT_RUNIC_POWER")
TargetManaEvents:RegisterEvent("UNIT_RAGE")
TargetManaEvents:RegisterEvent("UPDATE_SHAPESHIFT_FORM")
TargetManaEvents:RegisterEvent("PLAYER_TARGET_CHANGED")

local GUI_TargetMana = CreateFrame('Button', "GUI_TargetMana", GrimTargetFrame, "SecureActionButtonTemplate")
GUI_TargetMana:SetHeight(110)
GUI_TargetMana:SetWidth(36)
GUI_TargetMana:SetPoint("TOPRIGHT", GrimTargetFrame, "TOPRIGHT", 2, -34)

GUI_TargetMana:SetBackdrop{ 
		bgFile = nil, 
		edgeFile = "Interface/DialogFrame/UI-DialogBox-Border", tile = false, tileSize = 0, edgeSize = 5, 
		insets = { left = 0, right = 0, top = 0, bottom = 0 } 
	} 
GUI_TargetMana:SetBackdropBorderColor(0, 0, 0, 1)

GUI_TargetMana:SetFrameStrata("BACKGROUND")
GUI_TargetMana:SetFrameLevel("3")

GUI_TargetMana:RegisterForClicks("AnyUp")
GUI_TargetMana:SetAttribute("unit", "target")
GUI_TargetMana:SetAttribute("*type1", "target")

GUI_TargetMana.menu = showmenu
GUI_TargetMana.unit = "target"
GUI_TargetMana:SetAttribute("*type2", "menu")
GUI_TargetMana:SetScript("OnEnter", UnitFrame_OnEnter)
GUI_TargetMana:SetScript("OnLeave", UnitFrame_OnLeave)

local manaBar = CreateFrame("StatusBar", nil, GUI_TargetMana, "TextStatusBar")
manaBar:SetWidth(34)
manaBar:SetHeight(109)
manaBar:SetPoint("CENTER", GUI_TargetMana, "CENTER", 0, 0)
manaBar:SetStatusBarTexture([[Interface\AddOns\]] .. addonName .. [[\Media\VBarTexture]])
manaBar:SetOrientation("VERTICAL")
manaBar:SetFrameStrata("BACKGROUND")
manaBar:SetFrameLevel("2")

local percentMText = GUI_TargetHealth:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
percentMText:SetPoint("TOP", GUI_TargetMana, "TOP", 0, -1)
percentMText:SetTextColor(1, 1, 1, 1)
percentMText:SetFont([[Interface\AddOns\]] .. addonName .. [[\Media\Font1.ttf]], 11)

-- Health/Mana text display frame
local healthManaTxtDisplay = CreateFrame("frame", nil, GrimTargetFrame)
healthManaTxtDisplay:SetWidth(125)
healthManaTxtDisplay:SetHeight(50)
healthManaTxtDisplay:SetPoint("CENTER", GrimTargetFrame, "CENTER", 0, 60)
healthManaTxtDisplay:SetFrameStrata("HIGH")
healthManaTxtDisplay:SetFrameLevel("5")
healthManaTxtDisplay:RegisterEvent("PLAYER_TARGET_CHANGED")

local healthText = healthManaTxtDisplay:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
healthText:SetPoint("TOP", healthManaTxtDisplay, "TOP", 0, -8)
healthText:SetTextColor(1, 1, 1, 1)
healthText:SetFont([[Interface\AddOns\]] .. addonName .. [[\Media\Font1.ttf]], 12, "OUTLINE")

local manaText = healthManaTxtDisplay:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
manaText:SetPoint("TOP", healthText, "BOTTOM", 0, 0)
manaText:SetTextColor(1, 1, 1, 1)
manaText:SetFont([[Interface\AddOns\]] .. addonName .. [[\Media\Font1.ttf]], 11, "OUTLINE")

local targetLvlText = healthManaTxtDisplay:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
targetLvlText:SetPoint("BOTTOMRIGHT", healthManaTxtDisplay, "TOPLEFT", 2, -13)
targetLvlText:SetTextColor(1, 1, 1, 1)
targetLvlText:SetFont([[Interface\AddOns\]] .. addonName .. [[\Media\Font1.ttf]], 13, "OUTLINE")

TargetHealthEvents:SetScript("OnEvent", function(self) 
    local currHealth, maxHealth = UnitHealth("Target"), UnitHealthMax("Target") 
    local percentHealth = floor(currHealth / maxHealth * 100)
	
    local str = ("%s/%s"):format(currHealth, maxHealth)
    local perstr = ("%s%%"):format(percentHealth)   
    
	healthText:SetText(str) 
    healthBar:SetMinMaxValues(min(0, currHealth), maxHealth) 
    healthBar:SetValue(currHealth) 
	percentHText:SetText(perstr)
	local istap = UnitIsTapped("target")
	local ismytap = UnitIsTappedByPlayer("target")
	local alltap = UnitIsTappedByAllThreatList("target")
	
	if alltap then
		healthBar:SetStatusBarColor(.231, .682, .419, 1)
	else
		if istap and not ismytap then
			healthBar:SetStatusBarColor(.556, .556, .556, 1);
		else
			healthBar:SetStatusBarColor(.231, .682, .419, 1)
		end
	end
end)

TargetManaEvents:SetScript("OnEvent", function(self) 
    local currMana, maxMana = UnitMana("target"), UnitManaMax("target") 
    local powerType = UnitPowerType("target")
    local currPower = UnitPower("target")
    local maxPower = UnitPowerMax("target")
    local currShape = GetShapeshiftForm()
    local percentMana = floor(currMana / maxMana * 100)
	
    if maxMana >= 1 then
		local perMstr = ("%s%%"):format(percentMana)
		percentMText:SetText(perMstr)
	end
	
	if maxMana == 0 then
		local perMstr = ("0%")
		percentMText:SetText(perMstr)
	end
	
	if powerType == 0 then
        local manaSTR = ("%s/%s"):format(currMana, maxMana)
        manaText:SetText(manaSTR) 
        manaBar:SetMinMaxValues(min(0, currMana), maxMana) 
        manaBar:SetValue(currMana) 
        manaBar:SetStatusBarColor(.556, .556, .921, 1)
	elseif powerType == 1 or 3 or 6 then
		local manaSTR = ("%s/%s"):format(currPower, maxPower)
        manaText:SetText(manaSTR) 
        manaBar:SetMinMaxValues(min(0, currPower), maxPower) 
        manaBar:SetValue(currPower) 
        manaBar:SetStatusBarColor(.656, .456, .456, 1)
    end
end)

local BossTexture = CreateFrame("frame", BossTexture, nil )	

BossTexture.texture = BossTexture:CreateTexture(BossTexture)
BossTexture.texture:SetPoint("TOPLEFT", GrimTargetFrame, "TOPLEFT", 19, 0)
BossTexture.texture:SetHeight(12)
BossTexture.texture:SetWidth(13)
BossTexture:SetFrameStrata("HIGH")
BossTexture:SetFrameLevel("9")
local targetClassText = healthManaTxtDisplay:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
targetClassText:SetPoint("BOTTOM", healthText, "TOP", 0, 0)
targetClassText:SetPoint("RIGHT", healthManaTxtDisplay, "RIGHT", -6, 0)

targetClassText:SetTextColor(1, 1, 1, 1)
targetClassText:SetFont([[Interface\AddOns\]] .. addonName .. [[\Media\Font1.ttf]], 12, "OUTLINE")

local targetRaceText = healthManaTxtDisplay:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
targetRaceText:SetPoint("BOTTOM", healthText, "TOP", 0, 0)

targetRaceText:SetPoint("LEFT", healthManaTxtDisplay, "LEFT", 6, 0)
targetRaceText:SetTextColor(1, 1, 1, 1)
targetRaceText:SetFont([[Interface\AddOns\]] .. addonName .. [[\Media\Font1.ttf]], 12, "OUTLINE")


healthManaTxtDisplay:SetScript("OnEvent", function(self) 
	
	local targetlvl = UnitLevel("target")
	local targclass = UnitClass("target")
	local targetrace = UnitRace("target")
	local targetname = UnitName("target")
	local unitexists = UnitExists("target")
	local targetCfamily = UnitCreatureFamily("target") -- Returns the type of creature of the specified unit (e.g., "Crab"). 
	local targetCtype = UnitCreatureType("target") -- Returns the classification type of creature of the specified unit (e.g., "Beast"). 

	if targetrace and unitexists == 1 then
		local targRaceStr = ("%s"):format(targetrace)
		targetRaceText:SetText(targRaceStr)
		targetClassText:SetPoint("LEFT", targetRaceText, "RIGHT", 0, 0)
	elseif targetCtype then
		local targRaceStr = ("%s"):format(targetCtype)
		targetRaceText:SetText(targRaceStr)
		targetClassText:SetPoint("LEFT", targetRaceText, "RIGHT", 0, 0)
	else
		targetRaceText:SetText("")
	end
	
	if targclass and targclass ~= targetname then
		local color = colors[CLASS[targclass]]
		local targClasStr = ("%s"):format(targclass)
		targetClassText:SetText(targClasStr)
		targetClassText:SetTextColor(color.r, color.g, color.b)
	elseif targetCfamily then
		local targClasStr = ("%s"):format(targetCfamily)
		targetClassText:SetText(targClasStr)
		targetClassText:SetTextColor(100, 100, 100)
	else
		targetClassText:SetText("")
	end
	
	
	if targetlvl >= 0 then
		local color = addon:unitColor("target")
		local unitClass = UnitIsPlayer('target') and GCHex(color)..UnitClass('target').."|r" or ""
		local diff = GetQuestDifficultyColor(targetlvl)
		local targetlvltxt = ("%s%s|r"):format(GCHex(diff), tostring(targetlvl))
		local targLvlStr = ("%s"):format(targetlvltxt)
		targetLvlText:SetText(targLvlStr)
		BossTexture.texture:SetTexture(nil)
	elseif targetlvl == -1 then
		targetLvlText:SetText("")
		BossTexture.texture:SetTexture("Interface\\TargetingFrame\\UI-TargetingFrame-Skull.blp")
	end
end)

--[[######################  
Target Name / Guild Frame START 
########################]] 
local targetNameGuildFrame = CreateFrame("frame", nil, GrimTargetFrame)
targetNameGuildFrame:SetWidth(226)
targetNameGuildFrame:SetHeight(12)
targetNameGuildFrame:SetPoint("BOTTOM", GrimTargetFrame, "BOTTOM", 0, 16)
targetNameGuildFrame:SetFrameStrata("HIGH")
targetNameGuildFrame:SetFrameLevel("5")
targetNameGuildFrame:RegisterEvent("PLAYER_TARGET_CHANGED")

local targetNameText = targetNameGuildFrame:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
targetNameText:SetFont([[Interface\AddOns\]] .. addonName .. [[\Media\Font3.ttf]], 14, "OUTLINE")

targetNameText:SetPoint("TOP", targetNameGuildFrame, "TOP", 0, 1)


local targetGuildText = targetNameGuildFrame:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
targetGuildText:SetFont([[Interface\AddOns\]] .. addonName .. [[\Media\Font3.ttf]], 10, "OUTLINE")

targetGuildText:SetPoint("TOP", targetNameGuildFrame, "TOP", 0, -2)
targetGuildText:SetPoint("RIGHT", targetNameGuildFrame, "RIGHT", 0, 0)

targetNameGuildFrame:SetScript("OnEvent", function(self) 
    local targetName = UnitName("target")
    local targetGuildName = GetGuildInfo("target")
	local unitexists = UnitExists("target")
	local targclass = UnitClass("target")

	if targetName then
		if targetGuildName then
			local namegstr = ("%s"):format(getTargetNoU('target'))
			targetNameText:SetText(namegstr)
			local guildstr = ("- %s"):format(targetGuildName)
			targetGuildText:SetText(guildstr)
			
			local Ntex = targetNameText:GetStringWidth()
			local Gtex = targetGuildText:GetStringWidth()
			local mathdone = ((Gtex / 3) - (Ntex / 3))
			
			targetNameText:SetJustifyH("RIGHT")
			targetNameText:SetPoint("RIGHT", targetNameGuildFrame, "CENTER", -mathdone, 0)
			targetNameText:SetPoint("LEFT", targetNameGuildFrame, "LEFT", -mathdone, 0)
			targetGuildText:SetPoint("LEFT", targetNameText, "RIGHT", 0, 0)
			targetGuildText:SetJustifyH("LEFT")
		else
			local namegstr = ("%s"):format(getTargetNoU('target'))
			targetNameText:SetText(namegstr)
			targetGuildText:SetText("")
			targetNameText:SetJustifyH("CENTER")
			targetNameText:SetPoint("RIGHT", targetNameGuildFrame, "RIGHT", 0, 0)
			targetNameText:SetPoint("LEFT", targetNameGuildFrame, "LEFT", 0, 0)
		end
	end
end)
  
--[[######################  
	       Target targettarget Frame START 
########################]] 

local targetOfTargetFrame = CreateFrame("frame", nil, GrimTargetFrame)
targetOfTargetFrame:SetWidth(226)
targetOfTargetFrame:SetHeight(12)
targetOfTargetFrame:SetPoint("BOTTOM", GrimTargetFrame, "BOTTOM", 0, 3)
targetOfTargetFrame:SetFrameStrata("HIGH")
targetOfTargetFrame:SetFrameLevel("5")
targetOfTargetFrame:RegisterEvent("PLAYER_TARGET_CHANGED")
targetOfTargetFrame:RegisterEvent("UNIT_TARGET", "target")

local targetOfTargetClickFrame = CreateFrame("button", "GUI_TargetOfTarget", targetOfTargetFrame, "SecureUnitButtonTemplate")
targetOfTargetClickFrame:SetAllPoints(targetOfTargetFrame)
targetOfTargetClickFrame:SetFrameStrata("HIGH")
targetOfTargetClickFrame:SetFrameLevel("9")
targetOfTargetClickFrame:RegisterForClicks("AnyUp")
targetOfTargetClickFrame:SetAttribute("unit", "targettarget")
targetOfTargetClickFrame:SetAttribute("*type1", "target")

local showttmenu = function() 
	ToggleDropDownMenu(1, nil, TargetFrameDropDown, "cursor", 0, 0) 
end
targetOfTargetClickFrame.menu = showttmenu
targetOfTargetClickFrame.unit = "targettarget"
targetOfTargetClickFrame:SetAttribute("*type2", "menu")
targetOfTargetClickFrame:SetScript("OnEnter", UnitFrame_OnEnter)
targetOfTargetClickFrame:SetScript("OnLeave", UnitFrame_OnLeave)

local targetOfTargetText = targetOfTargetFrame:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
targetOfTargetText:SetPoint("TOP", targetOfTargetFrame, "TOP", 0, 0)
targetOfTargetText:SetPoint("LEFT", targetOfTargetFrame, "LEFT", 0, 0)
targetOfTargetText:SetPoint("RIGHT", targetOfTargetFrame, "RIGHT", 0, 0)
targetOfTargetText:SetTextColor(1, 1, 1, 1)
targetOfTargetText:SetFont([[Interface\AddOns\]] .. addonName .. [[\Media\Font3.ttf]], 12, "OUTLINE")

targetOfTargetFrame:SetScript("OnEvent", function(self) 
    local targetTargetName = UnitName("targettarget")
    local targetExists = UnitExists("targettarget")
	local targetMe = UnitName("player")
	
	if  targetExists == 1 and targetTargetName == targetMe then
		targetOfTargetText:SetText("Targeting - "..getTarget('targettarget'))
		
	end
	if  targetExists == 1 and targetTargetName ~= targetMe then
		local nametstr = ("Targeting - %s"):format(getTarget('targettarget'))
		targetOfTargetText:SetText(nametstr)
		
	end
	if targetExists == nil then
	targetOfTargetText:SetText("-No Target-")
	end
    
end)

--[[-----------------------------------------------------------------------------
Target Frame Buttons
-------------------------------------------------------------------------------]]
-- Let's create only one tooltip-function for all buttons  
-- and get the text and anchor from their variables (see below)  
local function button_OnEnter(self) 
	GameTooltip:SetOwner(self, self.Anchor) 
	GameTooltip:AddLine(self.TipText) 
	GameTooltip:Show() 
end 

local function button_OnLeave(self) 
	GameTooltip:Hide() 
end 

-- Same procedure as above, commonly used settings in a function  
-- we need a name which is also used for the backdrop file name  
-- and anchor and tooltipText (you remember, the tooltip above!)  
local function createTargetButton(name, anchor, tooltipText) 
	local button = CreateFrame("Button", "GrimUIcore"..name.."Button", GrimTargetFrame) 
	button:SetFrameStrata("HIGH") 
	button:Hide() 
	button:SetWidth(15) 
	button:SetHeight(15) 
	button.Anchor = anchor -- Lets store the anchor-variable in the button  
	button.TipText = tooltipText -- and the tooltipText, too  
	button:SetNormalTexture([[Interface\AddOns\]] .. addonName .. [[\Media\]] .. name .. "Icon") 
	button:SetHighlightTexture([[Interface\AddOns\]] .. addonName .. [[\Media\]] .. name .. "Icon")
	-- Assign our tooltip-functions from above  
	button:SetScript("OnEnter", button_OnEnter) 
	button:SetScript("OnLeave", button_OnLeave) 
	button:SetNormalFontObject(GameFontNormal)
	button:SetHighlightFontObject(GameFontHighlight) 
	button:SetDisabledFontObject(GameFontDisable) 
	button:SetFrameStrata("HIGH")
	button:SetFrameLevel(20)
	button:RegisterForClicks('AnyUp')
	return button 
end 

-- inspect 
local Ginspect = createTargetButton("GInspect", "ANCHOR_LEFT", "Inspect") 
Ginspect:SetPoint("CENTER", -63, 46) 
Ginspect:SetScript("OnClick", function(self) 
		if InspectFrame then
			if InspectFrame:IsShown() then
				InspectFrame:Hide()
			else
				LoadAddOn("Blizzard_InspectUI")
				InspectFrame_Show('target')
			end
		else
			LoadAddOn("Blizzard_InspectUI")
			InspectFrame_Show('target')
		end
end) 

-- whisper  
local whisper = createTargetButton("Whisper", "ANCHOR_LEFT", "Whisper") 
whisper:SetPoint("TOP", Ginspect, "BOTTOM", 0, -4) 
whisper:SetScript("OnClick", function(self) 
	local name, realm = UnitName("target") 
	if realm then 
		ChatFrame_SendTell(name.."-"..realm) 
	else 
		ChatFrame_SendTell(name) 
	end 
end) 

-- follow  
local follow = createTargetButton("Follow", "ANCHOR_LEFT", "Follow") 
follow:SetPoint("TOP", whisper, "BOTTOM", 0, -4) 
follow:SetScript("OnClick", function(self) 
		FollowUnit("target") 
end) 

-- trade  
local trade = createTargetButton("Trade", "ANCHOR_LEFT", "Trade") 
trade:SetPoint("TOP", follow, "BOTTOM", 0, -5) 
trade:SetScript("OnClick", function(self) 
	InitiateTrade("target") 
end)

-- invite
local invite = createTargetButton("Invite", "ANCHOR_RIGHT", "Invite") 
invite:SetPoint("CENTER", -43, 39) 
invite:SetScript("OnClick", function(self) 
	local name = UnitName("target") 
	InviteUnit(name) 
end)

-- gtip
local gtip = createTargetButton("Notes", "ANCHOR_RIGHT", "Add Note") 
gtip:SetWidth(14) 
gtip:SetHeight(14) 
gtip:SetPoint("TOPRIGHT", -35, -7) 
gtip:SetScript("OnClick", function(self, button) 
	if button == 'LeftButton' then
		addon:GTipNotesRun()
	end
	if button == 'RightButton' then
		addon:GTipNotesPrint()
	end
end) 

GrimTargetFrame:SetScript("OnEvent", function(self, event) 
    
	local isPlayer = UnitIsPlayer("target") 
	local canInspect = CanInspect("target", false)

		if isPlayer and UnitIsFriend("target","player") and not UnitIsUnit("target", "player") then 
			trade:Show() 
			follow:Show() 
			whisper:Show() 
			if not UnitInParty("target") then 
				invite:Show() 
			else 
				invite:Hide() 
			end 
		else 
			trade:Hide() 
			follow:Hide() 
			whisper:Hide() 
			invite:Hide() 
		end 
		if(UnitExists("target")) then
			gtip:Show()
		else
			gtip:Hide()
		end
	if isPlayer then 
		Ginspect:Show() 
	else 
		Ginspect:Hide() 
	end
	
	if event == "PLAYER_TARGET_CHANGED" then
		if InspectFrame then
			InspectFrame:Hide()
		end
	end
end)

--[[-----------------------------------------------------------------------------
Target Frame Buffs/DeBuffs
-------------------------------------------------------------------------------]]
local TargetBuffMainFrame = CreateFrame('Frame', "TargetBuffMainFrame", GrimTargetFrame)
TargetBuffMainFrame:SetHeight(105)
TargetBuffMainFrame:SetWidth(410)
TargetBuffMainFrame:SetPoint("BOTTOM", GrimTargetFrame, "TOP", 0, 7)
TargetBuffMainFrame:RegisterEvent("UNIT_AURA", "target")
TargetBuffMainFrame:RegisterEvent("PLAYER_TARGET_CHANGED")

local TargetIBuffedFrame = CreateFrame('Frame', "TargetIBuffedFrame", GrimTargetFrame)
TargetIBuffedFrame:SetHeight(40)
TargetIBuffedFrame:SetWidth(200)
TargetIBuffedFrame:SetPoint("TOPLEFT", TargetBuffMainFrame, "TOPLEFT")
--local tibbg = TargetIBuffedFrame:CreateTexture(nil, "BACKGROUND")
--tibbg:SetTexture(0, 0, 0, .7)
--tibbg:SetAllPoints(TargetIBuffedFrame)

local TargetIDebuffedFrame = CreateFrame('Frame', "TargetIDebuffedFrame", TargetBuffMainFrame)
TargetIDebuffedFrame:SetHeight(40)
TargetIDebuffedFrame:SetWidth(200)
TargetIDebuffedFrame:SetPoint("TOPRIGHT", TargetBuffMainFrame, "TOPRIGHT")
--local tidbbg = TargetIDebuffedFrame:CreateTexture(nil, "BACKGROUND")
--tidbbg:SetTexture(0, 0, 0, .7)
--tidbbg:SetAllPoints(TargetIDebuffedFrame)

local TargetBuffedFrame = CreateFrame('Frame', "TargetBuffedFrame", TargetBuffMainFrame)
TargetBuffedFrame:SetHeight(60)
TargetBuffedFrame:SetWidth(200)
TargetBuffedFrame:SetPoint("BOTTOMLEFT", TargetBuffMainFrame, "BOTTOMLEFT")
--local tbbg = TargetBuffedFrame:CreateTexture(nil, "BACKGROUND")
--tbbg:SetTexture(0, 0, 0, .7)
--tbbg:SetAllPoints(TargetBuffedFrame)

local TargetDebuffedFrame = CreateFrame('Frame', "TargetDebuffedFrame", TargetBuffMainFrame)
TargetDebuffedFrame:SetHeight(60)
TargetDebuffedFrame:SetWidth(200)
TargetDebuffedFrame:SetPoint("BOTTOMRIGHT", TargetBuffMainFrame, "BOTTOMRIGHT")
--local tdbbg = TargetDebuffedFrame:CreateTexture(nil, "BACKGROUND")
--tdbbg:SetTexture(0, 0, 0, .7)
--tdbbg:SetAllPoints(TargetDebuffedFrame)

function addon:TargetBuffSetup()
	local buff, buffCaster, buffName, _
	local myBuffsCount, myBuffsPrev, myBuffsPrevRow = 0
	local otherBuffsCount, otherBuffsPrev, otherBuffsPrevRow = 0
	local targetingMyPet = UnitIsUnit("target", "pet")
	for index = 1, 40 do
		buff = _G['TargetFrameBuff' .. index]
		buffName, _, _, _, _, _, _, buffCaster = UnitBuff('target', index)

		
		if buff and buffName then
			
			if buffCaster ~= 'player' then
				buff:SetParent(TargetBuffedFrame)
				if targetingMyPet == 1 then
					buff:SetScale(0.85)
				else
					buff:SetScale(1)
				end
				if otherBuffsCount % 10 ~= 0 then
					buff:ClearAllPoints()
					buff:SetPoint('RIGHT', otherBuffsPrev, 'LEFT', -1, 0)
				else
					if otherBuffsPrevRow then
						buff:ClearAllPoints()
						buff:SetPoint('BOTTOM', otherBuffsPrevRow, 'TOP', 0, 1)
					else
						buff:ClearAllPoints()
						buff:SetPoint('BOTTOMRIGHT')
					end
					otherBuffsPrevRow = buff
				end
				otherBuffsCount, otherBuffsPrev = otherBuffsCount + 1, buff
			else				
				buff:SetParent(TargetIBuffedFrame)
				if targetingMyPet == 1 then
					buff:SetScale(1.15)
				else
					buff:SetScale(1.35)
				end
				if myBuffsCount % 10 ~= 0 then
					buff:ClearAllPoints()
					buff:SetPoint('RIGHT', myBuffsPrev, 'LEFT', -1, 0)
				else
					if myBuffsPrevRow then
						buff:ClearAllPoints()
						buff:SetPoint('BOTTOM', myBuffsPrevRow, 'TOP', 0, 1)
					else
						buff:ClearAllPoints()
						buff:SetPoint('BOTTOMRIGHT')
					end
					myBuffsPrevRow = buff
				end
				myBuffsCount, myBuffsPrev = myBuffsCount + 1, buff
			end
		else
			break
		end
	end
end

function addon:TargetDebuffSetup()
	local debuff, debuffCaster, debuffName, _
	local mydeBuffsCount, mydeBuffsPrev, mydeBuffsPrevRow = 0
	local otherdeBuffsCount, otherdeBuffsPrev, otherdeBuffsPrevRow = 0
	
	for index = 1, 40 do
		debuff = _G['TargetFrameDebuff' .. index]
		debuffName, _, _, _, _, _, _, debuffCaster = UnitDebuff('target', index)


		if debuff and debuffName then
			if debuffCaster ~= 'player' then
				debuff:SetParent(TargetDebuffedFrame)
				debuff:SetScale(1)
				if otherdeBuffsCount % 10 ~= 0 then
					debuff:ClearAllPoints()
					debuff:SetPoint('LEFT', otherdeBuffsPrev, 'RIGHT', 1, 0)
				else
					if otherdeBuffsPrevRow then
						debuff:ClearAllPoints()
						debuff:SetPoint('BOTTOM', otherdeBuffsPrevRow, 'TOP', 0, 1)
					else
						debuff:ClearAllPoints()
						debuff:SetPoint('BOTTOMLEFT')
					end
					otherdeBuffsPrevRow = debuff
				end
				otherdeBuffsCount, otherdeBuffsPrev = otherdeBuffsCount + 1, debuff
			else
				debuff:SetParent(TargetIDebuffedFrame)
				debuff:SetScale(1.15)
				if mydeBuffsCount % 10 ~= 0 then
					debuff:ClearAllPoints()
					debuff:SetPoint('LEFT', mydeBuffsPrev, 'RIGHT', 1, 0)
				else
					if mydeBuffsPrevRow then
						debuff:ClearAllPoints()
						debuff:SetPoint('BOTTOM', mydeBuffsPrevRow, 'TOP', 0, 1)
					else
						debuff:ClearAllPoints()
						debuff:SetPoint('BOTTOMLEFT')
					end
					mydeBuffsPrevRow = debuff
				end
				mydeBuffsCount, mydeBuffsPrev = mydeBuffsCount + 1, debuff
			end
		else
			break
		end
	end
end

TargetBuffMainFrame:SetScript("OnEvent", function()
	addon:TargetBuffSetup()
	addon:TargetDebuffSetup()
end)

--[[-----------------------------------------------------------------------------
Clique Inclusion
-------------------------------------------------------------------------------]]
ClickCastFrames = ClickCastFrames or {}
ClickCastFrames[GUI_TargetHealth] = true
ClickCastFrames[GUI_TargetMana] = true
ClickCastFrames[GUI_TargetOfTarget] = true
