local PA = _G.ProjectAzilroka
local AR = PA:NewModule('AuraReminder', 'AceEvent-3.0', 'AceTimer-3.0')

PA.AR = AR

AR.Title = 'Aura Reminder'
AR.Header = '|cFF16C3F2Aura|r |cFFFFFFFFReminder|r'
AR.Description = 'Reminder for Buffs / Debuffs'
AR.Authors = 'Azilroka    NihilisticPandemonium'
AR.isEnabled = false

local _G = _G
local pairs = pairs
local ipairs = ipairs
local tonumber = tonumber
local tostring = tostring
local select = select
local format = format
local strmatch = strmatch
local unpack = unpack
local tinsert = tinsert
local wipe = wipe

local GetSpellCooldown = GetSpellCooldown
local GetSpellInfo = GetSpellInfo
local IsUsableSpell = IsUsableSpell
local IsInInstance = IsInInstance
local UnitAffectingCombat = UnitAffectingCombat
local UnitIsDeadOrGhost = UnitIsDeadOrGhost
local UnitLevel = UnitLevel
local GetInventoryItemID = GetInventoryItemID
local GetWeaponEnchantInfo = GetWeaponEnchantInfo
local GetInventoryItemTexture = GetInventoryItemTexture
local PlaySoundFile = PlaySoundFile
local GetSpecialization = GetSpecialization
local GetSpecializationRole = GetSpecializationRole
local GetSpecializationInfo = GetSpecializationInfo
local GetItemInfoInstant = GetItemInfoInstant

local MAX_PLAYER_LEVEL = MAX_PLAYER_LEVEL

local CreateFrame = CreateFrame
local UIParent = UIParent

_G.AuraReminder = AR

AR.CreatedReminders = {}

local selectedFilter, filters, spellList, DefaultFilters = nil, {}, {}

do
	local function SpellIDPredicate(spellIDToFind, casterToFind, _, _, _, _, _, _, _, caster, _, _, spellID)
		return (casterToFind and caster == casterToFind and spellIDToFind == spellID) or (spellIDToFind == spellID)
	end

	function AR:FindAuraBySpellID(spellID, unit, filter, caster)
		return _G.AuraUtil.FindAura(SpellIDPredicate, unit, filter, spellID, caster);
	end
end

function AR:FindPlayerAura(db, checkPersonal, filter)
	for spellID, value in pairs(db) do
		if value == true then
			return AR:FindAuraBySpellID(spellID, 'player', filter, checkPersonal and 'player')
		end
	end
end

function AR:IsSpellOnCooldown(id)
	local start, duration = GetSpellCooldown(id)
	if start > 0 and duration > 1.5 then
		return true
	end
end

function AR:IsSpellUsable(id)
	local isUsable = IsUsableSpell(id)
	if isUsable then
		return true
	end
end

function AR:UpdateColors(frame, id)
	local isUsable, notEnoughMana = IsUsableSpell(id)
	if isUsable then
		frame.icon:SetVertexColor(1, 1, 1)
	elseif notEnoughMana then
		frame.icon:SetVertexColor(.5, .5, 1)
	else
		frame.icon:SetVertexColor(.4, .4, .4)
	end
end

function AR:HasOffHandWeapon(itemID)
	if not itemID then return end
	local itemEquipLoc = select(4, GetItemInfoInstant(itemID))
	return (itemEquipLoc == "INVTYPE_WEAPON" or itemEquipLoc == "INVTYPE_2HWEAPON" or itemEquipLoc == "INVTYPE_WEAPONOFFHAND")
end

function AR:FilterCheck(db, isReverse)
	local _, instanceType = IsInInstance()
	local roleCheck, treeCheck, combatCheck, instanceCheck, PVPCheck = true, true, true, true, true

	if PA.Retail then
		local spec = GetSpecialization()

		if db.role and (db.role ~= 'ANY' and db.role ~= GetSpecializationRole(spec)) then
			roleCheck = false
		end

		if not isReverse and db.tree and (db.tree ~= 'ANY' and db.tree ~= spec) then
			treeCheck = false
		end

		if isReverse and db.talentTreeException and db.talentTreeException == spec then
			treeCheck = false
		end
	end

	if db.combat and not UnitAffectingCombat('player') then
		combatCheck = false
	end

	if db.instance and (instanceType ~= 'party' and instanceType ~= 'raid') then
		instanceCheck = false
	end

	if db.pvp and (instanceType ~= 'arena' and instanceType ~= 'pvp') then
		PVPCheck = false
	end

	if isReverse and combatCheck and (instanceCheck or PVPCheck) then
		return true
	elseif roleCheck and treeCheck and combatCheck and (instanceCheck or PVPCheck) then
		return true
	else
		return false
	end
end

function AR:Reminder_Update()
	if UnitIsDeadOrGhost('player') then return end

	for _, button in ipairs(AR.CreatedReminders) do
		button:Hide()
		button:SetAlpha(1)
	end

	local Position = 1
	for _, db in pairs(AR.db.Filters[PA.MyClass]) do
		if db.enable and db.level and UnitLevel('player') > db.level then
			local Button = AR.CreatedReminders[Position]
			if (not Button) or (Button:IsVisible()) then
				Button = AR:CreateReminder(Position)
				Position = Position + 1
			end

			AR:SetIconPosition(Button, db)

			local filterCheck, reverseCheck = AR:FilterCheck(db), AR:FilterCheck(db, true)

			if db.filterType == 'COOLDOWN' and db.cooldownSpellID and filterCheck then
				local start, duration = GetSpellCooldown(db.cooldownSpellID)
				if (duration and duration > 0) then
					Button.cooldown:SetCooldown(start, duration)
				end

				Button.cooldown:SetShown((duration and duration > 0))
				Button.icon:SetTexture(select(3, GetSpellInfo(db.cooldownSpellID)))
				Button:Show()

				AR:UpdateColors(Button, db.cooldownSpellID)

				if (duration and duration > 0) and filterCheck and db.onCooldown then
					Button:SetAlpha(db.cooldownAlpha or 0)
				end
			elseif (db.filterType == 'WEAPON' or (db.filterType == 'SPELL' and db.spellGroup)) then
				if db.filterType == 'SPELL' and not AR:FindPlayerAura(db.negateGroup, nil, 'HELPFUL') then
					local hasBuff, hasDebuff = AR:FindPlayerAura(db.spellGroup, db.personal, 'HELPFUL'), AR:FindPlayerAura(db.spellGroup, nil, 'HARMFUL')

					if not (hasBuff or hasDebuff) then
						for buff, value in pairs(db.spellGroup) do
							if value then
								local usable = IsUsableSpell(buff);
								if usable and AR:IsSpellOnCooldown(buff) then
									break
								end

								if usable or not db.strictFilter then
									Button.icon:SetTexture(select(3, GetSpellInfo(buff)))
									AR:UpdateColors(Button, buff)
									break
								end
							end
						end

						Button:SetShown((filterCheck and ((not hasBuff) and (not hasDebuff)) and not db.reverseCheck) or (reverseCheck and db.reverseCheck and ((hasBuff or hasDebuff) or ((not hasBuff) and (not hasDebuff)))))
					end
				end

				if db.filterType == 'WEAPON' and filterCheck then
					local hasOffhandWeapon = AR:HasOffHandWeapon(GetInventoryItemID('player', 17))
					local hasMainHandEnchant, _, _, hasOffHandEnchant, _, _ = GetWeaponEnchantInfo()

					if (not hasMainHandEnchant) then
						Button.icon:SetTexture(GetInventoryItemTexture('player', 16))
					elseif (hasOffhandWeapon and not hasOffHandEnchant) then
						Button.icon:SetTexture(GetInventoryItemTexture('player', 17))
					end

					Button:SetShown(not (hasMainHandEnchant or hasOffHandEnchant))
					Button.icon:SetVertexColor(1, 1, 1)
				end

				if Button:IsShown() and not db.disableSound then
					AR:PlaySoundFile()
				end
			end
		end
	end
end

function AR:ResetSoundPlayback()
	AR.IsPlaying = false
end

function AR:PlaySoundFile()
	if AR.IsPlaying then return end

	AR.IsPlaying = true

	PlaySoundFile(PA.LSM:Fetch('sound', AR.db.Sound))

	AR:ScheduleTimer('ResetSoundPlayback', 10)
end

function AR:SetIconPosition(button, db)
	if not (button or db) then return end

	local xOffset = db.xOffset or 0
	local yOffset = db.yOffset or 0
	local size = db.size or 40

	button:ClearAllPoints()
	button:SetPoint('CENTER', UIParent, 'CENTER', 0 + xOffset, 200 + yOffset);
	button:SetSize(size, size)
end

function AR:CreateReminder(index)
	local frame = CreateFrame('Frame', 'AuraReminder'..index, UIParent)
	frame:Hide()
	frame.icon = frame:CreateTexture(nil, 'OVERLAY')
	frame.icon:SetTexCoord(unpack(PA.TexCoords))
	frame.cooldown = CreateFrame('Cooldown', nil, frame, 'CooldownFrameTemplate')
	frame.cooldown:SetAllPoints(frame.icon)

	PA:SetTemplate(frame)
	PA:SetInside(frame.icon)

	tinsert(AR.CreatedReminders, frame)
	return frame
end

function AR:UpdateFilterGroup(group)
	for option, optionTable in pairs(PA.Options.args.AuraReminder.args.filterGroup.args[group].args) do
		if strmatch(option, "^AR") then
			optionTable.hidden = true
		end
	end

	if AR.db.Filters[PA.MyClass][selectedFilter] and AR.db.Filters[PA.MyClass][selectedFilter][group] then
		local i = 1
		for spell in pairs(AR.db.Filters[PA.MyClass][selectedFilter][group]) do
			if spell and GetSpellInfo(spell) then
				local name = format('AR%s', i + 2)
				local optionName = PA.Options.args.AuraReminder.args.filterGroup.args[group].args[name]
				if not optionName then
					PA.Options.args.AuraReminder.args.filterGroup.args[group].args[name] = { type = 'toggle' }
					optionName = PA.Options.args.AuraReminder.args.filterGroup.args[group].args[name]
				end

				optionName.name = function() return format('%s (%s)', GetSpellInfo(spell), spell) end
				optionName.get = function(info) return spell and AR.db.Filters[PA.MyClass][selectedFilter][group][spell] end
				optionName.set = function(info, value) AR.db.Filters[PA.MyClass][selectedFilter][group][spell] = value end
				optionName.hidden = false

				i = i + 1
			end
		end
	end
end

local addGroupTemplate = { name = '', template = ''}

function AR:GetOptions()
	PA.Options.args.AuraReminder = {
		type = 'group',
		name = 'Aura Reminder',
		get = function(info) return AR.db[info[#info]] end,
		set = function(info, value) AR.db[info[#info]] = value end,
		args = {
			Header = {
				order = 0,
				type = 'header',
				name = AR.Header,
			},
			Enable = {
				order = 1,
				type = 'toggle',
				name = PA.ACL['Enable'],
				set = function(info, value)
					AR.db[info[#info]] = value
					if (not AR.isEnabled) then
						AR:Initialize()
					else
						_G.StaticPopup_Show('PROJECTAZILROKA_RL')
					end
				end,
			},
			Sound = {
				order = 2,
				type = 'select', dialogControl = 'LSM30_Sound',
				name = PA.ACL['Sound'],
				desc = PA.ACL['Sound that will play when you have a warning icon displayed.'],
				values = PA.LSM:HashTable('sound'),
			},
			selectGroup = {
				order = 3,
				type = 'select',
				name = PA.ACL['Select Group'],
				get = function(info) return selectedFilter ~= '' and selectedFilter or '' end,
				set = function(info, value)
					selectedFilter = value ~= '' and value or nil
					AR:UpdateFilterGroup('spellGroup')
					AR:UpdateFilterGroup('negateGroup')
				end,
				values = function()
					wipe(filters)
					for filter in pairs(AR.db.Filters[PA.MyClass]) do
						filters[filter] = filter
					end
					if not next(filters) then
						filters[''] = PA.ACL['None']
					end
					return filters
				end,
			},
			groupControl = {
				order = 4,
				type = 'group',
				name = PA.ACL['Group Control'],
				guiInline = true,
				args = {
					addGroup = {
						order = 1,
						type = 'input',
						name = PA.ACL['New Group Name'],
						get = function(info) return addGroupTemplate.name end,
						set = function(info, value)
							if AR.db.Filters[PA.MyClass][value] then
								return
							end
							addGroupTemplate.name = value
						end,
					},
					addGroupTemplate = {
						order = 2,
						type = 'select',
						name = PA.ACL['New Group Filter Type'],
						get = function(info) return addGroupTemplate.template end,
						set = function(info, value)
							if AR.db.Filters[PA.MyClass][value] then
								return
							end
							addGroupTemplate.template = value
						end,
						values = {
							WEAPON = PA.ACL['Weapon'],
							SPELL = PA.ACL['Spell'],
							COOLDOWN = PA.ACL['Cooldown'],
						},
					},
					addGroupButton = {
						type = 'execute',
						order = 3,
						name = PA.ACL['Add Group'],
						hidden = function(info)
							return addGroupTemplate.name == '' or addGroupTemplate.template == ''
						end,
						func = function(info)
							AR.db.Filters[PA.MyClass][addGroupTemplate.name] = { enable = true, size = 50, filterType = addGroupTemplate.template, role = 'ANY', tree = 'ANY', level = 0 }
							if addGroupTemplate.template == 'COOLDOWN' then
								AR.db.Filters[PA.MyClass][addGroupTemplate.name].cooldownAlpha = .5
							elseif addGroupTemplate.template == 'WEAPON' then
							else
								AR.db.Filters[PA.MyClass][addGroupTemplate.name].spellGroup = {}
								AR.db.Filters[PA.MyClass][addGroupTemplate.name].negateGroup = {}
							end

							selectedFilter = addGroupTemplate.name

							addGroupTemplate.name = ''
							addGroupTemplate.template = ''
						end,
					},
					deleteGroup = {
						order = 5,
						type = 'select',
						name = PA.ACL['Remove Group'],
						get = function(info) return '' end,
						set = function(info, value)
							selectedFilter = nil
							if DefaultFilters[PA.MyClass][value] then
								AR.db.Filters[PA.MyClass][value].enable = false;
							else
								AR.db.Filters[PA.MyClass][value] = nil;
							end
						end,
						values = function()
							wipe(filters)
							for filter in pairs(AR.db.Filters[PA.MyClass]) do
								filters[filter] = filter
							end
							if not next(filters) then
								filters[''] = PA.ACL['None']
							end
							return filters
						end,
					},
				},
			},
			filterGroup = {
				order = 8,
				type = 'group',
				name = function() return selectedFilter end,
				guiInline = true,
				get = function(info) return AR.db.Filters[PA.MyClass][selectedFilter][info[#info]] end,
				set = function(info, value) AR.db.Filters[PA.MyClass][selectedFilter][info[#info]] = value end,
				hidden = function() return not selectedFilter end,
				args = {
					enable = {
						order = 1,
						type = 'toggle',
						name = PA.ACL['Enable'],
					},
					filterType = {
						order = 2,
						type = 'select',
						name = PA.ACL['Filter Type'],
						desc = PA.ACL['Change this if you want the Reminder module to check for weapon enchants, setting this will cause it to ignore any spells listed.'],
						values = {
							WEAPON = PA.ACL['Weapon'],
							SPELL = PA.ACL['Spell'],
							COOLDOWN = PA.ACL['Cooldown'],
						},
					},
					xOffset = {
						order = 3,
						type = 'range',
						name = PA.ACL['X Offset'],
						min = -250, max = 250, step = 1,
					},
					yOffset = {
						order = 4,
						type = 'range',
						name = PA.ACL['Y Offset'],
						min = -250, max = 250, step = 1,
					},
					size = {
						order = 5,
						type = 'range',
						name = PA.ACL['Size'],
						min = 0, max = 64, step = 1,
					},
					conditions = {
						order = 10,
						type = 'group',
						name = PA.ACL['Conditions'],
						guiInline = true,
						args = {
							instance = {
								order = 1,
								type = 'toggle',
								name = PA.ACL['Inside Raid/Party'],
								desc = PA.ACL['Only run checks inside raid/party instances.'],
							},
							pvp = {
								order = 2,
								type = 'toggle',
								name = PA.ACL['Inside BG/Arena'],
								desc = PA.ACL['Only run checks inside BG/Arena instances.'],
							},
							combat = {
								order = 3,
								type = 'toggle',
								name = PA.ACL['Combat'],
								desc = PA.ACL['Only run checks during combat.'],
							},
						},
					},
					filterConditions = {
						order = 11,
						type = 'group',
						name = PA.ACL['Filter Conditions'],
						guiInline = true,
						args = {
							level = {
								order = 4,
								type = 'range',
								name = PA.ACL['Level Requirement'],
								desc = PA.ACL['Level requirement for the icon to be able to display. 0 for disabled.'],
								min = 0, max = MAX_PLAYER_LEVEL, step = 1,
							},
							personal = {
								order = 5,
								type = 'toggle',
								name = PA.ACL['Personal Buffs'],
								desc = PA.ACL['Only check if the buff is coming from you.'],
								hidden = function() return AR.db.Filters[PA.MyClass][selectedFilter].filterType ~= 'SPELL' end,
							},
							reverseCheck = {
								order = 6,
								type = 'toggle',
								name = PA.ACL['Reverse Check'],
								desc = PA.ACL['Instead of hiding the frame when you have the buff, show the frame when you have the buff.'],
								hidden = function() return AR.db.Filters[PA.MyClass][selectedFilter].filterType ~= 'SPELL' end,
							},
							strictFilter = {
								order = 7,
								type = 'toggle',
								name = PA.ACL['Strict Filter'],
								desc = PA.ACL['This ensures you can only see spells that you actually know. You may want to uncheck this option if you are trying to monitor a spell that is not directly clickable out of your spellbook.'],
								hidden = function() return AR.db.Filters[PA.MyClass][selectedFilter].filterType == 'COOLDOWN' end,
							},
							disableSound = {
								order = 8,
								type = 'toggle',
								name = PA.ACL['Disable Sound'],
								hidden = function() return AR.db.Filters[PA.MyClass][selectedFilter].filterType == 'COOLDOWN' end,
							},
						},
					},
					cooldownConditions = {
						order = 12,
						type = 'group',
						name = PA.ACL['Cooldown Conditions'],
						guiInline = true,
						hidden = function() return AR.db.Filters[PA.MyClass][selectedFilter].filterType ~= 'COOLDOWN' end,
						args = {
							dscription = {
								order = 0,
								type = 'description',
								fontSize = 'medium',
								name = function()
									local spellID = AR.db.Filters[PA.MyClass][selectedFilter].cooldownSpellID
									if not spellID or spellID == '' then return end
									return format('%s (%s)', GetSpellInfo(spellID), spellID)
								end,
								hidden = function() return AR.db.Filters[PA.MyClass][selectedFilter].cooldownSpellID == '' end,
							},
							cooldownSpellID = {
								order = 1,
								type = 'input',
								name = PA.ACL['Spell ID'],
								get = function(info) return tostring(AR.db.Filters[PA.MyClass][selectedFilter][info[#info]] or '') end,
								set = function(info, value)
									value = tonumber(value)
									if not value then return end

									AR.db.Filters[PA.MyClass][selectedFilter][info[#info]] = value
								end,
							},
							onCooldown = {
								order = 2,
								type = 'toggle',
								name = PA.ACL['Show On Cooldown'],
							},
							cooldownAlpha = {
								order = 3,
								type = 'range',
								name = PA.ACL['Cooldown Alpha'],
								min = 0, max = 1, step = 0.1,
								hidden = function() return not AR.db.Filters[PA.MyClass][selectedFilter].onCooldown end,
							},
						},
					},
					spellGroup = {
						order = 13,
						type = 'group',
						name = PA.ACL['Spells'],
						guiInline = true,
						get = function(info) return '' end,
						hidden = function() return AR.db.Filters[PA.MyClass][selectedFilter].filterType ~= 'SPELL' end,
						args = {
							AddSpell = {
								order = 0,
								type = 'input',
								name = PA.ACL['New ID'],
								set = function(info, value)
									value = tonumber(value)
									if not value then return end

									AR.db.Filters[PA.MyClass][selectedFilter].spellGroup[value] = true
									AR:UpdateFilterGroup('spellGroup')
								end,
							},
							RemoveSpell = {
								order = 1,
								type = 'select',
								name = PA.ACL['Remove ID'],
								get = function() return '' end,
								set = function(info, value)
									AR.db.Filters[PA.MyClass][selectedFilter].spellGroup[value] = nil;
									AR:UpdateFilterGroup('spellGroup')
								end,
								values = function()
									wipe(spellList)
									for spellID in pairs(AR.db.Filters[PA.MyClass][selectedFilter].spellGroup) do
										local name = GetSpellInfo(spellID)
										spellList[spellID] = name and format('%s (%s)', name, spellID) or spellID
									end
									return spellList
								end,
							},
						},
					},
					negateGroup = {
						order = 14,
						type = 'group',
						name = PA.ACL['Negate Spells'],
						guiInline = true,
						get = function(info) return '' end,
						hidden = function() return AR.db.Filters[PA.MyClass][selectedFilter].filterType ~= 'SPELL' end,
						args = {
							AddSpell = {
								order = 0,
								type = 'input',
								name = PA.ACL['New ID'],
								set = function(info, value)
									value = tonumber(value)
									if not value then return end

									AR.db.Filters[PA.MyClass][selectedFilter].negateGroup[value] = true
									AR:UpdateFilterGroup('negateGroup')
								end,
							},
							RemoveSpell = {
								order = 1,
								type = 'select',
								name = PA.ACL['Remove ID'],
								get = function() return '' end,
								set = function(info, value)
									AR.db.Filters[PA.MyClass][selectedFilter].negateGroup[value] = nil;
									AR:UpdateFilterGroup('spellGroup')
								end,
								values = function()
									wipe(spellList)
									for spellID in pairs(AR.db.Filters[PA.MyClass][selectedFilter].negateGroup) do
										local name = GetSpellInfo(spellID)
										spellList[spellID] = name and format('%s (%s)', name, spellID) or spellID
									end
									return spellList
								end,
							},
						},
					},
				},
			},
			AuthorHeader = {
				order = -4,
				type = 'header',
				name = PA.ACL['Authors:'],
			},
			Authors = {
				order = -3,
				type = 'description',
				name = AR.Authors,
				fontSize = 'large',
			},
		},
	}

	if PA.Retail then
		local optionGroup = PA.Options.args.AuraReminder.args.filterGroup.args.filterConditions.args

		local Specializations = {
			['1'] = select(2, GetSpecializationInfo(1)),
			['2'] = select(2, GetSpecializationInfo(2)),
			['3'] = select(2, GetSpecializationInfo(3)),
			['ANY'] = PA.ACL['Any'],
		}

		if PA.MyClass == 'DRUID' then
			Specializations['4'] = select(2, GetSpecializationInfo(4))
		end

		optionGroup.role = {
			order = 1,
			type = 'select',
			name = PA.ACL['Role'],
			desc = PA.ACL['You must be a certain role for the icon to appear.'],
			values = {
				TANK = PA.ACL['Tank'],
				DAMAGER = PA.ACL['Damage'],
				HEALER = PA.ACL['Healer'],
				ANY = PA.ACL['Any'],
			},
		}

		optionGroup.tree = {
			order = 2,
			type = 'select',
			name = PA.ACL['Talent Tree'],
			desc = PA.ACL['You must be using a certain talent tree for the icon to show.'],
			hidden = function() return AR.db.Filters[PA.MyClass][selectedFilter].reverseCheck end,
			get = function(info, value) return tostring(AR.db.Filters[PA.MyClass][selectedFilter].tree) end,
			set = function(info, value)
				if value == 'ANY' then
					AR.db.Filters[PA.MyClass][selectedFilter].tree = 'ANY'
				else
					AR.db.Filters[PA.MyClass][selectedFilter].tree = tonumber(value)
				end
			end,
			values = Specializations,
		}

		optionGroup.talentTreeException = {
			order = 2,
			type = 'select',
			name = PA.ACL['Tree Exception'],
			desc = PA.ACL['Set a talent tree to not follow the reverse check.'],
			get = function(info) return tostring(AR.db.Filters[PA.MyClass][selectedFilter]['talentTreeException'] or 'NONE') end,
			set = function(info, value) if value == 'NONE' then AR.db.Filters[PA.MyClass][selectedFilter].talentTreeException = nil else AR.db.Filters[PA.MyClass][selectedFilter]['talentTreeException'] = tonumber(value) end; end,
			hidden = function() return not AR.db.Filters[PA.MyClass][selectedFilter].reverseCheck end,
			values = CopyTable(Specializations),
		}

		optionGroup.talentTreeException.values.NONE = PA.ACL['None']
	end
end

function AR:BuildProfile()
	PA.Defaults.profile.AuraReminder = {
		Enable = true,
		Sound = 'Warning',
		Filters = {},
	}

	for k in pairs(LOCALIZED_CLASS_NAMES_MALE) do PA.Defaults.profile.AuraReminder.Filters[k] = {} end

	DefaultFilters = CopyTable(PA.Defaults.profile.AuraReminder.Filters)
end

function AR:Initialize()
	AR.db = PA.db.AuraReminder

	if AR.db.Enable ~= true then
		return
	end

	AR.isEnabled = true

	AR:ScheduleRepeatingTimer('Reminder_Update', .5)
end
