local E = select(2, ...) -- Engine
local CO,L,UF,AB,LT,BA,TT = E:LoadModules("Config", "Locale", "Unitframes", "Actionbars", "Layout", "Bar_Auras", "Tooltip")

local _
local format = string.format

CO:InitializeOptionsCategory("unitframe", L["Unitframes"], 300)

local positionValues = {
	TOPLEFT = 'TOPLEFT',
	LEFT = 'LEFT',
	BOTTOMLEFT = 'BOTTOMLEFT',
	RIGHT = 'RIGHT',
	TOPRIGHT = 'TOPRIGHT',
	BOTTOMRIGHT = 'BOTTOMRIGHT',
	CENTER = 'CENTER',
	TOP = 'TOP',
	BOTTOM = 'BOTTOM',
}

local sortDirectionsHorizontal = {
	["+"] = "Left > Right",
	["-"] = "Right > Left",
}

local sortDirectionsVertical = {
	["+"] = "Bottom > Top",
	["-"] = "Top > Bottom",
}

local sortBarOrientation = {
	["HORIZONTAL"]  = "Left -> Right",
	["VERTICAL"]  = "Bottom -> Top",
}

local attachToValues = {
	["Health"] = "Health",
	["Power"] = "Power",
	["InfoPanel"] = "InfoPanel",
	["Frame"] = "Frame",
}

local GroupNames = {
	"player", "target", "targettarget", "focus", "focustarget", "pet", "arena", "party", "boss", "raid", "raid40"
}
local TextTypes = {
	"name", "health", "power", "level"
}

local DummyMode = false

local function HealthUpdate(groupName)
	
	local AddStr, NumToCreate
	
	AddStr			= ""
	NumToCreate 	= CO.ToCreate[groupName] or 1
	
	for i=1,NumToCreate do
		if NumToCreate ~= 1 then AddStr = i else AddStr = "" end
		
		local profileData = CO.db.profile.unitframe.units[groupName]['health']
		
		local textureframe = E.Frames[E:firstToUpper(groupName) .. "HealthOverlay"] -- Just target overlay (target texture)
		-- /run E:MoveFrame(E.Frames["PlayerHealthCluster"], 5, 50)
		
	end
	
	local frame = E.Frames[E:firstToUpper(groupName) .. "MainFrame"]
	frame:ClearAllPoints()
	frame:SetPoint(profileData["position"], _, profileData["position"], profileData["xOffset"], profileData["yOffset"])
end

local function GetOptionsTable_Health(groupName)
	local config = {
		order = 100,
		type = 'group',
		name = "Leben",
		get = function(info) return CO.db.profile.unitframe.units[groupName]['health'][ info[#info] ] end,
		set = function(info, value) CO.db.profile.unitframe.units[groupName]['health'][ info[#info] ] = value; HealthUpdate(groupName) end,
		args = {
			header = {
				order = 1,
				type = "header",
				name = "Leben",
			},
			position = {
				type = 'select',
				order = 2,
				name = "Position",
				values = positionValues,
			},
			xOffset = {
				order = 3,
				type = 'range',
				name = "X Offset",
				desc = "X Offset",
				min = -1000, max = 1000, step = 1,
			},
			yOffset = {
				order = 4,
				type = 'range',
				name = "Y Offset",
				desc = "Y Offset",
				min = -1000, max = 1000, step = 1,
			},
			attachTextTo = {
				type = 'select',
				order = 5,
				name = "Attach Text To",
				values = attachToValues,
			},
			text_format = {
				order = 100,
				name = "Text format",
				type = 'input',
				width = 'full',
				desc = "Text format",
			},
		},
	}

	return config
end

--------------------------------
--  Text Update
--------------------------------
local function UpdateUFText(groupName, tableType)
	local profileData = CO.db.profile.unitframe.units[groupName][tableType]
	local UF = E:GetModule("Unitframes")
	
	local frame, flags, AddStr, NumToCreate
	
	AddStr			= ""
	NumToCreate 	= UF.ToCreate[groupName] or 1
	
	for i=1,NumToCreate do
		if NumToCreate ~= 1 then AddStr = i else AddStr = "" end
			if UF.Frames[groupName .. AddStr] then
				frame = UF.Frames[groupName .. AddStr].Fonts[E:firstToUpper(tableType)]
				if frame then
					frame:ClearAllPoints()
					frame:SetPoint(profileData["position"])
					E:MoveFrame(frame, profileData["xOffset"], profileData["yOffset"])
					
					flags = profileData["fontFlags"]
					if profileData["fontFlags"] == "None" then flags = {} end
					
					-- (Frame, fontName, fontFlags, fontHeight, fontColor)
					E:SetFontInfo(frame, CO.Media:Fetch("font", profileData["fontType"]), flags, profileData["fontHeight"], nil)
					E:UpdateFont(frame)
					
					if profileData["width"] then frame:SetWidth(profileData["width"]) end
					if profileData["horizontalAlign"] then frame:SetJustifyH(profileData["horizontalAlign"]) end
					
					
					frame:SetShadowColor(profileData["fontShadowColor"].r, profileData["fontShadowColor"].g, profileData["fontShadowColor"].b, profileData["fontShadowColor"].a)
					frame:SetShadowOffset(profileData["xFontShadowOffset"], profileData["yFontShadowOffset"])
					
					-- Hide if disabled or if frame is type "level", "doNotShowOnMaxLevel" is enabled and unit is at max level
					if not (CO.db.profile.unitframe.units[groupName][tableType]["enable"]) or 
						(profileData["doNotShowOnMaxLevel"] and groupName == "player" and UnitLevel(groupName) == CO.UNIT_MAXLEVEL) then
							frame:Hide()
					else
						frame:Show()
					end
				end
			end
	end
end

local function UpdateUFAuraBars(groupName)
	if not CO.db.profile.auras.units[groupName] then return end
	
	local profileData = CO.db.profile.auras.units[groupName].aurabars
	local BA = E:GetModule("Bar_Auras")
	
	local F = BA.Bars[groupName]
	if not F then return end
	
	if profileData.enable == false then
		F:Hide()
		
		return
	else
		F:Show()
	end
	
	local FontObject, FontShadowColor, Flags
	local fonts = {"name", "time"}

	for i=1,BA.BAR_NUM do
		F[i]:SetSize(profileData.width, profileData.height)
		F[i].Bar.Overlay:SetSize(profileData.width, profileData.height)
		F[i].Bar.Border:SetSize(profileData.width, profileData.height)
		F[i].Bar.Background:SetSize(profileData.width, profileData.height)
		
		F[i].Bar.Background.Tex:SetColorTexture(profileData.backgroundColor[1], profileData.backgroundColor[2], profileData.backgroundColor[3], profileData.backgroundColor[4])
		
		E:MoveFrame(F[i], 0, (profileData.height + profileData.gapY) * (i - 1))
		
		F[i].Icon:SetSize(profileData.iconSize, profileData.iconSize)
		
		for _,v in pairs(fonts) do
			FontObject = F[i].Bar.Overlay[v]
			
			FontObject:ClearAllPoints()
			FontObject:SetPoint(profileData[format("%sFontPosition", v)])
			E:MoveFrame(FontObject, profileData[format("%sFontXOffset", v)], profileData[format("%sFontYOffset", v)])
			
			Flags = profileData[format("%sFontFlags", v)]
			if Flags == "None" then Flags = {} end
			
			-- (Frame, fontName, fontFlags, fontHeight, fontColor)
			E:SetFontInfo(FontObject, CO.Media:Fetch("font", profileData[format("%sFontType", v)]), Flags, profileData[format("%sFontHeight", v)], nil)
			E:UpdateFont(FontObject)
			
			FontShadowColor = profileData[format("%sFontShadowColor", v)]
			FontObject:SetShadowColor(FontShadowColor.r, FontShadowColor.g, FontShadowColor.b, FontShadowColor.a)
			FontObject:SetShadowOffset(profileData[format("%sXFontShadowOffset", v)], profileData[format("%sYFontShadowOffset", v)])
		end
	end
	
	BA:UpdateHeader(F)
end

local function UpdateUFPortrait(groupName)
	local profileData = CO.db.profile.unitframe.units[groupName].portrait
	local UF = E:GetModule("Unitframes")
	
	local frame, AddStr, NumToCreate
	
	AddStr			= ""
	NumToCreate 	= UF.ToCreate[groupName] or 1
	
	for i=1,NumToCreate do
		if NumToCreate ~= 1 then AddStr = i else AddStr = "" end
		frame = UF.Frames[groupName .. AddStr].Portrait
		
		if frame then
			if profileData.enable == false then
				frame:Hide()
			else
				frame:Show()
			end
		end
	end
end

local function UpdateUFGeneral(groupName)
	local profileData = CO.db.profile.unitframe.units[groupName]
	local UF = E:GetModule("Unitframes")
	
	if groupName == "raid" or groupName == "raid40" or groupName == "party" or groupName == "arena" or groupName == "boss" then
		if UF:GetHolder(groupName) then
			UF:LoadHolderConfig(groupName)
		end
	end
end

local function GetOptionsTable_General(groupName)
	
	local config = {
		order = 100,
		type = 'group',
		name = "General",
		get = function(info) return CO.db.profile.unitframe.units[groupName][ info[#info] ] end,
		set = function(info, value) CO.db.profile.unitframe.units[groupName][ info[#info] ] = value; UpdateUFGeneral(groupName) end,
		args = {
			generalHeader = {
				type = "header",
				name = "Positioning",
				order = 1,
			},
			position = {
				type = 'select',
				order = 10,
				name = "Position",
				desc = "Repositions this frame to a specific corner of your screen. Keep in mind your offsets when wondering where they went!",
				values = E.Positions,
				get = function(info)
					return CO.db.profile.movers[CO.UF:GetUFMover(groupName):GetName()]["point"]
				end,
				set = function(info, value)
					local MoverName = CO.UF:GetUFMover(groupName):GetName()
						CO.db.profile.movers[MoverName]["point"] = value
						E:LoadMoverPositions(MoverName)
				end,
			},
			xOffset = {
				order = 11,
				type = 'range',
				name = "X Offset",
				desc = "Moves this frame along the X axis [horizontal]",
				min = -1920, max = 1920, step = 1,
				get = function(info)
					return CO.db.profile.movers[CO.UF:GetUFMover(groupName):GetName()]["xOffset"]
				end,
				set = function(info, value)
					local MoverName = CO.UF:GetUFMover(groupName):GetName()
						CO.db.profile.movers[MoverName]["xOffset"] = value
						E:LoadMoverPositions(MoverName)
				end,
			},
			yOffset = {
				order = 12,
				type = 'range',
				name = "Y Offset",
				desc = "Moves this frame along the Ý axis [vertical]",
				min = -1920, max = 1920, step = 1,
				get = function(info)
					return CO.db.profile.movers[CO.UF:GetUFMover(groupName):GetName()]["yOffset"]
				end,
				set = function(info, value)
					local MoverName = CO.UF:GetUFMover(groupName):GetName()
						CO.db.profile.movers[MoverName]["yOffset"] = value
						E:LoadMoverPositions(MoverName)
				end,
			},
		},
	}
	
		if groupName == "raid" or groupName == "raid40" or groupName == "party" or groupName == "arena" or groupName == "boss" then
			local extension = {
				groupHeader = {
					order = 50,
					type = "header",
					name = "Frame Cluster",
				},
				targetWrapWidth = {
					order = 51,
					type = 'range',
					name = "Total Width",
					desc = "Sets the max total width for the frame holder. This is to give you the freedom to sort those frames freely instead of a fixed row/column count.",
					width = "full", -- Feels better
					min = 1, max = 2000, step = 1,
				},
				sortGapX = {
					order = 55,
					type = 'range',
					name = "X Gap",
					desc = "Modifies the horizontal gap between each member of this cluster",
					width = "full", -- Feels better
					min = 0, max = 50, step = 1,
					get = function(info) return CO.db.profile.unitframe.units[groupName].sort.gapX end,
					set = function(info, value) CO.db.profile.unitframe.units[groupName].sort.gapX = value; UpdateUFGeneral(groupName) end,
				},
				sortGapY = {
					order = 56,
					type = 'range',
					name = "Y Gap",
					desc = "Modifies the vertical gap between each member of this cluster",
					width = "full", -- Feels better
					min = 0, max = 50, step = 1,
					get = function(info) return CO.db.profile.unitframe.units[groupName].sort.gapY end,
					set = function(info, value) CO.db.profile.unitframe.units[groupName].sort.gapY = value; UpdateUFGeneral(groupName) end,
				},
				sortDirectionHorizontal = {
					type = 'select',
					order = 57,
					name = "Horizontal Direction",
					desc = "Horizontal Direction will be done first.",
					values = sortDirectionsHorizontal,
					get = function(info) return CO.db.profile.unitframe.units[groupName].sort.directionHorizontal end,
					set = function(info, value) CO.db.profile.unitframe.units[groupName].sort.directionHorizontal = value; UpdateUFGeneral(groupName) end,
				},
				sortDirectionVertical = {
					type = 'select',
					order = 58,
					name = "Vertical Direction",
					desc = "Horizontal Direction will be done first.",
					values = sortDirectionsVertical,
					get = function(info) return CO.db.profile.unitframe.units[groupName].sort.directionVertical end,
					set = function(info, value) CO.db.profile.unitframe.units[groupName].sort.directionVertical = value; UpdateUFGeneral(groupName) end,
				},
				visibilityCondition = {
					order = 59,
					type = 'input',
					name = "Visibility",
					desc = "A string of macro conditionals to determine, whether the cluster should be displayed.\nSome possible values:\n[group:party] [group:raid] [combat] [vehicle] [flying] [form:N] [stealth]\n\nFind more at https://wow.gamepedia.com/Macro_conditionals",
					width = "full",
				},
				defaultVisibility = {
					order = 60,
					type = "execute",
					name = "Default Visiblity",
					desc = "In case you want to reset the visiblity string to default",
					func = function()
						CO.db.profile.unitframe.units[groupName].visibilityCondition = E.ConfigDefaults.profile.unitframe.units[groupName].visibilityCondition
						UpdateUFGeneral(groupName)
					end,
				},
			}
			
			for k,v in pairs(extension) do
				config.args[k] = v
			end
		end
	
	

	return config
end

local function GetOptionsTable_HealthBar(groupName)
	
	local config = {
		order = 101,
		type = 'group',
		name = "Bar Health",
		get = function(info) return CO.db.profile.unitframe.units[groupName][ info[#info] ] end,
		set = function(info, value) CO.db.profile.unitframe.units[groupName][ info[#info] ] = value; CO.UF:LoadProfile(); CO.UF:LoadHolderConfig(groupName) end,
		args = {
			healthWidth = {
				order = 10,
				type = 'range',
				name = "Width",
				desc = "Width",
				min = 1, max = 800, step = 1,
			},
			healthHeight = {
				order = 11,
				type = 'range',
				name = "Height",
				desc = "Height",
				min = 1, max = 800, step = 1,
			},
			barBorderSize = {
				order = 12,
				type = 'range',
				name = "Border Size",
				min = -20, max = 20, step = 1,
				get = function(info) return CO.db.profile.unitframe.units[groupName].health.barBorderSize end,
				set = function(info, value) CO.db.profile.unitframe.units[groupName].health.barBorderSize = value; CO.UF:LoadProfile() end,
			},
			barBorderColor = {
				order = 13,
				type = 'color',
				name = "Border Color",
				hasAlpha = true,
				get = function(info)
					local c = CO.db.profile.unitframe.units[groupName].health.barBorderColor
					return c[1], c[2], c[3]
				end,
				set = function(info, r, g, b, a)
					local c = CO.db.profile.unitframe.units[groupName].health.barBorderColor
					c[1], c[2], c[3], c[4] = r, g, b, a
					
					CO.UF:LoadProfile()
				end,
			},
			barBackgroundColor = {
				order = 14,
				type = 'color',
				name = "Background Color",
				hasAlpha = true,
				get = function(info)
					local c = CO.db.profile.unitframe.units[groupName].health.barBackgroundColor
					return c[1], c[2], c[3]
				end,
				set = function(info, r, g, b, a)
					local c = CO.db.profile.unitframe.units[groupName].health.barBackgroundColor
					c[1], c[2], c[3], c[4] = r, g, b, a
					
					CO.UF:LoadProfile()
				end,
			},
			barSystemHeader = {
				type = "header",
				order = 20,
				name = "Bar System",
			},
			barInverseFill = {
				order = 21,
				type = "toggle",
				name = "Bar Inverse Fill",
				get = function(info) return CO.db.profile.unitframe.units[groupName].health.barInverseFill end,
				set = function(info, value) CO.db.profile.unitframe.units[groupName].health.barInverseFill = value; CO.UF:LoadProfile() end,
			},
			barOrientation = {
				type = 'select',
				order = 22,
				name = "Fill Direction",
				desc = "How the bar should be filled. Vertical or Horizontal.",
				values = sortBarOrientation,
				get = function(info) return CO.db.profile.unitframe.units[groupName].health.barOrientation end,
				set = function(info, value) CO.db.profile.unitframe.units[groupName].health.barOrientation = value; CO.UF:LoadProfile() end,
			},
		},
	}

	return config
end

local function GetOptionsTable_PowerBar(groupName)
	
	local config = {
		order = 102,
		type = 'group',
		name = "Bar Power",
		get = function(info) return CO.db.profile.unitframe.units[groupName].power[ info[#info] ] end,
		set = function(info, value) CO.db.profile.unitframe.units[groupName].power[ info[#info] ] = value; CO.UF:LoadProfile(); CO.UF:LoadHolderConfig(groupName) end,
		args = {
			barWidth = {
				order = 10,
				type = 'range',
				name = "Width",
				desc = "Width",
				min = 1, max = 800, step = 1,
			},
			barHeight = {
				order = 11,
				type = 'range',
				name = "Height",
				desc = "Height",
				min = 1, max = 800, step = 1,
			},
			barPosition = {
				type = 'select',
				order = 12,
				name = "Position",
				values = positionValues,
			},
			barXOffset = {
				order = 13,
				type = 'range',
				name = "X Offset",
				desc = "X Offset",
				min = -300, max = 300, step = 1,
			},
			barYOffset = {
				order = 14,
				type = 'range',
				name = "Y Offset",
				desc = "Y Offset",
				min = -300, max = 300, step = 1,
			},
			barBorderSize = {
				order = 15,
				type = 'range',
				name = "Border Size",
				min = -20, max = 20, step = 1,
			},
			barBorderColor = {
				order = 16,
				type = 'color',
				name = "Border Color",
				hasAlpha = true,
				get = function(info)
					local c = CO.db.profile.unitframe.units[groupName].power.barBorderColor
					return c[1], c[2], c[3]
				end,
				set = function(info, r, g, b, a)
					local c = CO.db.profile.unitframe.units[groupName].power.barBorderColor
					c[1], c[2], c[3], c[4] = r, g, b, a
					
					CO.UF:LoadProfile()
				end,
			},
			barBackgroundColor = {
				order = 17,
				type = 'color',
				name = "Background Color",
				hasAlpha = true,
				get = function(info)
					local c = CO.db.profile.unitframe.units[groupName].power.barBackgroundColor
					return c[1], c[2], c[3]
				end,
				set = function(info, r, g, b, a)
					local c = CO.db.profile.unitframe.units[groupName].power.barBackgroundColor
					c[1], c[2], c[3], c[4] = r, g, b, a
					
					CO.UF:LoadProfile()
				end,
			},
			barSystemHeader = {
				type = "header",
				order = 20,
				name = "Bar System",
			},
			barInverseFill = {
				order = 21,
				type = "toggle",
				name = "Bar Inverse Fill",
			},
			barOrientation = {
				type = 'select',
				order = 22,
				name = "Fill Direction",
				desc = "How the bar should be filled. Vertical or Horizontal.",
				values = sortBarOrientation,
			},
		},
	}

	return config
end

local function GetOptionsTable_MaxLevel(groupName, tableType)
	local doNotShowOnMaxLevel
	
	if tableType == "level" then
		doNotShowOnMaxLevel = {
			type = "toggle",
			order = 2,
			name = "Nicht bei Maximallevel",
		}
	end
	
	return doNotShowOnMaxLevel
end



-- tableType such as "name", "level" or "power" . . . .
local function GetOptionsTable_Text(groupName, tableType)
	
	local config = {
		order = 100,
		type = 'group',
		name = E:firstToUpper(tableType),
		get = function(info) return CO.db.profile.unitframe.units[groupName][tableType][ info[#info] ] end,
		set = function(info, value) CO.db.profile.unitframe.units[groupName][tableType][ info[#info] ] = value; UpdateUFText(groupName, tableType) end,
		args = {
			enable = {
				type = "toggle",
				order = 2,
				name = L["Enable"],
				width = "full",
			},
			width = {
				order = 3,
				type = 'range',
				name = "Width",
				desc = "Width",
				min = 0, max = 500, step = 1,
				disabled = function() return not CO.db.profile.unitframe.units[groupName][tableType]["enable"] end,
			},
			positionHeader = {
				order = 30,
				type = "header",
				name = "Positioning",
			},
			position = {
				type = 'select',
				order = 31,
				name = "Position",
				values = positionValues,
				disabled = function() return not CO.db.profile.unitframe.units[groupName][tableType]["enable"] end,
			},
			xOffset = {
				order = 32,
				type = 'range',
				name = "X Offset",
				desc = "X Offset",
				min = -300, max = 300, step = 1,
				disabled = function() return not CO.db.profile.unitframe.units[groupName][tableType]["enable"] end,
			},
			yOffset = {
				order = 33,
				type = 'range',
				name = "Y Offset",
				desc = "Y Offset",
				min = -300, max = 300, step = 1,
				disabled = function() return not CO.db.profile.unitframe.units[groupName][tableType]["enable"] end,
			},
			horizontalAlign = {
				name = L["HorizontalAlign"],
				type = "select",
				desc = "Sets the horizontal growth direction of this font. Left sets the growth to right. Right sets it to left. Just like in any text-processing program. To reposition the font, use the position dropdown.",
				order = 34,
				-- style = "dropdown",
				values = CO.FontHorizontalAlign,
				disabled = function() return not CO.db.profile.unitframe.units[groupName][tableType]["enable"] end,
			},
			styleHeader = {
				order = 40,
				type = "header",
				name = "Font Style",
			},
			fontHeight = {
				order = 41,
				type = 'range',
				name = "Font height",
				desc = "Font height",
				min = 3, max = 90, step = 1,
				disabled = function() return not CO.db.profile.unitframe.units[groupName][tableType]["enable"] end,
			},
			fontType = {
			  name = "Font Type",
			  dialogControl = "LSM30_Font",
			  type = "select",
			  desc = "Font Type",
			  order = 42,
			  -- style = "dropdown",
			  values = CO.AceGUIWidgetLSMlists["font"],
			  disabled = function() return not CO.db.profile.unitframe.units[groupName][tableType]["enable"] end,
			},
			fontFlags = {
			  name = "Font Flags",
			  type = "select",
			  desc = "Font Flags",
			  order = 43,
			  -- style = "dropdown",
			  values = CO.FontFlags,
			  disabled = function() return not CO.db.profile.unitframe.units[groupName][tableType]["enable"] end,
			},
			shadowHeader = {
				order = 50,
				type = "header",
				name = "Text Shadow",
			},
			fontShadowColor = {
			  name = "Shadow color",
			  type = "color",
			  hasAlpha = true,
			  desc = "Shadow color",
			  order = 51,
			  -- style = "dropdown",
			  get = function(info)
					local c = CO.db.profile.unitframe.units[groupName][tableType]["fontShadowColor"]
					return c.r, c.g, c.b, c.a
			  end,
			  set = function(info, r, g, b, a)
					local color = CO.db.profile.unitframe.units[groupName][tableType]["fontShadowColor"]
					color.r, color.g, color.b, color.a = r, g, b, a
					UpdateUFText(groupName, tableType)
			  end,
			  disabled = function() return not CO.db.profile.unitframe.units[groupName][tableType]["enable"] end,
			},
			xFontShadowOffset = {
				order = 52,
				type = 'range',
				name = "X Offset",
				desc = "X Offset",
				min = -10, max = 10, step = 1,
				disabled = function() return not CO.db.profile.unitframe.units[groupName][tableType]["enable"] end,
			},
			yFontShadowOffset = {
				order = 53,
				type = 'range',
				name = "Y Offset",
				desc = "Y Offset",
				min = -10, max = 10, step = 1,
				disabled = function() return not CO.db.profile.unitframe.units[groupName][tableType]["enable"] end,
			},
			doNotShowOnMaxLevel = GetOptionsTable_MaxLevel(groupName, tableType),
		},
	}
		-- Additional options for specific types
		if tableType == "health" or tableType == "level" then
			local extension = {
				fontColor = {
				name = "Font Color",
				type = "color",
				hasAlpha = true,
				order = 45,
				get = function(info)
						local c = CO.db.profile.unitframe.units[groupName][tableType]["fontColor"]
						return c[1], c[2], c[3], c[4]
				end,
				set = function(info, r, g, b, a)
						local color = CO.db.profile.unitframe.units[groupName][tableType]["fontColor"]
						color[1], color[2], color[3], color[4] = r, g, b, a
						CO.UF:LoadProfile()
				end,
				disabled = function() return not CO.db.profile.unitframe.units[groupName][tableType]["enable"] end,
				},
			}
			
			for k,v in pairs(extension) do
				config.args[k] = v
			end
		end

	return config
end


local function UpdateAllBarTextures()
	for k, v in pairs(E.StatusBars) do
		if v:GetAttribute("ReceivesGlobalTexture") ~= false then
			v:SetStatusBarTexture(CO.Media:Fetch("statusbar", CO.db.profile.unitframe.units["all"]['barTexture']))
		end
	end
end

local function GetOptionsTable_BarTexture(index)
	local groupName = "all"

	local barTexture = {
		type = "select", dialogControl = 'LSM30_Statusbar',
		order = index,
		name = "StatusBar Texture",
		desc = "Main statusbar texture.",
		values = CO.AceGUIWidgetLSMlists["statusbar"],
		get = function(info) return CO.db.profile.unitframe.units[groupName]['barTexture'] end,
		set = function(info, value) CO.db.profile.unitframe.units[groupName]['barTexture'] = value; UpdateAllBarTextures() end,
	}

	return barTexture
end

local function GetOptionsTable_ReactionColors(reaction, index)
	local reactionColor = {
	  name = E:firstToUpper(reaction),
	  type = "color",
	  hasAlpha = false,
	  desc = "Modifies the reaction/unit color of " .. reaction .. " units.",
	  order = index,
	  get = function(info)
			local c = CO.db.profile.unitframe.units.all.reactionColors[reaction]
			return c[1], c[2], c[3]
	  end,
	  set = function(info, r, g, b, a)
			local c = CO.db.profile.unitframe.units.all.reactionColors[reaction]
			c[1], c[2], c[3] = r, g, b
			
			CO.UF:UpdateAllUF()
	  end,
	}

	return reactionColor
end

local function GetOptionsTable_Portrait(groupName)
	local config = {
		order = -1,
		type = 'group',
		name = "Portrait",
		get = function(info) return CO.db.profile.unitframe.units[groupName].portrait[ info[#info] ] end,
		set = function(info, value) CO.db.profile.unitframe.units[groupName].portrait[ info[#info] ]  = value; UpdateUFPortrait(groupName) end,
		args = {
			header = {
				order = 1,
				type = "header",
				name = "Portrait",
			},
			enable = {
				type = "toggle",
				order = 2,
				name = L["Enable"],
				width = "full",
			},
			alpha = {
				order = 3,
				type = 'range',
				name = "Alpha",
				min = 0, max = 1, step = 0.01,
				disabled = function() return not CO.db.profile.unitframe.units[groupName].portrait.enable end,
				set = function(info, value) CO.db.profile.unitframe.units[groupName].portrait.alpha = value; CO.UF:LoadProfile() end,
			},
		},
	}

	return config
end

local function GetOptionsTable_AuraBarsText(groupName, type, index)
	local config = {
		[format("Bar%sHeader", type)] = {
			order = index,
			type = "header",
			name = format("|cffbc1a32%s Font Settings|r", E:firstToUpper(type)),
		},
		[format("%sFontPosition", type)] = {
			type = 'select',
			order = index + 1,
			name = "Position",
			values = positionValues,
			disabled = function() return not CO.db.profile.auras.units[groupName].aurabars["enable"] end,
		},
		
		[format("%sFontXOffset", type)] = {
			order = index + 2,
			type = 'range',
			name = "X Offset",
			desc = "X Offset",
			min = -300, max = 300, step = 1,
			disabled = function() return not CO.db.profile.auras.units[groupName].aurabars["enable"] end,
		},
		[format("%sFontYOffset", type)] = {
			order = index + 3,
			type = 'range',
			name = "Y Offset",
			desc = "Y Offset",
			min = -300, max = 300, step = 1,
			disabled = function() return not CO.db.profile.auras.units[groupName].aurabars["enable"] end,
		},
		[format("%sFontHeight", type)] = {
			order = index + 4,
			type = 'range',
			name = "Font height",
			desc = "Font height",
			min = 3, max = 90, step = 1,
			disabled = function() return not CO.db.profile.auras.units[groupName].aurabars["enable"] end,
		},
		[format("%sFontType", type)] = {
		  name = "Font Type",
		  dialogControl = "LSM30_Font",
		  type = "select",
		  desc = "Font Type",
		  order = index + 5,
		  values = CO.AceGUIWidgetLSMlists["font"],
		  disabled = function() return not CO.db.profile.auras.units[groupName].aurabars["enable"] end,
		},
		[format("%sFontFlags", type)] = {
		  name = "Font Flags",
		  type = "select",
		  desc = "Font Flags",
		  order = index + 6,
		  values = CO.FontFlags,
		  disabled = function() return not CO.db.profile.auras.units[groupName].aurabars["enable"] end,
		},
		[format("%sFontShadowColor", type)] = {
		  name = "Shadow color",
		  type = "color",
		  hasAlpha = true,
		  desc = "Shadow color",
		  order = index + 7,
		  get = function(info)
				local c = CO.db.profile.auras.units[groupName].aurabars[type .. "FontShadowColor"]
				return c.r, c.g, c.b, c.a
		  end,
		  set = function(info, r, g, b, a)
				local color = CO.db.profile.auras.units[groupName].aurabars[type .. "FontShadowColor"]
				color.r, color.g, color.b, color.a = r, g, b, a
				
				UpdateUFAuraBars(groupName)
		  end,
		  disabled = function() return not CO.db.profile.auras.units[groupName].aurabars["enable"] end,
		},
		[format("%sXFontShadowOffset", type)] = {
			order = index + 8,
			type = 'range',
			name = "X Offset",
			desc = "X Offset",
			min = -10, max = 10, step = 1,
			disabled = function() return not CO.db.profile.auras.units[groupName].aurabars["enable"] end,
		},
		[format("%sYFontShadowOffset", type)] = {
			order = index + 9,
			type = 'range',
			name = "Y Offset",
			desc = "Y Offset",
			min = -10, max = 10, step = 1,
			disabled = function() return not CO.db.profile.auras.units[groupName].aurabars["enable"] end,
		},
	}

	return config
end

local function GetOptionsTable_AuraBars(groupName)
	local config = {
		order = -1,
		type = 'group',
		name = "Aura Bars",
		get = function(info) return CO.db.profile.auras.units[groupName].aurabars[ info[#info] ] end,
		set = function(info, value) CO.db.profile.auras.units[groupName].aurabars[ info[#info] ]  = value; UpdateUFAuraBars(groupName) end,
		args = {
			header = {
				order = 1,
				type = "header",
				name = "General",
			},
			enable = {
				type = "toggle",
				order = 2,
				name = L["Enable"],
			},
			toggle = {
				order = 3,
				type = "execute",
				name = "Toggle",
				func = function()
					local BA = E:GetModule("Bar_Auras")
					BA:ToggleBars(groupName)
				end,
				disabled = function() return not CO.db.profile.auras.units[groupName].aurabars["enable"] end,
			},
			BarHeader = {
				order = 4,
				type = "header",
				name = "Bar Settings",
			},
			width = {
				order = 5,
				type = 'range',
				name = "Width",
				desc = "Width",
				min = 1, max = 750, step = 1,
				disabled = function() return not CO.db.profile.auras.units[groupName].aurabars["enable"] end,
			},
			height = {
				order = 6,
				type = 'range',
				name = "Height",
				desc = "Height",
				min = 1, max = 125, step = 1,
				disabled = function() return not CO.db.profile.auras.units[groupName].aurabars["enable"] end,
			},
			gapY = {
				order = 7,
				type = 'range',
				name = "Gap Y",
				min = 0, max = 100, step = 1,
				desc = "Gap Y",
				disabled = function() return not CO.db.profile.auras.units[groupName].aurabars["enable"] end,
			},
			iconSize = {
				order = 8,
				type = 'range',
				name = "Icon Size",
				min = 1, max = 128, step = 1,
				desc = "Icon Size",
				disabled = function() return not CO.db.profile.auras.units[groupName].aurabars["enable"] end,
			},
			backgroundColor = {
				name = "Background Color",
				type = "color",
				hasAlpha = true,
				order = 9,
				get = function(info)
					local c = CO.db.profile.auras.units[groupName].aurabars.backgroundColor
					return c[1], c[2], c[3], c[4]
				end,
				set = function(info, r, g, b, a)
					local c = CO.db.profile.auras.units[groupName].aurabars.backgroundColor
					c[1], c[2], c[3], c[4] = r, g, b, a
					
					UpdateUFAuraBars(groupName)
				end,
				disabled = function() return not CO.db.profile.auras.units[groupName].aurabars["enable"] end,
			},
			
			
			-- timeFont = unpack(GetOptionsTable_AuraBarsText(groupName, "name", 50)),
			
		},
	}
	
	local nameText = GetOptionsTable_AuraBarsText(groupName, "name", 10)
	local timeText = GetOptionsTable_AuraBarsText(groupName, "time", 50)
	for k,v in pairs(nameText) do
		config.args[k] = v
	end
	for k,v in pairs(timeText) do
		config.args[k] = v
	end
	
	
	
	return config
end

CO.Options.args.unitframe = {
	name = L["Unitframes"],
	type = 'group',
	order = 300,
	disabled = false,
	args = {
		header = {
			order = 1,
			type = "header",
			name = "Dummy Mode",
		},
		partyDummy = {
			order = 2,
			type = "execute",
			name = "Enable",
			width = "full",
			func = function()
				local UF = E:GetModule("Unitframes")
				if DummyMode == false then
					UF:SetUnitDummys(true)
					DummyMode = true
					CO.Options.args.unitframe.args.partyDummy.name = "Disable"
				else
					UF:SetUnitDummys(false)
					DummyMode = false
					CO.Options.args.unitframe.args.partyDummy.name = "Enable"
				end
			end,
		}
	},
}

CO.Options.args.unitframe.args.all = {
	name = L["All"],
	type = 'group',
	order = 1,
	childGroups = "tab",
	disabled = false,
	args = {
		textureHeader = {
			type = "header",
			name = "Bar Textures",
			order = 1,
		},
		barTexture = GetOptionsTable_BarTexture(2),
		
		textureHeader = {
			type = "header",
			name = "Reaction Colors",
			order = 3,
		},
		colorFriendly = GetOptionsTable_ReactionColors("friendly", 4),
		colorNeutral = GetOptionsTable_ReactionColors("neutral", 5),
		colorUnfriendly = GetOptionsTable_ReactionColors("unfriendly", 6),
		colorFHostile = GetOptionsTable_ReactionColors("hostile", 7),
	},
}
CO.Options.args.unitframe.args.player = {
	name = L["Player"],
	type = 'group',
	order = 2,
	childGroups = "tab",
	disabled = false,
	args = {
		generalGroup =  GetOptionsTable_General("player"),
		name = GetOptionsTable_Text("player", "name"),
		health = GetOptionsTable_Text("player", "health"),
		power = GetOptionsTable_Text("player", "power"),
		level = GetOptionsTable_Text("player", "level"),
		portrait = GetOptionsTable_Portrait("player"),
		aurabars = GetOptionsTable_AuraBars("player"),
		barHealth = GetOptionsTable_HealthBar("player"),
		barPower = GetOptionsTable_PowerBar("player"),
	},
	
}

CO.Options.args.unitframe.args.target = {
	name = L["Target"],
	type = 'group',
	order = 2,
	childGroups = "tab",
	disabled = false,
	args = {
		generalGroup =  GetOptionsTable_General("target"),
		name = GetOptionsTable_Text("target", "name"),
		health = GetOptionsTable_Text("target", "health"),
		power = GetOptionsTable_Text("target", "power"),
		level = GetOptionsTable_Text("target", "level"),
		portrait = GetOptionsTable_Portrait("target"),
		aurabars = GetOptionsTable_AuraBars("target"),
		barHealth = GetOptionsTable_HealthBar("target"),
		barPower = GetOptionsTable_PowerBar("target"),
	},
	
}

CO.Options.args.unitframe.args.pet = {
	name = L["Pet"],
	type = 'group',
	order = 2,
	childGroups = "tab",
	disabled = false,
	args = {
		generalGroup =  GetOptionsTable_General("pet"),
		name = GetOptionsTable_Text("pet", "name"),
		health = GetOptionsTable_Text("pet", "health"),
		power = GetOptionsTable_Text("pet", "power"),
		level = GetOptionsTable_Text("pet", "level"),
		portrait = GetOptionsTable_Portrait("pet"),
		barHealth = GetOptionsTable_HealthBar("pet"),
		barPower = GetOptionsTable_PowerBar("pet"),
	},
	
}

CO.Options.args.unitframe.args.targettarget = {
	name = L["TargetTarget"],
	type = 'group',
	order = 3,
	childGroups = "tab",
	disabled = false,
	args = {
		generalGroup =  GetOptionsTable_General("targettarget"),
		name = GetOptionsTable_Text("targettarget", "name"),
		health = GetOptionsTable_Text("targettarget", "health"),
		power = GetOptionsTable_Text("targettarget", "power"),
		level = GetOptionsTable_Text("targettarget", "level"),
		portrait = GetOptionsTable_Portrait("targettarget"),
		barHealth = GetOptionsTable_HealthBar("targettarget"),
		barPower = GetOptionsTable_PowerBar("targettarget"),
	},
	
}

CO.Options.args.unitframe.args.arena = {
	name = L["Arena"],
	type = 'group',
	order = 3,
	childGroups = "tab",
	disabled = false,
	args = {
		generalGroup =  GetOptionsTable_General("arena"),
		name = GetOptionsTable_Text("arena", "name"),
		health = GetOptionsTable_Text("arena", "health"),
		power = GetOptionsTable_Text("arena", "power"),
		level = GetOptionsTable_Text("arena", "level"),
		portrait = GetOptionsTable_Portrait("arena"),
		barHealth = GetOptionsTable_HealthBar("arena"),
		barPower = GetOptionsTable_PowerBar("arena"),
	},
	
}

CO.Options.args.unitframe.args.party = {
	name = L["Party"],
	type = 'group',
	order = 3,
	childGroups = "tab",
	disabled = false,
	args = {
		generalGroup =  GetOptionsTable_General("party"),
		name = GetOptionsTable_Text("party", "name"),
		health = GetOptionsTable_Text("party", "health"),
		power = GetOptionsTable_Text("party", "power"),
		level = GetOptionsTable_Text("party", "level"),
		portrait = GetOptionsTable_Portrait("party"),
		barHealth = GetOptionsTable_HealthBar("party"),
		barPower = GetOptionsTable_PowerBar("party"),
	},
	
}

CO.Options.args.unitframe.args.raid = {
	name = L["Raid"],
	type = 'group',
	order = 3,
	childGroups = "tab",
	disabled = false,
	args = {
		generalGroup = GetOptionsTable_General("raid"),
		name = GetOptionsTable_Text("raid", "name"),
		health = GetOptionsTable_Text("raid", "health"),
		power = GetOptionsTable_Text("raid", "power"),
		level = GetOptionsTable_Text("raid", "level"),
		portrait = GetOptionsTable_Portrait("raid"),
		barHealth = GetOptionsTable_HealthBar("raid"),
		barPower = GetOptionsTable_PowerBar("raid"),
	},
}

CO.Options.args.unitframe.args.raid40 = {
	name = L["Raid40"],
	type = 'group',
	order = 3,
	childGroups = "tab",
	disabled = false,
	args = {
		generalGroup = GetOptionsTable_General("raid40"),
		name = GetOptionsTable_Text("raid40", "name"),
		health = GetOptionsTable_Text("raid40", "health"),
		power = GetOptionsTable_Text("raid40", "power"),
		level = GetOptionsTable_Text("raid40", "level"),
		portrait = GetOptionsTable_Portrait("raid40"),
		barHealth = GetOptionsTable_HealthBar("raid40"),
		barPower = GetOptionsTable_PowerBar("raid40"),
	},
}

CO.Options.args.unitframe.args.boss = {
	name = L["Boss"],
	type = 'group',
	order = 3,
	childGroups = "tab",
	disabled = false,
	args = {
		generalGroup =  GetOptionsTable_General("boss"),
		name = GetOptionsTable_Text("boss", "name"),
		health = GetOptionsTable_Text("boss", "health"),
		power = GetOptionsTable_Text("boss", "power"),
		level = GetOptionsTable_Text("boss", "level"),
		portrait = GetOptionsTable_Portrait("boss"),
		barHealth = GetOptionsTable_HealthBar("boss"),
		barPower = GetOptionsTable_PowerBar("boss"),
	},
	
}

CO.Options.args.unitframe.args.focus = {
	name = L["Focus"],
	type = 'group',
	order = 4,
	childGroups = "tab",
	disabled = false,
	args = {
		generalGroup =  GetOptionsTable_General("focus"),
		name = GetOptionsTable_Text("focus", "name"),
		health = GetOptionsTable_Text("focus", "health"),
		power = GetOptionsTable_Text("focus", "power"),
		level = GetOptionsTable_Text("focus", "level"),
		portrait = GetOptionsTable_Portrait("focus"),
		barHealth = GetOptionsTable_HealthBar("focus"),
		barPower = GetOptionsTable_PowerBar("focus"),
	},
	
}

CO.Options.args.unitframe.args.focustarget = {
	name = L["FocusTarget"],
	type = 'group',
	order = 5,
	childGroups = "tab",
	disabled = false,
	args = {
		generalGroup =  GetOptionsTable_General("focustarget"),
		name = GetOptionsTable_Text("focustarget", "name"),
		health = GetOptionsTable_Text("focustarget", "health"),
		power = GetOptionsTable_Text("focustarget", "power"),
		level = GetOptionsTable_Text("focustarget", "level"),
		portrait = GetOptionsTable_Portrait("focustarget"),
		barHealth = GetOptionsTable_HealthBar("focustarget"),
		barPower = GetOptionsTable_PowerBar("focustarget"),
	},
	
}

function CO:UpdateAllGroups()
	
	for k,name in pairs(GroupNames) do
		for k,type in pairs(TextTypes) do
			UpdateUFText(name, type)
		end
		
		UpdateUFGeneral(name)
		UpdateUFPortrait(name)
	end
	
	UpdateUFAuraBars("player")
	UpdateUFAuraBars("target")
	
	UpdateAllBarTextures()
end