vanilla-wow-addons – Rev 1

Subversion Repositories:
Rev:
--[[      ---------------------------------------------------------------
                Call To Arms
                ---------------------------------------------------------------
                
                @Author:                Sacha Beharry
                @DateCreated:   26th May 2005
                @LastUpdate:    1st July 2006
                @Release:               R10
                @Version:               1.6
                @Note:                  
                ]]

                CTA_RELEASEVERSION      = "R10";
                CTA_RELEASENOTE         = "R10 [1.6]";
                CTA_THIS_VERSION        = 9;
        
--[[    ---------------------------------------------------------------
        
                Web:                    
        
                Filename:               CallToArms.lua
        
                Project Name:   Call To Arms
        
                Description:    Main Program
        
                Purpose:
                ---------------------------------------------------------------         
                ]]




--[[    ---------------------------------------------------------------
                Variables
                ---------------------------------------------------------------
                ]]

CTA_DEFAULT_RAID_CHANNEL                                = "CTAChannel";
CTA_INVITE_MAGIC_WORD                                   = "inviteme";
CTA_PLAYER                                                              = "PLAYER";
CTA_MAX_RESULTS_ITEMS                                   = 20;
CTA_MAX_BLACKLIST_ITEMS                                 = 15;
CTA_ALLIANCE                                            = "Alliance";
CTA_HORDE                                                               = "Horde";

CTA_DEFAULT_LFM_TRIGGER                                 = "\"lf%d*m\"";
CTA_DEFAULT_LFG_TRIGGER                                 = "lfg";

CTA_SavedVariables = {
        
        version                                                         = 0,
        
        runCount                                                        = 0,

        GreyList                                                        = {},
        
        MinimapArcOffset                                        = 223,
        MinimapRadiusOffset                                     = 75,
        
        MinimapMsgArcOffset                                     = 296,
        MinimapMsgRadiusOffset                          = 95,
        
        MainFrameTransparency                           = 0.85,
        lfmTrigger                                                      = "\"lf%d*m\"",
        lfgTrigger                                                      = "lfg"
};

CTA_CommunicationChannel                                = "CTAChannel";
CTA_MyRaid                                                              = nil;
CTA_RaidList                                                    = {};
CTA_ResultsListOffset                                   = 0;
CTA_BlackList                                                   = {};
CTA_PlayerListOffset                                    = 0;
CTA_MyRaidIsOnline                                              = nil;

CTA_IgnoreBlacklisted                                   = 1;


local CTA_RAID_TYPE_PVP                                 = 1;
local CTA_RAID_TYPE_PVE                                 = 0;
local CTA_GREYLISTED                                    = 0;
local CTA_BLACKLISTED                                   = 1;
local CTA_WHITELISTED                                   = 2;
local CTA_MESSAGE                                               = "M";
local CTA_GENERAL                                               = "I";
local CTA_GROUP_UPDATE                                  = "G";
local CTA_BLOCK                                                 = "X";
local CTA_SEARCH                                                = "S";

local CTA_MESSAGE_COLOURS = {
        M = { r = 1,   b = 1,   g = 0.5 },
        I = { r = 1,   b = 0.5, g = 1   },
        G = { r = 0.5, b = 0.5, g = 1   },
        X = { r = 1,   b = 0.5, g = 0.5 },
        S = { r = 0.5, b = 1,   g = 0.5 }
};

local CTA_MyRaidPassword                                = nil;
local CTA_UpdateTicker                                  = 0.0;
local CTA_SearchTimer                                   = 0;
local CTA_SelectedResultListItem                = 0;
local CTA_ChannelSpam                                   = {};
local CTA_SpamTimer                                     = 0;
local CTA_PendingMembers                                = {};
local CTA_GraceTimer                                    = 0;
local CTA_HostingRaidGroup                              = nil;
          CTA_InvitationRequests                        = {};
local CTA_OutstandingRequests                   = 0;
local CTA_RequestTimer                                  = 0;




CTA_PollBroadcast                                               = nil;
CTA_PollApplyFilters                                    = nil;
CTA_TimeSinceLastBroadcast                              = 0;
CTA_TimeSinceLastFilter                                 = 0
CTA_RawGroupList                                                = {};
CTA_JoinedChannel                                               = nil;
CTA_AcidSummary                                                 = nil;
CTA_AnnounceTimer                                               = 0;

CTA_WhoName                                                             = nil;


-- R7 BEGIN

local lfxChatMessageList                                = {};
local autoannounce                                              = nil;

--CTA_lfmTrigger                                                = CTA_DEFAULT_LFM_TRIGGER;
--CTA_lfgTrigger                                                = CTA_DEFAULT_LFG_TRIGGER;

CTA_CtaMessageList                                              = {};

CTA_ForwardTimer                                                = 10;
CTA_WhoFlag                                                     = nil;

CTA_AcidDetails                                                 = nil;
CTA_PlayerIsAFK                                                 = nil;

CTA_Classes                                                             = {};

--R7 END

--[[    ---------------------------------------------------------------
                OnLoad and Slash Commands
                ---------------------------------------------------------------
                ]]




--[[    CTA_OnLoad()
                ---------------------------------------------------------------
                Register events and hook functions.
                ]]

function CTA_OnLoad()

        --Register Slash Command
        SlashCmdList["CallToArmsCOMMAND"] = CTA_SlashHandler;
        SLASH_CallToArmsCOMMAND1 = "/cta";
        
        --Register Event Listeners
        this:RegisterEvent("CHAT_MSG_SYSTEM");
        this:RegisterEvent("PARTY_MEMBERS_CHANGED");
        this:RegisterEvent("PARTY_LEADER_CHANGED");
        this:RegisterEvent("CHAT_MSG_WHISPER");
        this:RegisterEvent("CHAT_MSG_CHANNEL");
        this:RegisterEvent("RAID_ROSTER_UPDATE");
        this:RegisterEvent("WHO_LIST_UPDATE");
        this:RegisterEvent("VARIABLES_LOADED");
         
        --Announce AddOn to user
        CTA_Println( CTA_CALL_TO_ARMS_LOADED );
        CTA_Error("-[ CTA "..CTA_RELEASEVERSION.." ]-");
        
        CTA_Classes[1] = CTA_PRIEST;
        CTA_Classes[2] = CTA_MAGE;
        CTA_Classes[3] = CTA_WARLOCK;
        CTA_Classes[4] = CTA_DRUID;
        CTA_Classes[5] = CTA_HUNTER;
        CTA_Classes[6] = CTA_ROGUE;
        CTA_Classes[7] = CTA_WARRIOR;
        if( UnitFactionGroup(CTA_PLAYER) == CTA_ALLIANCE ) then
                CTA_Classes[8] = CTA_PALADIN;
        else
                CTA_Classes[8] = CTA_SHAMAN;
        end                     
        CTA_Classes[CTA_PRIEST]         = 1;
        CTA_Classes[CTA_MAGE]           = 2;
        CTA_Classes[CTA_WARLOCK]        = 3;
        CTA_Classes[CTA_DRUID]          = 4;
        CTA_Classes[CTA_HUNTER]         = 5;
        CTA_Classes[CTA_ROGUE]          = 6;
        CTA_Classes[CTA_WARRIOR]        = 7;
        CTA_Classes[CTA_PALADIN]        = 8;
        CTA_Classes[CTA_SHAMAN]         = 8;    

        --Hook into ChatFrame to hide AddOn communication
        local old_ChatFrame_OnEvent = ChatFrame_OnEvent;
        function ChatFrame_OnEvent(event)

                -- R5 : effectively makes blacklist an extended ignore list as well
                if( arg2 and CTA_IgnoreBlacklisted and CTA_FindInList( arg2, CTA_BlackList ) ) then
                        --CTA_IconMsg( arg2, CTA_BLOCK ); -- left for testing, disabled for R7
                        CTA_LogMsg( "Blocked message from "..arg2, CTA_BLOCK ); -- R7
                        return;
                end

                if( strsub(event, 1, 16) == "CHAT_MSG_WHISPER" ) then
                        if( arg2 and arg1 and strsub(arg1, 1, 5) == "[CTA]" ) then
                                CTA_IconMsg( arg2, CTA_MESSAGE );
                                CTA_LogMsg( arg2..": "..arg1, CTA_MESSAGE );
                                return; --R3
                        end
                end
                
                if( arg9 and CTA_MuteLFGChannelCheckButton:GetChecked() and arg9=="LookingForGroup" ) then
                        --CTA_IconMsg( arg1 ); -- for testing
                        return;
                end

                if ( not arg1 or strsub(event, 1, 16) ~= "CHAT_MSG_WHISPER" or strsub(arg1, 1, 5) ~= "/cta " ) then -- not arg1: R3 bug fix
                        if( not arg1 or not CTA_MainFrame:IsVisible() or not string.find( arg1, "Away from Keyboard") ) then -- not arg1: R3 bug fix
                                old_ChatFrame_OnEvent(event);
                        end
                end

        end
        
        --Hook into FriendsFrame_OnEvent
        local old_FriendsFrame_OnEvent = FriendsFrame_OnEvent;
        function FriendsFrame_OnEvent()
                if( event ~= "WHO_LIST_UPDATE" or ( CTA_OutstandingRequests == 0 and CTA_WhoFlag == nil  ) ) then
                --if( CTA_OutstandingRequests == 0 and CTA_WhoFlag == nil ) then
                        old_FriendsFrame_OnEvent();
                end
        end
        
        ScriptErrors:SetScript("OnShow", CTA_ScriptError );             
end

function CTA_ScriptError()
        local message = ScriptErrors_Message:GetText();
        if (not message or not string.find( message, "CallToArms" ) ) then 
                --CTA_Println( "No CallToArms error found" );
                return; 
        end
        

        local extMsg = "Error: "..message;
        extMsg = extMsg..", Addons: ";
        local numAddons = GetNumAddOns();
        for i = 1, numAddons do
                if( IsAddOnLoaded( i ) ) then
                        local name = GetAddOnInfo( i );
                        extMsg = extMsg..name..", ";
                end
        end
        extMsg = extMsg.." Client: "..GetLocale();
        
    CTA_ErrorReportingFrameEditBox:SetText( extMsg );
        CTA_ErrorReportingFrame:Show();
end



--[[    CTA_SlashHandler(com)
                ---------------------------------------------------------------
                For Slash Commands (surprise)
                @arg The command String
                ]]

function CTA_SlashHandler(com)
        if( not com or  com=="" ) then
                CTA_Println( CTA_CALL_TO_ARMS.." "..CTA_RELEASEVERSION );
                CTA_Println( CTA_COMMANDS..": "..CTA_HELP.." | "..CTA_TOGGLE.." | "..CTA_ANNOUNCE_GROUP.." |  "..CTA_DISSOLVE_RAID );

                CTA_Println( CTA_COMMANDS..": "..CTA_TOGGLE_MINIMAP );

                CTA_Println( "Beta commands:" );
                CTA_Println( "/error: starts CTA error reporting function. Only works if an error has already occurred." );
                return;
        end

        if( com==CTA_HELP ) then
                CTA_Println( CTA_TOGGLE..": "..CTA_TOGGLE_HELP );
                CTA_Println( CTA_ANNOUNCE_GROUP..": "..CTA_ANNOUNCE_GROUP_HELP );
                CTA_Println( CTA_DISSOLVE_RAID..": "..CTA_DISSOLVE_RAID_HELP );
                return;
        end

        if( com==CTA_TOGGLE ) then
                if( CTA_MainFrame:IsVisible() ) then
                        CTA_MainFrame:Hide();
                else
                        CTA_MainFrame:Show();
                end
                return;
        end
        
        if( com==CTA_TOGGLE_MINIMAP ) then
                if( CTA_MinimapIcon:IsVisible() ) then
                        CTA_MinimapIcon:Hide();
                else
                        CTA_MinimapIcon:Show();
                end
                return;
        end
        
        if( com==CTA_DISSOLVE_RAID ) then
                if( IsRaidLeader() ) then
                        CTA_DissolveRaid();
                else
                        CTA_Println( CTA_MUST_BE_LEADER_TO_DISSOLVE_RAID );
                end
                return;
        end     
        
                
        if( com==CTA_AUTO_ANNOUNCE_OFF ) then
                autoannounce = nil;
                CTA_AnnounceTimer = 0;
                CTA_Println( "Auto announce OFF" );
                return;
        end     
        
        for channelName in string.gfind( com, CTA_ANNOUNCE_GROUP.." (%w+)" ) do 
                autoannounce = channelName;
                CTA_AnnounceTimer = 5;
                CTA_Println( "Auto announce ON" );
        end

        
        --[ [
        if( com=="error" ) then
                CTA_ScriptError();
                return;
        end     
        --]]
        
        if( com=="test" ) then
                local DefaultChannels = { GetChatWindowChannels(DEFAULT_CHAT_FRAME:GetID()) };
                local connected = nil;
                if( DefaultChannels ) then 
                        for item = 1, getn(DefaultChannels) do
                                CTA_Println( DefaultChannels[item] or "Null" );
                        end
                end
        end
                
end




--[[    ---------------------------------------------------------------
                OnUpdate and OnEvent
                ---------------------------------------------------------------
                ]]



--[[    CTA_OnUpdate()
                ---------------------------------------------------------------
                Keep the <var>CTA_UpdateTicker</var> running.
                @arg The time elapsed since the last call to this function
                ]]

function CTA_OnUpdate( arg1 )
        CTA_UpdateTicker = CTA_UpdateTicker + arg1;
        if( CTA_UpdateTicker >= 1 ) then
        
                if( CTA_AnnounceTimer > 0 ) then
                        CTA_AnnounceTimer = CTA_AnnounceTimer - 1;

                        -- r7
                        if( CTA_AnnounceTimer == 0 and autoannounce ) then      
                                if( CTA_PlayerIsAFK ) then
                                        autoannounce = nil;
                                        CTA_Println( "You are AFK: Setting auto announce to OFF" );
                                elseif ( CTA_GetNumGroupMembers() > 1 and not CTA_MyRaid ) then
                                        autoannouce = nil;
                                        CTA_Println( "You have joined a group. LFG Auto announce OFF" );
                                elseif( CTA_MyRaidIsOnline and CTA_MyRaid and CTA_AcidSummary ) then
                                        CTA_SendChatMessage( CTA_AcidSummary, "CHANNEL", autoannounce );
                                        CTA_AnnounceTimer = 100;
                                        PlaySound("TellMessage");
                                        CTA_IconMsg( "Announced LFM" );
                                        CTA_Println( "Announced LFM message to local channel" );
                                elseif( CTA_LGMPrefixLabel:GetText() and CTA_LFGDescriptionEditBox:GetText() ~= "" ) then
                                        CTA_SendChatMessage( CTA_LGMPrefixLabel:GetText()..CTA_LFGDescriptionEditBox:GetText(), "CHANNEL", autoannounce );
                                        CTA_AnnounceTimer = 100;
                                        PlaySound("TellMessage");
                                        CTA_IconMsg( "Announced LFG" );
                                        CTA_Println( "Announced LFG message to local channel" );
                                else
                                        autoannounce = nil;
                                        CTA_Println( "Nothing to announce: Setting auto announce to OFF" );
                                end
                        end
                        -- /r7
                end
        
                CTA_TimeSinceLastBroadcast = CTA_TimeSinceLastBroadcast + 1;
                if( CTA_TimeSinceLastBroadcast > 15 ) then
                        CTA_TimeSinceLastBroadcast = 0;
                        
                        --[[if( CTA_PlayerIsAFK ) then
                                CTA_PollBroadcast = nil;
                        else]]
                        
                        if( CTA_MyRaidIsOnline and CTA_MyRaid ) then
                                CTA_PollBroadcast = 1;
                        elseif( CTA_LFGCheckButton:GetChecked() and CTA_LGMPrefixLabel:GetText() and CTA_LFGDescriptionEditBox:GetText() ~= "" ) then
                                if( CTA_GetNumGroupMembers() > 1 ) then
                                        CTA_LFGCheckButton:SetChecked( 0 );
                                        CTA_Println( "You have joined a group. CTA has stopped listing you as looking for a group." );
                                else
                                        CTA_PollBroadcast = 3;
                                end
                        end
                        
                        --/r7
                end
                
                CTA_TimeSinceLastFilter = CTA_TimeSinceLastFilter + 1;
                if( CTA_TimeSinceLastFilter > 15 ) then
                        CTA_TimeSinceLastFilter = 0;
                        CTA_PollApplyFilters = 1;
                end

                CTA_SpamTimer = CTA_SpamTimer + CTA_UpdateTicker;
                if( CTA_SpamTimer > 10 ) then
                        CTA_ChannelSpam = {};
                        CTA_SpamTimer = 0;
                        

                        
                        -- Ok, piggybacking 10s SpamTimer to implement 
                        -- Polled Broadcasting and
                        -- Auto Search Updates.
                        
                        if( CTA_PollApplyFilters ) then
                                CTA_TimeSinceLastFilter = 0;
                                CTA_ApplyFiltersToGroupList();
                        end
                        
                        
                        if( CTA_PollBroadcast ) then
                                CTA_TimeSinceLastBroadcast = 0;
                                
                                --[[if( CTA_PlayerIsAFK ) then
                                        CTA_PollBroadcast = nil;
                                        CTA_Println( "You are AFK: CTA broadcasts paused " );
                                        
                                else]]
                                
                                if( CTA_PollBroadcast == 3 ) then --r7
                                        if( CTA_LFGCheckButton:GetChecked() and CTA_LGMPrefixLabel:GetText() and CTA_LFGDescriptionEditBox:GetText() ~= "" ) then
                                
                                                local tim, minute = GetGameTime();
                                                if( tim < 10 ) then tim = "0"..tim; end
                                                if( minute < 10 ) then tim = tim.."0"; end
                                                tim = tim..minute;      
                                                
                                                local lfgT = CTA_LFGDescriptionEditBox:GetText();
                                                
                                                --
                                                if string.find( lfgT, ":") then lfgT = string.gsub(lfgT, ":", "."); end;


                                                CTA_SendChatMessage( "/cta B<"..tim..":"..lfgT..":"..CTA_RELEASEVERSION..">", "CHANNEL", GetChannelName( CTA_CommunicationChannel ) );
                                        end
                                        CTA_PollBroadcast = nil;
                                elseif( CTA_PollBroadcast == 2 ) then
                                        CTA_SendChatMessage("/cta A<>", "CHANNEL", GetChannelName( CTA_CommunicationChannel ) );
                                        CTA_PollBroadcast = nil;
                                elseif( CTA_MyRaidIsOnline and CTA_MyRaid ) then
                                        CTA_BroadcastRaidInfo();
                                end
                        end                             
                end
                
                if( CTA_GraceTimer > 0  ) then
                        CTA_GraceTimer = CTA_GraceTimer - CTA_UpdateTicker;
                        CTA_IconMsg( floor(CTA_GraceTimer) );
                        if( CTA_GraceTimer <= 0 ) then
                                if( CTA_MyRaid and not CTA_PlayerCanHostGroup() ) then
                                        CTA_MyRaid = nil;
                                        CTA_MyRaidIsOnline = nil;
                                        CTA_HostingRaidGroup = nil;
                                        CTA_SearchFrame:Show();
                                        CTA_MyRaidFrame:Hide();
                                        CTA_StartRaidFrame:Hide();                      
                                else            
                                        CTA_MyRaidInstantUpdate();
                                end             
                        end
                end
                                
                CTA_RequestTimer = CTA_RequestTimer + CTA_UpdateTicker;
                if( CTA_RequestTimer > 5 ) then
                        if( CTA_OutstandingRequests > 0 ) then
                                CTA_LogMsg( CTA_OutstandingRequests.." invitation request(s) outstanding" );    
                                for name, data in CTA_InvitationRequests do
                                        if( data.status == 1 ) then
                                                SetWhoToUI(1);
                                                CTA_WhoName = name;
                                                SendWho("n-"..name);
                                                --SendWho(name);
                                                CTA_LogMsg( "Validating request from "..name ); 
                                                break;
                                        end
                                end
                        else
                                --r7 
                                if( not FriendsFrame:IsVisible() ) then -- R10: This stops CTA from sending who requests while the friends frame is open
                                        for i = 1, getn( CTA_CtaMessageList ) do
                                                if( not CTA_CtaMessageList[i].who ) then --CTA_CtaMessageList[i].who = { level = 0 };
                                                        SetWhoToUI(1);
                                                        local name = CTA_CtaMessageList[i].op or CTA_CtaMessageList[i].author;
                                                        CTA_WhoFlag = name;
                                                        SendWho("n-"..name);
                                                        --SendWho(name);
                                                        CTA_LogMsg( "Getting information on: "..name ); 
                                                        break;
                                                end
                                        end
                                else
                                        CTA_LogMsg( "CTA /who aborted: Social window open" );   
                                end
                        end
                        CTA_RequestTimer = 0;
                end
                
                CTA_ForwardTimer = CTA_ForwardTimer - 1;
                if( CTA_ForwardTimer == 0 ) then
                --[ [ R10: Prep to stop CTA LFX Forwarding in R11 
                        if( lfxChatMessageList[getn(lfxChatMessageList)] ) then
                                CTA_SendChatMessage( lfxChatMessageList[getn(lfxChatMessageList)].message, "CHANNEL", GetChannelName( CTA_CommunicationChannel ) );
                                local name = lfxChatMessageList[getn(lfxChatMessageList)].author;
                                table.remove( lfxChatMessageList, getn(lfxChatMessageList) );
                                CTA_LogMsg( "Forwarded msg from "..name..", lfx size is: "..getn(lfxChatMessageList) );
                        end
                --]]
                        CTA_ForwardTimer = 10;
                end
                                                                
                CTA_UpdateTicker = 0;
        end
end




--[[    CTA_OnEvent()
                ---------------------------------------------------------------
                Event handler.
                @arg The event to be handled
                ]]

function CTA_OnEvent( event )

        if(event == "VARIABLES_LOADED") then
                CTA_MinimapArcSlider:SetValue( CTA_SavedVariables.MinimapArcOffset );
                CTA_MinimapRadiusSlider:SetValue( CTA_SavedVariables.MinimapRadiusOffset );
                CTA_MinimapMsgArcSlider:SetValue( CTA_SavedVariables.MinimapMsgArcOffset );
                CTA_MinimapMsgRadiusSlider:SetValue( CTA_SavedVariables.MinimapMsgRadiusOffset );
                CTA_UpdateMinimapIcon();        
                CTA_AddGreyToBlack();
                CTA_ImportIgnoreListToGreyList();       
                if( not CTA_SavedVariables.runCount or CTA_SavedVariables.runCount == 0 ) then
                        CTA_SavedVariables.runCount = 0;
                        CTA_MainFrame:Show();
                        CTA_SearchFrame:Hide();
                        CTA_MyRaidFrame:Hide();
                        CTA_StartRaidFrame:Hide();
                        CTA_SettingsFrame:Show();
                        CTA_GreyListFrame:Hide();
                        CTA_LogFrame:Hide();
                end
                CTA_SavedVariables.runCount = CTA_SavedVariables.runCount + 1;
                CTA_UpdateGreyListItems(); -- R7 B4     
                CTA_UpdateResults(); -- R7 B4
                
                CTA_FrameTransparencySlider:SetValue( ( CTA_SavedVariables.MainFrameTransparency or 0.85 ) );
                CTA_MainFrame:SetAlpha( CTA_FrameTransparencySlider:GetValue() );
                
                if( not CTA_SavedVariables.lfgTrigger or strlen( CTA_SavedVariables.lfgTrigger ) < 3 ) then
                        CTA_SavedVariables.lfgTrigger = CTA_DEFAULT_LFG_TRIGGER;
                        CTA_SavedVariables.lfmTrigger = CTA_DEFAULT_LFM_TRIGGER;
                end
                
                if( not CTA_SavedVariables.version or CTA_SavedVariables.version < CTA_THIS_VERSION ) then
                        CTA_SavedVariables.lfgTrigger = CTA_DEFAULT_LFG_TRIGGER;
                        CTA_SavedVariables.lfmTrigger = CTA_DEFAULT_LFM_TRIGGER;
                        CTA_SavedVariables.version = CTA_THIS_VERSION;
                        CTA_Println( "CallToArms version updated. Resetting LFx triggers.");

                end
                
                CTA_SearchFrameLFGTriggerEditBox:SetText( CTA_SavedVariables.lfgTrigger or CTA_DEFAULT_LFG_TRIGGER );
                CTA_SearchFrameLFMTriggerEditBox:SetText( CTA_SavedVariables.lfmTrigger or CTA_DEFAULT_LFM_TRIGGER );
                

        end

        -- for R2 to see if we can tell when a player does not accept your invitation to join the group
        if ( event == "CHAT_MSG_SYSTEM" ) then  
                if ( string.find( arg1, "declines your group invitation" ) or string.find( arg1, "is already in a group" ) ) then
                        local name = string.gsub( arg1, "%s*([^%s]+).*", "%1" );
                        CTA_RemoveRequest( name );
                        CTA_LogMsg( name.." has declined the invitation - request removed" );   
                        CTA_MyRaidInstantUpdate();
                end
                if ( string.find( arg1, "You are now AFK" ) ) then
                        --CTA_Println( "AFK" );
                        CTA_PlayerIsAFK = 1;
                end
                if ( string.find( arg1, "You are no longer AFK" ) ) then
                        --CTA_Println( "NOT AFK" );
                        CTA_PlayerIsAFK = nil;
                end
        end     

        -- Listen for Invitation requests
        if ( event == "CHAT_MSG_WHISPER" ) then
                if( CTA_MyRaidIsOnline and string.lower( strsub(arg1, 1, 8) ) == CTA_INVITE_MAGIC_WORD ) then
                        if( not CTA_FindInList( arg2, CTA_BlackList ) ) then -- R2
                                if( CTA_ChannelSpam[arg2] == nil ) then
                                        CTA_ChannelSpam[arg2] = 0;
                                end
                                CTA_ChannelSpam[arg2] = CTA_ChannelSpam[arg2] + 1;
                                if( CTA_ChannelSpam[arg2] > 12 ) then --r7 4 -> 12
                                        CTA_RemoveRequest( arg2 );
                                        CTA_SendAutoMsg(arg2.." "..CTA_WAS_BLACKLISTED, arg2);  
                                        CTA_IconMsg( arg2.." "..CTA_WAS_BLACKLISTED, CTA_BLOCK );
                                        CTA_AddPlayer( arg2, CTA_BLACKLISTED_NOTE, CTA_DEFAULT_STATUS, CTA_DEFAULT_RATING, CTA_BlackList )
                                else
                                        CTA_ReceiveRaidInvitationRequest( arg1, arg2 ); 
                                end
                        end     
                end     

                if( CTA_MyRaidIsOnline and CTA_AcidDetails and string.lower( strsub(arg1, 1, 7) ) == "details" ) then
                        CTA_SendAutoMsg( CTA_AcidDetails, arg2 )                
                end     

                if( string.lower( strsub(arg1, 1, 4) ) == "cta?" ) then
                        CTA_SendAutoMsg( CTA_ABOUT_CTA_MESSAGE, arg2 )          
                end     
        end
        
        -- Listen for Group information
        
        
        
        
        
        --[[    ---------------------------------------------------------------         
                                           a   b  c d e  f g
                                       1234567890123
                                /cta A<1200255808060:~:~>
                                       ^   ^  ^ ^ ^  ^ ^
                                       4   3  2 2 2  ? ?
                       
                        a - time of transmission (HHMM 24HR format)
                        b - lfm classes code (0 = none, .. , 255 = any class)
                        c - current group size and pv? type 
                        d - maximum group size and password protection
                        e - minimum level to join group
                        f - group description
                        g - options (reserved for future releases)
                       
                                           a    b c 
                                       1234
                                /cta B<1200:~:~>
                                       ^    ^ ^
                                       4    ? ?
                       
                        a - time of transmission (HHMM 24HR format)
                        b - message
                        c - options (reserved for future releases)

                                           a    b c d 
                                       1234
                                /cta C<1200:~:~:~>
                                /cta D<1200:~:~:~>
                                       ^    ^ ^ ^
                                       4    ? ? ?
                       
                        a - time of transmission (HHMM 24HR format)
                        b - op name
                        c - op message
                        d - options (reserved for future releases)
        ---------------------------------------------------------------
        ]]

        
        if ( event == "CHAT_MSG_CHANNEL" ) then
        
                                        
                -- Use channel event to delay joining of CTAChannel
                if( not CTA_JoinedChannel ) then
                        CTA_Util.joinChannel( CTA_CommunicationChannel );
                        CTA_JoinedChannel = 1;
                end                     


                if( arg9 == CTA_CommunicationChannel ) then                     
                        
                        --R7 > Trusted CTA Channel Messages
                        
                        if( arg1 == "/cta A<>" ) then
                                for i = 1, getn( CTA_CtaMessageList ) do
                                        local name = CTA_CtaMessageList[i].author or "?";
                                        if( name == arg2 and not CTA_CtaMessageList[i].op ) then
                                                table.remove( CTA_CtaMessageList , i );
                                                break;
                                        end
                                end
                                CTA_PollApplyFilters = 1;
                                return;
                        end
                
                        for code, com, opt in string.gfind( arg1, "/cta A<(%d+):(.+):(.+)>" ) do        
                                local tim = string.sub( code,  1,  4 );
                                local cla = tonumber( string.sub( code,  5,  7 ) );
                                local siz = tonumber( string.sub( code,  8,  9 ) );
                                local max = tonumber( string.sub( code, 10, 11 ) );
                                local min = tonumber( string.sub( code, 12, 13 ) );
                                local pro = 0;
                                local typ = CTA_RAID_TYPE_PVE;
                                
                                if( siz > 40 ) then
                                        typ = CTA_RAID_TYPE_PVP;
                                        siz = siz - 40;
                                end
                                if( max > 40 ) then
                                        pro = 1;
                                        max = max - 40;
                                end

                                for i = 1, getn(lfxChatMessageList) do
                                        local name = lfxChatMessageList[i].author or "?";
                                        if( name == arg2 ) then
                                                table.remove( lfxChatMessageList, i );
                                                break;
                                        end
                                end
                                
                                local whoData = nil;

                                for i = 1, getn( CTA_CtaMessageList ) do
                                        local name = CTA_CtaMessageList[i].author or "?";
                                        if( name == arg2 and not CTA_CtaMessageList[i].op ) then
                                                whoData = CTA_CtaMessageList[i].who;
                                                table.remove( CTA_CtaMessageList , i );
                                                break;
                                        end
                                end
                                
                                -- R10: Show new messages in minimap icon text
                                if( CTA_ShowOnMinimapCheckButton:GetChecked() ) then 
                                        CTA_IconMsg( arg2..": "..com ); 
                                end

                                
                                local entry = {};
                                entry.ctaType = "A";
                                entry.author = arg2;
                                entry.message = com;
                                entry.time = tim;
                                entry.options = opt;
                                entry.who = whoData;
                                
                                entry.pvtype = tonumber(typ);
                                entry.size = tonumber(siz);
                                entry.maxSize = tonumber(max);
                                entry.minLevel = tonumber(min);
                                entry.classes = tonumber(cla);
                                entry.passwordProtected = tonumber(pro);

                                table.insert( CTA_CtaMessageList, 1, entry );   
                                CTA_PollApplyFilters = 1;
                                return;
                        end
                                        
                        for code, com, opt in string.gfind( arg1, "/cta B<(%d+):(.+):(.+)>" ) do        

                                for i = 1, getn(lfxChatMessageList) do
                                        local name = lfxChatMessageList[i].author or "?";
                                        if( name == arg2 ) then
                                                table.remove( lfxChatMessageList, i );
                                                break;
                                        end
                                end

                                local whoData = nil;

                                for i = 1, getn( CTA_CtaMessageList ) do
                                        local name = CTA_CtaMessageList[i].author or "?";
                                        if( name == arg2 and not CTA_CtaMessageList[i].op ) then
                                                whoData = CTA_CtaMessageList[i].who;
                                                table.remove( CTA_CtaMessageList , i );
                                                break;
                                        end
                                end
                                
                                -- R10: Show new messages in minimap icon text
                                if( CTA_ShowOnMinimapCheckButton:GetChecked() ) then 
                                        CTA_IconMsg( arg2..": "..com ); 
                                end

                                local entry = {};
                                entry.ctaType = "B";
                                entry.author = arg2;
                                entry.message = com;
                                entry.time = code;
                                entry.options = opt;
                                entry.who = whoData;
                                
                                table.insert( CTA_CtaMessageList, 1, entry );                                                           
                                CTA_PollApplyFilters = 1;
                                return;
                        end
                        
                        for code, opname, com, opt in string.gfind( arg1, "/cta C<(%d+):(.+):(.+):(.+)>" ) do   
                        --[ [ Removed for beta 4 tests
                                if( CTA_Util.search( com, CTA_SavedVariables.lfmTrigger ) > 0 ) then
                                
                        --]]

                                        for i = 1, getn(lfxChatMessageList) do
                                                local name = lfxChatMessageList[i].author or "?";
                                                if( name == opname ) then
                                                        table.remove( lfxChatMessageList, i );
                                                        CTA_LogMsg( "Rx cta forward msg re: "..opname.." from "..arg2.." - Removed monitor entry" );
                                                        break;
                                                end
                                        end
        
                                        local whoData = nil;
        
                                        for i = 1, getn( CTA_CtaMessageList ) do
                                                local name = CTA_CtaMessageList[i].op or "?";
                                                if( name == opname ) then
                                                        whoData = CTA_CtaMessageList[i].who;
                                                        table.remove( CTA_CtaMessageList , i );
                                                        break;
                                                end
                                        end

                                        -- R10: Show new messages in minimap icon text
                                        if( CTA_ShowOnMinimapCheckButton:GetChecked() ) then 
                                                CTA_IconMsg( opname..": "..com ); 
                                        end
                                        
                                        local entry = {};
                                        entry.ctaType = "C";
                                        entry.author = arg2;
                                        entry.message = com;
                                        entry.time = code;
                                        entry.options = opt;
                                        entry.who = whoData;
                                        
                                        entry.op = opname;
                                        
                                        table.insert( CTA_CtaMessageList, 1, entry );                                                           
                                        CTA_PollApplyFilters = 1;
                        --[ [ Removed for beta 4 tests
                                end
                        --]]
                                return;
                        end
                        
                        for code, opname, com, opt in string.gfind( arg1, "/cta D<(%d+):(.+):(.+):(.+)>" ) do   

                        --[ [ Removed for beta 4 tests
                                if( CTA_Util.search( com, CTA_SavedVariables.lfgTrigger ) > 0 ) then
                        --]]
                                
                                        for i = 1, getn(lfxChatMessageList) do
                                                local name = lfxChatMessageList[i].author or "?";
                                                if( name == opname ) then
                                                        table.remove( lfxChatMessageList, i );
                                                        CTA_LogMsg( "Rx cta forward msg re: "..opname.." from "..arg2.." - Removed monitor entry" );
                                                        break;
                                                end
                                        end
        
                                        local whoData = nil;
        
                                        for i = 1, getn( CTA_CtaMessageList ) do
                                                local name = CTA_CtaMessageList[i].op or "?";
                                                if( name == opname ) then
                                                        whoData = CTA_CtaMessageList[i].who;
                                                        table.remove( CTA_CtaMessageList , i );
                                                        break;
                                                end
                                        end

                                        -- R10: Show new messages in minimap icon text
                                        if( CTA_ShowOnMinimapCheckButton:GetChecked() ) then 
                                                CTA_IconMsg( opname..": "..com ); 
                                        end
                                        
                                        local entry = {};
                                        entry.ctaType = "D";
                                        entry.author = arg2;
                                        entry.message = com;
                                        entry.time = code;
                                        entry.options = opt;
                                        entry.who = whoData;
                                        
                                        entry.op = opname;
                                        
                                        table.insert( CTA_CtaMessageList, 1, entry );                                                           
                                        CTA_PollApplyFilters = 1;
                        --[ [ Removed for beta 4 tests
                                end
                        --]]
                                return;
                        end
                
                --[ [ R10: Prep to remove to stop forwarding messages in R11; global LFG channel introduced by Blizzard after R9
                        
                elseif( CTA_MonitorChatCheckButton:GetChecked() ) then
                        if( not CTA_SavedVariables.lfmTrigger or strlen( CTA_SavedVariables.lfmTrigger ) < 3 ) then return; end
                        
                        -- R7
                        local channel = arg8 or "?";
                        local author = arg2 or " ";
                        local ok = 0;
                        for word in string.gfind(author, "%w+") do
                                ok = ok + 1;
                        end
                        if( ok > 1 ) then return; end
                        
                        local msg = arg1 or "?";
                        local type = "C"
                        local score = CTA_Util.search( msg, CTA_SavedVariables.lfmTrigger );
                        if( score == 0 ) then
                                score = CTA_Util.search( msg, CTA_SavedVariables.lfgTrigger );
                                type = "D"
                        end
                        
                        if( score == 0 ) then
                                return;
                        end
                        
                        -- is a spam by another cta user
                        for i = 1, getn( CTA_CtaMessageList ) do
                                local name = CTA_CtaMessageList[i].author or "?";
                                if( name == author and not CTA_CtaMessageList[i].op ) then
                                        return;
                                end
                        end
                        
                        local tim, minute = GetGameTime();
                        if( tim < 10 ) then tim = "0"..tim; end
                        if( minute < 10 ) then tim = tim.."0"; end
                        tim = tim..minute;      
                        for i = 1, getn(lfxChatMessageList) do
                                local name = lfxChatMessageList[i].author or "?";
                                if( name == author ) then
                                        table.remove( lfxChatMessageList, i );
                                        break;
                                end
                        end
                        
                        --
                        if string.find( msg, ":") then msg = string.gsub(msg, ":", "."); end;
                        
                        local entry = {};
                        entry.author = author;
                        entry.message = "/cta "..type.."<"..tim..":"..author..":"..msg..":x>";
                        table.insert( lfxChatMessageList, 1, entry );   
                        
                        CTA_Util.logPrintln( "Picked up lfx msg from "..author..", lfx size is: "..getn(lfxChatMessageList) );
                        
                        -- /R7
                        --]]
                end     
        end
                        
        -- Listen for Who information
        if ( event == "WHO_LIST_UPDATE" ) then
                if( CTA_WhoName and CTA_MyRaid ) then
                        local name, level, class, group = CTA_GetWhoInfo();
                        --CTA_Println( "group: "..group );
                        if( name ) then
                                if( CTA_FindInList( name, CTA_BlackList ) ) then
                                        CTA_LogMsg( name.." has been blacklisted - Request denied and removed" );
                                        CTA_RemoveRequest(name);
                                end
                                
                                if( group == "yes" ) then
                                        CTA_LogMsg( name.." is already in a group - Request denied and removed" );
                                        CTA_RemoveRequest(name);
                                end
                        
                                if( CTA_InvitationRequests[name] and CTA_InvitationRequests[name].status == 1 and CTA_MyRaid ) then     
                                        CTA_OutstandingRequests = CTA_OutstandingRequests - 1;
                                        if( level >= CTA_MyRaid.minLevel and string.find( CTA_GetClassString(CTA_MyRaid.classes),class) ) then
                                                InviteByName( name );
                                                CTA_LogMsg( name.."\'s request processed: Valid player - Invitation sent" );    
                                                
                                                CTA_InvitationRequests[name].status = 2;
                                                CTA_InvitationRequests[name].class = class;
                                                CTA_InvitationRequests[name].level = level;
                                                                        
                                                CTA_IconMsg( CTA_INVITATION_SENT_TO.." "..name, CTA_GROUP_UPDATE );
                                                CTA_SendAutoMsg( CTA_INVITATION_SENT_MESSAGE, name );
                                                CTA_MyRaidInstantUpdate();
                                        else
                                                CTA_InvitationRequests[name] = nil;
                                                CTA_LogMsg( name.."\'s request processed: Invalid player - request removed" );  
                                                
                                                CTA_SendAutoMsg( CTA_WRONG_LEVEL_OR_CLASS, name );      
                                        end
                                end
                        else
                                CTA_LogMsg( "Player "..CTA_WhoName.." could not be found. Removing from requests list." );      
                                CTA_RemoveRequest(CTA_WhoName);
                        end
                        CTA_WhoName = nil;
                elseif( CTA_WhoFlag ) then
                
                        local numWhos, totalCount = GetNumWhoResults();
                        local name, guild, level, race, class, zone, group;
                        for i=1, totalCount do
                                name, guild, level, race, class, zone, group = GetWhoInfo(i);
                                if( not name or name == CTA_WhoFlag ) then
                                        --CTA_Println( "Name: "..name..", Group: "..( group or "Null" ) );
                                        break;
                                end
                        end
                        if( name ) then
                                for i = 1, getn( CTA_CtaMessageList ) do
                                        local cname = CTA_CtaMessageList[i].op or CTA_CtaMessageList[i].author or "?";
                                        if( name == cname ) then
                                                if( strlen( guild ) > 0 ) then
                                                        guild = "<"..guild..">";                                                
                                                end
                                        
                                                local entry = {
                                                        level = level;
                                                        class = class;
                                                        zone  = zone;
                                                        guild = guild;  
                                                        grouped = group;                                        
                                                };
                                                CTA_CtaMessageList[i].who = entry;
                                                break;
                                        end
                                end
                        else
                                for i = 1, getn( CTA_CtaMessageList ) do
                                        local cname = CTA_CtaMessageList[i].op or CTA_CtaMessageList[i].author or "?";
                                        if( CTA_WhoFlag == cname ) then
                                                local entry = {};
                                                entry.level = 0;
                                                --[[
                                                entry.class = ;
                                                entry.zone = ;
                                                entry.guild = ; ]]                                      
                                                CTA_CtaMessageList[i].who = entry;
                                                break;
                                        end
                                end
                        end
                        CTA_WhoFlag = nil;
                end
                
                SetWhoToUI(0);
        end  
                        
        -- Group update
        if ( event == "RAID_ROSTER_UPDATE" or event == "PARTY_LEADER_CHANGED" or event == "PARTY_MEMBERS_CHANGED" ) then
                CTA_GraceTimer = 2;
        end
                
end

function CTA_GetWhoInfo()
        local numWhos, totalCount = GetNumWhoResults();
        local name, guild, level, race, class, zone, group;
        for i=1, totalCount do
                name, guild, level, race, class, zone, group = GetWhoInfo(i);
                if( not name or name == CTA_WhoName ) then
                        break;
                end
        end
        return name, level, class, group;
end



















--[[    ---------------------------------------------------------------
                Communication - System
                ---------------------------------------------------------------
                ]]




--[[    CTA_JoinChannel()
                ---------------------------------------------------------------
                Attempts to join the <var>CTA_CommunicationChannel</var> 
                channel.
                ]]

function CTA_JoinChannel()
        CTA_Util.joinChannel( CTA_CommunicationChannel );
end




--[[    CTA_ConnectedToChannel() 
                ---------------------------------------------------------------
                Determines whether the client has joined the specified channel.
                @arg The name of the channel
                @return nil, 1 if already connected to the channel
                ]]

function CTA_ConnectedToChannel( channel ) 
        local DefaultChannels = { GetChatWindowChannels(DEFAULT_CHAT_FRAME:GetID()) };
        local connected = nil;
        if( DefaultChannels ) then 
                for item = 1, getn(DefaultChannels) do
                        CTA_LogMsg( DefaultChannels[item] );
                        if( DefaultChannels[item] == channel ) then
                                connected = 1;
                                break;
                        end
                end
        end
        return connected;
end




--[[    CTA_SendAutoMsg()
                ---------------------------------------------------------------
                Sends a chat message, by whisper, to the specified player.
                @arg The message to be sent
                @arg The recipient of the message
                ]]

function CTA_SendAutoMsg( message, player )
        CTA_SendChatMessage( "[CTA] "..message, "WHISPER", player );
end




--[[    CTA_SendChatMessage()
                ---------------------------------------------------------------
                Sends a chat message to the specified player or channel.
                @arg The message to be sent
                @arg The type of transmission eg. whisper, channel etc
                @arg The recipient player/channel of the message 
                ]]

function CTA_SendChatMessage( message, messageType, channel ) 
        local language = CTA_COMMON;
        if( UnitFactionGroup(CTA_PLAYER) ~= CTA_ALLIANCE ) then
                language = CTA_ORCISH;
        end
        SendChatMessage( string.gsub( message, "|c(%w+)|H(%w+):(.+)|h(.+)|h|r", "%4" ), messageType, language, channel );
end


















--[[    ---------------------------------------------------------------
                Invitations
                ---------------------------------------------------------------
                ]]




--[[    CTA_SendPasswordRaidInvitationRequest()
                ---------------------------------------------------------------
                Sends a request with a pasword for an invitation
                ]]

function CTA_SendPasswordRaidInvitationRequest()
        local raid = CTA_RaidList[ CTA_SelectedResultListItem ];
        local password = CTA_SafeSet( CTA_JoinRaidWindowEditBox:GetText(), "" );
        if( password ~= "" ) then
                CTA_SendChatMessage( CTA_INVITE_MAGIC_WORD.." "..password, "WHISPER", raid.leader );    
                CTA_JoinRaidWindow:Hide();
        end
end




--[[    CTA_SendRaidInvitationRequest()
                ---------------------------------------------------------------
                Sends a request for an invitation
                ]]

function CTA_SendRaidInvitationRequest()
        local raid = CTA_RaidList[ CTA_SelectedResultListItem ];
        CTA_JoinRaidWindow:Hide();
        CTA_RequestInviteButton:Disable();
        
        if( raid.passwordProtected == 1 ) then
                CTA_JoinRaidWindow:Show();
        else
                CTA_SendChatMessage( CTA_INVITE_MAGIC_WORD, "WHISPER", raid.author );           
        end
end




--[[    CTA_ReceiveRaidInvitationRequest()
                ---------------------------------------------------------------
                Handles incoming invitation requests.
                @arg The invitation request with optional password
                @arg The name pf the player requesting the invitation
                ]]

function CTA_ReceiveRaidInvitationRequest( msg, author )
        if( CTA_InvitationRequests[author] ) then return; end -- cheap short-circuit hack
        CTA_LogMsg( "Received invitation request from "..author );      
        if( CTA_MyRaid.size + getn(CTA_InvitationRequests) < CTA_MyRaid.maxSize ) then
                if( CTA_MyRaid.passwordProtected==1 ) then
                        local password = string.gsub( string.sub( msg, 9 ), "%s*([^%s]+).*", "%1" );
                        
                        if( password and password==CTA_MyRaidPassword ) then
                                CTA_AddRequest( author );
                        else
                                CTA_SendAutoMsg( CTA_INCORRECT_PASSWORD_MESSAGE, author);                       
                        end
                else
                        CTA_AddRequest( author );
                end
        else
                CTA_SendAutoMsg( CTA_NO_SPACE_MESSAGE, author); 
        end
end




--[[    CTA_AddRequest()
                ---------------------------------------------------------------
                Adds a player's request for an invitation to join the group.
                @arg The name of the player requesting an invitaion
                ]]

function CTA_AddRequest( name )
        CTA_InvitationRequests[name] = {};
        CTA_InvitationRequests[name].status = 1;
        CTA_OutstandingRequests = CTA_OutstandingRequests + 1;
end




--[[    CTA_RemoveRequest()
                ---------------------------------------------------------------
                Removes a player's request for an invitation to join the group.
                @arg The name of the player requesting an invitaion
                ]]

function CTA_RemoveRequest( name )
        if( CTA_InvitationRequests[name] ) then
                if( CTA_InvitationRequests[name].status == 1 ) then
                        CTA_OutstandingRequests = CTA_OutstandingRequests - 1;  
                end
                CTA_InvitationRequests[name] = nil;
        end
end













--[[    ---------------------------------------------------------------
                Inter-AddOn Group Information Communication
                ---------------------------------------------------------------
                ]]




--[[    CTA_BroadcastRaidInfo()
                ---------------------------------------------------------------
                Sends this group info to the CTA Channel.
                ]]

function CTA_BroadcastRaidInfo()
        CTA_PollBroadcast = nil;        

        if( CTA_MyRaidIsOnline == nil ) then return; end -- short circuit hack for push changeover in R5

        local myName = UnitName( CTA_PLAYER );
        local myRaid = CTA_MyRaid;
        --local com = CTA_GetGroupType()..": [CTA R3 Pre-release Test Group] "..myRaid.comment;
        local com = myRaid.comment.." ("..CTA_GetGroupType()..")";
        local typ = myRaid.pvtype;
        local siz = myRaid.size;
        local max = myRaid.maxSize;
        local min = myRaid.minLevel;
        local cla = myRaid.classes;     
        local pro = myRaid.passwordProtected;
        local opt = myRaid.options;             
        --local tim = myRaid.creationTime; ListChannelByName
        
        local hour, minute = GetGameTime();
        local tim = hour;
        if( hour < 10 ) then tim = "0"..tim; end
        if( minute < 10 ) then tim = tim.."0"; end
        tim = tim..minute;      
        
        if( typ == CTA_RAID_TYPE_PVP ) then
                siz = siz + 40;
        end
        
        if( pro == 1 ) then
                max = max + 40;
        end
        
        while( string.len( cla ) < 3 ) do
                cla = "0"..cla;
        end

        while( string.len( siz ) < 2 ) do
                siz = "0"..siz;
        end
        while( string.len( max ) < 2 ) do
                max = "0"..max;
        end
        while( string.len( min ) < 2 ) do
                min = "0"..min;
        end
        
        local code = ""..tim..cla..siz..max..min;
        --
        if string.find( com, ":") then com = string.gsub(com, ":", "."); end;

        CTA_SendChatMessage("/cta A<"..code..":"..com..":"..opt..">", "CHANNEL", GetChannelName( CTA_CommunicationChannel ) );
        
        --CTA_IconMsg( "Broadcast Sent" );
end





























































--[[    ---------------------------------------------------------------
                Functions Related To The Search Frame And The Group List
                --------------------------------------------------------------- 
                ]]




--[[    CTA_ApplyFiltersToGroupList()
                ---------------------------------------------------------------
                Applies filter settings to the group list and 
                updates the score for each one. This score will be used by the 
                <func>CTA_UpdateList()</func> function to refresh the results
                list with those groups with a score of at least 1.
                Called by CTA_SearchButton, will be renamed to ApplyFilters() 
                or something to that effect.
                ]]
                
                
function CTA_ApplyFiltersToGroupList()

        
        local showClasses = CTA_SafeSet( CTA_SearchFrameShowClassCheckButton:GetChecked(), 0 );
        if( showClasses == 0 ) then 
                showClasses = CTA_MyClassCode();
        else
                showClasses = 0;
        end
        local showPVP = CTA_SafeSet( CTA_SearchFrameShowPVPCheckButton:GetChecked(), 0 );
        local showPVE = CTA_SafeSet( CTA_SearchFrameShowPVECheckButton:GetChecked(), 0 );
        local keywords = CTA_SafeSet( CTA_SearchFrameDescriptionEditBox:GetText(), "*" );
        local showEmpty = CTA_SafeSet( CTA_SearchFrameShowEmptyCheckButton:GetChecked(), 0 );
        local showFull = CTA_SafeSet( CTA_SearchFrameShowFullCheckButton:GetChecked(), 0 );
        local showProtected = CTA_SafeSet( CTA_SearchFrameShowPasswordCheckButton:GetChecked(), 0 );
        local showMinLevel = CTA_SafeSet( CTA_SearchFrameShowLevelCheckButton:GetChecked(), 0 );
        if( showMinLevel == 0 ) then 
                showMinLevel = UnitLevel(CTA_PLAYER);
        else
                showMinLevel = 60; 
        end
        
        CTA_RequestInviteButton:Disable();
        CTA_ResultsListOffset = 0;
        CTA_SelectedResultListItem = 0; 
        
        local oldListSize = 0;
        if( CTA_RaidList ) then
                oldListSize = getn( CTA_RaidList );
        end
                
        
        CTA_RaidList = nil;
        CTA_RaidList = {};
        
        local chr, cmn = GetGameTime();
        cmn = cmn + 1;
        local pruneCount = 0;
        
        local playerClass, playerMinLevel, playerMaxLevel;

        for i=1, getn( CTA_CtaMessageList ) do
                local data = CTA_CtaMessageList[i];
                if( data ) then
                        
                        local ok = 1;
                        local rhr = tonumber( string.sub( data.time,  1,  2 ) ) or 0; -- added: beta 4 hack re: beta 3 reported error
                        local rmn = tonumber( string.sub( data.time,  3,  4 ) ) or 0; -- added: beta 4 hack re: beta 3 reported error
                        local dmn = cmn - rmn;
                        if( dmn < 0 ) then
                                dmn = dmn + 60;
                        end


                        playerClass = CTA_PlayerClassDropDownText:GetText() or CTA_ANY_CLASS;
                        if( strlen(CTA_PlayerMinLevelEditBox:GetText()) == 0 ) then
                                playerMinLevel = 1;
                        else
                                playerMinLevel = tonumber( CTA_PlayerMinLevelEditBox:GetText() );
                        end
                        if( strlen(CTA_PlayerMaxLevelEditBox:GetText()) == 0 ) then
                                playerMaxLevel = 60;
                        else
                                playerMaxLevel = tonumber( CTA_PlayerMaxLevelEditBox:GetText() );
                        end
        
                        
                        if( data.ctaType == "A" ) then
        
                                if( dmn > 2 ) then
                                        table.remove( CTA_CtaMessageList , i );
                                        pruneCount = pruneCount + 1;
                                        ok = nil;
                                        i = i - 1;
                                end
                                
                                if( ok and showClasses > 0 and CTA_CheckClasses( data.classes, showClasses ) == 0 ) then ok = nil; end
                                if( ok and showEmpty == 0 and data.size <= 1 ) then ok = nil; end
                                if( ok and showFull == 0 and data.size == data.maxSize ) then ok = nil; end
                                if( ok and showPVP == 0 and data.pvtype == CTA_RAID_TYPE_PVP ) then ok = nil; end
                                if( ok and showPVE == 0 and data.pvtype == CTA_RAID_TYPE_PVE ) then ok = nil; end
                                if( ok and showProtected == 0 and CTA_MyRaidPassword ) then ok = nil; end
                                if( ok and showMinLevel < data.minLevel ) then ok = nil; end
                                if ( CTA_SearchDropDownText:GetText() == CTA_SHOW_PLAYERS_ONLY ) then ok = nil; end
                                
                        elseif( data.ctaType == "B" ) then
        
                                if( dmn > 2 ) then
                                        table.remove( CTA_CtaMessageList , i );
                                        pruneCount = pruneCount + 1;
                                        ok = nil;
                                        i = i - 1;
                                end
                                if ( CTA_SearchDropDownText:GetText() == CTA_SHOW_GROUPS_ONLY ) then ok = nil; end
                                
                                if ( data.who and data.who.level ~= 0 ) then
                                        if( playerClass ~= CTA_ANY_CLASS and data.who.class ~= playerClass ) then ok = nil; end
                                        if( data.who.level < playerMinLevel or data.who.level > playerMaxLevel ) then ok = nil; end
                                end
                                
                        elseif( data.ctaType == "C" ) then
                                if( not CTA_ShowLocalLFXMessagesCheckButton:GetChecked() ) then
                                        ok = nil;
                                end
        
                                if( dmn > 15 ) then
                                        table.remove( CTA_CtaMessageList , i );
                                        pruneCount = pruneCount + 1;
                                        ok = nil;
                                        i = i - 1;
                                end
                                if ( CTA_SearchDropDownText:GetText() == CTA_SHOW_PLAYERS_ONLY ) then ok = nil; end
                                
                        elseif( data.ctaType == "D" ) then
                                if( not CTA_ShowLocalLFXMessagesCheckButton:GetChecked() ) then
                                        ok = nil;
                                end
        
                                if( dmn > 15 ) then
                                        table.remove( CTA_CtaMessageList , i );
                                        pruneCount = pruneCount + 1;
                                        ok = nil;
                                        i = i - 1;
                                end
                                if ( CTA_SearchDropDownText:GetText() == CTA_SHOW_GROUPS_ONLY ) then ok = nil; end
                                
                                if ( data.who and data.who.level ~= 0 ) then
                                        if( playerClass ~= CTA_ANY_CLASS and data.who.class ~= playerClass ) then ok = nil; end
                                        if( data.who.level < playerMinLevel or data.who.level > playerMaxLevel ) then ok = nil; end
                                end
                        
                        end
                        
                        if( ok ) then
                                local score = 1;
                                if( keywords and keywords~="*" ) then
                                        score = SachaSearch( data.author.." "..data.message, keywords );
                                end     
                                if( score > 0 ) then 
                                        data.elapsed = dmn;
                                        table.insert( CTA_RaidList, data );
                                end
                        end

                end
        end     
        
        if( pruneCount > 0 ) then
                CTA_LogMsg( "Removed "..pruneCount.." old result items." );
        end
        
        if ( oldListSize < getn( CTA_RaidList ) ) then
                --CTA_IconMsg( CTA_NEW_LFX );
                --PlaySound("TellMessage");
        end
                
        CTA_PollApplyFilters = nil;
        CTA_UpdateResults();
end




--[[    CTA_UpdateResults()                                                             UPDATE FUNCTION
                ---------------------------------------------------------------
                Updates the groups results list to show only those 
                groups with a score of at least 1. 
                Also updates the selected group as necessary.
                ]]
                --[[

                                local entry = {};
                                entry.ctaType = "A";
                                entry.author = arg2;
                                entry.message = com;
                                entry.time = tonumber(tim);
                                entry.options = opt;
                                
                                entry.pvtype = tonumber(typ);
                                entry.size = tonumber(siz);
                                entry.maxSize = tonumber(max);
                                entry.minLevel = tonumber(min);
                                entry.classes = tonumber(cla);
                                entry.passwordProtected = tonumber(pro);

                                -
                                
                                local entry = {};
                                entry.ctaType = "B";
                                entry.author = arg2;
                                entry.message = com;
                                entry.time = tonumber(code);
                                entry.options = opt;
                                
                                -
                                
                                local entry = {};
                                entry.ctaType = "C";
                                entry.author = arg2;
                                entry.message = com;
                                entry.time = tonumber(code);
                                entry.options = opt;
                                
                                entry.op = opname;
                                
                                -

                                local entry = {};
                                entry.ctaType = "D";
                                entry.author = arg2;
                                entry.message = com;
                                entry.time = tonumber(code);
                                entry.options = opt;
                                
                                entry.op = opname;

                ]]

function CTA_UpdateResults()
        local index = 1;
        local groupListLength = getn( CTA_RaidList );
        
        
                
        if( groupListLength ~= 0 ) then
                CTA_MinimapIconTextLabel:SetText( groupListLength );
                CTA_MinimapIconTextLabel:Show();
        else
                CTA_MinimapIconTextLabel:Hide();
        end
        
        if( groupListLength ~= 1 ) then 
                CTA_ResultsLabel:SetText( CTA_RESULTS_FOUND.." "..groupListLength.." / "..CTA_getn( CTA_CtaMessageList ) );
        else
                CTA_ResultsLabel:SetText( CTA_RESULTS_FOUND.." "..groupListLength );
        end


        CTA_PageLabel:Show();

        local cpage = floor( CTA_ResultsListOffset / CTA_MAX_RESULTS_ITEMS );
        local tpage = floor( groupListLength / CTA_MAX_RESULTS_ITEMS );
        if( cpage == 0 or cpage <= CTA_ResultsListOffset / CTA_MAX_RESULTS_ITEMS ) then cpage = cpage + 1; end
        if( tpage == 0 or tpage < groupListLength / CTA_MAX_RESULTS_ITEMS ) then tpage = tpage + 1; end
        CTA_PageLabel:SetText( CTA_PAGE.." "..cpage.." / "..tpage );

        
        while( index < CTA_MAX_RESULTS_ITEMS + 1 ) do
                local c = "CTA_NewItem"..index;
                if( getglobal( c ) ) then
                        if( index+CTA_ResultsListOffset <= groupListLength ) then 
                                local entry = CTA_RaidList[index+CTA_ResultsListOffset];
                                
                                --[[ The background colour
                                if( entry.ctaType== "A" or entry.ctaType== "B" ) then
                                        getglobal( c.."TexturePurple"):Show();
                                        getglobal( c.."TextureBlue"):Hide();
                                else
                                        getglobal( c.."TexturePurple"):Hide();
                                        getglobal( c.."TextureBlue"):Show();
                                end 
                                --]]
                                
                                -- The text colour
                                if( entry.ctaType== "A" or entry.ctaType== "C" ) then
                                        getglobal( c.."NameLabel"):SetTextColor( 1, 0.85, 0, 1 );
                                        getglobal( c.."TextureGold"):Show();
                                        getglobal( c.."TextureSilver"):Hide();
                                else
                                        getglobal( c.."NameLabel"):SetTextColor( 0.95, 0.95, 1, 1 );
                                        getglobal( c.."TextureGold"):Hide();
                                        getglobal( c.."TextureSilver"):Show();
                                end 
                                
                                -- get elapsed time
                                local timeText = "";
                                if( entry.elapsed ) then
                                        timeText = entry.elapsed.." min";
                                        if( entry.elapsed > 1 ) then timeText = timeText.."s"; end
                                else
                                        timeText = entry.time;
                                end
                                
                                local mainText = "";
                                local moreText = "";
                                local rightText = timeText.." ago";
                                
                                if( entry.ctaType== "A" ) then
                                
                                        local typeText = CTA_PVP;
                                        local passwordText = CTA_NO;
                                        if( entry.pvtype == CTA_RAID_TYPE_PVE ) then typeText = CTA_PVE; end
                                        if( entry.passwordProtected == 1 ) then passwordText = CTA_YES; end
                                        local myClass = UnitClass( CTA_PLAYER );
                                        local comment = entry.message;
                                        if( entry.minLevel > UnitLevel(CTA_PLAYER) or not string.find(CTA_GetClassString(entry.classes),myClass)  ) then
                                                comment = "|cffff0000"..comment.."|r";
                                        elseif( entry.passwordProtected == 1 ) then
                                                comment = "|cffffff00"..comment.."|r";
                                        else
                                                comment = "|cff00ff00"..comment.."|r";
                                        end
                                
                                        mainText = entry.author..": "..comment;
                                        moreText = "Type: "..typeText..", Size: "..entry.size.."/"..entry.maxSize..", Minimum level: "..entry.minLevel..", Password: "..passwordText;
                                        rightText = "CTA Group. Last updated ".. rightText;
                                elseif( entry.ctaType== "B" ) then

                                        mainText = entry.author..": "..entry.message;
                                        if( entry.who and entry.who.level ~= 0 ) then
                                                moreText = "Level "..entry.who.level.." "..entry.who.class..", "..entry.who.guild.." "..entry.who.zone;
                                                --[[
                                                if( entry.grouped == "yes" ) then
                                                        moreText = moreText.." - In a group at tiem of message ";
                                                else
                                                        moreText = moreText.." (not in a group)";
                                                end
                                                ]]
                                        end
                                        rightText = "CTA Player. Last updated ".. rightText;
                                                
                                elseif( entry.ctaType== "C" ) then

                                        mainText = entry.op..": "..entry.message;
                                        if( entry.who and entry.who.level ~= 0 ) then
                                                moreText = "Level "..entry.who.level.." "..entry.who.class..", "..entry.who.guild.." "..entry.who.zone;
                                        end
                                        rightText = "forwarded by "..entry.author.." "..rightText;
                                        
                                elseif( entry.ctaType== "D" ) then

                                        mainText = entry.op..": "..entry.message;
                                        if( entry.who and entry.who.level ~= 0 ) then
                                                moreText = "Level "..entry.who.level.." "..entry.who.class..", "..entry.who.guild.." "..entry.who.zone;
                                        end
                                        rightText = "forwarded by "..entry.author.." "..rightText;

                                end
                                
                                
                                
                                -- Set the texts
                                getglobal( c.."NameLabel"):SetText( mainText );
                                getglobal( c.."MoreLabel"):SetText( moreText );
                                getglobal( c.."MoreRightLabel"):SetText( rightText );
                                
                                if( CTA_SelectedResultListItem == index + CTA_ResultsListOffset ) then
                                        getglobal( c.."TextureSelected"):Show();
                                else
                                        getglobal( c.."TextureSelected"):Hide();
                                end
                                                                
                                getglobal( c ):Show();  
                        else    
                                getglobal( c ):Hide();
                        end
                end
                index = index + 1;
        end
end



--[[    CTA_ListItem_OnMouseUp()
                ---------------------------------------------------------------
                Sets the caller item as the selected group and updates the
                <ui>CTA_RequestInviteButton</ui> button as necessary, then
                calls the <func>CTA_UpdateResults()</func> afterwards.
                ]]

function CTA_ListItem_OnMouseUp()
        local value = string.gsub( this:GetName(), "CTA_NewItem(%d+)", "%1" ); 
        if( CTA_SelectedResultListItem == CTA_ResultsListOffset + value ) then
                CTA_SelectedResultListItem = 0;
                CTA_RequestInviteButton:Disable();
        else
                CTA_SelectedResultListItem = CTA_ResultsListOffset + value;
                
                local raid = CTA_RaidList[ CTA_ResultsListOffset + value ];
                
                -- R7
                if (arg1 == "RightButton") then
                        local name = raid.op or raid.author;
                        --FriendsFrame_ShowDropdown(name, 1);

                        HideDropDownMenu(1);
                        if ( name ~= UnitName("player") ) then
                                FriendsDropDown.initialize = FriendsFrameDropDown_Initialize;
                                FriendsDropDown.displayMode = "MENU";
                                FriendsDropDown.name = name;
                                ToggleDropDownMenu(1, nil, FriendsDropDown, this:GetName());
                        end

                        return;
                end
                -- /R7

                if( raid.ctaType == "A" ) then -- for R7 goodness
                
                        local myClass = UnitClass( CTA_PLAYER );
                        if( raid.minLevel > UnitLevel (CTA_PLAYER ) or not string.find( CTA_GetClassString( raid.classes ),myClass ) ) then
                                CTA_RequestInviteButton:Disable();
                        else
                                CTA_RequestInviteButton:Enable();
                        end
                end
        end
        CTA_UpdateResults();
end




--[[    CTA_ListItem_ShowTooltip()
                ---------------------------------------------------------------
                Set up and show the tooltip for the calling group list item.
                ]]

function CTA_ListItemAuxLeft_ShowTooltip()
        GameTooltip:ClearLines();
        local parent = this:GetParent();
        local value = CTA_ResultsListOffset + string.gsub( parent:GetName(), "CTA_NewItem(%d+)", "%1" );
        
        local entry = CTA_RaidList[value];
        GameTooltip:SetOwner( this, "ANCHOR_BOTTOMLEFT" );
        GameTooltip:ClearAllPoints();
        GameTooltip:SetPoint("BOTTOMLEFT", parent:GetName(), "TOPLEFT", 0, 8);
        
        if( entry == nil ) then return; end
        
        GameTooltip:AddLine( ( entry.op or entry.author ) );
        GameTooltip:AddLine( entry.message, 0.9, 0.9, 1.0, 1, 1 );
        GameTooltip:Show();
end


function CTA_ListItemAuxRight_ShowTooltip()

        local parent = this:GetParent();
        
        GameTooltip:ClearLines();
        local value = CTA_ResultsListOffset + string.gsub( parent:GetName(), "CTA_NewItem(%d+)", "%1" );
        
        local raid = CTA_RaidList[value];
        GameTooltip:SetOwner( this, "ANCHOR_BOTTOMRIGHT" );
        GameTooltip:ClearAllPoints();
        GameTooltip:SetPoint("BOTTOMRIGHT", parent:GetName(), "TOPRIGHT", 0, 8);
        
        if( raid == nil ) then return; end

        if( raid.ctaType == "A" ) then -- R7 condition

                local classes = { };
                classes[1] = CTA_PRIEST;
                classes[2] = CTA_MAGE;
                classes[3] = CTA_WARLOCK;
                classes[4] = CTA_DRUID;
                classes[5] = CTA_HUNTER;
                classes[6] = CTA_ROGUE;
                classes[7] = CTA_WARRIOR;
                if( UnitFactionGroup(CTA_PLAYER) == CTA_ALLIANCE ) then
                        classes[8] = CTA_PALADIN;
                else
                        classes[8] = CTA_SHAMAN;
                end                     
                local groupClasses, ctaVersion = CTA_DecodeGroupClasses( raid.options );
                if( groupClasses and ctaVersion ) then
                        GameTooltip:AddLine( CTA_CTA_GROUP, 0.1, 0.9, 0.1, 1, 1 );
                        GameTooltip:AddLine( CTA_CURRENT_GROUP_CLASSES..":", 0.1, 0.9, 0.1, 1, 1 );     
                        local classList = CTA_GetClassString(raid.classes);
                        for i = 1, 8 do
                                if( string.find(classList, classes[i]) ) then
                                        GameTooltip:AddDoubleLine( classes[i], groupClasses[i], 0.9, 0.9, 0.1, 0.1, 0.9, 0.1 );
                                else
                                        GameTooltip:AddDoubleLine( classes[i], groupClasses[i], 0.9, 0.9, 0.1, 0.9, 0.1, 0.1 );
                                end
                        end
                        GameTooltip:AddDoubleLine( CTA_VERSION, ctaVersion, 0.9, 0.9, 0.9, 0.1, 0.9, 0.1 );
                else
                        if( raid.classes == 255 ) then
                                GameTooltip:AddLine( CTA_LFM_ANY_CLASS, 0.1, 0.9, 0.1 );        
                        else 
                                local myClass = UnitClass( CTA_PLAYER );
                                local classList = CTA_GetClassString(raid.classes);
                                
                                if( string.find(classList, myClass) ) then
                                        GameTooltip:AddLine( CTA_LFM_CLASSLIST..classList, 0.1, 0.9, 0.1 );     
                                else
                                        if( not classList or classList == "" ) then
                                                GameTooltip:AddLine( CTA_NO_MORE_PLAYERS_NEEDED, 0.9, 0.1, 0.1 );       
                                        else
                                                GameTooltip:AddLine( CTA_LFM_CLASSLIST..classList, 0.9, 0.1, 0.1 );     
                                        end
                                end
                        end
                        GameTooltip:AddLine( CTA_PRE_R7_USER, 0.3, 0.3, 0.3, 1, 1 );
                end
        
        elseif( raid.ctaType == "B" ) then -- R7 condition
                        
                GameTooltip:AddLine( CTA_CTA_PLAYER, 0.1, 0.9, 0.1, 1, 1 );
                GameTooltip:AddDoubleLine( CTA_VERSION, raid.options, 0.9, 0.9, 0.9, 0.1, 0.9, 0.1 );

        elseif( raid.ctaType == "C" ) then -- R7 condition

                GameTooltip:AddLine( CTA_NON_CTA_GROUP_MESSAGE, 0.3, 0.3, 0.3, 1, 1 );

        elseif( raid.ctaType == "D" ) then -- R7 condition

                GameTooltip:AddLine( CTA_NON_CTA_PLAYER_MESSAGE, 0.3, 0.3, 0.3, 1, 1 );
        
        end
        
        GameTooltip:Show();     
end


function CTA_ResultItem_Hover_On(parent)
        local value = CTA_ResultsListOffset + string.gsub( parent:GetName(), "CTA_NewItem(%d+)", "%1" );
        local entry = CTA_RaidList[value];
        if( entry == nil ) then return; end

        parent:SetHeight( 32 );
        getglobal( parent:GetName().."MoreLabel" ):Show();
        getglobal( parent:GetName().."MoreRightLabel" ):Show();
        if( entry.ctaType== "A" or entry.ctaType== "B" ) then
                getglobal( parent:GetName().."TexturePurple"):Show();
                getglobal( parent:GetName().."TextureBlue"):Hide();
        else
                getglobal( parent:GetName().."TexturePurple"):Hide();
                getglobal( parent:GetName().."TextureBlue"):Show();
        end 
        
        if( entry.ctaType== "A" ) then
                getglobal( parent:GetName().."TextureSelectedIcon"):SetTexture( "Interface\\Icons\\Spell_Holy_SealOfFury" );    
        elseif( entry.ctaType== "B" ) then
                getglobal( parent:GetName().."TextureSelectedIcon"):SetTexture( "Interface\\Icons\\Spell_Holy_RetributionAura" );       
        elseif( entry.ctaType== "C" ) then
                getglobal( parent:GetName().."TextureSelectedIcon"):SetTexture( "Interface\\Icons\\Spell_Holy_SealOfProtection" );      
        elseif( entry.ctaType== "D" ) then
                getglobal( parent:GetName().."TextureSelectedIcon"):SetTexture( "Interface\\Icons\\Spell_Holy_RighteousnessAura" );     
        end
                                                                
        getglobal( parent:GetName().."NameLabel"):SetPoint( "TOPLEFT", parent:GetName(), "TOPLEFT", 37, 0 );
        getglobal( parent:GetName().."MoreLabel"):SetPoint( "LEFT", parent:GetName(), "LEFT", 37, -6 );
                
        getglobal( parent:GetName().."TextureSelectedBg"):Show();
        getglobal( parent:GetName().."TextureSelectedIcon"):Show();

end

function CTA_ResultItem_Hover_Off(parent)
        parent:SetHeight( 18 );
        getglobal( parent:GetName().."MoreLabel" ):Hide();
        getglobal( parent:GetName().."MoreRightLabel" ):Hide();
        getglobal( parent:GetName().."TexturePurple"):Hide();
        getglobal( parent:GetName().."TextureBlue"):Hide();

        getglobal( parent:GetName().."NameLabel"):SetPoint( "TOPLEFT", parent:GetName(), "TOPLEFT", 5, 0 );
        getglobal( parent:GetName().."MoreLabel"):SetPoint( "LEFT", parent:GetName(), "LEFT", 5, -6 );
                
        getglobal( parent:GetName().."TextureSelectedBg"):Hide();
        getglobal( parent:GetName().."TextureSelectedIcon"):Hide();

end





















































--[[    ---------------------------------------------------------------
                Functions Related To Hosting A Group And The Acid Items 
                --------------------------------------------------------------- 
                ]]




--[[    CTA_MyRaidInstantUpdate()                                               UPDATE FUNCTION
                ---------------------------------------------------------------
                Called by CTA_MyRaidFrame Components.
                This is the longest, most elaborate and buggy function and has
                been hacked and updated far too many times. 
                Todo: A complete rewrite of the function.
                ]]

function CTA_MyRaidInstantUpdate()
        if( CTA_MyRaid == nil ) then return; end
        
        local myName = UnitName( CTA_PLAYER );
        
        local myComment = CTA_SafeSet( CTA_MyRaidFrameDescriptionEditBox:GetText(), CTA_NO_DESCRIPTION );
        
        local myRaidType = CTA_RAID_TYPE_PVE;
        if( CTA_MyRaidFramePVPCheckButton:GetChecked() ) then
                myRaidType = CTA_RAID_TYPE_PVP;
        end
                
        -- Advanced Class Integration and Distribution
        -- ACID ACID ACID ACID ACID ACID ACID ACID ACID ACID ACID ACID ACID ACID ACID ACID ACID ACID ACID ACID ACID ACID 
        -- ACID ACID ACID ACID ACID ACID ACID ACID ACID ACID ACID ACID ACID ACID ACID ACID ACID ACID ACID ACID ACID ACID 
        
        --[[    ------------------------------------
                        [Setup Acid Items]
                        
                        If the acid item has no class list
                        then it is hidden.
                        ------------------------------------
                        ]]
        if( not CTA_Acid0.val ) then
                local classes = { };
                classes[1] = CTA_PRIEST;
                classes[2] = CTA_MAGE;
                classes[3] = CTA_WARLOCK;
                classes[4] = CTA_DRUID;
                classes[5] = CTA_HUNTER;
                classes[6] = CTA_ROGUE;
                classes[7] = CTA_WARRIOR;
                if( UnitFactionGroup(CTA_PLAYER) == CTA_ALLIANCE ) then
                        classes[8] = CTA_PALADIN;
                else
                        classes[8] = CTA_SHAMAN;
                end                             
                
                local num = 0;
                while( num < 9 ) do
                        local item = getglobal( "CTA_Acid"..num );
                        local class = getglobal( "CTA_Acid"..num.."ClassNameLabel" );
                        
                        if( num > 0 ) then
                                item.val = 0;
                                item.cur = 0;
                        else
                                class:SetText( CTA_ANY_CLASS );
                                item.val = CTA_MyRaid.maxSize;
                                getglobal( "CTA_Acid"..num.."LessButton"):Hide();
                                getglobal( "CTA_Acid"..num.."MoreButton"):Hide();                       
                                --getglobal( "CTA_Acid"..num.."EditButton"):Hide();                     
                                getglobal( "CTA_Acid"..num.."DeleteButton"):Hide();
                        end
                                
                        num = num + 1;
                end
        end
        

        --[[    ------------------------------------
                        [Update the Max Size]
                        
                        If the and sets up certain features
                        for raid / party
                        ------------------------------------
                        ]]

        local myOldMax = CTA_MyRaid.maxSize;
        if( not myOldMax ) then myOldMax = 40; end
        
        if ( IsRaidLeader() and GetNumRaidMembers() > 0 ) then CTA_HostingRaidGroup = 1; end
        local maxSizeLimit = 5;                                                 -- R2
        CTA_ConvertToRaidButton:Hide();
        CTA_MaxSizeHelpLabel:SetText( CTA_MAXIMUM_PLAYERS_HELP2 );
        if( IsPartyLeader() and GetNumRaidMembers() == 0  ) then
                CTA_ConvertToRaidButton:Show();
        else
                CTA_ConvertToRaidButton:Hide();
        end
        if( CTA_HostingRaidGroup ) then
                maxSizeLimit = 40;              
                CTA_MaxSizeHelpLabel:SetText( CTA_MAXIMUM_PLAYERS_HELP );       
        end
        if( IsRaidLeader() and GetNumRaidMembers() > 0 and GetNumRaidMembers() < 6 ) then
                CTA_ConvertToPartyButton:Show();        
        else
                CTA_ConvertToPartyButton:Hide();        
        end

        if( CTA_MyRaid.maxSize > maxSizeLimit ) then
                CTA_MyRaid.maxSize = maxSizeLimit;
        end
        
        local myMaxSize = CTA_SafeSetNumber( CTA_MyRaidFrameMaxSizeEditBox:GetText(), 5, maxSizeLimit ); 
        if( not myMaxSize ) then
                myMaxSize = CTA_MyRaid.maxSize;
        else
                CTA_MyRaid.maxSize = tonumber(myMaxSize);
        end
        CTA_MyRaidFrameMaxSizeEditBox:SetText(""..myMaxSize);
        

        --[[    ------------------------------------
                        [Update ACID Scale]
                        
                        According to the max size
                        ------------------------------------
                        ]]

        --if( myMaxSize ~= myOldMax ) then
                local num = 0;
                local cval = 0;
                while( num < 9 ) do     
                        local item = getglobal( "CTA_Acid"..num );
                        local ratio = item.val/myOldMax;
                        item.val = floor(myMaxSize*ratio);
                        cval = cval+item.val;
                        num = num + 1;
                end
                if( cval < myMaxSize ) then
                        CTA_Acid0.val = CTA_Acid0.val + (myMaxSize-cval);
                end
                num = 0;
                while( num < 9 and cval > myMaxSize ) do
                        local item = getglobal( "CTA_Acid"..num );
                        if( item.val > 0 ) then
                                item.val = item.val - 1;
                                cval = cval - 1;
                        else
                                num = num + 1;
                        end
                end
        --end
        --CTA_LogMsg( "Adjusted ACID Size ("..cval..")", CTA_GENERAL );


        --[[    ------------------------------------
                        [Reset Acid item current size]
                        
                        Set the current players in each rule 
                        to 0
                        ------------------------------------
                        ]]


        local num = 0;
        while( num < 9 ) do
                local item = getglobal( "CTA_Acid"..num );
                item.cur = 0;
                num = num + 1;
        end     
        
        
        --[[    ------------------------------------
                        [Update ACID items current size]
                        
                        Big change here now
                        ------------------------------------
                        ]]

        
        local name, level, class;
        local over = 0;
        num = 1;
        while ( num <= 40 ) do  
                name, level, class = CTA_GetGroupMemberInfo( num );
                if( name == nil ) then break; end
                local index = CTA_GetClassCode(class);
                
                local bestItem = nil;
                for i = 1, 8 do
                        local item = getglobal( "CTA_Acid"..i );
                        if( item.classes and item.classes[class] ) then
                                if( not bestItem or CTA_getn(bestItem.classes) > CTA_getn(item.classes) ) then
                                        if( item.cur < item.val ) then
                                                bestItem = item;
                                        end
                                end
                        end
                end
                
                if( not bestItem ) then
                        over = over + 1;
                else
                        bestItem.cur = bestItem.cur + 1;
                end
                --if( item.cur > item.val ) then over = over + 1; end
                
                if( CTA_InvitationRequests[name] ) then
                        CTA_RemoveRequest( name ); -- R2: Remove pending member if in raid
                        CTA_LogMsg( name.." has joined the group - request removed" );  
                        CTA_SendAutoMsg( CTA_PROMO..CTA_ANNOUNCE_JOIN_PROMPT, name );
                end

                num = num+1;
        end     


        --[[    ------------------------------------
                        [Update the Group Size]
                        
                        Take pendings into account etc
                        ------------------------------------
                        ]]


        local pendingSize = 0; 
        for name, data in CTA_InvitationRequests do
                if( name and data.status == 2 ) then    -- R2: pending members
                        --CTA_Println( name..": "..class );
                        local index = CTA_GetClassCode( data.class);
                        local item = getglobal( "CTA_Acid"..index );
                        item.cur = item.cur + 1;
                        pendingSize = pendingSize + 1;                  
                        if( item.cur > item.val ) then over = over + 1; end
                end             
        end
                
        CTA_Acid0.cur = over;
        
        --[[
        local oldSize = CTA_MyRaid.size;
        CTA_MyRaid.size = CTA_GetNumGroupMembers() + pendingSize;
        local mySize = CTA_MyRaid.size;

        if ( ( IsRaidLeader() and GetNumRaidMembers() > 0 ) ) then
                CTA_RaidSizeLabel:SetText( CTA_SIZE..": "..CTA_MyRaid.size.." ("..CTA_RAID..") ("..CTA_CURRENT..": "..CTA_GetNumGroupMembers().." "..CTA_PENDING..": "..pendingSize..")" );
        
        elseif( IsPartyLeader() and GetNumRaidMembers() == 0 ) then
                CTA_RaidSizeLabel:SetText( CTA_SIZE..": "..CTA_MyRaid.size.." ("..CTA_PARTY..") ("..CTA_CURRENT..": "..CTA_GetNumGroupMembers().." "..CTA_PENDING..": "..pendingSize..")" );
        
        end]]
        
        local oldSize = CTA_MyRaid.size;
        CTA_MyRaid.size = CTA_GetNumGroupMembers();
        local mySize = CTA_MyRaid.size;
        --CTA_Println( "Size = "..mySize );
        CTA_RaidSizeLabel:SetText( CTA_SIZE..": "..CTA_MyRaid.size.." ("..CTA_CURRENT..": "..CTA_GetNumGroupMembers().." "..CTA_PENDING..": "..CTA_getn(CTA_InvitationRequests)..")" );


        if( CTA_MyRaid.size > oldSize ) then
                PlaySound("TellMessage");
        end
        CTA_IconMsg( CTA_GROUP_MEMBERS..CTA_MyRaid.size, CTA_GROUP_UPDATE);
        
        -- R7 announce auto off

        if( autoannounce and  CTA_GetNumGroupMembers() >= CTA_MyRaid.maxSize ) then
                autoannouce = nil;
                CTA_AnnounceTimer = 0;
                CTA_Println( "Your group has the desired number of players. LFM Auto announce OFF" );
        end
        
        
        --[[    ------------------------------------
                        [Update the Acid Items]
                        
                        Accordingly
                        ------------------------------------
                        ]]

        
        num = 0;
        
        
        CTA_AcidSummary = CTA_LFM..": "..CTA_MyRaid.comment.." ("..CTA_MyRaid.size.."/"..CTA_MyRaid.maxSize..")"..CTA_ANNOUNCE_SUMMARY_PROMPT;
        CTA_AcidDetails = CTA_LFM..": "..CTA_MyRaid.comment.." ("..CTA_MyRaid.size.."/"..CTA_MyRaid.maxSize..") - ";
        
        while( num < 9 ) do
                local item = getglobal( "CTA_Acid"..num );
                
                if( item.classes or item:GetName()=="CTA_Acid0" ) then
                

                        
                        local nam = getglobal( "CTA_Acid"..num.."ClassNameLabel" );
                        
                        
                        if( item:GetName()~="CTA_Acid0" ) then
                                getglobal( "CTA_Acid"..num.."ClassNameLabel" ):Show();
                                --getglobal( "CTA_Acid"..num.."ClassPercentLabel" ):Show();
                                getglobal( "CTA_Acid"..num.."ClassAbsoluteLabel" ):Show();
                                getglobal( "CTA_Acid"..num.."ClassCurrentLabel" ):Show();
                                
                                getglobal( "CTA_Acid"..num.."LessButton"):Show();
                                getglobal( "CTA_Acid"..num.."MoreButton"):Show();                       
                                --getglobal( "CTA_Acid"..num.."EditButton"):Show();                     
                                getglobal( "CTA_Acid"..num.."DeleteButton"):SetText( "Edit" );                  
                        
                                nam:SetText( "" );
                                for key, val in item.classes do
                                        if( nam:GetText() ) then
                                                nam:SetText( nam:GetText()..key.."\n" );
                                        else
                                                nam:SetText( key.."\n" );
                                        end
                                end
                        end
                        
                        local percent = getglobal( "CTA_Acid"..num.."ClassPercentLabel" );
                        local current = getglobal( "CTA_Acid"..num.."ClassAbsoluteLabel" );
                        local absolute = getglobal( "CTA_Acid"..num.."ClassCurrentLabel" );
                        local percentTex = getglobal( "CTA_Acid"..num.."PercentTexture" );
                        local currentTex = getglobal( "CTA_Acid"..num.."CurrentTexture" );
        
                        local pval = floor(50*item.val/CTA_MyRaid.maxSize); --80 changed to 50 R5
                        if( pval > 50 ) then pval = 50; end -- cheapo fix
                        local percentage = floor(100*item.val/CTA_MyRaid.maxSize);
                        
                        percent:SetText( percentage.."%" );
                        absolute:SetText( "/"..item.val );
                        
                        if( item.val == 0)  then
                                percentTex:Hide();
                                absolute:SetTextColor( 0.5, 0.5, 0.5 );
                        else
                                percentTex:SetHeight( pval );
                                absolute:SetTextColor( 1.0, 0.82, 0.0 );
                                percentTex:Show();
                        end
        
                        local cval = item.cur;
                        local cpval = floor(50*cval/CTA_MyRaid.maxSize); --80 -> 50 R5
                        if( cpval > 50 ) then cpval = 50; end -- cheapo fix
                        current:SetText( cval );
                        
                        if( cval == 0)  then
                                currentTex:Hide();
                                current:SetTextColor( 0.5, 0.5, 0.5 );
                        else
                                current:SetTextColor( 1.0, 0.82, 0.0 );
                                currentTex:SetHeight( cpval );
                                currentTex:Show();
                        end
                        if( cval > item.val and CTA_Acid0.cur > CTA_Acid0.val ) then
                                current:SetTextColor( 1.0, 0.0, 0.0 );                  
                        end             
                        
                        local lfm = item.val-item.cur;
                        if( lfm > 0 ) then
                                if( num == 0 ) then
                                        CTA_AcidDetails = CTA_AcidDetails..(lfm).." "..CTA_ANY_CLASS..", ";
                                else
                                        CTA_AcidDetails = CTA_AcidDetails..(lfm).." ";
                                        local f = nil;
                                        for k,v in item.classes do
                                                if( f ) then
                                                        CTA_AcidDetails = CTA_AcidDetails.."/";
                                                else
                                                        f = 1;
                                                end
                                                CTA_AcidDetails = CTA_AcidDetails..k;

                                        end
                                        CTA_AcidDetails = CTA_AcidDetails..", ";
                                end
                        end
                else

                        getglobal( "CTA_Acid"..num.."ClassNameLabel" ):Hide();

                        --getglobal( "CTA_Acid"..num.."ClassPercentLabel" ):Hide();
                        getglobal( "CTA_Acid"..num.."ClassAbsoluteLabel" ):Hide();
                        getglobal( "CTA_Acid"..num.."ClassCurrentLabel" ):Hide();

                        getglobal( "CTA_Acid"..num.."PercentTexture" ):Hide();
                        getglobal( "CTA_Acid"..num.."CurrentTexture" ):Hide();

                        getglobal( "CTA_Acid"..num.."LessButton"):Hide();
                        getglobal( "CTA_Acid"..num.."MoreButton"):Hide();                       
                        --getglobal( "CTA_Acid"..num.."EditButton"):Hide();                     
                        getglobal( "CTA_Acid"..num.."DeleteButton"):SetText( "Add" );                   

                
                        --item:Hide();
                end
                                                        
                num = num + 1;
        end
        
        CTA_AcidDetails = CTA_AcidDetails..CTA_ANNOUNCE_DETAILS_PROMPT;
        
        
        CTA_AcidNote:SetText( CTA_AcidSummary );

        if( CTA_HostingRaidGroup and IsPartyLeader() and GetNumRaidMembers() == 0 ) then
                CTA_ConvertToRaid();
        end
        
        -- ACID ACID ACID ACID ACID ACID ACID ACID ACID ACID ACID ACID ACID ACID ACID ACID ACID ACID ACID ACID ACID ACID 
        -- ACID ACID ACID ACID ACID ACID ACID ACID ACID ACID ACID ACID ACID ACID ACID ACID ACID ACID ACID ACID ACID ACID 
        -- ACID ACID ACID ACID ACID ACID ACID ACID ACID ACID ACID ACID ACID ACID ACID ACID ACID ACID ACID ACID ACID ACID 
        
        local myMinLevel = CTA_SafeSetNumber( CTA_MyRaidFrameMinLevelEditBox:GetText(), 1, 60 ); 
        if( not myMinLevel ) then
                CTA_MyRaidFrameMinLevelEditBox:SetText( CTA_MyRaid.minLevel );
                myMinLevel = CTA_MyRaid.minLevel;
        end

        local myClasses = 0; 
        if( CTA_Acid0.cur < CTA_Acid0.val ) then
                myClasses = 255;
        else
                local num = 1;
                local b = 1;
                local combinedClasses = {};
                for i = 1, 8 do
                        local item = getglobal( "CTA_Acid"..i );
                        if( item.classes and item.cur < item.val ) then
                                for k, v in item.classes do
                                        combinedClasses[ k ] = 1;
                                end
                        end
                end
                
                for k,v in combinedClasses do
                        local index = CTA_GetClassCode( k );
                        myClasses = myClasses + (2^(index - 1 ));
                end
                --[[
                while( num < 9 ) do
                        local item = getglobal( "CTA_Acid"..num );
                        if( item.cur < item.val ) then
                                myClasses = myClasses + b;
                        end
                        b = b * 2;                      
                        num = num + 1;
                end     ]]
        end
        
        local myUsePassword = 1;
        local oldPassword = CTA_MyRaidPassword;
        CTA_MyRaidPassword = CTA_MyRaidFramePasswordEditBox:GetText(); 
        for space in string.gfind( CTA_MyRaidPassword, "(%s)" ) do 
                CTA_MyRaidPassword = oldPassword;
        end
        if( not CTA_MyRaidPassword or CTA_MyRaidPassword== "" ) then 
                myUsePassword = 0; 
                CTA_MyRaidPassword = nil;
                CTA_MyRaidFramePasswordEditBox:SetText( "" );

        else
                CTA_MyRaidFramePasswordEditBox:SetText( CTA_MyRaidPassword );
        end
        
        local myName = UnitName(CTA_PLAYER);
        local myTime = CTA_MyRaid.creationTime;
        local myOptions = CTA_GetGroupClassesCode()..CTA_RELEASEVERSION..",R";
        
        CTA_SetRaidInfo( CTA_MyRaid, myName, 100, myComment, myRaidType, mySize, myMaxSize, myMinLevel, myClasses, myUsePassword, myTime, myOptions );  
        CTA_PollBroadcast = 1;
        --CTA_IconMsg( "Broadcast Polled" );
end     

function CTA_AcidItemButton_OnClick()
        local item = getglobal( this:GetParent():GetName() );
        
        if( string.find( this:GetName(), "Delete" ) ) then
                CTA_StartEditAcidItem( item );
                --[[
                if( item.classes == nil ) then
                        CTA_AddAcidItem( item );
                else
                        CTA_StartEditAcidItem(item);
                end]]
        elseif( string.find( this:GetName(), "Less" ) ) then
                if( item.val > 0 ) then
                        item.val = item.val - 1;
                        CTA_Acid0.val = CTA_Acid0.val + 1;
                end
                CTA_MyRaidInstantUpdate();
        else
                if( CTA_Acid0.val > 0 ) then
                        item.val = item.val + 1;
                        CTA_Acid0.val = CTA_Acid0.val - 1;
                end
                CTA_MyRaidInstantUpdate();
        end
end




--[[    CTA_StartEditAcidItem()
                ---------------------------------------------------------------
                Called by CTA_Acid(0-8) AddButton Components.
                All this function really does is set up the check buttons
                in the <ui>CTA_AcidEditDialog</ui> Frame before showing it 
                to the user.
                ]]
                
function CTA_StartEditAcidItem( item ) 
        for i = 1, 8 do
                getglobal( "CTA_AcidClassCheckButton"..i ):SetChecked( 0 );
        end
        
        if( UnitFactionGroup(CTA_PLAYER) == CTA_ALLIANCE ) then
                CTA_AcidClassCheckButton8TextLabel:SetText( CTA_PALADIN );
        else
                CTA_AcidClassCheckButton8TextLabel:SetText( CTA_SHAMAN );
        end     
        
        if( item.classes ) then
                for key, val in item.classes do
                
                for i = 1, 8 do
                                if ( getglobal( "CTA_AcidClassCheckButton"..i.."TextLabel" ):GetText() == key ) then
                                        getglobal( "CTA_AcidClassCheckButton"..i ):SetChecked( 1 );
                                end
                        end
                end
        else
                item.classes = {};      
        end
         
        CTA_AcidEditDialogHeadingLabel:SetText( CTA_EDIT_ACID_CLASSES );
        CTA_AcidEditDialog.target = item:GetName();             
                                
        CTA_AcidEditDialog:Show();
end




--[[    CTA_EditAcidItem()
                ---------------------------------------------------------------
                Called by the <ui>CTA_AcidEditDialog</ui>'s OKButton Component.
                Sets the Acid item's class list to what classes were checked
                by the user in the edit dialog.
                ]]
                
function CTA_EditAcidItem()
        local acidItem = getglobal( CTA_AcidEditDialog.target );
        local checkCount = 0;
        acidItem.classes = {};
        for i = 1, 8 do
                local checked =  getglobal( "CTA_AcidClassCheckButton"..i ):GetChecked();
                if( checked ) then
                        acidItem.classes[ getglobal( "CTA_AcidClassCheckButton"..i.."TextLabel" ):GetText() ] = 0;
                        checkCount = checkCount + 1;
                end
        end
        
        if( checkCount == 0 or checkCount == 8 ) then
                acidItem.classes = nil;
                if( acidItem.val ) then
                        CTA_Acid0.val = CTA_Acid0.val + acidItem.val;
                end
                acidItem.val = 0;
        end
        
        CTA_AcidEditDialog:Hide();
        CTA_MyRaidInstantUpdate();
        
end




--[[    CTA_getn()
                ---------------------------------------------------------------
                Utility function that returns the length of a list.
                @arg the list 
                @return the length of the list 
                ]]

function CTA_getn( list ) 
        local c = 0;
        for i, j in list do
                c = c + 1;
        end
        return c;
end




--[[    CTA_StartAParty()
                ---------------------------------------------------------------
                Starts a party group.
                Called by StartARaidFrame's StartAPartyButton 
                ]]
                
function CTA_StartAParty()
        CTA_HostingRaidGroup = nil;
        CTA_MyRaid = {};
        CTA_SetRaidInfo( CTA_MyRaid,  UnitName( CTA_PLAYER ), 100, "", CTA_RAID_TYPE_PVE, GetNumPartyMembers()+1, 5, 1, 255, 0, CTA_GetTime(), 0 );     
        CTA_MyRaidIsOnline = 1;
        CTA_ShowStartRaidFrame();
end




--[[    CTA_StartARaid
                ---------------------------------------------------------------
                Starts a raid group.
                Called by StartARaidFrame's StartARaidButton
                ]]
                
function CTA_StartARaid()
        CTA_HostingRaidGroup = 1;
        CTA_MyRaid = {};
        CTA_SetRaidInfo( CTA_MyRaid,  UnitName( CTA_PLAYER ), 100, "", CTA_RAID_TYPE_PVE, GetNumRaidMembers(), 10, 1, 255, 0, CTA_GetTime(), 0 );       
        CTA_MyRaidIsOnline = 1;
        CTA_ShowStartRaidFrame();
end




--[[    CTA_StopHosting()
                ---------------------------------------------------------------
                Stops hosting a group with CTA. 
                ]]
                
function CTA_StopHosting()
        CTA_HostingRaidGroup = nil;
        CTA_MyRaid = nil;
        CTA_MyRaidIsOnline = nil;
        CTA_PollBroadcast = 2;
        
        CTA_SearchFrame:Hide();
        CTA_MyRaidFrame:Hide();
        CTA_SettingsFrame:Hide();
        CTA_GreyListFrame:Hide();
        CTA_LogFrame:Hide();
        
        CTA_ShowStartRaidFrame();
end




--[[    CTA_ShowStartRaidFrame()
                ---------------------------------------------------------------
                Prompts the user to start hosting a group with CTA or
                tells the user that s/he cannot currently host a group or
                shows the group information frame if user is already using
                CTA to host a group.
                ]]

function CTA_ShowStartRaidFrame() 
        CTA_StartRaidFrame:Show();
        
        if( CTA_MyRaid ) then
                CTA_StartRaidFrame:Hide();
                
                if( CTA_ToggleViewableButton:GetText() ==  CTA_GO_OFFLINE ) then
                        CTA_MyRaidIsOnline = 1;
                end
                
                CTA_MyRaidFrameDescriptionEditBox:SetText(""..CTA_MyRaid.comment);
                
                local myRaidType = CTA_MyRaid.pvtype;
                if( myRaidType == CTA_RAID_TYPE_PVP ) then
                        CTA_MyRaidFramePVPCheckButton:SetChecked(1)
                        CTA_MyRaidFramePVECheckButton:SetChecked(0)
                else
                        CTA_MyRaidFramePVPCheckButton:SetChecked(0)
                        CTA_MyRaidFramePVECheckButton:SetChecked(1)
                end
                
                CTA_MyRaidFrameMaxSizeEditBox:SetText(""..CTA_MyRaid.maxSize);
                CTA_MyRaidFrameMinLevelEditBox:SetText(""..CTA_MyRaid.minLevel); 
                
                if( CTA_MyRaidPassword ) then
                        CTA_MyRaidFramePasswordEditBox:SetText(CTA_MyRaidPassword); 
                else 
                        CTA_MyRaidFramePasswordEditBox:SetText(""); 
                end     
        
                CTA_MyRaidInstantUpdate(); 
                CTA_MyRaidFrame:Show();
        end

        CTA_StartARaidButton:Hide();
        CTA_StartAPartyButton:Hide();   

        if ( CTA_PlayerCanHostGroup() ) then
                CTA_StartRaidLabel:SetText( CTA_PLAYER_CAN_START_A_GROUP );     

                if( not CTA_MyRaid and IsRaidLeader() and GetNumRaidMembers() > 0 ) then
                        CTA_StartARaidButton:Show();
                elseif( not CTA_MyRaid and IsPartyLeader() and GetNumRaidMembers() == 0 ) then
                        CTA_StartAPartyButton:Show();   
                        CTA_StartARaidButton:Show();
                else
                        CTA_StartAPartyButton:Show();   
                        CTA_StartARaidButton:Show();
                end
        else
                CTA_StartRaidLabel:SetText( CTA_PLAYER_IS_RAID_MEMBER_NOT_LEADER );     
        end                                             
end




--[[    CTA_AcidItem_ShowTooltip()
                ---------------------------------------------------------------
                Shows tooltip for acid items.
                ]]

function CTA_AcidItem_ShowTooltip()
        GameTooltip:SetOwner( this, "ANCHOR_TOP" );
        GameTooltip:ClearLines();
        GameTooltip:ClearAllPoints();
        GameTooltip:SetPoint("TOPLEFT", this:GetName(), "BOTTOMLEFT", 0, -8);   
                
        local acidItem = this;
        if( not acidItem.classes and acidItem:GetName() ~= "CTA_Acid0" ) then 
                GameTooltip:AddLine( CTA_NO_CLASSES_TOOLTIP );          
                GameTooltip:AddLine( CTA_NO_CLASSES_TOOLTIP2, 1, 1, 1, 1, 1 );          
                return; 
        end
        
        local needed = acidItem.val - acidItem.cur;
        if( needed < 0 ) then needed = 0; end
        
        if( this:GetName() == "CTA_Acid0" ) then
                GameTooltip:AddDoubleLine( CTA_MAXIMUM_PLAYERS_ALLOWED..":", ""..this.val );
                GameTooltip:AddDoubleLine( CTA_PLAYERS_IN_RAID..":", ""..this.cur );
                GameTooltip:AddDoubleLine( CTA_NUMBER_OF_PLAYERS_NEEDED..":", ""..needed );
                GameTooltip:AddLine( CTA_ANY_CLASS_TOOLTIP, 1, 1, 1, 1, 1 );            
        else
                GameTooltip:AddDoubleLine( CTA_MINIMUM_PLAYERS_WANTED..":", ""..this.val );
                GameTooltip:AddDoubleLine( CTA_PLAYERS_IN_RAID..":", ""..this.cur );
                GameTooltip:AddDoubleLine( CTA_NUMBER_OF_PLAYERS_NEEDED..":", ""..needed );
                GameTooltip:AddLine( CTA_CLASS_TOOLTIP, 1, 1, 1, 1, 1 );                                
        end
        
        GameTooltip:Show();
end




--[[    CTA_GetGroupMemberInfo()
                ---------------------------------------------------------------
                Returns information about a group member. 
                @arg the index of the group member
                @return the name, level, class of the player.
                ]]

function CTA_GetGroupMemberInfo( index )
        local name, rank, subgroup, level, class, fileName, zone, online, isDead;
        if ( IsRaidLeader() and GetNumRaidMembers() > 0 ) then
                name, rank, subgroup, level, class, fileName, zone, online, isDead = GetRaidRosterInfo(index);  
        elseif ( IsPartyLeader() and GetNumPartyMembers() > 0 ) then
                local target = CTA_PLAYER;
                if( index > 1 and index < 6 ) then
                        target = "PARTY"..(index-1);
                end
                name = UnitName(target);
                level = UnitLevel(target);
                class = UnitClass(target);
        elseif( GetNumRaidMembers() == 0  and GetNumPartyMembers() == 0 and index == 1 ) then
                local target = CTA_PLAYER;
                name = UnitName(target);
                level = UnitLevel(target);
                class = UnitClass(target);
        end
        return name, level, class;
end




--[[    CTA_GetNumGroupMembers()
                ---------------------------------------------------------------
                Returns information about a group member. 
                @arg the index of the group member
                @return the name, level, class of the player.
                ]]

function CTA_GetNumGroupMembers()
        --[[
        if( IsRaidLeader() ) then
                return GetNumRaidMembers();
        elseif( IsPartyLeader() ) then
                return GetNumPartyMembers() + 1;
        else
                return 1;
        end
        ]]
        if( GetNumRaidMembers() > 0 ) then
                return GetNumRaidMembers();
        elseif( GetNumPartyMembers() > 0 ) then
                return GetNumPartyMembers() + 1;
        else
                return 1;
        end
        
end




--[[    CTA_DissolveRaid()
                ---------------------------------------------------------------
                Dissolves the group by removing each member.
                ]]

function CTA_DissolveRaid()
        CTA_IconMsg( CTA_DISSOLVING_RAID, CTA_GROUP_UPDATE );
        num = 1;
        local numRaidMembers = GetNumRaidMembers();
        local name, rank, subgroup, level, class, fileName, zone, online, isDead;
        local over = 0;
        while ( num <= numRaidMembers ) do      
                name, rank, subgroup, level, class, fileName, zone, online, isDead = GetRaidRosterInfo(num);
                if( name ~= UnitName(CTA_PLAYER) ) then
                        UninviteByName( name );
                        CTA_SendAutoMsg( CTA_DISSOLVING_THE_RAID_CHAT_MESSAGE, name);                                   
                end
                num = num+1;
        end     
        CTA_IconMsg( CTA_RAID_DISSOLVED, CTA_GROUP_UPDATE );
end




--[[    CTA_ConvertToParty()
                ---------------------------------------------------------------
                convert your raid to a party.
                ]]

function CTA_ConvertToParty() --R2 (suggested by Sadris)
        CTA_IconMsg( CTA_CONVERTING_TO_PARTY, CTA_GROUP_UPDATE );
        num = 1;
        local numRaidMembers = GetNumRaidMembers();
        if( numRaidMembers > 5 ) then
                CTA_Println( CTA_CANNOT_CONVERT_TO_PARTY );
                return;
        end
        local memberList = {};
        local name, rank, subgroup, level, class, fileName, zone, online, isDead;
        local over = 0;
        while ( num <= numRaidMembers ) do      
                name, rank, subgroup, level, class, fileName, zone, online, isDead = GetRaidRosterInfo(num);
                if( name ~= UnitName(CTA_PLAYER) ) then
                        memberList[num] = name;
                        UninviteByName( name );
                        CTA_MyRaidInstantUpdate();
                        
                        CTA_SendAutoMsg( CTA_CONVERTING_TO_PARTY_MESSAGE, name);                                        
                end
                num = num+1;
        end     
        for i = 1, numRaidMembers - 1 do
                InviteByName( memberList[i] );
        end
        CTA_IconMsg( CTA_CONVERTING_TO_PARTY_DONE, CTA_GROUP_UPDATE );
        CTA_HostingRaidGroup = nil;
end




--[[    CTA_GetGroupType()
                ---------------------------------------------------------------
                Returns a String representation of the type of group
                currently being hosted.
                @return CTA_GROUP or CTA_PARTY 
                ]]

function CTA_GetGroupType()
        if ( CTA_HostingRaidGroup ) then
                return CTA_RAID;
        end
        return CTA_PARTY;
end





--[[    CTA_ConvertToParty()
                ---------------------------------------------------------------
                Converts the raid to a party
                ]]
                
function CTA_ConvertToRaid()
        if( IsPartyLeader() ) then
                CTA_HostingRaidGroup = 1;
                ConvertToRaid();
        end
end




--[[    CTA_PlayerCanHostGroup()
                ---------------------------------------------------------------
                Indicates whether a player can start hosting a group according
                to CTA logic.
                returns 1 if can host, nil if not
                ]]
        
function CTA_PlayerCanHostGroup()
        if ( ( IsRaidLeader() and GetNumRaidMembers() > 0 ) or 
                 ( IsPartyLeader() and GetNumRaidMembers() == 0 ) or
                 ( GetNumPartyMembers() == 0 and GetNumRaidMembers() == 0 ) ) then
                return 1;
        else
                return nil;
        end
end


--[[    CTA_SetRaidInfo()
                ---------------------------------------------------------------
                Set group information for the specified group.
                ]]

function CTA_SetRaidInfo( raid, name, score, comment, groupType, size, maxSize, minLevel, classes, passwordProtected, creationTime, options )
        raid.leader = name;
        raid.score = tonumber(score);   
        raid.comment = comment;
        raid.pvtype = tonumber(groupType);
        raid.size = tonumber(size);
        raid.maxSize = tonumber(maxSize);
        raid.minLevel = tonumber(minLevel);
        raid.classes = tonumber(classes);
        raid.passwordProtected = tonumber(passwordProtected);
        raid.creationTime = creationTime;
        raid.options = options;
end






















































--[[    ---------------------------------------------------------------
                Functions Related To The Blacklist      
                --------------------------------------------------------------- 
                ]]




--[[    CTA_UpdateGreyListItems()                                       UPDATE FUNCTION
                ---------------------------------------------------------------
                Updates the list of blacklisted players.                                                                                   
                ]]

function CTA_UpdateGreyListItems()
        CTA_GreyListItem0NameLabel:SetText( CTA_NAME );
        CTA_GreyListItem0NoteLabel:SetText( CTA_PLAYER_NOTE );
        CTA_GreyListItem0StatusLabel:SetText( "" );
        CTA_GreyListItem0:Show();
                
        local gls = getn(CTA_BlackList);
        if( not gls ) then
                gls = 0;
        end
        CTA_GreyListFramePageLabel:Show();
        local cpage = floor( CTA_PlayerListOffset / CTA_MAX_BLACKLIST_ITEMS );
        local tpage = floor( gls / CTA_MAX_BLACKLIST_ITEMS );
        if( cpage == 0 or cpage <= CTA_PlayerListOffset / CTA_MAX_BLACKLIST_ITEMS ) then cpage = cpage + 1; end
        if( tpage == 0 or tpage < gls / CTA_MAX_BLACKLIST_ITEMS ) then tpage = tpage + 1; end
        CTA_GreyListFramePageLabel:SetText( CTA_PAGE.." "..cpage.." / "..tpage );
        
        
        for index = 1, CTA_MAX_BLACKLIST_ITEMS do
                local item = getglobal( "CTA_GreyListItem"..index );
                if( index + CTA_PlayerListOffset <= gls  ) then 
                        local data = CTA_BlackList[ index + CTA_PlayerListOffset ];
                        getglobal( "CTA_GreyListItem"..index.."NameLabel" ):SetText( data.name );
                        local i = CTA_FindInList( data.name, CTA_SavedVariables.GreyList );
                        if( i ) then
                                getglobal( "CTA_GreyListItem"..index.."NoteLabel" ):SetTextColor( 1, 1, 1 );
                        else
                                getglobal( "CTA_GreyListItem"..index.."NoteLabel" ):SetTextColor( 1, 0, 0 );
                        end
                        getglobal( "CTA_GreyListItem"..index.."NoteLabel" ):SetText( data.note );
                        getglobal( "CTA_GreyListItem"..index.."RatingLabel" ):SetText( data.rating );
                        getglobal( "CTA_GreyListItem"..index ):Show();
                else
                        item:Hide();
                end
        end
end




--[[    CTA_ShowGreyListFrame()
                ---------------------------------------------------------------
                Show the Greylist frame
                ]]
                
function CTA_ShowGreyListFrame()
        --CTA_SearchFrame:Hide();
        --CTA_MyRaidFrame:Hide();
        --CTA_StartRaidFrame:Hide();
        CTA_SettingsFrame:Hide();
        CTA_LogFrame:Hide();
        CTA_GreyListFrame:Show();
        CTA_UpdateGreyListItems();      
end




--[[    CTA_EditGreyListItem()
                ---------------------------------------------------------------
                Shows the Edit frame for the selected Greylist item 
                ]]
                
function CTA_EditGreyListItem()
        local listItem = getglobal( this:GetName() );
        CTA_GreyListItemEditFrame.name = ( getglobal( listItem:GetName().."NameLabel" ):GetText() or "?" );
        if( not CTA_FindInList( CTA_GreyListItemEditFrame.name, CTA_SavedVariables.GreyList ) ) then
                CTA_AddPlayer( CTA_GreyListItemEditFrame.name, CTA_DEFAULT_PLAYER_NOTE, CTA_DEFAULT_STATUS, CTA_DEFAULT_RATING, CTA_SavedVariables.GreyList );
        end
        CTA_GreyListItemEditFrameEditBox:SetText( CTA_SavedVariables.GreyList[ CTA_FindInList( CTA_GreyListItemEditFrame.name, CTA_SavedVariables.GreyList ) ].note );
        CTA_GreyListItemEditFrameTitleLabel:SetText( CTA_EDIT_PLAYER..": "..CTA_GreyListItemEditFrame.name );
        CTA_GreyListItemEditFrame:Show();
end




--[[    CTA_GreyListItemSaveChanges()
                ---------------------------------------------------------------
                Commits changes made to the selected Greylist item 
                ]]
                
function CTA_GreyListItemSaveChanges()
        CTA_SavedVariables.GreyList[CTA_FindInList( CTA_GreyListItemEditFrame.name, CTA_SavedVariables.GreyList )].note = CTA_GreyListItemEditFrameEditBox:GetText();
        CTA_BlackList[CTA_FindInList( CTA_GreyListItemEditFrame.name, CTA_BlackList )].note = CTA_GreyListItemEditFrameEditBox:GetText();
        
        CTA_GreyListItemEditFrame:Hide();
        CTA_ShowGreyListFrame();
end




--[[    CTA_DeletePlayer()
                ---------------------------------------------------------------
                Removes the player from the Greylist
                ]]
                
function CTA_DeletePlayer()
        table.remove( CTA_BlackList , CTA_FindInList( CTA_GreyListItemEditFrame.name, CTA_BlackList ) );
        table.remove( CTA_SavedVariables.GreyList , CTA_FindInList( CTA_GreyListItemEditFrame.name, CTA_SavedVariables.GreyList ) );
        CTA_GreyListItemEditFrame:Hide();
        CTA_ShowGreyListFrame();
end




--[[    
function CTA_ImportFriendsToGreyList()
        numFriends = GetNumFriends();
        for i=1,numFriends do
                local name, level, class, area, connected = GetFriendInfo(i);
                if( not CTA_SavedVariables.GreyList[name] ) then
                        CTA_AddPlayer( name, CTA_DEFAULT_PLAYER_NOTE, CTA_DEFAULT_STATUS, CTA_DEFAULT_RATING, CTA_SavedVariables.GreyList );
                end
        end             
end
]]




--[[    CTA_ImportIgnoreListToGreyList()
                ---------------------------------------------------------------
                Adds players from the ignore list to the Greylist
                ]]
                
function CTA_ImportIgnoreListToGreyList()
        local numIgnores = GetNumIgnores();
        for i = 1, numIgnores do
                local name = GetIgnoreName(i);
                CTA_AddPlayer( name, CTA_DEFAULT_IMPORTED_IGNORED_PLAYER_NOTE, CTA_DEFAULT_STATUS, CTA_DEFAULT_RATING, CTA_SavedVariables.GreyList );
                CTA_AddPlayer( name, CTA_DEFAULT_IMPORTED_IGNORED_PLAYER_NOTE, CTA_DEFAULT_STATUS, CTA_DEFAULT_RATING, CTA_BlackList );
        end
end





--[[    CTA_AddGreyToBlack()
                ---------------------------------------------------------------
                Updates the Blacklist by adding Greylist entries to it.
                ]]
                
function CTA_AddGreyToBlack()
        for i = 1, getn(CTA_SavedVariables.GreyList) do
                CTA_AddToList( CTA_SavedVariables.GreyList[i], CTA_BlackList );
        end
end





--[[    CTA_AddPlayer()
                ---------------------------------------------------------------
                Adds a new player to the Greylist.
                @arg the name of the player 
                @arg the note to be added 
                @arg the status of the player 
                @arg the rating of the player 
                @arg the list in which to enter the data
                ]]
                
function CTA_AddPlayer( name, note, status, rating, list )
        local data = { name=name, note=note, status=status, rating=rating };
        CTA_AddToList( data, list );
        CTA_UpdateGreyListItems();
end


--[[    CTA_AddToList()
                ---------------------------------------------------------------
                Add data to list only if the name is not already in the List
                @arg the data to be added
                @arg the list in which to enter the data
                ]]

function CTA_AddToList( data, list )
        if( not CTA_FindInList( data.name, list ) ) then
                table.insert( list, data ); 
        end
end




--[[    CTA_FindInList()
                ---------------------------------------------------------------
                Returns the index of the data which has a name field that
                matches the name provided
                @arg the name to search for
                @arg the list in which to search for the data
                @return index if found, nil if not found
                ]]
                
function CTA_FindInList( name, list )
        for i = 1, getn(list) do
                if( list[i].name == name ) then
                        return i;
                end
        end
        return nil;
end

























































--[[    ---------------------------------------------------------------
                Generic Functions Driven Directly By User Interface Events
                ---------------------------------------------------------------
                ]]
        
        

        
--[[    CTA_ToggleMainFrame()
                ---------------------------------------------------------------
                Show/hide the Main Frame. If the search frame is visible
                and the main frame is opened the results list is automatically
                refreshed.  
                Called by the minimap icon and the main frame's close button. 
                ]]
                
function CTA_ToggleMainFrame()
        PlaySound("igCharacterInfoTab");
        if( CTA_MainFrame:IsVisible() ) then
                CTA_MainFrame:Hide();
        else
                CTA_MainFrame:Show();
                --[[if( CTA_SearchFrame:IsVisible() ) then
                        CTA_ApplyFiltersToGroupList();
                end     ]]      
        end
end




--[[    CTA_Tab_OnCLick()
                ---------------------------------------------------------------
                Switches visibility of the frames in the main frame.
                Called by all tab buttons under the main frame. 
                ]]

function CTA_Tab_OnCLick()
        PlaySound("igCharacterInfoTab");
        CTA_SearchFrame:Hide();
        CTA_StartRaidFrame:Hide();
        CTA_MyRaidFrame:Hide();
        --CTA_SettingsFrame:Hide();
        --CTA_GreyListFrame:Hide();
        --CTA_LogFrame:Hide();
        CTA_MoreFeaturesFrame:Hide();
        CTA_CannotLFGFrame:Hide();
        
        CTA_LFGFrame:Hide(); -- r7
        
        
        CTA_ShowSearchButton:SetFrameLevel(CTA_MainFrame:GetFrameLevel() - 1);  
        CTA_ShowMyRaidButton:SetFrameLevel(CTA_MainFrame:GetFrameLevel() - 1);  
        --CTA_ShowPlayerListButton:SetFrameLevel(CTA_MainFrame:GetFrameLevel() - 1);    
        --CTA_ShowSettingsButton:SetFrameLevel(CTA_MainFrame:GetFrameLevel() - 1);      
        --CTA_ShowLogButton:SetFrameLevel(CTA_MainFrame:GetFrameLevel() - 1);   
        
        CTA_ShowLFGButton:SetFrameLevel(CTA_MainFrame:GetFrameLevel() - 1);     -- r7
        CTA_ShowMFFButton:SetFrameLevel(CTA_MainFrame:GetFrameLevel() - 1);     
        
        this:SetFrameLevel(CTA_MainFrame:GetFrameLevel() + 1);  
        
        if( this:GetName() == "CTA_ShowSearchButton" ) then
                CTA_SearchFrame:Show(); 
                --[[CTA_ApplyFiltersToGroupList();]]
        elseif( this:GetName() == "CTA_ShowMyRaidButton" ) then
                CTA_ShowStartRaidFrame();
        elseif( this:GetName() == "CTA_ShowPlayerListButton" ) then
                CTA_ShowGreyListFrame();
        elseif( this:GetName() == "CTA_ShowSettingsButton" ) then
                CTA_SettingsFrame:Show();
        elseif( this:GetName() == "CTA_ShowLogButton" ) then
                CTA_LogFrame:Show();
        elseif( this:GetName() == "CTA_ShowLFGButton" ) then
                CTA_ShowLFGFrame();
        elseif( this:GetName() == "CTA_ShowMFFButton" ) then
                CTA_MoreFeaturesFrame:Show();
        end
end




--[[    CTA_DialogOKButton_OnCLick()
                ---------------------------------------------------------------
                Handles all 'Ok button' events generated by dialogs. 
                ]]

function CTA_DialogOKButton_OnCLick()
        local item = this:GetParent();
        if( item:GetName() == "CTA_AddPlayerFrame" ) then
                local name = CTA_AddPlayerFrameEditBox:GetText();
                if( name and name ~= "" ) then
                        CTA_AddPlayer( name, CTA_DEFAULT_PLAYER_NOTE, CTA_DEFAULT_STATUS, CTA_DEFAULT_RATING, CTA_SavedVariables.GreyList );
                        CTA_AddPlayer( name, CTA_DEFAULT_PLAYER_NOTE, CTA_DEFAULT_STATUS, CTA_DEFAULT_RATING, CTA_BlackList );
                end
                CTA_AddPlayerFrame:Hide();
        end
        
        if( item:GetName() == "CTA_JoinRaidWindow" ) then
                CTA_SendPasswordRaidInvitationRequest();
        end     
        
        if( item:GetName() == "CTA_AcidEditDialog" ) then
                CTA_EditAcidItem();
        end     

end




--[[    CTA_UpdateMinimapIcon()
                ---------------------------------------------------------------
                Adjusts the minimap icon position. 
                ]]

function CTA_UpdateMinimapIcon()
        CTA_MinimapIcon:SetPoint( "TOPLEFT", "Minimap", "TOPLEFT",
                55 - ( ( CTA_SavedVariables.MinimapRadiusOffset ) * cos( CTA_SavedVariables.MinimapArcOffset ) ),
                ( ( CTA_SavedVariables.MinimapRadiusOffset ) * sin( CTA_SavedVariables.MinimapArcOffset ) ) - 55
        );
        CTA_MinimapMessageFrame:SetPoint( "TOPRIGHT", "Minimap", "TOPRIGHT",
                ( 0 - ( ( CTA_SavedVariables.MinimapMsgRadiusOffset ) * cos( CTA_SavedVariables.MinimapMsgArcOffset ) ) ) - 55,
                ( ( CTA_SavedVariables.MinimapMsgRadiusOffset ) * sin (CTA_SavedVariables.MinimapMsgArcOffset ) ) - 55
        );

end




--[[    ---------------------------------------------------------------
                Utility Functions       
                --------------------------------------------------------------- 
                ]]


-- Other Functions --

--      Searches a specified String (source) for a keyword String (search)
--      String patterns are not allowed - simple search keywords are used
--      Returns a number representing the degree to which the search string 
--      was found in the specified string using my own scoring system.
--      Number ( 0 - 100 )
--
function CTA_SearchScore( source, search, show )
        local ad = string.lower( source );
        local query = string.lower( search );
                
        if( string.find( ad, query ) ) then
                return 100, "|cff33ff33"..source.."|r";
        else
                local sourceWords = {};
                for word in string.gfind( ad, "%w+" ) do
                        sourceWords[word] = word;
                end
                
                local highlighted = source;     
                                
                local score = 0;
                local total = 0;
                for word in string.gfind(query, "%w+") do
                        total = total + 1;
                        if( sourceWords[word] ) then
                                score = score + 1;
                                
                                if( show ) then
                                        local s, e = string.find( string.lower( highlighted ), word );
                                        highlighted = string.sub( highlighted, 1, s-1 ).."|cff99ff33"..string.sub( highlighted, s, e ).."|r"..string.sub( highlighted, e+1 );
                                end
                        elseif( string.find( ad, word ) ) then
                                score = score + 0.9;
                                
                                if( show ) then
                                        local s, e = string.find( string.lower( highlighted ), word );
                                        highlighted = string.sub( highlighted, 1, s-1 ).."|cffccff33"..string.sub( highlighted, s, e ).."|r"..string.sub( highlighted, e+1 );
                                end
                        end
                end
                
                if( score > 0 ) then 
                        score = floor(99*score/total);  
                end
                
                return score, highlighted;
        end
end


--      Returns a String representation of the current time
--      String ( eg. "14:40" )
function CTA_GetTime()
        local hour, minute = GetGameTime();
        local t = hour;
        if( hour < 10 ) then t = "0"..t; end
        t = t..":";
        if( minute < 10 ) then t = t.."0"; end
        t = t..minute;
        return t;
end


--      Returns a String from the specified textfield (uiVal)
--      If the String is Nil, then (defaultVal) is returned
--      String / defaultVal
--
function CTA_SafeSet( uiVal, defaultVal )
        if( not uiVal or uiVal=="" ) then 
                return defaultVal;
        else
                return uiVal;
        end
end


--      Returns the number entered into the textfield (uiValue),
--      if the number is valid, is no less than (min) and is no more then (max)
--      Number / Nil
--
function CTA_SafeSetNumber( uiValue, min, max )
        for value in string.gfind( uiValue, "(%d+)" ) do 
                if( value and value ~= "" and tonumber(value) >=min and tonumber(value) <= max ) then
                        return tonumber(value);
                end
        end
        return nil;
end


--      Shows an error dialog with a title, text and close button
--
function CTA_ShowError( title, text )
    CTA_InformationDialogHeadingLabel:SetText( title );
    CTA_InformationDialogContentLabel:SetText( text );
        CTA_InformationDialog:Show();
end


--      Returns the class code for this player.
--      Number ( 1 - 8 )
--
function CTA_MyClassCode()
        local myClass = UnitClass(CTA_PLAYER);
        return CTA_GetClassCode(myClass);
end


--      Returns a String representaion of a class code
--      String ( eg. "Priest" )
--
function CTA_GetClassCode( name )
        local classes = { };
        classes[CTA_PRIEST] = 1;
        classes[CTA_MAGE] = 2;
        classes[CTA_WARLOCK] = 3;
        classes[CTA_DRUID] = 4;
        classes[CTA_HUNTER] = 5;
        classes[CTA_ROGUE] = 6;
        classes[CTA_WARRIOR] = 7;
        classes[CTA_PALADIN] = 8;
        classes[CTA_SHAMAN] = 8;

        return classes[name];
end


--      Returns whether the class code (value) is in a class set (classSet)
--      Number ( 1 / 0 )
--
function CTA_CheckClasses( classSet, value )
        local b = "";
        local c = classSet;

        while( c > 0 ) do
                local d = mod(c, 2);
                b = d..b;
                c = floor(c/2);
        end
        while(string.len(b) < 8 ) do
                b = "0"..b;
        end
        
        return tonumber( string.sub(b, 9-value, 9-value ) );
end


--      Returns a String with all the class names represented by the class set
--      String ( eg. "Priest Druid Warlock" )
--
function CTA_GetClassString( classSet )
        local b = "";
        local c = classSet;
        
        local classes = { };
        classes[1] = CTA_PRIEST;
        classes[2] = CTA_MAGE;
        classes[3] = CTA_WARLOCK;
        classes[4] = CTA_DRUID;
        classes[5] = CTA_HUNTER;
        classes[6] = CTA_ROGUE;
        classes[7] = CTA_WARRIOR;
        if( UnitFactionGroup(CTA_PLAYER) == CTA_ALLIANCE ) then
                classes[8] = CTA_PALADIN;
        else
                classes[8] = CTA_SHAMAN;
        end                             
        
        while( c > 0 ) do
                local d = mod(c, 2);
                b = d..b;
                c = floor(c/2);
        end
        while(string.len(b) < 8 ) do
                b = "0"..b;
        end
        
        local pos = 8;
        local t = "";
        while( pos > 0 ) do
                if( string.sub(b, pos, pos) == "1" ) then       
                        t = t..classes[9-pos].." ";
                end
                pos = pos - 1;
        end
        return t;
end


--      Generic Tooltip Function
--
function CTA_ShowTooltip()
        if( CTA_GenTooltips[this:GetName()] ) then
                GameTooltip:SetOwner( getglobal(this:GetName()), "ANCHOR_TOP" );
                GameTooltip:ClearLines();
                GameTooltip:ClearAllPoints();
                GameTooltip:SetPoint("TOPLEFT", this:GetName(), "BOTTOMLEFT", 0, -2);           
                GameTooltip:AddLine( CTA_GenTooltips[this:GetName()].tooltip1 );
                GameTooltip:AddLine( CTA_GenTooltips[this:GetName()].tooltip2, 1, 1, 1, 1, 1 );
                GameTooltip:Show();
        end
end




--[[    ---------------------------------------------------------------
                DEBUG / PROVING GROUNDS
                ---------------------------------------------------------------
                ]]
                
function CTA_Error( s )
        UIErrorsFrame:AddMessage(s, 0.75, 0.75, 1.0, 1.0, UIERRORS_HOLD_TIME);
end

function CTA_Println( s )
        local m = s;
        if( not m ) then
                m = "nil";
        end

        if( DEFAULT_CHAT_FRAME ) then
                DEFAULT_CHAT_FRAME:AddMessage( "CTA: "..m, 1, 1, 0.5);
        end             
end

function CTA_IconMsg( s, t )
        local m = s;
        if( not m ) then
                m = "nil";
        end
        
        if( not t ) then
                CTA_MinimapMessageFrame:AddMessage(m, 1.0, 1.0, 0.5, 1.0, UIERRORS_HOLD_TIME);
        else
                local r = CTA_MESSAGE_COLOURS[t].r;
                local g = CTA_MESSAGE_COLOURS[t].g;
                local b = CTA_MESSAGE_COLOURS[t].b;

                CTA_MinimapMessageFrame:AddMessage(m, r, g, b, 1.0, UIERRORS_HOLD_TIME);
        end
end

function CTA_LogMsg( s, t )
        local m = s;
        if( not m ) then
                m = "nil";
        end
        m = "["..CTA_GetTime().."] "..m;
        
        
        if( not t ) then
                CTA_Log:AddMessage( m, 1.0, 1.0, 0.5 ); 
        else
                local r = CTA_MESSAGE_COLOURS[t].r;
                local g = CTA_MESSAGE_COLOURS[t].g;
                local b = CTA_MESSAGE_COLOURS[t].b;

                CTA_Log:AddMessage( m, r, g, b );       
        end
end


        
        
                
                
                
-- R7




function SachaSearch( source, search ) 
        if( not ( source and search ) ) then
                return nil;
        end
        
        local s = trim( search );
        local operator, op1, op2 = getOps( s );
        
        if( operator ) then
                local op1Res = SachaSearch( source, op1 );              
                if( not op1Res ) then
                        return 0;
                elseif( op1Res > 0 and operator == "/" ) then
                        return 1;
                elseif( op1Res == 0 and operator == "+" ) then
                        return 0;
                end
                
                local op2Res = SachaSearch( source, op2, verbose );
                if( not op2Res ) then
                        return 0;
                elseif( op2Res > 0 and ( op1Res > 0 or operator == "/" ) ) then
                        return 1;
                end
                return 0;
        else
                local literal;                  
                if( string.sub( s, 1, 1 ) == "-" ) then
                        return( 1 - SachaSearch( source, trim( string.sub( s, 2 ) ) ) );
                elseif( string.sub( s, 1, 1 ) == "(" and string.sub( s, string.len( s ) ) == ")" ) then
                        return SachaSearch( source, trim( string.sub( s, 2, string.len( s ) - 1 ) ) );
                elseif( string.sub( s, 1, 1 ) == "\"" and string.sub( s, string.len( s ) ) == "\"" ) then
                        s = trim( string.sub( s, 2, string.len( s ) - 1 ) );
                        literal = 1;
                end
                
                if( literal ) then
                        if( string.find( source, s ) ) then
                                return 1;
                        else
                                return 0;
                        end
                else
                        if( SachaScoredSearch( source, s ) > 0 ) then
                                return 1;
                        else
                                return 0;
                        end
                end
        end
end

function trim(s)
        if( not s ) then return nil; end
        return( string.gsub(s, "^%s*(.-)%s*$", "%1") or s );
end

function getOps( source )
        local operatorFound = nil;
        local bracketCount = 0;
        local inQuote = 0;
        local pos = 0;
        
        local currentChar;
        while( pos < string.len( source ) ) do
                currentChar = string.sub( source, pos, pos );
                if( ( currentChar == "+" or currentChar == "/" ) and bracketCount == 0 and inQuote == 0 ) then
                        operatorFound = 1;
                        break;
                elseif( currentChar == "(" ) then
                        bracketCount = bracketCount + 1;
                elseif( currentChar == ")" ) then
                        bracketCount = bracketCount - 1;
                elseif( currentChar == "\"" ) then
                        inQuote = 1 - inQuote;
                end
                pos = pos + 1;
        end
        
        if( operatorFound ) then        
                return currentChar, string.sub( source, 1, pos - 1 ), string.sub( source, pos + 1 );
        end
end


function SachaScoredSearch( source, search )
        local ad = string.lower( source );
        local query = string.lower( search );
                
        if( string.find( ad, query ) ) then
                return 100;
        else
                local score = 0;
                local total = 0;
                for word in string.gfind(query, "%w+") do
                        total = total + 1;
                        if( string.find( ad, "%s+"..word.."%s+" ) ) then
                                score = score + 1;
                        elseif( string.find( ad, word ) ) then
                                score = score + 0.9;
                        end
                end
                
                if( score > 0 and total > 0 ) then 
                        score = floor(99*score/total);  
                end
                
                return score;
        end
end



function CTA_GetGroupClassesCode()
        local groupClasses = {};
        groupClasses[1] = 0;
        groupClasses[2] = 0;
        groupClasses[3] = 0;
        groupClasses[4] = 0;
        groupClasses[5] = 0;
        groupClasses[6] = 0;
        groupClasses[7] = 0;
        groupClasses[8] = 0;
        
        local name, level, class;
        for num = 1, 40 do
                name, level, class = CTA_GetGroupMemberInfo( num );
                if( name == nil ) then break; end
                groupClasses[ CTA_GetClassCode(class) ] = groupClasses[ CTA_GetClassCode(class) ] + 1;
        end     

        local retVal = "";
        for num = 1, 8 do
                retVal = retVal..groupClasses[ num ]..",";
        end     
        return retVal;
end

function CTA_DecodeGroupClasses( code )
        if( not code or code == 0 ) then
                return;
        end
        
        local classes = { };
        classes[1] = CTA_PRIEST;
        classes[2] = CTA_MAGE;
        classes[3] = CTA_WARLOCK;
        classes[4] = CTA_DRUID;
        classes[5] = CTA_HUNTER;
        classes[6] = CTA_ROGUE;
        classes[7] = CTA_WARRIOR;
        if( UnitFactionGroup(CTA_PLAYER) == CTA_ALLIANCE ) then
                classes[8] = CTA_PALADIN;
        else
                classes[8] = CTA_SHAMAN;
        end                     
        
        --local retVal;
        local retVal2;
        
        for priest, mage, warlock, druid, hunter, rogue, warrior, hybrid, version, extra in string.gfind( code, "(%d+),(%d+),(%d+),(%d+),(%d+),(%d+),(%d+),(%d+),(.+),(.+)" ) do
                --[[                                                                                                                               
                                                                                                                                                           ^extra reserved for any future releases 
                                                                                                                                                           
                        NB: I might need it to implement the max level req for groups.
                        
                                                                                                                                                           
                ]]

                classes[1] = priest;
                classes[2] = mage;
                classes[3] = warlock;
                classes[4] = druid;
                classes[5] = hunter;
                classes[6] = rogue;
                classes[7] = warrior;
                classes[8] = hybrid;
                
                retVal2 = version;

        end
        
        return classes, retVal2;
end




function CTA_SearchDropDown_OnClick()
        UIDropDownMenu_SetSelectedID(CTA_SearchDropDown, this:GetID());
end

function CTA_SearchDropDown_Init()
        local info = {};
        info.text = CTA_SHOW_PLAYERS_AND_GROUPS;
        info.func = CTA_SearchDropDown_OnClick;
        UIDropDownMenu_AddButton(info);

        info = {};
        info.text = CTA_SHOW_GROUPS_ONLY;
        info.func = CTA_SearchDropDown_OnClick;
        UIDropDownMenu_AddButton(info);

        info = {};
        info.text = CTA_SHOW_PLAYERS_ONLY;
        info.func = CTA_SearchDropDown_OnClick;
        UIDropDownMenu_AddButton(info);
end


function CTA_UpdateLFxButtonButton_OnClick()

        local text = CTA_SearchFrameLFGTriggerEditBox:GetText() or "";
        local ok = 1;
        for word in string.gfind(text, "%w+") do
                if( strlen( word ) < 3 ) then
                        ok = nil;
                        break;
                end
        end
        if( ok ) then
                local spos = string.find( text, CTA_DEFAULT_LFG_TRIGGER ) or 0;
                if( spos <= 0 ) then
                        CTA_SavedVariables.lfgTrigger = CTA_DEFAULT_LFG_TRIGGER.." "..text;
                else
                        CTA_SavedVariables.lfgTrigger = text;
                end
        end
        CTA_SearchFrameLFGTriggerEditBox:SetText( CTA_SavedVariables.lfgTrigger );
        
        text = CTA_SearchFrameLFMTriggerEditBox:GetText() or "";
        local ok = 1;
        for word in string.gfind(text, "%w+") do
                if( strlen( word ) < 3 ) then
                        ok = nil;
                        break;
                end
        end
        if( ok ) then
                local spos = string.find( text, CTA_DEFAULT_LFM_TRIGGER ) or 0;
                if( spos <= 0 ) then
                        CTA_SavedVariables.lfmTrigger = CTA_DEFAULT_LFM_TRIGGER.." "..text;
                else
                        CTA_SavedVariables.lfmTrigger = text;
                end
        end
        CTA_SearchFrameLFMTriggerEditBox:SetText( CTA_SavedVariables.lfmTrigger );

end

-- fix
function CTA_UpdateLFxButtonButton_OnClick()

        local text = CTA_SearchFrameLFGTriggerEditBox:GetText() or "";
        local ok = 1;
        for word in string.gfind(text, ".+") do
                if( string.sub( word, 1, 1 ) == "\"" and string.sub( word, string.len( word ) ) == "\"" ) then
                        if( strlen( word ) < 6 ) then
                                ok = nil;
                                break;
                        end
                else
                        if( strlen( word ) < 3 ) then
                                ok = nil;
                                break;
                        end
                end
        end
        if( ok ) then
                CTA_SavedVariables.lfgTrigger = text;
                CTA_SearchFrameLFGTriggerEditBox:SetText( CTA_SavedVariables.lfgTrigger );
        end
        text = CTA_SearchFrameLFMTriggerEditBox:GetText();
        local ok = 1;
        for word in string.gfind(text, ".+") do
                if( string.sub( word, 1, 1 ) == "\"" and string.sub( word, string.len( word ) ) == "\"" ) then
                        if( strlen( word ) < 6 ) then
                                ok = nil;
                                break;
                        end
                else
                        if( strlen( word ) < 3 ) then
                                ok = nil;
                                break;
                        end
                end
        end
        if( ok ) then
                CTA_SavedVariables.lfmTrigger = text;
                CTA_SearchFrameLFMTriggerEditBox:SetText( CTA_SavedVariables.lfmTrigger );
        end
end


function CTA_ShowLFGFrame()
        if ( CTA_GetNumGroupMembers() > 1  ) then
                CTA_CannotLFGFrame:Show();
                CTA_LFGFrame:Hide();
        else
                CTA_CannotLFGFrame:Hide();
                CTA_LGMPrefixLabel:SetText( "Level "..UnitLevel( CTA_PLAYER ).." "..UnitClass( CTA_PLAYER ).." "..CTA_LFG.." " );
                CTA_LFGFrame:Show();
        end
end


function CTA_InitClassTable()
        CTA_Classes[1] = CTA_PRIEST;
        CTA_Classes[2] = CTA_MAGE;
        CTA_Classes[3] = CTA_WARLOCK;
        CTA_Classes[4] = CTA_DRUID;
        CTA_Classes[5] = CTA_HUNTER;
        CTA_Classes[6] = CTA_ROGUE;
        CTA_Classes[7] = CTA_WARRIOR;
        if( UnitFactionGroup(CTA_PLAYER) == CTA_ALLIANCE ) then
                CTA_Classes[8] = CTA_PALADIN;
        else
                CTA_Classes[8] = CTA_SHAMAN;
        end                     
        CTA_Classes[CTA_PRIEST]         = 1;
        CTA_Classes[CTA_MAGE]           = 2;
        CTA_Classes[CTA_WARLOCK]        = 3;
        CTA_Classes[CTA_DRUID]          = 4;
        CTA_Classes[CTA_HUNTER]         = 5;
        CTA_Classes[CTA_ROGUE]          = 6;
        CTA_Classes[CTA_WARRIOR]        = 7;
        CTA_Classes[CTA_PALADIN]        = 8;
        CTA_Classes[CTA_SHAMAN]         = 8;    
end


function CTA_PlayerClassDropDown_Init()
        if( not CTA_Classes[i] ) then
                CTA_InitClassTable();
        end

        local info = {};
        info.text = CTA_ANY_CLASS;
        info.func = CTA_PlayerClassDropDown_OnClick;
        UIDropDownMenu_AddButton(info);
        
        for i=1, 8 do
                info = {};
                info.text = CTA_Classes[i];
                info.func = CTA_PlayerClassDropDown_OnClick;
                UIDropDownMenu_AddButton(info);
        end
end

function CTA_PlayerClassDropDown_OnClick()
        UIDropDownMenu_SetSelectedID(CTA_PlayerClassDropDown, this:GetID());
end




--[[



function CTA_InitLinks()

        local old_SetItemRef = SetItemRef;
        function SetItemRef(link, text, button)
                for name, msg in string.gfind( link, "xhmsg:(%w+)<XH>(.+)" ) do         
                
                        if( ItemRefTooltip:IsVisible() and lastName and lastName == name ) then                         
                
                                HideUIPanel(ItemRefTooltip);
                                --ItemRefTooltip:Hide();
                                lastName = nil;
                        
                        else
                                lastName = name;

                                ShowUIPanel(ItemRefTooltip);
                                if ( not ItemRefTooltip:IsVisible() ) then
                                        ItemRefTooltip:SetOwner(UIParent, "ANCHOR_PRESERVE");
                                end                             

                                ItemRefTooltip:ClearLines();
                                --ItemRefTooltip:ClearAllPoints();

                                if( name == "eas" and msg == "eas" ) then
                                
                                        ItemRefTooltip:AddLine( EAS_NOTE[1], 1, 0.5, 0 );
                                        ItemRefTooltip:AddLine( EAS_NOTE[2], 1, 1, 1, 1, 1 );
                                        ItemRefTooltip:AddLine( EAS_NOTE[3] );
                                
                                else
                                        ItemRefTooltip:AddLine( "Message", 0.5, 0.5, 1 );
                                        ItemRefTooltip:AddLine( name );
                                        ItemRefTooltip:AddLine( msg, 1, 1, 1, 1, 1 );
                                end
                                ItemRefTooltip:Show();
                                
                                --
                                --ShowUIPanel(ItemRefTooltip);
                                --if ( not ItemRefTooltip:IsVisible() ) then
                                --      ItemRefTooltip:SetOwner(UIParent, "ANCHOR_PRESERVE");
                                --end                           
                                
                        end
                        
                        return;
                end
                
                lastName = nil;
                old_SetItemRef(link, text, button);
        end
        
        
        local old_ChatFrame_OnEvent = ChatFrame_OnEvent;
        function ChatFrame_OnEvent(event)
                if( string.find( event, "CHAT_MSG" ) and arg1 and arg2 and string.len(arg1) > 16 ) then
                        local argl = string.lower(arg1);
                        local start; --, _ = string.find( argl, "enchanting");
                        local score = 100;
                        if( not start ) then
                                score = Sacha_LightSearch( arg1, "bracer chest boots weapon armor fiery demon slaying beast crusader" );
                                if( score > 0 and ( string.find( argl, "chant") or string.find( argl, "ench") ) ) then 
                                        start = 1;
                                end
                        end
                        
                        if( start and Sacha_LightSearch( arg1, "trainer thorium item:" ) == 0 ) then
                                arg1 = "|cff8888ff|Hxhmsg:"..arg2.."<XH>"..arg1.."|h[Enchantments]|h|r"; 
                                if( string.find(argl, "wts") ) then
                                        arg1 = "WTS "..arg1;
                                elseif( string.find(argl, "wtb") ) then
                                        arg1 = "WTB "..arg1;
                                else
                                        arg1 = "Regarding "..arg1;
                                end 
                        end
                end
                old_ChatFrame_OnEvent(event);
        end
        
        ChatPrintln( "|cffff8800|Hxhmsg:eas<XH>eas|h[Enchanter Ad Shrinker]|h|r loaded." );


end
]]

Generated by GNU Enscript 1.6.5.90.