vanilla-wow-addons – Rev 1

Subversion Repositories:
Rev:
if AceChatCmd then
        PerfectRaid.AceChatCmd = AceChatCmd
else
        local AceChatCmd = {}
        PerfectRaid.AceChatCmd = AceChatCmd
        
        local Ace = {}
        
        function Ace:print(...)
                local r,g,b,frame,delay
                if( type(arg[1]) == "table" ) then
                        r,g,b,frame,delay = unpack(tremove(arg,1))
                end
                (frame or DEFAULT_CHAT_FRAME):AddMessage(self.concat(arg),r,g,b,1,delay or 5)
        end
        
        function Ace.ParseWords(str, pat)
                if( Ace.tostr(str) == "" ) then return {} end
                local list = {}
                for word in gfind(str, pat or "%S+") do
                        tinsert(list, word)
                end
                return list
        end
        
        local ACE_CMD = {}
        ACE_CMD.OPT_HELP                        = "?"
        ACE_CMD.OPT_HELP_DESC           = "Display extra information about this addon."
        ACE_CMD.OPT_STANDBY                     = "standby"
        ACE_CMD.OPT_STANDBY_DESC        = "Toggle the addon's standby mode."
        ACE_CMD.OPT_REPORT                      = "report"
        ACE_CMD.OPT_REPORT_DESC         = "Display the status of all settings."
        ACE_CMD.OPT_INVALID                     = "Invalid option '%s' entered."
        ACE_CMD.OPT_LIST_ADDONS         = "Addon List"
        ACE_CMD.OPT_LOAD_IS_LOADED      = "%s is already loaded."
        ACE_CMD.OPT_LOAD_ERROR          = "%s could not be loaded because it is %s."
        ACE_CMD.OPT_LOAD_LOADED         = "%s is now loaded."
        ACE_CMD.OPT_AUTO_OFF_MSG        = "%s will no longer be loaded on demand at game start."
        ACE_CMD.ERROR                           = "|cffff6060[error]|r"
        
        ACE_CMD.ADDON_NOTFOUND          = "No addon named '%s' was found."
        ACE_CMD.ADDON_ENABLED           = "%s has been enabled. You must reload the game to load this addon."
        ACE_CMD.ADDON_ENABLED_ALL       = "All addons have been enabled. You must reload the game to load "..
                                                                  "previously unloaded addons."
        ACE_CMD.ADDON_DISABLED          = "%s has been disabled but will remain loaded until you reload the game."
        ACE_CMD.ADDON_DISABLED_ALL      = "All addons except Ace itself have been disabled but will remain loaded "..
                                                                  "until you reload the game."
        
        ACE_CMD.PROFILE_ADDON_ADDED = "%s has been added. Active profile: %s."
        ACE_CMD.PROFILE_ALL_ADDED       = "All addons have been added. Active profile: %s."
        ACE_CMD.PROFILE_ALL                     = "all"
        ACE_CMD.PROFILE_NO_PROFILE      = "%s has no profiling options available."
        
        ACE_CMD.USAGE_ADDON_DESC        = "|cffffff78[%s v%s]|r : %s"
        ACE_CMD.USAGE_HEADER            = "|cffffff78Usage:|r |cffd8c7ff%s|r %s"
        ACE_CMD.USAGE_OPT_DESC          = " - |cffffff78%s:|r %s"
        ACE_CMD.USAGE_OPT_SEP           = " | "
        ACE_CMD.USAGE_OPT_OPEN          = "["
        ACE_CMD.USAGE_OPT_CLOSE         = "]"
        ACE_CMD.USAGE_OPTION            = "|cffd8c7ff%s %s|r %s"
        ACE_CMD.USAGE_NOINFO            = "No further information"
        
        ACE_CMD.RESULT                          = "|cffffff78%s:|r %s"
        
        ACE_CMD.REPORT_STATUS           = "Status"
        ACE_CMD.REPORT_LINE                     = "%s [|cfff5f530%s|r]"
        ACE_CMD.REPORT_LINE_PRE         = " - "
        ACE_CMD.REPORT_LINE_INDENT      = "   "
        
        ACE_CMD.REPORT_NO_VAL           = "|cffc7c7c7no value|r"
        
        
        -- Recursively iterate through the table and sub-tables until the entire table
        -- structure is copied over. Note: I used to check whether the table was numerically
        -- indexed and use two different for() loops, one with ipairs() and one without. I
        -- did this because there seemed to be problems otherwise, but in rewriting this, I
        -- haven't encountered any problems.
        function Ace.CopyTable(into, from)
                for key, val in from do
                        if( type(val) == "table" ) then
                                if( not into[key] ) then into[key] = {} end
                                Ace.CopyTable(into[key], val)
                        else
                                into[key] = val
                        end
                end
                
                if (getn(from)) then
                        table.setn(into, getn(from))            
                end
        
                return into
        end
        
        function Ace.GetTableKeys(tbl)
                local t = {}
                for key, val in pairs(tbl) do
                        tinsert(t, key)
                end
                return(t)
        end
        
        function Ace.TableFindKeyCaseless(tbl, key)
                key = strlower(key)
                for i, val in tbl do
                        if( strlower(i) == key ) then return i, val end
                end
        end
        
        function Ace.TableFindByKeyValue(tbl, key, val, caseless)
                if( not tbl ) then error("No table supplied to TableFindByKeyValue.", 2) end
                for i, t in ipairs(tbl) do
                        if( (caseless and (strlower(t[key]) == strlower(val))) or (t[key] == val) ) then
                                return i, t
                        end
                end
        end
        
        function Ace.concat(t,sep)
                local msg = ""
                if( getn(t) > 0 ) then
                        for key, val in ipairs(t) do
                                if( msg ~= "" and sep ) then msg = msg..sep end
                                msg = msg..Ace.tostr(val)
                        end
                else
                        for key, val in t do
                                if( msg ~= "" and sep ) then msg = msg..sep end
                                msg = msg..key.."="..Ace.tostr(val)
                        end
                end
                return msg
        end
        
        function Ace.round(num)
                return floor(Ace.tonum(num)+.5)
        end
        
        function Ace.sort(tbl, comp)
                sort(tbl, comp)
                return tbl
        end
        
        function Ace.strlen(str)
                return strlen(str or "")
        end
        
        function Ace.tonum(val, base)
                return tonumber((val or 0), base) or 0
        end
        
        function Ace.tostr(val)
                return tostring(val or "")
        end
        
        function Ace.toggle(val)
                if( val ) then return FALSE end
                return TRUE
        end
        
        function Ace.trim(str, opt)
                if( (not opt) or (opt=="left" ) ) then str = gsub(str, "^%s*", "") end
                if( (not opt) or (opt=="right") ) then str = gsub(str, "%s*$", "") end
                return str
        end
        
        -- Object constructor
        function AceChatCmd:new(commands,options)
                self.__index = self
                return setmetatable({_cmdList=commands,options=options}, self)
        end
        
        --[[---------------------------------------------------------------------------------
          Reporting Methods
        ------------------------------------------------------------------------------------]]
        
        function AceChatCmd:result(...)
                Ace:print(self.app.disabled and ACE_ADDON_STANDBY.." " or "",
                                  format(ACE_CMD.RESULT, self.app.name, Ace.concat(arg))
                                 )
        end
        
        function AceChatCmd:msg(...) self:result(format(unpack(arg))) end
        function AceChatCmd:error(...) self:result(ACE_CMD.ERROR.." ", format(unpack(arg))) end
        function AceChatCmd:status(text, val, map)
                if( map ) then val = map[val or 0] or val end
                self:result(text, " ", ACE_TEXT_NOW_SET_TO, " ",
                                        format(ACE_DISPLAY_OPTION, val or ACE_CMD.REPORT_NO_VAL)
                                   )
        end
        
        function AceChatCmd:report(hdr, def)
                if( not def ) then def = hdr; hdr = nil end
                Ace:print(hdr or format(ACE_CMD.RESULT,
                                                                self.app.name.." "..ACE_CMD.REPORT_STATUS,
                                                                self.app.disabled and ACE_ADDON_STANDBY or ""
                                                           )
                                 )
                for _, ref in ipairs(def) do
                        local val
                        if( ref.map ) then val = ref.map[ref.val or 0]
                        else val = ref.val
                        end
                        Ace:print(
                                (ref.indent
                                        and (strrep(" ", strlen(ACE_CMD.REPORT_LINE_PRE))..
                                                 strrep(ACE_CMD.REPORT_LINE_INDENT, ref.indent))
                                        or  ACE_CMD.REPORT_LINE_PRE
                                ),
                                format(ACE_CMD.REPORT_LINE, ref.text, val or ACE_CMD.REPORT_NO_VAL)
                        )
                end
        end
        
        
        --[[---------------------------------------------------------------------------------
          Command Handling Methods
        ------------------------------------------------------------------------------------]]
        
        function AceChatCmd:FindCommand(cmd)
                cmd = strlower(cmd)
                for index in SlashCmdList do
                        local i, cmdString = 0
                        repeat
                                i = i + 1
                                cmdString = getglobal("SLASH_"..index..i)
                                if( strlower(cmdString or "") == cmd ) then return TRUE end
                        until( not cmdString )
                end
        end
        
        function AceChatCmd:Register(handler)
                if( not self._cmdList ) then
                        error("Attempt to register command handler without defining commands.", 2)
                end
                if( self.registered ) then return end
        
                local slashID = strupper(self.app.name).."_CMD"
        
                SlashCmdList[slashID] = function(msg) self:ProcessCommand(msg) end
                local i = 0
                for index, cmd in self._cmdList do
                        if( not self:FindCommand(cmd) ) then
                                if( not self.commands ) then self.commands = {} end
                                i = i + 1
                                tinsert(self.commands, cmd)
                                setglobal("SLASH_"..slashID..i, cmd)
                        end
                end
        
                self.handler = handler or self
        
                if( not self.options ) then self.options = {} end
        
                if( self.handler.Report ) then
                        tinsert(self.options, 1, {
                                                                                option = ACE_CMD.OPT_REPORT,
                                                                                desc   = ACE_CMD.OPT_REPORT_DESC,
                                                                                method = "Report"
                                                                         }
                                   )
                end
        
                if( self.app.Enable ) then
                        tinsert(self.options, 1, {
                                                                                option = ACE_CMD.OPT_STANDBY,
                                                                                desc   = format(ACE_CMD.OPT_STANDBY_DESC, self.app.name),
                                                                                method = "ToggleStandBy"
                                                                         }
                                   )
                end
        
                tinsert(self.options, 1, {option = ACE_CMD.OPT_HELP, desc = ACE_CMD.OPT_HELP_DESC})
        
                -- Create a closure for printing option lines, since it's done so much
                self.printOpt   = function(l,t) Ace:print(format(ACE_CMD.USAGE_OPT_DESC,l,t)) end
                self.registered = TRUE
        end
        
        function AceChatCmd:ProcessCommand(msg)
                msg = Ace.trim(msg or "")
        
                if( strfind(strlower(msg), ACE_CMD.OPT_HELP) == 1 ) then
                        self:DisplayAddonInfo(self.options)
                        return
                elseif( msg ~= "" ) then
                        return self:ProcessOptions(self.options, msg, self.handler, self.handler.CommandHandler)
                elseif( self.handler.CommandHandler ) then
                        self.handler.CommandHandler(self.handler, msg)
                        return
                end
        
                self:DisplayUsage()
        end
        
        function AceChatCmd:ProcessOptions(list, msg, handler, method, opttext)
                local _, _, cmd = strfind(strlower(msg), "(%S+)")
                local args = gsub(msg, cmd.."%s*", "")
        
                local i = Ace.TableFindByKeyValue(list, "option", cmd, TRUE)
                if( i ) then
                        local opt = list[i]
                        if( opt.args and (args ~= "") and
                                self:ProcessOptions(opt.args,
                                                                        args,
                                                                        opt.handler or handler,
                                                                        opt.method or method,
                                                                        opttext and opttext.." "..opt.option or opt.option
                                                                   )
                        ) then
                                return TRUE
                        elseif( opt.method and ((args ~= "") or (not opt.input)) and
                                        (strlower(args) ~= ACE_CMD.OPT_HELP)
                        ) then
                                handler = opt.handler or handler
                                handler[opt.method](handler, args)
                                return TRUE
                        elseif( opt.input and (args == "") or (opt.args and (not method)) or
                                        (strlower(args) == ACE_CMD.OPT_HELP)
                        ) then
                                self:OptionHeader(opt, opttext)
                                self:DisplayArgUsage(opt)
                                return TRUE
                        end
                elseif( ((cmd or "") ~= "") and (cmd ~= ACE_CMD.OPT_HELP) and (not method) ) then
                        self:result(format(ACE_CMD.OPT_INVALID, cmd))
                        return TRUE
                end
        end
        
        
        --[[---------------------------------------------------------------------------------
          Usage Display Methods
        ------------------------------------------------------------------------------------]]
        
        function AceChatCmd:DisplayAddonInfo()
                self:CommandHeader()
                if( self.commands ) then
                        self.printOpt(ACE_TEXT_COMMANDS, Ace.concat(self.commands, " | "))
                end
                if( self.app.author ) then  self.printOpt(ACE_TEXT_AUTHOR, self.app.author) end
                if( self.app.releaseDate ) then self.printOpt(ACE_TEXT_RELEASED, self.app.releaseDate) end
                if( self.app.email ) then self.printOpt(ACE_TEXT_EMAIL, self.app.email) end
                if( self.app.website ) then self.printOpt(ACE_TEXT_WEBSITE, self.app.website) end
        end
        
        function AceChatCmd:OptionHeader(option, opttext)
                local args
                if( option.args ) then
                        args = self:ConcatOptions(option.args, ACE_CMD.USAGE_OPT_SEP)
                end
                if( not args ) then
                        args = "- "..(option.desc or ACE_CMD.USAGE_NOINFO)
                end
                Ace:print(format(ACE_CMD.USAGE_OPTION,
                                                 self.commands[1],
                                                 opttext and opttext.." "..option.option or option.option,
                                                 args
                                                )
                                 )
        end
        
        function AceChatCmd:DisplayArgUsage(option)
                if( not option.args ) then return end
                for _, arg in ipairs(option.args) do
                        self.printOpt(arg.option, arg.desc)
                end
        end
        
        function AceChatCmd:DisplayUsage()
                self:CommandHeader()
        
                if( getn(self.options) < 1 ) then return end
        
                Ace:print(format(ACE_CMD.USAGE_HEADER,
                                                 self.commands[1],
                                                 self:ConcatOptions(self.options, ACE_CMD.USAGE_OPT_SEP)
                                                )
                                 )
        
                -- Have to print the lines one at a time or risk it getting too large for the
                -- print buffer.
                for _, opt in ipairs(self.options) do
                        self.printOpt(opt.option, opt.desc)
                end
        end
        
        function AceChatCmd:CommandHeader()
                Ace:print(self.app.disabled and ACE_ADDON_STANDBY.." " or "",
                                  format(ACE_CMD.USAGE_ADDON_DESC,
                                                 self.app.name,
                                                 self.app.version,
                                                 self.app.description
                                                )
                                 )
        end
        
        function AceChatCmd:ConcatOptions(options, sep)
                local str = ""
                for _, opt in options do
                        if( (str ~= "") and sep ) then str = str..sep end
                        str = str..opt.option
                end
                return str
        end
end

Generated by GNU Enscript 1.6.5.90.