Omen 9.0 Changes
-----------------------------------------------------------------------------
-----------------------------------------------------------------------------
-- Addon declaration
-- Addon declaration
local Omen = LibStub("AceAddon-3.0"):NewAddon("Omen", "AceConsole-3.0", "AceEvent-3.0", "AceTimer-3.0", "LibSink-2.0")
local Omen = LibStub("AceAddon-3.0"):NewAddon("Omen", "AceConsole-3.0", "AceEvent-3.0", "AceTimer-3.0", "LibSink-2.0")
local L = LibStub("AceLocale-3.0"):GetLocale("Omen", false)
local L = LibStub("AceLocale-3.0"):GetLocale("Omen", false)
local LSM = LibStub("LibSharedMedia-3.0")
local LSM = LibStub("LibSharedMedia-3.0")
local LDB = LibStub("LibDataBroker-1.1", true)
local LDB = LibStub("LibDataBroker-1.1", true)
local LDBIcon = LDB and LibStub("LibDBIcon-1.0", true)
local LDBIcon = LDB and LibStub("LibDBIcon-1.0", true)
Omen.version = GetAddOnMetadata("Omen", "Version")
Omen.version = GetAddOnMetadata("Omen", "Version")
Omen.versionstring = "Omen v"..GetAddOnMetadata("Omen", "Version")
Omen.versionstring = "Omen v"..GetAddOnMetadata("Omen", "Version")
_G["Omen"] = Omen
_G["Omen"] = Omen
local WoWClassic = (WOW_PROJECT_ID == WOW_PROJECT_CLASSIC)
local WoWClassic = (WOW_PROJECT_ID == WOW_PROJECT_CLASSIC)
-----------------------------------------------------------------------------
-----------------------------------------------------------------------------
-- Keybinding globals
-- Keybinding globals
BINDING_HEADER_OMEN = Omen.versionstring
BINDING_HEADER_OMEN = Omen.versionstring
BINDING_NAME_OMENTOGGLE = L["Toggle Omen"]
BINDING_NAME_OMENTOGGLE = L["Toggle Omen"]
BINDING_NAME_OMENTOGGLEFOCUS = L["Toggle Focus"]
BINDING_NAME_OMENTOGGLEFOCUS = L["Toggle Focus"]
-----------------------------------------------------------------------------
-----------------------------------------------------------------------------
-- Register some media
-- Register some media
if WoWClassic then
if WoWClassic then
-- most of these sounds are nto actually in classic
-- most of these sounds are nto actually in classic
--LSM:Register("sound", "Rubber Ducky", [[Sound\Doodad\Goblin_Lottery_Open01.ogg]])
--LSM:Register("sound", "Rubber Ducky", [[Sound\Doodad\Goblin_Lottery_Open01.ogg]])
--LSM:Register("sound", "Cartoon FX", [[Sound\Doodad\Goblin_Lottery_Open03.ogg]])
--LSM:Register("sound", "Cartoon FX", [[Sound\Doodad\Goblin_Lottery_Open03.ogg]])
--LSM:Register("sound", "Explosion", [[Sound\Doodad\Hellfire_Raid_FX_Explosion05.ogg]])
--LSM:Register("sound", "Explosion", [[Sound\Doodad\Hellfire_Raid_FX_Explosion05.ogg]])
--LSM:Register("sound", "Shing!", [[Sound\Doodad\PortcullisActive_Closed.ogg]])
--LSM:Register("sound", "Shing!", [[Sound\Doodad\PortcullisActive_Closed.ogg]])
--LSM:Register("sound", "Wham!", [[Sound\Doodad\PVP_Lordaeron_Door_Open.ogg]])
--LSM:Register("sound", "Wham!", [[Sound\Doodad\PVP_Lordaeron_Door_Open.ogg]])
--LSM:Register("sound", "Simon Chime", [[Sound\Doodad\SimonGame_LargeBlueTree.ogg]])
--LSM:Register("sound", "Simon Chime", [[Sound\Doodad\SimonGame_LargeBlueTree.ogg]])
--LSM:Register("sound", "War Drums", [[Sound\Event Sounds\Event_wardrum_ogre.ogg]])
--LSM:Register("sound", "War Drums", [[Sound\Event Sounds\Event_wardrum_ogre.ogg]])
--LSM:Register("sound", "Cheer", [[Sound\Event Sounds\OgreEventCheerUnique.ogg]])
--LSM:Register("sound", "Cheer", [[Sound\Event Sounds\OgreEventCheerUnique.ogg]])
--LSM:Register("sound", "Humm", [[Sound\Spells\SimonGame_Visual_GameStart.ogg]])
--LSM:Register("sound", "Humm", [[Sound\Spells\SimonGame_Visual_GameStart.ogg]])
--LSM:Register("sound", "Short Circuit", [[Sound\Spells\SimonGame_Visual_BadPress.ogg]])
--LSM:Register("sound", "Short Circuit", [[Sound\Spells\SimonGame_Visual_BadPress.ogg]])
--LSM:Register("sound", "Fel Portal", [[Sound\Spells\Sunwell_Fel_PortalStand.ogg]])
--LSM:Register("sound", "Fel Portal", [[Sound\Spells\Sunwell_Fel_PortalStand.ogg]])
--LSM:Register("sound", "Fel Nova", [[Sound\Spells\SeepingGaseous_Fel_Nova.ogg]])
--LSM:Register("sound", "Fel Nova", [[Sound\Spells\SeepingGaseous_Fel_Nova.ogg]])
LSM:Register("sound", "You Will Die!", [[Sound\Creature\CThun\CThunYouWillDIe.ogg]])
LSM:Register("sound", "You Will Die!", [[Sound\Creature\CThun\CThunYouWillDIe.ogg]])
else
else
LSM:Register("sound", "Rubber Ducky", 566121) -- [[Sound\Doodad\Goblin_Lottery_Open01.ogg]]
LSM:Register("sound", "Rubber Ducky", 566121) -- [[Sound\Doodad\Goblin_Lottery_Open01.ogg]]
LSM:Register("sound", "Cartoon FX", 566543) --  [[Sound\Doodad\Goblin_Lottery_Open03.ogg]]
LSM:Register("sound", "Cartoon FX", 566543) --  [[Sound\Doodad\Goblin_Lottery_Open03.ogg]]
LSM:Register("sound", "Explosion", 566982) -- [[Sound\Doodad\Hellfire_Raid_FX_Explosion05.ogg]]
LSM:Register("sound", "Explosion", 566982) -- [[Sound\Doodad\Hellfire_Raid_FX_Explosion05.ogg]]
LSM:Register("sound", "Shing!", 566240) -- [[Sound\Doodad\PortcullisActive_Closed.ogg]]
LSM:Register("sound", "Shing!", 566240) -- [[Sound\Doodad\PortcullisActive_Closed.ogg]]
LSM:Register("sound", "Wham!", 566946) -- [[Sound\Doodad\PVP_Lordaeron_Door_Open.ogg]]
LSM:Register("sound", "Wham!", 566946) -- [[Sound\Doodad\PVP_Lordaeron_Door_Open.ogg]]
LSM:Register("sound", "Simon Chime", 566076) -- [[Sound\Doodad\SimonGame_LargeBlueTree.ogg]]
LSM:Register("sound", "Simon Chime", 566076) -- [[Sound\Doodad\SimonGame_LargeBlueTree.ogg]]
LSM:Register("sound", "War Drums", 567275) -- [[Sound\Event Sounds\Event_wardrum_ogre.ogg]]
LSM:Register("sound", "War Drums", 567275) -- [[Sound\Event Sounds\Event_wardrum_ogre.ogg]]
LSM:Register("sound", "Cheer", 567283) -- [[Sound\Event Sounds\OgreEventCheerUnique.ogg]]
LSM:Register("sound", "Cheer", 567283) -- [[Sound\Event Sounds\OgreEventCheerUnique.ogg]]
LSM:Register("sound", "Humm", 569518) -- [[Sound\Spells\SimonGame_Visual_GameStart.ogg]]
LSM:Register("sound", "Humm", 569518) -- [[Sound\Spells\SimonGame_Visual_GameStart.ogg]]
LSM:Register("sound", "Short Circuit", 568975) -- [[Sound\Spells\SimonGame_Visual_BadPress.ogg]]
LSM:Register("sound", "Short Circuit", 568975) -- [[Sound\Spells\SimonGame_Visual_BadPress.ogg]]
LSM:Register("sound", "Fel Portal", 569215) -- [[Sound\Spells\Sunwell_Fel_PortalStand.ogg]]
LSM:Register("sound", "Fel Portal", 569215) -- [[Sound\Spells\Sunwell_Fel_PortalStand.ogg]]
LSM:Register("sound", "Fel Nova", 568582) -- [[Sound\Spells\SeepingGaseous_Fel_Nova.ogg]]
LSM:Register("sound", "Fel Nova", 568582) -- [[Sound\Spells\SeepingGaseous_Fel_Nova.ogg]]
LSM:Register("sound", "You Will Die!", 546633) -- [[Sound\Creature\CThun\CThunYouWillDIe.ogg]]
LSM:Register("sound", "You Will Die!", 546633) -- [[Sound\Creature\CThun\CThunYouWillDIe.ogg]]
end
end
LSM:Register("sound", "Omen: Aoogah!", [[Interface\AddOns\Omen\aoogah.ogg]])
LSM:Register("sound", "Omen: Aoogah!", [[Interface\AddOns\Omen\aoogah.ogg]])
-----------------------------------------------------------------------------
-----------------------------------------------------------------------------
-- Localize some global functions
-- Localize some global functions
local floor, format, random, pairs, type = floor, format, random, pairs, type
local floor, format, random, pairs, type = floor, format, random, pairs, type
local tinsert, tremove, next, sort, wipe = tinsert, tremove, next, sort, wipe
local tinsert, tremove, next, sort, wipe = tinsert, tremove, next, sort, wipe
local RAID_CLASS_COLORS = RAID_CLASS_COLORS
local RAID_CLASS_COLORS = RAID_CLASS_COLORS
local UnitDetailedThreatSituation = UnitDetailedThreatSituation
local UnitDetailedThreatSituation = UnitDetailedThreatSituation
local UnitExists, UnitGUID, UnitName, UnitClass, UnitHealth = UnitExists, UnitGUID, UnitName, UnitClass, UnitHealth
local UnitExists, UnitGUID, UnitName, UnitClass, UnitHealth = UnitExists, UnitGUID, UnitName, UnitClass, UnitHealth
local UnitIsPlayer, UnitPlayerControlled, UnitCanAttack = UnitIsPlayer, UnitPlayerControlled, UnitCanAttack
local UnitIsPlayer, UnitPlayerControlled, UnitCanAttack = UnitIsPlayer, UnitPlayerControlled, UnitCanAttack
local IsInGroup, IsInRaid = IsInGroup, IsInRaid
local IsInGroup, IsInRaid = IsInGroup, IsInRaid
local GetNumGroupMembers, GetNumSubgroupMembers = GetNumGroupMembers, GetNumSubgroupMembers
local GetNumGroupMembers, GetNumSubgroupMembers = GetNumGroupMembers, GetNumSubgroupMembers
-----------------------------------------------------------------------------
-----------------------------------------------------------------------------
-- Local variables used
-- Local variables used
local db
local db
local function BarClassesFunc()
local function BarClassesFunc()
	local t = {}
	local t = {}
	for i, className in pairs(CLASS_SORT_ORDER) do
	for i, className in pairs(CLASS_SORT_ORDER) do
		t[className] = true
		t[className] = true
	end
	end
	t["PET"] = true
	t["PET"] = true
	t["*NOTINPARTY*"] = true
	t["*NOTINPARTY*"] = true
	return t
	return t
end
end
local defaults = {
local defaults = {
	profile = {
	profile = {
		Alpha        = 1,
		Alpha        = 1,
		Scale        = 1,
		Scale        = 1,
		GrowUp       = false,
		GrowUp       = false,
		Autocollapse = false,
		Autocollapse = false,
		NumBars      = 10,
		NumBars      = 10,
		CollapseHide = false,
		CollapseHide = false,
		Locked       = false,
		Locked       = false,
		PositionW    = 200,
		PositionW    = 200,
		PositionH    = 82,
		PositionH    = 82,
		VGrip1       = 85,
		VGrip1       = 85,
		VGrip2       = 115,
		VGrip2       = 115,
		UseFocus     = false,
		UseFocus     = false,
		IgnorePlayerPets = true,
		IgnorePlayerPets = true,
		FrameStrata = "3-MEDIUM",
		FrameStrata = "3-MEDIUM",
		ClampToScreen = true,
		ClampToScreen = true,
		ClickThrough = false,
		ClickThrough = false,
		Background = {
		Background = {
			Texture = "Blizzard Parchment",
			Texture = "Blizzard Parchment",
			BorderTexture = "Blizzard Dialog",
			BorderTexture = "Blizzard Dialog",
			Color = {r = 1, g = 1, b = 1, a = 1,},
			Color = {r = 1, g = 1, b = 1, a = 1,},
			BorderColor = {r = 0.8, g = 0.6, b = 0, a = 1,},
			BorderColor = {r = 0.8, g = 0.6, b = 0, a = 1,},
			Tile = false,
			Tile = false,
			TileSize = 32,
			TileSize = 32,
			EdgeSize = 8,
			EdgeSize = 8,
			BarInset = 3,
			BarInset = 3,
		},
		},
		TitleBar = {
		TitleBar = {
			Height = 16,
			Height = 16,
			Font = "Friz Quadrata TT",
			Font = "Friz Quadrata TT",
			FontOutline = "",
			FontOutline = "",
			FontColor = {r = 1, g = 1, b = 1, a = 1,},
			FontColor = {r = 1, g = 1, b = 1, a = 1,},
			FontSize = 10,
			FontSize = 10,
			ShowTitleBar = true,
			ShowTitleBar = true,
			UseSameBG = true,
			UseSameBG = true,
			Texture = "Blizzard Parchment",
			Texture = "Blizzard Parchment",
			BorderTexture = "Blizzard Dialog",
			BorderTexture = "Blizzard Dialog",
			Color = {r = 1, g = 1, b = 1, a = 1,},
			Color = {r = 1, g = 1, b = 1, a = 1,},
			BorderColor = {r = 0.8, g = 0.6, b = 0, a = 1,},
			BorderColor = {r = 0.8, g = 0.6, b = 0, a = 1,},
			Tile = false,
			Tile = false,
			TileSize = 32,
			TileSize = 32,
			EdgeSize = 8,
			EdgeSize = 8,
		},
		},
		Bar = {
		Bar = {
			Texture = "Blizzard",
			Texture = "Blizzard",
			Height = 12,
			Height = 12,
			Spacing = 0,
			Spacing = 0,
			AnimateBars  = true,
			AnimateBars  = true,
			ShortNumbers = true,
			ShortNumbers = true,
			Font = "Friz Quadrata TT",
			Font = "Friz Quadrata TT",
			FontOutline = "",
			FontOutline = "",
			FontColor = {r = 1, g = 1, b = 1, a = 1,},
			FontColor = {r = 1, g = 1, b = 1, a = 1,},
			FontSize = 10,
			FontSize = 10,
			Classes = BarClassesFunc(),
			Classes = BarClassesFunc(),
			ShowTPS = true,
			ShowTPS = true,
			TPSWindow = 10,
			TPSWindow = 10,
			ShowHeadings = true,
			ShowHeadings = true,
			HeadingBGColor = {r = 0, g = 0, b = 0, a = 0,},
			HeadingBGColor = {r = 0, g = 0, b = 0, a = 0,},
			UseMyBarColor = false,
			UseMyBarColor = false,
			MyBarColor = {r = 1, g = 0, b = 0, a = 1,},
			MyBarColor = {r = 1, g = 0, b = 0, a = 1,},
			ShowPercent = true,
			ShowPercent = true,
			ShowValue = true,
			ShowValue = true,
			UseClassColors = true,
			UseClassColors = true,
			BarColor = {r = 1, g = 0, b = 0, a = 1,},
			BarColor = {r = 1, g = 0, b = 0, a = 1,},
			UseTankBarColor = false,
			UseTankBarColor = false,
			TankBarColor = {r = 1, g = 0, b = 0, a = 1,},
			TankBarColor = {r = 1, g = 0, b = 0, a = 1,},
			AlwaysShowSelf = true,
			AlwaysShowSelf = true,
			ShowAggroBar = true,
			ShowAggroBar = true,
			AggroBarColor = {r = 1, g = 0, b = 0, a = 1,},
			AggroBarColor = {r = 1, g = 0, b = 0, a = 1,},
			PetBarColor = {r = 0.77, g = 0, b = 1, a = 1},
			PetBarColor = {r = 0.77, g = 0, b = 1, a = 1},
			FadeBarColor = {r = 0.5, g = 0.5, b = 0.5, a = 1},
			FadeBarColor = {r = 0.5, g = 0.5, b = 0.5, a = 1},
			UseCustomClassColors = true,
			UseCustomClassColors = true,
			InvertColors = false,
			InvertColors = false,
		},
		},
		ShowWith = {
		ShowWith = {
			UseShowWith = true,
			UseShowWith = true,
			Pet = true,
			Pet = true,
			Alone = false,
			Alone = false,
			Party = true,
			Party = true,
			Raid = true,
			Raid = true,
			-- Deprecated SV values
			-- Deprecated SV values
			-- Resting = false, PVP = false, Dungeon = true, ShowOnlyInCombat = false,
			-- Resting = false, PVP = false, Dungeon = true, ShowOnlyInCombat = false,
			HideWhileResting = true,
			HideWhileResting = true,
			HideInPVP = true,
			HideInPVP = true,
			HideWhenOOC = false,
			HideWhenOOC = false,
		},
		},
		FuBar = {
		FuBar = {
			HideMinimapButton = true,
			HideMinimapButton = true,
			AttachMinimap = false,
			AttachMinimap = false,
		},
		},
		Warnings = {
		Warnings = {
			Sound = true,
			Sound = true,
			Flash = true,
			Flash = true,
			Shake = false,
			Shake = false,
			Message = false,
			Message = false,
			SinkOptions = {},
			SinkOptions = {},
			Threshold = 90,
			Threshold = 90,
			SoundFile = "Fel Nova",
			SoundFile = "Fel Nova",
			SoundChannel = "SFX",
			SoundChannel = "SFX",
			DisableWhileTanking = true,
			DisableWhileTanking = true,
		},
		},
		MinimapIcon = {
		MinimapIcon = {
			hide = false,
			hide = false,
			minimapPos = 220,
			minimapPos = 220,
			radius = 80,
			radius = 80,
		},
		},
	},
	},
}
}
-- Posible sound channel options -- Cexikitin@ shadowmoon
-- Posible sound channel options -- Cexikitin@ shadowmoon
local SoundChannels = {
local SoundChannels = {
	["Master"] = L["Master"],
	["Master"] = L["Master"],
	["SFX"] = L["SFX"],
	["SFX"] = L["SFX"],
	["Ambience"] = L["Ambience"],
	["Ambience"] = L["Ambience"],
	["Music"] = L["Music"]
	["Music"] = L["Music"]
}
}
local guidNameLookup = {}   -- Format: guidNameLookup[guid] = "Unit Name"
local guidNameLookup = {}   -- Format: guidNameLookup[guid] = "Unit Name"
local guidClassLookup = {}  -- Format: guidClassLookup[guid] = "CLASS"
local guidClassLookup = {}  -- Format: guidClassLookup[guid] = "CLASS"
local timers = {}           -- Format: timers.timerName = timer returned from AceTimer-3.0
local timers = {}           -- Format: timers.timerName = timer returned from AceTimer-3.0
local bars = {}             -- Format: bars[i] = frame containing the i-th bar from the top of Omen
local bars = {}             -- Format: bars[i] = frame containing the i-th bar from the top of Omen
local inRaid, inParty       -- boolean variables indicating if the player is in a raid and/or party
local inRaid, inParty       -- boolean variables indicating if the player is in a raid and/or party
local testMode = false      -- boolean: Are we in test mode?
local testMode = false      -- boolean: Are we in test mode?
local manualToggle = false  -- boolean: Did we manually toggle Omen?
local manualToggle = false  -- boolean: Did we manually toggle Omen?
local moduleOptions = {}    -- Table for LoD module options registration
local moduleOptions = {}    -- Table for LoD module options registration
local LDBIconRegistered = false  -- Registered icon?
local LDBIconRegistered = false  -- Registered icon?
Omen.GuidNameLookup = guidNameLookup
Omen.GuidNameLookup = guidNameLookup
Omen.GuidClassLookup = guidClassLookup
Omen.GuidClassLookup = guidClassLookup
Omen.Timers = timers
Omen.Timers = timers
Omen.Bars = bars
Omen.Bars = bars
setmetatable(guidNameLookup, {__index = function(self, guid) return L["<Unknown>"] end})
setmetatable(guidNameLookup, {__index = function(self, guid) return L["<Unknown>"] end})
-- For speedups. Rather than concantenating every time we need a unitID, we just look
-- For speedups. Rather than concantenating every time we need a unitID, we just look
-- it up instead. That is rID[i] is much faster than format("raid%d", i) or "raid"..i
-- it up instead. That is rID[i] is much faster than format("raid%d", i) or "raid"..i
local pID = {}
local pID = {}
local ptID = {}
local ptID = {}
local ppID = {}
local ppID = {}
local pptID = {}
local pptID = {}
local rID = {}
local rID = {}
local rtID = {}
local rtID = {}
local rpID = {}
local rpID = {}
local rptID = {}
local rptID = {}
for i = 1, 4 do
for i = 1, 4 do
	pID[i] = format("party%d", i)
	pID[i] = format("party%d", i)
	ptID[i] = format("party%dtarget", i)
	ptID[i] = format("party%dtarget", i)
	ppID[i] = format("partypet%d", i)
	ppID[i] = format("partypet%d", i)
	pptID[i] = format("partypet%dtarget", i)
	pptID[i] = format("partypet%dtarget", i)
end
end
for i = 1, 40 do
for i = 1, 40 do
	rID[i] = format("raid%d", i)
	rID[i] = format("raid%d", i)
	rtID[i] = format("raid%dtarget", i)
	rtID[i] = format("raid%dtarget", i)
	rpID[i] = format("raidpet%d", i)
	rpID[i] = format("raidpet%d", i)
	rptID[i] = format("raidpet%dtarget", i)
	rptID[i] = format("raidpet%dtarget", i)
end
end
local showClassesOptionTable = {}
local showClassesOptionTable = {}
for i, className in pairs(CLASS_SORT_ORDER) do
for i, className in pairs(CLASS_SORT_ORDER) do
	showClassesOptionTable[className] = LOCALIZED_CLASS_NAMES_MALE[className]
	showClassesOptionTable[className] = LOCALIZED_CLASS_NAMES_MALE[className]
end
end
showClassesOptionTable["*NOTINPARTY*"] = L["*Not in Party*"]
showClassesOptionTable["*NOTINPARTY*"] = L["*Not in Party*"]
showClassesOptionTable["PET"] = L["PET"]
showClassesOptionTable["PET"] = L["PET"]
----------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------
-- Use a common frame and setup some common functions for the Omen dropdown menus
-- Use a common frame and setup some common functions for the Omen dropdown menus
local Omen_DropDownMenu = CreateFrame("Frame", "Omen_DropDownMenu")
local Omen_DropDownMenu = CreateFrame("Frame", "Omen_DropDownMenu")
Omen_DropDownMenu.displayMode = "MENU"
Omen_DropDownMenu.displayMode = "MENU"
Omen_DropDownMenu.info = {}
Omen_DropDownMenu.info = {}
Omen_DropDownMenu.HideMenu = function()
Omen_DropDownMenu.HideMenu = function()
	if UIDROPDOWNMENU_OPEN_MENU == Omen_DropDownMenu then
	if UIDROPDOWNMENU_OPEN_MENU == Omen_DropDownMenu then
		CloseDropDownMenus()
		CloseDropDownMenus()
	end
	end
end
end
Omen_DropDownMenu.OnClick = function(frame, button, down)
Omen_DropDownMenu.OnClick = function(frame, button, down)
	if Omen_DropDownMenu.initialize ~= frame.initMenuFunc then
	if Omen_DropDownMenu.initialize ~= frame.initMenuFunc then
		CloseDropDownMenus()
		CloseDropDownMenus()
		Omen_DropDownMenu.initialize = frame.initMenuFunc
		Omen_DropDownMenu.initialize = frame.initMenuFunc
	end
	end
	ToggleDropDownMenu(1, nil, Omen_DropDownMenu, frame, 0, 0)
	ToggleDropDownMenu(1, nil, Omen_DropDownMenu, frame, 0, 0)
end
end
-----------------------------------------------------------------------------
-----------------------------------------------------------------------------
-- Table Pool for recycling tables
-- Table Pool for recycling tables
local tablePool = {}
local tablePool = {}
setmetatable(tablePool, {__mode = "kv"}) -- Weak table
setmetatable(tablePool, {__mode = "kv"}) -- Weak table
-- Get a new table
-- Get a new table
local function newTable()
local function newTable()
	local t = next(tablePool) or {}
	local t = next(tablePool) or {}
	tablePool[t] = nil
	tablePool[t] = nil
	return t
	return t
end
end
-- Delete table and return to pool -- Recursive!! -- Use with care!!
-- Delete table and return to pool -- Recursive!! -- Use with care!!
local function delTable(t)
local function delTable(t)
	if type(t) == "table" then
	if type(t) == "table" then
		for k, v in pairs(t) do
		for k, v in pairs(t) do
			if type(v) == "table" then
			if type(v) == "table" then
				delTable(v) -- child tables get put into the pool
				delTable(v) -- child tables get put into the pool
			end
			end
			t[k] = nil
			t[k] = nil
		end
		end
		t[true] = true -- resize table to 1 item
		t[true] = true -- resize table to 1 item
		t[true] = nil
		t[true] = nil
		setmetatable(t, nil)
		setmetatable(t, nil)
		tablePool[t] = true
		tablePool[t] = true
	end
	end
	return nil -- return nil to assign input reference
	return nil -- return nil to assign input reference
end
end
-----------------------------------------------------------------------------
-----------------------------------------------------------------------------
-- Omen initialization and frame functions
-- Omen initialization and frame functions
local function startmoving(self)
local function startmoving(self)
	if not db.Locked then
	if not db.Locked then
		Omen.Anchor.IsMovingOrSizing = 1
		Omen.Anchor.IsMovingOrSizing = 1
		Omen.Anchor:StartMoving()
		Omen.Anchor:StartMoving()
	end
	end
end
end
local function stopmoving(self)
local function stopmoving(self)
	if Omen.Anchor.IsMovingOrSizing then
	if Omen.Anchor.IsMovingOrSizing then
		Omen.Anchor:StopMovingOrSizing()
		Omen.Anchor:StopMovingOrSizing()
		Omen:SetAnchors()
		Omen:SetAnchors()
		Omen:UpdateBars()
		Omen:UpdateBars()
		Omen.Anchor.IsMovingOrSizing = nil
		Omen.Anchor.IsMovingOrSizing = nil
	end
	end
	if self == Omen.Anchor then db.Shown = self:IsShown() end
	if self == Omen.Anchor then db.Shown = self:IsShown() end
end
end
local function sizing(self)
local function sizing(self)
	local w = Omen.Anchor:GetWidth()
	local w = Omen.Anchor:GetWidth()
	db.VGrip1 = w * Omen.Anchor.VGrip1Ratio
	db.VGrip1 = w * Omen.Anchor.VGrip1Ratio
	db.VGrip2 = w * Omen.Anchor.VGrip2Ratio
	db.VGrip2 = w * Omen.Anchor.VGrip2Ratio
	if db.VGrip1 < 10 then db.VGrip1 = 10 end
	if db.VGrip1 < 10 then db.VGrip1 = 10 end
	if db.VGrip1 > w - 10 then db.VGrip1 = w - 10 end
	if db.VGrip1 > w - 10 then db.VGrip1 = w - 10 end
	if db.Bar.ShowTPS then
	if db.Bar.ShowTPS then
		if db.VGrip2 < db.VGrip1 + 10 then db.VGrip2 = db.VGrip1 + 10 end
		if db.VGrip2 < db.VGrip1 + 10 then db.VGrip2 = db.VGrip1 + 10 end
		if db.VGrip1 > w - 20 then
		if db.VGrip1 > w - 20 then
			db.VGrip1 = w - 20
			db.VGrip1 = w - 20
			db.VGrip2 = w - 10
			db.VGrip2 = w - 10
		end
		end
		Omen.VGrip2:ClearAllPoints()
		Omen.VGrip2:ClearAllPoints()
		Omen.VGrip2:SetPoint("TOPLEFT", Omen.BarList, "TOPLEFT", db.VGrip2, 0)
		Omen.VGrip2:SetPoint("TOPLEFT", Omen.BarList, "TOPLEFT", db.VGrip2, 0)
		Omen.VGrip2:SetPoint("BOTTOMLEFT", Omen.BarList, "BOTTOMLEFT", db.VGrip2, 0)
		Omen.VGrip2:SetPoint("BOTTOMLEFT", Omen.BarList, "BOTTOMLEFT", db.VGrip2, 0)
	end
	end
	Omen.VGrip1:ClearAllPoints()
	Omen.VGrip1:ClearAllPoints()
	Omen.VGrip1:SetPoint("TOPLEFT", Omen.BarList, "TOPLEFT", db.VGrip1, 0)
	Omen.VGrip1:SetPoint("TOPLEFT", Omen.BarList, "TOPLEFT", db.VGrip1, 0)
	Omen.VGrip1:SetPoint("BOTTOMLEFT", Omen.BarList, "BOTTOMLEFT", db.VGrip1, 0)
	Omen.VGrip1:SetPoint("BOTTOMLEFT", Omen.BarList, "BOTTOMLEFT", db.VGrip1, 0)
	Omen:ResizeBars()
	Omen:ResizeBars()
	Omen:ReAnchorLabels()
	Omen:ReAnchorLabels()
	Omen:UpdateBars()
	Omen:UpdateBars()
end
end
local function movegrip1(self)
local function movegrip1(self)
	local x = GetCursorPosition() / UIParent:GetEffectiveScale() / Omen.Anchor:GetScale()
	local x = GetCursorPosition() / UIParent:GetEffectiveScale() / Omen.Anchor:GetScale()
	local x1 = Omen.Anchor:GetLeft() + 10
	local x1 = Omen.Anchor:GetLeft() + 10
	local x2 = db.Bar.ShowTPS and Omen.Anchor:GetLeft() + db.VGrip2 - 10 or Omen.Anchor:GetRight() - 10
	local x2 = db.Bar.ShowTPS and Omen.Anchor:GetLeft() + db.VGrip2 - 10 or Omen.Anchor:GetRight() - 10
	if x > x1 and x < x2 then
	if x > x1 and x < x2 then
		db.VGrip1 = x - x1 + 10
		db.VGrip1 = x - x1 + 10
		Omen.VGrip1:ClearAllPoints()
		Omen.VGrip1:ClearAllPoints()
		Omen.VGrip1:SetPoint("TOPLEFT", Omen.BarList, "TOPLEFT", db.VGrip1, 0)
		Omen.VGrip1:SetPoint("TOPLEFT", Omen.BarList, "TOPLEFT", db.VGrip1, 0)
		Omen.VGrip1:SetPoint("BOTTOMLEFT", Omen.BarList, "BOTTOMLEFT", db.VGrip1, 0)
		Omen.VGrip1:SetPoint("BOTTOMLEFT", Omen.BarList, "BOTTOMLEFT", db.VGrip1, 0)
	end
	end
	Omen:ReAnchorLabels()
	Omen:ReAnchorLabels()
end
end
local function movegrip2(self)
local function movegrip2(self)
	local x = GetCursorPosition() / UIParent:GetEffectiveScale() / Omen.Anchor:GetScale()
	local x = GetCursorPosition() / UIParent:GetEffectiveScale() / Omen.Anchor:GetScale()
	local x1 = Omen.Anchor:GetLeft() + db.VGrip1 + 10
	local x1 = Omen.Anchor:GetLeft() + db.VGrip1 + 10
	local x2 = Omen.Anchor:GetRight() - 10
	local x2 = Omen.Anchor:GetRight() - 10
	if x > x1 and x < x2 then
	if x > x1 and x < x2 then
		db.VGrip2 = x - x1 + db.VGrip1 + 10
		db.VGrip2 = x - x1 + db.VGrip1 + 10
		Omen.VGrip2:ClearAllPoints()
		Omen.VGrip2:ClearAllPoints()
		Omen.VGrip2:SetPoint("TOPLEFT", Omen.BarList, "TOPLEFT", db.VGrip2, 0)
		Omen.VGrip2:SetPoint("TOPLEFT", Omen.BarList, "TOPLEFT", db.VGrip2, 0)
		Omen.VGrip2:SetPoint("BOTTOMLEFT", Omen.BarList, "BOTTOMLEFT", db.VGrip2, 0)
		Omen.VGrip2:SetPoint("BOTTOMLEFT", Omen.BarList, "BOTTOMLEFT", db.VGrip2, 0)
	end
	end
	Omen:ReAnchorLabels()
	Omen:ReAnchorLabels()
end
end
function Omen:CreateFrames()
function Omen:CreateFrames()
	-- Create anchor
	-- Create anchor
	self.Anchor = CreateFrame("Frame", "OmenAnchor", UIParent)
	self.Anchor = CreateFrame("Frame", "OmenAnchor", UIParent)
	self.Anchor:SetResizable(true)
	self.Anchor:SetResizable(true)
	self.Anchor:SetMinResize(90, db.Background.EdgeSize * 2)
	self.Anchor:SetMinResize(90, db.Background.EdgeSize * 2)
	self.Anchor:SetMovable(true)
	self.Anchor:SetMovable(true)
	self.Anchor:SetPoint("CENTER", UIParent, "CENTER")
	self.Anchor:SetPoint("CENTER", UIParent, "CENTER")
	self.Anchor:SetWidth(225)
	self.Anchor:SetWidth(225)
	self.Anchor:SetHeight(150)
	self.Anchor:SetHeight(150)
	self.Anchor:SetScript("OnHide", stopmoving)
	self.Anchor:SetScript("OnHide", stopmoving)
	self.Anchor:SetScript("OnShow", function(self) db.Shown = true Omen:UpdateBars() end)
	self.Anchor:SetScript("OnShow", function(self) db.Shown = true Omen:UpdateBars() end)
	-- Create Title
	-- Create Title
	self.Title = CreateFrame("Button", "OmenTitle", self.Anchor)
	self.Title = CreateFrame("Button", "OmenTitle", self.Anchor, "BackdropTemplate")
	self.Title:SetPoint("TOPLEFT", self.Anchor, "TOPLEFT")
	self.Title:SetPoint("TOPLEFT", self.Anchor, "TOPLEFT")
	self.Title:SetPoint("TOPRIGHT", self.Anchor, "TOPRIGHT")
	self.Title:SetPoint("TOPRIGHT", self.Anchor, "TOPRIGHT")
	self.Title:SetHeight(16)
	self.Title:SetHeight(16)
	self.Title:SetMinResize(90, db.Background.EdgeSize * 2)
	self.Title:SetMinResize(90, db.Background.EdgeSize * 2)
	self.Title:EnableMouse(true)
	self.Title:EnableMouse(true)
	self.Title:SetScript("OnMouseDown", startmoving)
	self.Title:SetScript("OnMouseDown", startmoving)
	self.Title:SetScript("OnMouseUp", stopmoving)
	self.Title:SetScript("OnMouseUp", stopmoving)
	self.Title:SetScript("OnClick", Omen_DropDownMenu.OnClick)
	self.Title:SetScript("OnClick", Omen_DropDownMenu.OnClick)
	self.Title.initMenuFunc = self.TitleQuickMenu
	self.Title.initMenuFunc = self.TitleQuickMenu
	self.Title:RegisterForClicks("RightButtonUp")
	self.Title:RegisterForClicks("RightButtonUp")
	-- Create Title text
	-- Create Title text
	self.TitleText = self.Title:CreateFontString(nil, nil, "GameFontNormal")
	self.TitleText = self.Title:CreateFontString(nil, nil, "GameFontNormal")
	self.TitleText:SetPoint("LEFT", self.Title, "LEFT", 8, 1)
	self.TitleText:SetPoint("LEFT", self.Title, "LEFT", 8, 1)
	self.TitleText:SetJustifyH("LEFT")
	self.TitleText:SetJustifyH("LEFT")
	self.TitleText:SetTextColor(1, 1, 1, 1)
	self.TitleText:SetTextColor(1, 1, 1, 1)
	self.defaultTitle = "Omen|cffffcc003|r"
	self.defaultTitle = "Omen|cffffcc003|r"
	self.TitleText:SetText(self.defaultTitle)
	self.TitleText:SetText(self.defaultTitle)
	-- Create Bar List
	-- Create Bar List
	self.BarList = CreateFrame("Frame", "OmenBarList", self.Anchor)
	self.BarList = CreateFrame("Frame", "OmenBarList", self.Anchor, "BackdropTemplate")
	self.BarList:SetResizable(true)
	self.BarList:SetResizable(true)
	self.BarList:EnableMouse(true)
	self.BarList:EnableMouse(true)
	self.BarList:SetPoint("TOPLEFT", self.Title, "BOTTOMLEFT")
	self.BarList:SetPoint("TOPLEFT", self.Title, "BOTTOMLEFT")
	self.BarList:SetPoint("BOTTOMRIGHT", self.Anchor, "BOTTOMRIGHT")
	self.BarList:SetPoint("BOTTOMRIGHT", self.Anchor, "BOTTOMRIGHT")
	self.BarList:SetScript("OnMouseDown", startmoving)
	self.BarList:SetScript("OnMouseDown", startmoving)
	self.BarList:SetScript("OnMouseUp", stopmoving)
	self.BarList:SetScript("OnMouseUp", stopmoving)
	self.BarList:SetScript("OnHide", stopmoving)
	self.BarList:SetScript("OnHide", stopmoving)
	self.BarList.barsShown = 0
	self.BarList.barsShown = 0
	-- Create resizing corner grip
	-- Create resizing corner grip
	self.Grip = CreateFrame("Button", "OmenResizeGrip", self.BarList)
	self.Grip = CreateFrame("Button", "OmenResizeGrip", self.BarList)
	self.Grip:SetNormalTexture("Interface\\AddOns\\Omen\\ResizeGrip")
	self.Grip:SetNormalTexture("Interface\\AddOns\\Omen\\ResizeGrip")
	self.Grip:SetHighlightTexture("Interface\\AddOns\\Omen\\ResizeGrip")
	self.Grip:SetHighlightTexture("Interface\\AddOns\\Omen\\ResizeGrip")
	self.Grip:SetWidth(16)
	self.Grip:SetWidth(16)
	self.Grip:SetHeight(16)
	self.Grip:SetHeight(16)
	self.Grip:SetPoint("BOTTOMRIGHT", self.BarList, "BOTTOMRIGHT", 0, 1)
	self.Grip:SetPoint("BOTTOMRIGHT", self.BarList, "BOTTOMRIGHT", 0, 1)
	self.Grip:SetScript("OnMouseDown", function(self, button)
	self.Grip:SetScript("OnMouseDown", function(self, button)
		if not db.Locked then
		if not db.Locked then
			Omen.Anchor.IsMovingOrSizing = 2
			Omen.Anchor.IsMovingOrSizing = 2
			Omen.Anchor.VGrip1Ratio = db.VGrip1 / Omen.Anchor:GetWidth()
			Omen.Anchor.VGrip1Ratio = db.VGrip1 / Omen.Anchor:GetWidth()
			Omen.Anchor.VGrip2Ratio = db.VGrip2 / Omen.Anchor:GetWidth()
			Omen.Anchor.VGrip2Ratio = db.VGrip2 / Omen.Anchor:GetWidth()
			Omen.Anchor:SetScript("OnSizeChanged", sizing)
			Omen.Anchor:SetScript("OnSizeChanged", sizing)
			Omen.Anchor:StartSizing()
			Omen.Anchor:StartSizing()
		end
		end
	end)
	end)
	self.Grip:SetScript("OnMouseUp", function(self)
	self.Grip:SetScript("OnMouseUp", function(self)
		if Omen.Anchor.IsMovingOrSizing == 2 then
		if Omen.Anchor.IsMovingOrSizing == 2 then
			Omen.Anchor:SetScript("OnSizeChanged", nil)
			Omen.Anchor:SetScript("OnSizeChanged", nil)
			Omen.Anchor:StopMovingOrSizing()
			Omen.Anchor:StopMovingOrSizing()
			sizing()
			sizing()
			Omen:SetAnchors()
			Omen:SetAnchors()
			Omen.Anchor.IsMovingOrSizing = nil
			Omen.Anchor.IsMovingOrSizing = nil
			Omen.Anchor.VGrip1Ratio = nil
			Omen.Anchor.VGrip1Ratio = nil
		end
		end
	end)
	end)
	self.Grip:SetScript("OnHide", self.Grip:GetScript("OnMouseUp"))
	self.Grip:SetScript("OnHide", self.Grip:GetScript("OnMouseUp"))
	-- Create label resizing vertical grip 1
	-- Create label resizing vertical grip 1
	self.VGrip1 = CreateFrame("Button", "OmenVResizeGrip1", self.BarList)
	self.VGrip1 = CreateFrame("Button", "OmenVResizeGrip1", self.BarList)
	self.VGrip1:SetWidth(1)
	self.VGrip1:SetWidth(1)
	self.VGrip1:SetPoint("TOPLEFT", self.BarList, "TOPLEFT", db.VGrip1, 0)
	self.VGrip1:SetPoint("TOPLEFT", self.BarList, "TOPLEFT", db.VGrip1, 0)
	self.VGrip1:SetPoint("BOTTOMLEFT", self.BarList, "BOTTOMLEFT", db.VGrip1, 0)
	self.VGrip1:SetPoint("BOTTOMLEFT", self.BarList, "BOTTOMLEFT", db.VGrip1, 0)
	self.VGrip1:SetNormalTexture("Interface\\Tooltips\\UI-Tooltip-Background")
	self.VGrip1:SetNormalTexture("Interface\\Tooltips\\UI-Tooltip-Background")
	self.VGrip1:SetHighlightTexture("Interface\\Tooltips\\UI-Tooltip-Background")
	self.VGrip1:SetHighlightTexture("Interface\\Tooltips\\UI-Tooltip-Background")
	self.VGrip1:GetNormalTexture():SetVertexColor(1, 1, 1, 0.5)
	self.VGrip1:GetNormalTexture():SetVertexColor(1, 1, 1, 0.5)
	self.VGrip1:GetHighlightTexture():SetVertexColor(1, 1, 1, 0.5)
	self.VGrip1:GetHighlightTexture():SetVertexColor(1, 1, 1, 0.5)
	self.VGrip1:SetScript("OnMouseDown", function(self)
	self.VGrip1:SetScript("OnMouseDown", function(self)
		if not db.Locked then self:SetScript("OnUpdate", movegrip1) end
		if not db.Locked then self:SetScript("OnUpdate", movegrip1) end
	end)
	end)
	self.VGrip1:SetScript("OnMouseUp", function(self) self:SetScript("OnUpdate", nil) end)
	self.VGrip1:SetScript("OnMouseUp", function(self) self:SetScript("OnUpdate", nil) end)
	self.VGrip1:SetScript("OnHide", self.VGrip1:GetScript("OnMouseUp"))
	self.VGrip1:SetScript("OnHide", self.VGrip1:GetScript("OnMouseUp"))
	self.VGrip1:SetFrameLevel(self.BarList:GetFrameLevel() + 2)
	self.VGrip1:SetFrameLevel(self.BarList:GetFrameLevel() + 2)
	-- Create label resizing vertical grip 2
	-- Create label resizing vertical grip 2
	self.VGrip2 = CreateFrame("Button", "OmenVResizeGrip2", self.BarList)
	self.VGrip2 = CreateFrame("Button", "OmenVResizeGrip2", self.BarList)
	self.VGrip2:SetWidth(1)
	self.VGrip2:SetWidth(1)
	self.VGrip2:SetPoint("TOPLEFT", self.BarList, "TOPLEFT", db.VGrip2, 0)
	self.VGrip2:SetPoint("TOPLEFT", self.BarList, "TOPLEFT", db.VGrip2, 0)
	self.VGrip2:SetPoint("BOTTOMLEFT", self.BarList, "BOTTOMLEFT", db.VGrip2, 0)
	self.VGrip2:SetPoint("BOTTOMLEFT", self.BarList, "BOTTOMLEFT", db.VGrip2, 0)
	self.VGrip2:SetNormalTexture("Interface\\Tooltips\\UI-Tooltip-Background")
	self.VGrip2:SetNormalTexture("Interface\\Tooltips\\UI-Tooltip-Background")
	self.VGrip2:SetHighlightTexture("Interface\\Tooltips\\UI-Tooltip-Background")
	self.VGrip2:SetHighlightTexture("Interface\\Tooltips\\UI-Tooltip-Background")
	self.VGrip2:GetNormalTexture():SetVertexColor(1, 1, 1, 0.5)
	self.VGrip2:GetNormalTexture():SetVertexColor(1, 1, 1, 0.5)
	self.VGrip2:GetHighlightTexture():SetVertexColor(1, 1, 1, 0.5)
	self.VGrip2:GetHighlightTexture():SetVertexColor(1, 1, 1, 0.5)
	self.VGrip2:SetScript("OnMouseDown", function(self)
	self.VGrip2:SetScript("OnMouseDown", function(self)
		if not db.Locked then self:SetScript("OnUpdate", movegrip2) end
		if not db.Locked then self:SetScript("OnUpdate", movegrip2) end
	end)
	end)
	self.VGrip2:SetScript("OnMouseUp", self.VGrip1:GetScript("OnMouseUp"))
	self.VGrip2:SetScript("OnMouseUp", self.VGrip1:GetScript("OnMouseUp"))
	self.VGrip2:SetScript("OnHide", self.VGrip1:GetScript("OnMouseUp"))
	self.VGrip2:SetScript("OnHide", self.VGrip1:GetScript("OnMouseUp"))
	self.VGrip2:SetFrameLevel(self.BarList:GetFrameLevel() + 2)
	self.VGrip2:SetFrameLevel(self.BarList:GetFrameLevel() + 2)
	--[[self.FocusButton = CreateFrame("Button", "OmenFocusButton", self.Title, "OptionsButtonTemplate")
	--[[self.FocusButton = CreateFrame("Button", "OmenFocusButton", self.Title, "OptionsButtonTemplate")
	self.FocusButton:SetWidth(16)
	self.FocusButton:SetWidth(16)
	self.FocusButton:SetHeight(16)
	self.FocusButton:SetHeight(16)
	self.FocusButton:SetPoint("TOPRIGHT")
	self.FocusButton:SetPoint("TOPRIGHT")
	self.FocusButton:SetText("F")
	self.FocusButton:SetText("F")
	self.FocusButton:SetScript("OnClick", function(self, button, down)
	self.FocusButton:SetScript("OnClick", function(self, button, down)
		db.UseFocus = not db.UseFocus
		db.UseFocus = not db.UseFocus
		if db.UseFocus then
		if db.UseFocus then
			self:GetFontString():SetTextColor(1, 0.82, 0, 1)
			self:GetFontString():SetTextColor(1, 0.82, 0, 1)
		else
		else
			self:GetFontString():SetTextColor(0.5, 0.5, 0.5, 1)
			self:GetFontString():SetTextColor(0.5, 0.5, 0.5, 1)
		end
		end
		Omen:UpdateBars()
		Omen:UpdateBars()
	end)
	end)
	if db.UseFocus then
	if db.UseFocus then
		self.FocusButton:GetFontString():SetTextColor(1, 0.82, 0, 1)
		self.FocusButton:GetFontString():SetTextColor(1, 0.82, 0, 1)
	else
	else
		self.FocusButton:GetFontString():SetTextColor(0.5, 0.5, 0.5, 1)
		self.FocusButton:GetFontString():SetTextColor(0.5, 0.5, 0.5, 1)
	end]]
	end]]
	self.CreateFrames = nil
	self.CreateFrames = nil
end
end
function Omen:OnInitialize()
function Omen:OnInitialize()
	-- Create savedvariables
	-- Create savedvariables
	self.db = LibStub("AceDB-3.0"):New("Omen3DB", defaults)
	self.db = LibStub("AceDB-3.0"):New("Omen3DB", defaults)
	self.db.RegisterCallback(self, "OnProfileChanged", "OnProfileChanged")
	self.db.RegisterCallback(self, "OnProfileChanged", "OnProfileChanged")
	self.db.RegisterCallback(self, "OnProfileCopied", "OnProfileChanged")
	self.db.RegisterCallback(self, "OnProfileCopied", "OnProfileChanged")
	self.db.RegisterCallback(self, "OnProfileReset", "OnProfileChanged")
	self.db.RegisterCallback(self, "OnProfileReset", "OnProfileChanged")
	db = self.db.profile
	db = self.db.profile
	self:SetSinkStorage(db.Warnings.SinkOptions)
	self:SetSinkStorage(db.Warnings.SinkOptions)
	LSM.RegisterCallback(self, "LibSharedMedia_Registered", "UpdateUsedMedia")
	LSM.RegisterCallback(self, "LibSharedMedia_Registered", "UpdateUsedMedia")
	-- These 2 functions self GC after running
	-- These 2 functions self GC after running
	self:CreateFrames()
	self:CreateFrames()
	self:SetupOptions()
	self:SetupOptions()
	self.OnInitialize = nil
	self.OnInitialize = nil
end
end
function Omen:PLAYER_LOGIN()
function Omen:PLAYER_LOGIN()
	-- We set up anchors here because we only want to do it once on
	-- We set up anchors here because we only want to do it once on
	-- PLAYER_LOGIN, hence we don't do it in OnEnable() which triggers on
	-- PLAYER_LOGIN, hence we don't do it in OnEnable() which triggers on
	-- the same event as well as on every subsequent Enable()/Disable() calls.
	-- the same event as well as on every subsequent Enable()/Disable() calls.
	-- It cannot be earlier than PLAYER_LOGIN because layout-cache.txt
	-- It cannot be earlier than PLAYER_LOGIN because layout-cache.txt
	-- is loaded just before this event fires.
	-- is loaded just before this event fires.
	self:SetAnchors(true)
	self:SetAnchors(true)
	self.Anchor:SetAlpha(db.Alpha)
	self.Anchor:SetAlpha(db.Alpha)
	self.Anchor:SetFrameStrata(strsub(db.FrameStrata, 3))
	self.Anchor:SetFrameStrata(strsub(db.FrameStrata, 3))
	self.Anchor:SetClampedToScreen(db.ClampToScreen)
	self.Anchor:SetClampedToScreen(db.ClampToScreen)
	self:UpdateBackdrop()
	self:UpdateBackdrop()
	self:UpdateTitleBar()
	self:UpdateTitleBar()
	self:UpdateGrips()
	self:UpdateGrips()
	self:ResizeBars()
	self:ResizeBars()
	self:ReAnchorBars()
	self:ReAnchorBars()
	self:ReAnchorLabels()
	self:ReAnchorLabels()
	self:UpdateBarLabelSettings()
	self:UpdateBarLabelSettings()
	self:UpdateBarTextureSettings()
	self:UpdateBarTextureSettings()
	self:UpdateClickThrough()
	self:UpdateClickThrough()
	self:UpdateRaidClassColors()
	self:UpdateRaidClassColors()
	self:ClearAll()
	self:ClearAll()
	self:UnregisterEvent("PLAYER_LOGIN")
	self:UnregisterEvent("PLAYER_LOGIN")
	if not db.Shown then self.Anchor:Hide() end -- Auto-show/hide will override this later if enabled
	if not db.Shown then self.Anchor:Hide() end -- Auto-show/hide will override this later if enabled
	-- Optional !ClassColors addon support
	-- Optional !ClassColors addon support
	if CUSTOM_CLASS_COLORS then
	if CUSTOM_CLASS_COLORS then
		CUSTOM_CLASS_COLORS:RegisterCallback("UpdateBars", self)
		CUSTOM_CLASS_COLORS:RegisterCallback("UpdateBars", self)
	end
	end
	-- ConfigMode support
	-- ConfigMode support
	do
	do
		CONFIGMODE_CALLBACKS = CONFIGMODE_CALLBACKS or {}
		CONFIGMODE_CALLBACKS = CONFIGMODE_CALLBACKS or {}
		local oldTestMode = testMode
		local oldTestMode = testMode
		local oldLocked = db.Locked
		local oldLocked = db.Locked
		function CONFIGMODE_CALLBACKS.Omen(action)
		function CONFIGMODE_CALLBACKS.Omen(action)
			if action == "ON" then
			if action == "ON" then
				oldTestMode = testMode
				oldTestMode = testMode
				oldLocked = db.Locked
				oldLocked = db.Locked
				testMode = true
				testMode = true
				db.Locked = false
				db.Locked = false
				Omen:Toggle(true)
				Omen:Toggle(true)
			elseif action == "OFF" then
			elseif action == "OFF" then
				testMode = oldTestMode
				testMode = oldTestMode
				db.Locked = oldLocked
				db.Locked = oldLocked
				manualToggle = false
				manualToggle = false
				Omen:UpdateVisible()
				Omen:UpdateVisible()
			end
			end
			Omen:UpdateGrips()
			Omen:UpdateGrips()
			Omen:UpdateBars()
			Omen:UpdateBars()
			LibStub("AceConfigRegistry-3.0"):NotifyChange("Omen")
			LibStub("AceConfigRegistry-3.0"):NotifyChange("Omen")
		end
		end
	end
	end
	-- LDB launcher
	-- LDB launcher
	if LDB then
	if LDB then
		OmenLauncher = LDB:NewDataObject("Omen", {
		OmenLauncher = LDB:NewDataObject("Omen", {
			type = "launcher",
			type = "launcher",
			icon = "Interface\\AddOns\\Omen\\icon",
			icon = "Interface\\AddOns\\Omen\\icon",
			OnClick = function(clickedframe, button)
			OnClick = function(clickedframe, button)
				if button == "RightButton" then Omen:ShowConfig() else Omen:Toggle() end
				if button == "RightButton" then Omen:ShowConfig() else Omen:Toggle() end
			end,
			end,
			OnTooltipShow = function(tt)
			OnTooltipShow = function(tt)
				tt:AddLine(self.defaultTitle)
				tt:AddLine(self.defaultTitle)
				tt:AddLine("|cffffff00" .. L["Click|r to toggle the Omen window"])
				tt:AddLine("|cffffff00" .. L["Click|r to toggle the Omen window"])
				tt:AddLine("|cffffff00" .. L["Right-click|r to open the options menu"])
				tt:AddLine("|cffffff00" .. L["Right-click|r to open the options menu"])
			end,
			end,
		})
		})
		if LDBIcon and not LibStub:GetLibrary("LibFuBarPlugin-3.0", true) then
		if LDBIcon and not LibStub:GetLibrary("LibFuBarPlugin-3.0", true) then
			LDBIcon:Register("Omen", OmenLauncher, db.MinimapIcon)
			LDBIcon:Register("Omen", OmenLauncher, db.MinimapIcon)
			LDBIconRegistered = true
			LDBIconRegistered = true
		end
		end
	end
	end
	-- Optional launcher support for LFBP-3.0 if present, this code is placed here so
	-- Optional launcher support for LFBP-3.0 if present, this code is placed here so
	-- that it runs after all other addons have loaded since we don't embed LFBP-3.0
	-- that it runs after all other addons have loaded since we don't embed LFBP-3.0
	-- Yes, this is one big hack since LFBP-3.0 is a Rock library, and we embed it
	-- Yes, this is one big hack since LFBP-3.0 is a Rock library, and we embed it
	-- via Ace3. OnEmbedInitialize() needs to be called manually.
	-- via Ace3. OnEmbedInitialize() needs to be called manually.
	if LibStub:GetLibrary("LibFuBarPlugin-3.0", true) and not IsAddOnLoaded("FuBar2Broker") then
	if LibStub:GetLibrary("LibFuBarPlugin-3.0", true) and not IsAddOnLoaded("FuBar2Broker") then
		local LFBP = LibStub:GetLibrary("LibFuBarPlugin-3.0")
		local LFBP = LibStub:GetLibrary("LibFuBarPlugin-3.0")
		LibStub("AceAddon-3.0"):EmbedLibrary(self, "LibFuBarPlugin-3.0")
		LibStub("AceAddon-3.0"):EmbedLibrary(self, "LibFuBarPlugin-3.0")
		self:SetFuBarOption("tooltipType", "GameTooltip")
		self:SetFuBarOption("tooltipType", "GameTooltip")
		self:SetFuBarOption("hasNoColor", true)
		self:SetFuBarOption("hasNoColor", true)
		self:SetFuBarOption("cannotDetachTooltip", true)
		self:SetFuBarOption("cannotDetachTooltip", true)
		self:SetFuBarOption("hideWithoutStandby", true)
		self:SetFuBarOption("hideWithoutStandby", true)
		self:SetFuBarOption("iconPath", [[Interface\AddOns\Omen\icon]])
		self:SetFuBarOption("iconPath", [[Interface\AddOns\Omen\icon]])
		self:SetFuBarOption("hasIcon", true)
		self:SetFuBarOption("hasIcon", true)
		self:SetFuBarOption("defaultPosition", "RIGHT")
		self:SetFuBarOption("defaultPosition", "RIGHT")
		self:SetFuBarOption("tooltipHiddenWhenEmpty", true)
		self:SetFuBarOption("tooltipHiddenWhenEmpty", true)
		self:SetFuBarOption("configType", "None")
		self:SetFuBarOption("configType", "None")
		LFBP:OnEmbedInitialize(self)
		LFBP:OnEmbedInitialize(self)
		function Omen:OnUpdateFuBarTooltip()
		function Omen:OnUpdateFuBarTooltip()
			GameTooltip:AddLine(self.defaultTitle)
			GameTooltip:AddLine(self.defaultTitle)
			GameTooltip:AddLine("|cffffff00" .. L["Click|r to toggle the Omen window"])
			GameTooltip:AddLine("|cffffff00" .. L["Click|r to toggle the Omen window"])
			GameTooltip:AddLine("|cffffff00" .. L["Right-click|r to open the options menu"])
			GameTooltip:AddLine("|cffffff00" .. L["Right-click|r to open the options menu"])
		end
		end
		function Omen:OnFuBarClick(button)
		function Omen:OnFuBarClick(button)
			if button == "RightButton" then self:ShowConfig() else self:Toggle() end
			if button == "RightButton" then self:ShowConfig() else self:Toggle() end
		end
		end
		self.optionsFrames["FuBar"] = LibStub("AceConfigDialog-3.0"):AddToBlizOptions("Omen", L["FuBar Options"], self.versionstring, "FuBar")
		self.optionsFrames["FuBar"] = LibStub("AceConfigDialog-3.0"):AddToBlizOptions("Omen", L["FuBar Options"], self.versionstring, "FuBar")
		self:UpdateFuBarSettings()
		self:UpdateFuBarSettings()
	end
	end
	self.PLAYER_LOGIN = nil
	self.PLAYER_LOGIN = nil
end
end
function Omen:OnEnable()
function Omen:OnEnable()
	if self.PLAYER_LOGIN then self:PLAYER_LOGIN() end
	if self.PLAYER_LOGIN then self:PLAYER_LOGIN() end
	self:RegisterEvent("UNIT_THREAT_LIST_UPDATE")
	self:RegisterEvent("UNIT_THREAT_LIST_UPDATE")
	self:RegisterEvent("UNIT_THREAT_SITUATION_UPDATE")
	self:RegisterEvent("UNIT_THREAT_SITUATION_UPDATE")
	self:RegisterEvent("PLAYER_TARGET_CHANGED")
	self:RegisterEvent("PLAYER_TARGET_CHANGED")
	self:RegisterEvent("GROUP_ROSTER_UPDATE")
	self:RegisterEvent("GROUP_ROSTER_UPDATE")
	self:RegisterEvent("UNIT_PET", "GROUP_ROSTER_UPDATE")
	self:RegisterEvent("UNIT_PET", "GROUP_ROSTER_UPDATE")
	self:RegisterEvent("UNIT_NAME_UPDATE", "GROUP_ROSTER_UPDATE")
	self:RegisterEvent("UNIT_NAME_UPDATE", "GROUP_ROSTER_UPDATE")
	self:RegisterEvent("PLAYER_UPDATE_RESTING", "UpdateVisible")
	self:RegisterEvent("PLAYER_UPDATE_RESTING", "UpdateVisible")
	self:RegisterEvent("PLAYER_ENTERING_WORLD")
	self:RegisterEvent("PLAYER_ENTERING_WORLD")
	self:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED")
	self:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED")
	if not WoWClassic then
	if not WoWClassic then
		self:RegisterEvent("PET_BATTLE_OPENING_START", "UpdateVisible")
		self:RegisterEvent("PET_BATTLE_OPENING_START", "UpdateVisible")
		self:RegisterEvent("PET_BATTLE_CLOSE", "UpdateVisible")
		self:RegisterEvent("PET_BATTLE_CLOSE", "UpdateVisible")
	end
	end
	if db.ShowWith.HideWhenOOC then
	if db.ShowWith.HideWhenOOC then
		self:RegisterEvent("PLAYER_REGEN_DISABLED", "UpdateVisible")
		self:RegisterEvent("PLAYER_REGEN_DISABLED", "UpdateVisible")
		self:RegisterEvent("PLAYER_REGEN_ENABLED", "UpdateVisible")
		self:RegisterEvent("PLAYER_REGEN_ENABLED", "UpdateVisible")
	end
	end
	if db.UseFocus then
	if db.UseFocus then
		self:RegisterEvent("UNIT_TARGET")
		self:RegisterEvent("UNIT_TARGET")
	end
	end
	self:GROUP_ROSTER_UPDATE()
	self:GROUP_ROSTER_UPDATE()
	self:PLAYER_TARGET_CHANGED()
	self:PLAYER_TARGET_CHANGED()
end
end
function Omen:OnDisable()
function Omen:OnDisable()
	-- Cancel all timers (well at least nil them all
	-- Cancel all timers (well at least nil them all
	-- out in timers[], since AceTimer-3.0 cancels
	-- out in timers[], since AceTimer-3.0 cancels
	-- them all OnDisable anyway).
	-- them all OnDisable anyway).
	for k, v in pairs(timers) do
	for k, v in pairs(timers) do
		self:CancelTimer(v, true)
		self:CancelTimer(v, true)
		timers[k] = nil
		timers[k] = nil
	end
	end
	self:_toggle(false)
	self:_toggle(false)
end
end
function Omen:OnProfileChanged(event, database, newProfileKey)
function Omen:OnProfileChanged(event, database, newProfileKey)
	db = database.profile
	db = database.profile
	self:SetAnchors(true)
	self:SetAnchors(true)
	self.Anchor:SetAlpha(db.Alpha)
	self.Anchor:SetAlpha(db.Alpha)
	self.Anchor:SetFrameStrata(strsub(db.FrameStrata, 3))
	self.Anchor:SetFrameStrata(strsub(db.FrameStrata, 3))
	self.Anchor:SetClampedToScreen(db.ClampToScreen)
	self.Anchor:SetClampedToScreen(db.ClampToScreen)
	self:UpdateBackdrop()
	self:UpdateBackdrop()
	self:UpdateTitleBar()
	self:UpdateTitleBar()
	self:UpdateGrips()
	self:UpdateGrips()
	self:ResizeBars()
	self:ResizeBars()
	self:ReAnchorBars()
	self:ReAnchorBars()
	self:ReAnchorLabels()
	self:ReAnchorLabels()
	self:UpdateBarLabelSettings()
	self:UpdateBarLabelSettings()
	self:UpdateBarTextureSettings()
	self:UpdateBarTextureSettings()
	self:UpdateClickThrough()
	self:UpdateClickThrough()
	self:UpdateRaidClassColors()
	self:UpdateRaidClassColors()
	self:UpdateFuBarSettings()
	self:UpdateFuBarSettings()
	-- These remainder settings were not placed in functions
	-- These remainder settings were not placed in functions
	-- and were just updated directly from the config code.
	-- and were just updated directly from the config code.
	if LDBIcon and not IsAddOnLoaded("Broker2FuBar") and not IsAddOnLoaded("FuBar") then
	if LDBIcon and not IsAddOnLoaded("Broker2FuBar") and not IsAddOnLoaded("FuBar") then
		LDBIcon:Refresh("Omen", db.MinimapIcon)
		LDBIcon:Refresh("Omen", db.MinimapIcon)
	end
	end
	if db.ShowWith.HideWhenOOC then
	if db.ShowWith.HideWhenOOC then
		self:RegisterEvent("PLAYER_REGEN_DISABLED", "UpdateVisible")
		self:RegisterEvent("PLAYER_REGEN_DISABLED", "UpdateVisible")
		self:RegisterEvent("PLAYER_REGEN_ENABLED", "UpdateVisible")
		self:RegisterEvent("PLAYER_REGEN_ENABLED", "UpdateVisible")
	else
	else
		self:UnregisterEvent("PLAYER_REGEN_DISABLED")
		self:UnregisterEvent("PLAYER_REGEN_DISABLED")
		self:UnregisterEvent("PLAYER_REGEN_ENABLED")
		self:UnregisterEvent("PLAYER_REGEN_ENABLED")
	end
	end
	if db.UseFocus then
	if db.UseFocus then
		self:RegisterEvent("UNIT_TARGET")
		self:RegisterEven
	else
		self:Unregister