local E = unpack(ElvUI)
local S = E:GetModule('Skins')
local valuecolors = E.myClassColor
local colorsborders = valuecolors
local _G = _G
local CreateFrame = _G.CreateFrame
local hooksecurefunc = _G.hooksecurefunc
local EnumerateFrames = _G.EnumerateFrames
local getmetatable = _G.getmetatable
local type = _G.type
local BackdropTemplateMixin = _G.BackdropTemplateMixin
local GetItemQualityColor = _G.C_Item and _G.C_Item.GetItemQualityColor or _G.GetItemQualityColor
local fixedConfig = false

local widgetAtlas = {
	["widgetstatusbar-fill-blue"] = { r = 0, g = 0, b = 255, a = 1},
	["widgetstatusbar-fill-green"] = { r = 0, g = 255, b = 0, a = 1},
	["widgetstatusbar-fill-red"] = { r = 255, g = 0, b = 0, a = 1},
	["widgetstatusbar-fill-white"] = { r = 255, g = 255, b = 255, a = 1},
	["widgetstatusbar-fill-yellow"] = { r = 255, g = 255, b = 0, a = 1},
	["cosmic-bar-fill-white"] = { r = 255, g = 255, b = 255, a = 1},
	["mixingpool-frame-fill-white"] = { r = 255, g = 255, b = 255, a = 1},
}

local function togglebackdrop(frame,show)
	if frame.TopLeftCorner then
		if show then
			frame.TopLeftCorner:Show()
			frame.TopRightCorner:Show()
			frame.BottomLeftCorner:Show()
			frame.BottomRightCorner:Show()

			frame.LeftEdge:Show()
			frame.RightEdge:Show()
			frame.BottomEdge:Show()
			frame.TopEdge:Show()
		else
			frame.TopLeftCorner:Hide()
			frame.TopRightCorner:Hide()
			frame.BottomLeftCorner:Hide()
			frame.BottomRightCorner:Hide()

			frame.LeftEdge:Hide()
			frame.RightEdge:Hide()
			frame.BottomEdge:Hide()
			frame.TopEdge:Hide()
		end
	end
	if frame.backdrop then
		if show then
			frame.backdrop.TopLeftCorner:Show()
			frame.backdrop.TopRightCorner:Show()
			frame.backdrop.BottomLeftCorner:Show()
			frame.backdrop.BottomRightCorner:Show()

			frame.backdrop.LeftEdge:Show()
			frame.backdrop.RightEdge:Show()
			frame.backdrop.BottomEdge:Show()
			frame.backdrop.TopEdge:Show()
		else
			frame.backdrop.TopLeftCorner:Hide()
			frame.backdrop.TopRightCorner:Hide()
			frame.backdrop.BottomLeftCorner:Hide()
			frame.backdrop.BottomRightCorner:Hide()

			frame.backdrop.LeftEdge:Hide()
			frame.backdrop.RightEdge:Hide()
			frame.backdrop.BottomEdge:Hide()
			frame.backdrop.TopEdge:Hide()
		end
	end
end

local function EltruismBorders(frame,isUnitFrameElement)
	if (isUnitFrameElement and not (frame:GetDebugName() and frame:GetDebugName():match("AuraBar"))) then return end
	if E.db.ElvUI_EltreumUI.borders.universalborders and not frame.eltruismuniversalborders and not frame.eltruismuniversalbordersadded then
		frame.eltruismuniversalborders = CreateFrame("Frame", nil, frame, BackdropTemplateMixin and "BackdropTemplate")
		frame.eltruismuniversalborders:SetPoint("CENTER", frame, "CENTER", 0, 0)
		frame.eltruismuniversalborders:SetBackdrop({
			edgeFile = E.LSM:Fetch("border", E.db.ElvUI_EltreumUI.borders.texture),
			edgeSize = E.db.ElvUI_EltreumUI.borders.universalborderssettings.thickness,
		})
		frame.eltruismuniversalborders:SetBackdropBorderColor(colorsborders.r, colorsborders.g, colorsborders.b, 1)
		frame.eltruismuniversalborders:SetFrameLevel(frame:GetFrameLevel()+2)
		frame.eltruismuniversalborders:SetFrameStrata(frame:GetFrameStrata())
		if frame.Center then
			frame.eltruismuniversalborders:SetOutside(frame.Center, E.db.ElvUI_EltreumUI.borders.universalborderssettings.xOffset, E.db.ElvUI_EltreumUI.borders.universalborderssettings.yOffset)
		else
			frame.eltruismuniversalborders:SetOutside(frame, E.db.ElvUI_EltreumUI.borders.universalborderssettings.xOffset, E.db.ElvUI_EltreumUI.borders.universalborderssettings.yOffset)
		end
		--if not hiding the config frame border then the buttons become unclickable
		if not fixedConfig then
			local configFrame = E:Config_GetWindow()
			if configFrame and configFrame.eltruismuniversalborders then
				--configFrame.eltruismuniversalborders:Kill()
				--configFrame.eltruismuniversalborders = nil
				configFrame.eltruismuniversalborders:SetFrameStrata("MEDIUM")
				configFrame.Center:ClearAllPoints()
				configFrame.Center:SetPoint("TOPLEFT", configFrame, "TOPLEFT", 2, -2)
				configFrame.Center:SetPoint("BOTTOMRIGHT", configFrame, "BOTTOMRIGHT", -2, 2)

				fixedConfig = true
			end
		end

		if frame.IconBorder then --items are different
			if frame.rarity then
				local r,g,b = GetItemQualityColor(frame.rarity)
				frame.eltruismuniversalborders:SetBackdropBorderColor(r, g, b, 1)
				frame.eltruismuniversalborders:Show()
				togglebackdrop(frame)
			else
				--[[frame.eltruismuniversalborders:SetBackdropBorderColor(0, 0, 0, 1)
				frame.eltruismuniversalborders:Show()
				togglebackdrop(frame,false)]]
				frame.eltruismuniversalborders:Hide()
				togglebackdrop(frame,true)
			end
			if frame.caerdonButton then
				frame.eltruismuniversalborders:SetFrameLevel(frame:GetFrameLevel()+1)
				frame.caerdonButton:SetFrameLevel(frame:GetFrameLevel()+2)
			end

			hooksecurefunc(frame, "SetBackdropBorderColor", function(frametable)
				frametable.eltruismuniversalborders:SetBackdrop({
					edgeFile = E.LSM:Fetch("border", E.db.ElvUI_EltreumUI.borders.texture),
					edgeSize = E.db.ElvUI_EltreumUI.borders.universalborderssettings.thickness,
				})
				if frametable.Center then
					frametable.eltruismuniversalborders:SetOutside(frametable.Center, E.db.ElvUI_EltreumUI.borders.universalborderssettings.xOffset, E.db.ElvUI_EltreumUI.borders.universalborderssettings.yOffset)
				else
					frametable.eltruismuniversalborders:SetOutside(frametable, E.db.ElvUI_EltreumUI.borders.universalborderssettings.xOffset, E.db.ElvUI_EltreumUI.borders.universalborderssettings.yOffset)
				end
				if frametable.rarity then
					local r,g,b = GetItemQualityColor(frametable.rarity)
					frametable.eltruismuniversalborders:SetBackdropBorderColor(r, g, b, 1)
					frametable.eltruismuniversalborders:Show()
					togglebackdrop(frametable)
				else
					--[[frametable.eltruismuniversalborders:SetBackdropBorderColor(0, 0, 0, 1)
					frametable.eltruismuniversalborders:Show()
					togglebackdrop(frametable,false)]]
					frametable.eltruismuniversalborders:Hide()
					togglebackdrop(frametable,true)
				end
				if frametable.caerdonButton then
					frametable.eltruismuniversalborders:SetFrameLevel(frametable:GetFrameLevel()+1)
					frametable.caerdonButton:SetFrameLevel(frametable:GetFrameLevel()+2)
				end
			end)
			hooksecurefunc(frame.IconBorder, "SetShown", function(frametable,shown)
				if shown then
					local r,g,b = frametable:GetVertexColor()
					frametable:GetParent().eltruismuniversalborders:SetBackdropBorderColor(r, g, b, 1)
					frametable:GetParent().eltruismuniversalborders:Show()
					togglebackdrop(frametable:GetParent())
					if frametable:GetParent().caerdonButton then
						frametable:GetParent().eltruismuniversalborders:SetFrameLevel(frametable:GetParent():GetFrameLevel()+1)
						frametable:GetParent().caerdonButton:SetFrameLevel(frametable:GetParent():GetFrameLevel()+2)
					end
				else
					--[[frametable:GetParent().eltruismuniversalborders:SetBackdropBorderColor(0, 0, 0, 1)
					frametable:GetParent().eltruismuniversalborders:Show()
					togglebackdrop(frametable:GetParent(),false)]]
					frametable:GetParent().eltruismuniversalborders:Hide()
					togglebackdrop(frametable:GetParent(),true)
				end
			end)
			hooksecurefunc(frame.IconBorder, "Show", function(frametable,shown)
				E:Delay(0, function() --delay until after the vertex color is set
					if shown then
						local r,g,b = frametable:GetVertexColor()
						frametable:GetParent().eltruismuniversalborders:SetBackdropBorderColor(r, g, b, 1)
						frametable:GetParent().eltruismuniversalborders:Show()
						togglebackdrop(frametable:GetParent())
						if frametable:GetParent().caerdonButton then
							frametable:GetParent().eltruismuniversalborders:SetFrameLevel(frametable:GetParent():GetFrameLevel()+1)
							frametable:GetParent().caerdonButton:SetFrameLevel(frametable:GetParent():GetFrameLevel()+2)
						end
					else
						--[[frametable:GetParent().eltruismuniversalborders:SetBackdropBorderColor(0, 0, 0, 1)
						frametable:GetParent().eltruismuniversalborders:Show()
						togglebackdrop(frametable:GetParent(),false)]]
						frametable:GetParent().eltruismuniversalborders:Hide()
						togglebackdrop(frametable:GetParent(),true)
					end
				end)
			end)
			hooksecurefunc(frame.IconBorder, "Hide", function(frametable)
				--[[frametable:GetParent().eltruismuniversalborders:SetBackdropBorderColor(0, 0, 0, 1)
				frametable:GetParent().eltruismuniversalborders:Show()
				togglebackdrop(frametable:GetParent(),false)]]
				frametable:GetParent().eltruismuniversalborders:Hide()
				togglebackdrop(frametable:GetParent(),true)
			end)

			if frame.shadow then frame.shadow:Hide() end
		end

		--sharedmedia dropdown preview
		if frame:GetParent() then
			if frame:GetParent().displayButton then
				frame:GetParent().displayButton:SetFrameLevel(frame:GetFrameLevel()+3)
			end
			if frame:GetParent().NameBackground then
				frame:GetParent().artBackdrop:SetOutside(frame.Icon)
				--frame:GetParent().Icon:SetInside(frame.eltruismuniversalborders)
			end
		end
		if _G.ElvNP_TargetClassPowerClassPower and _G.ElvNP_TargetClassPowerClassPower.backdrop and _G.ElvNP_TargetClassPowerClassPower.backdrop.eltruismuniversalborders then
			_G.ElvNP_TargetClassPowerClassPower.backdrop.eltruismuniversalborders:SetFrameLevel(frame:GetFrameLevel())
		end
		if frame:GetDebugName() then
			if frame:GetDebugName():match("AuraBar") then
				frame.eltruismuniversalborders:SetFrameLevel(1)
				frame.eltruismuniversalborders:SetFrameStrata("BACKGROUND")
			elseif frame:GetDebugName():match("QuestIcons") then
				frame.eltruismuniversalborders:Hide()
			end
		end

		togglebackdrop(frame)
		frame.eltruismuniversalbordersadded = true

		--even though shadows shouldnt be made, try to handle possible ones
		if frame.shadow then
			frame.shadow:Hide()
		elseif frame.backdrop and frame.backdrop.shadow then
			frame.backdrop.shadow:Hide()
			if frame.backdrop.eltruismuniversalborders then
				frame.backdrop.eltruismuniversalborders:Hide()
			end
		elseif frame:GetParent() and frame:GetParent().shadow then
			frame:GetParent().shadow:Hide()
		elseif frame:GetParent() and frame:GetParent():GetParent() and frame:GetParent():GetParent().shadow then
			frame:GetParent():GetParent().shadow:Hide()
		end

		--lfg selected issue
		if frame.SelectedTexture and not frame.SelectedTextureEltruismHook then
			if frame.TopLeftCorner then
				hooksecurefunc(frame,"SetBackdropBorderColor", function(_,r)--,a)
					if r == 1 then
						frame.eltruismuniversalborders:SetBackdropBorderColor(1, 1, 0, 1)
					else
						frame.eltruismuniversalborders:SetBackdropBorderColor(colorsborders.r, colorsborders.g, colorsborders.b, 1)
					end
				end)
			end
			frame.SelectedTextureEltruismHook = true
		end

		 --fix pet battle/transmog issue
		if frame:GetDebugName():match("PetJournalLoadoutPet") and frame:GetDebugName():match("backdrop") and not frame:GetDebugName():match("Spell") then
			local r,g,b = frame.BottomEdge:GetVertexColor()
			frame.eltruismuniversalborders:SetBackdropBorderColor(r, g, b, 1)
			if not frame.FixedPetBattleBorderColorEltruism then
				hooksecurefunc(frame, "SetBackdropBorderColor", function(frametable,r1,g1,b1)
					frametable.eltruismuniversalborders:SetBackdropBorderColor(r1, g1, b1, 1)
				end)
				frame.FixedPetBattleBorderColorEltruism = true
			end
		elseif frame:GetDebugName():match("PetJournal.ScrollBox.ScrollTarget") or frame:GetDebugName():match("PetJournalPetCardPetInfo") then
			local r,g,b = frame.BottomEdge:GetVertexColor()
			frame.eltruismuniversalborders:SetBackdropBorderColor(r, g, b, 1)
			if not frame.FixedPetBattleBorderColorEltruism then
				hooksecurefunc(frame, "SetBackdropBorderColor", function(frametable,r2,g2,b2)
					frametable.eltruismuniversalborders:SetBackdropBorderColor(r2, g2, b2, 1)
				end)
				frame.FixedPetBattleBorderColorEltruism = true
			end
		elseif frame:GetDebugName():match("PetBattleFrame") and (frame:GetDebugName():match("Ally") or frame:GetDebugName():match("Enemy")) then
			if frame.Icon then
				frame.eltruismuniversalborders:Hide()
				return
			end
			local r,g,b = frame.BottomEdge:GetVertexColor()
			frame.eltruismuniversalborders:SetBackdropBorderColor(r, g, b, 1)
			if not frame.FixedPetBattleBorderColorEltruism then
				hooksecurefunc(frame, "SetBackdropBorderColor", function(frametable,r3,g3,b3)
					frametable.eltruismuniversalborders:SetBackdropBorderColor(r3, g3, b3, 1)
				end)
				frame.FixedPetBattleBorderColorEltruism = true
			end
		elseif frame:GetDebugName():match("WardrobeCollectionFrame.ItemsCollectionFrame.Model") then
			if frame:GetParent().HideVisual then
				frame:GetParent().HideVisual:SetFrameLevel(frame:GetFrameLevel()+2)
			end
			if frame:GetParent().Favorite then
				frame:GetParent().Favorite:SetFrameLevel(frame:GetFrameLevel()+2)
			end
			if not frame.FixedPetBattleBorderColorEltruism then
				hooksecurefunc(frame, "SetBackdropBorderColor", function(frametable,r,g,b)
					if r == 1 and g == 0.7 and b == 1 then --highlighted
						frametable.eltruismuniversalborders:SetBackdropBorderColor(r, g, b, 1)
					else
						frame.eltruismuniversalborders:SetBackdropBorderColor(colorsborders.r, colorsborders.g, colorsborders.b, 1)
					end
				end)
				frame.FixedPetBattleBorderColorEltruism = true
			end
		end
	end
end

local function EltruismBackground(frame,isUnitFrameElement,isNamePlateElement)
	if isUnitFrameElement and not E.db.ElvUI_EltreumUI.skins.elvui.unitframes then return end
	if isNamePlateElement and not E.db.ElvUI_EltreumUI.skins.elvui.nameplates then return end
	if frame:GetObjectType() == "Button" and not E.db.ElvUI_EltreumUI.skins.elvui.button then return end
	if frame:GetParent() and frame:GetParent():GetObjectType() == "Button" and not E.db.ElvUI_EltreumUI.skins.elvui.button then return end
	if (frame:GetParent() and frame:GetParent().VisitHouseButton) then return end
	if not frame.EltruismBackground then
		frame.eltruismbgtexture = frame:CreateTexture(nil, "BORDER")
		frame.eltruismbgtexture:SetParent(frame)
		frame.eltruismbgtexture:ClearAllPoints()
		frame.eltruismbgtexture:SetPoint("TOPLEFT", 1, -1)
		frame.eltruismbgtexture:SetPoint("BOTTOMRIGHT", -1, 1)
		frame.eltruismbgtexture:SetTexture(E.LSM:Fetch("background", E.db.ElvUI_EltreumUI.skins.elvui.texture), true, true)
		frame.eltruismbgtexture:SetHorizTile(true)
		frame.eltruismbgtexture:SetVertTile(true)
		frame.eltruismbgtexture:SetBlendMode("ADD")
		if (frame:GetObjectType() == "Button" or frame:GetObjectType() == "CheckButton") and frame.icon then --fix for buttons since the texture could overlap over the icon
			frame.eltruismbgtexture:SetDrawLayer("BACKGROUND")
		end
		if frame:GetParent() then
			if frame:GetParent():GetObjectType() == "Button" and frame:GetParent().icon and not isUnitFrameElement then --fix for buttons since the texture could overlap over the icon
				frame.eltruismbgtexture:SetDrawLayer("BACKGROUND")
			end
			if frame:GetParent().TransmogStateTexture then --transmog stuff
				frame.eltruismbgtexture:SetTexture("")
			end
			if frame:GetParent().TransmogSelectedAnim then --transmog stuff
				--frame.eltruismbgtexture:SetTexture("") --at some point this stopped working and now the frame needs to be hidden
				frame:Hide()
			end
		end
		--[[if (frame.SelectedTexture or frame.glossTex) then --fix some more buttons
			frame.eltruismbgtexture:Hide()
		end]]
		if isUnitFrameElement and (frame:GetParent() and frame:GetParent().isTransparent == false) then --only on health
			frame.eltruismbgtexture:SetDrawLayer("ARTWORK")
			frame.eltruismbgtexture:SetParent(frame:GetParent())
		end
		if E.db.ElvUI_EltreumUI.skins.elvui.color.classcolor then
			frame.eltruismbgtexture:SetVertexColor(valuecolors.r,valuecolors.g,valuecolors.b,0.15)
		else
			frame.eltruismbgtexture:SetVertexColor(E.db.ElvUI_EltreumUI.skins.elvui.color.r,E.db.ElvUI_EltreumUI.skins.elvui.color.g,E.db.ElvUI_EltreumUI.skins.elvui.color.b,E.db.ElvUI_EltreumUI.skins.elvui.color.a)
		end

		if frame.leftHolder then --elvui second config frame stuff
			frame.eltruismbgtexture:SetTexture("")
		end

		if ElvUI_EltreumUI:IsThisASafeSecret(nil,nil,true) and ElvUI_EltreumUI:IsThisASafeSecret(frame,true) and frame:GetDebugName():match("PetJournalLoadoutPet") then --fix pet battle issue --has secret
			if frame.icon and frame.backdrop then frame.backdrop:SetFrameLevel(frame:GetFrameLevel()+2) end
		end

		frame.EltruismBackground = true
	end
end

local function EltruisAce3(frame)
	if E.db.ElvUI_EltreumUI.skins.ace3.enable then
		if not frame.EltruismAce3HooksSetup then
			E:Delay(0,function()
				if frame:GetParent() then
					if frame:GetParent().obj then
						if frame:GetParent().obj.SetValue then
							if not frame:GetParent().obj.EltruismHookLabel then
								hooksecurefunc(frame:GetParent().obj,"SetValue", function(frametext)
									E:Delay(0, function()
										if frametext.label then
											if not E.db.ElvUI_EltreumUI.skins.ace3.tab.TextEnabled.classcolor then
												frametext.label:SetTextColor(E.db.ElvUI_EltreumUI.skins.ace3.tab.TextEnabled.r, E.db.ElvUI_EltreumUI.skins.ace3.tab.TextEnabled.g, E.db.ElvUI_EltreumUI.skins.ace3.tab.TextEnabled.b)
											else
												frametext.label:SetTextColor(valuecolors.r, valuecolors.g, valuecolors.b)
											end
										end
										if frametext.titletext then
											if not E.db.ElvUI_EltreumUI.skins.ace3.tab.TextEnabled.classcolor then
												frametext.titletext:SetTextColor(E.db.ElvUI_EltreumUI.skins.ace3.tab.TextEnabled.r, E.db.ElvUI_EltreumUI.skins.ace3.tab.TextEnabled.g, E.db.ElvUI_EltreumUI.skins.ace3.tab.TextEnabled.b)
											else
												frametext.titletext:SetTextColor(valuecolors.r, valuecolors.g, valuecolors.b)
											end
										end
									end)
								end)
								frame:GetParent().obj.EltruismHookLabel = true
							end
						end
						if frame:GetParent().obj.SetText then
							if not frame:GetParent().obj.EltruismHookSetText then
								hooksecurefunc(frame:GetParent().obj,"SetText", function(frametext)
									E:Delay(0, function()
										if frametext.label then
											if not E.db.ElvUI_EltreumUI.skins.ace3.tab.TextEnabled.classcolor then
												frametext.label:SetTextColor(E.db.ElvUI_EltreumUI.skins.ace3.tab.TextEnabled.r, E.db.ElvUI_EltreumUI.skins.ace3.tab.TextEnabled.g, E.db.ElvUI_EltreumUI.skins.ace3.tab.TextEnabled.b)
											else
												frametext.label:SetTextColor(valuecolors.r, valuecolors.g, valuecolors.b)
											end
										end
										if frametext.titletext then
											if not E.db.ElvUI_EltreumUI.skins.ace3.tab.TextEnabled.classcolor then
												frametext.titletext:SetTextColor(E.db.ElvUI_EltreumUI.skins.ace3.tab.TextEnabled.r, E.db.ElvUI_EltreumUI.skins.ace3.tab.TextEnabled.g, E.db.ElvUI_EltreumUI.skins.ace3.tab.TextEnabled.b)
											else
												frametext.titletext:SetTextColor(valuecolors.r, valuecolors.g, valuecolors.b)
											end
										end
									end)
								end)
								frame:GetParent().obj.EltruismHookSetText = true
							end
						end
					end
					if frame:GetParent().label then
						if frame:GetParent().label.SetText then
							if not frame:GetParent().EltruismHookSetTextLabel then
								hooksecurefunc(frame:GetParent().label,"SetText", function(frametext)
									E:Delay(0, function()
										if not E.db.ElvUI_EltreumUI.skins.ace3.tab.TextEnabled.classcolor then
											frametext:SetTextColor(E.db.ElvUI_EltreumUI.skins.ace3.tab.TextEnabled.r, E.db.ElvUI_EltreumUI.skins.ace3.tab.TextEnabled.g, E.db.ElvUI_EltreumUI.skins.ace3.tab.TextEnabled.b)
										else
											frametext:SetTextColor(valuecolors.r, valuecolors.g, valuecolors.b)
										end
									end)
								end)
								frame:GetParent().EltruismHookSetTextLabel = true
							end
						end
					end
					if frame:GetParent().titletext then
						if frame:GetParent().titletext.SetText then
							if not frame:GetParent().EltruismHookSetTextTitleText then
								hooksecurefunc(frame:GetParent().titletext,"SetText", function(frametext)
									E:Delay(0, function()
										if not E.db.ElvUI_EltreumUI.skins.ace3.tab.TextEnabled.classcolor then
											frametext:SetTextColor(E.db.ElvUI_EltreumUI.skins.ace3.tab.TextEnabled.r, E.db.ElvUI_EltreumUI.skins.ace3.tab.TextEnabled.g, E.db.ElvUI_EltreumUI.skins.ace3.tab.TextEnabled.b)
										else
											frametext:SetTextColor(valuecolors.r, valuecolors.g, valuecolors.b)
										end
									end)
								end)
								frame:GetParent().EltruismHookSetTextTitleText = true
							end
						end
					end
				end
			end)
			frame.EltruismAce3HooksSetup = true
		end
		E:Delay(0,function()
			if frame:GetParent() then
				if frame:GetParent().obj then
					if frame:GetParent().obj.label and frame:GetParent().obj.label.SetTextColor then
						if not E.db.ElvUI_EltreumUI.skins.ace3.tab.TextEnabled.classcolor then
							frame:GetParent().obj.label:SetTextColor(E.db.ElvUI_EltreumUI.skins.ace3.tab.TextEnabled.r, E.db.ElvUI_EltreumUI.skins.ace3.tab.TextEnabled.g, E.db.ElvUI_EltreumUI.skins.ace3.tab.TextEnabled.b)
						else
							frame:GetParent().obj.label:SetTextColor(valuecolors.r, valuecolors.g, valuecolors.b)
						end
					end
					if frame:GetParent().obj.titletext and frame:GetParent().obj.titletext.SetTextColor then
						if not E.db.ElvUI_EltreumUI.skins.ace3.tab.TextEnabled.classcolor then
							frame:GetParent().obj.titletext:SetTextColor(E.db.ElvUI_EltreumUI.skins.ace3.tab.TextEnabled.r, E.db.ElvUI_EltreumUI.skins.ace3.tab.TextEnabled.g, E.db.ElvUI_EltreumUI.skins.ace3.tab.TextEnabled.b)
						else
							frame:GetParent().obj.titletext:SetTextColor(valuecolors.r, valuecolors.g, valuecolors.b)
						end
					end
				end
				if frame:GetParent().label then
					if frame:GetParent().label.SetText then
						if not E.db.ElvUI_EltreumUI.skins.ace3.tab.TextEnabled.classcolor then
							frame:GetParent().label:SetTextColor(E.db.ElvUI_EltreumUI.skins.ace3.tab.TextEnabled.r, E.db.ElvUI_EltreumUI.skins.ace3.tab.TextEnabled.g, E.db.ElvUI_EltreumUI.skins.ace3.tab.TextEnabled.b)
						else
							frame:GetParent().label:SetTextColor(valuecolors.r, valuecolors.g, valuecolors.b)
						end
					end
				end
				if frame:GetParent().titletext then
					if frame:GetParent().titletext.SetText then
						if not E.db.ElvUI_EltreumUI.skins.ace3.tab.TextEnabled.classcolor then
							frame:GetParent().titletext:SetTextColor(E.db.ElvUI_EltreumUI.skins.ace3.tab.TextEnabled.r, E.db.ElvUI_EltreumUI.skins.ace3.tab.TextEnabled.g, E.db.ElvUI_EltreumUI.skins.ace3.tab.TextEnabled.b)
						else
							frame:GetParent().titletext:SetTextColor(valuecolors.r, valuecolors.g, valuecolors.b)
						end
					end
				end
				if frame:GetParent().Label then
					if frame:GetParent().Label.SetText then
						if not E.db.ElvUI_EltreumUI.skins.ace3.tab.TextEnabled.classcolor then
							frame:GetParent().Label:SetTextColor(E.db.ElvUI_EltreumUI.skins.ace3.tab.TextEnabled.r, E.db.ElvUI_EltreumUI.skins.ace3.tab.TextEnabled.g, E.db.ElvUI_EltreumUI.skins.ace3.tab.TextEnabled.b)
						else
							frame:GetParent().Label:SetTextColor(valuecolors.r, valuecolors.g, valuecolors.b)
						end
					end
				end
			end
			if ElvUI_EltreumUI:IsThisASafeSecret(frame.name,true) and frame.name and frame.name.SetText then
				if frame.objectType and frame.objectType == "item" then
					return
				end
				if not E.db.ElvUI_EltreumUI.skins.ace3.tab.TextEnabled.classcolor then
					frame.name:SetTextColor(E.db.ElvUI_EltreumUI.skins.ace3.tab.TextEnabled.r, E.db.ElvUI_EltreumUI.skins.ace3.tab.TextEnabled.g, E.db.ElvUI_EltreumUI.skins.ace3.tab.TextEnabled.b)
				else
					frame.name:SetTextColor(valuecolors.r, valuecolors.g, valuecolors.b)
				end
			end
			if frame.TitleText and frame.TitleText.SetText then
				if not E.db.ElvUI_EltreumUI.skins.ace3.tab.TextEnabled.classcolor then
					frame.TitleText:SetTextColor(E.db.ElvUI_EltreumUI.skins.ace3.tab.TextEnabled.r, E.db.ElvUI_EltreumUI.skins.ace3.tab.TextEnabled.g, E.db.ElvUI_EltreumUI.skins.ace3.tab.TextEnabled.b)
				else
					frame.TitleText:SetTextColor(valuecolors.r, valuecolors.g, valuecolors.b)
				end
			end
			if frame.TitleContainer and frame.TitleContainer.TitleText and frame.TitleContainer.TitleText.SetText then
				if not E.db.ElvUI_EltreumUI.skins.ace3.tab.TextEnabled.classcolor then
					frame.TitleContainer.TitleText:SetTextColor(E.db.ElvUI_EltreumUI.skins.ace3.tab.TextEnabled.r, E.db.ElvUI_EltreumUI.skins.ace3.tab.TextEnabled.g, E.db.ElvUI_EltreumUI.skins.ace3.tab.TextEnabled.b)
				else
					frame.TitleContainer.TitleText:SetTextColor(valuecolors.r, valuecolors.g, valuecolors.b)
				end
			end
			if frame.Name and frame.Name.SetText and not frame.HotKey then
				if frame.objectType and frame.objectType == "item" then
					return
				end
				if not E.db.ElvUI_EltreumUI.skins.ace3.tab.TextEnabled.classcolor then
					frame.Name:SetTextColor(E.db.ElvUI_EltreumUI.skins.ace3.tab.TextEnabled.r, E.db.ElvUI_EltreumUI.skins.ace3.tab.TextEnabled.g, E.db.ElvUI_EltreumUI.skins.ace3.tab.TextEnabled.b)
				else
					frame.Name:SetTextColor(valuecolors.r, valuecolors.g, valuecolors.b)
				end
			end
			if frame.Header and frame.Header.Text and frame.Header.Text.SetText then
				if not E.db.ElvUI_EltreumUI.skins.ace3.tab.TextEnabled.classcolor then
					frame.Header.Text:SetTextColor(E.db.ElvUI_EltreumUI.skins.ace3.tab.TextEnabled.r, E.db.ElvUI_EltreumUI.skins.ace3.tab.TextEnabled.g, E.db.ElvUI_EltreumUI.skins.ace3.tab.TextEnabled.b)
				else
					frame.Header.Text:SetTextColor(valuecolors.r, valuecolors.g, valuecolors.b)
				end
			end
		end)
	end
end

local function EltruismShadow(frame,template)
	if E.db.ElvUI_EltreumUI.skins.shadow.universalshadows and template ~= "NoBackdrop" then
		if frame then
			if frame.backdrop then
				if not frame.backdrop.shadow then
					frame.backdrop:CreateShadow(E.db.ElvUI_EltreumUI.skins.shadow.length)
					ElvUI_EltreumUI:ShadowColor(frame.backdrop.shadow)
				end
			else
				if not frame.shadow then
					frame:CreateShadow(E.db.ElvUI_EltreumUI.skins.shadow.length)
					ElvUI_EltreumUI:ShadowColor(frame.shadow)
				end
			end
		end
	else
		if E.db.ElvUI_EltreumUI.skins.shadow.enable then
			--saved instances shadow
			if frame:GetParent() and frame:GetParent().key and frame:GetParent().key == "SavedInstancesTooltip" and not E.db.ElvUI_EltreumUI.borders.universalborders then
				if not frame.shadow then
					frame:CreateShadow(E.db.ElvUI_EltreumUI.skins.shadow.length)
					ElvUI_EltreumUI:ShadowColor(frame.shadow)
				end
			end

			--possible widget shadows
			if frame:GetParent() and frame:GetParent():GetParent() and frame:GetParent():GetParent().widgetContainer then
				if not frame.shadow and not E.db.ElvUI_EltreumUI.borders.universalborders then
					frame:CreateShadow(E.db.ElvUI_EltreumUI.skins.shadow.length)
					ElvUI_EltreumUI:ShadowColor(frame.shadow)
				end
			end

			--new dropdowns?
			if frame:GetParent() and frame:GetParent().InitScrollLayout and not E.db.ElvUI_EltreumUI.borders.universalborders then
				if not frame.shadow then
					frame:CreateShadow(E.db.ElvUI_EltreumUI.skins.shadow.length)
					ElvUI_EltreumUI:ShadowColor(frame.shadow)
				end
			end

			--petbattle
			if frame:GetParent() and frame:GetParent().PetType and not E.db.ElvUI_EltreumUI.borders.universalborders then
				if not frame.shadow then
					frame:CreateShadow(E.db.ElvUI_EltreumUI.skins.shadow.length)
					ElvUI_EltreumUI:ShadowColor(frame.shadow)
				end
			end
			--if ElvUI_EltreumUI:IsThisASafeSecret(frame,true) and ElvUI_EltreumUI:IsThisASafeSecret(nil,nil,true) and ElvUI_EltreumUI:IsThisASafeSecret(frame:GetDebugName(),true) then
			if not E.Retail then
				if frame:GetDebugName():match("PetBattleFrame") then
					if not frame.shadow then
						frame:CreateShadow(E.db.ElvUI_EltreumUI.skins.shadow.length)
						ElvUI_EltreumUI:ShadowColor(frame.shadow)
					end
				end
			end
			if frame:GetParent() and frame:GetParent() == _G["ElvUIPetBattleActionBar"] and not E.db.ElvUI_EltreumUI.borders.universalborders then
				if not frame.shadow then
					frame:CreateShadow(E.db.ElvUI_EltreumUI.skins.shadow.length)
					ElvUI_EltreumUI:ShadowColor(frame.shadow)
				end
			end
		end
	end
end

local function SkinFrame(object)
	if not object then return end --rare but not impossible nil error
	if object:GetObjectType() == "Texture" then object = object:GetParent() end
	local mt = getmetatable(object).__index
	if not mt then return end
	if type(mt) == 'function' then return end
	if mt.SetTemplate and not mt.SetTemplateEltruismHook then
		hooksecurefunc(mt, "SetTemplate", function(frame, template, _, _, _, isUnitFrameElement, isNamePlateElement)
			if frame:GetObjectType() == "CheckButton" and frame.mask then return end --actionbar masks fix
			if frame.bgrElvUISkin then return end --baganator elvui skin

			if E.Retail then --due to an issue in retail disable the scoreboard skin (_G.PVPMatchScoreboard)
				E.private.skins.blizzard.bgscore = false
			end

			--if frame.showDispellableDebuff then return end --fix RaidDebufs
			if template ~= "NoBackdrop" then
				if E.db.ElvUI_EltreumUI.skins.elvui.SetTemplate then
					EltruismBackground(frame,isUnitFrameElement,isNamePlateElement)
				end
				if E.db.ElvUI_EltreumUI.borders.universalborders then
					EltruismBorders(frame,isUnitFrameElement)
				end
			else
				if frame.eltruismbgtexture then
					frame.eltruismbgtexture:Hide()
				end
			end

			if E.db.ElvUI_EltreumUI.skins.ace3.enable then
				EltruisAce3(frame)
			end
			if E.db.ElvUI_EltreumUI.skins.shadow.enable then
				EltruismShadow(frame,template)
			end

			--widget things
			if frame:GetParent() and frame:GetParent():GetParent() and not frame:GetParent():GetParent().EltruismWidgetHook then
				if frame:GetParent():GetParent().widgetContainer then

					--font/texture
					if frame:GetParent():GetParent().Label then
						local _,size = frame:GetParent():GetParent().Label:GetFont()
						frame:GetParent():GetParent().Label:SetFont(E.LSM:Fetch("font", E.db.general.font), size, ElvUI_EltreumUI:FontFlag(E.db.general.fontStyle))
					end
					if frame:GetParent():GetParent().Bar and frame:GetParent():GetParent().Bar.SetStatusBarColor and frame:GetParent():GetParent().Bar.SetStatusBarTexture then
						local atlas = frame:GetParent():GetParent().Bar:GetStatusBarTexture():GetAtlas()
						--frame:GetParent():GetParent().Bar.EltruismAtlas = atlas
						frame:GetParent():GetParent().Bar:SetStatusBarTexture(E.LSM:Fetch("statusbar", "ElvUI Norm1"))
						if E.db.ElvUI_EltreumUI.dev then
							print("atlas:",atlas)
						end
						if widgetAtlas[atlas] then
							frame:GetParent():GetParent().Bar:SetStatusBarColor(widgetAtlas[atlas].r,widgetAtlas[atlas].g,widgetAtlas[atlas].b,widgetAtlas[atlas].a)
						end
						if not frame:GetParent():GetParent().Bar.EltruismColorHook and frame:GetParent():GetParent().Bar.DisplayBarValue then
							hooksecurefunc(frame:GetParent():GetParent().Bar, "DisplayBarValue", function(widget)
								local _, maxValue = widget:GetMinMaxValues()
								S:StatusBarColorGradient(widget, widget:GetValue(), maxValue)
								widget.backdrop:SetAlpha(E.db.general.backdropfadecolor.a)
								widget.backdrop:SetBackdropColor(0,0,0)
								widget:SetStatusBarTexture(E.LSM:Fetch("statusbar", "ElvUI Norm1"))

								--[[if not atlas then
									atlas = widget:GetStatusBarTexture():GetAtlas()
								end
								if not atlas then
									atlas = widget.EltruismAtlas
								end]]
								--widget:SetStatusBarColor(widgetAtlas[atlas].r,widgetAtlas[atlas].g,widgetAtlas[atlas].b,widgetAtlas[atlas].a)
							end)
							frame:GetParent():GetParent().Bar.EltruismColorHook = true
						end
					end

					-- hook for when label gets added
					if not frame:GetParent():GetParent().EltruismLabelHook then
						frame:GetParent():GetParent():HookScript("OnShow", function(widget)
							if widget.Label then
								local _,size = widget.Label:GetFont()
								widget.Label:SetFont(E.LSM:Fetch("font", E.db.general.font), size, ElvUI_EltreumUI:FontFlag(E.db.general.fontStyle))
							end
							if widget.Bar then
								local atlas = widget.Bar:GetStatusBarTexture():GetAtlas()
								if atlas then
									widget.Bar:GetStatusBarTexture():SetColorTexture(widgetAtlas[atlas].r,widgetAtlas[atlas].g,widgetAtlas[atlas].b,widgetAtlas[atlas].a)
									widget.Bar:SetStatusBarTexture(E.LSM:Fetch("statusbar", "ElvUI Norm1"))
								end
							end
						end)
						frame:GetParent():GetParent().EltruismLabelHook = true
					end

					--same as above, but for when its the first parent
					if frame:GetParent().Label then
						local _,size = frame:GetParent().Label:GetFont()
						frame:GetParent().Label:SetFont(E.LSM:Fetch("font", E.db.general.font), size, ElvUI_EltreumUI:FontFlag(E.db.general.fontStyle))
					end
					if frame:GetParent().Bar then
						local atlas = frame:GetParent().Bar:GetStatusBarTexture():GetAtlas()
						if atlas then
							frame:GetParent().Bar:GetStatusBarTexture():SetColorTexture(widgetAtlas[atlas].r,widgetAtlas[atlas].g,widgetAtlas[atlas].b,widgetAtlas[atlas].a)
							frame:GetParent().Bar:SetStatusBarTexture(E.LSM:Fetch("statusbar", "ElvUI Norm1"))
						end
					end

					-- hook for when label gets added
					if not frame:GetParent().EltruismLabelHook then
						frame:GetParent():HookScript("OnShow", function(widget)
							if widget.Label then
								local _,size = widget.Label:GetFont()
								widget.Label:SetFont(E.LSM:Fetch("font", E.db.general.font), size, ElvUI_EltreumUI:FontFlag(E.db.general.fontStyle))
							end
							if widget.Bar then
								local atlas = widget.Bar:GetStatusBarTexture():GetAtlas()
								if atlas then
									widget.Bar:GetStatusBarTexture():SetColorTexture(widgetAtlas[atlas].r,widgetAtlas[atlas].g,widgetAtlas[atlas].b,widgetAtlas[atlas].a)
									widget.Bar:SetStatusBarTexture(E.LSM:Fetch("statusbar", "ElvUI Norm1"))
								end
							end
						end)
						frame:GetParent():GetParent().EltruismLabelHook = true
					end

					frame:GetParent():GetParent().EltruismWidgetHook = true
				end
			end

			if frame == _G.QuestInfoItemHighlight then --fix the highlight
				frame:SetBackdropBorderColor(1, 1, 0)
				frame:SetBackdropColor(0, 0, 0, 0)
			end
		end)
		mt.SetTemplateEltruismHook = true
	end
end

--based on elvui toolkit
local loopframe = CreateFrame("Frame")
local frametypes = {
	["Region"] = true,
	["Texture"] = true,
	["Cooldown"] = true,
	["Slider"] = true,
	["ScrollFrame"] = true,
	["ModelScene"] = true,
}
function ElvUI_EltreumUI:SetTemplateSkin()
	if E.db.ElvUI_EltreumUI.skins.elvui.SetTemplate or E.db.ElvUI_EltreumUI.skins.ace3.enable or E.db.ElvUI_EltreumUI.skins.shadow.enable or E.db.ElvUI_EltreumUI.borders.universalborders then
		if not E.db.ElvUI_EltreumUI.borders.classcolor then --set the variable here so its not spamming
			colorsborders = {
				r = E.db.ElvUI_EltreumUI.borders.bordercolors.r,
				g = E.db.ElvUI_EltreumUI.borders.bordercolors.g,
				b = E.db.ElvUI_EltreumUI.borders.bordercolors.b
			}
		end
		SkinFrame(loopframe)
		loopframe = EnumerateFrames()
		while loopframe do
			if (not loopframe:IsForbidden()) and not frametypes[loopframe:GetObjectType()] then
				SkinFrame(loopframe)
				frametypes[loopframe:GetObjectType()] = true
			end
			loopframe = EnumerateFrames(loopframe)
		end
		E:UpdateAll(true)
		E:Delay(10, function()
			if E.db.ElvUI_EltreumUI.chat.chattoggles then
				_G.LeftChatToggleButton:SetAlpha(1)
				_G.LeftChatToggleButton:Show()
				_G.RightChatToggleButton:SetAlpha(1)
				_G.RightChatToggleButton:Show()
			end
		end)
	end
end
