vanilla-wow-addons – Rev 1

Subversion Repositories:
Rev:
function GB_Main_RegisterEvents()
        this:RegisterEvent("ACTIONBAR_HIDEGRID");
        this:RegisterEvent("BAG_UPDATE");
        this:RegisterEvent("PLAYER_AURAS_CHANGED");
        this:RegisterEvent("PLAYER_ENTER_COMBAT");
        this:RegisterEvent("PLAYER_ENTERING_WORLD");
        --this:RegisterEvent("PLAYER_LEAVING_WORLD");
        this:RegisterEvent("PLAYER_LEAVE_COMBAT");
        this:RegisterEvent("PLAYER_REGEN_DISABLED");
        this:RegisterEvent("PLAYER_REGEN_ENABLED");
        this:RegisterEvent("PLAYER_TARGET_CHANGED");
        this:RegisterEvent("RAID_ROSTER_UPDATE");
        this:RegisterEvent("SPELLCAST_FAILED");
        this:RegisterEvent("SPELLCAST_INTERRUPTED");
        this:RegisterEvent("SPELLCAST_START");
        this:RegisterEvent("SPELLCAST_STOP");
        this:RegisterEvent("SPELLS_CHANGED");
        this:RegisterEvent("TRAINER_CLOSED");
        this:RegisterEvent("UNIT_AURA");
        this:RegisterEvent("UNIT_HEALTH");
        this:RegisterEvent("UNIT_INVENTORY_CHANGED");
        this:RegisterEvent("UNIT_LEVEL");
        this:RegisterEvent("UPDATE_BINDINGS");
        this:RegisterEvent("VARIABLES_LOADED");
end

function GB_Main_OnLoad()
        GB_Main_RegisterEvents();

        SlashCmdList["GB"] = GB_Slash_Handler;
        SLASH_GB1 = "/gb";
        SLASH_GB2 = "/groupbuttons";
end

function GB_Main_OnEvent()
        if (event == "VARIABLES_LOADED") then
                GB_VARIABLES_LOADED = true;
                if (  GB_ENTERING_WORLD and GB_BAGS_LOADED) then
                        GB_Initialize();
                end
        elseif (event == "PLAYER_ENTERING_WORLD") then
                --GB_Main_RegisterEvents();
                GB_ENTERING_WORLD = true;
                if ( GB_VARIABLES_LOADED and GB_BAGS_LOADED) then
                        GB_Initialize();
                end
                GB_REGEN = true;
                GB_INCOMBAT = false;
        elseif (event == "ACTIONBAR_HIDEGRID") then
                GB_Clear_MouseAction();
        elseif (event == "BAG_UPDATE") then
                if (GB_INITIALIZED) then
                        GroupButtonsFrame.itemstimer = .5;
                else
                        GB_BAGS_LOADED = nil;
                        GroupButtonsFrame.bagsloadedtimer = 1;
                end
        elseif (event == "PLAYER_ENTER_COMBAT") then
                GB_ATTACKING = true;
                GB_INCOMBAT = true;
        elseif (event == "PLAYER_LEAVE_COMBAT") then
                GB_ATTACKING = false;
                if (GB_REGEN) then
                        GB_INCOMBAT = false;
                end
        elseif (event == "PLAYER_LEAVING_WORLD") then
                this:UnregisterAllEvents();
                this:RegisterEvent("PLAYER_ENTERING_WORLD");
        elseif (event == "PLAYER_REGEN_DISABLED") then
                GB_REGEN = false;
                GB_INCOMBAT = true;
        elseif (event == "PLAYER_REGEN_ENABLED") then
                GB_REGEN = true;
                if (not GB_ATTACKING) then
                        GB_INCOMBAT = false;
                end
        elseif (event == "PLAYER_TARGET_CHANGED") then
                if (UnitName("target")) then
                        this.targetauras = true;
                        GB_Update_Auras("target");
                else
                        this.targetauras = false;
                end
        elseif (event == "RAID_ROSTER_UPDATE") then
                if (not GB_INITIALIZED) then return; end
                for i=1,40 do
                        local unit = "raid"..i;
                        if (UnitExists(unit) and UnitName(unit) and (not GB_SKIP_NAMES[UnitName(unit)])) then
                                GB_RAID_MEMBERS[UnitName(unit)] = 1;
                        end
                end
                GB_Update_RaidMemberSelect();
                if (not GB_Settings[GB_INDEX].raid.hide) then
                        GB_Initialize_Labels();
                end
                if (GetNumRaidMembers() > 0 and GB_SHUFFLE_RAID and (not GB_Settings[GB_INDEX].raid.hide)) then
                        GB_Set_Appearance("raid");
                end
                if (GB_Settings[GB_INDEX].hideInRaid and GetNumRaidMembers() > 0) then
                        local partyBar, petBar;
                        for i=1,4 do
                                partyBar = getglobal(GB_Get_UnitBar("party"..i));
                                petBar = getglobal(GB_Get_UnitBar("partypet"..i));
                                partyBar.noshow = true;
                                petBar.noshow = true;
                                partyBar:Hide();
                                petBar:Hide();
                        end
                end
        elseif (event == "SPELLCAST_FAILED") then
                if (GB_ANNOUNCEFAILURE) then
                        GB_Announce_Failed(GB_Get("failedText"));
                end
                GB_ANNOUNCEFAILURE = nil;
                GB_ANNOUNCEINTERRUPTED = nil;
                GB_ISCASTING = nil;
                GB_INSTANTCASTING = nil;
                GB_CURRENT_HEAL = {nil};
                GB_ANNOUNCED = {nil};
                GB_SPELLISCASTING = nil;
        elseif (event == "SPELLCAST_INTERRUPTED") then
                if (GB_ANNOUNCEINTERRUPTED) then
                        GB_Announce_Failed(GB_Get("interruptedText"));
                end
                GB_ANNOUNCEFAILURE = nil;
                GB_ANNOUNCEINTERRUPTED = nil;
                GB_ISCASTING = nil;
                GB_INSTANTCASTING = nil;
                GB_CURRENT_HEAL = {nil};
                GB_ANNOUNCED = {nil};
                GB_SPELLISCASTING = nil;
        elseif (event == "SPELLCAST_START") then
                GB_ANNOUNCEFAILURE = nil;
                GB_ANNOUNCEINTERRUPTED = nil;
                GB_INSTANTCASTING = nil;
                if (GB_ANNOUNCETEXT) then
                        GB_Announce_Spellcast(GB_ANNOUNCETEXT, GB_WHISPERTARGET);
                end
                GB_ISCASTING = nil;
                GB_INSTANTCASTING = nil;
                GB_ANNOUNCETEXT = nil;
                GB_SPELLISCASTING = true;
        elseif (event == "SPELLCAST_STOP") then
                if (GB_INSTANTCASTING) then
                        GB_Announce_Spellcast(GB_ANNOUNCETEXT, GB_WHISPERTARGET);
                        GB_ANNOUNCEFAILURE = nil;
                        GB_ANNOUNCEINTERRUPTED = nil;
                        GB_ISCASTING = nil;
                end
                GB_INSTANTCASTING = nil;
                GB_CURRENT_HEAL = {nil};
                GB_SPELLISCASTING = nil;
        elseif (event == "SPELLS_CHANGED") then
                if (GB_CheckForNewSpells() and GB_INITIALIZED) then
                        if (ClassTrainerFrame and ClassTrainerFrame:IsVisible()) then return; end
                        GroupButtonsFrame.spellstimer = .1;
                        GB_Spellbook_Initialize();
                end
        elseif (event == "TRAINER_CLOSED") then
                GB_Spellbook_Initialize();
                if (GB_SPELLS_UPDATED) then
                        GB_SPELLS_UPDATED = nil;
                else
                        GB_Update_SpellRanks();
                end
        elseif (event == "UNIT_AURA") then
                if (arg1 == "target") then
                        if (this.targetauras) then
                                GB_Update_Auras(arg1);                          
                        end
                else
                        GB_Update_Auras(arg1);
                end
        elseif (event == "PLAYER_AURAS_CHANGED") then
                GB_Update_Auras("player");
        elseif (event == "UNIT_HEALTH") then
                if (GB_CURRENT_HEAL[1] and arg1 == GB_CURRENT_HEAL[3]) then
                        if (GB_Settings[GB_INDEX].cancelHealThreshold) then
                                if (not GB_Get_PastThreshold("cancelHealThreshold", GB_CURRENT_HEAL[3])) then
                                        local text = GB_TEXT.HealCancelledMessage;
                                        text = string.gsub(text, '$s', GB_CURRENT_HEAL[1]);
                                        text = string.gsub(text, '$r', GB_CURRENT_HEAL[2]);
                                        GB_Feedback(text);
                                        GB_CURRENT_HEAL = {};
                                        SpellStopCasting();
                                end
                        end
                end
        elseif (event == "UNIT_INVENTORY_CHANGED") then
                if (GB_INITIALIZED) then
                        GroupButtonsFrame.itemstimer = .5;
                end
        elseif (event == "UNIT_LEVEL") then
                if (GetNumRaidMembers() > 0 and string.find(arg1, "raid")) then
                        GB_Update_RaidMemberSelect();
                end
        elseif (event == "UNIT_NAME") then
                if (GetNumRaidMembers() > 0 and string.find(arg1, "raid")) then
                        GB_Update_RaidMemberSelect();
                end
        elseif (event == "UPDATE_BINDINGS") then
                GB_Update_Bindings();
        end
end

function GB_Slash_Handler(msg)
        local command, param;
        local index = string.find(msg, " ");

        if( index) then
                command = string.sub(msg, 1, (index - 1));
                param = string.sub(msg, (index + 1)  );
        else
                command = msg;
        end
   
        if ( command == "" ) then
                GB_Show_OptionsFrame("main");
        elseif (command == "updateranges") then
                GB_Update_SpellRanges(1)
        elseif (command == "updatespells") then
                GB_Update_Spells(1);
        elseif (command == "toggle") then
                if (param == "labels") then
                        GB_Toggle_Labels();
                elseif (param == "empty") then
                        GB_Toggle_EmptyButtons();
                elseif (param == "spellbook") then
                        GB_Toggle_MiniSpellbook();
                elseif (param == "barlock") then
                        GB_Toggle_BarLock();
                elseif (param == "buttonlock") then
                        GB_Toggle_ButtonsLock();
                end
        elseif (command == "hidebar") then
                local unitBar = GB_Get_UnitBar(param);
                if (unitBar) then
                        GB_Settings[GB_INDEX][getglobal(unitBar).index].hide = true;
                        GB_Set_Appearance(getglobal(unitBar).index);
                end
        elseif (command == "showbar") then
                local unitBar = GB_Get_UnitBar(param);
                if (unitBar) then
                        GB_Settings[GB_INDEX][getglobal(unitBar).index].hide = nil;
                        GB_Set_Appearance(getglobal(unitBar).index);
                end
        elseif (command == "setkeybar") then
                local unitBar = GB_Get_UnitBar(param);
                if (param == "target") then unitBar = "target"; end
                if (unitBar) then
                        GB_Set_CurrentKeybindingBar(unitBar);
                end
        elseif (command == "useaction") then
                local _, _, bar, button = string.find(param, "(.*) (.*)");
                bar = GB_Get_UnitBar(bar);
                if (bar) then
                        button = tonumber(button);
                        if (button) then
                                GB_ActionButton_OnClick(bar, button);
                        end
                end
        elseif (command == "contexts") then
                local unitBar = GB_Get_UnitBar("target");
                local button;
                for i=1,20 do
                        button = getglobal(unitBar.."_Button_"..i);
                        for index,v in button.InContext do
                                if (v == -1) then
                                        GB_Debug("button "..i.." "..index.." = "..v);
                                end
                        end
                end
        elseif (command == "spelldata") then
                for name, ranks in GB_SPELLS do
                        for rank,data in ranks do
                                for i, v in data do
                                        if (string.find(name, param)) then
                                                GB_Feedback(name.." "..rank..": "..i.." = "..v);        
                                        end
                                end
                        end
                end
        elseif (command == "clearall") then
                GB_Settings[GB_INDEX] = nil;
                GB_Initialize_DefaultSettings();
                GB_Initialize_NewSettings();
                GB_UnitFrames_Initialize();
                GB_Initialize_BarOptions("player");
                GB_Initialize_Labels();
                GB_Initialize_Toggles();
                GB_Initialize_AllBars();
                GB_Initialize_AnnounceOptions();
                GB_Initialize_ThresholdsOptions();
                GB_Initialize_MiscOptions();
        elseif (command == "hidebar") then
                if (GB_Settings[GB_INDEX][param]) then
                        GB_Settings[GB_INDEX][param].hide = true;
                        GB_Set_Appearance(param);
                end
        elseif (command == "showbar") then
                if (GB_Settings[GB_INDEX][param]) then
                        GB_Settings[GB_INDEX][param].hide = nil;
                        GB_Set_Appearance(param);
                end
        else
                for _, t in GB_HELP_TEXT do
                        GB_Feedback(t);
                end
        end
end

function GB_Debug(msg)
        DEFAULT_CHAT_FRAME:AddMessage( msg, 1.0, 0.0, 0.0 );
end

function GB_Feedback(msg)
        if (GB_Get("disableGBSpam")) then return; end
        DEFAULT_CHAT_FRAME:AddMessage( msg, 1.0, 1.0, 0.0 );
end

function GB_StopMoving(frame)
        if (frame) then
                this = frame;
        end
        if (this.isMoving) then
                this:StopMovingOrSizing();
                this:SetUserPlaced(true);
                GB_Settings[GB_INDEX].frameLocs[this:GetName()] = {x = this:GetLeft(), y = this:GetTop()};
                this.isMoving = false;
        end
end

function GB_StartMoving(frame)
        if (frame) then
                this = frame;
        end
        if (this:GetName() ~= "GB_Options" and this:GetName() ~= "GB_MiniSpellbook" ) then
                if (not GB_Get("barsLocked")) then
                        GB_Feedback(GB_TEXT.BarsUnlockedWarning);
                end
        end
        if (arg1 == "LeftButton") then
                this:SetUserPlaced(true);
                this:StartMoving();
                this.isMoving = true;
        end
end

function GB_Copy_Table(src, dest)
        for index, value in src do
                if (type(value) == "table") then
                        dest[index] = {};
                        GB_Copy_Table(value, dest[index]);
                else
                        dest[index] = value;
                end
        end
end

function GB_MenuTimeout()
        if (this.timer) then
                this.timer = this.timer - arg1;
                if (this.timer < 0) then
                        this:Hide();
                        this.timer = nil;
                end
        end
end

function GB_SpellChanged(text, name, rank)
        text = string.gsub(text, "$name", name);
        if (rank and rank ~= "") then
                text = string.gsub(text, "$rank", "("..rank..")");
        end
        GB_Feedback(text);
end

function GB_Show_Tooltip(bar, button)
        if (GB_Settings[GB_INDEX].Disable) then return; end
        if (GB_Get("disableTooltip")) then return; end
        local idType = GB_Settings[GB_INDEX][bar].Button[button].idType;
        local name = GB_Settings[GB_INDEX][bar].Button[button].name;
        if (not name) then
                return;
        end
        GameTooltip_SetDefaultAnchor(GameTooltip, this);
        if (idType == "spell") then
                GameTooltip:SetSpell(GB_SPELLS[name][GB_Settings[GB_INDEX][bar].Button[button].rank].id, SpellBookFrame.bookType);
        elseif (idType == "item") then
                local hasCooldown = GameTooltip:SetBagItem(GB_ITEMS[name].bag,GB_ITEMS[name].slot);
                if ( hasCooldown ) then
                        this.updateTooltip = TOOLTIP_UPDATE_TIME;
                else
                        this.updateTooltip = nil;
                end
        elseif (idType == "inv") then
                local _,hasCooldown = GameTooltip:SetInventoryItem("player", GB_INVENTORY[name].id);
                if ( hasCooldown ) then
                        this.updateTooltip = TOOLTIP_UPDATE_TIME;
                else
                        this.updateTooltip = nil;
                end
        elseif (idType == "macro") then
                GameTooltip:SetText(name, 1, 1, 1);
        end
end

function GB_AttackTarget()
        if (UnitCanAttack("player","target") and UnitHealth("target") > 0) then
                if (not GB_ATTACKING) then
                        if (not GB_Get("dontAttack")) then
                                AttackTarget(); 
                        end
                end
        end
end

function GB_Announce_Spellcast(text, target)
        if (not GB_ISCASTING) then return; end
        if (not text) then return; end
        if (GB_Get("announceDisabled")) then return; end

        if (GB_Get("doNotAnnounceSolo")) then
                local numParty = GetNumPartyMembers() + GetNumRaidMembers();
                if (numParty < 1) then return; end
        end

        local channel = "SAY";
        local lang = ChatFrameEditBox.language;
        
        if (GB_Get("doNotUseSay")) then channel="WHISPER"; end
        if (not GB_Get("doNotUseParty")) then
                if (GetNumPartyMembers() > 0) then channel = "PARTY"; end
        end
        if (not GB_Get("doNotUseRaid")) then
                if (GetNumRaidMembers() > 0) then channel = "RAID"; end
        end

        if (GB_Settings[GB_INDEX].sendToChannel and GB_Settings[GB_INDEX].announceChannel and GB_Settings[GB_INDEX].announceChannel ~= "") then
                channel = "CHANNEL";
                target = GetChannelName(GB_Settings[GB_INDEX].announceChannel);
        end
        
        SendChatMessage(text, channel, lang, target);

        if (GB_Get("announceFailed")) then
                GB_ANNOUNCEFAILURE = true;
        else
                GB_ANNOUNCEFAILURE = nil;
        end
        if (GB_Get("announceInterrupted")) then
                GB_ANNOUNCEINTERRUPTED = true;
        else
                GB_ANNOUNCEINTERRUPTED = nil;
        end
end

function GB_KeyBindingFrame_GetLocalizedName(name, prefix)
        if ( not name ) then
                return "";
        end
        local tempName = name;
        local i = strfind(name, "-");
        local dashIndex = nil;
        while ( i ) do
                if ( not dashIndex ) then
                        dashIndex = i;
                else
                        dashIndex = dashIndex + i;
                end
                tempName = strsub(tempName, i + 1);
                i = strfind(tempName, "-");
        end

        local modKeys = '';
        if ( not dashIndex ) then
                dashIndex = 0;
        else
                modKeys = strsub(name, 1, dashIndex);
                if ( GetLocale() == "deDE") then
                        modKeys = gsub(modKeys, "CTRL", "STRG");
                end
        end

        local variablePrefix = prefix;
        if ( not variablePrefix ) then
                variablePrefix = "";
        end
        local localizedName = nil;
        if ( IsMacClient() ) then
                -- see if there is a mac specific name for the key
                localizedName = getglobal(variablePrefix..tempName.."_MAC");
        end
        if ( not localizedName ) then
                localizedName = getglobal(variablePrefix..tempName);
        end
        if ( not localizedName ) then
                localizedName = tempName;
        end
        return modKeys..localizedName;
end

function GB_Update_Bindings()
        for bar in GB_UNITS_ARRAY do
                for _, unitBar in GB_UNITS_ARRAY[bar].frames do
                        for button = 1, GB_UNITS_ARRAY[bar].buttons do
                                local keytext = getglobal(unitBar.."_Button_"..button.."TextFrame_HotKey");
                                local keytext2 = getglobal(unitBar.."_Button_"..button.."TextFrame_DynamicHotKey");
                                local unit = getglobal(unitBar).unit;
                                if (bar == "lowesthealth") then
                                        unit = bar;
                                end
                                if (unit == "hostiletarget") then unit = "target";
                                elseif (unit == "friendlytarget") then unit = "target";
                                end
                                local action = "GB_"..string.upper(unit)..button;
                                if (string.find(unit,"party")) then
                                        action = "GB_"..string.upper(unit).."_"..button;
                                end
                                local action2 = "GB_DYNAMICKB"..button;
                                local kbtext = GB_KeyBindingFrame_GetLocalizedName(GetBindingKey(action), "KEY_");
                                local kbtext2 = GB_KeyBindingFrame_GetLocalizedName(GetBindingKey(action2), "KEY_");
                                kbtext = string.upper(kbtext);
                                kbtext2 = string.upper(kbtext2);
                                kbtext = string.gsub(kbtext, "SHIFT", "S");
                                kbtext = string.gsub(kbtext, "CTRL", "C");
                                kbtext = string.gsub(kbtext, "ALT", "A");
                                kbtext = string.gsub(kbtext, "MOUSE BUTTON", "MB");
                                kbtext = string.gsub(kbtext, "MIDDLE MOUSE", "MM");
                                kbtext = string.gsub(kbtext, "NUM PAD", "NP");
                                kbtext2 = string.gsub(kbtext2, "SHIFT", "S");
                                kbtext2 = string.gsub(kbtext2, "CTRL", "C");
                                kbtext2 = string.gsub(kbtext2, "ALT", "A");
                                kbtext2 = string.gsub(kbtext2, "MIDDLE MOUSE", "MM");
                                kbtext2 = string.gsub(kbtext2, "MOUSE BUTTON", "MB");
                                kbtext2 = string.gsub(kbtext2, "NUM PAD", "NP");
                                if (GB_Get("hideBaseBindings")) then kbtext = ""; end
                                if (GB_Get("hideDynamicBindings")) then kbtext2 = ""; end
                                keytext:SetText(kbtext);
                                if (GB_CURRENT_KB_BAR == unitBar or GB_CURRENT_KB_BAR == unit) then
                                        keytext2:SetText(kbtext2);
                                else
                                        keytext2:SetText("");
                                end
                        end
                end
        end
end

function GB_Set_CurrentKeybindingBar(unitBar)
        GB_CURRENT_KB_BAR = unitBar;
        GB_Update_Bindings();
end

function GB_Announce_Failed(text)
        if ((not text) or text == "") then return; end
        if (not GB_ANNOUNCED.spellName) then return; end
        if (GB_ANNOUNCED.target) then
                text = string.gsub(text, '$t', GB_ANNOUNCED.target);
        end
        if (GB_ANNOUNCED.spellRank) then
                text = string.gsub(text, '$r', GB_ANNOUNCED.spellRank);
        end
        text = string.gsub(text, '$s', GB_ANNOUNCED.spellName);
        local channel = "SAY";
        local lang = ChatFrameEditBox.language;
        if (GB_Get("doNotUseSay")) then channel="WHISPER"; end
        if (not GB_Get("doNotUseParty")) then
                if (GetNumPartyMembers() > 0) then channel = "PARTY"; end
        end
        if (not GB_Get("doNotUseRaid")) then
                if (GetNumRaidMembers() > 0) then channel = "RAID"; end
        end
        if (GB_Settings[GB_INDEX].sendToChannel and GB_Settings[GB_INDEX].announceChannel and GB_Settings[GB_INDEX].announceChannel ~= "") then
                channel = "CHANNEL";
                GB_ANNOUNCED.target = GetChannelName(GB_Settings[GB_INDEX].announceChannel);
        end
        SendChatMessage(text, channel, lang, GB_ANNOUNCED.target);
end

function GB_Update_SpellRanks()
        if (GB_Settings[GB_INDEX].Disable) then return; end 
        GB_SPELLS_UPDATED = true;
        GB_CheckForNewSpells();
        GB_Update_Spells();
        local idType, spellrank, rank, autoUpdate, name
        for bar in GB_UNITS_ARRAY do
                for button = 1, 20 do
                        name = GB_Settings[GB_INDEX][bar].Button[button].name
                        idType = GB_Settings[GB_INDEX][bar].Button[button].idType;
                        spellrank = GB_Settings[GB_INDEX][bar].Button[button].rank;
                        autoUpdate = GB_Settings[GB_INDEX][bar].Button[button].autoUpdate;
                        if (idType == "spell" and autoUpdate) then
                                _,_,rank = string.find(spellrank, " (%d*)");
                                rank = tonumber(rank);
                                if (rank) then
                                        rank = rank + 1;
                                        if (GB_SPELLS[name][GB_TEXT.Rank..rank]) then
                                                GB_Settings[GB_INDEX][bar].Button[button].rank = GB_TEXT.Rank..rank;
                                                GB_ActionButton_Initialize(bar, button);
                                                if (bar == GB_BAR) then
                                                        GB_Options_InitAction(bar, button);
                                                end
                                        end
                                end
                        end
                end
        end
end

function GB_CheckForNewSpells()
        count = 0;
        while true do
                count = count + 1;
                local spellName, spellRank = GetSpellName(count, BOOKTYPE_SPELL);
                if not spellName then
                        do break end
                end
        end
        if (GB_SPELLS_COUNT ~= (count  - 1)) then
                return true;
        end
end

function GB_CheckTimeout(timeout, elapsed)
        if (GroupButtonsFrame[timeout].time) then
                GroupButtonsFrame[timeout].time = GroupButtonsFrame[timeout].time - elapsed;
                if (GroupButtonsFrame[timeout].time < 0) then
                        GroupButtonsFrame[timeout].time = nil;
                        GroupButtonsFrame[timeout].func();
                end
        end
end

function GB_CheckBagsTimer(elapsed)
        if (this.bagsloadedtimer) then
                this.bagsloadedtimer = this.bagsloadedtimer - elapsed;
                if (this.bagsloadedtimer < 0) then
                        this.bagsloadedtimer = nil;
                        GB_BAGS_LOADED = true;
                        if (GB_ENTERING_WORLD and GB_VARIABLES_LOADED) then
                                GB_Initialize();
                        end
                end
        end
end

function GB_CheckItemUpdateTimer(elapsed)
        if (this.itemstimer) then
                this.itemstimer = this.itemstimer - elapsed;
                if (this.itemstimer < 0) then
                        this.itemstimer = nil;
                        GB_Update_InventoryItems();
                        GB_Update_ContainerItems();
                end
        end
end

function GB_CheckSpellsUpdateTimer(elapsed)
        if (this.spellstimer) then
                this.spellstimer = this.spellstimer - elapsed;
                if (this.spellstimer < 0) then
                        this.spellstimer = nil;
                        GB_Update_Spells();
                        GB_Spellbook_Initialize();
                end
        end
end

function GB_UnitInRaid(unit)
        local name = UnitName(unit);
        for i=1, GetNumRaidMembers() do
                if (UnitName("raid"..i) == name) then return true; end
        end
end

function GB_CureAny(unit)
        if (not unit) then
                if (GB_LAST_UNIT) then
                        unit = GB_LAST_UNIT;
                else
                        unit = "target";
                end
        end
        if (not UnitName(unit)) then return; end
        local disease, poison, curse, magic;
        local debuff;
        local spell, rank;
        for i = 1, 8 do
                debuff = UnitDebuff(unit, i);   
                if (not debuff) then break; end
                GBTooltip:SetUnitDebuff(unit, i);
                if (GBTooltipTextRight1:IsVisible()) then
                        debuff = GBTooltipTextRight1:GetText();
                else
                        debuff = nil;
                end
                if (debuff) then
                        if (string.find(debuff, GB_FILTERS.Disease)) then
                                if (disease) then
                                        disease = disease + 1;
                                else
                                        disease = 1;
                                end
                        end
                        if (string.find(debuff, GB_FILTERS.Poison)) then
                                if (poison) then
                                        poison = poison + 1;
                                else
                                        poison = 1;
                                end
                        end
                        if (string.find(debuff, GB_FILTERS.Magic)) then
                                if (magic) then
                                        magic = magic + 1;
                                else
                                        magic = 1;
                                end
                        end
                        if (string.find(debuff, GB_FILTERS.Curse)) then
                                if (curse) then
                                        curse = curse + 1;
                                else
                                        curse = 1;
                                end
                        end
                end
        end
        if (magic and (not spell)) then
                if (GB_SPELLS[GB_CURES.DispelMagic.text]) then
                        spell = GB_CURES.DispelMagic.text;
                        rank = 1;
                        if (magic > 1) then
                                rank = 2;
                        end
                elseif (GB_SPELLS[GB_CURES.Cleanse.text]) then
                        spell = GB_CURES.Cleanse.text;
                end
        end
        if (disease and (not spell)) then
                if (GB_SPELLS[GB_CURES.CureDisease.text]) then
                        spell = GB_CURES.CureDisease.text;
                elseif (GB_SPELLS[GB_CURES.Purify.text]) then
                        spell = GB_CURES.Purify.text;
                end
                if (disease > 1 and GB_SPELLS[GB_CURES.AbolishDisease.text]) then
                        if (not GB_Get_BuffMatch(GB_CURES.AbolishDisease.text, target)) then
                                spell = GB_CURES.AbolishDisease.text;
                        else
                                spell = nil;
                        end
                end
        end
        if (poison and (not spell)) then
                if (GB_SPELLS[GB_CURES.CurePoison.text]) then
                        spell = GB_CURES.CurePoison.text;
                elseif (GB_SPELLS[GB_CURES.Purify.text]) then
                        spell = GB_CURES.Purify.text;
                end
                if (poison > 1 and GB_SPELLS[GB_CURES.AbolishPoison.text]) then
                        if (not GB_Get_BuffMatch(GB_CURES.AbolishPoison.text, target)) then
                                spell = GB_CURES.AbolishPoison.text;
                        else
                                spell = nil;
                        end
                end
        end
        if (curse and (not spell)) then
                if (GB_SPELLS[GB_CURES.RemoveCurse.text]) then
                        spell = GB_CURES.RemoveCurse.text;
                end
        end
        if (spell) then
                if (rank) then
                        rank = GB_TEXT.Rank..rank;
                else
                        rank = "";
                end
                CastSpell( GB_SPELLS[spell][rank].id, "BOOKTYPE_SPELL" );
        else
                GB_Feedback(GB_TEXT.NoEffectsFound);
        end
end

--[[function GB_RunMacro(macroname)
        local macroID = GetMacroIndexByName(macroname);
        local _, _, body = GetMacroInfo(macroID);
        if (string.find(body, "\n")) then
                local line = "";
                for i=1,string.len(body) do
                        local character = string.sub(body, i, i);
                        if (character == "\n") then
                                GB_MacroBox:SetText(line);
                                ChatEdit_SendText(GB_MacroBox);
                                line = "";
                        else
                                line = line..character;
                        end
                end
        else
                GB_MacroBox:SetText(body);
                ChatEdit_SendText(GB_MacroBox);
        end
end --]]

function GB_RunMacro(macroname)
        local name, texture, body, isLocal = GetMacroInfo(GetMacroIndexByName(macroname));

        if ( not body ) then return; end

        local length = string.len(body);
        local text="";
        for i = 1, length do
                text=text..string.sub(body,i,i);
                if ( string.sub(body,i,i) == "\n" or i == length ) then
                        if ( string.find(text,"/cast") ) then
                                local i, booktype = GB_GetSpell(gsub(text,"%s*/cast%s*(.*)%s;*.*","%1"));
                                if ( i ) then
                                        RunScript("CastSpell("..i..",'"..booktype.."')");
                                end
                        else
                                while ( string.find(text, "CastSpellByName")) do
                                        local spell = gsub(text,'.-CastSpellByName.-%(.-"(.-)".*','%1',1);
                                        local i, booktype = GB_GetSpell(spell);
                                        if ( i ) then
                                                text = gsub(text,'CastSpellByName.-%(.-".-"','CastSpell('..i..','..'"'..booktype..'"',1);
                                        else
                                                text = gsub(text,'CastSpellByName.-%(.-".-"%)','',1);
                                        end
                                end
                                if ( string.find(text,"/script")) then
                                        RunScript(gsub(text,"%s*/script%s*(.*)","%1"));
                                else
                                        GB_MacroBox:SetText(text);
                                        ChatEdit_SendText(GB_MacroBox);
                                end
                        end
                        text="";
                end
        end
end

function GB_GetSpell(spell)
        local s = gsub(spell, "%s-(.-)%s*%(.*","%1");
        local r;
        if ( string.find(spell, "%(%s*[Rr]acial")) then
                r = "racial"
        elseif ( string.find(spell, "%(%s*[Ss]ummon")) then
                r = "summon"
        elseif ( string.find(spell, "%(%s*[Aa]pprentice")) then
                r = "apprentice"
        elseif ( string.find(spell, "%(%s*[Jj]ourneyman")) then
                r = "journeyman"
        elseif ( string.find(spell, "%(%s*[Ee]xpert")) then
                r = "expert"
        elseif ( string.find(spell, "%(%s*[Aa]rtisan")) then
                r = "artisan"
        elseif ( string.find(spell, "%(%s*[Mm]aster")) then
                r = "master"
        elseif ( not string.find(spell, "%(")) then
                r = ""
        else
                r = gsub(spell, ".*%(.*[Rr]ank%s*(%d+).*", "Rank %1");
        end
        return GB_FindSpell(s,r);
end

function GB_FindSpell(spell, rank)
        local i = 1;
        local booktype = "spell";
        local s,r;
        local ys, yr;
        while true do
                s, r = GetSpellName(i,"spell");
                if ( not s ) then break; end
                if ( string.lower(s) == string.lower(spell)) then ys=true; end
                if ( (r == rank) or (r and rank and string.lower(r) == string.lower(rank))) then yr=true; end
                if ( ys and yr ) then
                        return i,booktype;
                end
                i=i+1;
                ys = nil;
                yr = nil;
        end
        i = 1;
        while true do
                s, r = GetSpellName(i,"pet");
                if ( not s) then break; end
                if ( string.lower(s) == string.lower(spell)) then ys=true; end
                if ( (r == rank) or (r and rank and string.lower(r) == string.lower(rank))) then yr=true; end
                if ( ys and yr ) then
                        booktype = "pet";
                        return i,booktype;
                end
                i=i+1;
                ys = nil;
                yr = nil;
        end
        return nil, booktype;
end

function GB_Update_Auras(unit)
        if (unit == "mouseover") then return; end
        if (not UnitName(unit)) then return; end
        GB_BUFFS[unit] = {nil};
        GB_DEBUFFS[unit] = {nil};
        GBAuraTooltip:SetOwner(WorldFrame, "ANCHOR_NONE");

        if (unit == "player") then
                GB_SHADOWFORM_INDEX = nil
        end
        for i = 1, 16 do
                if (UnitBuff(unit, i)) then
                        GBAuraTooltip:SetUnitBuff(unit, i);
                        if (GBAuraTooltipTextLeft1:IsShown()) then
                                GB_BUFFS[unit][GBAuraTooltipTextLeft1:GetText()] = i;
                                if (unit == "player" and GBAuraTooltipTextLeft1:GetText() == GB_TEXT.Shadowform) then
                                        for j = 0, 15 do
                                                local bi = GetPlayerBuff(j, "HELPFUL")
                                                if (GetPlayerBuffTexture(bi)) then
                                                        GBAuraTooltip:SetPlayerBuff(bi);
                                                        if (GBAuraTooltipTextLeft1:IsShown() and GBAuraTooltipTextLeft1:GetText() == GB_TEXT.Shadowform) then
                                                                GB_SHADOWFORM_INDEX = j
                                                                break
                                                        end
                                                end
                                        end
                                end
                                if (string.find(GBAuraTooltipTextLeft1:GetText(), "-", 1, true)) then
                                        GB_BUFFS[unit][UnitBuff(unit, i)] = i;
                                end
                        end
                end
        end
        for i = 1, 16 do
                if (UnitDebuff(unit, i)) then
                        GBAuraTooltip:SetUnitDebuff(unit, i);
                        if (GBAuraTooltipTextLeft1:IsShown()) then
                                GB_DEBUFFS[unit][GBAuraTooltipTextLeft1:GetText()] = true;
                        end
                        if (GBAuraTooltipTextRight1:IsShown()) then
                                GB_DEBUFFS[unit][GBAuraTooltipTextRight1:GetText()] = true;
                        end
                end
        end
end

Generated by GNU Enscript 1.6.5.90.