iFilger.lua 39 KB
Newer Older
Azilroka's avatar
Azilroka committed
1 2 3 4
local PA = _G.ProjectAzilroka
local iFilger = PA:NewModule('iFilger', 'AceEvent-3.0', 'AceTimer-3.0')
PA.iFilger = iFilger

Azilroka's avatar
Azilroka committed
5
iFilger.Title = '|cFF16C3F2i|r|cFFFFFFFFFilger|r'
Azilroka's avatar
Azilroka committed
6 7 8 9 10
iFilger.Description = 'Minimalistic Auras / Buffs / Procs / Cooldowns'
iFilger.Authors = 'Azilroka    Nils Ruesch    Ildyria'

iFilger.isEnabled = false

11 12
local _G = _G

Azilroka's avatar
Azilroka committed
13 14 15 16 17
_G.iFilger = iFilger

local CreateFrame = CreateFrame
local UIParent = UIParent

18
local floor = floor
Azilroka's avatar
Azilroka committed
19
local format = format
20 21 22
local ipairs = ipairs
local next = next
local pairs = pairs
Azilroka's avatar
Azilroka committed
23
local select = select
24 25
local sort = sort
local strmatch = strmatch
Azilroka's avatar
Azilroka committed
26
local tinsert = tinsert
27 28 29 30 31 32 33 34 35 36 37 38
local tonumber = tonumber
local tostring = tostring
local type = type
local unpack = unpack
local wipe = wipe

local CopyTable = CopyTable
local GetContainerItemCooldown = GetContainerItemCooldown
local GetContainerItemID = GetContainerItemID
local GetContainerNumSlots = GetContainerNumSlots
local GetFlyoutInfo = GetFlyoutInfo
local GetFlyoutSlotInfo = GetFlyoutSlotInfo
Azilroka's avatar
Azilroka committed
39
local GetInventoryItemCooldown = GetInventoryItemCooldown
40 41 42 43 44 45 46 47 48 49 50
local GetInventoryItemLink = GetInventoryItemLink
local GetItemCooldown = GetItemCooldown
local GetItemIcon = GetItemIcon
local GetItemInfo = GetItemInfo
local GetSpellBookItemInfo = GetSpellBookItemInfo
local GetSpellBookItemName = GetSpellBookItemName
local GetSpellCharges = GetSpellCharges
local GetSpellCooldown = GetSpellCooldown
local GetSpellInfo = GetSpellInfo
local GetSpellLink = GetSpellLink
local GetTime = GetTime
Azilroka's avatar
Azilroka committed
51
local IsSpellKnown = IsSpellKnown
52 53
local RegisterUnitWatch = RegisterUnitWatch
local UnitAura = UnitAura
Azilroka's avatar
Azilroka committed
54 55 56

local VISIBLE = 1
local HIDDEN = 0
Azilroka's avatar
Azilroka committed
57 58 59
local selectedSpell = ''
local selectedFilter = nil
local spellList = {}
Azilroka's avatar
Azilroka committed
60

Azilroka's avatar
Azilroka committed
61 62 63 64 65 66
iFilger.Cooldowns = {}
iFilger.ActiveCooldowns = {}
iFilger.DelayCooldowns = {}
iFilger.IsChargeCooldown = {}
iFilger.SpellList = {}
iFilger.CompleteSpellBook = {}
Azilroka's avatar
Azilroka committed
67
iFilger.ItemCooldowns = {}
Azilroka's avatar
Azilroka committed
68 69 70
iFilger.HasCDDelay = {
	[5384] = true
}
Azilroka's avatar
Azilroka committed
71

Azilroka's avatar
1.61  
Azilroka committed
72
local GLOBAL_COOLDOWN_TIME = 1.5
Azilroka's avatar
Azilroka committed
73 74
local COOLDOWN_MIN_DURATION = .1
local AURA_MIN_DURATION = .1
Azilroka's avatar
1.61  
Azilroka committed
75

Azilroka's avatar
Azilroka committed
76 77 78
-- Simpy Magic
local t = {}
for _, name in pairs({'SPELL_RECAST_TIME_SEC','SPELL_RECAST_TIME_MIN','SPELL_RECAST_TIME_CHARGES_SEC','SPELL_RECAST_TIME_CHARGES_MIN'}) do
Azilroka's avatar
Azilroka committed
79
    t[name] = _G[name]:gsub('%%%.%dg','[%%d%%.]-'):gsub('%.$','%%.'):gsub('^(.-)$','^%1$')
Azilroka's avatar
Azilroka committed
80 81
end

Azilroka's avatar
Azilroka committed
82
function iFilger:Spawn(unit, name, db, filter, position)
83
	local object = CreateFrame('Button', 'iFilger_'..name, PA.PetBattleFrameHider)
Azilroka's avatar
Azilroka committed
84 85 86 87 88 89
	object:SetSize(100, 20)
	object:SetPoint(unpack(position))
	object.db = db
	object.name = name
	object.createdIcons = 0
	object.anchoredIcons = 0
Azilroka's avatar
Azilroka committed
90 91
	object.Whitelist = db.Whitelist
	object.Blacklist = db.Blacklist
fgprodigal's avatar
fgprodigal committed
92
	object:EnableMouse(false)
Azilroka's avatar
Azilroka committed
93 94
	iFilger:CreateMover(object)

Azilroka's avatar
Azilroka committed
95
	if name ~= 'Cooldowns' and name ~= 'ItemCooldowns' then
Azilroka's avatar
Azilroka committed
96 97 98 99 100 101 102 103 104 105
		object:SetAttribute('unit', unit)
		object.unit = unit
		object.filter = filter
		object:RegisterEvent('UNIT_AURA')
		object:SetScript('OnEvent', function() iFilger:UpdateAuras(object, unit) end)
		RegisterUnitWatch(object)

		if not db.Enable then
			iFilger:DisableUnit(object)
		end
Azilroka's avatar
Azilroka committed
106 107
	end

Azilroka's avatar
Azilroka committed
108 109 110 111 112 113
	return object
end

function iFilger:DisableUnit(button)
	button:Disable()
	button:UnregisterEvent('UNIT_AURA')
Azilroka's avatar
Azilroka committed
114
	for _, element in ipairs(button) do
Azilroka's avatar
Azilroka committed
115
		element:Hide()
Azilroka's avatar
Azilroka committed
116
	end
Azilroka's avatar
Azilroka committed
117 118 119 120
end

function iFilger:EnableUnit(button)
	button:Enable()
Azilroka's avatar
Azilroka committed
121
	button:RegisterEvent('UNIT_AURA')
Azilroka's avatar
Azilroka committed
122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151
end

function iFilger:ScanTooltip(index, bookType)
	PA.ScanTooltip:SetOwner(_G.UIParent, 'ANCHOR_NONE')
	PA.ScanTooltip:SetSpellBookItem(index, bookType)
	PA.ScanTooltip:Show()

	for i = 2, 4 do
		local str = _G['PAScanTooltipTextRight'..i]
		local text = str and str:GetText()
		if text then
			for _, matchtext in pairs(t) do
				if strmatch(text, matchtext) then
					return true
				end
			end
		end
	end
end

function iFilger:ScanSpellBook(bookType, numSpells, offset)
	offset = offset or 0
	for index = offset + 1, offset + numSpells, 1 do
		local skillType, special = GetSpellBookItemInfo(index, bookType)
		if skillType == 'SPELL' or skillType == 'PETACTION' then
			local SpellID, SpellName, Rank
			if PA.Retail then
				SpellID = select(2, GetSpellLink(index, bookType))
			else
				SpellName, Rank, SpellID = GetSpellBookItemName(index, bookType)
Azilroka's avatar
iFilger  
Azilroka committed
152 153 154
				if Rank ~= '' and Rank ~= nil then
					SpellName = format('%s %s', SpellName, Rank)
				end
Azilroka's avatar
Azilroka committed
155
			end
Azilroka's avatar
Azilroka committed
156 157 158 159 160
			if SpellID then
				iFilger.CompleteSpellBook[SpellID] = true
				if iFilger:ScanTooltip(index, bookType) then
					iFilger.SpellList[SpellID] = SpellName or true
				end
Azilroka's avatar
Azilroka committed
161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189
			end
		elseif skillType == 'FLYOUT' then
			local flyoutId = special
			local _, _, numSlots, isKnown = GetFlyoutInfo(flyoutId)
			if numSlots > 0 and isKnown then
				for flyoutIndex = 1, numSlots, 1 do
					local SpellID, overrideId = GetFlyoutSlotInfo(flyoutId, flyoutIndex)
					if SpellID ~= overrideId then
						iFilger.CompleteSpellBook[overrideId] = true
					else
						iFilger.CompleteSpellBook[SpellID] = true
					end
					if iFilger:ScanTooltip(index, bookType) then
						if SpellID ~= overrideId then
							iFilger.SpellList[overrideId] = true
						else
							iFilger.SpellList[SpellID] = true
						end
					end
				end
			end
		elseif skillType == 'FUTURESPELL' then
		elseif not skillType then
			break
		end
	end
end

function iFilger:UpdateActiveCooldowns()
Azilroka's avatar
Azilroka committed
190 191 192 193
	local Panel = iFilger.Panels.Cooldowns

	for i = PA:CountTable(iFilger.ActiveCooldowns) + 1, #Panel do
		Panel[i]:Hide()
Azilroka's avatar
Azilroka committed
194 195 196 197 198 199 200 201
	end

	local Position = 0
	for SpellID in pairs(iFilger.ActiveCooldowns) do
		local Name, _, Icon = GetSpellInfo(SpellID)

		if Name then
			Position = Position + 1
Azilroka's avatar
Azilroka committed
202
			local button = Panel[Position] or iFilger:CreateAuraIcon(Panel)
Azilroka's avatar
Azilroka committed
203 204 205 206 207 208 209 210 211

			local Start, Duration, CurrentDuration, Charges

			if iFilger.IsChargeCooldown[SpellID] then
				Charges, _, Start, Duration = GetSpellCharges(SpellID)
			else
				Start, Duration = GetSpellCooldown(SpellID)
			end

Azilroka's avatar
Azilroka committed
212
			CurrentDuration = (Start + Duration - GetTime())
Azilroka's avatar
Azilroka committed
213

Azilroka's avatar
Azilroka committed
214 215 216 217 218 219 220 221 222
			if Charges and Start == (((2^32)/1000) - Duration) then
				CurrentDuration = 0
			end

			button.duration = Duration
			button.spellID = SpellID
			button.spellName = Name

			button.Texture:SetTexture(Icon)
Azilroka's avatar
Azilroka committed
223
			button:SetShown(CurrentDuration and CurrentDuration >= COOLDOWN_MIN_DURATION)
Azilroka's avatar
Azilroka committed
224

Azilroka's avatar
Azilroka committed
225
			if (CurrentDuration and CurrentDuration >= COOLDOWN_MIN_DURATION) then
Azilroka's avatar
Azilroka committed
226
				if Panel.db.StatusBar then
Azilroka's avatar
Azilroka committed
227
					local timervalue, formatid = PA:GetTimeInfo(CurrentDuration, iFilger.db.Cooldown.threshold)
Azilroka's avatar
Azilroka committed
228 229 230 231
					local color = PA.TimeColors[formatid]

					button.StatusBar:SetValue(CurrentDuration / Duration)
					button.StatusBar.Time:SetFormattedText(PA.TimeFormats[formatid][1], timervalue)
Azilroka's avatar
Azilroka committed
232
					button.StatusBar.Time:SetTextColor(unpack(PA.TimeColors[formatid]))
Azilroka's avatar
Azilroka committed
233 234 235
					button.StatusBar.Time:SetTextColor(color.r, color.g, color.b)
					if Panel.db.FollowCooldownText and (formatid == 1 or formatid == 2) then
						button.StatusBar:SetStatusBarColor(color.r, color.g, color.b)
Azilroka's avatar
Azilroka committed
236
					end
Azilroka's avatar
Azilroka committed
237 238

					button.StatusBar.Name:SetText(Name)
Azilroka's avatar
Azilroka committed
239
				else
Azilroka's avatar
Azilroka committed
240
					button.Cooldown:SetCooldown(Start, Duration)
Azilroka's avatar
Azilroka committed
241
				end
Azilroka's avatar
Azilroka committed
242 243 244

				button.Cooldown:SetShown(not Panel.db.StatusBar)
				button.StatusBar:SetShown(Panel.db.StatusBar)
Azilroka's avatar
Azilroka committed
245 246
			else
				iFilger.ActiveCooldowns[SpellID] = nil
Azilroka's avatar
Azilroka committed
247
				button.CurrentDuration = 0
Azilroka's avatar
Azilroka committed
248 249 250
			end
		end
	end
Azilroka's avatar
Azilroka committed
251 252

	iFilger:SetPosition(Panel)
Azilroka's avatar
Azilroka committed
253 254
end

Azilroka's avatar
Azilroka committed
255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276
function iFilger:UpdateItemCooldowns()
	local Panel = iFilger.Panels.ItemCooldowns

	for i = PA:CountTable(iFilger.ItemCooldowns) + 1, #Panel do
		Panel[i]:Hide()
	end

	local Position = 0
	for itemID in pairs(iFilger.ItemCooldowns) do
		local Name = GetItemInfo(itemID)

		if Name then
			Position = Position + 1
			local button = Panel[Position] or iFilger:CreateAuraIcon(Panel)

			local Start, Duration, CurrentDuration
			Start, Duration = GetItemCooldown(itemID)
			CurrentDuration = (Start + Duration - GetTime())

			button.duration = Duration
			button.itemID = itemID
			button.itemName = Name
Azilroka's avatar
Azilroka committed
277
			button.expiration = Start + Duration
Azilroka's avatar
Azilroka committed
278 279

			button.Texture:SetTexture(GetItemIcon(itemID))
Azilroka's avatar
Azilroka committed
280
			button:SetShown(CurrentDuration and CurrentDuration >= COOLDOWN_MIN_DURATION)
Azilroka's avatar
Azilroka committed
281

Azilroka's avatar
Azilroka committed
282
			if (CurrentDuration and CurrentDuration >= COOLDOWN_MIN_DURATION) then
Azilroka's avatar
Azilroka committed
283
				if Panel.db.StatusBar then
Azilroka's avatar
Azilroka committed
284
					local timervalue, formatid = PA:GetTimeInfo(CurrentDuration, iFilger.db.Cooldown.threshold)
Azilroka's avatar
Azilroka committed
285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311
					local color = PA.TimeColors[formatid]

					button.StatusBar:SetValue(CurrentDuration / Duration)
					button.StatusBar.Time:SetFormattedText(PA.TimeFormats[formatid][1], timervalue)
					button.StatusBar.Time:SetTextColor(unpack(PA.TimeColors[formatid]))
					button.StatusBar.Time:SetTextColor(color.r, color.g, color.b)
					if Panel.db.FollowCooldownText and (formatid == 1 or formatid == 2) then
						button.StatusBar:SetStatusBarColor(color.r, color.g, color.b)
					end

					button.StatusBar.Name:SetText(Name)
				else
					button.Cooldown:SetCooldown(Start, Duration)
				end

				button.Cooldown:SetShown(not Panel.db.StatusBar)
				button.StatusBar:SetShown(Panel.db.StatusBar)
			else
				iFilger.ItemCooldowns[itemID] = nil
				button.CurrentDuration = 0
			end
		end
	end

	iFilger:SetPosition(Panel)
end

Azilroka's avatar
Azilroka committed
312 313 314 315 316 317 318 319 320 321 322 323 324 325 326
function iFilger:UpdateDelayedCooldowns()
	local Start, Duration, Enable, CurrentDuration, Charges, _

	for SpellID in pairs(iFilger.DelayCooldowns) do
		Start, Duration, Enable = GetSpellCooldown(SpellID)

		if iFilger.IsChargeCooldown[SpellID] then
			Charges, _, Start, Duration = GetSpellCharges(SpellID)
			if Charges then
				Start, Duration = Start, Duration
			end
		end

		CurrentDuration = (Start + Duration - GetTime())

Azilroka's avatar
Azilroka committed
327
		if Enable and CurrentDuration and (CurrentDuration < iFilger.db.Cooldowns.SuppressDuration) then
Azilroka's avatar
Azilroka committed
328 329 330 331 332 333 334 335
			iFilger.DelayCooldowns[SpellID] = nil
			iFilger.ActiveCooldowns[SpellID] = Duration
		end
	end
end

function iFilger:CreateMover(frame)
	if PA.ElvUI then
336
		_G.ElvUI[1]:CreateMover(frame, frame:GetName()..'Mover', frame:GetName(), nil, nil, nil, 'ALL,iFilger', nil, 'ProjectAzilroka,iFilger,'..frame.name)
Azilroka's avatar
Azilroka committed
337
	elseif PA.Tukui then
Azilroka's avatar
Azilroka committed
338
		_G.Tukui[1]['Movers']:RegisterFrame(frame)
Azilroka's avatar
Azilroka committed
339 340 341 342 343 344
	end
end

function iFilger:IsAuraRemovable(dispelType)
	if not dispelType then return end

Azilroka's avatar
Azilroka committed
345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362
	if PA.MyClass == 'DEMONHUNTER' then
		return dispelType == 'Magic' and IsSpellKnown(205604)
	elseif PA.MyClass == 'DRUID' then
		return (dispelType == 'Curse' or dispelType == 'Poison') and IsSpellKnown(2782) or (dispelType == 'Magic' and (IsSpellKnown(88423) or IsSpellKnown(2782)))
	elseif PA.MyClass == 'HUNTER' then
		return (dispelType == 'Disease' or dispelType == 'Poison') and IsSpellKnown(212640)
	elseif PA.MyClass == 'MAGE' then
		return dispelType == 'Curse' and IsSpellKnown(475) or dispelType == 'Magic' and IsSpellKnown(30449)
	elseif PA.MyClass == 'MONK' then
		return dispelType == 'Magic' and IsSpellKnown(115450) or (dispelType == 'Disease' or dispelType == 'Poison') and (IsSpellKnown(115450) or IsSpellKnown(218164))
	elseif PA.MyClass == 'PALADIN' then
		return dispelType == 'Magic' and IsSpellKnown(4987) or (dispelType == 'Disease' or dispelType == 'Poison') and (IsSpellKnown(4987) or IsSpellKnown(213644))
	elseif PA.MyClass == 'PRIEST' then
		return dispelType == 'Magic' and (IsSpellKnown(528) or IsSpellKnown(527)) or dispelType == 'Disease' and IsSpellKnown(213634)
	elseif PA.MyClass == 'SHAMAN' then
		return dispelType == 'Magic' and (IsSpellKnown(370) or IsSpellKnown(77130)) or dispelType == 'Curse' and (IsSpellKnown(77130) or IsSpellKnown(51886))
	elseif PA.MyClass == 'WARLOCK' then
		return dispelType == 'Magic' and (IsSpellKnown(171021, true) or IsSpellKnown(89808, true) or IsSpellKnown(212623))
Azilroka's avatar
Azilroka committed
363 364 365 366 367 368
	end

	return false
end

function iFilger:CustomFilter(element, unit, button, name, texture, count, debuffType, duration, expiration, caster, isStealable, nameplateShowSelf, spellID, canApply, isBossDebuff, casterIsPlayer)
Azilroka's avatar
Azilroka committed
369
	if duration == 0 then
Azilroka's avatar
Azilroka committed
370
		return false
Azilroka's avatar
Azilroka committed
371 372 373 374 375 376 377 378 379 380
	end
	if element.db.FilterByList == 'Blacklist' then
		return not element.Blacklist[spellID]
	elseif element.db.FilterByList == 'Whitelist' then
		return element.Whitelist[spellID]
	elseif element.db.FilterByList == 'None' then
		if element.name == 'Procs' then
			if (caster == 'player' or caster == 'pet') then
				return not iFilger.CompleteSpellBook[spellID]
			end
Azilroka's avatar
Azilroka committed
381
		else
Azilroka's avatar
Azilroka committed
382 383 384 385 386 387
			local isPlayer = (caster == 'player' or caster == 'vehicle' or caster == 'pet')
			if (isPlayer or casterIsPlayer) and (duration ~= 0) then
				return true
			else
				return false
			end
Azilroka's avatar
Azilroka committed
388 389 390 391 392
		end
	end
end

function iFilger:UpdateAuraIcon(element, unit, index, offset, filter, isDebuff, visible)
Azilroka's avatar
Azilroka committed
393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408
	local name, texture, count, debuffType, duration, expiration, caster, isStealable, nameplateShowSelf, spellID, canApply, isBossDebuff, casterIsPlayer, nameplateShowAll, timeMod, effect1, effect2, effect3

	if PA.Classic and PA.LCD and not UnitIsUnit('player', unit) then
		local durationNew, expirationTimeNew
		name, texture, count, debuffType, duration, expiration, caster, isStealable, nameplateShowSelf, spellID, canApply, isBossDebuff, casterIsPlayer, nameplateShowAll, timeMod, effect1, effect2, effect3 = PA.LCD:UnitAura(unit, index, filter)

		if spellID then
			durationNew, expirationTimeNew = PA.LCD:GetAuraDurationByUnit(unit, spellID, caster, name)
		end

		if durationNew and durationNew > 0 then
			duration, expiration = durationNew, expirationTimeNew
		end
	else
		name, texture, count, debuffType, duration, expiration, caster, isStealable, nameplateShowSelf, spellID, canApply, isBossDebuff, casterIsPlayer, nameplateShowAll, timeMod, effect1, effect2, effect3 = UnitAura(unit, index, filter)
	end
Azilroka's avatar
Azilroka committed
409 410 411

	if name then
		local position = visible + offset + 1
Azilroka's avatar
Azilroka committed
412
		local button = element[position] or iFilger:CreateAuraIcon(element, position)
Azilroka's avatar
Azilroka committed
413 414 415 416 417 418 419

		button.caster = caster
		button.filter = filter
		button.isDebuff = isDebuff
		button.isPlayer = caster == 'player' or caster == 'vehicle'
		button.expiration = expiration
		button.duration = duration
Azilroka's avatar
Azilroka committed
420
		button.spellID = spellID
Azilroka's avatar
Azilroka committed
421 422 423 424 425

		local show = iFilger:CustomFilter(element, unit, button, name, texture, count, debuffType, duration, expiration, caster, isStealable, nameplateShowSelf, spellID, canApply, isBossDebuff, casterIsPlayer, nameplateShowAll,timeMod, effect1, effect2, effect3)

		if show then
			if not element.db.StatusBar then
Azilroka's avatar
Azilroka committed
426
				if (duration and duration >= AURA_MIN_DURATION) then
Azilroka's avatar
Azilroka committed
427 428
					button.Cooldown:SetCooldown(expiration - duration, duration)
				end
Azilroka's avatar
Azilroka committed
429
				button.Cooldown:SetShown(duration and duration >= AURA_MIN_DURATION)
Azilroka's avatar
Azilroka committed
430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459
			end

			button.StatusBar:SetStatusBarColor(unpack(element.db.StatusBarTextureColor))

			button.Texture:SetTexture(texture)
			button.Stacks:SetText(count > 1 and count)
			button.StatusBar.Name:SetText(name)

			button:SetID(index)
			button:Show()

			if isDebuff then
				button.Backdrop:SetBackdropBorderColor(1, 0, 0)
			else
				button.Backdrop:SetBackdropBorderColor(0, 0, 0)
			end

			return VISIBLE
		else
			return HIDDEN
		end
	end
end

function iFilger:SetPosition(element)
	local sizex = (element.db.Size + element.db.Spacing + 2) + (element.db.StatusBar and element.db.StatusBarWidth or 0)
	local sizey = element.db.Size + element.db.Spacing + 2
	local anchor = element.initialAnchor or 'BOTTOMLEFT'
	local growthx = not element.db.StatusBar and (element.db.Direction == 'LEFT' and -1) or 1
	local growthy = ((element.db.StatusBar and element.db.StatusBarDirection == 'DOWN' or element.db.Direction == 'DOWN') and -1) or 1
Azilroka's avatar
iFilger  
Azilroka committed
460
	local cols = element.db.StatusBar and 1 or element.db.NumPerRow
Azilroka's avatar
Azilroka committed
461

Azilroka's avatar
Azilroka committed
462
	local col, row
Azilroka's avatar
Azilroka committed
463
	for i, button in ipairs(element) do
Azilroka's avatar
Azilroka committed
464
		if (not button) then break end
Azilroka's avatar
Azilroka committed
465 466
		col = (i - 1) % cols
		row = floor((i - 1) / cols)
Azilroka's avatar
Azilroka committed
467 468 469 470 471 472 473 474

		button:ClearAllPoints()
		button:SetPoint(anchor, element, anchor, col * sizex * growthx, row * sizey * growthy)
	end
end

function iFilger:FilterAuraIcons(element, unit, filter, limit, isDebuff, offset, dontHide)
	if (not offset) then offset = 0 end
Azilroka's avatar
Azilroka committed
475 476
	local index, visible, hidden = 1, 0, 0

Azilroka's avatar
Azilroka committed
477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507
	while (visible < limit) do
		local result = iFilger:UpdateAuraIcon(element, unit, index, offset, filter, isDebuff, visible)
		if (not result) then
			break
		elseif (result == VISIBLE) then
			visible = visible + 1
		elseif (result == HIDDEN) then
			hidden = hidden + 1
		end

		index = index + 1
	end

	if (not dontHide) then
		for i = visible + offset + 1, #element do
			element[i]:Hide()
		end
	end

	return visible, hidden
end

function iFilger:UpdateAuras(element, unit)
	if(element.unit ~= unit) then return end

	iFilger:FilterAuraIcons(element, unit, element.filter, element.numAuras or 32, nil, 0)

	iFilger:SetPosition(element)
end

function iFilger:PLAYER_ENTERING_WORLD()
Azilroka's avatar
Azilroka committed
508
	for SpellID in pairs(iFilger.db.Cooldowns.SpellCDs) do
Azilroka's avatar
Azilroka committed
509 510 511
		local Start, Duration, Enable = GetSpellCooldown(SpellID)
		local CurrentDuration = (Start + Duration - GetTime()) or 0

Azilroka's avatar
Azilroka committed
512 513
		if Enable and (CurrentDuration > .1) and (CurrentDuration < iFilger.db.Cooldowns.IgnoreDuration) then
			if (CurrentDuration >= iFilger.db.Cooldowns.SuppressDuration) then
Azilroka's avatar
Azilroka committed
514
				iFilger.DelayCooldowns[SpellID] = true
Azilroka's avatar
Azilroka committed
515
			elseif (CurrentDuration > GLOBAL_COOLDOWN_TIME) then
Azilroka's avatar
Azilroka committed
516
				iFilger.ActiveCooldowns[SpellID] = true
Azilroka's avatar
Azilroka committed
517 518 519 520 521 522 523
			end
		end
	end

	if iFilger.db.SortByDuration then
		sort(iFilger.ActiveCooldowns)
	end
Azilroka's avatar
Azilroka committed
524 525

	iFilger:UnregisterEvent('PLAYER_ENTERING_WORLD')
Azilroka's avatar
Azilroka committed
526 527 528
end

function iFilger:UNIT_SPELLCAST_SUCCEEDED(_, unit, _, SpellID)
Azilroka's avatar
Azilroka committed
529
	if (unit == 'player' or unit == 'pet') and iFilger.db.Cooldowns.SpellCDs[SpellID] then
Azilroka's avatar
Azilroka committed
530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553
		iFilger.Cooldowns[SpellID] = true
	end
end

function iFilger:SPELL_UPDATE_COOLDOWN()
	local Start, Duration, Enable, Charges, _, ChargeStart, ChargeDuration, CurrentDuration

	for SpellID in pairs(iFilger.Cooldowns) do
		Start, Duration, Enable = GetSpellCooldown(SpellID)

		if iFilger.IsChargeCooldown[SpellID] ~= false then
			Charges, _, ChargeStart, ChargeDuration = GetSpellCharges(SpellID)

			if iFilger.IsChargeCooldown[SpellID] == nil then
				iFilger.IsChargeCooldown[SpellID] = Charges and true or false
			end

			if Charges then
				Start, Duration = ChargeStart, ChargeDuration
			end
		end

		CurrentDuration = (Start + Duration - GetTime())

Azilroka's avatar
Azilroka committed
554
		if Enable and CurrentDuration and (CurrentDuration < iFilger.db.Cooldowns.IgnoreDuration) then
Azilroka's avatar
Azilroka committed
555
			if (CurrentDuration >= iFilger.db.Cooldowns.SuppressDuration) or iFilger.HasCDDelay[SpellID] then
Azilroka's avatar
Azilroka committed
556
				iFilger.DelayCooldowns[SpellID] = true
Azilroka's avatar
Azilroka committed
557
			elseif (CurrentDuration > GLOBAL_COOLDOWN_TIME) then
Azilroka's avatar
Azilroka committed
558
				iFilger.ActiveCooldowns[SpellID] = true
Azilroka's avatar
Azilroka committed
559 560 561 562 563 564 565 566 567 568 569
			end
		end

		iFilger.Cooldowns[SpellID] = nil
	end

	if iFilger.db.SortByDuration then
		sort(iFilger.ActiveCooldowns)
	end
end

Azilroka's avatar
Azilroka committed
570
function iFilger:BAG_UPDATE_COOLDOWN()
571
	for bagID = 0, 4 do
Azilroka's avatar
Azilroka committed
572 573 574 575
		for slotID = 1, GetContainerNumSlots(bagID) do
			local itemID = GetContainerItemID(bagID, slotID)
			if itemID then
				local start, duration, enable = GetContainerItemCooldown(bagID, slotID)
Azilroka's avatar
1.61  
Azilroka committed
576
				if duration and duration > GLOBAL_COOLDOWN_TIME then
Azilroka's avatar
Azilroka committed
577 578 579 580 581 582 583
					iFilger.ItemCooldowns[itemID] = true
				end
			end
		end
	end
end

Azilroka's avatar
Azilroka committed
584 585 586 587 588 589 590 591 592 593 594 595 596
function iFilger:CreateAuraIcon(element)
	local Frame = CreateFrame('Button', nil, element)
	Frame:EnableMouse(false)
	Frame:SetSize(element.db.Size, element.db.Size)

	Frame.Cooldown = CreateFrame('Cooldown', nil, Frame, 'CooldownFrameTemplate')
	Frame.Cooldown:SetAllPoints()
	Frame.Cooldown:SetReverse(false)
	Frame.Cooldown:SetDrawEdge(false)
	Frame.Cooldown.CooldownOverride = 'iFilger'
	PA:RegisterCooldown(Frame.Cooldown)

	Frame.Texture = Frame:CreateTexture(nil, 'ARTWORK')
Azilroka's avatar
1.61  
Azilroka committed
597
	PA:SetInside(Frame.Texture)
Azilroka's avatar
Azilroka committed
598 599
	Frame.Texture:SetTexCoord(unpack(PA.TexCoords))

600 601 602 603 604
	local stackFrame = CreateFrame('Frame', nil, Frame)
	stackFrame:SetAllPoints(Frame)
	stackFrame:SetFrameLevel(Frame.Cooldown:GetFrameLevel() + 1)

	Frame.Stacks = stackFrame:CreateFontString(nil, 'OVERLAY', 'NumberFontNormal')
Azilroka's avatar
Azilroka committed
605 606 607 608 609 610 611 612 613 614
	Frame.Stacks:SetFont(PA.LSM:Fetch('font', element.db.StackCountFont), element.db.StackCountFontSize, element.db.StackCountFontFlag)
	Frame.Stacks:SetPoint('BOTTOMRIGHT', Frame, 'BOTTOMRIGHT', 0, 2)

	Frame.StatusBar = CreateFrame('StatusBar', nil, Frame)
	Frame.StatusBar:SetSize(element.db.StatusBarWidth, element.db.StatusBarHeight)
	Frame.StatusBar:SetStatusBarTexture(PA.LSM:Fetch('statusbar', element.db.StatusBarTexture))
	Frame.StatusBar:SetStatusBarColor(unpack(element.db.StatusBarTextureColor))
	Frame.StatusBar:SetPoint('BOTTOMLEFT', Frame, 'BOTTOMRIGHT', 2, 0)
	Frame.StatusBar:SetMinMaxValues(0, 1)
	Frame.StatusBar:SetValue(0)
Azilroka's avatar
Azilroka committed
615

Azilroka's avatar
Azilroka committed
616
	if element.name ~= 'Cooldowns' and element.name ~= 'ItemCooldowns' then
617
		Frame.Cooldown:SetReverse(true)
Azilroka's avatar
Azilroka committed
618 619
		Frame.StatusBar:SetScript('OnUpdate', function(s, elapsed)
			s.elapsed = (s.elapsed or 0) + elapsed
Azilroka's avatar
Azilroka committed
620
			if (s.elapsed > COOLDOWN_MIN_DURATION) then
Azilroka's avatar
Azilroka committed
621
				local expiration = Frame.expiration - GetTime()
Azilroka's avatar
Azilroka committed
622
				local timervalue, formatid = PA:GetTimeInfo(expiration, iFilger.db.Cooldown.threshold)
Azilroka's avatar
Azilroka committed
623 624 625 626 627 628 629 630 631
				local color = PA.TimeColors[formatid]
				if timervalue then
					local Normalized = expiration / Frame.duration
					s:SetValue(Normalized)
					s.Time:SetFormattedText(PA.TimeFormats[formatid][1], timervalue)
					s.Time:SetTextColor(color.r, color.g, color.b)
					if element.db.FollowCooldownText and (formatid == 1 or formatid == 2) then
						s:SetStatusBarColor(color.r, color.g, color.b)
					end
Azilroka's avatar
Azilroka committed
632
				end
Azilroka's avatar
Azilroka committed
633
				self.elapsed = 0
Azilroka's avatar
Azilroka committed
634
			end
Azilroka's avatar
Azilroka committed
635 636
		end)
	end
Azilroka's avatar
Azilroka committed
637 638 639 640 641 642 643 644 645 646 647 648

	Frame.StatusBar.Name = Frame.StatusBar:CreateFontString(nil, 'OVERLAY')
	Frame.StatusBar.Name:SetFont(PA.LSM:Fetch('font', element.db.StatusBarFont), element.db.StatusBarFontSize, element.db.StatusBarFontFlag)
	Frame.StatusBar.Name:SetPoint('BOTTOMLEFT', Frame.StatusBar, element.db.StatusBarNameX, element.db.StatusBarNameY)
	Frame.StatusBar.Name:SetJustifyH('LEFT')

	Frame.StatusBar.Time = Frame.StatusBar:CreateFontString(nil, 'OVERLAY')
	Frame.StatusBar.Time:SetFont(PA.LSM:Fetch('font', element.db.StatusBarFont), element.db.StatusBarFontSize, element.db.StatusBarFontFlag)
	Frame.StatusBar.Time:SetPoint('BOTTOMRIGHT', Frame.StatusBar, element.db.StatusBarTimeX, element.db.StatusBarTimeY)
	Frame.StatusBar.Time:SetJustifyH('RIGHT')

	PA:CreateBackdrop(Frame)
Azilroka's avatar
Azilroka committed
649
	PA:CreateShadow(Frame.Backdrop)
Azilroka's avatar
Azilroka committed
650 651 652
	PA:CreateBackdrop(Frame.StatusBar, 'Default')
	PA:CreateShadow(Frame.StatusBar.Backdrop)

Azilroka's avatar
Azilroka committed
653 654 655 656
	Frame.StatusBar:SetShown(element.db.StatusBar)
	Frame.StatusBar.Name:SetShown(element.db.StatusBarNameEnabled)
	Frame.StatusBar.Time:SetShown(element.db.StatusBarTimeEnabled)

Azilroka's avatar
Azilroka committed
657
	tinsert(element, Frame)
Azilroka's avatar
Azilroka committed
658
	element.createdIcons = element.createdIcons + 1
Azilroka's avatar
Azilroka committed
659 660 661 662 663 664

	return Frame
end

function iFilger:UpdateAll()
	for _, Frame in pairs(iFilger.Panels) do
Azilroka's avatar
Azilroka committed
665 666 667 668 669
		if Frame.db.Enable then
			iFilger:EnableUnit(Frame)
		else
			iFilger:DisableUnit(Frame)
		end
Azilroka's avatar
iFilger  
Azilroka committed
670
		Frame:SetWidth((Frame.db.StatusBar and 1 or Frame.db.NumPerRow) * (Frame.db.StatusBar and Frame.db.StatusBarWidth or Frame.db.Size))
Azilroka's avatar
Azilroka committed
671 672 673 674 675 676 677 678 679 680
		for _, Button in ipairs(Frame) do
			Button:SetSize(Frame.db.Size, Frame.db.Size)
			Button.Stacks:SetFont(PA.LSM:Fetch('font', Frame.db.StackCountFont), Frame.db.StackCountFontSize, Frame.db.StackCountFontFlag)
			Button.StatusBar:SetStatusBarTexture(PA.LSM:Fetch('statusbar', Frame.db.StatusBarTexture))
			Button.StatusBar:SetStatusBarColor(unpack(Frame.db.StatusBarTextureColor))
			Button.StatusBar:SetSize(Frame.db.StatusBarWidth, Frame.db.StatusBarHeight)
			Button.StatusBar.Name:SetFont(PA.LSM:Fetch('font', Frame.db.StatusBarFont), Frame.db.StatusBarFontSize, Frame.db.StatusBarFontFlag)
			Button.StatusBar.Time:SetFont(PA.LSM:Fetch('font', Frame.db.StatusBarFont), Frame.db.StatusBarFontSize, Frame.db.StatusBarFontFlag)
			Button.StatusBar.Name:SetPoint('BOTTOMLEFT', Button.StatusBar, Frame.db.StatusBarNameX, Frame.db.StatusBarNameY)
			Button.StatusBar.Time:SetPoint('BOTTOMRIGHT', Button.StatusBar, Frame.db.StatusBarTimeX, Frame.db.StatusBarTimeY)
Azilroka's avatar
Azilroka committed
681
			Button.StatusBar:SetShown(Frame.db.StatusBar)
Azilroka's avatar
Azilroka committed
682 683 684 685
			Button.StatusBar.Name:SetShown(Frame.db.StatusBarNameEnabled)
			Button.StatusBar.Time:SetShown(Frame.db.StatusBarTimeEnabled)
		end
	end
Azilroka's avatar
Azilroka committed
686 687

	iFilger:CancelAllTimers()
688

Azilroka's avatar
Azilroka committed
689 690 691 692
	if iFilger.db.Cooldowns.Enable then
		iFilger:ScheduleRepeatingTimer('UpdateActiveCooldowns', iFilger.db.Cooldowns.UpdateSpeed)
		iFilger:ScheduleRepeatingTimer('UpdateDelayedCooldowns', .5)
	end
693 694 695 696

	if iFilger.db.ItemCooldowns.Enable then
		iFilger:ScheduleRepeatingTimer('UpdateItemCooldowns', iFilger.db.ItemCooldowns.UpdateSpeed)
	end
Azilroka's avatar
Azilroka committed
697 698
end

Azilroka's avatar
Azilroka committed
699 700 701 702 703
function iFilger:SPELLS_CHANGED()
	local numPetSpells = _G.HasPetSpells()
	if numPetSpells then
		iFilger:ScanSpellBook(_G.BOOKTYPE_PET, numPetSpells)

704
		PA:AddKeysToTable(iFilger.db.Cooldowns.SpellCDs, iFilger.SpellList)
Azilroka's avatar
Azilroka committed
705 706 707 708 709

		PA.Options.args.iFilger.args.Cooldowns.args.Spells.args = iFilger:GenerateSpellOptions()
	end
end

Azilroka's avatar
Azilroka committed
710 711 712 713 714 715 716 717 718
local function GetSelectedSpell()
	if selectedSpell and selectedSpell ~= '' then
		local spell = strmatch(selectedSpell, " %((%d+)%)$") or selectedSpell
		if spell then
			return tonumber(spell) or spell
		end
	end
end

Azilroka's avatar
Azilroka committed
719
function iFilger:BuildProfile()
Azilroka's avatar
Azilroka committed
720 721 722 723 724 725 726 727 728 729 730 731 732 733
	for tab = 1, _G.GetNumSpellTabs(), 1 do
		local name, _, offset, numSpells = _G.GetSpellTabInfo(tab)
		if name then
			iFilger:ScanSpellBook(_G.BOOKTYPE_SPELL, numSpells, offset)
		end
	end

	local numPetSpells = _G.HasPetSpells()
	if numPetSpells then
		iFilger:ScanSpellBook(_G.BOOKTYPE_PET, numPetSpells)
	end

	PA.ScanTooltip:Hide()

Azilroka's avatar
Azilroka committed
734
	PA.Defaults.profile.iFilger = {
Azilroka's avatar
Azilroka committed
735
		Enable = false,
Azilroka's avatar
Azilroka committed
736
		Cooldown = CopyTable(PA.Defaults.profile.Cooldown),
Azilroka's avatar
Azilroka committed
737 738
	}

Azilroka's avatar
Azilroka committed
739
	for _, Name in ipairs({'Cooldowns', 'ItemCooldowns', 'Buffs', 'Procs', 'Enhancements', 'RaidDebuffs', 'TargetDebuffs', 'FocusBuffs', 'FocusDebuffs'}) do
Azilroka's avatar
Azilroka committed
740 741 742 743 744
		PA.Defaults.profile.iFilger[Name] = {
			Direction = 'RIGHT',
			Enable = true,
			FollowCooldownText = false,
			Size = 28,
Azilroka's avatar
iFilger  
Azilroka committed
745
			NumPerRow = 12,
Azilroka's avatar
Azilroka committed
746 747 748
			SuppressDuration = 60,
			IgnoreDuration = 300,
			UpdateSpeed = .1,
Azilroka's avatar
Azilroka committed
749 750 751 752 753 754 755 756 757 758 759 760
			Spacing = 4,
			StackCountFont = PA.ElvUI and 'Homespun' or 'Arial Narrow',
			StackCountFontFlag = PA.ElvUI and 'MONOCHROMEOUTLINE' or 'OUTLINE',
			StackCountFontSize = PA.ElvUI and 10 or 12,
			StatusBar = false,
			StatusBarDirection = 'UP',
			StatusBarFont = PA.ElvUI and 'Homespun' or 'Arial Narrow',
			StatusBarFontFlag = PA.ElvUI and 'MONOCHROMEOUTLINE' or 'OUTLINE',
			StatusBarFontSize = PA.ElvUI and 10 or 12,
			StatusBarHeight = 5,
			StatusBarNameEnabled = true,
			StatusBarNameX = 0,
Azilroka's avatar
Azilroka committed
761
			StatusBarNameY = 8,
Azilroka's avatar
Azilroka committed
762 763 764 765
			StatusBarTexture = PA.ElvUI and 'ElvUI Norm' or 'Blizzard Raid Bar',
			StatusBarTextureColor = { .24, .54, .78 },
			StatusBarTimeEnabled = true,
			StatusBarTimeX = 0,
Azilroka's avatar
Azilroka committed
766
			StatusBarTimeY = 8,
Azilroka's avatar
Azilroka committed
767 768
			StatusBarWidth = 148,
		}
Azilroka's avatar
Azilroka committed
769 770

		if Name ~= 'Cooldowns' then
Azilroka's avatar
Azilroka committed
771
			PA.Defaults.profile.iFilger[Name].FilterByList = 'None'
Azilroka's avatar
Azilroka committed
772 773 774
			PA.Defaults.profile.iFilger[Name].Whitelist = {}
			PA.Defaults.profile.iFilger[Name].Blacklist = {}
		end
Azilroka's avatar
Azilroka committed
775
	end
Azilroka's avatar
Azilroka committed
776 777

	PA.Defaults.profile.iFilger.Cooldowns.SpellCDs = iFilger.SpellList
Azilroka's avatar
Azilroka committed
778 779
end

Azilroka's avatar
Azilroka committed
780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798
function iFilger:GenerateSpellOptions()
	local SpellOptions = {}

	for SpellID, SpellName in pairs(iFilger.db.Cooldowns.SpellCDs) do
		local Name, _, Icon = GetSpellInfo(SpellID)
		if Name then
			SpellOptions[tostring(SpellID)] = {
				type = 'toggle',
				image = Icon,
				imageCoords = PA.TexCoords,
				name = ' '..(type(SpellName) == 'string' and SpellName or Name),
				desc = 'Spell ID: '..SpellID,
			}
		end
	end

	return SpellOptions
end

Azilroka's avatar
Azilroka committed
799
function iFilger:GetOptions()
Azilroka's avatar
Azilroka committed
800
	iFilger:UpdateSettings()
Azilroka's avatar
Azilroka committed
801

Azilroka's avatar
Azilroka committed
802
	PA.Options.args.iFilger = PA.ACH:Group(iFilger.Title, iFilger.Description, nil, 'tab')
Azilroka's avatar
Azilroka committed
803
	PA.Options.args.iFilger.args.Description = PA.ACH:Description(iFilger.Description, 0)
Azilroka's avatar
Azilroka committed
804
	PA.Options.args.iFilger.args.Enable = PA.ACH:Toggle(PA.ACL['Enable'], nil, 1, nil, nil, nil, function(info) return iFilger.db[info[#info]] end, function(info, value) iFilger.db[info[#info]] = value if (not iFilger.isEnabled) then iFilger:Initialize() else _G.StaticPopup_Show('PROJECTAZILROKA_RL') end end)
Azilroka's avatar
iFilger  
Azilroka committed
805

Azilroka's avatar
Azilroka committed
806 807
	PA.Options.args.iFilger.args.AuthorHeader = PA.ACH:Header(PA.ACL['Authors:'], -2)
	PA.Options.args.iFilger.args.Authors = PA.ACH:Description(iFilger.Authors, -1, 'large')
Azilroka's avatar
Azilroka committed
808

Azilroka's avatar
Azilroka committed
809
	for _, Name in ipairs({'Cooldowns','ItemCooldowns','Buffs','Procs','Enhancements','RaidDebuffs','TargetDebuffs','FocusBuffs','FocusDebuffs'}) do
Azilroka's avatar
iFilger  
Azilroka committed
810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850
		PA.Options.args.iFilger.args[Name] = PA.ACH:Group(Name, nil, nil, nil, function(info) return iFilger.db[Name][info[#info]] end, function(info, value) iFilger.db[Name][info[#info]] = value iFilger:UpdateAll() end)

		PA.Options.args.iFilger.args[Name].args.Enable = PA.ACH:Toggle(PA.ACL['Enable'], nil, 0)
		PA.Options.args.iFilger.args[Name].args.Size = PA.ACH:Range(PA.ACL['Icon Size'], nil, 1, { min = 16, max = 64, step = 1 })
		PA.Options.args.iFilger.args[Name].args.Spacing = PA.ACH:Range(PA.ACL['Spacing'], nil, 2, { min = 0, max = 18, step = 1 })
		PA.Options.args.iFilger.args[Name].args.NumPerRow = PA.ACH:Range(PA.ACL['Number Per Row'], nil, 3, { min = 1, max = 24, step = 1 }, nil, nil, nil, nil, function() return iFilger.db[Name].StatusBar end)
		PA.Options.args.iFilger.args[Name].args.Direction = PA.ACH:Select(PA.ACL['Growth Direction'], nil, 4, { LEFT = 'Left', RIGHT = 'Right' }, nil, nil, nil, nil, nil, function() return iFilger.db[Name].StatusBar end)
		PA.Options.args.iFilger.args[Name].args.FilterByList = PA.ACH:Select(PA.ACL['Filter by List'], nil, 5, { None = 'None', Whitelist = 'Whitelist', Blacklist = 'Blacklist' }, nil, nil, nil, nil, nil, Name == 'Cooldowns')

		PA.Options.args.iFilger.args[Name].args.IconStack = PA.ACH:Group(PA.ACL['Stack Count'], nil, 10)
		PA.Options.args.iFilger.args[Name].args.IconStack.inline = true
		PA.Options.args.iFilger.args[Name].args.IconStack.args.StackCountFont = PA.ACH:SharedMediaFont(PA.ACL['Font'], nil, 1)
		PA.Options.args.iFilger.args[Name].args.IconStack.args.StackCountFontSize = PA.ACH:Range(PA.ACL['Font Size'], nil, 2, { min = 8, max = 18, step = 1 })
		PA.Options.args.iFilger.args[Name].args.IconStack.args.StackCountFontFlag = PA.ACH:FontFlags(PA.ACL['Font Flag'], nil, 3)

		PA.Options.args.iFilger.args[Name].args.StatusBarGroup = PA.ACH:Group(PA.ACL['StatusBar'], nil, 11, nil, nil, nil, function() return not iFilger.db[Name].StatusBar end)
		PA.Options.args.iFilger.args[Name].args.StatusBarGroup.inline = true
		PA.Options.args.iFilger.args[Name].args.StatusBarGroup.args.StatusBar = PA.ACH:Toggle(PA.ACL['Enable'], nil, 0, nil, nil, nil, nil, nil, false)
		PA.Options.args.iFilger.args[Name].args.StatusBarGroup.args.FollowCooldownText = PA.ACH:Toggle(PA.ACL['Follow Cooldown Text Color'], PA.ACL['Follow Cooldown Text Colors (Expiring / Seconds)'], 1)
		PA.Options.args.iFilger.args[Name].args.StatusBarGroup.args.StatusBarWidth = PA.ACH:Range(PA.ACL['Width'], nil, 3, { min = 1, max = 256, step = 1 })
		PA.Options.args.iFilger.args[Name].args.StatusBarGroup.args.StatusBarHeight = PA.ACH:Range(PA.ACL['Height'], nil, 4, { min = 1, max = 64, step = 1 })
		PA.Options.args.iFilger.args[Name].args.StatusBarGroup.args.StatusBarTexture = PA.ACH:SharedMediaStatusbar(PA.ACL['Texture'], nil, 5)
		PA.Options.args.iFilger.args[Name].args.StatusBarGroup.args.StatusBarTextureColor = PA.ACH:Color(PA.ACL['Texture Color'], nil, 6, nil, nil, function(info) return unpack(iFilger.db[Name][info[#info]]) end, function(info, r, g, b, a) iFilger.db[Name][info[#info]] = { r, g, b, a} end)
		PA.Options.args.iFilger.args[Name].args.StatusBarGroup.args.StatusBarFont = PA.ACH:SharedMediaFont(PA.ACL['Font'], nil, 7)
		PA.Options.args.iFilger.args[Name].args.StatusBarGroup.args.StatusBarFontSize = PA.ACH:Range(PA.ACL['Font Size'], nil, 8, { min = 8, max = 18, step = 1 })
		PA.Options.args.iFilger.args[Name].args.StatusBarGroup.args.StatusBarFontFlag = PA.ACH:FontFlags(PA.ACL['Font Flags'], nil, 9)
		PA.Options.args.iFilger.args[Name].args.StatusBarGroup.args.StatusBarDirection = PA.ACH:Select(PA.ACL['Growth Direction'], nil, 10, { UP = 'Up', DOWN = 'Down' })

		PA.Options.args.iFilger.args[Name].args.StatusBarGroup.args.StatusBarName = PA.ACH:Group(PA.ACL['Name'], nil, 11)
		PA.Options.args.iFilger.args[Name].args.StatusBarGroup.args.StatusBarName.inline = true
		PA.Options.args.iFilger.args[Name].args.StatusBarGroup.args.StatusBarName.args.StatusBarNameEnabled = PA.ACH:Toggle(PA.ACL['Enable'], nil, 0)
		PA.Options.args.iFilger.args[Name].args.StatusBarGroup.args.StatusBarName.args.StatusBarNameX = PA.ACH:Range(PA.ACL['X Offset'], nil, 1, { min = -256, max = 256, step = 1 })
		PA.Options.args.iFilger.args[Name].args.StatusBarGroup.args.StatusBarName.args.StatusBarNameY = PA.ACH:Range(PA.ACL['Y Offset'], nil, 2, { min = -64, max = 64, step = 1 })

		PA.Options.args.iFilger.args[Name].args.StatusBarGroup.args.StatusBarTime = PA.ACH:Group(PA.ACL['Name'], nil, 12)
		PA.Options.args.iFilger.args[Name].args.StatusBarGroup.args.StatusBarTime.inline = true
		PA.Options.args.iFilger.args[Name].args.StatusBarGroup.args.StatusBarTime.args.StatusBarTimeEnabled = PA.ACH:Toggle(PA.ACL['Enable'], nil, 0)
		PA.Options.args.iFilger.args[Name].args.StatusBarGroup.args.StatusBarTime.args.StatusBarTimeX = PA.ACH:Range(PA.ACL['X Offset'], nil, 1, { min = -256, max = 256, step = 1 })
		PA.Options.args.iFilger.args[Name].args.StatusBarGroup.args.StatusBarTime.args.StatusBarTimeY = PA.ACH:Range(PA.ACL['Y Offset'], nil, 2, { min = -64, max = 64, step = 1 })

		PA.Options.args.iFilger.args[Name].args.filterGroup = PA.ACH:Group(PA.ACL['Filters'], nil, 12, nil, nil, nil, nil, Name == 'Cooldowns')
Azilroka's avatar
Azilroka committed
851
		PA.Options.args.iFilger.args[Name].args.filterGroup.inline = true
Azilroka's avatar
iFilger  
Azilroka committed
852 853 854 855 856 857 858 859 860 861 862
		PA.Options.args.iFilger.args[Name].args.filterGroup.args.selectFilter = PA.ACH:Select(PA.ACL['Select Filter'], nil, 1, { Whitelist = 'Whitelist', Blacklist = 'Blacklist' }, nil, nil, function() return selectedFilter end, function(_, value) selectedFilter, selectedSpell = nil, nil if value ~= '' then selectedFilter = value end end)
		PA.Options.args.iFilger.args[Name].args.filterGroup.args.resetFilter = PA.ACH:Execute(PA.ACL["Reset Filter"], PA.ACL["This will reset the contents of this filter back to default. Any spell you have added to this filter will be removed."], 2, function() wipe(iFilger.db[Name][selectedFilter]) selectedSpell = nil end, nil, true)

		PA.Options.args.iFilger.args[Name].args.filterGroup.args.filterGroup = PA.ACH:Group(function() return selectedFilter end, nil, 10, nil, nil, nil, nil, function() return not selectedFilter end)
		PA.Options.args.iFilger.args[Name].args.filterGroup.args.filterGroup.inline = true
		PA.Options.args.iFilger.args[Name].args.filterGroup.args.filterGroup.args.addSpell = PA.ACH:Input(PA.ACL['Add SpellID'], PA.ACL['Add a spell to the filter.'], 1, nil, nil, function() return '' end, function(_, value) value = tonumber(value) if not value then return end local spellName = GetSpellInfo(value) selectedSpell = (spellName and value) or nil if not selectedSpell then return end iFilger.db[Name][selectedFilter][value] = true end)
		PA.Options.args.iFilger.args[Name].args.filterGroup.args.filterGroup.args.removeSpell = PA.ACH:Execute(PA.ACL["Remove Spell"], PA.ACL["Remove a spell from the filter. Use the spell ID if you see the ID as part of the spell name in the filter."], 2, function() local value = GetSelectedSpell() if not value then return end selectedSpell = nil iFilger.db[Name][selectedFilter][value] = nil end, nil, true)
		PA.Options.args.iFilger.args[Name].args.filterGroup.args.filterGroup.args.selectSpell = PA.ACH:Select(PA.ACL["Select Spell"], nil, 10, function() local list = iFilger.db[Name][selectedFilter] if not list then return end wipe(spellList) for filter in pairs(list) do local spellName = tonumber(filter) and GetSpellInfo(filter) local name = (spellName and format("%s |cFF888888(%s)|r", spellName, filter)) or tostring(filter) spellList[filter] = name end if not next(spellList) then spellList[''] = PA.ACL["None"] end return spellList end, nil, 'double', function() if not iFilger.db[Name][selectedFilter][selectedSpell] then selectedSpell = nil end return selectedSpell or '' end, function(_, value) selectedSpell = (value ~= '' and value) or nil end)
		PA.Options.args.iFilger.args[Name].args.filterGroup.args.spellGroup = PA.ACH:Group(function() local spell = GetSelectedSpell() local spellName = spell and GetSpellInfo(spell) return (spellName and spellName..' |cFF888888('..spell..')|r') or spell or ' ' end, nil, -15, nil, nil, nil, nil, function() return not GetSelectedSpell() end)
		PA.Options.args.iFilger.args[Name].args.filterGroup.args.spellGroup.inline = true
		PA.Options.args.iFilger.args[Name].args.filterGroup.args.spellGroup.args.enabled = PA.ACH:Toggle(PA.ACL['Enable'], nil, 0, nil, nil, nil, function() local spell = GetSelectedSpell() if not spell then return end return iFilger.db[Name][selectedFilter][spell] end, function(_, value) local spell = GetSelectedSpell() if not spell then return end iFilger.db[Name][selectedFilter][spell] = value end)
Azilroka's avatar
Azilroka committed
863
	end
Azilroka's avatar
Azilroka committed
864

Azilroka's avatar
Azilroka committed
865 866
	PA.Options.args.iFilger.args.Cooldowns.args.UpdateSpeed = PA.ACH:Range(PA.ACL['Update Speed'], nil, 5, { min = .1, max = .5, step = .1 })
	PA.Options.args.iFilger.args.ItemCooldowns.args.UpdateSpeed = PA.ACH:Range(PA.ACL['Update Speed'], nil, 5, { min = .1, max = .5, step = .1 })
Azilroka's avatar
Azilroka committed
867

Azilroka's avatar
Azilroka committed
868 869
	PA.Options.args.iFilger.args.Cooldowns.args.SuppressDuration = PA.ACH:Range(PA.ACL['Suppress Duration Threshold'], PA.ACL['Duration in Seconds'], 6, { min = 2, max = 600, step = 1 })
	PA.Options.args.iFilger.args.Cooldowns.args.IgnoreDuration = PA.ACH:Range(PA.ACL['Ignore Duration Threshold'], PA.ACL['Duration in Seconds'], 7, { min = 2, max = 600, step = 1 })
Azilroka's avatar
Azilroka committed
870

Azilroka's avatar
Azilroka committed
871
	PA.Options.args.iFilger.args.Cooldowns.args.Spells = PA.ACH:Group(_G.SPELLS, nil, 12, nil, function(info) return iFilger.db.Cooldowns.SpellCDs[tonumber(info[#info])] end, function(info, value) iFilger.db.Cooldowns.SpellCDs[tonumber(info[#info])] = value end)
Azilroka's avatar
Azilroka committed
872
	PA.Options.args.iFilger.args.Cooldowns.args.Spells.inline = true
Azilroka's avatar
Azilroka committed
873
	PA.Options.args.iFilger.args.Cooldowns.args.Spells.args = iFilger:GenerateSpellOptions()
Azilroka's avatar
Azilroka committed
874 875
end

Azilroka's avatar
Azilroka committed
876
function iFilger:UpdateSettings()
Azilroka's avatar
Azilroka committed
877
	iFilger.db = PA.db.iFilger
Azilroka's avatar
Azilroka committed
878 879 880 881
end

function iFilger:Initialize()
	iFilger:UpdateSettings()
Azilroka's avatar
Azilroka committed
882 883 884 885 886 887 888 889

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

	iFilger.isEnabled = true

	if PA.ElvUI then
Azilroka's avatar
Azilroka committed
890 891
		tinsert(_G.ElvUI[1].ConfigModeLayouts, #(_G.ElvUI[1].ConfigModeLayouts)+1, 'iFilger')
		_G.ElvUI[1].ConfigModeLocalizedStrings['iFilger'] = 'iFilger'
Azilroka's avatar
Azilroka committed
892 893 894 895 896 897 898 899
	end

	iFilger.Panels = {
		Buffs = iFilger:Spawn('player', 'Buffs', iFilger.db.Buffs, 'HELPFUL', { 'TOPLEFT', UIParent, 'CENTER', -351, -203 }),
		RaidDebuffs = iFilger:Spawn('player', 'RaidDebuffs', iFilger.db.RaidDebuffs, 'HARMFUL', { 'TOPLEFT', UIParent, 'CENTER', -351, -203 }),
		Procs = iFilger:Spawn('player', 'Procs', iFilger.db.Procs, 'HELPFUL', { 'BOTTOMLEFT', UIParent, 'CENTER', -57, -52 }),
		Enhancements = iFilger:Spawn('player', 'Enhancements', iFilger.db.Enhancements, 'HELPFUL', { 'BOTTOMRIGHT', UIParent, 'CENTER', -351, 161 }),
		TargetDebuffs = iFilger:Spawn('target', 'TargetDebuffs', iFilger.db.TargetDebuffs, 'HARMFUL|PLAYER', { 'TOPLEFT', UIParent, 'CENTER', 283, -207 }),
Azilroka's avatar
Azilroka committed
900
		Cooldowns = iFilger:Spawn('player', 'Cooldowns', iFilger.db.Cooldowns, nil, { 'BOTTOMRIGHT', UIParent, 'CENTER', -71, -109 }),
Azilroka's avatar
Azilroka committed
901
		ItemCooldowns = iFilger:Spawn('player', 'ItemCooldowns', iFilger.db.ItemCooldowns, nil, { 'BOTTOMRIGHT', UIParent, 'CENTER', -71, -109 }),
Azilroka's avatar
Azilroka committed
902 903 904 905
	}

	iFilger:RegisterEvent('UNIT_SPELLCAST_SUCCEEDED')	-- For Cooldown Queue
	iFilger:RegisterEvent('SPELL_UPDATE_COOLDOWN')		-- Process Cooldown Queue
Azilroka's avatar
Azilroka committed
906
	iFilger:RegisterEvent('SPELLS_CHANGED')
Azilroka's avatar
Azilroka committed
907
	iFilger:RegisterEvent('BAG_UPDATE_COOLDOWN')
Azilroka's avatar
Azilroka committed
908 909 910 911 912 913 914
	iFilger:RegisterEvent('PLAYER_TARGET_CHANGED', function() iFilger:UpdateAuras(iFilger.Panels.TargetDebuffs, 'target') end)

	if PA.Retail then
		iFilger.Panels.FocusBuffs = iFilger:Spawn('focus', 'FocusBuffs', iFilger.db.FocusBuffs, 'HELPFUL', { 'TOPRIGHT', UIParent, 'CENTER', -53, 53 })
		iFilger.Panels.FocusDebuffs = iFilger:Spawn('focus', 'FocusDebuffs', iFilger.db.FocusDebuffs, 'HARMFUL', { 'TOPRIGHT', UIParent, 'CENTER', -53, 53 })
		iFilger:RegisterEvent('PLAYER_FOCUS_CHANGED', function() iFilger:UpdateAuras(iFilger.Panels.FocusBuffs, 'focus') iFilger:UpdateAuras(iFilger.Panels.FocusDebuffs, 'focus') end)
	end
Azilroka's avatar
Azilroka committed
915

Azilroka's avatar
Azilroka committed
916 917 918 919
	if iFilger.db.Cooldowns.Enable then
		iFilger:ScheduleRepeatingTimer('UpdateActiveCooldowns', iFilger.db.Cooldowns.UpdateSpeed)
		iFilger:ScheduleRepeatingTimer('UpdateDelayedCooldowns', .5)
	end
Azilroka's avatar
Azilroka committed
920 921 922 923

	if iFilger.db.ItemCooldowns.Enable then
		iFilger:ScheduleRepeatingTimer('UpdateItemCooldowns', iFilger.db.ItemCooldowns.UpdateSpeed)
	end
Azilroka's avatar
Azilroka committed
924
end