WoWInterface SVN PowerAurasClassic

[/] [trunk/] [PowerAuras/] [PowerAuras.lua] - Rev 24

Compare with Previous | Blame | View Log

--- ------------------------------------------------
---            << Power Auras >>
---              Par -Sinsthar-
---    [Ziya/Tiven - serveur Fr - Kirin Tor] 
---
---     Effets visuels autour du personnage 
---     en cas de buff, debuff et autres...
--- ------------------------------------------------

--- Author: Smacker(v2.6.2),Gameldar (v2.6.1), Driizt (v2.5+), Garstiger (Powa Continued), Sinsthar (original author/concept)
--- Thanks: Kouri for debuff type detection code
--- Thanks: StingerSoft for Russian translations
--- Changes:
--- Version 2.6.2 (WotLK Raid or Self or Party)
---  Feature: Option to match buff/debuff on group (raid or party or self)
---  Feature: Option to match on buff/debuff tool-tip text
---  Feature: In Vehicle flag added
---  Feature: Resting flag added (except when in combat)
---  Feature: Stun/Silence/Root/CC/Snare detection added to DebuffType
---  Feature: Can flag to trigger only dispellable DebuffTypes 
---  Feature: Added >= and <= stack comparisons
---  Feature: Copy/Import/Export now includes timer settings
---  Feature: Ability to look-up buffs/debuffs/spellalerts by icon name (ensure at least one underscore is in the buff name)
---  Feature: Ability to look-up spells by spellIds (use [12345])
---  Feature: Russian localisation added (thanks to StingerSoft)
---  Feature: Option to hide leading zeros on timers
---  Feature: Option to use transparent timer textures
---  Change: Use Blizzard threat values instead of Banzi
---  Bugfix: PvP Trigger now works
---  Bugfix: Timers on buffs/debuff on other players now show
--- Version 2.6.1a (WotLK Dual-Specs)
---  Bugfix: corrected typo in the index value for the dual spec conditional (j != k)
--- Version 2.6.1 (WotLK Dual-Specs)
---  Feature: WoW 3.1 verison match (no longer out of date)
---  Feature: Basic integration of dual specs support
--- Version 2.6.0 (WotLK)
---  Feature: WoW 3.1 compatibility update.
---  Feature: Deathknight Presences added to Stance Auras.
---  Feature: Whitespace added to export strings to facilitate forum posting.
---  Feature: Better granularity for Mana/Health/Rage/Energy/Power threshold (step 5 -> 2).
---  Feature: Mounted option changed to toggle (checked: only when mounted, unchecked: only when dismounted)
---  Feature: Texture glow option affects timer.
---  Bugfix: Mana/Rage/Energy/RunicPower Party & Raid triggers.
---  Bugfix: Mana/Rage/Energy/RunicPower Unit triggers.
---  Bugfix: PvP Trigger.
---  Bugfix: "Casted" -> "Cast" typo.
--- Version 2.5.9a (WotLK)
---  Bugfix: 'hundredth', 'dual' timers checkbox errors.
--- Version 2.5.9 (WotLK)
---  Feature: Option to monitor "my" buffs/debuffs.
---  Feature: Unlimited timers. (1 per aura instead of 5 total)
---  Feature: Dynamic Aura update when multiple matches and 'own texture' checked.
---  Feature: Import and export Auras as strings.
---  Feature: Any/All toggle for party, raid buff checks. (default = all)
---  Bugfix: Action Usable aura when action linked to stance.
---  Bugfix: Make "Activate Power Auras" checkbox actually do something and shutdown processing when unchecked. :P
--- Version 2.5.8b (WotLK)
---  Bugfix: gui bug threshold invert option.
--- Version 2.5.8a (WotLK)
---  Bugfix: combination triggers with "show when not active" checked.
---  Various internal logic optimizations.
--- Version 2.5.8 (WotLK)
---  Bugfix: Various label fonts (template breakage by Blizzard in builds 8982->9014)
---  Bugfix: Font Select button not visible on first editor open.
---  Feature: Text shadow option for textauras.
---  Feature: Ability to setup auras with combination of triggers.
---  Feature: Spell Casting activation trigger added (target and focus).
--- Version 2.5.7b (WotLK)
---  Bugfix: Begin animation "replaying" on aura refresh.
--- Version 2.5.7a (WotLK)
---  Bugfix: Offhand temporary enchant detection/stacks
---      Feature: Weapon buff auras can be defined separately per temporary enchant 
---           and optionally filtered by slot (main or offhand)
--- Version 2.5.7 (WotLK)
---  Feature: Text Aura Option added (thanks to Garstiger for initial code)
---  Feature: Option to invert default threshold behavior added.
---  Feature: Pet health/mana activation enabled (enter "pet" in UnitName editbox)
---  Bugfix: Manual.html pictures (submitted by Garstiger)
---  Bugfix: Aura Type checkboxes
---  Bugfix: UnitName nil error
---  Bugfix: Threshold when Rage/Energy/Power is zero.
--- Version 2.5.6c (WotLK)
---  Bugfix: Not in Combat initial state.
--- Version 2.5.6b (WotLK)
---  Bugfix: .TimerFrame checkboxes nil error
---  Bugfix: Target buff/debuff timers
--- Version 2.5.6a (WotLK)
---  Bugfix: GetComboPoints() API change.
--- Version 2.5.6 (WotLK)
---  Feature: Runic Power threshold added.
---  Bugfix: GetPlayerBuff/UnitBuff/Debuff API changes.
---  Bugfix: UIDropMenu, PanelTemplates_TabResize, Font Widget, this->self changes. 
--- Version 2.5.5b
---  Bugfix: Health/Mana threshold for party/raid units (line 1297 error)
--- Version 2.5.5a
---  Bugfix: Custom duration timer for target buffs/debuffs (wasn't reseting on target change)
---  Bugfix: Hide player auras when dead/ghost.
--- Version 2.5.5
---  Feature: Stance options for Druid and Rogue(stealth) added
---  Bugfix: Stance detection is now dynamic so lower levels that don't have all forms/stances yet are supported.
---  Feature: Custom timer enabled for action usable. It overrides the calculated timers if used.
---  Feature: Rage/Energy trigger implemented with upper thresholds.
--- Version 2.5.4a
---  Bugfix: Buff and Debuff timers for non-player units.
--- Version 2.5.4
---  Bugfix: Buff and Debuff timers.
---  Feature: Custom textures editbox now accepts spellname or spellid in addition to filename.tga
--- Version 2.5.3
---  Bugfix: Buff and Debuff stacks.
---  Bugfix: Mana-threshold auras when shifting to bear/cat.
---  Feature: New custom sounds.
---  Feature: Updated zh-CN localization by <Doomiris>.
--- Version 2.5.2
---  Feature: 30 more wow textures added to available choices
---  Feature: PvP flag added to triggers
---  Feature: Aggro status added to triggers
---  Feature: Option to use ability/spell texture instead of predetermined choice where available.
--- Version 2.5.1a
---  Feature: Hide Auras when hiding the interface (Alt+z)
--- Version 2.5.1
---  Feature: WoW 2.4 compatibility re-code (various changes related to the new combatlog)
---  Feature: New textures can now be added to defaults as long as they're named Auraxx.tga
---           The selection slider will accommodate automatically next time you start the game.
---  Bugfix: Stance detection
---  Bugfix: Mounted detection (flying included)
---  Bugfix: Aura change
---  Bugfix: Action Usable (workaround for the absense of cooldown complete events)
---          If you want to get notification when a trinket or bag item is usable you have
---                                      drag it to an actionbar (doesn't have to be a visible one)      

-- Exposed for Saving
PowaMisc = 
        {
                disabled = false,
                debug = false,
                OnUpdateLimit = 0,
                AnimationLimit = 0,
        };

PowaSet = {};
PowaTimer = {};

PowaGlobalSet = {};
PowaGlobalListe = {};
PowaPlayerListe = {};

--Default page names
for i = 1, 5 do
        PowaPlayerListe[i] = PowaAuras.Text.ListePlayer.." "..i;
end
for i = 1, 10 do
        PowaGlobalListe[i] = PowaAuras.Text.ListeGlobal.." "..i;
end

--- ---------------------------------------------------------------------------------------------------------

function PowaAuras:Toggle(enabled)
        if enabled then
                if PowaAuras_Frame and not PowaAuras_Frame:IsShown() then               
                        PowaAuras_Frame:Show(); -- Show Main Options Frame
                        self:RegisterEvents(PowaAuras_Frame);
                end
                PowaMisc.disabled = false;
        else
                if PowaAuras_Frame and PowaAuras_Frame:IsShown() then
                        PowaAuras_Frame:UnregisterAllEvents();
                        PowaAuras_Frame:Hide();
                end
                self:OptionHideAll(true);
                PowaMisc.disabled = true;
        end
end

function PowaAuras:OnLoad(frame)
        
        --- Setting up the Import/Export static popups
        self:SetupStaticPopups();

        if (not PowaMisc.disabled) then
                self:RegisterEvents(frame);
        end
        
        --- options init
        SlashCmdList["POWA"] = PowaAuras_CommanLine;
        SLASH_POWA1 = "/powa"   
end

function PowaAuras:RegisterEvents(frame)
        --- TODO: conditionally Register/unregister events according to options for improved performance
        for _, event in ipairs(self.Events) do
                if (self[event]) then
                        frame:RegisterEvent(event);
                else
                        self:Message("Event has no method ", event); --OK
                end
        end
end

function PowaAuras:LoadAuras()
        --self:Message("Saved varaible convertion: PowaSet");

        self.Auras = {};
        
        for k, v in pairs(PowaGlobalSet) do
                self:UnitTestDebug("PowaGlobalSet",k,v.buffname);
                if (v.is_a == nil or not v:is_a(cPowaAura)) then
                        --self:UnitTestDebug(k,v.buffname);
                        self.Auras[k] = self:AuraFactory(v.bufftype, k, v);
                end
        end

        for k, v in pairs(PowaSet) do
                --self:UnitTestDebug("PowaSet",k,v.buffname, self.Auras[k]);
                if (not self.Auras[k]) then
                        --self:UnitTestDebug("is_a=",v.is_a);
                        if (v.is_a == nil or not v:is_a(cPowaAura)) then
                                self.Auras[k] = self:AuraFactory(v.bufftype, k, v);
                                --self:UnitTestDebug("Out=",self.Auras[k].buffname);
                        end
                end
        end

        --self:Message("Default Aura");
        self.Auras[0] = cPowaAura(0, {off=true});

        -- Update for backwards combatiblity
        for i = 1, 360 do
                -- gere les rajouts
                local aura = self.Auras[i];
                local oldaura = PowaSet[i];
                if (oldaura==nil) then
                        oldaura = PowaGlobalSet[i];
                end
                if (aura) then          
                        if (aura.buffname == "") then
                                --self:Message("Delete aura "..i);
                                self.Auras[i] = nil;
                        elseif (aura.bufftype == nil and oldaura~=nil) then
                                --self:Message("Repair bufftype for #"..i);
                                
                                if (oldaura.isdebuff) then
                                        aura.bufftype = self.BuffTypes.Debuff;
                                elseif (oldaura.isdebufftype) then
                                        aura.bufftype = self.BuffTypes.TypeDebuff;
                                elseif (oldaura.isenchant) then
                                        aura.bufftype = self.BuffTypes.Enchant;
                                else
                                        aura.bufftype = self.BuffTypes.Buff;
                                end
                                
                        -- Update old combo style 1235 => 1/2/3/5
                        elseif (aura.bufftype==self.BuffTypes.Combo) then
                                self:UnitTestDebug("Combo upgrade check ", aura.buffname, " for ", aura.id);
                                if (string.len(aura.buffname)>1 and string.find(aura.buffname, "/", 1, true)==nil) then
                                        local newBuffName=string.sub(aura.buffname, 1, 1);
                                        for i=2, string.len(aura.buffname) do
                                                newBuffName = newBuffName.."/"..string.sub(aura.buffname, i, i);
                                        end
                                        aura.buffname = newBuffName
                                end
                        end

                end
        end
        
        --self:Message("Saved varaible convertion: PowaTimer #", #PowaTimer);
        -- Copy old timer info (should be once only)
        for k, v in pairs(PowaTimer) do
                local aura = self.Auras[k];
                if (aura) then
                        aura.Timer = cPowaTimer(k, v);
                        if (PowaSet[k]~=nil and PowaSet[k].timer~=nil) then
                                aura.Timer.enabled = PowaSet[k].timer;
                        end
                        if (PowaGlobalSet[k]~=nil and PowaGlobalSet[k].timer~=nil) then
                                aura.Timer.enabled = PowaGlobalSet[k].timer;
                        end
                end
        end     
        
        -- Copy to Saved Sets
        PowaSet = self.Auras;
        for i = 121, 360 do
                PowaGlobalSet[i] = self.Auras[i];
        end
        PowaTimer = {};
        
end
------------------------------------------------------------------------------------------------------- EVENTS

function PowaAuras:VARIABLES_LOADED(...)
        DEFAULT_CHAT_FRAME:AddMessage("|cffB0A0ff<Power Auras Classic>|r |cffffff00"..self.Version.."|r - "..self.Text.welcome);

        PowaMisc.OnUpdateLimit = PowaMisc.OnUpdateLimit or 0;
        PowaMisc.AnimationLimit = PowaMisc.AnimationLimit or 0;

        if (TestPA==nil) then
                PowaState = {};
        end
        
        _, self.playerclass = UnitClass("player");

        self:LoadAuras();

        for i = 1, 5 do
                getglobal("PowaOptionsList"..i):SetText(PowaPlayerListe[i]);
        end
        for i = 1, 10 do
                getglobal("PowaOptionsList"..i+5):SetText(PowaGlobalListe[i]);
        end
        
        self.maxtextures = 1;
        local texi = 1;
        while ( getglobal("AuraTexture"):SetTexture("Interface\\Addons\\PowerAuras\\Auras\\Aura"..texi..".tga") == 1 ) do 
                self.maxtextures = texi;
                texi = texi+1;
        end
        
        getglobal("PowaBarAuraTextureSlider"):SetMinMaxValues(1, self.maxtextures);
        getglobal("PowaBarAuraTextureSliderHigh"):SetText(self.maxtextures);
        
        self:CreateEffectLists();
end

function PowaAuras:PLAYER_ENTERING_WORLD(...)
        if (PowaMisc.disabled == true) then
                self:Toggle(false);
                return;
        end
        PowaAuras_Tooltip:SetOwner(UIParent, "ANCHOR_NONE");

        -- Look-up spells by spellId for debuff types
        self.DebuffCatSpells = {}
        for k, v in pairs(self.DebuffTypeSpellIds) do
                local spellName = GetSpellInfo(k);
                if spellName then
                        self.DebuffCatSpells[spellName] = v
                else
                        self:Debug("Unknown spellId: ", k)
                end
        end     
        
        if UnitIsDeadOrGhost("player") then
                self.WeAreAlive = false;
        end
        if (GetNumRaidMembers() > 0) then
                self.WeAreInRaid = true;
        else
                self.WeAreInRaid = false;
        end
        self.WeAreMounted = (IsMounted()~=nil);
        self.WeAreInVehicle = (UnitInVehicle("player")~=nil);

        self.ActiveTalentGroup = GetActiveTalentGroup();
        
        self:GetStances();
        
        self:MemorizeActions();
        
        self.Initialising = false;
        
        self.DoCheck.All = true;
end

function PowaAuras:GetStances()
        for iForm=1, GetNumShapeshiftForms() do
                self.PowaStance[iForm] = select(2,GetShapeshiftFormInfo(iForm));
        end
end
                
function PowaAuras:PLAYER_TALENT_UPDATE(...)
        self.ActiveTalentGroup = GetActiveTalentGroup();
end
                
function PowaAuras:PLAYER_UPDATE_RESTING(...)
        if (self.ModTest == false) then
                self.DoCheck.All = true;
        end
end

function PowaAuras:PARTY_MEMBERS_CHANGED(...)     
        if (self.ModTest == false) then
                self.DoCheck.PartyBuffs = true;
                self.DoCheck.GroupOrSelfBuffs = true;
                self.DoCheck.PartyHealth = true;
                self.DoCheck.PartyMana = true;
        end
end
                
function PowaAuras:RAID_ROSTER_UPDATE(...)
        if (self.ModTest == false) then
                self.DoCheck.RaidBuffs = true;
                self.DoCheck.GroupOrSelfBuffs = true;
                self.DoCheck.RaidHealth = true;
                self.DoCheck.RaidMana = true;   
        end
        if GetNumRaidMembers() > 0 then
                self.WeAreInRaid = true;
        else
                self.WeAreInRaid = false;
        end
end
                                
function PowaAuras:UNIT_HEALTH(...)
        local unit = ...;
        self:SetCheckResource("Health", unit);
end
                
function PowaAuras:UNIT_MAXHEALTH(...)
        local unit = ...;
        self:SetCheckResource("Health", unit);
end
                
function PowaAuras:UNIT_MANA(...)
        local unit = ...;
        self:SetCheckResource("Mana", unit);
end
                
function PowaAuras:UNIT_MAXMANA(...)
        local unit = ...;
        self:SetCheckResource("Mana", unit);
end

function PowaAuras:UNIT_RAGE(...)
        local unit = ...;
        self:SetCheckResource("RageEnergy", unit);
end

function PowaAuras:UNIT_ENERGY(...)
        local unit = ...;
        self:SetCheckResource("RageEnergy", unit);
end

function PowaAuras:UNIT_MAXENERGY(...)
        local unit = ...;
        self:SetCheckResource("RageEnergy", unit);
end

function PowaAuras:UNIT_RUNIC_POWER(...)
        local unit = ...;
        self:SetCheckResource("RageEnergy", unit);
end

function PowaAuras:SetCheckResource(resourceType, unitType)
        if (self.ModTest == false) then
                if (unitType == "target") then
                        self.DoCheck["Target"..resourceType] = true;                            
                elseif (unitType == "focus") then             
                        self.DoCheck["Focus"..resourceType] = true;                             
                elseif ("party" == string.sub(unitType, 1, 5)) then 
                        self.DoCheck["Party"..resourceType] = true;     
                        self.DoCheck["NamedUnit"..resourceType] = true;                 
                elseif ("raid" == string.sub(unitType, 1, 4)) then              
                        self.DoCheck["Raid"..resourceType] = true;              
                        self.DoCheck["NamedUnit"..resourceType] = true;         
                elseif (unitType == "pet") then
                        self.DoCheck["NamedUnit"..resourceType] = true;
                elseif (unitType == "player") then
                        self.DoCheck[resourceType] = true; --- active les checks                
                end
        end
end

function PowaAuras:UNIT_MAXRUNIC_POWER(...)
        local unit = ...;
        self:SetCheckResource("RageEnergy", unit);
end

function PowaAuras:SpellcastEvent(unit)
        if (self.ModTest == false) then
                --- spell alert handling
                if unit and not UnitIsDead(unit) and UnitCanAttack(unit, "player") then
                        if UnitIsUnit(unit, "target") then
                                self.DoCheck.TargetSpells = true;
                        end
                        if UnitIsUnit(unit, "focus") then
                                self.DoCheck.FocusSpells = true;
                        end
                        self.DoCheck.Spells = true; --- party/raidscan for casting units in this case
                end
        end
end

function PowaAuras:UNIT_SPELLCAST_SUCCEEDED(...)          
        if (self.ModTest == false) then
                local unit, spell = ...;
                --- druid shapeshift special case
                if unit and (unit == "player") and ( (spell == GetSpellInfo(768)) or (spell == GetSpellInfo(5487)) or (spell == GetSpellInfo(9634)) ) then
                        self.DoCheck.Mana = true;
                        self.DoCheck.RageEnergy = true;
                end
                PowaAuras:SpellcastEvent(unit);
        end
end

function PowaAuras:UNIT_SPELLCAST_START(...)
        local unit = ...;
        PowaAuras:SpellcastEvent(unit);
end

function PowaAuras:UNIT_SPELLCAST_CHANNEL_START(...)
        local unit = ...;
        PowaAuras:SpellcastEvent(unit);
end

function PowaAuras:UNIT_SPELLCAST_DELAYED(...)
        local unit = ...;
        PowaAuras:SpellcastEvent(unit);
end

function PowaAuras:UNIT_SPELLCAST_CHANNEL_UPDATE(...)
        local unit = ...;
        PowaAuras:SpellcastEvent(unit);
end

function PowaAuras:UNIT_SPELLCAST_STOP(...)
        local unit = ...;
        PowaAuras:SpellcastEvent(unit);
end

function PowaAuras:UNIT_SPELLCAST_FAILED(...)
        local unit = ...;
        PowaAuras:SpellcastEvent(unit);
end

function PowaAuras:UNIT_SPELLCAST_INTERRUPTED(...)
        local unit = ...;
        PowaAuras:SpellcastEvent(unit);
end

function PowaAuras:UNIT_SPELLCAST_CHANNEL_STOP(...)
        local unit = ...;
        PowaAuras:SpellcastEvent(unit);
end
                
function PowaAuras:PLAYER_FOCUS_CHANGED(...)      
        if (self.ModTest == false) then
                self.DoCheck.FocusBuffs = true;
                self.DoCheck.FocusHealth = true;
                self.DoCheck.FocusMana = true;
                self.DoCheck.FocusRageEnergy = true;
                self.DoCheck.FocusSpells = true;
        end
end

function PowaAuras:BuffsChanged(unit)
        if (not self.ModTest) then
                --self:Message("BuffsChanged ", unit);
                if (arg1 == "target") then
                        self.DoCheck.TargetBuffs = true;
                elseif ("party" == string.sub(arg1, 1, 5)) then 
                        self.DoCheck.PartyBuffs = true;
                        self.DoCheck.GroupOrSelfBuffs = true;
                elseif (arg1 == "focus") then
                        self.DoCheck.FocusBuffs = true;
                elseif (string.sub(arg1, 1, 4) == "raid") then
                        self.DoCheck.RaidBuffs = true;       
                        self.DoCheck.GroupOrSelfBuffs = true;
                elseif (arg1 == "player") then
                        --- active les checks
                        self.DoCheck.Buffs = true;
                        self.DoCheck.GroupOrSelfBuffs = true;
                else
                        self.DoCheck.UnitBuffs = true;
                end
        end
end

function PowaAuras:UNIT_AURA(...)
        local unit = ...;
        self:BuffsChanged(unit);
end

function PowaAuras:UNIT_AURASTATE(...)
        local unit = ...;
        self:BuffsChanged(unit);
end

function PowaAuras:PLAYER_DEAD(...)
        if (self.ModTest == false) then
                self.DoCheck.All = true;
        end
        self.WeAreMounted = false;
        self.WeAreInVehicle = false;
        self.WeAreAlive = false;
end
        
function PowaAuras:PLAYER_ALIVE(...)
        if not UnitIsDeadOrGhost("player") then
                self.WeAreAlive = true;
                if (self.ModTest == false) then
                        self.DoCheck.All = true;
                end
        end
end
        
function PowaAuras:PLAYER_UNGHOST(...)
        if not UnitIsDeadOrGhost("player") then
                self.WeAreAlive = true;
                if (self.ModTest == false) then
                        self.DoCheck.All = true;
                end
        end
end
 
function PowaAuras:PLAYER_TARGET_CHANGED(...)
        if (self.ModTest == false) then
                self.DoCheck.TargetBuffs = true;
                self.DoCheck.TargetHealth = true;
                self.DoCheck.TargetMana = true;
                self.DoCheck.TargetRageEnergy = true;
                self.ResetTargetTimers = true;
                self.DoCheck.Actions = true;
                self.DoCheck.TargetSpells = true;
                self.DoCheck.Combo = true;
        end
end
         
function PowaAuras:PLAYER_REGEN_DISABLED(...)
        if (self.ModTest == false) then
                self.WeAreInCombat = true;
                self.DoCheck.Others = true;
                self.DoCheck.Enchants = true;
                self.DoCheck.TargetBuffs = true;
                self.DoCheck.Buffs = true;
                self.DoCheck.GroupOrSelfBuffs = true;
                self.DoCheck.Actions = true;
        end        
end
           
function PowaAuras:PLAYER_REGEN_ENABLED(...)
        if (self.ModTest == false) then
                self.WeAreInCombat = false;
                self.DoCheck.Others = true;
                self.DoCheck.Enchants = true;
                self.DoCheck.TargetBuffs = true;
                self.DoCheck.Buffs = true;
                self.DoCheck.GroupOrSelfBuffs = true;
                self.DoCheck.Actions = true;
        end
end   
        
function PowaAuras:UNIT_COMBO_POINTS(...)
        local unit = ...;
        if unit ~= "player" then return; end
        if (self.ModTest == false) then
                self.DoCheck.Combo = true;
        end
end

function PowaAuras:VehicleCheck(unit, entered)
        if unit ~= "player" then return; end
        if (self.ModTest == false) then
                self.DoCheck.All = true;
        end     
        self.WeAreInVehicle = entered;
end
                
function PowaAuras:UNIT_ENTERED_VEHICLE(...)
        local unit = ...;
        self:VehicleCheck(unit, true)
end

function PowaAuras:UNIT_EXITED_VEHICLE(...)
        local unit = ...;
        self:VehicleCheck(unit, false)
end
        
function PowaAuras:UNIT_FACTION(...) --- GetPVPTimer() returns the time until unflag in ms
        local unit = ...;
        if (self.ModTest == false) then
                if unit == "player" then
                        self.DoCheck.PvP = true;
                elseif unit == "target" then
                        self.DoCheck.TargetPvP = true;
                end

                for i=1,GetNumPartyMembers() do
                        if unit == "party"..i then
                                self.DoCheck.PartyPvP = true;
                                break;
                        end
                end
                for i=1, GetNumRaidMembers() do
                        if unit == "raid"..i then
                                self.DoCheck.RaidPvP = true;
                                break;
                        end
                end
        end
end
        
function PowaAuras:COMBAT_LOG_EVENT_UNFILTERED(...)
        local timestamp,event,sourceGUID,sourceName,sourceFlags,destGUID,destName,destFlags, spellId, spellName = ...;
        if (not self.ModTest) and destName and destName==UnitName("player") then
                if event == "SPELL_PERIODIC_DAMAGE" then
                        if spellName then
                                self.AoeAuraAdded = spellName;
                                self.AoeAuraTexture = select(3, GetSpellInfo(spellId));
                                self.DoCheck.Aoe = true;
                        end
                elseif event == "SPELL_AURA_REMOVED" then
                        if spellName then
                                self.AoeAuraFaded = spellName;
                                self.AoeAuraTexture = select(3, GetSpellInfo(spellId));
                                self.DoCheck.Aoe = true;
                        end
                end
        end
end

function PowaAuras:ACTIONBAR_SLOT_CHANGED(...)
        local arg1 = ...;
        self:MemorizeActions(arg1);
end
        
function PowaAuras:UPDATE_SHAPESHIFT_FORMS(...)
        self:GetStances();
        if (self.ModTest) then return; end
        
        self.DoCheck.Stance = true;
end
        
function PowaAuras:ACTIONBAR_UPDATE_COOLDOWN(...)
        if (self.ModTest == false) then
                self.DoCheck.Actions = true;
                self.DoCheck.Stance = true;
                for slot=1,120 do
                        if HasAction(slot) then
                                local start, duration, enable = GetActionCooldown(slot);
                                if enable > 0 and start > 0 and duration > 0 then
                                        self.UsablePending[slot] = math.ceil(start + duration);
                                else
                                        self.UsablePending[slot] = nil;
                                end
                        end
                end
        end     
end
                
function PowaAuras:ACTIONBAR_UPDATE_USABLE(...)
        if (self.ModTest == false) then
                self.DoCheck.Actions = true;
                self.DoCheck.Stance = true;
        end
end

function PowaAuras:SPELL_UPDATE_COOLDOWN(...)
        if (self.ModTest == false) then
                self.DoCheck.OwnSpells = true;
                --self:Message("SPELL_UPDATE_COOLDOWN", ...);
        end     
end

function PowaAuras:SPELL_UPDATE_USABLE(...)
        if (self.ModTest == false) then
                self.DoCheck.OwnSpells = true;
                --self:Message("SPELL_UPDATE_USABLE", ...);
        end
end

function PowaAuras:UPDATE_SHAPESHIFT_FORM(...)
        if (self.ModTest == false) then
                self:Debug("UPDATE_SHAPESHIFT_FORM");
                self.DoCheck.Stance = true;
                self.DoCheck.Actions = true;
        end  
end

function PowaAuras:UNIT_THREAT_SITUATION_UPDATE(...)
        local unit = ...;
        if (self.ModTest == false) then
                --self:Message("UNIT_THREAT_SITUATION_UPDATE ", unit);
                if unit == "player" then
                        self.DoCheck.Aggro = true;
                        return;
                end

                for i=1,GetNumPartyMembers() do
                        if unit == "party"..i then
                                self.DoCheck.PartyAggro = true;
                                break;
                        end
                end
                for i=1, GetNumRaidMembers() do
                        if unit == "raid"..i then
                                self.DoCheck.RaidAggro = true;
                                break;
                        end
                end
        end
end

function PowaAuras:CustomTexPath(customname)
        local texpath;
        if string.find(customname,".", 1, true) then
                texpath = "Interface\\Addons\\PowerAuras\\Custom\\"..customname;
        else
                _, _, texpath = GetSpellInfo(customname);
        end
        if not texpath then texpath = "" end
        return texpath;
end

--- ------------------------------------------------------------------------------------

function PowaAuras:CreateTimerFrame(auraId, index)
        local frame = CreateFrame("Frame", "TimerFrame"..auraId.."_"..index);
        self.TimerFrame[auraId][index] = frame;
        
        frame:SetFrameStrata("LOW");
        frame:Hide(); 
        frame.TimerValue = 0;
        
        frame.texture = frame:CreateTexture(nil,"BACKGROUND");
        frame.texture:SetBlendMode("ADD");
        frame.texture:SetAllPoints(frame);
        if (self.Auras[auraId].Timer.Transparent) then
                frame.texture:SetTexture("Interface\\Addons\\PowerAuras\\timersTransparent.tga");
        else
                frame.texture:SetTexture("Interface\\Addons\\PowerAuras\\timers.tga");
        end
end

function PowaAuras:CreateTimerFrameIfMissing(auraId)
        if (not self.TimerFrame[auraId]) then
                --self:Message("Creating missing TimerFrames for aura "..tostring(auraId));             
                self.TimerFrame[auraId] = {};
                self:CreateTimerFrame(auraId, 1);
                self:CreateTimerFrame(auraId, 2);
        end
        self:UpdateOptionsTimer(auraId);
        return self.TimerFrame[auraId][1], self.TimerFrame[auraId][2];
end

function PowaAuras:CreateStacksFrameIfMissing(auraId)
        if (not self.StacksFrames[auraId]) then
                --self:Message("Creating missing StacksFrame for aura "..tostring(auraId));             
                local frame = CreateFrame("Frame", "StacksFrame"..auraId);
                self.StacksFrames[auraId] = frame;
                
                frame:SetFrameStrata("LOW");
                frame:Hide(); 
                
                frame.texture = frame:CreateTexture(nil,"BACKGROUND");
                frame.texture:SetBlendMode("ADD");
                frame.texture:SetAllPoints(frame);
                if (self.Auras[auraId].Stacks.Transparent) then
                        frame.texture:SetTexture("Interface\\Addons\\PowerAuras\\timersTransparent.tga");
                else
                        frame.texture:SetTexture("Interface\\Addons\\PowerAuras\\timers.tga");
                end
        end
        self:UpdateOptionsStacks(auraId);
        return self.StacksFrames[auraId];
end

--- ----------------------------------------------------------------------------------------------- CREE LA LISTE DES CHECKS

function PowaAuras:CreateEffectLists()
        
        for k in pairs(self.AurasByType) do
                self.AurasByType[k] = {};
        end
        
        for auraId, aura in pairs(self.Auras) do
                if (aura ~= nil and aura.off ~= true) then
                        --print("Aura", aura.id);
                        aura:AddEffect(auraId);
                end
        end 

        if (PowaMisc.debug == true) then
                for k in pairs(self.AurasByType) do
                        self:Message(k .. " : " .. #self.AurasByType[k]); --OK
                end
        end

end

--- ----------------------------------------------------------------------------------------------- Memorize les actions
function PowaAuras:MemorizeActions(actionIndex)
        local imin, imax;
        self:Debug("---MemorizeActions---");
        if (#self.AurasByType.Actions == 0) then
                return;
        end
        
        --- scan tout ou uniquement le slot qui a change
        if (actionIndex == nil) then
                self:Debug("---Scan all Actionbuttons---");
                imin = 1;
                imax = 120;
                --- reset all action positions
                for _, v in pairs(self.AurasByType.Actions) do
                        self.Auras[v].slot = nil;
                end
                
        else
                imin = actionIndex;
                imax = actionIndex;
        end

        for i = imin, imax do
                if (HasAction(i)) then
                        self:Debug("---Button",i," Action Found---");
                        PowaAction_Tooltip:SetOwner(UIParent, "ANCHOR_NONE");
                        PowaAction_Tooltip:SetAction(i);
                        local text = PowaAction_TooltipTextLeft1:GetText();                             
                        --self:Debug("tooltip text=",text);
                        if text and text ~= "" then
                                self:Debug("| "..text.." |");
                        end     
                        if (text~=nil and PowaAction_TooltipTextLeft1:IsShown()) then
                                for _, v in pairs(self.AurasByType.Actions) do
                                        local actionAura = self.Auras[v];
                                        --self:Debug("actionAura",v,actionAura.buffname, actionAura.ignoremaj);
                                        if((actionAura.ignoremaj == true  and string.find(string.upper(text), string.upper(actionAura.buffname), 1, true)) or
                                           (actionAura.ignoremaj == false and string.find(text, actionAura.buffname, 1, true)) ) then --- on a trouve le slot
                                                actionAura.slot = i; --- remember the slot
                                                self:Debug("---------------------------------------");
                                                self:Debug("Actionname="..actionAura.buffname.." / Search in Tooltipstring="..text);
                                                --- remember the texture
                                                local tempicon;
                                                if (actionAura.owntex == true) then
                                                        getglobal("PowaIconTexture"):SetTexture(GetActionTexture(i));
                                                        tempicon = getglobal("PowaIconTexture"):GetTexture();
                                                        if (actionAura.icon ~= tempicon) then
                                                                actionAura.icon = tempicon;
                                                        end
                                                end
                                                if (actionAura.icon == "") then
                                                        getglobal("PowaIconTexture"):SetTexture(GetActionTexture(i));
                                                        actionAura.icon = getglobal("PowaIconTexture"):GetTexture();
                                                end
                                        end
                                end
                        end
                        PowaAction_Tooltip:Hide();
                end
        end
end

function PowaAuras:CheckMultiple(aura, reason, giveReason)
        if (not aura.multiids or aura.multiids == "") then
                if (not giveReason) then return true; end
                return true, reason;
        end
        if string.find(aura.multiids, "[^0-9/!]") then --- invalid input (only numbers and / allowed)
                self:Debug("Multicheck. Invalid Input. Only numbers and '/' allowed.");
                if (not giveReason) then return true; end
                return true, reason;
        end
        for pword in string.gmatch(aura.multiids, "[^/]+") do
                local reverse;
                if (string.sub(pword, 1, 1) == "!") then
                        pword = string.sub(pword, 2);
                        reverse = true;
                end
                local k = tonumber(pword);
                local linkedAura = self.Auras[k];
                if linkedAura then
                        self:Debug("Multicheck. Aura ",k);      
                        result, reason = linkedAura:ShouldShow(giveReason, reverse);
                        if (not result) then
                                if (not giveReason) then return false; end
                                return result, reason;
                        end                             
                else
                        self:Debug("Multicheck. Non-existant Aura ID specified: "..pword);
                end
        end
        if (not giveReason) then return true; end
        return true, "All multiples match "..aura.multiids;     
end

function PowaAuras:TestThisEffect(auraId, giveReason)
        self:UnitTestInfo("TestThisEffect", auraId);

        local aura = self.Auras[auraId];

        self:Debug("----------------------------------");
        self:Debug("Test Aura for Hide or Show = ",auraId, " showing=",aura.Showing);

        --local shouldShow, reason = aura:ShouldShow(giveReason);
        local shouldShow, reason = aura:ShouldShow(true);
        if (shouldShow) then
                shouldShow, reason = self:CheckMultiple(aura, reason, giveReason);
        end
        
        if shouldShow then
                if (not aura.Showing or aura.HideRequest) then
                        --self:Message("ShowAura ", aura.buffname, " (",auraId,") ", reason);
                        self:DisplayAura(auraId);
                end
        else
                if (aura.Showing) then
                        --self:Message("HideAura ", aura.buffname, " (",auraId,") ", reason);
                        aura.HideRequest = true;
                        local secondaryAura = self.SecondaryAuras[aura.id];
                        if (secondaryAura and secondaryAura.Showing) then
                                secondaryAura.HideRequest = true;
                        end
                end
        end
        
        return shouldShow, reason;
end

function PowaAuras:NewCheckBuffs()
        self:UnitTestInfo("NewCheckBuffs");

        for auraType in pairs(self.AurasByType) do
                if ((self.DoCheck[auraType] or self.DoCheck.All) and #self.AurasByType[auraType]>0) then
                        --self:Message("TestAuraTypes ",auraType," DoCheck ", self.DoCheck[auraType], " All ", self.DoCheck.All, " #", #self.AurasByType[auraType]);
                        for _, v in pairs(self.AurasByType[auraType]) do
                                --self:Message("TestThisEffect ",v);
                                self:TestThisEffect(v);
                        end
                        self.DoCheck[auraType] = false;
                end
        end

        self.DoCheck.All = false;

end

--- -----------------------------------------------------------------------------------------------------------
function PowaAuras:ShowAuraForFirstTime(aura)
        self:UnitTestInfo("ShowAuraForFirstTime", aura.id);
        --self:Message("ShowAuraForFirstTime ", aura.id);
        local auraId = aura.id;

        if (self.ModTest == false) then
                if (aura.sound > 0) and (aura.customsound == "") then
                        PlaySound(aura.soundfile);
                end     
                if not (aura.customsound == "") then
                        PlaySoundFile("Interface\\AddOns\\PowerAuras\\Sounds\\"..aura.customsound);
                end     
        end
        
        local frame, texture = aura:CreateFrames();

        if (aura.owntex == true) then
                texture:SetTexture(aura.icon);
        elseif (aura.wowtex == true) then
                texture:SetTexture(self.WowTextures[aura.texture]);
        elseif (aura.customtex == true) then
                texture:SetTexture(self:CustomTexPath(aura.customname));
        elseif (aura.textaura == true) then
                texture:SetText(aura.aurastext);                
        else
                texture:SetTexture("Interface\\Addons\\PowerAuras\\Auras\\Aura"..aura.texture..".tga");
        end
  
        if (aura.randomcolor) then
                texture:SetVertexColor(random(20,100)/100,random(20,100)/100,random(20,100)/100);       
        else
                texture:SetVertexColor(aura.r,aura.g,aura.b);
        end
  
        if (aura.texmode == 1) then
                if (aura.textaura ~= true) then
                        texture:SetBlendMode("ADD");
                else
                        texture:SetShadowColor(0.0, 0.0, 0.0, 0.8);
                        texture:SetShadowOffset(2,-2);
                end
                frame:SetFrameStrata("LOW");
        else
                if (aura.textaura ~= true) then
                        texture:SetBlendMode("DISABLE");
                else
                        texture:SetShadowColor(0.0, 0.0, 0.0, 0.0);
                        texture:SetShadowOffset(0,0);
                end
                frame:SetFrameStrata("BACKGROUND");
        end

        if (aura.textaura ~= true) then
          if (aura.symetrie == 1) then 
                texture:SetTexCoord(1, 0, 0, 1); --- inverse X
          elseif (aura.symetrie == 2) then 
                texture:SetTexCoord(0, 1, 1, 0); --- inverse Y
          elseif (aura.symetrie == 3) then 
                texture:SetTexCoord(1, 0, 1, 0); --- inverse XY
          else 
                texture:SetTexCoord(0, 1, 0, 1); 
          end   
        end

        frame.baseH = 256 * aura.size * (2-aura.torsion);
        if (aura.textaura == true) then
                local fontsize = math.min(33, math.max(10, math.floor(frame.baseH / 12.8)));
                local checkfont = texture:SetFont(self.Fonts[aura.aurastextfont], fontsize, "OUTLINE, MONOCHROME");
                if not checkfont then
                        texture:SetFont(STANDARD_TEXT_FONT, fontsize, "OUTLINE, MONOCHROME");
                end
                frame.baseL = texture:GetStringWidth() + 5;
        else
                frame.baseL = 256 * aura.size * aura.torsion;
        end
        
        frame:SetAlpha(aura.alpha);
        frame:SetPoint("Center",aura.x, aura.y);
        frame:SetWidth(frame.baseL);
        frame:SetHeight(frame.baseH);
        
        frame.statut = 0;
        
        aura.TimeShown = 0;
        aura.DurationExpired = false;
        if (aura.Timer and aura.timerduration) then
                aura.Timer.CustomDuration = aura.timerduration;
        end
        
        if (aura.begin > 0) then 
                frame.beginAnim = 1;
        else 
                frame.beginAnim = 0; 
        end

        if (aura.begin and aura.begin>0) then
                aura.animation = self:AnimationBeginFactory(aura.begin, aura, frame);
        else
                aura.animation = self:AnimationMainFactory(aura.anim1, aura, frame);
        end
        
        self:UnitTestInfo("frame:Show()", aura.id);
        
        --self:Message("frame:Show()", aura.id, " ", frame);
        frame:Show(); -- Show Aura Frame

        aura.Showing = true;
        if (aura.Timer) then
                aura.Timer.HideRequest = false;
        end
        if (aura.Stacks) then aura.Stacks.HideRequest = false; end
        aura.HideRequest = false;
        self:ShowSecondaryAuraForFirstTime(aura);       
end

function PowaAuras:ShowSecondaryAuraForFirstTime(aura)
        self:UnitTestInfo("ShowSecondaryAuraForFirstTime", aura.id);

        if (aura.anim2 == 0) then --- no secondary aura
                local secondaryAura = self.SecondaryAuras[aura.id];
                if (secondaryAura) then
                        secondaryAura:Hide();
                end
                self.SecondaryAuras[aura.id] = nil;
                self.SecondaryFrames[aura.id] = nil;
                self.SecondaryTextures[aura.id] = nil;
                return;
        end

        -- new secondary Aura
        local secondaryAura = self:AuraFactory(aura.bufftype, aura.id, aura);
        self.SecondaryAuras[aura.id] = secondaryAura;
        
        secondaryAura.isSecondary = true;
        secondaryAura.alpha = aura.alpha * 0.5;
        secondaryAura.anim1 = aura.anim2;
        secondaryAura.speed = aura.speed - 0.1; --- legerement plus lent

        local auraId = aura.id;
        local frame = self.Frames[auraId];
        local texture = self.Textures[auraId];

        local secondaryFrame, secondaryTexture = secondaryAura:CreateFrames();
        
        if (aura.owntex == true) then
                secondaryTexture:SetTexture(aura.icon);
        elseif (aura.wowtex == true) then
                secondaryTexture:SetTexture(self.WowTextures[aura.texture]);
        elseif (aura.customtex == true) then
                secondaryTexture:SetTexture(self:CustomTexPath(aura.customname));
        elseif (aura.textaura == true) then
                secondaryTexture:SetText(aura.aurastext);               
        else
                secondaryTexture:SetTexture("Interface\\Addons\\PowerAuras\\Auras\\Aura"..aura.texture..".tga");
        end
        
        if (aura.randomcolor) then
                if texture:GetObjectType() == "Texture" then
                        secondaryTexture:SetVertexColor( texture:GetVertexColor() );
                elseif texture:GetObjectType() == "FontString" then
                        secondaryTexture:SetVertexColor(texture:GetTextColor());
                end
        else
                secondaryTexture:SetVertexColor(aura.r,aura.g,aura.b);
        end
        
        if (aura.texmode == 1) then
                if (aura.textaura ~= true) then
                        secondaryTexture:SetBlendMode("ADD");
                end
                secondaryFrame:SetFrameStrata("LOW");
        else
                if (aura.textaura ~= true) then
                        secondaryTexture:SetBlendMode("DISABLE");
                end
                secondaryFrame:SetFrameStrata("BACKGROUND");
        end
        
        if not aura.textaura == true then
                if (aura.symetrie == 1) then 
                        secondaryTexture:SetTexCoord(1, 0, 0, 1); --- inverse X
                elseif (aura.symetrie == 2) then 
                        secondaryTexture:SetTexCoord(0, 1, 1, 0); --- inverse Y
                elseif (aura.symetrie == 3) then 
                        secondaryTexture:SetTexCoord(1, 0, 1, 0); --- inverse XY
                else 
                        secondaryTexture:SetTexCoord(0, 1, 0, 1); 
                end
        end

        secondaryFrame.baseL = frame.baseL;
        secondaryFrame.baseH = frame.baseH;
        secondaryFrame:SetPoint("Center",aura.x, aura.y);
        secondaryFrame:SetWidth(secondaryFrame.baseL);
        secondaryFrame:SetHeight(secondaryFrame.baseH);
        
        secondaryFrame.statut = 1;
                
        if (aura.begin > 0) then 
                secondaryFrame.beginAnim = 2;
        else 
                secondaryFrame.beginAnim = 0; 
        end

        if (not aura.begin or aura.begin==0) then
                secondaryAura.animation = self:AnimationMainFactory(aura.anim2, secondaryAura, secondaryFrame);
        else
                secondaryFrame:SetAlpha(0.0); -- Hide secondary until primary begin animation finishes
        end

        self:UnitTestInfo("secondaryFrame:Show()", aura.id);
        secondaryFrame:Show(); -- Show Secondary Aura Frame
        --self:Message("Show #2");
        secondaryAura.Showing = true;
        secondaryAura.HideRequest = false;
end

function PowaAuras:DisplayAura(auraId)
        self:UnitTestInfo("DisplayAura", auraId);
        if (self.Initialising) then return; end   --- de-actived

        local aura = self.Auras[auraId];
        if (aura==nil or aura.off) then return; end

        --self:Message("DisplayAura aura ", aura);
        
        if (not aura.Showing or aura.HideRequest) then
                self:ShowAuraForFirstTime(aura);
        end
end

--- ------------------------------------------------------------------------------------------------- ON UPDATE

function PowaAuras:UpdateAura(aura, elapsed)
        --self:Message("UpdateAura ", aura.id, " ", elapsed);
        if (aura == nil) then
                self:UnitTestInfo("UpdateAura: Don't show, aura missing");
                --self:Message("UpdateAura: Don't show, aura missing");
                return;
        end
        if (aura.off) then
                if (not aura.Showing and not aura:TimerShowing() and not aura:StacksShowing()) then
                        self:UnitTestInfo("UpdateAura: Don't show, off=", aura.off);
                        --self:Message("UpdateAura: Don't show, off=", aura.off);
                        return;
                end
                aura.HideRequest = true;
                if (aura.Timer) then aura.Timer.HideRequest = true; end
        end
        --if (not aura.Showing and not aura:TimerShowing() and not aura:StacksShowing()) then
                --self:UnitTestInfo("UpdateAura: Nothing Showing");
                --self:Message("UpdateAura: Nothing Showing");
                --return;
        --end
        
        --self:Message("aura.Showing ", aura.Showing);
        if (aura.Showing) then
                local frame = aura:GetFrame();
                if (frame == nil) then
                        self:UnitTestInfo("UpdateAura: Don't show, frame missing");
                        --self:Message("UpdateAura: Don't show, frame missing");
                        return;
                end
                --self:Message("UpdateAura ", aura, " ", elapsed);
                
                if (not aura.HideRequest and not aura.isSecondary and not self.ModTest and not aura.DurationExpired and aura.duration > 0) then
                        aura.TimeShown = aura.TimeShown + elapsed;              
                        if (aura.TimeShown > aura.duration) then --- If duration has expired then hide this aura
                                self:UnitTestInfo("UpdateAura: Hide, duration expired");
                                --self:Message("UpdateAura: Hide, duration expired");
                                aura.HideRequest = true;
                                aura.DurationExpired = true;
                        end
                end
                
                if (aura.HideRequest) then
                        if (aura.Timer and self.ModTest) then
                                aura.Timer.HideRequest = true;
                        end

                        if (aura.Stacks) then
                                aura.Stacks.HideRequest = true;
                                aura.Stacks:Hide();
                        end
                        --self:Message("Hide Requested for ",aura.id);
                        aura.animation = self:AnimationEndFactory(aura.finish, aura, frame);
                        if (not aura.animation) then
                                aura:Hide();
                        end
                end

                self:UpdateAuraAnimation(aura, elapsed);

                if (aura.Stacks and not aura.Stacks.HideRequest) then
                        aura.Stacks:Update();   
                end
        end
        
        if (aura.isSecondary) then return; end
        
        if (aura.Timer) then
                if (aura.Timer.HideRequest) then
                        aura.Timer:Hide();
                else
                        aura.Timer:Update(elapsed);     
                end
        end
        
        aura.HideRequest = false;
        
end

function PowaAuras:UpdateAuraAnimation(aura, elapsed)
        if (not aura.Showing) then return; end
        if (not aura.animation or elapsed==0) then return; end
                        
        local finished = aura.animation:Update(math.min(elapsed, 0.03));
        
        if (not finished) then return end
        
        if (aura.animation.IsBegin) then
                aura.animation = self:AnimationMainFactory(aura.anim1, aura, frame);
                local secondaryAura = self.SecondaryAuras[aura.id];
                if (secondaryAura) then
                        local secondaryAuraFrame = self.SecondaryFrames[aura.id];
                        if (secondaryAuraFrame) then
                                secondaryAura.animation = self:AnimationMainFactory(aura.anim2, secondaryAura, secondaryAuraFrame);
                        end
                end
                return;
        end
        
        if (aura.animation.IsEnd) then
                aura:Hide();
        end

end

function PowaAuras:OnUpdate(elapsed)
        self:UnitTestInfo("OnUpdate", elapsed);

        if (self.Initialising) then return; end 
                
        self.DebugTimer = self.DebugTimer + elapsed;
        self.ChecksTimer = self.ChecksTimer + elapsed;
        self.AnimationThrottleTimer = self.AnimationThrottleTimer + elapsed;    
        self.ThrottleTimer = self.ThrottleTimer + elapsed;
        
        local checkAura = false;
        if (PowaMisc.OnUpdateLimit == 0 or self.ThrottleTimer >= PowaMisc.OnUpdateLimit) then
                checkAura = true;
                self.ThrottleTimer = 0;
        end
                        
        if (not self.ModTest and checkAura) then

            --self:Message("OnUpdate ",elapsedCheck, " ", self.ChecksTimer);
                self:UnitTestInfo("ChecksTimer", self.ChecksTimer, self.NextCheck);
                if (self.ChecksTimer > (self.NextCheck + PowaMisc.OnUpdateLimit)) then
                        self.ChecksTimer = 0;
                        local isMountedNow = (IsMounted()~=nil);
                        if (isMountedNow ~= self.WeAreMounted) then
                                self.DoCheck.All = true;
                                self.WeAreMounted = isMountedNow;
                        end     
                        self.DoCheck.Enchants = true;
                        self.DoCheck.OwnSpells = true;
                end

                --- Usable pending Checks
                if self.UsablePending then
                        self:UnitTestInfo("UsablePending");
                        for slot, cd in pairs(self.UsablePending) do    
                                if cd then
                                        if GetTime() > cd then
                                                self.DoCheck.Actions = true;
                                                self.DoCheck.Stance = true;
                                                self.WeAreMounted = (IsMounted()~=nil);
                                                self.WeAreInVehicle = (UnitInVehicle("player")~=nil);
                                                self.UsablePending[slot] = nil;
                                        end
                                end
                        end
                end
        
                self:UnitTestInfo("DoCheck update");
                for k ,v in pairs(self.DoCheck) do
                        self:Debug("DoCheck "..k.." = " .. tostring(v)  );
                        if (v) then
                                self:NewCheckBuffs();
                                break;
                        end
                end
        end
        
        if (PowaMisc.AnimationLimit > 0 and self.AnimationThrottleTimer < PowaMisc.AnimationLimit) then
                return;
        end
        elapsed = self.AnimationThrottleTimer;
        self.AnimationThrottleTimer = 0;

        -- Update each aura (timers and animations)
        self:UnitTestInfo("Aura updates");
        for _, aura in pairs(self.Auras) do
                self:UpdateAura(aura, elapsed);
        end     
        for _, aura in pairs(self.SecondaryAuras) do
                self:UpdateAura(aura, elapsed);
        end     
        
        self.ResetTargetTimers = false;

end

function PowaAuras:ExtractImportValue(valueType, value)
        if valueType == "st" then
                return value;
        elseif valueType == "bo" then
                if value == "false" then
                        return false;
                elseif value == "true" then
                        return true;
                end
        elseif valueType == "nu" then
                return tonumber(value);
        end
        return nil;
end

function PowaAuras:ImportAura(aurastring, auraId)

        --self:Message("Import ", auraId);
        --self:Message(aurastring);

        local aura = cPowaAura(auraId);

        local aurastring = string.gsub(aurastring,";%s*",";");
        local temptbl = {strsplit(";", aurastring)};
        local importAuraSettings = {};
        local importTimerSettings = {};
        local hasTimerSettings = false;

        for i, val in ipairs(temptbl) do
                --self:Message(i, "  ", val);
                local key, var = strsplit(":", val);
                local varpref = string.sub(var,1,2);
                var = string.sub(var,3);
                if (string.sub(key,1,6)  == "timer.") then
                        importTimerSettings[key] = self:ExtractImportValue(varpref, var);
                        hasTimerSettings = true;
                else
                    importAuraSettings[key] = self:ExtractImportValue(varpref, var);
                end
        end
        
        for k, v in pairs(aura) do
                local varType = type(v);
                --self:Message(k, "  ", v, "  ", varType, "  ", importAuraSettings[k]);
                if (varType == "string" or varType == "boolean" or varType == "number" and k~="id") then
                        aura[k] = importAuraSettings[k];
                end
        end     
        
        if (aura.bufftype==self.BuffTypes.Combo) then --backwards compatability
                if (string.len(aura.buffname)>1 and string.find(aura.buffname, "/", 1, true)==nil) then
                        local newBuffName=string.sub(aura.buffname, 1, 1);
                        for i=2, string.len(aura.buffname) do
                                newBuffName = newBuffName.."/"..string.sub(aura.buffname, i, i);
                        end
                        aura.buffname = newBuffName
                end
        end
        
        if (importAuraSettings.timer) then --backwards compatability
                aura.Timer = cPowaTimer(aura.id);
        end
        
        --self:Message("hasTimerSettings=", hasTimerSettings);
        if (hasTimerSettings) then
                --self:CreateTimerFrameIfMissing(aura.id)
                if (aura.Timer==nil) then
                        aura.Timer = cPowaTimer(aura.id);
                end
                for k in pairs(aura.Timer) do
                        aura.Timer[k] = importTimerSettings["timer."..k];
                end
        end
        --self:Message("new Aura created from import");
        --aura:Display();
        return self:AuraFactory(aura.bufftype, auraId, aura);
end

function PowaAuras:CreateNewAuraFromImport(auraId, importString)
        if importString==nil or importString == "" then
                return;
        end
        self.Auras[auraId] = self:ImportAura(importString, auraId);
        if (auraId > 120) then
                PowaGlobalSet[auraId] = self.Auras[auraId];
        end                             
end

function PowaAuras:SetupStaticPopups()
        
        StaticPopupDialogs["POWERAURAS_IMPORT_AURA"] = {
                text = self.Text.aideImport,
                button1 = ACCEPT,
                button2 = CANCEL,
                hasEditBox = 1,
                maxLetters = 2000,
                hasWideEditBox = 1,
                OnAccept = function(self)
                        PowaAuras:CreateNewAuraFromImport(PowaAuras.ImportAuraId, self.wideEditBox:GetText());
                        self:Hide();
                end,
                OnShow = function(self)
                        self.wideEditBox:SetFocus();
                end,
                OnHide = function(self)
                        if ( ChatFrameEditBox:IsShown() ) then
                                ChatFrameEditBox:SetFocus();
                        end
                        self.wideEditBox:SetText("");
                        PowaAuras:DisplayAura(PowaAuras.CurrentAuraId);
                        PowaAuras:UpdateMainOption();
                end,
                EditBoxOnEnterPressed = function(self)
                        local parent = self:GetParent();
                        PowaAuras:CreateNewAuraFromImport(PowaAuras.ImportAuraId, parent.wideEditBox:GetText());
                        parent:Hide();
                end,
                EditBoxOnEscapePressed = function(self)
                        self:GetParent():Hide();
                end,
                timeout = 0,
                exclusive = 1,
                whileDead = 1,
                hideOnEscape = 1
        };      
        
        StaticPopupDialogs["POWERAURAS_EXPORT_AURA"] = {
                text = self.Text.aideExport,
                button1 = OKAY,
                button2 = EXIT,
                hasEditBox = 1,
                maxLetters = 2000,
                hasWideEditBox = 1,
                OnShow = function(self)
                        self.wideEditBox:SetText(PowaAuras.Auras[PowaAuras.CurrentAuraId]:CreateAuraString());
                        self.wideEditBox:SetFocus();
                        self.wideEditBox:HighlightText();
                end,
                OnHide = function(self)
                        if ( ChatFrameEditBox:IsShown() ) then
                                ChatFrameEditBox:SetFocus();
                        end
                        self.wideEditBox:SetText("");
                end,
                EditBoxOnEnterPressed = function(self)
                        self:GetParent():Hide();
                end,
                EditBoxOnEscapePressed = function(self)
                        self:GetParent():Hide();
                end,
                timeout = 0,
                exclusive = 1,
                whileDead = 1,
                hideOnEscape = 1
        };
        
end

--- ------------------------------------------------------------------------------------ GESTION DES OPTIONS
function PowaAuras:RedisplayAura() ---Re-show aura after options changed

        if (self.Initialising) then return; end 

        local aura = self.Auras[self.CurrentAuraId];
        if (not aura or not aura.Showing) then
                return;
        end
        aura:Hide();
        aura:CreateFrames();
        self.SecondaryAuras[aura.id] = nil; -- Force recreate
        self:DisplayAura(aura.id);
end

function PowaAuras:OptionTest() --- teste ou masque l'effet choisi

        --self:Message("OptionTest for ", self.CurrentAuraId);
        local aura = self.Auras[self.CurrentAuraId];
        if (not aura or aura.buffname == "" or aura.buffname == " ") then
                return;
        end

        if (aura.Showing) then 
                aura.HideRequest = true;
        else
                aura:CreateFrames();
                self.SecondaryAuras[aura.id] = nil; -- Force recreate
                self:DisplayAura(aura.id);
        end
end


function PowaAuras:OptionHideAll(now) --- Hide all auras
        --self:Message("Hide All Frames now=", now);
        for id, aura in pairs(self.Auras) do
                if now then
                        --self:Message("Hide aura id=", id);
                        aura:Hide();
                else
                        aura.HideRequest = true;
                        if (aura.Timer)  then aura.Timer.HideRequest  = true; end
                        if (aura.Stacks) then aura.Stacks.HideRequest = true; end
                end
        end     

end

Compare with Previous | Blame