vanilla-wow-addons – Rev 1

Subversion Repositories:
Rev:
--[[
        MCom
                A set of utility functions to simplify addon creation
        
        By: Mugendai
        Contact: mugekun@gmail.com
        
        MCom provides several functions designed to lower the amount of code
        required to make an addon be configurable.  It helps to handle the
        things that need to go on to handle user input, either via console
        or via some GUI(like Cosmos or Khaos).
        
        It aims mainly at tasks that are repeated in multiple places in every addon.
        Any addon that wants to have chat commands needs a chat handler, and functions
        for each command it can accept.  It also needs functions for updating
        the variables that have to do with configuration.  Addons may also need
        wrapper functions for a GUI interface.  They may also need to have multiple
        registers to support multiple GUIs, such as Cosmos and Khaos.
        
        These things are all handled by MCom either by registering with it for such
        functions, or by calling functions that do the repetative part.
        
        $Id: MCom.lua 2641 2005-10-17 09:26:21Z mugendai $
        $Rev: 2641 $
        $LastChangedBy: mugendai $
        $Date: 2005-10-17 04:26:21 -0500 (Mon, 17 Oct 2005) $
]]--

--If we should update/declare MCom, then do so now
if (MCom_Update) then

        if (not Khaos) then
                -- Provide Khaos config keywords for MCom mods for when Khaos isn't around
                K_TEXT = "text";
                K_CHECKBOX = "text"; -- Not a typo. Checkboxes use the "text" type to describe their right-side
                K_BUTTON = "button";
                K_SLIDER = "slider";
                K_EDITBOX = "editbox";
                K_PULLDOWN = "pulldown";
                K_COLORPICKER = "colorpicker";
                K_HEADER = "separator";
        end
        
        if (not myAddOnsList) then
                MYADDONS_CATEGORY_BARS = "Bars";
                MYADDONS_CATEGORY_CHAT = "Chat";
                MYADDONS_CATEGORY_CLASS = "Class";
                MYADDONS_CATEGORY_COMBAT = "Combat";
                MYADDONS_CATEGORY_COMPILATIONS = "Compilations";
                MYADDONS_CATEGORY_GUILD = "Guild";
                MYADDONS_CATEGORY_INVENTORY = "Inventory";
                MYADDONS_CATEGORY_MAP = "Map";
                MYADDONS_CATEGORY_OTHERS = "Others";
                MYADDONS_CATEGORY_PROFESSIONS = "Professions";
                MYADDONS_CATEGORY_QUESTS = "Quests";
                MYADDONS_CATEGORY_RAID = "Raid";
        end

        --------------------------------------------------
        --
        -- Public Library Functions
        --
        --------------------------------------------------
        --[[
                registerSmart ( {reglist} )
                        A single function that can register a chat command, and a UI variable at the same time.
                        You pass only the data you need to, and it will do anything it can with that data.
                        If you pass enough data to register a UI command and callback, a slash command, a super slash command,
                        and a sub slash command, this will do all of those things.
                
                Args:
                        reglist - the table of options, some options will be listed more than once to show when they are needed, but only set them once
                                {
                                Data required to register a Cosmos or Khaos command:
                                        (string) uivar - the name of the UI variable
                                        (string) uitype - the type of UI variable
                                        (string) uilabel - the label of the UI variable
                                        
                                Data required to register a Khaos command:
                                        (string) uisec - the ID of the Khaos set to put the option in
                                        
                                Optional data for Cosmos or Khaos options:
                                        (function) func -       the function to call when this variable changes, see addSlashCommand for further details on the function
                                                                                                                if this is not passed, a generic callback will be provided for you
                                        (string) varbool - the name of the boolean variable to use in the generic setter
                                        (string) varnum - the name of the number variable to use in the generic setter
                                        (string) varstring - the name of the editbox variable to use in the generic setter
                                        (string) varchoice - the name of the pulldown variable to use in the generic setter
                                        (string) varcolor - the name of the color variable to use in the generic setter
                                        (function) update - this function will be called when using the generic setter, and the variable is updated
                                        (function) noupdate - this function will be called when using the generic setter, and the variable is not updated
                                        (function) anyupdate - this function will be called when using the generic setter, whether the variable is updated or not
                                        (boolean) hasbool - set to true if this option has a checkbox in it
                                        
                                        (table) uioption -      this can either be a table in the form of a Cosmos registration, or a KhaosOption.  If it is passed
                                                                                                                        then it will be used to pull as much data as MCom can make use of out of it.  This can allow you to
                                                                                                                        pass a Cosmos style option, that registers a Khaos option, for instance.  It also allows you to set
                                                                                                                        anything in the Khaos option that MCom doesn't have an argument for.
                                                                                                                        If this is a Khaos option, it can include an entry called mcopts, which is a table of MCom options to set
                                                                                                                        for the option
                                        (string) uisec -        the ID of the section/set to put the option in, if the section/set already exists, the option wil be
                                                                                                                added to it, if it doesn't exist, it will be created
                                        (string) uiseclabel - the name of the section/set to put the option in
                                        (string) uisecdesc - the description of the section/set to put the option in
                                                NOTE: Once passed, the uisec variables will be stored as defaults for further commands
                                        (string) uisep -        the ID of the separator/header to put the option in, if the separator/header already exists, then the
                                                                                                                option will be added after it, if it doesn't exist, it will be created
                                                NOTE: Once passed, the uisep variable will be stored as default for further commands
                                        (string) uiseplabel - the name of the separator/header to put the option in
                                        (string) uisepdesc - the description of the separator/header to put the option in
                                        (string) uidesc - the description of the UI variable
                                        (number) uicheck - the default value for a checkbox, 1 or 0
                                        (number) uislider - the default value for a slider
                                        (number) uimin - the minimum value for a slider
                                        (number) uimax - the maximum value for a slider
                                        (string) uitext - the text to show on a UI control
                                        (number) uistep - the increment to use for a slider
                                        (number) uitexton - whether to show the text for the control or not, 1 or 0
                                        (string) uisuffix - the suffix to show at the end of the slider text
                                        (number) uimul - how much to multiple the slider value by when displaying it

                                Optional data for Khaos only options:
                                        (table) uiset - this can be an entire KhaosSet, and if it is, the whole thing will be MCom registered
                                        (string) uifolder - the Khaos folder to put the option in, if you don't pass this, and uicat is passed with a compatible type, uicat will be used
                                                NOTE: Once passed, the uifolder variable will be stored as default for further commands
                                        (string) uisecdiff - the difficulty of the set to put the option in
                                        (string) uiseccall - the callback of the set to put the option in
                                        (string) uisecdef - the default of the set to put the option in
                                        (string) uiseccom - the commands list of the set to put the option in
                                                NOTE: Once passed, the uisec variables will be stored as defaults for further commands
                                        (string) uisepdiff - the difficulty of the header to put the option in
                                        (string) uisepcall - the callback of the header to put the option in
                                        (string) uisepdef - the default of the header to put the option in
                                        (string) uikey - the key to use for the option
                                        (string) uivalue - the value to use for the option
                                        (number) uidiff - the difficulty of the option
                                        { key = { value = requirement } } uidep -       A table listing what key's in a Khaos option set need to have what value set to what requirement
                                                                                                                                                                                                                for the option to be enabled
                                        (boolean) uiradio - set to true if the option has a radio control
                                        (function) uifeedback - the function to call to show feedback data
                                        (table) uisetup - the control setup structure
                                        (string) uisliderlow - the text to show on the lower potion of the slider control
                                        (string) uisliderhigh - the text to show on the higher potion of the slider control
                                        (function) uisliderfunc - the function to use to setup the text to show on the slider
                                        {       string = value, ... } choices - A list of choices and values to use when using a pulldown, string is the string shown in the pulldown
                                                                                                                                                                                and value is the value that should be associated with that string.
                                        (boolean) multichoice - set to true if more than one option can be selected in a pulldown
                                        (boolean) hasopacity - set to true if a colorpicker should also have an opacity slider
                                        (color) uicolor - the default color to use in a color picker
                                        (string/table) uichoice - the default option(s) to be selected in a pulldown
                                        (string) uistring - the default string to be set in a textbox
                                        (table) uicallon - the default string to be set in a textbox
                                        (boolean) uidischeck - the value of a checkbox when the option set is disabled
                                        (number) uidisslider - the value of a slider when the option set is disabled
                                        (color) uidiscolor - the value of a color picker when the option set is disabled
                                        (string/table) uidischoice - the value of a pulldown when the option set is disabled
                                        (string) uidisstring - the value of a text box when the option set is disabled
                                                NOTE: Disabled options will use default settings, if they are not passed or nil
                                        
                                Data required to register with myAddOns
                                        NOTE: You do not have to wait for VARIABLES_LOADED to register for myAddOns via MCom
                                                                Also, if you have set any section info for a Khaos or Cosmos section, that will be used with myAddOns
                                        (string) addonname - This must be the exact same as the title in the toc file.  Defaults to uisec.
                                                or
                                        (string) uisec -        Where to place the addon in the myAddOnsList, defaults to uiseclabel
                                                or
                                        (string) uiseclabel - The name to show in myAddOns, defaults to uisec
                                        
                                Optional data for registering with myAddOns
                                        (string) uisec -        Where to place the addon in the myAddOnsList, defaults to uiseclabel
                                        (string) uiseclabel - The name to show in myAddOns, defaults to uisec
                                        (string) uisecdesc - NO LONGER USED BY myAddOns - The description to show in myAddOns, defaults to uiseclabel
                                        (string or number) uiver - The version to show in the UI
                                        (string) uidate - The date this version of the addon was released
                                        (string) uiauthor - The name of the author of the addon
                                        (string) uiwww - The website the addon can be found at, if any
                                        (string) uimail - The email address the author can be reached at
                                        (string) uicat - The category to place the addon in, if you don't pass this, and uifolder is passed with a compatible type, uifolder will be used
                                        (string) uiframe - NO LONGER USED BY myAddOns - The name of the frame used to detect if your addon is loaded
                                        (string) uioptionsframe -       The name of the frame to show when the myAddOns options button is pressed for this Addon.  If this is not passed, and
                                                                                                                                                you are registering a Cosmos or Khaos option at the same time as this, then Cosmos or Khaos will be set as the options frame.
                                                                                                                                                This will also add the frame to UIPanelWindows
                                        ( string or {string} ) uihelp - The help text to display in myAddOns and in slash command, and Khaos help.  If it is a table, each entry is a page.

                                Data required to register a standard slash command:
                                        (string) command - the name of the slash command Ex: "/command", or {"/command", "/com"}
                                        (string) comtype -      [Required if uitype is not passed, takes precidence over uitype]
                                                                                                                        the type of data you are expecting from this slash command
                                                                                                                        MCOM_BOOLT - Expects boolean data, an on, off, 1, or 0
                                                                                                                        MCOM_NUMT - Expects a number value
                                                                                                                        MCOM_MULTIT -   Expects a boolean and then a number value, Ex: "/command on 3", this has been surplanted via simply
                                                                                                                                                                                using hasbool with MCOM_NUMT
                                                                                                                        MCOM_STRINGT - Expects any string
                                                                                                                        MCOM_COLORT - Expects a color setup, and optionally opacity
                                                                                                                        MCOM_CHOICET - Expects a choice from a list of choices, or optionaly multiple choices
                                                                                                                        MCOM_SIMPLET - No input needed, just calls the function
                                        
                                Optional data for a standard slash command, or sub command:
                                        (function) func -       the function to call when this variable changes, see addSlashCommand for further details on the function
                                                                                                                if this is not passed, a generic callback will be provided for you
                                        (boolean) hasbool - set to true if this option has a boolean portion
                                        (string) varbool - the name of the boolean variable to use in the generic setter
                                        (string) varnum - the name of the number variable to use in the generic setter
                                        (string) varstring - the name of the string variable to use in the generic setter
                                        (string) varchoice - the name of the choice variable to use in the generic setter
                                        (string) varcolor - the name of the color variable to use in the generic setter
                                        (number) varmin -       the minimum value the number variable can be set to when using the generic setter
                                                                                                                if not passed, and uimin is passed, uimin will be used
                                        (number) varmax -       the maximum value the number variable can be set to when using the generic setter
                                                                                                                if not passed, and uimax is passed, uimax will be used
                                        (function) update - this function will be called when using the generic setter, and the variable is updated
                                        (function) noupdate - this function will be called when using the generic setter, and the variable is not updated
                                        (function) anyupdate - this function will be called when using the generic setter, whether the variable is updated or not
                                        (string) textname -     specifies the name of the option to display when printing status changes without a UI, only used if
                                                                                                                        textbool/num/string/choice/color aren't
                                        (string) textbool, textnum, textstring, textchoice, textcolor - the string to print for the corrisponding portion, when not using a UI,
                                                                                                                                                                                                                                                                                                        and the variable has been updated in the generic setter.  If this string
                                                                                                                                                                                                                                                                                                        contains a %s, then it will be replaced with the value its updated to.
                                        (boolean) textshow - if this is true, then the text will be printed on update, whether or not a UI is around(when using the generic setter)
                                        (number) commul - the value to multiply the number by when showing it's status
                                        (number) cominmul - the value to multiply the number by when it is passed in by the user
                                        (string) comaction -    The action to perform, see Sky documentation for further details
                                        (number) comsticky -    Whether the command is sticky or not(1 or 0), see Sky documentation for further details
                                        (boolean) multichoice - set to true if more than one option can be selected in an MCOM_CHOICET
                                        (boolean) hasopacity - set to true if an MCOM_COLORT should also have an opacity setting
                                
                                Optional data for a standard slash command only:
                                        (string) comhelp -      What message to display as help in Sky for this command, see Sky documentation for further details
                                        ({string}) extrahelp -  A table of extra help messages to display, each line in the table is a separate line when printed.
                                        
                                Data required to register a super slash command:
                                        (string) supercom - the name of the super slash command Ex: "/command", or {"/command", "/com"}
                                        
                                Optional data for a super slash command:
                                        (string) comaction -    The action to perform, see Sky documentation for further details
                                        (number) comsticky -    Whether the command is sticky or not(1 or 0), see Sky documentation for further details
                                        (string) comhelp -      What message to display as help in Sky for this command, see Sky documentation for further details
                                        ({string}) extrahelp -  A table of extra help messages to display, each line in the table is a separate line when printed.
                                        
                                Data required to register a sub slash command:
                                        (string) supercom - the name of the super slash command to use for this sub slash command Ex: "/command", or {"/command", "/com"}
                                        (string) subcom - the name of the sub command, Ex: "command", or {"command", "com"}
                                        
                                        (string) comtype -      [Required if uitype is not passed], see above for details

                                Optional data for a sub command only:
                                        (string) subhelp -      What message to display next to the sub command when listing sub commands in the help output.
                                                                                                                        NOTE: if this is an MCOM_CHOICET then if you put a %s in this string, it will be replaced with a list of
                                                                                                                        the choices you passed.
                                        
                                Data required for a slash command to update a Cosmos or Khaos variable:
                                        (string) uivar -        The UI variable that should be updated

                                Data required for a slash command to update a Cosmos or Khaos variable, if func does not return a value:
                                        (string) varbool -      The variable that the UI variable should be set by
                                                                                                                This should be a string containing the name of the variable to update, this can include .'s for tables, Ex: "Something.Value"
                                                                                                                When type is MULTI, this specifies the bool variable
                                        (string) varnum - The same as comnum, but used to specify the number variable when type is MULTI, only used for MULTI type
                                
                                Data required for a slash command to update a Khaos variable:
                                        (string) uisec - The option set ID that the uivar is found in   
                                
                                Data required for a slash command to when type is MCOM_CHOICET:
                                        {       string = value, ... } choices - A list of choices and values to use when using a MCOM_CHOICET, string is the string passed in from the console
                                                                                                                                                                                and value is the value that should be associated with that string.
                                
                                Data required for help window:
                                        ( string or {string} ) infotext -       If this is passed the text will be shown in a help window then the slash command help is used, or when the help button
                                                                                                                                                                                is pressed in Khaos or Cosmos, this is also used for myAddOns help if uihelp was not passed.  If it is a table, each
                                                                                                                                                                                entry is a page.
                                
                                Optional data for help window:
                                        (string) name - Sets the name to refer to the addon as in the help window
                                        (string) infotitle - Sets the title of the help window, if not passed, then name is used with a default string, Ex. "AddonName Help"
                                }
        ]]--
        MCom.registerSmart = function ( inreglist )
                --Get a copy of the registration table
                local reglist;
                if ( type(inreglist) == "table" ) then
                        reglist = MCom.table.copy(inreglist);
                end
                --Make sure reglist is here, and a table
                if (type(reglist) == "table") then
                        --Register the Khaos options set if it has been passed
                        if ( type(reglist.uiset) == "table" ) then
                                MCom.uisec = reglist.uiset.id;
                                MCom.uiseclabel = reglist.uiset.text;
                                MCom.uisecdesc = reglist.uiset.helptext;
                                MCom.uisecdiff = reglist.uiset.difficulty;
                                MCom.uisecdef = reglist.uiset.default;
                                MCom.uiseccall = reglist.uiset.callback;
                                MCom.uiseccom = reglist.uiset.commands;
                                --Register each option in the list
                                if ( type(reglist.uiset.options) == "table" ) then
                                        for curOption = 1, getn(reglist.uiset.options) do
                                                local newMComSet = MCom.table.copy(reglist);
                                                newMComSet.uiset = nil;
                                                newMComSet.uioption = reglist.uiset.options[curOption];
                                                MCom.registerSmart( newMComSet );
                                        end
                                end
                        end
                        
                        --Support for old sytax variables
                        if (reglist.comvar) then
                                reglist.varbool = reglist.comvar;
                        end
                        if (reglist.comvarmulti) then
                                reglist.varnum = reglist.comvarmulti;
                        end
                        
                        --This will be set to true if we find that uioption is in Khaos format.
                        local isKhaosOption = nil;
                        
                        --If option data has been passed use any of it, as needed
                        if ( type(reglist.uioption) == "table" ) then
                                --If the option data seems to be Khaos style, then parse it as such
                                if (    (reglist.uioption.id ~= nil) or (reglist.uioption.key ~= nil) or (reglist.uioption.value ~= nil) or 
                                                        (reglist.uioption.text ~= nil) or (reglist.uioption.diificulty ~= nil) or (reglist.uioption.helptext ~= nil) or 
                                                        (reglist.uioption.callback ~= nil) or (reglist.uioption.feedback ~= nil) or (reglist.uioption.check ~= nil) or 
                                                        (reglist.uioption.radio ~= nil) or (reglist.uioption.type ~= nil) or (reglist.uioption.setup ~= nil) or 
                                                        (reglist.uioption.default ~= nil) or (reglist.uioption.disabled ~= nil) or (reglist.uioption.dependencies ~= nil) or
                                                        (reglist.uioption.mcopts ~= nil)
                                ) then
                                        isKhaosOption = true;
                                        if (reglist.uivar == nil) then
                                                reglist.uivar = reglist.uioption.id;
                                        end
                                        if (reglist.uikey == nil) then
                                                reglist.uikey = reglist.uioption.key;
                                        end
                                        if (reglist.uivalue == nil) then
                                                reglist.uivalue = reglist.uioption.value;
                                        end
                                        if (reglist.uilabel == nil) then
                                                reglist.uilabel = reglist.uioption.text;
                                        end
                                        if (reglist.uidiff == nil) then
                                                reglist.uidiff = reglist.uioption.difficulty;
                                        end
                                        if (reglist.uidesc == nil) then
                                                reglist.uidesc = reglist.uioption.helptext;
                                        end
                                        if (reglist.uifunc == nil) then
                                                reglist.uifunc = reglist.uioption.callback;
                                                --If this is a Khaos style function, going into Cosmos, then convert the values to Cosmos style
                                                if ((not Khaos) and CosmosMaster_Init and reglist.uifunc) then
                                                        reglist.uifunc = function (check, value) reglist.uioption.callback({ checked = (check == 1); slider = value; }); end;
                                                end
                                        end
                                        if (reglist.hasbool == nil) then
                                                reglist.hasbool = reglist.uioption.check;
                                        end
                                        if (reglist.uiradio == nil) then
                                                reglist.uiradio = reglist.uioption.radio;
                                        end
                                        if (reglist.uitype == nil) then
                                                reglist.uitype = reglist.uioption.type;
                                        end
                                        if ( type(reglist.uioption.setup) == "table" ) then
                                                if (reglist.uisetup == nil) then
                                                        reglist.uisetup = reglist.uioption.setup;
                                                end
                                                if (reglist.uitext == nil) then
                                                        if ( (reglist.uitype == K_BUTTON) or (reglist.uitype == "BUTTON") ) then
                                                                reglist.uitext = reglist.uioption.setup.buttonText;
                                                        elseif ( (reglist.uitype == K_SLIDER) or (reglist.uitype == "SLIDER") or (reglist.uitype == "BOTH") ) then
                                                                reglist.uitext = reglist.uioption.setup.sliderText;
                                                        end
                                                end
                                                if (reglist.uimin == nil) then
                                                        reglist.uimin = reglist.uioption.setup.sliderMin;
                                                end
                                                if (reglist.uimax == nil) then
                                                        reglist.uimax = reglist.uioption.setup.sliderMax;
                                                end
                                                if (reglist.uistep == nil) then
                                                        reglist.uistep = reglist.uioption.setup.sliderStep;
                                                end
                                                if (reglist.uisliderlow == nil) then
                                                        reglist.uisliderlow = reglist.uioption.setup.sliderLowText;
                                                end
                                                if (reglist.uisliderhigh == nil) then
                                                        reglist.uisliderhigh = reglist.uioption.setup.sliderHighText;
                                                end
                                                if (reglist.uisliderfunc == nil) then
                                                        reglist.uisliderfunc = reglist.uioption.setup.sliderDisplayFunc;
                                                end
                                                if (reglist.choices == nil) then
                                                        reglist.choices = reglist.uioption.setup.options;
                                                end
                                                if (reglist.multichoice == nil) then
                                                        reglist.multichoice = reglist.uioption.setup.multiSelect;
                                                end
                                                if (reglist.hasopacity == nil) then
                                                        reglist.hasopacity = reglist.uioption.setup.hasOpacity;
                                                end
                                                if (reglist.uicallon == nil) then
                                                        reglist.uicallon = reglist.uioption.setup.callOn;
                                                end
                                        end
                                        if (reglist.uifeedback == nil) then
                                                reglist.uifeedback = reglist.uioption.feedback;
                                        end
                                        if ( type(reglist.uioption.default) == "table" ) then
                                                if (reglist.uicheck == nil) then
                                                        reglist.uicheck = reglist.uioption.default.checked;
                                                        if (reglist.uicheck) then
                                                                reglist.uicheck = 1;
                                                        else
                                                                reglist.uicheck = 0;
                                                        end
                                                end
                                                if (reglist.uislider == nil) then
                                                        reglist.uislider = reglist.uioption.default.slider;
                                                end
                                                if (reglist.uicolor == nil) then
                                                        reglist.uicolor = reglist.uioption.default.color;
                                                end
                                                if (reglist.uitype == K_EDITBOX) then
                                                        if (reglist.uistring == nil) then
                                                                reglist.uistring = reglist.uioption.default.value;
                                                        end
                                                end
                                                if (reglist.uitype == K_PULLDOWN) then
                                                        if (reglist.uichoice == nil) then
                                                                reglist.uichoice = reglist.uioption.default.value;
                                                        end
                                                end
                                        end
                                        if ( type(reglist.uioption.disabled) == "table" ) then
                                                if (reglist.uidischeck == nil) then
                                                        reglist.uidischeck = reglist.uioption.disabled.checked;
                                                        if (reglist.uidischeck) then
                                                                reglist.uidischeck = 1;
                                                        else
                                                                reglist.uidischeck = 0;
                                                        end
                                                end
                                                if (reglist.uidisslider == nil) then
                                                        reglist.uidisslider = reglist.uioption.disabled.slider;
                                                end
                                                if (reglist.uidiscolor == nil) then
                                                        reglist.uidiscolor = reglist.uioption.disabled.color;
                                                end
                                                if (reglist.uitype == K_EDITBOX) then
                                                        if (reglist.uidisstring == nil) then
                                                                reglist.uidisstring = reglist.uioption.disabled.value;
                                                        end
                                                end
                                                if (reglist.uitype == K_PULLDOWN) then
                                                        if (reglist.uidischoice == nil) then
                                                                reglist.uidischoice = reglist.uioption.disabled.value;
                                                        end
                                                end
                                        end
                                        if (reglist.uidep == nil) then
                                                reglist.uidep = reglist.uioption.dependencies;
                                        end

                                        --If an MCom option set is in here, then use it
                                        if ( type(reglist.uioption.mcopts) == "table" ) then
                                                for curOpt in reglist.uioption.mcopts do
                                                        reglist[curOpt] = reglist.uioption.mcopts[curOpt];
                                                end
                                        end
                                else
                                        --If it's not Khaos style, we treat it as Cosmos style
                                        if (reglist.uivar == nil) then
                                                reglist.uivar = reglist.uioption[1];
                                        end
                                        if (reglist.uitype == nil) then
                                                reglist.uitype = reglist.uioption[2];
                                        end
                                        if (reglist.uilabel == nil) then
                                                reglist.uilabel = reglist.uioption[3];
                                        end
                                        if (reglist.uidesc == nil) then
                                                reglist.uidesc = reglist.uioption[4];
                                        end
                                        if (reglist.uifunc == nil) then
                                                reglist.uifunc = reglist.uioption[5];
                                                --If it's a Cosmos style function, being used in Khaos then convert the arguments to match
                                                if (Khaos and (not CosmosMaster_Init) and reglist.uifunc) then
                                                        local checkFunc = function (check)
                                                                if (check) then
                                                                        return 1;
                                                                else
                                                                        return 0;
                                                                end
                                                        end
                                                        reglist.uifunc = function (state) reglist.uioption[5]( checkFunc(state.checked) , state.slider); end;
                                                        if ( reglist.func == nil ) then
                                                                if (reglist.uitype == "SLIDER") then
                                                                        reglist.func = function (value) reglist.uioption[5](0,value); end;
                                                                else
                                                                        reglist.func = function (bool, value) reglist.uioption[5](bool,value); end;
                                                                end
                                                        end
                                                end
                                        end
                                        if (reglist.uicheck == nil) then
                                                reglist.uicheck = reglist.uioption[6];
                                        end
                                        if (reglist.uislider == nil) then
                                                reglist.uislider = reglist.uioption[7];
                                        end
                                        if (reglist.uimin == nil) then
                                                reglist.uimin = reglist.uioption[8];
                                        end
                                        if (reglist.uimax == nil) then
                                                reglist.uimax = reglist.uioption[9];
                                        end
                                        if (reglist.uitext == nil) then
                                                reglist.uitext = reglist.uioption[10];
                                        end
                                        if (reglist.uistep == nil) then
                                                reglist.uistep = reglist.uioption[11];
                                        end
                                        if (reglist.uitexton == nil) then
                                                reglist.uitexton = reglist.uioption[12];
                                        end
                                        if (reglist.uisuffix == nil) then
                                                reglist.uisuffix = reglist.uioption[13];
                                        end
                                        if (reglist.uimul == nil) then
                                                reglist.uimul = reglist.uioption[14];
                                        end
                                end
                        end
                        
                        --Default our regtype to nil
                        local regtype = nil;
                        --If we have uitype, then figure out the MCOM type for it
                        if (reglist.uitype) then
                                --If we are doing Khaos, then use it's types, and convert Cosmos types
                                --to Khaos types
                                if (Khaos) then
                                                if ( reglist.uitype == K_TEXT ) then
                                                        if (reglist.hasbool == true) then
                                                                regtype = MCOM_BOOLT;
                                                        end
                                                elseif ( reglist.uitype == K_SLIDER ) then
                                                        regtype = MCOM_NUMT;
                                                elseif ( reglist.uitype == K_EDITBOX ) then
                                                        regtype = MCOM_STRINGT;
                                                elseif ( reglist.uitype == K_BUTTON ) then
                                                        regtype = MCOM_SIMPLET;
                                                elseif ( reglist.uitype == K_PULLDOWN ) then
                                                        regtype = MCOM_CHOICET;
                                                elseif ( reglist.uitype == K_COLORPICKER ) then
                                                        regtype = MCOM_COLORT;
                                                elseif (reglist.uitype == "CHECKBOX") then
                                                        reglist.uitype = K_TEXT;
                                                        regtype = MCOM_BOOLT;
                                                        reglist.hasbool = true;
                                                elseif (reglist.uitype == "SLIDER") then
                                                        reglist.uitype = K_SLIDER;
                                                        regtype = MCOM_NUMT;
                                                elseif (reglist.uitype == "BOTH") then
                                                        reglist.uitype = K_SLIDER;
                                                        reglist.hasbool = true;
                                                        regtype = MCOM_MULTIT;
                                                elseif (reglist.uitype == "BUTTON") then
                                                        reglist.uitype = K_BUTTON;
                                                        regtype = MCOM_SIMPLET;
                                                elseif (reglist.uitype == "SEPARATOR") then
                                                        reglist.uitype = K_HEADER;
                                                end
                                else
                                        --If we are doing Cosmos, then use it's types, and convert Khaos types
                                        --to Cosmos types
                                        if ( reglist.uitype == K_TEXT ) then
                                                if (reglist.hasbool == true) then
                                                        regtype = MCOM_BOOLT;
                                                        reglist.uitype = "CHECKBOX";
                                                end
                                        elseif ( reglist.uitype == K_SLIDER ) then
                                                regtype = MCOM_NUMT;
                                                reglist.uitype = "SLIDER";
                                                if (reglist.hasbool == true) then
                                                        reglist.uitype = "BOTH";
                                                end
                                        elseif ( reglist.uitype == K_EDITBOX ) then
                                                regtype = MCOM_STRINGT;
                                        elseif ( reglist.uitype == K_BUTTON ) then
                                                regtype = MCOM_SIMPLET;
                                                reglist.uitype = "BUTTON";
                                        elseif ( reglist.uitype == K_PULLDOWN ) then
                                                regtype = MCOM_CHOICET;
                                        elseif ( reglist.uitype == K_COLORPICKER ) then
                                                regtype = MCOM_COLORT;
                                        elseif (reglist.uitype == K_HEADER) then
                                                        reglist.uitype = "SEPARATOR";
                                        elseif (reglist.uitype == "CHECKBOX") then
                                                regtype = MCOM_BOOLT;
                                                reglist.hasbool = true;
                                        elseif (reglist.uitype == "SLIDER") then
                                                regtype = MCOM_NUMT;
                                        elseif (reglist.uitype == "BOTH") then
                                                regtype = MCOM_MULTIT;
                                        elseif (reglist.uitype == "BUTTON") then
                                                regtype = MCOM_SIMPLET;
                                        end
                                end
                        end
                        --If we have the comtype, use it instead of the uitype
                        if (reglist.comtype) then
                                regtype = reglist.comtype;
                        end
                        
                        --If regtype is not set, and we have check set, then set type is BOOLT.
                        if ( (regtype == nil) and (reglist.hasbool == true) ) then
                                regtype = MCOM_BOOLT;
                        end
                        --If regtype is BOOLT, and we dont have check set, then set it.
                        if ( (regtype == MCOM_BOOLT) and (not reglist.hasbool) ) then
                                reglist.hasbool = true;
                        end
                        --If regtype is MULTIT, and we dont have check set, then set it.
                        if ( (regtype == MCOM_MULTIT) and (not reglist.hasbool) ) then
                                reglist.hasbool = true;
                        end
                        
                        --If no min, max, or mul were provided for the setter, but was provided for the UI, then use the ui values
                        --and visa versa
                        if ( reglist.uimin and (not reglist.varmin) ) then
                                reglist.varmin = reglist.uimin;
                        elseif ( reglist.varmin and (not reglist.uimin) ) then
                                reglist.uimin = reglist.varmin;
                        end
                        if ( reglist.uimax and (not reglist.varmax) ) then
                                reglist.varmax = reglist.uimax;
                        elseif ( reglist.varmax and (not reglist.uimax) ) then
                                reglist.uimax = reglist.varmax;
                        end
                        if ( reglist.uimul and (not reglist.commul) ) then
                                reglist.commul = reglist.uimul;
                        elseif ( reglist.commul and (not reglist.uimul) ) then
                                reglist.uimul = reglist.commul;
                        end
                        if ( not reglist.uimul ) then
                                reglist.uimul = 1;
                        end
                        if ( reglist.commul and ( not reglist.cominmul ) ) then
                                reglist.cominmul = 1 / reglist.commul;
                        end
                        if ( not reglist.commul ) then
                                reglist.commul = 1;
                        end
                        if ( not reglist.cominmul ) then
                                reglist.cominmul = 1;
                        end
                        
                        if (not reglist.func) then
                                if (reglist.uifunc) then
                                        --If there was no function passed, but a ui func was passed, use the uifunc
                                        reglist.func = reglist.uifunc;
                                else
                                        --If textname wasn't passed, try and make it from other data
                                        if (not reglist.textname) then
                                                reglist.textname = reglist.uilabel;
                                        end
                                        if (not reglist.textname) then
                                                if ( type(reglist.subcom) == "table" ) then
                                                        reglist.textname = reglist.subcom[1];
                                                else
                                                        reglist.textname = reglist.subcom;
                                                end
                                        end
                                        if (not reglist.textname) then
                                                if ( type(reglist.command) == "table" ) then
                                                        reglist.textname = reglist.command[1];
                                                else
                                                        reglist.textname = reglist.command;
                                                end
                                        end
                                        
                                        --Generate defaults for the text strings if none are passed
                                        if (reglist.textname) then
                                                if (not reglist.textbool) then
                                                        reglist.textbool = string.format(MCOM_CHAT_STATUS_B, reglist.textname);
                                                end
                                                if (not reglist.textnum) then
                                                        reglist.textnum = string.format(MCOM_CHAT_STATUS_N, reglist.textname);
                                                end
                                                if (not reglist.textstring) then
                                                        reglist.textstring = string.format(MCOM_CHAT_STATUS_S, reglist.textname);
                                                end
                                                if (not reglist.textchoice) then
                                                        reglist.textchoice = string.format(MCOM_CHAT_STATUS_C, reglist.textname);
                                                end
                                                if (not reglist.textcolor) then
                                                        reglist.textcolor = string.format(MCOM_CHAT_STATUS_K, reglist.textname);
                                                end
                                        end
                                        
                                        --If there was no function passed, then provide our own generic function
                                        if ((regtype == MCOM_BOOLT) and reglist.varbool) then
                                                reglist.func =  function (checked)
                                                                                                                        if (MCom.updateVar(reglist.varbool, checked, MCOM_BOOLT)) then
                                                                                                                                --If there is a function to run on an update, call it
                                                                                                                                if (reglist.update and (type(reglist.update) == "function")) then
                                                                                                                                        reglist.update(reglist.varbool);
                                                                                                                                end

                                                                                                                                if (reglist.textbool) then
                                                                                                                                        --Print output to let the player know the command succeeded, if there is no UI
                                                                                                                                        MCom.printStatus(reglist.textbool, MCom.getStringVar(reglist.varbool), true, reglist.textshow);
                                                                                                                                end
                                                                                                                        else
                                                                                                                                --If there is a function to run on an attempted update, that resulted in no change, then run it
                                                                                                                                if (reglist.noupdate and (type(reglist.noupdate) == "function")) then
                                                                                                                                        reglist.noupdate(reglist.varbool);
                                                                                                                                end
                                                                                                                        end
                                                                                                                        --If there is a function to run on any update, then run it
                                                                                                                        if (reglist.anyupdate and (type(reglist.anyupdate) == "function")) then
                                                                                                                                reglist.anyupdate(reglist.varbool);
                                                                                                                        end
                                                                                                                end;
                                        elseif ( ( (regtype == MCOM_NUMT) and (not reglist.hasbool) ) and reglist.varnum ) then
                                                reglist.func =  function (value)
                                                                                                                        if (MCom.updateVar(reglist.varnum, value, MCOM_NUMT, reglist.varmin, reglist.varmax)) then
                                                                                                                                --If there is a function to run on an update, call it
                                                                                                                                if (reglist.update and (type(reglist.update) == "function")) then
                                                                                                                                        reglist.update(reglist.varnum);
                                                                                                                                end

                                                                                                                                if (reglist.textnum) then
                                                                                                                                        --Print output to let the player know the command succeeded, if there is no UI
                                                                                                                                        if (value and reglist.commul and MCom.getStringVar(reglist.varnum)) then
                                                                                                                                                value = MCom.math.round( ( MCom.getStringVar(reglist.varnum) * reglist.commul ) * 100 ) / 100;
                                                                                                                                        else
                                                                                                                                                value = MCom.getStringVar(reglist.varnum);
                                                                                                                                        end
                                                                                                                                        MCom.printStatus(reglist.textnum, value, nil, reglist.textshow);
                                                                                                                                end
                                                                                                                        else
                                                                                                                                --If there is a function to run on an attempted update, that resulted in no change, then run it
                                                                                                                                if (reglist.noupdate and (type(reglist.noupdate) == "function")) then
                                                                                                                                        reglist.noupdate(reglist.varnum);
                                                                                                                                end
                                                                                                                        end
                                                                                                                        --If there is a function to run on any update, then run it
                                                                                                                        if (reglist.anyupdate and (type(reglist.anyupdate) == "function")) then
                                                                                                                                reglist.anyupdate(reglist.varnum);
                                                                                                                        end
                                                                                                                end;
                                        elseif ( ( (regtype == MCOM_STRINGT) and (not reglist.hasbool) ) and reglist.varstring ) then
                                                reglist.func =  function (value)
                                                                                                                        if (MCom.updateVar(reglist.varstring, value, MCOM_STRINGT)) then
                                                                                                                                --If there is a function to run on an update, call it
                                                                                                                                if (reglist.update and (type(reglist.update) == "function")) then
                                                                                                                                        reglist.update(reglist.varstring);
                                                                                                                                end
                                                                                                                                
                                                                                                                                if (reglist.textstring) then
                                                                                                                                        --Print output to let the player know the command succeeded, if there is no UI
                                                                                                                                        MCom.printStatus(reglist.textstring, MCom.getStringVar(reglist.varstring), nil, reglist.textshow);
                                                                                                                                end
                                                                                                                        else
                                                                                                                                --If there is a function to run on an attempted update, that resulted in no change, then run it
                                                                                                                                if (reglist.noupdate and (type(reglist.noupdate) == "function")) then
                                                                                                                                        reglist.noupdate(reglist.varstring);
                                                                                                                                end
                                                                                                                        end
                                                                                                                        --If there is a function to run on any update, then run it
                                                                                                                        if (reglist.anyupdate and (type(reglist.anyupdate) == "function")) then
                                                                                                                                reglist.anyupdate(reglist.varstring);
                                                                                                                        end
                                                                                                                end;
                                        elseif ( ( (regtype == MCOM_CHOICET) and (not reglist.hasbool) ) and reglist.varchoice ) then
                                                reglist.func =  function (value, name)
                                                                                                                        if (MCom.updateVar(reglist.varchoice, value, MCOM_CHOICET)) then
                                                                                                                                --If there is a function to run on an update, call it
                                                                                                                                if (reglist.update and (type(reglist.update) == "function")) then
                                                                                                                                        reglist.update(reglist.varchoice);
                                                                                                                                end
                                                                                                                                
                                                                                                                                if (reglist.textchoice) then
                                                                                                                                        --Print output to let the player know the command succeeded, if there is no UI
                                                                                                                                        MCom.printStatus(reglist.textchoice, name, nil, reglist.textshow);
                                                                                                                                end
                                                                                                                        else
                                                                                                                                --If there is a function to run on an attempted update, that resulted in no change, then run it
                                                                                                                                if (reglist.noupdate and (type(reglist.noupdate) == "function")) then
                                                                                                                                        reglist.noupdate(reglist.varchoice);
                                                                                                                                end
                                                                                                                        end
                                                                                                                        --If there is a function to run on any update, then run it
                                                                                                                        if (reglist.anyupdate and (type(reglist.anyupdate) == "function")) then
                                                                                                                                reglist.anyupdate(reglist.varchoice);
                                                                                                                        end
                                                                                                                end;
                                        elseif ( ( (regtype == MCOM_COLORT) and (not reglist.hasbool) ) and reglist.varcolor ) then
                                                reglist.func =  function (value)
                                                                                                                        if (MCom.updateVar(reglist.varcolor, value, MCOM_COLORT)) then
                                                                                                                                --If there is a function to run on an update, call it
                                                                                                                                if (reglist.update and (type(reglist.update) == "function")) then
                                                                                                                                        reglist.update(reglist.varcolor);
                                                                                                                                end
                                                                                                                                
                                                                                                                                if (reglist.textcolor) then
                                                                                                                                        --Build a color string
                                                                                                                                        local curColor = MCom.getStringVar(reglist.varstring);
                                                                                                                                        local curColString = "";
                                                                                                                                        if ( type(curColor) == "table" ) then
                                                                                                                                                if (curColor.r) then
                                                                                                                                                        curColString = string.format(MCOM_CHAT_COM_K_R, MCom.math.round(curColor.r * 100));
                                                                                                                                                end
                                                                                                                                                if (curColor.g) then
                                                                                                                                                        if ( curColString ~= "" ) then
                                                                                                                                                                curColString = curColString..", ";
                                                                                                                                                        end
                                                                                                                                                        curColString = curColString..string.format(MCOM_CHAT_COM_K_G, MCom.math.round(curColor.g * 100));
                                                                                                                                                end
                                                                                                                                                if (curColor.b) then
                                                                                                                                                        if ( curColString ~= "" ) then
                                                                                                                                                                curColString = curColString..", ";
                                                                                                                                                        end
                                                                                                                                                        curColString = curColString..string.format(MCOM_CHAT_COM_K_B, MCom.math.round(curColor.b * 100));
                                                                                                                                                end
                                                                                                                                                if (reglist.hasopacity) then
                                                                                                                                                        local displayOpacity = 1;
                                                                                                                                                        if (curColor.opacity) then
                                                                                                                                                                displayOpacity = curColor.opacity;
                                                                                                                                                        end
                                                                                                                                                        if ( curColString ~= "" ) then
                                                                                                                                                                curColString = curColString..", ";
                                                                                                                                                        end
                                                                                                                                                        curColString = curColString..string.format(MCOM_CHAT_COM_K_O, MCom.math.round(displayOpacity * 100));
                                                                                                                                                end
                                                                                                                                        end
                                                                                                                                        --Print output to let the player know the command succeeded, if there is no UI
                                                                                                                                        MCom.printStatus(reglist.textcolor, curColString, nil, reglist.textshow);
                                                                                                                                end
                                                                                                                        else
                                                                                                                                --If there is a function to run on an attempted update, that resulted in no change, then run it
                                                                                                                                if (reglist.noupdate and (type(reglist.noupdate) == "function")) then
                                                                                                                                        reglist.noupdate(reglist.varcolor);
                                                                                                                                end
                                                                                                                        end
                                                                                                                        --If there is a function to run on any update, then run it
                                                                                                                        if (reglist.anyupdate and (type(reglist.anyupdate) == "function")) then
                                                                                                                                reglist.anyupdate(reglist.varcolor);
                                                                                                                        end
                                                                                                                end;
                                        elseif ( ( (regtype == MCOM_MULTIT) or ( (regtype == MCOM_NUMT) and reglist.hasbool ) ) and reglist.varbool and reglist.varnum ) then
                                                reglist.func =  function (checked, value)
                                                                                                                        if (MCom.updateVar(reglist.varbool, checked, MCOM_BOOLT)) then
                                                                                                                                --If there is a function to run on an update, call it
                                                                                                                                if (reglist.update and (type(reglist.update) == "function")) then
                                                                                                                                        reglist.update(reglist.varbool);
                                                                                                                                end
                                                                                                                                
                                                                                                                                if (reglist.textbool) then
                                                                                                                                        --Print output to let the player know the command succeeded, if there is no UI
                                                                                                                                        MCom.printStatus(reglist.textbool, MCom.getStringVar(reglist.varbool), true, reglist.textshow);
                                                                                                                                end
                                                                                                                        else
                                                                                                                                --If there is a function to run on an attempted update, that resulted in no change, then run it
                                                                                                                                if (reglist.noupdate and (type(reglist.noupdate) == "function")) then
                                                                                                                                        reglist.noupdate(reglist.varbool);
                                                                                                                                end
                                                                                                                        end
                                                                                                                        --If there is a function to run on any update, then run it
                                                                                                                        if (reglist.anyupdate and (type(reglist.anyupdate) == "function")) then
                                                                                                                                reglist.anyupdate(reglist.varbool);
                                                                                                                        end
                                                                                                                        
                                                                                                                        --If no value was passed, then don't set it
                                                                                                                        if (value) then
                                                                                                                                if (MCom.updateVar(reglist.varnum, value, MCOM_NUMT, reglist.varmin, reglist.varmax)) then
                                                                                                                                        --If there is a function to run on an update, call it
                                                                                                                                        if (reglist.update and (type(reglist.update) == "function")) then
                                                                                                                                                reglist.update(reglist.varnum);
                                                                                                                                        end
                                                                                                                                        
                                                                                                                                        if (reglist.textnum) then
                                                                                                                                                --Print output to let the player know the command succeeded, if there is no UI
                                                                                                                                                if (value and reglist.commul and MCom.getStringVar(reglist.varnum)) then
                                                                                                                                                        value = MCom.math.round( ( MCom.getStringVar(reglist.varnum) * reglist.commul ) * 100 ) / 100;
                                                                                                                                                else
                                                                                                                                                        value = MCom.getStringVar(reglist.varnum);
                                                                                                                                                end
                                                                                                                                                MCom.printStatus(reglist.textnum, value, nil, reglist.textshow);
                                                                                                                                        end
                                                                                                                                else
                                                                                                                                        --If there is a function to run on an attempted update, that resulted in no change, then run it
                                                                                                                                        if (reglist.noupdate and (type(reglist.noupdate) == "function")) then
                                                                                                                                                reglist.noupdate(reglist.varnum);
                                                                                                                                        end
                                                                                                                                end
                                                                                                                        end
                                                                                                                        --If there is a function to run on any update, then run it
                                                                                                                        if (reglist.anyupdate and (type(reglist.anyupdate) == "function")) then
                                                                                                                                reglist.anyupdate(reglist.varnum);
                                                                                                                        end
                                                                                                                end;
                                        elseif ( ( ( (regtype == MCOM_STRINGT) and reglist.hasbool ) ) and reglist.varbool and reglist.varstring ) then
                                                reglist.func =  function (checked, value)
                                                                                                                        if (MCom.updateVar(reglist.varbool, checked, MCOM_BOOLT)) then
                                                                                                                                --If there is a function to run on an update, call it
                                                                                                                                if (reglist.update and (type(reglist.update) == "function")) then
                                                                                                                                        reglist.update(reglist.varbool);
                                                                                                                                end
                                                                                                                                
                                                                                                                                if (reglist.textbool) then
                                                                                                                                        --Print output to let the player know the command succeeded, if there is no UI
                                                                                                                                        MCom.printStatus(reglist.textbool, MCom.getStringVar(reglist.varbool), true, reglist.textshow);
                                                                                                                                end
                                                                                                                        else
                                                                                                                                --If there is a function to run on an attempted update, that resulted in no change, then run it
                                                                                                                                if (reglist.noupdate and (type(reglist.noupdate) == "function")) then
                                                                                                                                        reglist.noupdate(reglist.varbool);
                                                                                                                                end
                                                                                                                        end
                                                                                                                        --If there is a function to run on any update, then run it
                                                                                                                        if (reglist.anyupdate and (type(reglist.anyupdate) == "function")) then
                                                                                                                                reglist.anyupdate(reglist.varbool);
                                                                                                                        end
                                                                                                                        
                                                                                                                        --If no value was passed, then don't set it
                                                                                                                        if (value) then
                                                                                                                                if (MCom.updateVar(reglist.varstring, value, MCOM_STRINGT)) then
                                                                                                                                        --If there is a function to run on an update, call it
                                                                                                                                        if (reglist.update and (type(reglist.update) == "function")) then
                                                                                                                                                reglist.update(reglist.varstring);
                                                                                                                                        end
                                                                                                                                        
                                                                                                                                        if (reglist.textstring) then
                                                                                                                                                --Print output to let the player know the command succeeded, if there is no UI
                                                                                                                                                MCom.printStatus(reglist.textstring, MCom.getStringVar(reglist.varstring), nil, reglist.textshow);
                                                                                                                                        end
                                                                                                                                else
                                                                                                                                        --If there is a function to run on an attempted update, that resulted in no change, then run it
                                                                                                                                        if (reglist.noupdate and (type(reglist.noupdate) == "function")) then
                                                                                                                                                reglist.noupdate(reglist.varstring);
                                                                                                                                        end
                                                                                                                                end
                                                                                                                        end
                                                                                                                        --If there is a function to run on any update, then run it
                                                                                                                        if (reglist.anyupdate and (type(reglist.anyupdate) == "function")) then
                                                                                                                                reglist.anyupdate(reglist.varstring);
                                                                                                                        end
                                                                                                                end;
                                        elseif ( ( ( (regtype == MCOM_CHOICET) and reglist.hasbool ) ) and reglist.varbool and reglist.varchoice ) then
                                                reglist.func =  function (checked, value, name)
                                                                                                                        if (MCom.updateVar(reglist.varbool, checked, MCOM_BOOLT)) then
                                                                                                                                --If there is a function to run on an update, call it
                                                                                                                                if (reglist.update and (type(reglist.update) == "function")) then
                                                                                                                                        reglist.update(reglist.varbool);
                                                                                                                                end
                                                                                                                                
                                                                                                                                if (reglist.textbool) then
                                                                                                                                        --Print output to let the player know the command succeeded, if there is no UI
                                                                                                                                        MCom.printStatus(reglist.textbool, MCom.getStringVar(reglist.varbool), true, reglist.textshow);
                                                                                                                                end
                                                                                                                        else
                                                                                                                                --If there is a function to run on an attempted update, that resulted in no change, then run it
                                                                                                                                if (reglist.noupdate and (type(reglist.noupdate) == "function")) then
                                                                                                                                        reglist.noupdate(reglist.varbool);
                                                                                                                                end
                                                                                                                        end
                                                                                                                        --If there is a function to run on any update, then run it
                                                                                                                        if (reglist.anyupdate and (type(reglist.anyupdate) == "function")) then
                                                                                                                                reglist.anyupdate(reglist.varbool);
                                                                                                                        end
                                                                                                                        
                                                                                                                        --If no value was passed, then don't set it
                                                                                                                        if (value) then
                                                                                                                                if (MCom.updateVar(reglist.varchoice, value, MCOM_CHOICET)) then
                                                                                                                                        --If there is a function to run on an update, call it
                                                                                                                                        if (reglist.update and (type(reglist.update) == "function")) then
                                                                                                                                                reglist.update(reglist.varchoice);
                                                                                                                                        end
                                                                                                                                        
                                                                                                                                        if (reglist.textchoice) then
                                                                                                                                                --Print output to let the player know the command succeeded, if there is no UI
                                                                                                                                                MCom.printStatus(reglist.textchoice, name, nil, reglist.textshow);
                                                                                                                                        end
                                                                                                                                else
                                                                                                                                        --If there is a function to run on an attempted update, that resulted in no change, then run it
                                                                                                                                        if (reglist.noupdate and (type(reglist.noupdate) == "function")) then
                                                                                                                                                reglist.noupdate(reglist.varchoice);
                                                                                                                                        end
                                                                                                                                end
                                                                                                                        end
                                                                                                                        --If there is a function to run on any update, then run it
                                                                                                                        if (reglist.anyupdate and (type(reglist.anyupdate) == "function")) then
                                                                                                                                reglist.anyupdate(reglist.varchoice);
                                                                                                                        end
                                                                                                                end;
                                        elseif ( ( ( (regtype == MCOM_COLORT) and reglist.hasbool ) ) and reglist.varbool and reglist.varcolor ) then
                                                reglist.func =  function (checked, value)
                                                                                                                        if (MCom.updateVar(reglist.varbool, checked, MCOM_BOOLT)) then
                                                                                                                                --If there is a function to run on an update, call it
                                                                                                                                if (reglist.update and (type(reglist.update) == "function")) then
                                                                                                                                        reglist.update(reglist.varbool);
                                                                                                                                end
                                                                                                                                
                                                                                                                                if (reglist.textbool) then
                                                                                                                                        --Print output to let the player know the command succeeded, if there is no UI
                                                                                                                                        MCom.printStatus(reglist.textbool, MCom.getStringVar(reglist.varbool), true, reglist.textshow);
                                                                                                                                end
                                                                                                                        else
                                                                                                                                --If there is a function to run on an attempted update, that resulted in no change, then run it
                                                                                                                                if (reglist.noupdate and (type(reglist.noupdate) == "function")) then
                                                                                                                                        reglist.noupdate(reglist.varbool);
                                                                                                                                end
                                                                                                                        end
                                                                                                                        --If there is a function to run on any update, then run it
                                                                                                                        if (reglist.anyupdate and (type(reglist.anyupdate) == "function")) then
                                                                                                                                reglist.anyupdate(reglist.varbool);
                                                                                                                        end
                                                                                                                        
                                                                                                                        --If no value was passed, then don't set it
                                                                                                                        if (value) then
                                                                                                                                if (MCom.updateVar(reglist.varcolor, value, MCOM_COLORT)) then
                                                                                                                                        --If there is a function to run on an update, call it
                                                                                                                                        if (reglist.update and (type(reglist.update) == "function")) then
                                                                                                                                                reglist.update(reglist.varcolor);
                                                                                                                                        end
                                                                                                                                        
                                                                                                                                        if (reglist.textcolor) then
                                                                                                                                                --Build a color string
                                                                                                                                                local curColor = MCom.getStringVar(reglist.varstring);
                                                                                                                                                local curColString = "";
                                                                                                                                                if ( type(curColor) == "table" ) then
                                                                                                                                                        if (curColor.r) then
                                                                                                                                                                curColString = string.format(MCOM_CHAT_COM_K_R, MCom.math.round(curColor.r * 100));
                                                                                                                                                        end
                                                                                                                                                        if (curColor.g) then
                                                                                                                                                                if ( curColString ~= "" ) then
                                                                                                                                                                        curColString = curColString..", ";
                                                                                                                                                                end
                                                                                                                                                                curColString = curColString..string.format(MCOM_CHAT_COM_K_G, MCom.math.round(curColor.g * 100));
                                                                                                                                                        end
                                                                                                                                                        if (curColor.b) then
                                                                                                                                                                if ( curColString ~= "" ) then
                                                                                                                                                                        curColString = curColString..", ";
                                                                                                                                                                end
                                                                                                                                                                curColString = curColString..string.format(MCOM_CHAT_COM_K_B, MCom.math.round(curColor.b * 100));
                                                                                                                                                        end
                                                                                                                                                        if (reglist.hasopacity) then
                                                                                                                                                                local displayOpacity = 1;
                                                                                                                                                                if (curColor.opacity) then
                                                                                                                                                                        displayOpacity = curColor.opacity;
                                                                                                                                                                end
                                                                                                                                                                if ( curColString ~= "" ) then
                                                                                                                                                                        curColString = curColString..", ";
                                                                                                                                                                end
                                                                                                                                                                curColString = curColString..string.format(MCOM_CHAT_COM_K_O, MCom.math.round(displayOpacity * 100));
                                                                                                                                                        end
                                                                                                                                                end
                                                                                                                                                --Print output to let the player know the command succeeded, if there is no UI
                                                                                                                                                MCom.printStatus(reglist.textcolor, curColString, nil, reglist.textshow);
                                                                                                                                        end
                                                                                                                                else
                                                                                                                                        --If there is a function to run on an attempted update, that resulted in no change, then run it
                                                                                                                                        if (reglist.noupdate and (type(reglist.noupdate) == "function")) then
                                                                                                                                                reglist.noupdate(reglist.varcolor);
                                                                                                                                        end
                                                                                                                                end
                                                                                                                        end
                                                                                                                        --If there is a function to run on any update, then run it
                                                                                                                        if (reglist.anyupdate and (type(reglist.anyupdate) == "function")) then
                                                                                                                                reglist.anyupdate(reglist.varcolor);
                                                                                                                        end
                                                                                                                end;
                                        end
                                end
                        end

                        --If uifolder was not passed, see if there is a compatable uicat for it
                        if (not reglist.uifolder) then
                                if (reglist.uicat == MYADDONS_CATEGORY_BARS) then
                                        reglist.uifolder = "bars";
                                elseif (reglist.uicat == MYADDONS_CATEGORY_CHAT) then
                                        reglist.uifolder = "chat";
                                elseif (reglist.uicat == MYADDONS_CATEGORY_COMBAT) then
                                        reglist.uifolder = "combat";
                                elseif (reglist.uicat == MYADDONS_CATEGORY_INVENTORY) then
                                        reglist.uifolder = "inventory";
                                elseif (reglist.uicat == MYADDONS_CATEGORY_QUESTS) then
                                        reglist.uifolder = "quest";
                                end
                        end

                        if (reglist.uitype == "SECTION") then
                                --If a Cosmos section has been passed, then we need to store it's data so that
                                --when we are ready to register an option, we can then create the option set
                                --based on the section data
                                MCom.uifolder = reglist.uifolder;
                                MCom.uisec = reglist.uisec;
                                MCom.uisecabel = reglist.uiseclabel;
                                MCom.uisecdesc = reglist.uisecdesc;
                                MCom.uisecdiff = reglist.uisecdiff;
                                MCom.uiseccall = reglist.uiseccall;
                                MCom.uisecdef = reglist.uisecdef;
                                MCom.uiseccom = reglist.uiseccom;
                                if (not reglist.uisec) then
                                        reglist.uisec = reglist.uivar;
                                        MCom.uisec = reglist.uivar;
                                end
                                if (not reglist.uiseclabel) then
                                        MCom.uiseclabel = reglist.uilabel;
                                end
                                if (not reglist.uisecdesc) then
                                        MCom.uisecdesc = reglist.uidesc;
                                end
                        end
                        
                        --If no set was passed, then use the previously stored one
                        if (not reglist.uisec) then
                                reglist.uisec = MCom.uisec;
                        end

                        --If the previously stored set exists, and is the same as the one passed, then pull
                        --the data from it
                        if ( MCom.uisec and (MCom.uisec == reglist.uisec) ) then
                                if (not reglist.uiseclabel) then
                                        reglist.uiseclabel = MCom.uiseclabel;
                                end
                                if (not reglist.uisecdesc) then
                                        reglist.uisecdesc = MCom.uisecdesc;
                                end
                                if (not reglist.uisecdiff) then
                                        reglist.uisecdiff = MCom.uisecdiff;
                                end
                                if (not reglist.uiseccall) then
                                        reglist.uiseccall = MCom.uiseccall;
                                end
                                if (not reglist.uisecdef) then
                                        reglist.uisecdef = MCom.uisecdef;
                                end
                                if (not reglist.uiseccom) then
                                        reglist.uiseccom = MCom.uiseccom;
                                end
                        end
                        
                        --Setup stored set with current data
                        MCom.uisec = reglist.uisec;
                        MCom.uiseclabel = reglist.uiseclabel;
                        MCom.uisecdesc = reglist.uisecdesc;
                        MCom.uisecdiff = reglist.uisecdiff;
                        MCom.uiseccall = reglist.uiseccall;
                        MCom.uisecdef = reglist.uisecdef;
                        MCom.uiseccom = reglist.uiseccom;

                        --If MyAddOns is loaded, then try to register with it
                        if ( myAddOnsList and (MCom.uisec or MCom.uiseclabel or reglist.addonname) ) then
                                --Figure out an entry, label, and description
                                local addonEntry = MCom.uisec;
                                if (not addonEntry) then
                                        addonEntry = reglist.addonname;
                                end
                                if (not addonEntry) then
                                        addonEntry = MCom.uilabel;
                                end
                                local addonName = reglist.addonname;
                                if (not addonName) then
                                        addonName = addonEntry;
                                end
                                if (not addonName) then
                                        addonName = reglist.uiseclabel;
                                end
                                if ( (not myAddOnsFrame_Register) and MCom.uiseclabel ) then
                                        addonName = MCom.uiseclabel;
                                end
                                local addonDesc = reglist.uisecdesc;
                                if (not addonDesc) then
                                        addonDesc = addonName;
                                end
                                if (not MCom.MyAddOnsList) then
                                        MCom.MyAddOnsList = {};
                                end

                                --Default the addon list to an internal one that MCom keeps, until loading is done
                                local addonList = MCom.MyAddOnsList;
                                --If we have finished loading MyAddOns, then go ahead and use its list
                                if (MCom.MyAddOnsLoaded) then
                                        addonList = myAddOnsList;
                                elseif (not MCom.MyAddonsHooked) then
                                        --If variables haven't loaded yet, then store the registered addons in a temporary list
                                        --that will will use to add to the real list once variables have loaded
                                        MCom.MyAddonsHooked = true;
                                        --Hook the MyAddOns event function so we know when variables have loaded
                                        MCom.util.hook("myAddOnsFrame_OnEvent", "MCom.myAddOnsFrame_OnEvent", "after");
                                end

                                --Only add this to the list if it isn't already there
                                if ( not addonList[addonEntry] ) then
                                        --If category wasn't passed see if a compatable folder was passed
                                        if (not reglist.uicat) then
                                                if (reglist.uifolder == "bars") then
                                                        reglist.uicat = MYADDONS_CATEGORY_BARS;
                                                elseif (reglist.uifolder == "chat") then
                                                        reglist.uicat = MYADDONS_CATEGORY_CHAT;
                                                elseif (reglist.uifolder == "combat") then
                                                        reglist.uicat = MYADDONS_CATEGORY_COMBAT;
                                                elseif (reglist.uifolder == "inventory") then
                                                        reglist.uicat = MYADDONS_CATEGORY_INVENTORY;
                                                elseif (reglist.uifolder == "quest") then
                                                        reglist.uicat = MYADDONS_CATEGORY_QUESTS;
                                                else
                                                        reglist.uicat = MYADDONS_CATEGORY_OTHERS;
                                                end
                                        end

                                        --If no options frame was passed, and this is a Cosmos or Khaos registration, then set
                                        --the options frame to be the Khaos or Cosmos options frame
                                        if (not reglist.uioptionsframe) then
                                                if (Khaos and reglist.uivar and reglist.uitype and reglist.uilabel) then
                                                        reglist.uioptionsframe = "KhaosFrame";
                                                elseif (CosmosMaster_Init and reglist.uivar and reglist.uitype and reglist.uilabel ) then
                                                        reglist.uioptionsframe = "CosmosMasterFrame";
                                                end
                                        end
                                        --If an options frame was passed, and it isn't in the UIPanel's list, then add it
                                        if (reglist.uioptionsframe and ( not UIPanelWindows[reglist.uioptionsframe] ) ) then
                                                UIPanelWindows[reglist.uioptionsframe] = {area = "center", pushable = 0};
                                        end
                                        --If uihelp wasn't passed, use infotext
                                        if (not reglist.uihelp) then
                                                reglist.uihelp = reglist.infotext;
                                        end
                                        --Make usre uihelp is a table or boolean
                                        if (reglist.uihelp and (type(reglist.uihelp) ~= "table") and (type(reglist.uihelp) ~= "boolean") ) then
                                                reglist.uihelp = { reglist.uihelp };
                                        end
                                        --Add the addon to the list
                                        addonList[addonEntry] = {
                                                details = {
                                                        name = addonName;
                                                        description = addonDesc;
                                                        version = reglist.uiver;
                                                        releaseDate = reglist.uidate,
                                                        author = reglist.uiauthor,
                                                        email = reglist.uimail,
                                                        website = reglist.uiwww,
                                                        category = reglist.uicat;
                                                        frame = reglist.uiframe;
                                                        optionsframe = reglist.uioptionsframe;
                                                };
                                                help = reglist.uihelp;
                                                supercom = reglist.supercom;
                                        };
                                end
                        end
                        
                        --If the variable name is not prefixed with COS_ and cosmos is the UI then put it on there
                        if ( reglist.uivar and CosmosMaster_Init and (not Khaos) ) then
                                if ( (string.len(reglist.uivar) < 4) or (string.sub(reglist.uivar, 1, 4) ~= "COS_") ) then
                                        reglist.uivar = "COS_"..reglist.uivar;
                                end
                        end

                        if (Khaos and reglist.uivar and reglist.uitype and reglist.uilabel) then
                                --If we have Khaos and the data needed to register with it, then try to work that out
                                if (reglist.uitype ~= "SECTION") then
                                        --Only work with valid Khaos types
                                        if (    (reglist.uitype == K_HEADER) or (reglist.uitype == K_TEXT) or (reglist.uitype == K_CHECKBOX) or
                                                                (reglist.uitype == K_BUTTON) or (reglist.uitype == K_SLIDER) or (reglist.uitype == K_EDITBOX) or
                                                                (reglist.uitype == K_PULLDOWN) or (reglist.uitype == K_COLORPICKER)     ) then
                                                --We have now go through the proccess of preparing a Khaos option, then we will register it
                                                --If a folder has been passed then store it for use now, and for future registers
                                                if (reglist.uifolder) then
                                                        MCom.uifolder = reglist.uifolder;
                                                end
                                                --If a separator has been passed then store it for use now, and for future registers
                                                if (reglist.uisep) then
                                                        MCom.uisep = reglist.uisep;
                                                end
                                                if (reglist.uitype == K_HEADER) then
                                                        MCom.uisep = reglist.uivar;
                                                end
                                        
                                                --If we don't have a uifunc yet, then wrap the func
                                                if ( (not reglist.uifunc) and reglist.func ) then
                                                        --Wrap it for Khaos
                                                        reglist.uifunc = function (state, keypressed) MCom.SetFromKUI(reglist.uivar, state, keypressed, reglist.choices); end;
                                                        --Add the function to the list of callback functions
                                                        if (reglist.uitype) then
                                                                --Only do this for UI elements that have options
                                                                if ((reglist.uitype == K_SLIDER) or (reglist.uitype == K_PULLDOWN) or (reglist.uitype == K_EDITBOX) or (reglist.uitype == K_COLORPICKER) or (reglist.uitype == K_BUTTON) or ( (reglist.uitype == K_TEXT) and (reglist.hasbool) ) ) then
                                                                        --If there is no function list yet, then make it
                                                                        if (not MCom.UIFuncList) then
                                                                                MCom.UIFuncList = {};
                                                                        end
                                                                        --If this function is not yet in the list, then make it
                                                                        if (not MCom.UIFuncList[reglist.uivar]) then
                                                                                MCom.UIFuncList[reglist.uivar] = {};
                                                                        end
                                                                        MCom.UIFuncList[reglist.uivar].func = reglist.func;
                                                                        MCom.UIFuncList[reglist.uivar].uitype = reglist.uitype;
                                                                        MCom.UIFuncList[reglist.uivar].hasbool = reglist.hasbool;
                                                                end
                                                        end
                                                end
                                                
                                                --Make our option structure
                                                local kOption = {};
                                                --If uioption is a Khaos style option, use it as our option structure
                                                if (isKhaosOption) then
                                                        kOption = reglist.uioption;
                                                end
                                                
                                                --Setup the varying parts of the option with MCom data
                                                kOption.id = reglist.uivar;
                                                kOption.key = reglist.uikey;
                                                kOption.value = reglist.uivalue;
                                                kOption.text = reglist.uilabel;
                                                kOption.difficulty = reglist.uidiff;
                                                kOption.helptext = reglist.uidesc;
                                                kOption.callback = reglist.uifunc;
                                                if ( reglist.hasbool == nil ) then
                                                        if ( (regtype == MCOM_BOOLT) or (regtype == MCOM_MULTIT) ) then
                                                                reglist.hasbool = true;
                                                        end
                                                end
                                                kOption.check = reglist.hasbool;
                                                kOption.radio = reglist.uiradio;
                                                kOption.type = reglist.uitype;
                                                --Setup the setup structure
                                                if ( type(reglist.uisetup) == "table" ) then
                                                        kOption.setup = reglist.uisetup;
                                                else
                                                        kOption.setup = {};
                                                end
                                                if (reglist.uitype == K_BUTTON) then
                                                        kOption.setup.buttonText = reglist.uitext;
                                                end

                                                --Setup the slider
                                                if (reglist.uitype == K_SLIDER) then
                                                        kOption.setup.sliderMin = reglist.uimin;
                                                        kOption.setup.sliderMax = reglist.uimax;
                                                        kOption.setup.sliderStep = reglist.uistep;
                                                        --If no slider display func has been passed, then make a generic one, that behaves the same
                                                        --as the one in Cosmos
                                                        kOption.setup.sliderLowText = reglist.uisliderlow;
                                                        kOption.setup.sliderHighText = reglist.uisliderhigh;
                                                        kOption.setup.sliderText = reglist.text;
                                                        if (not reglist.uisuffix) then
                                                                reglist.uisuffix = "";
                                                        end
                                                        sliderDisplayFunc = reglist.uisliderfunc;
                                                        if (sliderDisplayFunc == nil) then
                                                                kOption.setup.sliderDisplayFunc = function ( value ) return ( MCom.math.round( ( value * reglist.uimul ) * 100 ) / 100 )..reglist.uisuffix;  end;
                                                        end
                                                end
                                                kOption.setup.options = reglist.choices;
                                                kOption.setup.multiSelect = reglist.multichoice;
                                                kOption.setup.hasOpacity = reglist.hasopacity;
                                                kOption.setup.callOn = reglist.uicallon;

                                                kOption.feedback = reglist.uifeedback;
                                                --If no feedback has been passed, then make a generic feedback function
                                                if (not kOption.feedback) then
                                                        if ( reglist.uitype ~= K_HEADER and reglist.uitype ~= K_BUTTON ) then 
                                                                kOption.feedback = function(state)
                                                                        local retString;        --The string to return
                                                                        --If it is has a check or radio then set the return string up for that
                                                                        if (kOption.check ) then
                                                                                if ( state.checked ) then
                                                                                        retString = string.format(MCOM_FEEDBACK_CHECK, kOption.text, MCOM_CHAT_ENABLED);
                                                                                else
                                                                                        retString = string.format(MCOM_FEEDBACK_CHECK, kOption.text, MCOM_CHAT_DISABLED);
                                                                                end
                                                                        elseif (kOption.radio ) then
                                                                                if ( state.value ) then
                                                                                        retString = string.format(MCOM_FEEDBACK_RADIO, kOption.text, state.value);
                                                                                end
                                                                        end
                                                                        --If it has a slider then set the string up for that
                                                                        if (reglist.uitype == K_SLIDER) then
                                                                                if ( state.slider ) then
                                                                                        if (not retString) then
                                                                                                retString = string.format(MCOM_FEEDBACK_SLIDER, kOption.text, kOption.setup.sliderDisplayFunc(state.slider) );
                                                                                        else
                                                                                                --If we also have a check or radio, then use a version that displays both that, and this
                                                                                                retString = string.format(MCOM_FEEDBACK_SLIDER_M, retString, kOption.setup.sliderDisplayFunc(state.slider) );
                                                                                        end
                                                                                end
                                                                        end
                                                                        if (reglist.uitype == K_EDITBOX) then
                                                                                if ( state.value ) then
                                                                                        if (not retString) then
                                                                                                retString = string.format(MCOM_FEEDBACK_EDITBOX, kOption.text, state.value);
                                                                                        else
                                                                                                --If we also have a check or radio, then use a version that displays both that, and this
                                                                                                retString = string.format(MCOM_FEEDBACK_EDITBOX_M, retString, state.value);
                                                                                        end
                                                                                end
                                                                        end
                                                                        if (reglist.uitype == K_COLORPICKER) then
                                                                                if ( state.color ) then
                                                                                        if (not retString) then
                                                                                                retString = string.format(MCOM_FEEDBACK_COLOR, MCom.string.colorToString(state.color), kOption.text);
                                                                                        else
                                                                                                --If we also have a check or radio, then use a version that displays both that, and this
                                                                                                retString = string.format(MCOM_FEEDBACK_COLOR_M, MCom.string.colorToString(state.color), retString);
                                                                                        end
                                                                                end
                                                                        end
                                                                        if (reglist.uitype == K_CHOICE) then
                                                                                if ( state.value ) then
                                                                                        --Create a text list of options
                                                                                        local options;
                                                                                        if ( type(state.value) == "table" ) then
                                                                                                for curOption = 1, table.getn(state.value) do
                                                                                                        if (options) then
                                                                                                                options = options..", "..state.value[curOption];
                                                                                                        else
                                                                                                                options = state.value[curOption];
                                                                                                        end
                                                                                                end
                                                                                        else
                                                                                                options = state.value;
                                                                                        end
                                                                                        if (not retString) then
                                                                                                retString = string.format(MCOM_FEEDBACK_CHOICE, kOption.text, options);
                                                                                        else
                                                                                                --If we also have a check or radio, then use a version that displays both that, and this
                                                                                                retString = string.format(MCOM_FEEDBACK_CHOICE_M, retString, options);
                                                                                        end
                                                                                end
                                                                        end
                                                                        return retString;
                                                                end
                                                        end
                                                end

                                                --Convert the default check state to Khaos style
                                                if ( reglist.uicheck and ( (reglist.uicheck == 1) or (reglist.uicheck == true) ) ) then
                                                        reglist.uicheck = true;
                                                else
                                                        reglist.uicheck = false;
                                                end
                                                --Convert the disabled check to Khaos format
                                                if ( reglist.uidischeck and ( (reglist.uidischeck == 1) or (reglist.uidischeck == true) ) ) then
                                                        reglist.uidischeck = true;
                                                elseif (reglist.uidischeck == 0) then
                                                        reglist.uidischeck = false;
                                                end

                                                --Setup the default structure
                                                kOption.default = {};
                                                if (reglist.hasbool) then
                                                        kOption.default.checked = reglist.uicheck;
                                                end
                                                if (reglist.uitype == K_SLIDER) then
                                                        kOption.default.slider = reglist.uislider;
                                                        if (kOption.default.slider == nil) then
                                                                kOption.default.slider = reglist.uimax;
                                                        end
                                                        if (kOption.default.slider == nil) then
                                                                kOption.default.slider = reglist.uimin;
                                                        end
                                                        if (kOption.default.slider == nil) then
                                                                kOption.default.slider = 1;
                                                        end
                                                end
                                                if (reglist.uitype == K_COLORPICKER) then
                                                        kOption.default.color = reglist.uicolor;
                                                end
                                                if ( (reglist.uitype == K_PULLDOWN) ) then
                                                        kOption.default.value = reglist.uichoice;
                                                end
                                                if ( (reglist.uitype == K_EDITBOX) ) then
                                                        kOption.default.value = reglist.uistring;
                                                end
                                                
                                                --Setup the disabled structure
                                                --fallback to default, if disabled is not passed
                                                kOption.disabled = {};
                                                if (reglist.hasbool) then
                                                        kOption.disabled.checked = reglist.uidischeck;
                                                        if (kOption.disabled.checked == nil) then
                                                                kOption.disabled.checked = reglist.uicheck;
                                                        end
                                                end
                                                if (reglist.uitype == K_SLIDER) then
                                                        kOption.disabled.slider = reglist.uidisslider;
                                                        if (kOption.disabled.slider == nil) then
                                                                kOption.disabled.slider = reglist.uislider;
                                                        end
                                                        if (kOption.disabled.slider == nil) then
                                                                kOption.disabled.slider = reglist.uimax;
                                                        end
                                                        if (kOption.disabled.slider == nil) then
                                                                kOption.disabled.slider = reglist.uimin;
                                                        end
                                                        if (kOption.disabled.slider == nil) then
                                                                kOption.disabled.slider = 1;
                                                        end
                                                end
                                                if (reglist.uitype == K_COLORPICKER) then
                                                        kOption.disabled.color = reglist.uidiscolor;
                                                        if (kOption.disabled.color == nil) then
                                                                kOption.disabled.color = reglist.uicolor;
                                                        end
                                                end
                                                if ( (reglist.uitype == K_PULLDOWN) ) then
                                                        kOption.disabled.value = reglist.uidisstring;
                                                        if (kOption.disabled.value == nil) then
                                                                kOption.disabled.value = reglist.uistring;
                                                        end
                                                end
                                                if ( (reglist.uitype == K_EDITBOX) ) then
                                                        kOption.disabled.value = reglist.uidischoice;
                                                        if (kOption.disabled.value == nil) then
                                                                kOption.disabled.value = reglist.uichoice;
                                                        end
                                                end
                                                --Setup the option dependencies
                                                kOption.dependencies = reglist.uidep;

                                                --Pull the option set from Khaos
                                                local optionSet = KhaosData.configurationSets[MCom.uisec];
                                                --Will be set to true if we need to register this set(as in, it has not yet been registered)
                                                local needsReg = false;
                                                --If the set didn't yet exist, then create it
                                                if (not optionSet) then
                                                        needsReg = true;        --New set, so we need to register it
                                                        optionSet = {   id = reglist.uisec;
                                                                                                                text = reglist.uiseclabel;
                                                                                                                helptext = reglist.uisecdesc;
                                                                                                                difficulty = reglist.uisecdiff;
                                                                                                                callback =  reglist.uiseccall;
                                                                                                                default = reglist.uisecdef;
                                                                                                                commands = reglist.uiseccom };
                                                end
                                                
                                                --If there is no option structure in this set yet, then make one
                                                if (not optionSet.options) then
                                                        optionSet.options = {};
                                                end
                                                
                                                --Check that this option does not already exist
                                                local alreadyExists = false;
                                                for curOpt = 1, table.getn(optionSet.options) do
                                                        if (optionSet.options[curOpt].id == reglist.uivar) then
                                                                alreadyExists = true;
                                                                break;
                                                        end
                                                end
                                                
                                                --Only proceed further if the option doesn't already exist
                                                if (not alreadyExists) then
                                                        --Default the option insertion position to the end of the option list
                                                        local optionPos = table.getn(optionSet.options);
                                                        
                                                        --If we have a header specified, then try to find the last position after it
                                                        --and if it doesn't exist yet.. then make it
                                                        if (MCom.uisep) then
                                                                local foundHeader = false;      --Set true if we find the header
                                                                --Try to find the header
                                                                for curOpt = 1, table.getn(optionSet.options) do
                                                                        --If we have found the header, and we have made it to the next header
                                                                        --then break here, to put the option just before this header
                                                                        if (foundHeader) then
                                                                                if (optionSet.options[curOpt].type == K_HEADER) then
                                                                                        break;
                                                                                end
                                                                        end
                                                                        --If we found the header, set foundHeader
                                                                        if (optionSet.options[curOpt].id == MCom.uisep) then
                                                                                foundHeader = true;
                                                                        end
                                                                        --Set the current option position to this postition
                                                                        optionPos = curOpt;
                                                                end
                                                                --If we didn't find the passed header, then make it, at the last spot in the list
                                                                if (not foundHeader) then
                                                                        --Make sure a header was passed
                                                                        if (reglist.uisep) then
                                                                                --If no label was passed for the header, use the header variable name
                                                                                if (not reglist.uiseplabel) then
                                                                                        reglist.uiseplabel = reglist.uisep;
                                                                                end
                                                                                --If no description was passed for the header, use the header label
                                                                                if (not reglist.uisepdesc) then
                                                                                        reglist.uisepdesc = reglist.uiseplabel;
                                                                                end
                                                                                --Make the header option structure
                                                                                local hOption = {       id = reglist.uisep;
                                                                                                                                                        text = reglist.uiseplabel;
                                                                                                                                                        helptext = reglist.uisepdesc;
                                                                                                                                                        type = K_HEADER;
                                                                                                                                                        difficulty = reglist.uisepdiff; };
                                                                                --Itterate the option position up one
                                                                                optionPos = optionPos + 1;
                                                                                --Shove the header in the last slot in the list
                                                                                table.insert(optionSet.options, optionPos, hOption);
                                                                        else
                                                                                --If we didn't find the header, and there wasn't one passed... then clean out the
                                                                                --stored header
                                                                                MCom.uisep = nil;
                                                                        end                                                             
                                                                end
                                                        end
                                                        
                                                        --Shove the option into the next spot in the table
                                                        table.insert(optionSet.options, optionPos + 1, kOption);

                                                        if (needsReg) then
                                                                --If the option set hasn't been registered yet.. then register it
                                                                Khaos.registerOptionSet(MCom.uifolder, optionSet);
                                                        else
                                                                --If the option set has been registered, then we need to validate it, to make sure it's kuhl
                                                                Khaos.validateOptionSet(optionSet);
                                                        end
                                                end
                                        end
                                end
                        elseif (CosmosMaster_Init and reglist.uivar and reglist.uitype and reglist.uilabel ) then
                                --Only register valid Cosmos types
                                if (    (reglist.uitype == "SECTION") or (reglist.uitype == "SEPARATOR") or (reglist.uitype == "BUTTON") or
                                                        (reglist.uitype == "CHECKBOX") or (reglist.uitype == "SLIDER") or (reglist.uitype == "BOTH")    ) then
                                        --If we don't have Khaos, but do have Cosmos, then register for Cosmos
                                        --If the section has been passed, then register it
                                        if (reglist.uisec) then
                                                --If the section variable name is not prefixed with COS_ then put it on there
                                                if ( (string.len(reglist.uisec) < 4) or (string.sub(reglist.uisec, 1, 4) ~= "COS_") ) then
                                                        reglist.uisec = "COS_"..reglist.uisec;
                                                end
                                                --Register the section
                                                Cosmos_RegisterConfiguration(reglist.uisec, "SECTION", reglist.uiseclabel, reglist.uisecdesc);
                                        end
                                        --If the separator has been passed, then register it
                                        if (reglist.uisep) then
                                                --If the separator variable name is not prefixed with COS_ then put it on there
                                                if ( (string.len(reglist.uisep) < 4) or (string.sub(reglist.uisep, 1, 4) ~= "COS_") ) then
                                                        reglist.uisep = "COS_"..reglist.uisep;
                                                end
                                                --If no label is passed for the separator, then use the variable name
                                                if (not reglist.uiseplabel) then
                                                        reglist.uiseplabel = reglist.uisep;
                                                end
                                                --If no description is passed for the separator, then use the label
                                                if (not reglist.uisepdesc) then
                                                        reglist.uisepdesc = reglist.uiseplabel;
                                                end
                                                --Register the seperator
                                                Cosmos_RegisterConfiguration(reglist.uisep, "SEPARATOR", reglist.uiseplabel, reglist.uisepdesc);
                                        end

                                        --If we don't have a uifunc yet, then wrap the func
                                        if ( (not reglist.uifunc) and reglist.func ) then
                                                reglist.uifunc = function (checked, value) MCom.SetFromUI(reglist.uivar, checked, value); end;
                                                
                                                --Add the function to the list of callback functions
                                                if (reglist.uitype) then
                                                        --Only do this for UI elements that have options
                                                        if ((reglist.uitype == "CHECKBOX") or (reglist.uitype == "SLIDER") or (reglist.uitype == "BOTH") or (reglist.uitype == "BUTTON")) then
                                                                if (not MCom.UIFuncList) then
                                                                        MCom.UIFuncList = {};
                                                                end
                                                                if (not MCom.UIFuncList[reglist.uivar]) then
                                                                        MCom.UIFuncList[reglist.uivar] = {};
                                                                end
                                                                MCom.UIFuncList[reglist.uivar].func = reglist.func;
                                                                MCom.UIFuncList[reglist.uivar].uitype = reglist.uitype;
                                                                MCom.UIFuncList[reglist.uivar].hasbool = reglist.hasbool;
                                                        end
                                                end
                                        end
                                        
                                        --Convert the default check state to Cosmos style
                                        if ( reglist.uicheck and ( (reglist.uicheck == 1) or (reglist.uicheck == true) ) ) then
                                                reglist.uicheck = 1;
                                        else
                                                reglist.uicheck = 0;
                                        end
                                        
                                        --Register with Cosmos if available
                                        Cosmos_RegisterConfiguration(reglist.uivar, reglist.uitype, reglist.uilabel, reglist.uidesc,
                                                reglist.uifunc, reglist.uicheck, reglist.uislider, reglist.uimin, reglist.uimax, reglist.uitext,
                                                reglist.uistep, reglist.uitexton, reglist.uisuffix, reglist.uimul
                                        );
                                end
                        end
                        
                        --If we have enough data to register a slash command, then do it
                        --We need to make sure to pass the right ordered var data to the function
                        local comVar = reglist.varbool;
                        local comVarMulti = reglist.varnum;
                        if (regtype == MCOM_STRINGT) then
                                comVarMulti = reglist.varstring;
                        elseif (regtype == MCOM_CHOICET) then
                                comVarMulti = reglist.varchoice;
                        elseif (regtype == MCOM_COLORT) then
                                comVarMulti = reglist.varcolor;
                        end
                        if (not comVar) then
                                comVar = comVarMulti;
                                comVarMulti = nil;
                        end
                        if (reglist.command and reglist.func) then
                                --If no command help was passed, but a ui description was, then use the ui description
                                if ( ( not reglist.bomhelp ) and ( reglist.uidesc ) ) then
                                        reglist.bomhelp = reglist.uidesc;
                                end
                                MCom.addSlashCom(reglist.command, reglist.func, reglist.comaction, reglist.comsticky, reglist.comhelp, regtype, reglist.uisec, reglist.uivar, comVar, comVarMulti, reglist.varmin, reglist.varmax, reglist.commul, reglist.cominmul, reglist.hasbool, reglist.choices, reglist.multichoice, reglist.hasopacity, reglist.extrahelp);
                        end
                        --If we have enough data to register a super slash command, then do it
                        if (reglist.supercom) then
                                MCom.addSlashSuperCom(reglist.supercom, reglist.comaction, reglist.comsticky, reglist.comhelp, reglist.extrahelp);
                        end
                        --If we have enough data to register a sub slash command, then do it
                        if (reglist.supercom and reglist.subcom and reglist.func) then
                                --If no sub command help was passed, but a ui description was, then use the ui description
                                if ( ( not reglist.subhelp ) and ( reglist.uidesc ) ) then
                                        reglist.subhelp = reglist.uidesc;
                                end
                                MCom.addSlashSubCom(reglist.supercom, reglist.subcom, reglist.func, reglist.subhelp, regtype, reglist.uisec, reglist.uivar, comVar, comVarMulti, reglist.varmin, reglist.varmax, reglist.commul, reglist.cominmul, reglist.hasbool, reglist.choices, reglist.multichoice, reglist.hasopacity);
                        end

                        --If we should be adding an info option, then handle this now
                        if (reglist.infotext) then
                                --Setup a function to display addon information, if data is available for it
                                local infofunc = nil;
                                if (reglist.infotext) then
                                        --If reglist.infotext isn't already a table, then turn it into one
                                        if (type(reglist.infotext) ~= "table") then
                                                reglist.infotext = { reglist.infotext };
                                        end
                                        --Setup a default info title if we dont have one
                                        local curInfoTitle = reglist.infotitle;
                                        if (not curInfoTitle) then
                                                curInfoTitle = MCOM_HELP_GENERIC_TITLE;
                                                if (reglist.name) then
                                                        curInfoTitle = string.format(MCOM_HELP_TITLE, reglist.name);
                                                end
                                        end
                                
                                        --If this is not a boolean, then add the slash command info to the end of the text as a new page
                                        if ( type(reglist.infotext) ~= "boolean" ) then
                                                infofunc = function ()
                                                        --Get the info text and title
                                                        local infotext = MCom.table.copy(reglist.infotext);
                                                        local infotitle = curInfoTitle;
                                                        --If the text isn't a table turn it into one
                                                        if (type(infotext) ~= "table" ) then
                                                                infotext = { infotext };
                                                        end
                                                        if (reglist.supercom) then
                                                                --Add the slash command info on to it
                                                                infotext[table.getn(infotext) + 1] = MCom.PrintSlashCommandInfo(MCom.getComID(reglist.supercom), true);
                                                        end
                                                        --Show the text frame
                                                        MCom.textFrame( { text = infotext; title = infotitle; } );
                                                end;
                                        elseif ( reglist.supercom ) then
                                                infofunc = function ()
                                                        --Set the text as the slash command info
                                                        local infotext = MCom.PrintSlashCommandInfo(MCom.getComID(reglist.supercom), true);
                                                        local infotitle = curInfoTitle;
                                                        --Show the text frame
                                                        MCom.textFrame( { text = infotext; title = infotitle; } );
                                                end;
                                        end
                                end
                                
                                --If we have an info function, then add options to access it
                                if (infofunc) then
                                        --Use the generic description
                                        local infoDesc = MCOM_HELP_GENERIC;
                                        --If a name has been passed for this mod, then use it in the description
                                        if (reglist.name) then
                                                infoDesc = string.format(MCOM_HELP_CONFIG_INFO, reglist.name);
                                        end
                                        --If we have Khaos or Cosmos then register with them
                                        if (Khaos or CosmosMaster_Init and reglist.name) then
                                                --Setup the difficulty of the help button
                                                local infodiff = reglist.uisecdiff;
                                                if (not infodiff) then
                                                        infodiff = reglist.uidiff;
                                                end
                                                if (not infodiff) then
                                                        infodiff = 1;
                                                end
                                                --Setup the name to display
                                                local infoName = string.format(MCOM_HELP_CONFIG, reglist.name);
                                                --Register the option
                                                MCom.registerSmart( {
                                                        uivar = reglist.name.."MComInfo";                                                                       --The option name for the UI
                                                        uitype = K_BUTTON;                                                                                                                              --The option type for the UI
                                                        uilabel = infoName;                                                                                                                             --The label to use for the checkbox in the UI
                                                        uidesc = infoDesc;                                                                                                                              --The description to use for the checkbox in the UI
                                                        uidiff = infodiff;                                                                                                                              --The option's difficulty in Khaos
                                                        uifunc = infofunc;                                                                                                                              --The function to call
                                                        uitext = MCOM_HELP_GENERIC_TITLE;                                                                       --The text to show on the button
                                                } );
                                        end
                                        --Register the sub slash command
                                        if ( reglist.supercom ) then
                                                MCom.registerSmart( {
                                                        supercom = reglist.supercom;
                                                        subcom = MCOM_HELP_COMMAND;
                                                        subhelp = infoDesc;
                                                        comtype = MCOM_SIMPLET;
                                                        func = infofunc;
                                                } );
                                        end
                                end
                        end
                end
        end;
        
        --[[
                getStringVar ( string value )
                        Accepts a variable as a string, and returns the value.
                        However this can parse complex variable names that contain .
                        such as "Something.Variable"
                        
                        It does not handle "Something['Variable']".. Just use the .
                        format instead.  This also works for number indexes.
                
                Args:
                        varString - the variable to get, encapsulated in a string, ex:
                        "Something.Variable.Monkey.Hippo"
         
                Returns:
                        the contents of the variable in the passed string
        ]]--
        MCom.getStringVar = function (varString)
                if (Sea and Sea.util and Sea.util.getValue) then
                        return Sea.util.getValue(varString);
                else
                        --Legorols get string var code, no GCs, and no need to store each entry
                        if ( type(varString) ~= "string" ) then
                                return nil;
                        end;
                        
                        -- Table we reuse with calls to split
                        if ( not MCom.valueTable ) then
                                MCom.valueTable = {};
                        end
                        
                        -- Split the variable name at ".", first field is a global name
                        local fields = MCom.util.split(varString, ".", MCom.valueTable);
                        local encloser, member = getglobal(fields[1]), fields[2];
                        
                        -- If encloser is the only field, it's a global, return its value
                        if ( not member ) then
                                return encloser;
                        end
                        
                        -- If there are subsequent fields present, get to deeper levels
                        for i = 3, table.getn(fields) do
                                if ( type(encloser) ~= "table" ) then
                                        return nil;
                                end
                                encloser = encloser[member];
                                member = fields[i];
                        end
                        
                        -- Encloser is now the last but one field, member is the last field
                        if ( type(encloser) == "table" ) then
                                return encloser[member];
                        end
                        -- Error occured, encloser is not a table, return nil
                end
        end;
        --Alias for compatability
        MCom.stringToVar = MCom.getStringVar;
        
        --[[
                stringVarToGetFunc ( string varString )
                        Accepts a variable as a string, and returns a function that
                        returns the value.
                        However this can parse complex variable names that contain .
                        such as "Something.Variable"
                        
                        This is alot like getStringVar.  However, getStringVar has to
                        generate several objects that will need to be garbage
                        collected.  The function returned by stringVarToFunc does
                        not generate any amount of GCs worth worying about.  So if
                        you are needing to do this very often, like OnUpdate, then
                        it is best to use this function to convert to a function,
                        and simply call that functin to get the data you need.                  

                        It does not handle "Something['Variable']".. Just use the .
                        format instead.  This also works for number indexes.
                
                Args:
                        varString - the variable to get, encapsulated in a string, ex:
                        "Something.Variable.Monkey.Hippo"
         
                Returns:
                        a function that when called will return the data in the passed variable
        ]]--
        MCom.stringVarToGetFunc = function (varString)
                if ( type(varString) == "string" ) then
                        --Seperate the variable by the .'s into a list
                        local valList = MCom.util.split(varString, ".");
                        --The function we will return
                        local varFunc;
                        
                        --Only proceed if we have a variable to work with
                        if (valList and valList[1]) then
                                --If it's a table make it a function that will parse the parts
                                if (getn(valList) > 1) then
                                        --Create the function
                                        varFunc = function ()
                                                --Get the global variable
                                                local value = getglobal(valList[1]);
                                                --Go through each entry in the table and get that variable
                                                for curPart = 2, getn(valList) do
                                                        --Only get the variable if it is a table
                                                        if ( ( type(value) == "table" ) and value[ valList[curPart] ] ) then
                                                                --Get the variable
                                                                value = value[ valList[curPart] ];
                                                        else
                                                                --Something was invalid, return nil
                                                                return;
                                                        end
                                                end
                                                --We got the value, so return it
                                                return value;
                                        end;
                                else
                                        --This is a simple variable, so just return the global
                                        varFunc = function ()
                                                return getglobal(valList[1]);
                                        end;
                                end
                        end
                        --Return the function
                        return varFunc;
                end
        end;
        
        --[[
                setStringVar ( string varString, value )
                        Sets a variable, specified by a string, to a value.
                        However this can parse complex variable names that contain .
                        such as "Something.Variable"
                        
                        It does not handle "Something['Variable']".. Just use the .
                        format instead.  This also works for number indexes.
                
                Args:
                        varString - the variable to set, encapsulated in a string, ex:
                                "Something.Variable.Monkey.Hippo"
                        value - the value to set the variable to, can be any type
        ]]--
        MCom.setStringVar = function (varString, value)
                if (Sea and Sea.util and Sea.util.setValue) then
                        return Sea.util.setValue(varString, value);
                else
                        --Legorols set string var code, no GCs, and no need to store each entry
                        if ( type(varString) ~= "string" ) then
                                return false;
                        end;
                        
                        -- Table we reuse with calls to split
                        if ( not MCom.valueTable ) then
                                MCom.valueTable = {};
                        end
                        
                        -- Split the variable name at ".", first field is a global name
                        local fields = MCom.util.split(varString, ".", MCom.valueTable);
                        local encloser, member = getglobal(fields[1]), fields[2];
                        
                        -- If encloser is the only field, variable is a global, set its value
                        if ( not member ) then
                                setglobal(varString, value);
                                return true;
                        end
                        
                        -- If there are subsequent fields present, get to deeper levels
                        for i = 3, table.getn(fields) do
                                if ( type(encloser) ~= "table" ) then
                                        return false;
                                end
                                encloser = encloser[member];
                                member = fields[i];
                        end
                        
                        -- Encloser is now the last but one field, member is the last field
                        if ( type(encloser) == "table" ) then
                                encloser[member] = value;
                                return true;
                        end
                        
                        -- Error occured, encloser is not a table
                        return false;
                end
        end;
        
        --[[
                stringVarToSetFunc ( string varString )
                        Returns a function that can be used to set the passed string
                        to a value.  However this can parse complex variable names
                        that contain . such as "Something.Variable"
                        
                        This is alot like setStringVar.  However, setStringVar has to
                        generate several objects that will need to be garbage
                        collected.  The function returned by stringVarToSetFunc does
                        not generate any amount of GCs worth worying about.  So if
                        you are needing to do this very often, like OnUpdate, then
                        it is best to use this function to convert to a function,
                        and simply call that functin to set the data you need.                  

                        It does not handle "Something['Variable']".. Just use the .
                        format instead.  This also works for number indexes.
                
                Args:
                        varString - the variable to set, encapsulated in a string, ex:
                        "Something.Variable.Monkey.Hippo"
         
                Returns:
                        function ( number value) - a function that when called will
                        set the string passed here, to  the value passed to the function.
        ]]--
        MCom.stringVarToSetFunc = function (varString)
                if ( type(varString) == "string" ) then
                        --Seperate the variable by the .'s into a list
                        local valList = MCom.util.split(varString, ".");
                        --The function we will return
                        local varFunc;
                        
                        --Only proceed if we have a variable to work with
                        if (valList and valList[1]) then
                                --If it's a table make it a function that will parse the parts
                                if (getn(valList) > 1) then
                                        --Create the function
                                        varFunc = function (value)
                                                --Get the global variable
                                                local var = getglobal(valList[1]);
                                                --Go through each entry in the table and get that variable
                                                for curPart = 2, getn(valList) do
                                                        --If we have reached the last entry in the list, then set it
                                                        if ( curPart == getn(valList) ) then
                                                                if ( type(var) == "table" ) then
                                                                        var[ valList[curPart] ] = value;
                                                                else
                                                                        return;
                                                                end
                                                        else
                                                                --Only get the variable if it is a table
                                                                if ( ( type(var) == "table" ) and var[ valList[curPart] ] ) then
                                                                        --Get the variable
                                                                        var = var[ valList[curPart] ];
                                                                else
                                                                        --Something was invalid, return nil
                                                                        return;
                                                                end
                                                        end
                                                end
                                        end;
                                else
                                        --This is a simple variable, so just return the global
                                        varFunc = function (value)
                                                setglobal(valList[1], value);
                                        end;
                                end
                        end
                        --Return the function
                        return varFunc;
                end
        end;
        
        --[[
                updateVar ( string varname, value [, string vartype, number varmin, number varmax] )
                        updates the variable contained in varname, to value.
                        Handles things different based on the type of var varname is.
                        If it should be a bool, then it only accepts 1 and 0, or -1 to invert the current setting.
                        For number, it makes sure it is in the range varmin and varmax.
                
                Args:
                        varname - name of the variable to update, wrapped in a string, can be complex like "Something.Variable"
                        value - what to set it to, should be 1, 0, or -1 for bool, any number for number type, or any string for string type
        
                Optional: 
                        vartype - should be one of the MCOM_ types
                        varmin - specifies the minimum value for a number type
                        varmax - specifies the maximum value for a number type
         
                Returns:
                        if the value changed from its origional value, returns true
        ]]--
        MCom.updateVar = function (varname, value, vartype, varmin, varmax)
                if (varname and value) then
                        -- store the old value of the variable
                        local oldValue = MCom.getStringVar(varname);

                        if (vartype == MCOM_BOOLT) then
                                --If a -1 is passed, invert the value
                                if (value and (value == -1)) then
                                        if (oldValue == 1) then
                                                value = 0;
                                        else
                                                value = 1;
                                        end
                                end
                                
                                --Update the value
                                if (value and (value==1)) then
                                        value = 1;
                                else
                                        value = 0;
                                end
                        elseif (vartype == MCOM_NUMT) then
                                --if its a number and max/min were specified, make sure it's in range
                                if (varmin and (value < varmin)) then
                                        value = varmin;
                                end
                                if (varmax and (value > varmax)) then
                                        value = varmax;
                                end
                        end
                        
                        local didUpdate = false;
                        if (vartype == MCOM_COLORT) then
                                --If we don't have an old value, then make one
                                if ( not oldValue ) then
                                        didUpdate = true;
                                        oldValue = {};
                                end
                                --if its a color then make sure the color parts are in range
                                if (value.r) then
                                        if (value.r > 1) then
                                                value.r = 1;
                                        end
                                        if (value.r < 0) then
                                                value.r = 0;
                                        end
                                        if (oldValue.r ~= value.r) then
                                                didUpdate = true;
                                        end
                                else
                                        value.r = oldValue.r;
                                end
                                if (value.g) then
                                        if (value.g > 1) then
                                                value.g = 1;
                                        end
                                        if (value.g < 0) then
                                                value.g = 0;
                                        end
                                        if (oldValue.g ~= value.g) then
                                                didUpdate = true;
                                        end
                                else
                                        value.g = oldValue.g;
                                end
                                if (value.b) then
                                        if (value.b > 1) then
                                                value.b = 1;
                                        end
                                        if (value.b < 0) then
                                                value.b = 0;
                                        end
                                        if (oldValue.b ~= value.b) then
                                                didUpdate = true;
                                        end
                                else
                                        value.b = oldValue.b;
                                end
                                if (value.opacity) then
                                        if (value.opacity > 1) then
                                                value.opacity = 1;
                                        end
                                        if (value.opacity < 0) then
                                                value.opacity = 0;
                                        end
                                        if (oldValue.opacity ~= value.opacity) then
                                                didUpdate = true;
                                        end
                                else
                                        value.opacity = oldValue.opacity;
                                end
                        else    
                                --if the value changed, return true
                                if (value ~= oldValue) then
                                        didUpdate = true;
                                end
                        end
                        
                        if (didUpdate) then
                                MCom.setStringVar(varname, value);
                                return true;
                        end
                end
        end;

        --[[
                printStatus ( string text, [string/number/bool] value, bool isbool, bool show )
                        If Cosmos is not found printStatus will print out a status message, intended to let user know when an option has
                        been changed, when there is no GUI available.
                
                Args:
                        text -          the text to print, this can include a %s, and value(or enabled/disabled for bool) will be put in place of the %s
                                                                Ex: "This option has been %s" for bool, or "This option has been set to %s" for number or string
        
                Optional: 
                        value -         what value to display, can be a string, a number, or a bool
                        isbool -        if this is true, then the value will be treated as a bool, and if true(or 1) then the %s will contain
                                                                the world "Enabled" or "Disabled" for false(or 0)
                        show - if this is true, then the text will be printed whether there is a UI or not
        ]]--
        MCom.printStatus = function (text, value, isbool, show)
                if ( ( not MCom.hasUI() ) or show ) then
                        --Convert to string
                        if (type(value) == "number") then
                                value = tostring(value);
                        end
                        --If it's boolean or nill convert to 1 or 0
                        if ((type(value) == "boolean") or (type(value) == "nil")) then
                                if (value) then
                                        value = "1";
                                else
                                        value = "0";
                                end
                        end
                        if (type(value) == "string") then
                                local outText = value;
                                --If it's a bool convert to Enabled/Disabled
                                if (isbool) then
                                        outText = MCOM_CHAT_DISABLED;
                                        if (value == "1") then
                                                outText = MCOM_CHAT_ENABLED;
                                        end
                                end
                                --Format and print the message
                                local msg = string.format(text, outText);
                                MCom.IO.printc(ChatTypeInfo["SYSTEM"], msg);
                        end
                end     
        end;
        
        --[[
                hasUI ( )
                        Tells whether or not a UI, like Cosmos or Khaos is present.
         
                Returns:
                        true - there is a UI
                        false - there is no UI
        ]]--
        MCom.hasUI = function (varString)
                local hasUI = true;
                if ( ( CosmosMaster_Init == nil ) and ( Khaos == nil ) ) then 
                        hasUI = false;
                end
                
                return hasUI;
        end;
        
        --[[
                updateUI ( string slashcom, string subcom )
                        Updates the UI(Cosmos or Khaos) with the values of the variable associated with the slash command
                        passed to the function.  If this is done on a super slash command, then all sub commands
                        will be updated, unless a specific on is specified.
                
                Args:
                        slashcom - The slash commmand, or super slash command to update the variable from.
        
                Optional: 
                        subcom -        If slashcom is a super slash command, you can use this to specify which slash
                                                                command to update.
        ]]--
        MCom.updateUI = function (slashcom, subcom)
                if (MCom.SlashComs) then
                        --Get the command IDs
                        local comid, subcomid = MCom.getComID(slashcom, subcom);
                        if (comid) then
                                --Get the command
                                local command = MCom.SlashComs[comid];
                                --If we have a subcommand, then lets use it
                                if (subcomid) then
                                        command = { command.commands[subcomid] };
                                elseif (command.commands) then
                                        command = command.commands;
                                end
                                
                                --If command isnt a table, then turn it into one
                                if (type(command) ~= "table") then
                                        command = { command };
                                end
                                local didUpdate = nil;
                                if (KhaosData and KhaosData.configurationSets) then
                                        --If we have Khaos around, then lets update for it
                                        local curCom = nil;
                                        local newValMulti = nil;
                                        local newVal = nil;
                                        --Go trhough all commands and update them
                                        for curComID in command do
                                                --Grab the current command structure
                                                curCom = command[curComID];
                                                if (curCom.uisec and KhaosData.configurationSets[curCom.uisec] and curCom.uivar and curCom.comvar) then
                                                        --get the value of the variable
                                                        newVal = MCom.getStringVar(curCom.comvar);
                                                        if (newVal) then
                                                                --Grab the second variable, if there is one
                                                                newValMulti = MCom.getStringVar(curCom.comvarmulti);
                                                                
                                                                --Deault param to change is value
                                                                local param = "value";
                                                                --If it's a boolean, or we have a boolean as well.. then update the boolean part
                                                                if ( (curCom.comtype == MCOM_BOOLT) or (curCom.comtype == MCOM_MULTIT) or curCom.hasbool) then
                                                                        --Make sure the value is in true/false form
                                                                        if (newVal == 1) then
                                                                                newVal = true;
                                                                        else
                                                                                newVal = false;
                                                                        end
                                                                        --Update the value
                                                                        Khaos.setSetKeyParameter(curCom.uisec, curCom.uivar, "checked", newVal);
                                                                end
                                                                --If it isn't a boolean type then proccess either the other types, or secondary part
                                                                if ( curCom.comtype ~= MCOM_BOOLT ) then
                                                                        --If we have a second part variable, then use it now
                                                                        if (newValMulti) then
                                                                                newVal = newValMulti;
                                                                        end
                                                                        
                                                                        --Handle number types as sliders
                                                                        if ( (curCom.comtype == MCOM_NUMT) or (curCom.comtype == MCOM_MULTIT) ) then
                                                                                param = "slider";
                                                                        end
                                                                        
                                                                        --Handle color types as color pickers
                                                                        if (curCom.comtype == MCOM_COLORT) then
                                                                                param = "color";
                                                                        end
                                                                        
                                                                        --Update the value
                                                                        Khaos.setSetKeyParameter(curCom.uisec, curCom.uivar, param, newVal);
                                                                end
                                                                didUpdate = true;
                                                        end
                                                end
                                        end
                                        --If we updated something, then update the Khaos display
                                        if (didUpdate) then
                                                Khaos.refresh();
                                        end
                                else
                                        --We only need to update Cosmos if it exists
                                        if (CosmosMaster_Init) then
                                                local curCom = nil;
                                                local newValMulti = nil;
                                                local newVal = nil;
                                                --Go trhough all commands and update them
                                                for curComID in command do
                                                        curCom = command[curComID];
                                                        if (curCom.uivar and curCom.comvar) then
                                                                --get the value of the variable
                                                                newVal = MCom.getStringVar(curCom.comvar);
                                                                if (newVal) then
                                                                        newValMulti = MCom.getStringVar(curCom.comvarmulti);
                                                                        if ((curCom.comtype ~= MCOM_MULTIT) or ((curCom.comtype == MCOM_MULTIT) and newValMulti)) then
                                                                                --if its a boolean, then set the checkbox
                                                                                if ((curCom.comtype == MCOM_BOOLT) or (curCom.comtype == MCOM_MULTIT)) then
                                                                                        Cosmos_UpdateValue(curCom.uivar, CSM_CHECKONOFF, newVal);
                                                                                        didUpdate = true;
                                                                                end
                                                                                --if its a number, then set the slider
                                                                                if ((curCom.comtype == MCOM_NUMT) or (curCom.comtype == MCOM_MULTIT)) then
                                                                                        if (curCom.comtype == MCOM_MULTIT) then
                                                                                                newVal = newValMulti;
                                                                                        end
                                                                                        Cosmos_UpdateValue(curCom.uivar, CSM_SLIDERVALUE, newVal);
                                                                                        didUpdate = true;
                                                                                end
                                                                        end
                                                                end
                                                        end
                                                end
                                                --If we updated something, then update the Cosmos display
                                                if (didUpdate) then
                                                        CosmosMaster_DrawData();
                                                end
                                        end
                                end
                        end
                end
        end;
        
        
        --[[
                getComID ( [string/number] slashcom, string subcom )
                        Gets the ID of the slashcom in the slash commands list, as well as a
                        sub slash command, if you specify that you want a sub commands ID.
                
                Args:
                        slashcom -      The slash commmand, or super slash command to get the ID of.
                                                                        If you pass the ID itself, that ID will be used when getting
                                                                        the sub command.  This can be a list of commands, instead of
                                                                        just one, in which case, it will return the first one in the
                                                                        list that it finds. Don't forget the / ex. "/command"
                Optional:
                        slashcom -      The sub command you want to get, if you want one.  This can
                                                                        be a list instead of just one command, the first one found
                                                                        will be used.
                        
                Returns:
                        commandid - If it finds the command, it returns the ID, otherwise it returns nil.
                        subcommand - If it finds the subcommand it also returns that, otherwise, nil.
        ]]--
        MCom.getComID = function (command, subcom)
                local commandid = nil;
                local subcommandid = nil;
                if (MCom.SlashComs) then
                        --If the ID was passed, then use it
                        if ((type(command) == "number") and MCom.SlashComs[command]) then
                                commandid = command;
                        else
                                --make sure command is a table
                                if (type(command) ~= "table") then
                                        command = {command};
                                end
                                --find the command in the table
                                for curCom in command do
                                        for curListCom in MCom.SlashComs do
                                                if (MCom.SlashComs[curListCom].basecommand) then
                                                        for curBaseCom in MCom.SlashComs[curListCom].basecommand do
                                                                if (MCom.SlashComs[curListCom].basecommand[curBaseCom] == command[curCom]) then
                                                                        commandid = curListCom;
                                                                        break;
                                                                end
                                                        end
                                                        if (commandid) then
                                                                break;
                                                        end
                                                end
                                        end
                                end
                        end                     
                        
                        if (commandid and subcom) then
                                --make sure sub command is a table
                                if (type(subcom) ~= "table") then
                                        subcom = {subcom};
                                end
                                --Try and find the subcommand in the list
                                for curSub in subcom do
                                        for curCom in MCom.SlashComs[commandid].commands do
                                                if (MCom.SlashComs[commandid].commands[curCom].command) then
                                                        for curComCom in MCom.SlashComs[commandid].commands[curCom].command do
                                                                if (MCom.SlashComs[commandid].commands[curCom].command[curComCom] == subcom[curSub]) then
                                                                        subcommandid = curCom;
                                                                        break;
                                                                end
                                                        end
                                                        if (subcommandid) then
                                                                break;
                                                        end
                                                end
                                        end
                                end
                        end                     
                end
                return commandid, subcommandid;
        end;

        --[[
                saveConfig ( {reglist} )
                        This will store all of the variables you want into a per realm, per character table(MComStorage) inside the passed variable.
                        This is meant to facilatate storing/loading variables on a per realm, per character basis.  You must register the passed
                        variable for saving, yourself.
                        
                Args:
                        reglist - This contains all options for this save procedure
                                {
                                Required:
                                        (string) configVar -    The name of the config variable, this should have been registered for save by you, and must be a table with a simple
                                                                                                                                variable name.  IE no .'s or []'s
                                
                                Optional:
                                        (string) storeVar -     The name of the variable to load/store the data in.  If not passed then configVar.MComStorage is used.  Remember to register
                                                                                                                        it for saving.
                                        (string) exactVar -     If you pass this, then data will be stored in this var, regardless of realm/character.  It will go into this exact var.  This
                                                                                                                        takes precidence over storeVar.
                                        (string) realm  - This allows you to specify the realm to store to, if not passed, then the current realm will be used.
                                        (string) character      - This allows you to specify the character to store to, if not passed, then the current character will be used.
                                        NOTE: For all the following, this will only work on root level variables.  I.E. Whatever_Config.Variable.  For this you would pass "Variable"
                                        (string or table) saveList -    The names of all variables in the config to be stored, if this is not passed, then MCom will try to store
                                                                                                                                                                all variables except the MComStorage variable.
                                        (string or table) ignoreList - The names of any variables that you want MCom to not store.
                                        (string or table) uiList -      These variables will only be stored if there is no UI available.  Any options that you have the UI controlling
                                                                                                                                                        should be included in here, so you can leave it up to the UI to properly load/save them.
                                        (string or table) nonUIList -   If this list is declared, then uiList will be ignored, and all variables, except these, will be considered UI
                                                                                                                                                                variables.
                                        (string or table) forceList -   After going through the normal vars, MCom will go through and save these vars, even if they are nil.  This list
                                                                                                                                                                is affected by the rules set by the above lists as well.
                                }
                
                Returns:
                                true - Some data was saved
                                false - No data was saved
        ]]--
        MCom.saveConfig = function ( reglist )
                --We will set this true, if we saved any data
                local didSave = false;
                --Make sure we have the required info in the right form
                if ( reglist and ( type(reglist) == "table" ) and reglist.configVar ) then
                        --Get the config variable table
                        local varTable = MCom.getStringVar(reglist.configVar);
                        --Only proceed if the config variable is a table
                        if ( type(varTable) == "table" ) then
                                --Get the realm and character name
                                local realm = reglist.realm;
                                if (not realm) then
                                        realm = GetCVar("RealmName");
                                end
                                local character = reglist.character;
                                if (not character) then
                                        character = UnitName("player")
                                end
                                
                                --Setup the variable to store data in.
                                local storeVar = MCom.getStringVar(reglist.exactVar);
                                --If we don't have an exactVar and we have the server and character name then generate the storeVar
                                if ( (not storeVar) and realm and character and ( ( character ~= UKNOWNBEING ) and ( character ~= UNKNOWNOBJECT ) ) ) then
                                        --Get the storage var if one was passed
                                        storeVar = MCom.getStringVar(reglist.storeVar);
                                        if (not storeVar) then
                                                --If the MComStorage variable isn't there yet, or isn't a table, then set it as an empty table
                                                if (type(varTable.MComStorage) ~= "table") then
                                                        varTable.MComStorage = {};
                                                end
                                                storeVar = varTable.MComStorage;
                                        end
                                        
                                        --If this realm doesn't exist, then create it
                                        if (not storeVar[realm]) then
                                                storeVar[realm] = {};
                                        end
                                        --If this character doesn't exist, then create it
                                        if (not storeVar[realm][character]) then
                                                storeVar[realm][character] = {};
                                        end
                                        --Set storeVar to use the current realm/char
                                        storeVar = storeVar[realm][character];
                                end
                                
                                --If we have the variable to store to, then we are good to go
                                if (storeVar) then
                                        --Go through all the variables in the table
                                        for curVar in varTable do
                                                --Ignore the MComStorage variable
                                                if (curVar ~= "MComStorage") then
                                                        --This will become true if we shouldn't store this variable
                                                        local doIgnore = false;
                                                        
                                                        --If we have a list of vars to save, then go through them, and if this var is not in there, then ignore it
                                                        if (reglist.saveList) then
                                                                --Default to ignoring now
                                                                doIgnore = true;
                                                                --Make sure the saveList is a table
                                                                if (type(reglist.saveList) ~= "table") then
                                                                        reglist.saveList = { reglist.saveList };
                                                                end
                                                                --Go through the list and see if we find the variable, if we do, then we don't ignore it
                                                                for i, curSaveCheck in reglist.saveList do
                                                                        if (curVar == curSaveCheck) then
                                                                                doIgnore = false;
                                                                                break;
                                                                        end
                                                                end
                                                        end
                                                        
                                                        --If we are supposed to ignore this guy, then do so now
                                                        if (not doIgnore) then
                                                                --If we have a list of vars to ignore, then go through them, and if this var is in there, then ignore it
                                                                if (reglist.ignoreList) then
                                                                        --Make sure the ignoreList is a table
                                                                        if (type(reglist.ignoreList) ~= "table") then
                                                                                reglist.ignoreList = { reglist.ignoreList };
                                                                        end
                                                                        --Go through the list and see if we find the variable, if we do, then ignore it
                                                                        for i, curIgnoreCheck in reglist.ignoreList do
                                                                                if (curVar == curIgnoreCheck) then
                                                                                        doIgnore = true;
                                                                                        break;
                                                                                end
                                                                        end
                                                                end
                                                                
                                                                --If we are supposed to ignore this guy, then do so now
                                                                if (not doIgnore) then
                                                                        if (reglist.nonUIList) then
                                                                                --Since these are UI vars, then we should only be ignoring them if the UI is around
                                                                                if ( MCom.hasUI() ) then
                                                                                        --Unless we find this in the list, we should be ignoring it
                                                                                        doIgnore = true;
                                                                                        --Make sure the nonUIList is a table
                                                                                        if (type(reglist.nonUIList) ~= "table") then
                                                                                                nonUIList = { reglist.nonUIList };
                                                                                        end
                                                                                        --Go through the list and see if we find the variable, if we do, then don't ignore it
                                                                                        for i, curUICheck in reglist.nonUIList do
                                                                                                if (curVar == curUICheck) then
                                                                                                        doIgnore = false;
                                                                                                        break;
                                                                                                end
                                                                                        end
                                                                                end
                                                                        else
                                                                                if (reglist.uiList) then
                                                                                        --Since these are UI vars, then we should only be ignoring them if the UI is around
                                                                                        if ( MCom.hasUI() ) then
                                                                                                --Make sure the uiList is a table
                                                                                                if (type(reglist.uiList) ~= "table") then
                                                                                                        uiList = { reglist.uiList };
                                                                                                end
                                                                                                --Go through the list and see if we find the variable, if we do, then ignore it
                                                                                                for i, curUICheck in reglist.uiList do
                                                                                                        if (curVar == curUICheck) then
                                                                                                                doIgnore = true;
                                                                                                                break;
                                                                                                        end
                                                                                                end
                                                                                        end
                                                                                end
                                                                        end
                                                                        
                                                                        --If we are supposed to ignore this guy, then do so now
                                                                        if (not doIgnore) then
                                                                                --Store the variable
                                                                                storeVar[curVar] = varTable[curVar];
                                                                                --Set that we saved data
                                                                                didSave = true;
                                                                        end
                                                                end
                                                        end
                                                end
                                        end
                                        
                                        --If a forced list has been passed, then go through it
                                        if (reglist.forceList) then
                                                --Make sure it is a table
                                                if ( type(reglist.forceList) ~= "table" ) then
                                                        reglist.forceList = { reglist.forceList };
                                                end
                                                --Go through all the variables in the table
                                                for i, curVar in reglist.forceList do
                                                        --Ignore the MComStorage variable
                                                        if (curVar ~= "MComStorage") then
                                                                --This will become true if we shouldn't store this variable
                                                                local doIgnore = false;
                                                                
                                                                --If we have a list of vars to save, then go through them, and if this var is not in there, then ignore it
                                                                if (reglist.saveList) then
                                                                        --Default to ignoring now
                                                                        doIgnore = true;
                                                                        --Make sure the saveList is a table
                                                                        if (type(reglist.saveList) ~= "table") then
                                                                                reglist.saveList = { reglist.saveList };
                                                                        end
                                                                        --Go through the list and see if we find the variable, if we do, then we don't ignore it
                                                                        for i, curSaveCheck in reglist.saveList do
                                                                                if (curVar == curSaveCheck) then
                                                                                        doIgnore = false;
                                                                                        break;
                                                                                end
                                                                        end
                                                                end
                                                                
                                                                --If we are supposed to ignore this guy, then do so now
                                                                if (not doIgnore) then
                                                                        --If we have a list of vars to ignore, then go through them, and if this var is in there, then ignore it
                                                                        if (reglist.ignoreList) then
                                                                                --Make sure the ignoreList is a table
                                                                                if (type(reglist.ignoreList) ~= "table") then
                                                                                        reglist.ignoreList = { reglist.ignoreList };
                                                                                end
                                                                                --Go through the list and see if we find the variable, if we do, then ignore it
                                                                                for i, curIgnoreCheck in reglist.ignoreList do
                                                                                        if (curVar == curIgnoreCheck) then
                                                                                                doIgnore = true;
                                                                                                break;
                                                                                        end
                                                                                end
                                                                        end
                                                                        
                                                                        --If we are supposed to ignore this guy, then do so now
                                                                        if (not doIgnore) then
                                                                                if (reglist.nonUIList) then
                                                                                        --Since these are UI vars, then we should only be ignoring them if the UI is around
                                                                                        if ( MCom.hasUI() ) then
                                                                                                --Unless we find this in the list, we should be ignoring it
                                                                                                doIgnore = true;
                                                                                                --Make sure the nonUIList is a table
                                                                                                if (type(reglist.nonUIList) ~= "table") then
                                                                                                        nonUIList = { reglist.nonUIList };
                                                                                                end
                                                                                                --Go through the list and see if we find the variable, if we do, then don't ignore it
                                                                                                for i, curUICheck in reglist.nonUIList do
                                                                                                        if (curVar == curUICheck) then
                                                                                                                doIgnore = false;
                                                                                                                break;
                                                                                                        end
                                                                                                end
                                                                                        end
                                                                                else
                                                                                        if (reglist.uiList) then
                                                                                                --Since these are UI vars, then we should only be ignoring them if the UI is around
                                                                                                if ( MCom.hasUI() ) then
                                                                                                        --Make sure the uiList is a table
                                                                                                        if (type(reglist.uiList) ~= "table") then
                                                                                                                uiList = { reglist.uiList };
                                                                                                        end
                                                                                                        --Go through the list and see if we find the variable, if we do, then ignore it
                                                                                                        for i, curUICheck in reglist.uiList do
                                                                                                                if (curVar == curUICheck) then
                                                                                                                        doIgnore = true;
                                                                                                                        break;
                                                                                                                end
                                                                                                        end
                                                                                                end
                                                                                        end
                                                                                end
                                                                                
                                                                                --If we are supposed to ignore this guy, then do so now
                                                                                if (not doIgnore) then
                                                                                        --Store the variable
                                                                                        storeVar[curVar] = varTable[curVar];
                                                                                        --Set that we saved data
                                                                                        didSave = true;
                                                                                end
                                                                        end
                                                                end
                                                        end
                                                end
                                        end
                                end
                        end
                end
                --Return if we saved data or not
                return didSave;
        end;

        --[[
                loadConfig ( {reglist} )
                        This will load all variables stored in the passed table in MComStorage.  This only works on variables that have stored the data using
                        MCom.saveConfig
                        
                Args:
                        reglist - This contains all options for this load procedure
                                {
                                Required:
                                        (string) configVar -    The name of the config variable, this should have been registered for save by you, and must be a table with a simple
                                                                                                                                variable name.  IE no .'s or []'s
                                
                                Optional:
                                        (string) storeVar -     The name of the variable to load/store the data in.  If not passed then configVar.MComStorage is used.  Remember to register
                                                                                                                        it for saving.
                                        (string) exactVar -     If you pass this, then data will be loaded from this var, regardless of realm/character.  It will get from this exact var.  This
                                                                                                                        takes precidence over storeVar.
                                        (string) realm  - This allows you to specify the realm to load from, if not passed, then the current realm will be used.
                                        (string) character      - This allows you to specify the character to load from, if not passed, then the current character will be used.
                                        NOTE: For all the following, this will only work on root level variables.  I.E. Whatever_Config.Variable.  For this you would pass "Variable"
                                        (string or table) loadList -    The names of all variables in the config to be loaded, if this is not passed, then MCom will try to load
                                                                                                                                                                all variables except the MComStorage variable.
                                        (string or table) ignoreList - The names of any variables that you want MCom to not load.
                                        (string or table) uiList -      These variables will only be loaded if there is no UI available.  Any options that you have the UI controlling
                                                                                                                                                        should be included in here, so you can leave it up to the UI to properly load/save them.
                                        (string or table) nonUIList -   If this list is declared, then uiList will be ignored, and all variables, except these, will be considered UI
                                                                                                                                                                variables.
                                        (string or table) forceList -   After going through the normal vars, MCom will go through and load these vars, even if they are nil.
                                                                                                                                                                is affected by the rules set by the above lists as well.
                                }
                        
                        Returns:
                                true - Some data was loaded
                                false - No data was loaded
        ]]--
        MCom.loadConfig = function ( reglist )
                --We will set this true, if we loaded any data
                local didLoad = false;
                --Make sure we have the required info in the right form
                if ( reglist and ( type(reglist) == "table" ) and reglist.configVar ) then
                        --Get the config variable table
                        local varTable = MCom.getStringVar(reglist.configVar);
                        --Only proceed if the config variable is a table
                        if ( type(varTable) == "table" ) then
                                
                                
                                --Get the realm and character name
                                local realm = reglist.realm;
                                if (not realm) then
                                        realm = GetCVar("RealmName");
                                end
                                local character = reglist.character;
                                if (not character) then
                                        character = UnitName("player")
                                end
                                
                                --Setup the variable to load data from
                                local storeVar = MCom.getStringVar(reglist.exactVar);
                                --If we don't have an exactVar and we have the server and character name then generate the storeVar
                                if ( (not storeVar) and realm and character and ( ( character ~= UKNOWNBEING ) and ( character ~= UNKNOWNOBJECT ) ) ) then
                                        --Get the storage var if one was passed
                                        storeVar = MCom.getStringVar(reglist.storeVar);
                                        if (not storeVar) then
                                                --If the MComStorage variable isn't there yet, or isn't a table, then set it as an empty table
                                                if (type(varTable.MComStorage) ~= "table") then
                                                        varTable.MComStorage = {};
                                                end
                                                storeVar = varTable.MComStorage;
                                        end
                                        
                                        --If this realm doesn't exist, then create it
                                        if (not storeVar[realm]) then
                                                storeVar[realm] = {};
                                        end
                                        --If this character doesn't exist, then create it
                                        if (not storeVar[realm][character]) then
                                                storeVar[realm][character] = {};
                                        end
                                        --Set storeVar to use the current realm/char
                                        storeVar = storeVar[realm][character];
                                end
                                
                                --If we have the variable to load from, then we are good to go
                                if (storeVar) then
                                        --Go through all the variables in the table
                                        for curVar in storeVar do
                                                --This will become true if we shouldn't load this variable
                                                local doIgnore = false;
                                                
                                                --If we have a list of vars to load, then go through them, and if this var is not in there, then ignore it
                                                if (reglist.loadList) then
                                                        --Default to ignoring now
                                                        doIgnore = true;
                                                        --Make sure the loadList is a table
                                                        if (type(reglist.loadList) ~= "table") then
                                                                reglist.loadList = { reglist.loadList };
                                                        end
                                                        --Go through the list and see if we find the variable, if we do, then we don't ignore it
                                                        for i, curLoadCheck in reglist.loadList do
                                                                if (curVar == curLoadCheck) then
                                                                        doIgnore = false;
                                                                        break;
                                                                end
                                                        end
                                                end
                                                
                                                --If we are supposed to ignore this guy, then do so now
                                                if (not doIgnore) then
                                                        --If we have a list of vars to ignore, then go through them, and if this var is in there, then ignore it
                                                        if (reglist.ignoreList) then
                                                                --Make sure the ignoreList is a table
                                                                if (type(reglist.ignoreList) ~= "table") then
                                                                        reglist.ignoreList = { reglist.ignoreList };
                                                                end
                                                                --Go through the list and see if we find the variable, if we do, then ignore it
                                                                for i, curIgnoreCheck in reglist.ignoreList do
                                                                        if (curVar == curIgnoreCheck) then
                                                                                doIgnore = true;
                                                                                break;
                                                                        end
                                                                end
                                                        end
                                                        
                                                        --If we are supposed to ignore this guy, then do so now
                                                        if (not doIgnore) then
                                                                if (reglist.nonUIList) then
                                                                        --Since these are UI vars, then we should only be ignoring them if the UI is around
                                                                        if ( MCom.hasUI() ) then
                                                                                --Unless we find this in the list, we should be ignoring it
                                                                                doIgnore = true;
                                                                                --Make sure the nonUIList is a table
                                                                                if (type(reglist.nonUIList) ~= "table") then
                                                                                        nonUIList = { reglist.nonUIList };
                                                                                end
                                                                                --Go through the list and see if we find the variable, if we do, then don't ignore it
                                                                                for i, curUICheck in reglist.nonUIList do
                                                                                        if (curVar == curUICheck) then
                                                                                                doIgnore = false;
                                                                                                break;
                                                                                        end
                                                                                end
                                                                        end
                                                                else
                                                                        if (reglist.uiList) then
                                                                                --Since these are UI vars, then we should only be ignoring them if the UI is around
                                                                                if ( MCom.hasUI() ) then
                                                                                        --Make sure the uiList is a table
                                                                                        if (type(reglist.uiList) ~= "table") then
                                                                                                uiList = { reglist.uiList };
                                                                                        end
                                                                                        --Go through the list and see if we find the variable, if we do, then ignore it
                                                                                        for i, curUICheck in reglist.uiList do
                                                                                                if (curVar == curUICheck) then
                                                                                                        doIgnore = true;
                                                                                                        break;
                                                                                                end
                                                                                        end
                                                                                end
                                                                        end
                                                                end
                                                                        
                                                                --If we are supposed to ignore this guy, then do so now
                                                                if (not doIgnore) then
                                                                        --Load the variable
                                                                        varTable[curVar] = storeVar[curVar];
                                                                        --Set that we loaded data
                                                                        didLoad = true;
                                                                end
                                                        end
                                                end
                                        end
                                        
                                        --If a forced list has been passed, then go through it
                                        if (reglist.forceList) then
                                                --Make sure it is a table
                                                if ( type(reglist.forceList) ~= "table" ) then
                                                        reglist.forceList = { reglist.forceList };
                                                end
                                                --Go through all the variables in the table
                                                for i, curVar in reglist.forceList do
                                                        --This will become true if we shouldn't load this variable
                                                        local doIgnore = false;
                                                        
                                                        --If we have a list of vars to load, then go through them, and if this var is not in there, then ignore it
                                                        if (reglist.loadList) then
                                                                --Default to ignoring now
                                                                doIgnore = true;
                                                                --Make sure the loadList is a table
                                                                if (type(reglist.loadList) ~= "table") then
                                                                        reglist.loadList = { reglist.loadList };
                                                                end
                                                                --Go through the list and see if we find the variable, if we do, then we don't ignore it
                                                                for i, curLoadCheck in reglist.loadList do
                                                                        if (curVar == curLoadCheck) then
                                                                                doIgnore = false;
                                                                                break;
                                                                        end
                                                                end
                                                        end
                                                        
                                                        --If we are supposed to ignore this guy, then do so now
                                                        if (not doIgnore) then
                                                                --If we have a list of vars to ignore, then go through them, and if this var is in there, then ignore it
                                                                if (reglist.ignoreList) then
                                                                        --Make sure the ignoreList is a table
                                                                        if (type(reglist.ignoreList) ~= "table") then
                                                                                reglist.ignoreList = { reglist.ignoreList };
                                                                        end
                                                                        --Go through the list and see if we find the variable, if we do, then ignore it
                                                                        for i, curIgnoreCheck in reglist.ignoreList do
                                                                                if (curVar == curIgnoreCheck) then
                                                                                        doIgnore = true;
                                                                                        break;
                                                                                end
                                                                        end
                                                                end
                                                                
                                                                --If we are supposed to ignore this guy, then do so now
                                                                if (not doIgnore) then
                                                                        if (reglist.nonUIList) then
                                                                                --Since these are UI vars, then we should only be ignoring them if the UI is around
                                                                                if ( MCom.hasUI() ) then
                                                                                        --Unless we find this in the list, we should be ignoring it
                                                                                        doIgnore = true;
                                                                                        --Make sure the nonUIList is a table
                                                                                        if (type(reglist.nonUIList) ~= "table") then
                                                                                                nonUIList = { reglist.nonUIList };
                                                                                        end
                                                                                        --Go through the list and see if we find the variable, if we do, then don't ignore it
                                                                                        for i, curUICheck in reglist.nonUIList do
                                                                                                if (curVar == curUICheck) then
                                                                                                        doIgnore = false;
                                                                                                        break;
                                                                                                end
                                                                                        end
                                                                                end
                                                                        else
                                                                                if (reglist.uiList) then
                                                                                        --Since these are UI vars, then we should only be ignoring them if the UI is around
                                                                                        if ( MCom.hasUI() ) then
                                                                                                --Make sure the uiList is a table
                                                                                                if (type(reglist.uiList) ~= "table") then
                                                                                                        uiList = { reglist.uiList };
                                                                                                end
                                                                                                --Go through the list and see if we find the variable, if we do, then ignore it
                                                                                                for i, curUICheck in reglist.uiList do
                                                                                                        if (curVar == curUICheck) then
                                                                                                                doIgnore = true;
                                                                                                                break;
                                                                                                        end
                                                                                                end
                                                                                        end
                                                                                end
                                                                        end
                                                                                
                                                                        --If we are supposed to ignore this guy, then do so now
                                                                        if (not doIgnore) then
                                                                                --Load the variable
                                                                                varTable[curVar] = storeVar[curVar];
                                                                                --Set that we loaded data
                                                                                didLoad = true;
                                                                        end
                                                                end
                                                        end
                                                end
                                        end
                                end
                        end
                end
                --Return if we loaded data or not
                return didLoad;
        end;

        --[[
                safeLoad ( configVar )
                        Used to ensure that when variables are loaded into a table based variable, that none of the defaults
                        are niled out.
                        Call this after you have setup the defaults for your table, but before VARIABLES_LOADED occurs.
                        When the variables are loaded, anything that is missing will be filled in with the defaults.

                Args:
                        Required:
                                (string) configVar -    The name of the config variable, this should have been registered for save by you, and must be a table with a simple
                                                                                                                        variable name.  IE no .'s or []'s
        ]]--
        MCom.safeLoad = function ( configVar )
                if (not MCom.didVarsLoaded) then
                        --Get the actual config table
                        local varTable = MCom.getStringVar(configVar);
                        if ( type(varTable) == "table" ) then
                                --If we don't have a table of safe loads yet, then make one
                                if (not MCom.safeLoads) then
                                        MCom.safeLoads = {};
                                end
                                if (not MCom.safeLoads.addonLoaded) then
                                        MCom.safeLoads.addonLoaded = {};
                                end
                                if (not MCom.safeLoads.varsLoaded) then
                                        MCom.safeLoads.varsLoaded = {};
                                end

                                --Store this config for loading later
                                MCom.safeLoads.addonLoaded[configVar] = varTable;

                                --Hook for the VARIABLES_LOADED event
                                if (not MCom.HookedOnEvent) then
                                        MCom.HookedOnEvent = true;
                                        MCom.util.hook("UIParent_OnEvent", "MCom.UIParent_OnEvent", "after");
                                end
                                --Hook for the ADDON_LOADED event
                                if (not MCom.RegisteredAddonLoaded) then
                                        UIParent:RegisterEvent("ADDON_LOADED");
                                end
                        end
                end
        end;

        --[[
                varsLoaded
                        This will simply check to see if the variables needed to be able to use MCom.loadConfig have been loaded.
                        To use this properly you must have an OnEvent function.  You must have registered for the "UNIT_NAME_UPDATE"
                        event.  In your OnEvent handler you need to check if that event has occured, and if it has if the arg1 is player.
                        You should also have a variable that keeps up with whether or not you have loaded your config, and only try to
                        do so if it hasn't loaded.
                        
                        Ex      (somewhere in the OnLoad handler) this will either register with the UI to call ModName.LoadConfig when
                                        they load their configuration, or it will register a "UNIT_NAME_UPDATE" event for you:
                        MCom.registerForLoad(ModName.LoadConfig);
                        
                        Ex      (somewhere in the OnEvent handler) this will handle waiting till the right vars are loaded before calling
                                        the config, when there is no UI around:
                        if (( event == "UNIT_NAME_UPDATE" ) and (arg1 == "player") and (not ModName.VarsLoaded)) then
                                if ( MCom.varsLoaded() ) then
                                        ModName.VarsLoaded = true;
                                        ModName.LoadConfig();
                                end
                        end
                        
                        NOTE: Make sure you're LoadConfig function only loads the config once, as some UIs might call the function more
                                                than once.
                
                Returns:
                        true - the variables needed to load the config are present and proper
                        false - the variables needed to load the config are not present or not proper
                        
        ]]--
        MCom.varsLoaded = function ()
                --Get the realm and character names
                local realm = GetCVar("RealmName");
                local character = UnitName("player");
                --If we have the needed data, in proper format, then return true, otherwise return false
                if ( realm and character and ( character ~= UKNOWNBEING ) and ( character ~= UNKNOWNOBJECT ) ) then
                        return true;
                end
                return false;
        end;
        
        --[[
                registerVarsLoaded ( function callback )
                        This will call the passed function back when the variables have been loaded by the game, or the
                        UI.  This would be an optimal time to load 
                
                Args:
                        callback( vltype ) - the function to be called when the variables have been loaded
                                Args:
                                        (string) vltype - indicates what kind of load has occured, "UIParent" for normal, "Khaos", or "Cosmos"
        ]]--
        MCom.registerVarsLoaded = function ( callback )
                --Add this callback to the list
                if (not MCom.varsLoadedList) then
                        MCom.varsLoadedList = {};
                end
                table.insert(MCom.varsLoadedList, callback);

                --Only register for the load notice once
                if (not MCom.LoadNoticeRegistered) then
                        MCom.LoadNoticeRegistered = true;
                        --Try to register with Khaos
                        if (Khaos) then
                                Khaos.registerConfigurationLoadNotice( { onConfigurationChange = MCom.VariablesLoaded; id = "MCom"; description = "Handles all MCom registered load notices"; } );
                        elseif (Cosmos_RegisterVarsLoaded) then
                                --Try to register with Cosmos
                                Cosmos_RegisterVarsLoaded( MCom.VariablesLoaded );
                        else
                                --Hook the event function of UIParent so we know when VARS_LOADED occurs
                                if (not MCom.HookedOnEvent) then
                                        MCom.HookedOnEvent = true;
                                        MCom.util.hook("UIParent_OnEvent", "MCom.UIParent_OnEvent", "after");
                                end
                                MCom.UseVarsLoadedEvent = true;
                        end
                end
        end;
        
        --[[
                DEPRICATED!  For Backward compatability only.
                USE MCom.registerVarsLoaded
        ]]--
        MCom.registerForLoad = function ( callback )
                --Try to register with Khaos
                if (Khaos and this:GetName()) then
                        Khaos.registerConfigurationLoadNotice( { onConfigurationChange = callback; id = this:GetName(); description = ""; } );
                elseif (Cosmos_RegisterVarsLoaded) then
                        --Try to register with Cosmos
                        Cosmos_RegisterVarsLoaded( callback );
                else
                        --No UI around, so we register the event
                        this:RegisterEvent( "UNIT_NAME_UPDATE" );
                end
                return false;
        end;

        --[[
                addSlashCom ( [string/{string, ...}] command, function comfunc, string comaction, bool comsticky, string comhelp, string comtype, string uisec, string uivar, string comvar, string comvarmulti, number commin, number commax, number commul, number cominmul, bool hasbool, {string = string, ...} choices, bool multichoice, bool hasopacity, {string, ...} extrahelp )
                        Registers a standard slash command.  This will register with Sky, if it exists.
                        addSlashCom makes its own chat handler function.  The function expects a particular kind of input, specified by comtype.
                        
                        For boolean input, it will require that the user pass on, off, 1, or 0, to consider the command valid. It will then call
                        the function you pass, and will pass a 1, 0, or a -1, standing for True, False, and no input(I suggest you make it invert
                        the current value in this case).  If Cosmos is loaded, and you have passed uivar and comvar, it will update the cosmos
                        variable after the function has completed.
                        
                        If the slash command is already registered with MCom, nothing will happen.
                
                Args:
                        command -       The slash command(s) you want to register. Ex: "/command". This can be a string or a table of strings if you
                                                                want more than one command.
                        comfunc -       The function that the should be called when the slash command is used, and valid.  If the function returns a value
                                                                that value will be used to update a cosmos variable, if uivar has been passed.  You don't have to return a value
                                                                to do this, but if you don't then you need to use comvar, and comvarmulti(for multi type).  For multi type it
                                                                should return the bool then the value, like so: "return enabled, value;"
                                                                BOOL - function (bool enabled)
                                                                NUMBER - function (number value)
                                                                MULTI - function (bool enabled, number value)
                                                                STRING - function (string value)
                                                                SIMPLE - function ()
        
                Optional: 
                        comaction -     The action to perform, see Sky documentation for further details
                        comsticky -     Whether the command is sticky or not(1 or 0), see Sky documentation for further details
                        comhelp -       What message to display as help in Sky for this command, see Sky documentation for further details
                        comtype -       the type of data you are expecting from this slash command
                                                                MCOM_BOOLT - Expects boolean data, an on, off, 1, or 0
                                                                MCOM_NUMT - Expects a number value
                                                                MCOM_MULTIT - Expects a boolean and then a number value, Ex: "/command on 3"
                                                                MCOM_STRINGT - Expects any string
                                                                MCOM_SIMPLET - No input needed, just calls the function
                        commin - the minimum value the number variable can be set to, for help display only
                        commax - the maximum value the number variable can be set to, for help display only
                        commul - the value to multiply the number by when showing it's status
                        cominmul - A value to multiply the number passed in by the user(for number types only)
                        hasbool - If this option has a boolean part, set this to true
                        multichoice - Set this true if this is a choice type and can have multiple choices selected
                        hasopacity - Set this true if this is a color type that should also have an opacity setting
                        extrahelp - A table of extra help messages to display, each line is printed on a seperate line
                        
                These are required if you want to update a Cosmos or Khaos variable:
                        uivar - The Cosmos variable that should be updated, if you want this slash command to update a cosmos variable
                These are required if you want to update a Cosmos or Khaos variable, and your function doesn't return the updated value:
                        comvar -        The variable that the cosmos variable should be set by, if you want this slash command to update a cosmos variable
                                                                This should be a string containing the name of the variable to update, this can include .'s for tables, Ex: "Something.Value"
                                                                When type is MULTI, this specifies the bool variable
                        comvarmulti - The same as comvar, but used to specify the number variable when type is MULTI, only used for MULTI type
                        
                This is required if you want to update a Khaos variable:
                        uisec - The option set ID that the uivar is found in
                        
                This is required is you are using a MCOM_CHOICET type:
                        choices - The list of choices
        ]]--
        MCom.addSlashCom = function (command, comfunc, comaction, comsticky, comhelp, comtype, uisec, uivar, comvar, comvarmulti, commin, commax, commul, cominmul, hasbool, choices, multichoice, hasopacity, extrahelp)
                --We need at bare minimum command, and comfunc
                if (command and comfunc) then
                        --If we dont have our chat command list yet, make one
                        if (not MCom.SlashComs) then
                                MCom.SlashComs = {};
                        end
                        --make sure command is a table
                        if (type(command) ~= "table") then
                                command = {command};
                        end

                        --If the command is not in the list yet, then add it
                        if (not MCom.getComID(command)) then
                                table.insert(MCom.SlashComs, {});
                                local commandid = getn(MCom.SlashComs);

                                --Set the commands various elements
                                MCom.SlashComs[commandid].basecommand = command;
                                MCom.SlashComs[commandid].comfunc = comfunc;
                                if (comtype) then
                                        MCom.SlashComs[commandid].comtype = comtype;
                                elseif (MCom.SlashComs[commandid].comtype == nil) then
                                        --Default to simple type
                                        MCom.SlashComs[commandid].comtype = MCOM_SIMPLET;
                                end
                                if (uisec) then
                                        MCom.SlashComs[commandid].uisec = uisec;
                                end
                                if (uivar) then
                                        MCom.SlashComs[commandid].uivar = uivar;
                                end
                                if (comvar) then
                                        MCom.SlashComs[commandid].comvar = comvar;
                                end
                                if (comvarmulti) then
                                        MCom.SlashComs[commandid].comvarmulti = comvarmulti;
                                end
                                if (commim) then
                                        MCom.SlashComs[commandid].commin = commin;
                                end
                                if (commax) then
                                        MCom.SlashComs[commandid].commax = commax;
                                end
                                if (commul) then
                                        MCom.SlashComs[commandid].commul = commul;
                                end
                                if (cominmul) then
                                        MCom.SlashComs[commandid].cominmul = cominmul;
                                end
                                if (extrahelp) then
                                        MCom.SlashComs[commandid].extrahelp = extrahelp;
                                end
                                if (hasbool) then
                                        MCom.SlashComs[commandid].hasbool = hasbool;
                                end
                                if (choices) then
                                        MCom.SlashComs[commandid].choices = choices;
                                end
                                if (multichoice) then
                                        MCom.SlashComs[commandid].multichoice = multichoice;
                                end
                                if (hasopacity) then
                                        MCom.SlashComs[commandid].hasopacity = hasopacity;
                                end
                                
                                --Register the command with Sky, or the default method
                                if ( Sky ) then
                                        --Register the command with Sky
                                        Sky.registerSlashCommand(
                                                {
                                                        id=string.upper(command[1]).."_COMMAND";
                                                        commands = command;
                                                        onExecute = function (msg) MCom.SlashCommandHandler(commandid, msg); end;
                                                        action = comaction;
                                                        sticky = comsticky;
                                                        helpText = comhelp;
                                                }
                                        );
                                else
                                        SlashCmdList[string.upper(string.sub(command[1], 2))] = function (msg) MCom.SlashCommandHandler(commandid, msg); end;
                                        for curCom = 1, getn(command) do
                                                setglobal("SLASH_"..string.upper(string.sub(command[1], 2))..curCom, command[curCom]);
                                        end
                                end
                        end
                end
        end;
        
        --[[
                addSlashSuperCom ( [string/{string, ...}] command, string comaction, number comsticky, string comhelp )
                        This registers a slash command that will have sub commands in it.  See addSlashSubCom for more details on sub commands.
                        
                        If the slash command is already registered with MCom, nothing will happen.
                
                Args:
                        command -       The slash command(s) you want to register. Ex: "/command". This can be a string or a table of strings if you
                                                                want more than one command.
        
                Optional: 
                        comaction -     The action to perform, see Sky documentation for further details
                        comsticky -     Whether the command is sticky or not(1 or 0), see Sky documentation for further details
                        comhelp -       What message to display as help in Sky for this command, see Sky documentation for further details
                        extrahelp - A table of extra help messages to display, each line is printed on a seperate line
        ]]--
        MCom.addSlashSuperCom = function (command, comaction, comsticky, comhelp, extrahelp)
                --We need at bare minimum command
                if (command) then
                        --If we dont have our chat command list yet, make one
                        if (not MCom.SlashComs) then
                                MCom.SlashComs = {};
                        end
                        --make sure command is a table
                        if (type(command) ~= "table") then
                                command = {command};
                        end
                        
                        --If the command is not in the list yet, then add it
                        if (not MCom.getComID(command)) then
                                table.insert(MCom.SlashComs, {});
                                local commandid = getn(MCom.SlashComs);

                                MCom.SlashComs[commandid].basecommand = command;
                                if (extrahelp) then
                                        MCom.SlashComs[commandid].extrahelp = extrahelp;
                                end
                                
                                --Register the command with Sky, or the default method
                                if ( Sky ) then
                                        Sky.registerSlashCommand(
                                                {
                                                        id=string.upper(command[1]).."_COMMAND";
                                                        commands = command;
                                                        onExecute = function (msg) MCom.SlashCommandHandler(commandid, msg); end;
                                                        action = comaction;
                                                        sticky = comsticky;
                                                        helpText = comhelp;
                                                }
                                        );
                                else
                                        SlashCmdList[string.upper(string.sub(command[1], 2))] = function (msg) MCom.SlashCommandHandler(commandid, msg); end;
                                        for curCom = 1, getn(command) do
                                                setglobal("SLASH_"..string.upper(string.sub(command[1], 2))..curCom, command[curCom]);
                                        end
                                end
                        end
                end
        end;
        
        --[[
                addSlashSubCom ( [string/{string, ...}] basecommand, [string/{string, ...}] subcommand, function comfunc, string comhelp, string comtype, string uisec, string uivar, string comvar, string comvarmulti, number commin, number commax, number commul, number cominmul, bool hasbool, {string = string, ...} choices, bool multichoice, bool hasopacity)
                        This is like addSlashCom, but it registers a sub command to be used with a super command.
                        A sub command is one that is entered after the super command is entered.
                        Example:
                        Normal command: "/modcommand on"
                        Sub command, with super command of mod: "/mod command on"
                        
                        Using super and sub commands allows you to register only one actual real command, which helps to clean up the listing of slash
                        commands, and helps to prevent using a slash command that may already be there.  It also makes it easier for the user to remember
                        and use, as if the user simply types the super command by itself they will get a listing of all sub commands, and usage.
                        
                        If the slash command is already registered with MCom, nothing will happen.
                
                Args:
                        basecommand -   The super command that this sub command goes with.  Can be a single command or a list of commands.
                        subcommand -    The sub command(s) you want to register. Ex: "command". This can be a string or a table of strings if you
                                                                want more than one command.
                        comfunc -       The function that the should be called when the slash command is used, and valid.  If the function returns a value
                                                                that value will be used to update a cosmos variable, if uivar has been passed.  You don't have to return a value
                                                                to do this, but if you don't then you need to use comvar, and comvarmulti(for multi type).  For multi type it
                                                                should return the bool then the value, like so: "return enabled, value;"
                                                                BOOL - function (bool enabled)
                                                                NUMBER - function (number value)
                                                                MULTI - function (bool enabled, number value)
                                                                STRING - function (string value)
                                                                SIMPLE - function ()
        
                Optional: 
                        comhelp -       What message to display next to the sub command when listing sub commands in the help output.
                                                                NOTE: if this is an MCOM_CHOICET then if you put a %s in this string, it will be replaces with a list of
                                                                the choices you passed.
                        comtype -       the type of data you are expecting from this slash command
                                                                MCOM_BOOLT - Expects boolean data, an on, off, 1, or 0
                                                                MCOM_NUMT - Expects a number value
                                                                MCOM_MULTIT - Expects a boolean and then a number value, Ex: "/command on 3"
                                                                MCOM_STRINGT - Expects any string
                                                                MCOM_SIMPLET - No input needed, just calls the function
                        commin - the minimum value the number variable can be set to, for help display only
                        commax - the maximum value the number variable can be set to, for help display only
                        commul - the value to multiply the number by when showing it's status
                        cominmul - A value to multiply the number passed in by the user(for number types only)
                        hasbool - If this option has a boolean part, set this to true
                        multichoice - Set this true if this is a choice type and can have multiple choices selected
                        hasopacity - Set this true if this is a color type that should also have an opacity setting
                        
                These are required if you want to update a Cosmos variable:
                        uivar - The Cosmos variable that should be updated, if you want this slash command to update a cosmos variable
                These are required if you want to update a Cosmos variable, and your function doesn't return the updated value:
                        comvar -        The variable that the cosmos variable should be set by, if you want this slash command to update a cosmos variable
                                                                This should be a string containing the name of the variable to update, this can include .'s for tables, Ex: "Something.Value"
                                                                When type is MULTI, this specifies the bool variable
                        comvarmulti - The same as comvar, but used to specify the number variable when type is MULTI, only used for MULTI type
                        
                This is required if you want to update a Khaos variable:
                        uisec - The option set ID that the uivar is found in
                        
                This is required is you are using a MCOM_CHOICET type:
                        choices - The list of choices
        ]]--
        MCom.addSlashSubCom = function (basecommand, subcommand, comfunc, comhelp, comtype, uisec, uivar, comvar, comvarmulti, commin, commax, commul, cominmul, hasbool, choices, multichoice, hasopacity)
                --We need at bare minimum commandid, subcommand, and comfunc
                if (basecommand and subcommand and comfunc) then
                        --If we don't have a chat com list, then we shouldn't do anything
                        if (MCom.SlashComs) then
                                --Make sure basecommand is a table
                                if (type(basecommand) ~= "table") then
                                        basecommand = {basecommand};
                                end
                                
                                --get the ID of the super command, if it is in the list
                                local commandid = MCom.getComID(basecommand);           
                                
                                --no commandid means no nothing
                                if (commandid) then
                                        --If this super command doesn't have a list of sub commands yet, then make one
                                        if (not MCom.SlashComs[commandid].commands) then
                                                MCom.SlashComs[commandid].commands = {};
                                        end
                                        
                                        --If the sub command isn't a table turn it to one
                                        if (type(subcommand) ~= "table") then
                                                subcommand = {subcommand};
                                        end
                                        
                                        --Try and find the subcommand in the list
                                        local monkey, subcommandid = MCom.getComID(commandid, subcommand);
                                        
                                        --Make sure this sub command doesn't already exist
                                        if (not subcommandid) then
                                                --Make the sub command
                                                table.insert(MCom.SlashComs[commandid].commands, {});
                                                subcommandid = getn(MCom.SlashComs[commandid].commands);
                                                
                                                --Setup the sub commands elements
                                                MCom.SlashComs[commandid].commands[subcommandid].command = subcommand;
                                                MCom.SlashComs[commandid].commands[subcommandid].comfunc = comfunc;
                                                if (comhelp) then
                                                        MCom.SlashComs[commandid].commands[subcommandid].comhelp = comhelp;
                                                end
                                                if (comtype) then
                                                        MCom.SlashComs[commandid].commands[subcommandid].comtype = comtype;
                                                elseif (MCom.SlashComs[commandid].commands[subcommandid].comtype == nil) then
                                                        --Default to simple type
                                                        MCom.SlashComs[commandid].commands[subcommandid].comtype = MCOM_SIMPLET;
                                                end
                                                if (uisec) then
                                                        MCom.SlashComs[commandid].commands[subcommandid].uisec = uisec;
                                                end
                                                if (uivar) then
                                                        MCom.SlashComs[commandid].commands[subcommandid].uivar = uivar;
                                                end
                                                if (comvar) then
                                                        MCom.SlashComs[commandid].commands[subcommandid].comvar = comvar;
                                                end
                                                if (comvarmulti) then
                                                        MCom.SlashComs[commandid].commands[subcommandid].comvarmulti = comvarmulti;
                                                end
                                                if (commin) then
                                                        MCom.SlashComs[commandid].commands[subcommandid].commin = commin;
                                                end
                                                if (commax) then
                                                        MCom.SlashComs[commandid].commands[subcommandid].commax = commax;
                                                end
                                                if (commul) then
                                                        MCom.SlashComs[commandid].commands[subcommandid].commul = commul;
                                                end
                                                if (cominmul) then
                                                        MCom.SlashComs[commandid].commands[subcommandid].cominmul = cominmul;
                                                end
                                                if (hasbool) then
                                                        MCom.SlashComs[commandid].commands[subcommandid].hasbool = hasbool;
                                                end
                                                if (choices) then
                                                        MCom.SlashComs[commandid].commands[subcommandid].choices = choices;
                                                end
                                                if (multichoice) then
                                                        MCom.SlashComs[commandid].commands[subcommandid].multichoice = multichoice;
                                                end
                                                if (hasopacity) then
                                                        MCom.SlashComs[commandid].commands[subcommandid].hasopacity = hasopacity;
                                                end
                                        end
                                end                             
                        end
                end
        end;
        
        --[[
                callHook ( (string) hook, (any) a1..a20 )
                        Calls the origional hooked function.

                Args:
                        (string) hook - The name of the origional function to call
                        (any) a1..a20 - Any variables that need to be passed to the function

                Returns:
                        Whatever the passed function returns
        ]]--
        MCom.callHook = function ( hook, a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17,a18,a19,a20 )
                --Make sure we have a hook
                if ( hook ) then
                        --If we can use Sea, then do so
                        if ( Sea ) then
                                if ( Sea.util and Sea.util.Hooks and Sea.util.Hooks[hook] and Sea.util.Hooks[hook].orig ) then
                                        return Sea.util.Hooks[hook].orig(a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17,a18,a19,a20);
                                end
                        elseif ( MCom.util.Hooks and MCom.util.Hooks[hook] and MCom.util.Hooks[hook].orig ) then
                                --Use the MCom list if Sea isn't available
                                return MCom.util.Hooks[hook].orig(a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17,a18,a19,a20);
                        end
                end
        end;
        
        --[[
                textFrame ( { reglist } )
                        Displays the passed text in a multipage scrollable frame.
                        This will not be available if the ItemTextFrame has been opened by the game.
                        
                Args:
                        reglist -       Either a table with the options, or a string or list of strings to display as
                                                                the text.
                                {
                                Required:
                                        (string or table) text -        The text you want to display, if this is a table, then each
                                                                                                                                                numbered entry will be a page.
                                
                                Optional:
                                        (string) title -        The title to display at the top of the frame.
                                        (string) material -     The appearance to use for the frame, can be "Stone", "Parchment", "Marble", "Silver",
                                                                                                                        or "Bronze", defaults to "Stone" font with a black background.
                                        (number) textscale -    What size to scale the text to, relative to normal (Ex. 1 is normal, 0.5 is half),
                                                                                                                                defaults to 0.85
                                }
                
                Returns:
                        true - The text frame was displayed
                        true - The text frame was not displayed
        ]]--
        MCom.textFrame = function ( reglist )
                --We have to have a reglist
                if (reglist) then
                        --We need to hook some of the functions of the ItemTextFrame so we can have it
                        --behave properly for this usage.
                        local TextFrame = "MComText";
                        if ( not getglobal(TextFrame.."Frame") ) then
                                TextFrame = "ItemText";
                                if (not MCom.HasHookedText) then
                                        MCom.HasHookedText = true;
                                        MCom.util.hook("ItemTextNextPage", "MCom.ItemTextNextPage", "after");
                                        MCom.util.hook("ItemTextPrevPage", "MCom.ItemTextPrevPage", "after");
                                        MCom.util.hook("CloseItemText", "MCom.CloseItemText", "after");
                                        MCom.util.hook("ItemTextFrame_OnEvent", "MCom.ItemTextFrame_OnEvent", "before");
                                end
                        end

                        --Only display the frame if it isn't already visible
                        if ( (not MCom.NoTextAvail) and ( not getglobal(TextFrame.."Frame"):IsVisible() ) ) then
                                --If this isn't a table, then turn it into one
                                if ( type(reglist) ~= "table" ) then
                                        reglist = { text = { reglist }; };
                                end
                                --If this is a table of strings, then move the strings into text
                                if ( ( not reglist.text ) and reglist[1] ) then
                                        reglist.text = {};
                                        for curPage = 1, table.getn(reglist) do
                                                reglist.text[curPage] = reglist[curPage];
                                                reglist[curPage] = nil;
                                        end
                                end
                                --If text isn't a table then make it one
                                if ( type(reglist.text) ~= "table" ) then
                                        reglist.text = { reglist.text };
                                end
                                --Set the current text and page, to what was passed
                                MCom.CurText = reglist.text;
                                MCom.CurTextPage = 1;
                                --If there was no title passed, set it as an empty string
                                if (not reglist.title) then
                                        reglist.title = "";
                                end
                                --Got through all the pages and add some extra fluff new lines to let the user scroll down further
                                for curPage in MCom.CurText do
                                        if (MCom.CurText[curPage]) then
                                                MCom.CurText[curPage] = MCom.CurText[curPage].."\n\n\n\n";
                                        end
                                end
                                --Set the title of the frame
                                getglobal(TextFrame.."TitleText"):SetText(reglist.title);
                                --Hide the scrollframe and status bar
                                getglobal(TextFrame.."ScrollFrame"):Hide();
                                getglobal(TextFrame.."StatusBar"):Hide();
                                --Setup the look of the frame to the passed look
                                local material = Stone;
                                --Make sure the material is one of the available materials
                                local textColor = {1,1,1};
                                if ( reglist.material and MATERIAL_TEXT_COLOR_TABLE[reglist.material] ) then
                                        material = reglist.material;
                                        textColor = MATERIAL_TEXT_COLOR_TABLE[material];
                                end
                                getglobal(TextFrame.."PageText"):SetTextColor(textColor[1], textColor[2], textColor[3]);

                                if (not material) then
                                        if (MComTextFrame) then
                                                MComTextTopLeft:Show();
                                                MComTextTop:Show();
                                                MComTextTopRight:Show();
                                                MComTextBotLeft:Show();
                                                MComTextBot:Show();
                                                MComTextBotRight:Show();
                                                MComItemTextTopLeft:Hide();
                                                MComItemTextTopRight:Hide();
                                                MComItemTextBotLeft:Hide();
                                                MComItemTextBotRight:Hide();
                                                getglobal(TextFrame.."MaterialTopLeft"):Hide();
                                                getglobal(TextFrame.."MaterialTopRight"):Hide();
                                                getglobal(TextFrame.."MaterialBotLeft"):Hide();
                                                getglobal(TextFrame.."MaterialBotRight"):Hide();
                                                MComSpellBookIcon:Hide();
                                                MComTextFrame:SetWidth(512);
                                                MComTextCloseButton:SetPoint("CENTER", MComTextFrame, "TOPRIGHT", -58, -19);
                                                MComTextScrollFrame:SetPoint("TOPRIGHT", MComTextFrame, "TOPRIGHT", -82, -58);
                                                MComTextScrollFrame:SetWidth(408);
                                                MComTextScrollFrame:SetHeight(406);
                                                MComTextScrollFrameMiddle:Show();
                                                MComTextTitleText:SetPoint("CENTER", MComTextFrame, "CENTER", -14, 230);
                                                MComTextCurrentPage:SetPoint("TOP", MComTextFrame, "TOP", -14, -34);
                                                MComTextNextPageButton:SetPoint("CENTER", MComTextFrame, "TOPRIGHT", -86, -32);
                                                MComTextPrevPageButton:SetPoint("CENTER", MComTextFrame, "TOPLEFT", 32, -32);
                                                MComTextPageText:SetWidth(400);
                                        else
                                                getglobal(TextFrame.."MaterialTopLeft"):SetVertexColor(0,0,0);
                                                getglobal(TextFrame.."MaterialTopRight"):SetVertexColor(0,0,0);
                                                getglobal(TextFrame.."MaterialBotLeft"):SetVertexColor(0,0,0);
                                                getglobal(TextFrame.."MaterialBotRight"):SetVertexColor(0,0,0);
                                        end
                                else
                                        if (MComTextFrame) then
                                                MComTextTopLeft:Hide();
                                                MComTextTop:Hide();
                                                MComTextTopRight:Hide();
                                                MComTextBotLeft:Hide();
                                                MComTextBot:Hide();
                                                MComTextBotRight:Hide();
                                                MComItemTextTopLeft:Show();
                                                MComItemTextTopRight:Show();
                                                MComItemTextBotLeft:Show();
                                                MComItemTextBotRight:Show();
                                                MComSpellBookIcon:Show();
                                                MComTextFrame:SetWidth(384);
                                                MComTextCloseButton:SetPoint("CENTER", MComTextFrame, "TOPRIGHT", -45, -26);
                                                MComTextScrollFrame:SetPoint("TOPRIGHT", MComTextFrame, "TOPRIGHT", -66, -76);
                                                MComTextScrollFrame:SetWidth(280);
                                                MComTextScrollFrame:SetHeight(355);
                                                MComTextScrollFrameMiddle:Hide();
                                                MComTextTitleText:SetPoint("CENTER", MComTextFrame, "CENTER", 6, 230);
                                                MComTextCurrentPage:SetPoint("TOP", MComTextFrame, "TOP", 10, -50);
                                                MComTextNextPageButton:SetPoint("CENTER", MComTextFrame, "TOPRIGHT", -55, -56);
                                                MComTextPrevPageButton:SetPoint("CENTER", MComTextFrame, "TOPLEFT", 90, -56);
                                                MComTextPageText:SetWidth(270);
                                        end
                                        getglobal(TextFrame.."MaterialTopLeft"):SetVertexColor(1,1,1);
                                        getglobal(TextFrame.."MaterialTopRight"):SetVertexColor(1,1,1);
                                        getglobal(TextFrame.."MaterialBotLeft"):SetVertexColor(1,1,1);
                                        getglobal(TextFrame.."MaterialBotRight"):SetVertexColor(1,1,1);
                                end

                                --If the look is parchment, then hide the extra textures
                                if ( material == "Parchment" ) then
                                        getglobal(TextFrame.."MaterialTopLeft"):Hide();
                                        getglobal(TextFrame.."MaterialTopRight"):Hide();
                                        getglobal(TextFrame.."MaterialBotLeft"):Hide();
                                        getglobal(TextFrame.."MaterialBotRight"):Hide();
                                elseif (material) then
                                        getglobal(TextFrame.."MaterialTopLeft"):Show();
                                        getglobal(TextFrame.."MaterialTopRight"):Show();
                                        getglobal(TextFrame.."MaterialBotLeft"):Show();
                                        getglobal(TextFrame.."MaterialBotRight"):Show();
                                        getglobal(TextFrame.."MaterialTopLeft"):SetTexture("Interface\\ItemTextFrame\\ItemText-"..material.."-TopLeft");
                                        getglobal(TextFrame.."MaterialTopRight"):SetTexture("Interface\\ItemTextFrame\\ItemText-"..material.."-TopRight");
                                        getglobal(TextFrame.."MaterialBotLeft"):SetTexture("Interface\\ItemTextFrame\\ItemText-"..material.."-BotLeft");
                                        getglobal(TextFrame.."MaterialBotRight"):SetTexture("Interface\\ItemTextFrame\\ItemText-"..material.."-BotRight");
                                end
                                --Default the scrollbar positions for all pages to the top
                                MCom.CurText.Scroll = {};
                                for curPage in MCom.CurText do
                                        MCom.CurText.Scroll[curPage] = { Value = 0; };
                                end
                                
                                --Resize the text
                                if (not reglist.textscale) then
                                        reglist.textscale = 0.85;
                                        if (MComTextFrame) then
                                                reglist.textscale = 1;
                                        end
                                end
                                MCom.PageWidth = getglobal(TextFrame.."PageText"):GetWidth();
                                MCom.PageScale = getglobal(TextFrame.."PageText"):GetScale();
                                getglobal(TextFrame.."PageText"):SetWidth(MCom.PageWidth / reglist.textscale);
                                getglobal(TextFrame.."PageText"):SetScale(MCom.PageScale * reglist.textscale);
                                
                                --Update it with the new text
                                MCom.UpdateTextPage();
                                --Show the frame
                                getglobal(TextFrame.."Frame"):Show();
                                return true;
                        end
                end
                return false;
        end
        
        --------------------------------------------------
        --
        -- Private Library Functions
        --
        --------------------------------------------------
        --[[ Updates the text in the text frame ]]--
        MCom.UpdateTextPage = function ()
                --Only do this if CurText is a table
                if ( type(MCom.CurText) == "table" ) then
                        local TextFrame = "MComText";
                        if ( not getglobal(TextFrame.."Frame") ) then
                                TextFrame = "ItemText";
                        end
                        --If there is more than one page then setup the frame for that
                        if ( table.getn(MCom.CurText) > 1 ) then
                                --Show the text that shows the current page number
                                local pageText = string.format(MCOM_PAGE_TEXT, MCom.CurTextPage, table.getn(MCom.CurText));
                                if (pageText) then
                                        getglobal(TextFrame.."CurrentPage"):SetText(pageText);
                                        getglobal(TextFrame.."CurrentPage"):Show();
                                else
                                        getglobal(TextFrame.."CurrentPage"):Hide();
                                end
                                --If we have gone passed the first page, then enable the previous page button
                                if ( MCom.CurTextPage > 1 ) then
                                        getglobal(TextFrame.."PrevPageButton"):Show();
                                else
                                        getglobal(TextFrame.."PrevPageButton"):Hide();
                                end
                                --If we are not on the last page, then enable the next page button
                                if ( MCom.CurTextPage < table.getn(MCom.CurText) ) then
                                        getglobal(TextFrame.."NextPageButton"):Show();
                                else
                                        getglobal(TextFrame.."NextPageButton"):Hide();
                                end
                        else
                                --There is only one page, so hide the page controls
                                getglobal(TextFrame.."CurrentPage"):Hide();
                                getglobal(TextFrame.."PrevPageButton"):Hide();
                                getglobal(TextFrame.."NextPageButton"):Hide();
                        end
                        
                        --Hide the scroll frame
                        getglobal(TextFrame.."ScrollFrame"):Hide();
                        --Set the text for this page
                        getglobal(TextFrame.."PageText"):SetText(MCom.CurText[MCom.CurTextPage]);
                        --Update the scrollframe and show if neccisary
                        getglobal(TextFrame.."ScrollFrame"):UpdateScrollChildRect();
                        getglobal(TextFrame.."ScrollFrame"):Show();
                        --Reset the scroll bar position to the one stored for this page
                        getglobal(TextFrame.."ScrollFrameScrollBar"):SetValue(MCom.CurText.Scroll[MCom.CurTextPage].Value);
                else
                        MCom.CurText = nil;
                end
        end;

        --[[ Adds any entry missing in the toTable from the fromTable ]]--
        MCom.LoadSafeTable = function (toTable, fromTable)
                --Make sure we have tables to work with
                if ( ( type(toTable) == "table" ) and ( type(fromTable) == "table" ) ) then
                        --Go through each entry in the from table
                        for curEntry in fromTable do
                                --If the from entry is a table, then we need to parse each of its entries
                                if ( type( fromTable[curEntry] ) == "table" ) then
                                        --If the to table is not already a table, then turn it into one
                                        if ( type( toTable[curEntry] ) ~= "table" ) then
                                                toTable[curEntry] = {};
                                        end
                                        --Load the entries from the current from table entry into the current to table entry
                                        MCom.LoadSafeTable( toTable[curEntry], fromTable[curEntry] );
                                elseif ( toTable[curEntry] == nil ) then
                                        --If this entry is not a table, and it is nil, then load from the from table
                                        toTable[curEntry] = fromTable[curEntry];
                                end
                        end
                end
        end;

        --[[ Calls all frames registered for variables loaded notification ]]--
        MCom.VariablesLoaded = function ()
                --Only proceed if we have a list of callbacks
                if ( type(MCom.varsLoadedList) == "table" ) then
                        --Figure out what type of load notice was used
                        local regType = "UIParent";
                        if (Khaos) then
                                regType = "Khaos";
                        elseif (Cosmos_RegisterVarsLoaded) then
                                regType = "Cosmos";
                        end
                        --Call all the callbacks, and pass the type of load notice
                        for i = 1, table.getn(MCom.varsLoadedList) do
                                if ( type(MCom.varsLoadedList[i]) == "function" ) then
                                        MCom.varsLoadedList[i](regType);
                                end
                        end
                end
        end;

        --[[ Parses a boolean command ]]--
        MCom.ParseBoolCommand = function (value)
                --If it's a boolean then treat it as one
                if (value) then
                        value = string.upper(value);
                        if ( string.find(value, string.upper(MCOM_CHAT_ON) ) ) then
                                value = 1;
                        else
                                if ( string.find(value, string.upper(MCOM_CHAT_OFF) ) ) then
                                        value = 0;
                                else
                                        if ( string.find(value, "1") ) then
                                                value = 1;
                                        else
                                                if ( string.find(value, "0") ) then
                                                        value = 0;
                                                else                                                                    
                                                        value = nil;
                                                end
                                        end
                                end
                        end
                else
                        --If there was no data passed for this boolean, then send -1 to the functions
                        value = -1;
                end
                
                return value;
        end;
        
        --[[ Parses a number command ]]--
        MCom.ParseNumCommand = function (cominmul, value)
                if (value) then
                        --Get the valid decimal portion only
                        local dump, dump1;
                        dump, dump1, value = string.find(value, "(%d*%.*%d+)");
                        --If we got a valid decimal, multiply it by cominmul
                        if (value) then
                                if (not cominmul) then
                                        cominmul = 1;
                                end
                                value = value * cominmul;
                        end
                end
                
                return value;
        end;

        --[[ Parses a choice command ]]--
        MCom.ParseChoiceCommand = function (choices, multichoice, value)
                retVal = nil;
                name = nil;
                --Make sure we have the needed data
                if (choices and value) then
                        --Split the list by spaces
                        value = MCom.util.split(value, " ");
                        --Make sure it is in table format
                        if (type(value) ~= "table") then
                                value = {value};
                        end
                        --Go through all passed choices, and keep any that are in the available list
                        for choice in value do
                                local curChoice = value[choice];
                                --If this isn't a viable choice, then see if there is one with any capitalization
                                if (not choices[curChoice]) then
                                        for curCheck in choices do
                                                if ( string.lower(curChoice) == string.lower( curCheck ) ) then
                                                        curChoice = curCheck;
                                                        break;
                                                end
                                        end
                                end
                                --Make sure we have a good choice
                                if ( choices[curChoice] ) then
                                        --If it is multichoice, add it to the list
                                        if (multichoice) then
                                                if (retVal == nil) then
                                                        retVal = {};
                                                end
                                                table.insert(retVal, choices[curChoice]);
                                                --Make a named list of the selected choices
                                                if (name) then
                                                        name = name..", "..curChoice;
                                                else
                                                        name = curChoice;
                                                end
                                        else
                                                --If it's single choice, then return it
                                                retVal = choices[curChoice];
                                                name = curChoice;
                                                break;
                                        end
                                end
                        end
                end
                
                return retVal, name;
        end;
        
        --[[ Parses a color command ]]--
        MCom.ParseColorCommand = function (hasopacity, value1, value2, value3, value4)
                local value = nil;
                local dump, dump1;
                --Make sure we have atleast the R the G and the B
                if (value1 and value2 and value3) then
                        --Get valid decimals for all three values, and divide them to a percent format
                        value = {};
                        dump, dump1, value1 = string.find(value1, "(%d*%.*%d+)");
                        if (value1) then
                                value.r = value1/100;
                        end
                        dump, dump1, value2 = string.find(value2, "(%d*%.*%d+)");
                        if (value1) then
                                value.g = value2/100;
                        end
                        dump, dump1, value3 = string.find(value3, "(%d*%.*%d+)");
                        if (value3) then
                                value.b = value3/100;
                        end
                        if (hasopacity and value4) then
                                --If we are supposed to have an opacity part then
                                --Get a valid decimal for opacity, and divide it to a percent format
                                dump, dump1, value3 = string.find(value4, "(%d*%.*%d+)");
                                if (value4) then
                                        value.opacity = value4/100;
                                end
                        end
                        --If we didn't have all three values, then return nil
                        if ( not (value1 and value2 and value3) ) then
                                value = nil;
                        end
                        --If we are supposed to have opacity, and it wasn't passed, then return nil
                        if (hasopacity and (not value4) ) then
                                value = nil;
                        end
                end
                
                return value;
        end;

        --[[ The slash command handler used by MCom slash commands ]]--
        MCom.SlashCommandHandler = function (commandid, msg)
                --Only works if we have some registered slash commands
                if (MCom.SlashComs and MCom.SlashComs[commandid]) then
                        --Get a shorthand for the current command
                        curCommand = MCom.SlashComs[commandid];
                        --Only proccess the message if there is one
                        if ((msg and (msg ~= "")) or ((curCommand.comtype) and (curCommand.comtype == MCOM_BOOLT))) then
                                local subcommand, value;
                                local isSimple = true;  --Set true if the command is a standard, not super, slash command
                                local comType = nil;            --Stores the type of command
                                local badCommand = nil; --Set true if the data for the command turns out bad
                                
                                if (not curCommand.commands) then
                                        --This is simple so unpack it to the values
                                        if (msg) then
                                                value = MCom.util.split(msg, " ");
                                        end
                                else
                                        --This is a super command, so unpack the subcommand and values
                                        isSimple = nil;
                                        --Get the position of the subcommand, and the rest goes into msg2
                                        local first, last, msg2 = string.find(msg, " (.*)");
                                        --If we got the subcommand position then get that portion to the subcommand
                                        if (first) then
                                                subcommand = string.sub(msg, 1, first - 1);
                                        else
                                                --If we didn't find a position then we have only the subcommand
                                                subcommand = msg;
                                        end
                                        --Move the rest of the values into msg
                                        msg = msg2;
                                        --If we have values in msg, then parse them out
                                        if (msg) then
                                                value = MCom.util.split(msg, " ");
                                        end
                                        
                                        if (subcommand) then
                                                --Try and find an exact match of the subcommand in the list
                                                local subcommandid = nil;
                                                for curCom in MCom.SlashComs[commandid].commands do
                                                        if (MCom.SlashComs[commandid].commands[curCom].command) then
                                                                for curComCom in MCom.SlashComs[commandid].commands[curCom].command do
                                                                        if (MCom.SlashComs[commandid].commands[curCom].command[curComCom] == subcommand) then
                                                                                subcommandid = curCom;
                                                                                break;
                                                                        end
                                                                end
                                                                if (subcommandid) then
                                                                        break;
                                                                end
                                                        end
                                                end
                                                
                                                if (not subcommandid) then
                                                        --Try and find a similar match of the subcommand in the list
                                                        for curCom in MCom.SlashComs[commandid].commands do
                                                                if (MCom.SlashComs[commandid].commands[curCom].command) then
                                                                        for curComCom in MCom.SlashComs[commandid].commands[curCom].command do
                                                                                if (string.find(MCom.SlashComs[commandid].commands[curCom].command[curComCom], subcommand)) then
                                                                                        subcommandid = curCom;
                                                                                        break;
                                                                                end
                                                                        end
                                                                        if (subcommandid) then
                                                                                break;
                                                                        end
                                                                end
                                                        end
                                                end
                                                
                                                if (not subcommandid) then
                                                        --We didn't find the sub command, so we've got a bad command
                                                        badCommand = true;
                                                else
                                                        --We found the sub command so change curCommand to point at it
                                                        curCommand = curCommand.commands[subcommandid];
                                                end
                                        else
                                                --No subcommand passed, so thats a bad command
                                                badCommand = true;
                                        end
                                end
                                --We only want to continue if the command was good
                                if (not badCommand) then
                                        --Get the command type
                                        if (curCommand.comtype) then
                                                comType = curCommand.comtype;
                                        end
                                        
                                        local retVal, retVal2;

                                        if ( ( (comType == MCOM_BOOLT) or curCommand.hasbool ) and (value == nil) ) then
                                                --If nothing was passed and its a bool command then invert it
                                                curCommand.comfunc(-1);
                                        elseif ( (comType ~= MCOM_SIMPLET) ) then
                                                --If it's not a simply command parse the data if we have data
                                                if (value) then
                                                        --Setup a list of variables to use for checking the passed data
                                                        local checkVal = value[1];
                                                        local checkVal2 = value[2];
                                                        local checkVal3 = value[3];
                                                        local checkVal4 = value[4];
                                                        --This stores the boolean portion of the command, if it has two parts
                                                        local boolVal = value;
                                                        --This stores the display name for choice types
                                                        local name = nil;
                                                        if ( (comType == MCOM_MULTIT) or (curCommand.hasbool and (comType ~= MCOM_BOOLT)) ) then
                                                                --Since the first value was the boolean, move the other values down in the list
                                                                checkVal = value[2];
                                                                checkVal2 = value[3];
                                                                checkVal3 = value[4];
                                                                checkVal4 = value[5];
                                                                
                                                                --Remove the boolean part of the message
                                                                local dump1, dump2;
                                                                dump1, dump2, msg = string.find(msg, " (.*)");
                                                        end
                                                        
                                                        --If it is a multi part, or a boolean, then parse the first value as boolean
                                                        if ( (comType == MCOM_BOOLT) or (comType == MCOM_MULTIT) or curCommand.hasbool ) then
                                                                boolVal = MCom.ParseBoolCommand(value[1]);
                                                                value = boolVal;
                                                        end
                                                        
                                                        --Parse the value, or secondary as the appropriate type
                                                        if ( (comType == MCOM_NUMT) or (comType == MCOM_MULTIT) ) then
                                                                value = MCom.ParseNumCommand(curCommand.cominmul, checkVal);
                                                        elseif (comType == MCOM_STRINGT) then
                                                                --For string we pass the message so spaces can be included
                                                                value = msg;
                                                        elseif (comType == MCOM_CHOICET) then
                                                                --For choice we pass the message so as many passed choices as are passed can be used on a multichoice
                                                                value, name = MCom.ParseChoiceCommand(curCommand.choices, curCommand.multichoice, msg);
                                                        elseif (comType == MCOM_COLORT) then
                                                                value = MCom.ParseColorCommand(curCommand.hasopacity, checkVal, checkVal2, checkVal3, checkVal4);
                                                        end
                                                        
                                                        if ( (comType == MCOM_MULTIT) or (curCommand.hasbool and (comType ~= MCOM_BOOLT)) ) then
                                                                --Handle the two part commands
                                                                if (boolVal or value) then
                                                                        --Call the function
                                                                        retVal, retVal2 = curCommand.comfunc(boolVal, value, name);
                                                                else
                                                                        --We got bad data
                                                                        badCommand = true;
                                                                end
                                                        else
                                                                --Handle the one part commands
                                                                if (value) then
                                                                        --Call the function
                                                                        retVal = curCommand.comfunc(value, name);
                                                                else
                                                                        --We got bad data
                                                                        badCommand = true;
                                                                end
                                                        end
                                                else
                                                        badCommand = true;
                                                end
                                        else
                                                --It's a simple type, so just call it and quit
                                                curCommand.comfunc();
                                                return;
                                        end

                                        if (not badCommand) then
                                                --If Khaos is around, then we update the variable with it, if possible
                                                if (Khaos and (curCommand.comvar or retVal) and curCommand.uivar and curCommand.uisec) then
                                                        --Make sure the passed set exists
                                                        if ( KhaosData.configurationSets and (KhaosData.configurationSets[curCommand.uisec]) ) then
                                                                --get the value of the variable
                                                                local newVal = MCom.getStringVar(curCommand.comvar);
                                                                --If a value was returned from the setter function, then use it
                                                                if (retVal) then
                                                                        newVal = retVal;
                                                                end
                                                                if (newVal) then
                                                                        --Get the second part variable if there is one
                                                                        local newValMulti = MCom.getStringVar(curCommand.comvarmulti);
                                                                        --If a value was returned from the setter function from the second part, then use it
                                                                        if (retVal2) then
                                                                                newValMulti = retVal2;
                                                                        end
                                                                        
                                                                        --Default param type is value
                                                                        local param = "value";
                                                                        --If we have a boolean type, or boolean portion, then update that
                                                                        if ( (comType == MCOM_BOOLT) or (comType == MCOM_MULTIT) or curCommand.hasbool) then
                                                                                --Make sure its in true/false format
                                                                                if (newVal == 1) then
                                                                                        newVal = true;
                                                                                else
                                                                                        newVal = false;
                                                                                end
                                                                                --Update the boolean variable
                                                                                Khaos.setSetKeyParameter(curCommand.uisec, curCommand.uivar, "checked", newVal);
                                                                        end
                                                                        --If it isn't a boolean type, then update the other types, or secondary variable
                                                                        if ( comType ~= MCOM_BOOLT ) then
                                                                                --If we have a secondary variable, then switch to using it
                                                                                if (newValMulti) then
                                                                                        newVal = newValMulti;
                                                                                end
                                                                                
                                                                                --Treat number types as sliders
                                                                                if ( (comType == MCOM_NUMT) or (comType == MCOM_MULTIT) ) then
                                                                                        param = "slider";
                                                                                end
                                                                                
                                                                                --Treat color types as color pickers
                                                                                if (comType == MCOM_COLORT) then
                                                                                        param = "color";
                                                                                end
                                                                        
                                                                                --Update the variable
                                                                                Khaos.setSetKeyParameter(curCommand.uisec, curCommand.uivar, param, newVal);
                                                                        end
                                                                end
                                                        end
                                                else
                                                        if(CosmosMaster_Init and (curCommand.comvar or retVal) and curCommand.uivar) then
                                                                --get the value of the variable
                                                                local newVal = MCom.getStringVar(curCommand.comvar);
                                                                if (retVal) then
                                                                        newVal = retVal;
                                                                end
                                                                if (newVal) then
                                                                        local newValMulti = MCom.getStringVar(curCommand.comvarmulti);
                                                                        if (retVal2) then
                                                                                newValMulti = retVal2;
                                                                        end
                                                                        if (((comType ~= MCOM_MULTIT) and (not ((comType ~= MCOM_BOOLT) and curCommand.hasbool))) or (((comType == MCOM_MULTIT) or ((comType ~= MCOM_BOOLT) and curCommand.hasbool)) and newValMulti)) then
                                                                                --if its a boolean, then set the checkbox
                                                                                if ((comType == MCOM_BOOLT) or (comType == MCOM_MULTIT)) then
                                                                                        Cosmos_UpdateValue(curCommand.uivar, CSM_CHECKONOFF, newVal);
                                                                                end
                                                                                --if its a number, then set the slider
                                                                                if ((comType == MCOM_NUMT) or (comType == MCOM_MULTIT)) then
                                                                                        if (comType == MCOM_MULTIT) then
                                                                                                newVal = newValMulti;
                                                                                        end
                                                                                        Cosmos_UpdateValue(curCommand.uivar, CSM_SLIDERVALUE, newVal);
                                                                                end
                                                                        end
                                                                end
                                                        end
                                                end
                                                return;
                                        end
                                end
                        elseif ((curCommand.comtype) and (curCommand.comtype == MCOM_SIMPLET)) then
                                --If the command is a standard simple command, then just execute it
                                curCommand.comfunc();
                                return;
                        end
                        
                        --If we didn't find any valid commands we print out the help
                        local infoText = MCom.PrintSlashCommandInfo(commandid, true);
                        MCom.textFrame( { text = infoText; title = MCOM_HELP_GENERIC_TITLE; } );
                end
        end;

        --[[ Either prints out, or adds to a string the current chat line ]]--
        MCom.PrintSlashCommandLine = function ( asString, chatLine, extraLine )
                --If it's supposed to be in a string then add this to the string
                if ( asString ) then
                        --If it isn't a string yet, then just set it to this line
                        if ( type(asString) ~= "string" ) then
                                asString = chatLine;
                        else
                                --It's already a string so add a newline and then this line
                                if (extraLine) then
                                        asString = asString.."\n\n"..chatLine
                                else
                                        asString = asString.."\n"..chatLine
                                end
                        end
                        --Return the string
                        return asString;
                else
                        --Print out the chat line
                        MCom.IO.printc(ChatTypeInfo["SYSTEM"], chatLine);
                end
        end

        --[[ Prints the help for a chat command ]]--
        MCom.PrintSlashCommandInfo = function (commandid, asString)
                if (MCom.SlashComs[commandid]) then
                        local chatLine = ""; --The current line of text to be printed
                        local basecommand = MCom.SlashComs[commandid].basecommand[1];

                        --Construct a list of the aliases for the command, if any
                        local aliasList = "";
                        if (getn(MCom.SlashComs[commandid].basecommand) > 1) then
                                for curCom = 2, getn(MCom.SlashComs[commandid].basecommand) do
                                        if (aliasList ~= "") then
                                                aliasList = aliasList..", ";
                                        else
                                                aliasList = basecommand..", ";
                                        end
                                        aliasList = aliasList..MCom.SlashComs[commandid].basecommand[curCom];
                                end
                        end

                        --Print list of aliases, if there are any
                        if (aliasList ~= "") then
                                chatLine = string.format(MCOM_CHAT_COM_ALIAS, aliasList);
                                asString = MCom.PrintSlashCommandLine(asString, chatLine, true);
                        end

                        local isSimple = true;          --Set true if this command does not have sub commands
                        local eSample = nil;                    --Set to something if a simple command is found
                        local bSample = nil;                    --Set to something if a bool command is found
                        local nSample = nil;                    --Set to something if a num command is found
                        local nSampleV = nil;                   --Set to and example value for a number command
                        local sSample = nil;                    --Set to something if a string command is found
                        local cSample = nil;                    --Set to something if a choice command is found
                        local cnSampleV = nil;          --Set to and example value for a choice command
                        local cmSample = nil;                   --Set to something if a multi choice command is found
                        local cmnSampleV = nil;         --Set to and example value for a multi choice command
                        local koSample = nil;                   --Set to something if a color with opacity command is found
                        local bnSample = nil;                   --Set to something if a bool and num command is found
                        local bnSampleV = nil;          --Set to and example value for a bool and number command
                        local bsSample = nil;                   --Set to something if a bool and string command is found
                        local bcSample = nil;                   --Set to something if a bool and choice command is found
                        local bcnSampleV = nil;         --Set to and example value for a bool and choice command
                        local bcmSample = nil;          --Set to something if a bool and multi choice command is found
                        local bcmnSampleV = nil;        --Set to and example value for a bool and multi choice command
                        local bkoSample = nil;          --Set to something if a bool and color with opacity command is found

                        --If this command has sub commands, then print a list of them
                        if (MCom.SlashComs[commandid].commands) then
                                asString = MCom.PrintSlashCommandLine(asString, MCOM_CHAT_COM_COMMANDS, true);
                                isSimple = nil; --This is not a simple command, lets remember that
                                for curCom = 1, getn(MCom.SlashComs[commandid].commands) do
                                        local curComType = MCOM_SIMPLET;        --Default our type to simple
                                        local curComBool = false;                                       --Default has bool to false
                                        local curComChoices = nil;                              --The choices for a choice type
                                        local curComMulti = false;                              --Default multi choice to false
                                        local curComOpacity = false;                    --Default has opacity to false
                                        local curComValue = nil;                                        --The value of the variable associated with the command
                                        local curComValueMulti = nil;                   --The value of the multi variable associated with the command
                                        local curComMin = nil;                                          --The minimum a value can be set to
                                        local curComMax = nil;                                          --The maximum a value can be set to
                                        local curComMul = 1;                                                    --The value to multiply numbers by when showing status
                                        --If a type is specified look it up
                                        if (MCom.SlashComs[commandid].commands[curCom].comtype) then
                                                curComType = MCom.SlashComs[commandid].commands[curCom].comtype;
                                        end
                                        --If a hasbool is specified look it up
                                        if (MCom.SlashComs[commandid].commands[curCom].hasbool) then
                                                curComBool = true;
                                        end
                                        --If choices are specified look them up
                                        if (MCom.SlashComs[commandid].commands[curCom].choices) then
                                                curComChoices = MCom.SlashComs[commandid].commands[curCom].choices;
                                        end
                                        --If a multichoioce is specified look it up
                                        if (MCom.SlashComs[commandid].commands[curCom].multichoice) then
                                                curComMulti = true;
                                        end
                                        --If a hasopacity is specified look it up
                                        if (MCom.SlashComs[commandid].commands[curCom].hasopacity) then
                                                curComOpacity = MCom.SlashComs[commandid].commands[curCom].hasopacity;
                                        end
                                        --If a comvar is specified look it up
                                        if (MCom.SlashComs[commandid].commands[curCom].comvar ~= nil) then
                                                curComValue = MCom.getStringVar(MCom.SlashComs[commandid].commands[curCom].comvar);
                                        end
                                        --If a comvarmulti is specified look it up
                                        if (MCom.SlashComs[commandid].commands[curCom].comvarmulti ~= nil) then
                                                curComValueMulti = MCom.getStringVar(MCom.SlashComs[commandid].commands[curCom].comvarmulti);
                                        end
                                        --If a commin is specified look it up
                                        if (MCom.SlashComs[commandid].commands[curCom].commin ~= nil) then
                                                curComMin = MCom.SlashComs[commandid].commands[curCom].commin;
                                        end
                                        --If a commax is specified look it up
                                        if (MCom.SlashComs[commandid].commands[curCom].commax ~= nil) then
                                                curComMax = MCom.SlashComs[commandid].commands[curCom].commax;
                                        end
                                        --If a commul is specified look it up
                                        if (MCom.SlashComs[commandid].commands[curCom].commul ~= nil) then
                                                curComMul = MCom.SlashComs[commandid].commands[curCom].commul;
                                        end
                                        
                                        --Store this command as a sample of whatever type it is
                                        if ((not eSample) and (curComType == MCOM_SIMPLET)) then
                                                eSample = MCom.SlashComs[commandid].commands[curCom].command[1];
                                        end
                                        if ((not bSample) and (curComType == MCOM_BOOLT)) then
                                                bSample = MCom.SlashComs[commandid].commands[curCom].command[1];
                                        end
                                        if (not curComBool) then
                                                if ((not nSample) and (curComType == MCOM_NUMT)) then
                                                        nSample = MCom.SlashComs[commandid].commands[curCom].command[1];
                                                        --Get a valid sample number
                                                        nSampleV = curComMin;
                                                        if (not nSampleV) then
                                                                nSampleV = curComMax;
                                                        end
                                                        if (not nSampleV) then
                                                                nSampleV = MCOM_CHAT_COM_EXAMPLE_O_N;
                                                        end
                                                end
                                                if ((not sSample) and (curComType == MCOM_STRINGT)) then
                                                        sSample = MCom.SlashComs[commandid].commands[curCom].command[1];
                                                end
                                                if (not curComMulti) then
                                                        if ((not cSample) and (curComType == MCOM_CHOICET)) then
                                                                cSample = MCom.SlashComs[commandid].commands[curCom].command[1];
                                                                --Get a valid sample choice
                                                                for sampleV in curComChoices do
                                                                        cSampleV = sampleV;
                                                                        break;
                                                                end
                                                        end
                                                else
                                                        if ((not cmSample) and (curComType == MCOM_CHOICET)) then
                                                                cmSample = MCom.SlashComs[commandid].commands[curCom].command[1];
                                                                --Get a valid sample choice
                                                                local count = 0;
                                                                --Construct an example with two valid choices
                                                                for sampleV in curComChoices do
                                                                        count = count + 1;
                                                                        if (cmSampleV) then
                                                                                cmSampleV = cmSampleV.." "..sampleV;
                                                                        else
                                                                                cmSampleV = sampleV;
                                                                        end
                                                                        if (count > 1) then
                                                                                break;
                                                                        end
                                                                end
                                                        end
                                                end
                                                if (not curComOpacity) then
                                                        if ((not kSample) and (curComType == MCOM_COLORT)) then
                                                                kSample = MCom.SlashComs[commandid].commands[curCom].command[1];
                                                        end
                                                else
                                                        if ((not koSample) and (curComType == MCOM_COLORT)) then
                                                                koSample = MCom.SlashComs[commandid].commands[curCom].command[1];
                                                        end
                                                end
                                        else
                                                if ((not bnSample) and ((curComType == MCOM_NUMT) or (curComType == MCOM_MULTIT))) then
                                                        bnSample = MCom.SlashComs[commandid].commands[curCom].command[1];
                                                        --Get a valid sample number
                                                        bnSampleV = curComMin;
                                                        if (not bnSampleV) then
                                                                bnSampleV = curComMax;
                                                        end
                                                        if (not bnSampleV) then
                                                                bnSampleV = MCOM_CHAT_COM_EXAMPLE_O_N;
                                                        end
                                                end
                                                if ((not bsSample) and (curComType == MCOM_STRINGT)) then
                                                        bsSample = MCom.SlashComs[commandid].commands[curCom].command[1];
                                                end
                                                if (not curComMulti) then
                                                        if ((not bcSample) and (curComType == MCOM_CHOICET)) then
                                                                bcSample = MCom.SlashComs[commandid].commands[curCom].command[1];
                                                                --Get a valid sample choice
                                                                for sampleV in curComChoices do
                                                                        bcSampleV = sampleV;
                                                                        break;
                                                                end
                                                        end
                                                else
                                                        if ((not bcmSample) and (curComType == MCOM_CHOICET)) then
                                                                bcmSample = MCom.SlashComs[commandid].commands[curCom].command[1];
                                                                --Get a valid sample choice
                                                                local count = 0;
                                                                --Construct an example with two valid choices
                                                                for sampleV in curComChoices do
                                                                        count = count + 1;
                                                                        if (bcmSampleV) then
                                                                                bcmSampleV = bcmSampleV.." "..sampleV;
                                                                        else
                                                                                bcmSampleV = sampleV;
                                                                        end
                                                                        if (count > 1) then
                                                                                break;
                                                                        end
                                                                end
                                                        end
                                                end
                                                if (not curComOpacity) then
                                                        if ((not bkSample) and (curComType == MCOM_COLORT)) then
                                                                bkSample = MCom.SlashComs[commandid].commands[curCom].command[1];
                                                        end
                                                else
                                                        if ((not bkoSample) and (curComType == MCOM_COLORT)) then
                                                                bkoSample = MCom.SlashComs[commandid].commands[curCom].command[1];
                                                        end
                                                end
                                        end
                                        
                                        --If help was specified look it up
                                        local curHelp = MCOM_CHAT_COM_NOINFO;
                                        if (MCom.SlashComs[commandid].commands[curCom].comhelp) then
                                                curHelp = MCom.SlashComs[commandid].commands[curCom].comhelp;
                                        end
                                        --If we have a choice type, then make a list of the choices, and tack that onto the help
                                        if ( curComType == MCOM_CHOICET ) then
                                                if (curHelp == MCOM_CHAT_COM_NOINFO) then
                                                        curHelp = MCOM_CHAT_COM_CLIST;
                                                end
                                                local curChoices = nil;
                                                for curChoice in curComChoices do
                                                        if (curChoices) then
                                                                curChoices = curChoices..", "..curChoice;
                                                        else
                                                                curChoices = curChoice;
                                                        end
                                                end
                                                curHelp = string.format(curHelp, curChoices);
                                        end
                                        
                                        --If we have aliases for this sub command then make a list
                                        local comList = MCom.SlashComs[commandid].commands[curCom].command[1];
                                        if (getn(MCom.SlashComs[commandid].commands[curCom].command) > 1) then
                                                for curAlias = 2, getn(MCom.SlashComs[commandid].commands[curCom].command) do
                                                        comList = comList.."/"..MCom.SlashComs[commandid].commands[curCom].command[curAlias];
                                                end
                                        end
                
                                        --Prepare the type string
                                        local curComTypeString = curComType;
                                        if ( curComType == MCOM_MULTIT ) then
                                                curComTypeString = MCOM_NUMT;
                                        end
                                        if ( curComMulti and (curComType == MCOM_CHOICET) ) then
                                                curComTypeString = MCOM_CHAT_C_M;
                                        end
                                        if ( curComOpacity and (curComType == MCOM_COLORT) ) then
                                                curComTypeString = MCOM_CHAT_K_O;
                                        end
                                        if ( curComBool and (not (curComType == MCOM_BOOLT) ) ) then
                                                curComTypeString = MCOM_BOOLT..curComTypeString;
                                        end
                                        --If we have a number type, then display the min and max values
                                        if ( ( curComType == MCOM_NUMT ) or ( curComType == MCOM_MULTIT ) ) then
                                                local curRangeString = nil;
                                                if (curComMin) then
                                                        curRangeString = string.format(MCOM_CHAT_COM_N_MIN, curComMin * curComMul);
                                                end
                                                if (curComMax) then
                                                        if (curRangeString) then
                                                                curRangeString = curRangeString..", ";
                                                        else
                                                                curRangeString = "";
                                                        end
                                                        curRangeString = curRangeString..string.format(MCOM_CHAT_COM_N_MAX, curComMax * curComMul);
                                                end
                                                if (curRangeString) then
                                                        curComTypeString = curComTypeString..string.format(MCOM_CHAT_COM_N_RANGE, curRangeString);
                                                end
                                        end

                                        --Prepare the command info
                                        local curValString = nil;
                                        if ( ( curComType == MCOM_SIMPLET ) or ( curComValue == nil ) ) then
                                                chatLine = string.format(MCOM_CHAT_COM_SUBCOMMAND_S, comList, curComTypeString, curHelp);
                                        elseif ( curComValue ~= nil ) then
                                                --If it is a bool, or has a bool, then get the boolean part
                                                if ( curComBool or ( curComType == MCOM_BOOLT ) ) then
                                                        if ( curComValue == 1 ) then
                                                                curValString = MCOM_CHAT_ON;
                                                        else
                                                                curValString = MCOM_CHAT_OFF;
                                                        end
                                                end
                                                --If this doesn't have a boolean part, then handle curcomvalue
                                                if (not curComBool) then
                                                        --Handle number type
                                                        if ( ( curComType == MCOM_NUMT ) or ( curComType == MCOM_MULTIT ) ) then
                                                                curValString = ( MCom.math.round( ( curComValue * curComMul ) * 100 ) / 100 );
                                                        end
                                                        --Handle string type
                                                        if ( curComType == MCOM_STRINGT ) then
                                                                curValString = curComValue;
                                                        end
                                                        --If it's a choice type, then handle the one choice, or a list of choices
                                                        if (curComType == MCOM_CHOICET) then
                                                                --If we don't have a table of choices, then just use the values
                                                                if ( type(curComChoices) ~= "table" ) then
                                                                        --If this can not have multiple choices, then use just the one
                                                                        if (not curComMulti) then
                                                                                curValString = curComValue;
                                                                        elseif ( type(curComValue) == "table" ) then
                                                                                --This is a multi choice selection, so make a list of selected choices
                                                                                curValString = curComValue[1];
                                                                                if ( curValString ~= nil ) then
                                                                                        for curVal = 2, table.getn(curComValue) do
                                                                                                if ( curComValue[curVal] ~= nil ) then
                                                                                                        curValString = curValString..", "..curComValue[curVal];
                                                                                                end
                                                                                        end
                                                                                end
                                                                        end
                                                                else
                                                                        --If we have a table of choices, then make a table indexed by value
                                                                        local curChoiceDex = {};
                                                                        for curChoice in curComChoices do
                                                                                curChoiceDex[curComChoices[curChoice]] = curChoice;
                                                                        end
                                                                        --If this can not have multiple choices, then use just the one
                                                                        if (not curComMulti) then
                                                                                curValString = curChoiceDex[curComValue];
                                                                        elseif ( type(curComValue) == "table" ) then
                                                                                --This is a multi choice selection, so make a list of selected choices
                                                                                curValString = curChoiceDex[curComValue[1]];
                                                                                if ( curValString ~= nil ) then
                                                                                        for curVal = 2, table.getn(curComValue) do
                                                                                                if ( ( curComValue[curVal] ~= nil ) and ( curChoiceDex[curComValue[curVal]] ~= nil ) ) then
                                                                                                        curValString = curValString..", "..curChoiceDex[curComValue[curVal]];
                                                                                                end
                                                                                        end
                                                                                end
                                                                        end
                                                                end
                                                        end
                                                        --If it's a color type, then handle the color parts
                                                        if (curComType == MCOM_COLORT) then
                                                                if ( type(curComValue) == "table" ) then
                                                                        local curColString = "";
                                                                        if (curComValue.r) then
                                                                                curColString = string.format(MCOM_CHAT_COM_K_R, MCom.math.round(curComValue.r * 100));
                                                                        end
                                                                        if (curComValue.g) then
                                                                                if ( curColString ~= "" ) then
                                                                                        curColString = curColString..", ";
                                                                                end
                                                                                curColString = curColString..string.format(MCOM_CHAT_COM_K_G, MCom.math.round(curComValue.g * 100));
                                                                        end
                                                                        if (curComValue.b) then
                                                                                if ( curColString ~= "" ) then
                                                                                        curColString = curColString..", ";
                                                                                end
                                                                                curColString = curColString..string.format(MCOM_CHAT_COM_K_B, MCom.math.round(curComValue.b * 100));
                                                                        end
                                                                        if (curComOpacity) then
                                                                                local displayOpacity = 1;
                                                                                if (curComValue.opacity) then
                                                                                        displayOpacity = curComValue.opacity;
                                                                                end
                                                                                if ( curColString ~= "" ) then
                                                                                        curColString = curColString..", ";
                                                                                end
                                                                                curColString = curColString..string.format(MCOM_CHAT_COM_K_O, MCom.math.round(displayOpacity * 100));
                                                                        end
                                                                        if ( curColString ~= "" ) then
                                                                                curColString = curColString..", ";
                                                                        end
                                                                        curColString = curColString..string.format(MCOM_CHAT_COM_K_X, MCom.string.colorToString(curComValue));
                                                                        curValString = curColString;
                                                                end
                                                        end
                                                elseif ( curComValueMulti ~= nil ) then
                                                        --If we have a second variable, then prepare the second part of the string
                                                        if ( curValString == nil ) then
                                                                curValString = "";
                                                        else
                                                                curValString = curValString..", ";
                                                        end
                                                        --Handle number type
                                                        if ( ( curComType == MCOM_NUMT ) or ( curComType == MCOM_MULTIT ) ) then
                                                                curValString = curValString..( MCom.math.round( ( curComValueMulti * curComMul ) * 100 ) / 100 );
                                                        end
                                                        --Handle string type
                                                        if ( curComType == MCOM_STRINGT ) then
                                                                curValString = curValString..curComValueMulti;
                                                        end
                                                        --If it's a choice type, then handle the one choice, or a list of choices
                                                        if (curComType == MCOM_CHOICET) then
                                                                --If we don't have a table of choices, then just use the values
                                                                if ( type(curComChoices) ~= "table" ) then
                                                                        --If this can not have multiple choices, then use just the one
                                                                        if (not curComMulti) then
                                                                                curValString = curValString..curComValueMulti;
                                                                        elseif ( type(curComValueMulti) == "table" ) then
                                                                                --This is a multi choice selection, so make a list of selected choices
                                                                                curValString = curValString..curComValueMulti[1];
                                                                                if ( curComValueMulti[1] ~= nil ) then
                                                                                        for curVal = 2, table.getn(curComValueMulti) do
                                                                                                if ( curComValueMulti[curVal] ~= nil ) then
                                                                                                        curValString = curValString..", "..curComValueMulti[curVal];
                                                                                                end
                                                                                        end
                                                                                end
                                                                        end
                                                                else
                                                                        --If we have a table of choices, then make a table indexed by value
                                                                        local curChoiceDex = {};
                                                                        for curChoice in curComChoices do
                                                                                curChoiceDex[curComChoices[curChoice]] = curChoice;
                                                                        end
                                                                        --If this can not have multiple choices, then use just the one
                                                                        if (not curComMulti) then
                                                                                curValString = curValString..curChoiceDex[curComValueMulti];
                                                                        elseif ( type(curComValueMulti) == "table" ) then
                                                                                --This is a multi choice selection, so make a list of selected choices
                                                                                curValString = curValString..curChoiceDex[curComValueMulti[1]];
                                                                                if ( curChoiceDex[curComValueMulti[1]] ~= nil ) then
                                                                                        for curVal = 2, table.getn(curComValueMulti) do
                                                                                                if ( ( curComValueMulti[curVal] ~= nil ) and ( curChoiceDex[curComValueMulti[curVal]] ~= nil ) ) then
                                                                                                        curValString = curValString..", "..curChoiceDex[curComValueMulti[curVal]];
                                                                                                end
                                                                                        end
                                                                                end
                                                                        end
                                                                end
                                                        end
                                                        --If it's a color type, then handle the color parts
                                                        if (curComType == MCOM_COLORT) then
                                                                if ( type(curComValueMulti) == "table" ) then
                                                                        local curColString = "";
                                                                        if (curComValueMulti.r) then
                                                                                curColString = string.format(MCOM_CHAT_COM_K_R, MCom.math.round(curComValueMulti.r * 100));
                                                                        end
                                                                        if (curComValueMulti.g) then
                                                                                if ( curColString ~= "" ) then
                                                                                        curColString = curColString.." ";
                                                                                end
                                                                                curColString = curColString..string.format( MCOM_CHAT_COM_K_G, MCom.math.round(curComValueMulti.g * 100));
                                                                        end
                                                                        if (curComValueMulti.b) then
                                                                                if ( curColString ~= "" ) then
                                                                                        curColString = curColString.." ";
                                                                                end
                                                                                curColString = curColString..string.format(MCOM_CHAT_COM_K_B, MCom.math.round(curComValueMulti.b * 100));
                                                                        end
                                                                        if (curComOpacity) then
                                                                                if (curComValueMulti.opacity) then
                                                                                        if ( curColString ~= "" ) then
                                                                                                curColString = curColString.." ";
                                                                                        end
                                                                                        curColString = curColString..string.format(MCOM_CHAT_COM_K_O, MCom.math.round(curComValueMulti.opacity * 100));
                                                                                end
                                                                        end
                                                                        if ( curColString ~= "" ) then
                                                                                curColString = curColString..", ";
                                                                        end
                                                                        curColString = curColString..string.format(MCOM_CHAT_COM_K_X, MCom.string.colorToString(curComValueMulti));
                                                                        curValString = curValString..curColString;
                                                                end
                                                        end
                                                end
                                                if ( ( curValString ~= nil ) and ( curValString ~= "" ) and ( curValString ~= ", " ) ) then
                                                        chatLine = string.format(MCOM_CHAT_COM_SUBCOMMAND, comList, curComTypeString, curValString, curHelp);
                                                else
                                                        chatLine = string.format(MCOM_CHAT_COM_SUBCOMMAND_S, comList, curComTypeString, curHelp);
                                                end
                                        end

                                        --Print out the command info
                                        asString = MCom.PrintSlashCommandLine(asString, chatLine, true);
                                end
                        else
                                --This is a simple command, find out what type it is, and set the correct sample
                                if (MCom.SlashComs[commandid].comtype == MCOM_BOOLT) then
                                        bSample = true;
                                else
                                        if (not MCom.SlashComs[commandid].hasbool) then
                                                if (MCom.SlashComs[commandid].comtype == MCOM_NUMT) then
                                                        nSample = true;
                                                        --Get a valid sample number
                                                        nSampleV = MCom.SlashComs[commandid].commin;
                                                        if (not nSampleV) then
                                                                nSampleV = MCom.SlashComs[commandid].commax;
                                                        end
                                                        if (not nSampleV) then
                                                                nSampleV = MCOM_CHAT_COM_EXAMPLE_O_N;
                                                        end
                                                elseif (MCom.SlashComs[commandid].comtype == MCOM_STRINGT) then
                                                        sSample = true;
                                                elseif (MCom.SlashComs[commandid].comtype == MCOM_CHOICET) then
                                                        if (not MCom.SlashComs[commandid].multichoice) then
                                                                cSample = true;
                                                                --Get a valid sample choice
                                                                for sampleV in MCom.SlashComs[commandid].choices do
                                                                        cSampleV = sampleV;
                                                                        break;
                                                                end
                                                        else
                                                                cmSample = true;
                                                                --Get a valid sample choice
                                                                local count = 0;
                                                                --Construct an example with two valid choices
                                                                for sampleV in MCom.SlashComs[commandid].choices do
                                                                        count = count + 1;
                                                                        if (cmSampleV) then
                                                                                cmSampleV = cmSampleV.." "..sampleV;
                                                                        else
                                                                                cmSampleV = sampleV;
                                                                        end
                                                                        if (count > 1) then
                                                                                break;
                                                                        end
                                                                end
                                                        end
                                                elseif (MCom.SlashComs[commandid].comtype == MCOM_COLORT) then
                                                        if (not MCom.SlashComs[commandid].hasopacity) then
                                                                kSample = true;
                                                        else
                                                                okSample = true;
                                                        end
                                                else
                                                        eSample = true;
                                                end
                                        else
                                                if (MCom.SlashComs[commandid].comtype == MCOM_NUMT) then
                                                        bnSample = true;
                                                elseif (MCom.SlashComs[commandid].comtype == MCOM_MULTIT) then
                                                        bnSample = true;
                                                        --Get a valid sample number
                                                        bnSampleV = MCom.SlashComs[commandid].commin;
                                                        if (not bnSampleV) then
                                                                bnSampleV = MCom.SlashComs[commandid].commax;
                                                        end
                                                        if (not bnSampleV) then
                                                                bnSampleV = MCOM_CHAT_COM_EXAMPLE_O_N;
                                                        end
                                                elseif (MCom.SlashComs[commandid].comtype == MCOM_STRINGT) then
                                                        bsSample = true;
                                                elseif (MCom.SlashComs[commandid].comtype == MCOM_CHOICET) then
                                                        if (not MCom.SlashComs[commandid].multichoice) then
                                                                bcSample = true;
                                                                --Get a valid sample choice
                                                                for sampleV in MCom.SlashComs[commandid].choices do
                                                                        bcSampleV = sampleV;
                                                                        break;
                                                                end
                                                        else
                                                                bcmSample = true;
                                                                --Get a valid sample choice
                                                                local count = 0;
                                                                --Construct an example with two valid choices
                                                                for sampleV in MCom.SlashComs[commandid].choices do
                                                                        count = count + 1;
                                                                        if (bcmSampleV) then
                                                                                bcmSampleV = bcmSampleV.." "..sampleV;
                                                                        else
                                                                                bcmSampleV = sampleV;
                                                                        end
                                                                        if (count > 1) then
                                                                                break;
                                                                        end
                                                                end
                                                        end
                                                elseif (MCom.SlashComs[commandid].comtype == MCOM_COLORT) then
                                                        if (not MCom.SlashComs[commandid].hasopacity) then
                                                                bkSample = true;
                                                        else
                                                                bokSample = true;
                                                        end
                                                else
                                                        eSample = true;
                                                end
                                        end
                                end
                        end     
                        
                        --Print basic usage info
                        local usageLine = MCOM_CHAT_COM_USAGE;
                        if (bSample or bnSample or bsSample or bcSample or bcmSample or bkSample or bkoSample) then
                                usageLine = usageLine.."\n\n"..MCOM_CHAT_COM_USAGE_B;
                        end
                        if (bnSample) then
                                usageLine = usageLine.."\n\n"..string.format(MCOM_CHAT_COM_USAGE_B_M, MCOM_NUMT, MCOM_CHAT_COM_USAGE_B_N);
                        elseif (bsSample) then
                                usageLine = usageLine.."\n\n"..string.format(MCOM_CHAT_COM_USAGE_B_M, MCOM_STRINGT, MCOM_CHAT_COM_USAGE_B_S);
                        elseif (bcSample or bcmSample) then
                                usageLine = usageLine.."\n\n"..string.format(MCOM_CHAT_COM_USAGE_B_M, MCOM_CHOICET, MCOM_CHAT_COM_USAGE_B_C);
                        elseif (bkSample or bkoSample) then
                                usageLine = usageLine.."\n\n"..string.format(MCOM_CHAT_COM_USAGE_B_M, MCOM_COLORT, MCOM_CHAT_COM_USAGE_B_K);
                        end
                        asString = MCom.PrintSlashCommandLine(asString, usageLine, true);
                        
                        --Print detailed usage info
                        if (isSimple) then
                                --If its simple we print the simple versions of the usage info, but only for the command type
                                if (eSample) then
                                        chatLine = string.format(MCOM_CHAT_COM_USAGE_S_E, basecommand);
                                        asString = MCom.PrintSlashCommandLine(asString, chatLine, true);
                                end
                                if (bSample) then
                                        chatLine = string.format(MCOM_CHAT_COM_USAGE_S_S, basecommand, MCOM_CHAT_COM_B);
                                        asString = MCom.PrintSlashCommandLine(asString, chatLine, true);
                                end
                                if (nSample) then
                                        chatLine = string.format(MCOM_CHAT_COM_USAGE_S_S, basecommand, MCOM_CHAT_COM_N);
                                        asString = MCom.PrintSlashCommandLine(asString, chatLine, true);
                                end
                                if (sSample) then
                                        chatLine = string.format(MCOM_CHAT_COM_USAGE_S_S, basecommand, MCOM_CHAT_COM_S);
                                        asString = MCom.PrintSlashCommandLine(asString, chatLine, true);
                                end
                                if (cSample) then
                                        chatLine = string.format(MCOM_CHAT_COM_USAGE_S_S, basecommand, MCOM_CHAT_COM_C);
                                        asString = MCom.PrintSlashCommandLine(asString, chatLine, true);
                                end
                                if (cmSample) then
                                        chatLine = string.format(MCOM_CHAT_COM_USAGE_S_S, basecommand, MCOM_CHAT_COM_C_M);
                                        asString = MCom.PrintSlashCommandLine(asString, chatLine, true);
                                end
                                if (kSample) then
                                        chatLine = string.format(MCOM_CHAT_COM_USAGE_S_S, basecommand, MCOM_CHAT_COM_K);
                                        asString = MCom.PrintSlashCommandLine(asString, chatLine, true);
                                end
                                if (koSample) then
                                        chatLine = string.format(MCOM_CHAT_COM_USAGE_S_S, basecommand, MCOM_CHAT_COM_K_O);
                                        asString = MCom.PrintSlashCommandLine(asString, chatLine, true);
                                end
                                if (bnSample) then
                                        chatLine = string.format(MCOM_CHAT_COM_USAGE_S_M, basecommand, MCOM_CHAT_COM_N);
                                        asString = MCom.PrintSlashCommandLine(asString, chatLine, true);
                                end
                                if (bsSample) then
                                        chatLine = string.format(MCOM_CHAT_COM_USAGE_S_M, basecommand, MCOM_CHAT_COM_S);
                                        asString = MCom.PrintSlashCommandLine(asString, chatLine, true);
                                end
                                if (bcSample) then
                                        chatLine = string.format(MCOM_CHAT_COM_USAGE_S_M, basecommand, MCOM_CHAT_COM_C);
                                        asString = MCom.PrintSlashCommandLine(asString, chatLine, true);
                                end
                                if (bcmSample) then
                                        chatLine = string.format(MCOM_CHAT_COM_USAGE_S_M, basecommand, MCOM_CHAT_COM_C_M);
                                        asString = MCom.PrintSlashCommandLine(asString, chatLine, true);
                                end
                                if (bkSample) then
                                        chatLine = string.format(MCOM_CHAT_COM_USAGE_S_M, basecommand, MCOM_CHAT_COM_K);
                                        asString = MCom.PrintSlashCommandLine(asString, chatLine, true);
                                end
                                if (bkoSample) then
                                        chatLine = string.format(MCOM_CHAT_COM_USAGE_S_M, basecommand, MCOM_CHAT_COM_K_O);
                                        asString = MCom.PrintSlashCommandLine(asString, chatLine, true);
                                end
                        else
                                --If its not simple then we print usage info for any type of subcommand used
                                if (eSample) then
                                        chatLine = string.format(MCOM_CHAT_COM_USAGE_E, basecommand);
                                        asString = MCom.PrintSlashCommandLine(asString, chatLine, true);
                                end
                                if (bSample) then
                                        chatLine = string.format(MCOM_CHAT_COM_USAGE_S, MCOM_BOOLT, basecommand, MCOM_CHAT_COM_B);
                                        asString = MCom.PrintSlashCommandLine(asString, chatLine, true);
                                end
                                if (nSample) then
                                        chatLine = string.format(MCOM_CHAT_COM_USAGE_S, MCOM_NUMT, basecommand, MCOM_CHAT_COM_N);
                                        asString = MCom.PrintSlashCommandLine(asString, chatLine, true);
                                end
                                if (sSample) then
                                        chatLine = string.format(MCOM_CHAT_COM_USAGE_S, MCOM_STRINGT, basecommand, MCOM_CHAT_COM_S);
                                        asString = MCom.PrintSlashCommandLine(asString, chatLine, true);
                                end
                                if (cSample) then
                                        chatLine = string.format(MCOM_CHAT_COM_USAGE_S, MCOM_CHOICET, basecommand, MCOM_CHAT_COM_C);
                                        asString = MCom.PrintSlashCommandLine(asString, chatLine, true);
                                end
                                if (cmSample) then
                                        chatLine = string.format(MCOM_CHAT_COM_USAGE_S, MCOM_CHAT_C_M, basecommand, MCOM_CHAT_COM_C_M);
                                        asString = MCom.PrintSlashCommandLine(asString, chatLine, true);
                                end
                                if (kSample) then
                                        chatLine = string.format(MCOM_CHAT_COM_USAGE_S, MCOM_COLORT, basecommand, MCOM_CHAT_COM_K);
                                        asString = MCom.PrintSlashCommandLine(asString, chatLine, true);
                                end
                                if (koSample) then
                                        chatLine = string.format(MCOM_CHAT_COM_USAGE_S, MCOM_CHAT_K_O, basecommand, MCOM_CHAT_COM_K_O);
                                        asString = MCom.PrintSlashCommandLine(asString, chatLine, true);
                                end
                                if (bnSample) then
                                        chatLine = string.format(MCOM_CHAT_COM_USAGE_M, MCOM_BOOLT..MCOM_NUMT, basecommand, MCOM_CHAT_COM_N);
                                        asString = MCom.PrintSlashCommandLine(asString, chatLine, true);
                                end
                                if (bsSample) then
                                        chatLine = string.format(MCOM_CHAT_COM_USAGE_M, MCOM_BOOLT..MCOM_STRINGT, basecommand, MCOM_CHAT_COM_S);
                                        asString = MCom.PrintSlashCommandLine(asString, chatLine, true);
                                end
                                if (bcSample) then
                                        chatLine = string.format(MCOM_CHAT_COM_USAGE_M, MCOM_BOOLT..MCOM_CHOICET, basecommand, MCOM_CHAT_COM_C);
                                        asString = MCom.PrintSlashCommandLine(asString, chatLine, true);
                                end
                                if (bcmSample) then
                                        chatLine = string.format(MCOM_CHAT_COM_USAGE_M, MCOM_BOOLT..MCOM_CHAT_C_M, basecommand, MCOM_CHAT_COM_C_M);
                                        asString = MCom.PrintSlashCommandLine(asString, chatLine, true);
                                end
                                if (bkSample) then
                                        chatLine = string.format(MCOM_CHAT_COM_USAGE_M, MCOM_BOOLT..MCOM_COLORT, basecommand, MCOM_CHAT_COM_K);
                                        asString = MCom.PrintSlashCommandLine(asString, chatLine, true);
                                end
                                if (bkoSample) then
                                        chatLine = string.format(MCOM_CHAT_COM_USAGE_M, MCOM_BOOLT..MCOM_CHAT_K_O, basecommand, MCOM_CHAT_COM_K_M);
                                        asString = MCom.PrintSlashCommandLine(asString, chatLine, true);
                                end
                        end
                        
                        --Print extra help for the command
                        if (MCom.SlashComs[commandid].extrahelp) then
                                if (type(MCom.SlashComs[commandid].extrahelp) ~= "table") then
                                        MCom.SlashComs[commandid].extrahelp = { MCom.SlashComs[commandid].extrahelp };
                                end
                                --Add an extra line before the extra help
                                if (asString) then
                                        asString = asString.."\n";
                                end
                                for curHelp in MCom.SlashComs[commandid].extrahelp do
                                        asString = MCom.PrintSlashCommandLine(asString, MCom.SlashComs[commandid].extrahelp[curHelp]);
                                end
                        end
                        
                        --Print example usage
                        asString = MCom.PrintSlashCommandLine(asString, MCOM_CHAT_COM_EXAMPLE, true);
                        if (isSimple) then
                                --If it's simple we print an example for the appropriate type
                                if (eSample) then
                                        chatLine = string.format(MCOM_CHAT_COM_EXAMPLE_S_E, basecommand);
                                        asString = MCom.PrintSlashCommandLine(asString, chatLine);
                                end
                                if (bSample) then
                                        chatLine = string.format(MCOM_CHAT_COM_EXAMPLE_S_S, basecommand, MCOM_CHAT_COM_EXAMPLE_O_B);
                                        asString = MCom.PrintSlashCommandLine(asString, chatLine);
                                end
                                if (nSample) then
                                        chatLine = string.format(MCOM_CHAT_COM_EXAMPLE_S_S, basecommand, nSampleV);
                                        asString = MCom.PrintSlashCommandLine(asString, chatLine);
                                end
                                if (sSample) then
                                        chatLine = string.format(MCOM_CHAT_COM_EXAMPLE_S_S, basecommand, MCOM_CHAT_COM_EXAMPLE_O_S);
                                        asString = MCom.PrintSlashCommandLine(asString, chatLine);
                                end
                                if (cSample) then
                                        chatLine = string.format(MCOM_CHAT_COM_EXAMPLE_S_S, basecommand, cSampleV);
                                        asString = MCom.PrintSlashCommandLine(asString, chatLine);
                                end
                                if (cmSample) then
                                        chatLine = string.format(MCOM_CHAT_COM_EXAMPLE_S_S, basecommand, cmSampleV);
                                        asString = MCom.PrintSlashCommandLine(asString, chatLine);
                                end
                                if (kSample) then
                                        chatLine = string.format(MCOM_CHAT_COM_EXAMPLE_S_S, basecommand, MCOM_CHAT_COM_EXAMPLE_O_K);
                                        asString = MCom.PrintSlashCommandLine(asString, chatLine);
                                end
                                if (koSample) then
                                        chatLine = string.format(MCOM_CHAT_COM_EXAMPLE_S_S, basecommand, MCOM_CHAT_COM_EXAMPLE_O_K_O);
                                        asString = MCom.PrintSlashCommandLine(asString, chatLine);
                                end
                                if (bnSample) then
                                        chatLine = string.format(MCOM_CHAT_COM_EXAMPLE_S_M, basecommand, bnSampleV);
                                        asString = MCom.PrintSlashCommandLine(asString, chatLine);
                                end
                                if (bsSample) then
                                        chatLine = string.format(MCOM_CHAT_COM_EXAMPLE_S_M, basecommand, MCOM_CHAT_COM_EXAMPLE_O_S);
                                        asString = MCom.PrintSlashCommandLine(asString, chatLine);
                                end
                                if (bcSample) then
                                        chatLine = string.format(MCOM_CHAT_COM_EXAMPLE_S_M, basecommand, bcSampleV);
                                        asString = MCom.PrintSlashCommandLine(asString, chatLine);
                                end
                                if (bcmSample) then
                                        chatLine = string.format(MCOM_CHAT_COM_EXAMPLE_S_M, basecommand, bcmSampleV);
                                        asString = MCom.PrintSlashCommandLine(asString, chatLine);
                                end
                                if (bkSample) then
                                        chatLine = string.format(MCOM_CHAT_COM_EXAMPLE_S_M, basecommand, MCOM_CHAT_COM_EXAMPLE_O_K);
                                        asString = MCom.PrintSlashCommandLine(asString, chatLine);
                                end
                                if (bkoSample) then
                                        chatLine = string.format(MCOM_CHAT_COM_EXAMPLE_S_M, basecommand, MCOM_CHAT_COM_EXAMPLE_O_K_O);
                                        asString = MCom.PrintSlashCommandLine(asString, chatLine);
                                end
                        else
                                --If it's not simple we print an example for each type used
                                if (eSample) then
                                        chatLine = string.format(MCOM_CHAT_COM_EXAMPLE_E, basecommand, eSample);
                                        asString = MCom.PrintSlashCommandLine(asString, chatLine);
                                end
                                if (bSample) then
                                        chatLine = string.format(MCOM_CHAT_COM_EXAMPLE_S, basecommand, bSample, MCOM_CHAT_COM_EXAMPLE_O_B);
                                        asString = MCom.PrintSlashCommandLine(asString, chatLine);
                                end
                                if (nSample) then
                                        chatLine = string.format(MCOM_CHAT_COM_EXAMPLE_S, basecommand, nSample, nSampleV);
                                        asString = MCom.PrintSlashCommandLine(asString, chatLine);
                                end
                                if (sSample) then
                                        chatLine = string.format(MCOM_CHAT_COM_EXAMPLE_S, basecommand, sSample, MCOM_CHAT_COM_EXAMPLE_O_S);
                                        asString = MCom.PrintSlashCommandLine(asString, chatLine);
                                end
                                if (cSample) then
                                        chatLine = string.format(MCOM_CHAT_COM_EXAMPLE_S, basecommand, cSample, cSampleV);
                                        asString = MCom.PrintSlashCommandLine(asString, chatLine);
                                end
                                if (cmSample) then
                                        chatLine = string.format(MCOM_CHAT_COM_EXAMPLE_S, basecommand, cmSample, cmSampleV);
                                        asString = MCom.PrintSlashCommandLine(asString, chatLine);
                                end
                                if (kSample) then
                                        chatLine = string.format(MCOM_CHAT_COM_EXAMPLE_S, basecommand, kSample, MCOM_CHAT_COM_EXAMPLE_O_K);
                                        asString = MCom.PrintSlashCommandLine(asString, chatLine);
                                end
                                if (koSample) then
                                        chatLine = string.format(MCOM_CHAT_COM_EXAMPLE_S, basecommand, koSample, MCOM_CHAT_COM_EXAMPLE_O_K_O);
                                        asString = MCom.PrintSlashCommandLine(asString, chatLine);
                                end
                                if (bnSample) then
                                        chatLine = string.format(MCOM_CHAT_COM_EXAMPLE_M, basecommand, bnSample, bnSampleV);
                                        asString = MCom.PrintSlashCommandLine(asString, chatLine);
                                end
                                if (bsSample) then
                                        chatLine = string.format(MCOM_CHAT_COM_EXAMPLE_M, basecommand, bsSample, MCOM_CHAT_COM_EXAMPLE_O_S);
                                        asString = MCom.PrintSlashCommandLine(asString, chatLine);
                                end
                                if (bcSample) then
                                        chatLine = string.format(MCOM_CHAT_COM_EXAMPLE_M, basecommand, bcSample, bcSampleV);
                                        asString = MCom.PrintSlashCommandLine(asString, chatLine);
                                end
                                if (bcmSample) then
                                        chatLine = string.format(MCOM_CHAT_COM_EXAMPLE_M, basecommand, bcmSample, bcmSampleV);
                                        asString = MCom.PrintSlashCommandLine(asString, chatLine);
                                end
                                if (bkSample) then
                                        chatLine = string.format(MCOM_CHAT_COM_EXAMPLE_M, basecommand, bkSample, MCOM_CHAT_COM_EXAMPLE_O_K);
                                        asString = MCom.PrintSlashCommandLine(asString, chatLine);
                                end
                                if (bkoSample) then
                                        chatLine = string.format(MCOM_CHAT_COM_EXAMPLE_M, basecommand, bkoSample, MCOM_CHAT_COM_EXAMPLE_O_K_O);
                                        asString = MCom.PrintSlashCommandLine(asString, chatLine);
                                end
                        end
                end
                --Return the string
                return asString;
        end;
        
        --[[ The Cosmos callback function handler ]]--
        MCom.SetFromUI = function (option, checked, value)
                if (not MCom.UIFuncList) then
                        MCom.UIFuncList = {};
                end
                
                --Get the info for this function
                local funcInfo = MCom.UIFuncList[option];
                if (funcInfo) then
                        local func = funcInfo.func;
                        local funcType = funcInfo.uitype;
                        --Call the appropriate kind of function for this kind of element
                        if (func and funcType) then
                                if (funcType == "CHECKBOX") then
                                        func(checked);
                                elseif (funcType == "SLIDER") then
                                        func(value);
                                elseif (funcType == "BOTH") then
                                        func(checked, value);
                                else
                                        func();
                                end
                        end
                end
        end;
        
        --[[ The Khaos callback function handler ]]--
        MCom.SetFromKUI = function (option, state, keypressed, choices)
                if (not MCom.UIFuncList) then
                        MCom.UIFuncList = {};
                end
                
                --Get the info for this function
                local funcInfo = MCom.UIFuncList[option];
                if (funcInfo) then
                        local func = funcInfo.func;
                        local funcType = funcInfo.uitype;
                        
                        --split into hasbool and not hasbool sections.
                        
                        --Call the appropriate kind of function for this kind of element
                        if (func and funcType) then
                                local checked = nil;
                                if (funcInfo.hasbool) then
                                        checked = 0;
                                        if (state and state.checked) then
                                                checked = 1;
                                        end
                                end
                                
                                local value = nil;
                                local name = nil;
                                --If it's a bool then call it as such
                                if ((funcType == K_TEXT) and funcInfo.hasbool) then
                                        func(checked);
                                else
                                        --Handle the value from the right variable for this type
                                        if (funcType == K_SLIDER) then
                                                value = state.slider;
                                        elseif ( funcType ==  K_EDITBOX ) then
                                                value = state.value;
                                        elseif (funcType == K_PULLDOWN) then
                                                value = state.value;
                                                --If we don't have a table of choices, then just use the values
                                                if ( type(choices) ~= "table" ) then
                                                        --If this can not have multiple choices, then use just the one
                                                        if ( type(value) ~= "table" ) then
                                                                name = value;
                                                        else
                                                                --This is a multi choice selection, so make a list of selected choices
                                                                name = value[1];
                                                                if ( name ~= nil ) then
                                                                        for curVal = 2, table.getn(value) do
                                                                                if ( value[curVal] ~= nil ) then
                                                                                        name = name..", "..value[curVal];
                                                                                end
                                                                        end
                                                                end
                                                        end
                                                else
                                                        --If we have a table of choices, then make a table indexed by value
                                                        local curChoiceDex = {};
                                                        for curChoice in choices do
                                                                curChoiceDex[choices[curChoice]] = curChoice;
                                                        end
                                                        --If this can not have multiple choices, then use just the one
                                                        if ( type(value) ~= "table" ) then
                                                                name = curChoiceDex[value];
                                                        else
                                                                --This is a multi choice selection, so make a list of selected choices
                                                                name = curChoiceDex[value[1]];
                                                                if ( name ~= nil ) then
                                                                        for curVal = 2, table.getn(value) do
                                                                                if ( ( value[curVal] ~= nil ) and ( curChoiceDex[value[curVal]] ~= nil ) ) then
                                                                                        name = name..", "..curChoiceDex[value[curVal]];
                                                                                end
                                                                        end
                                                                end
                                                        end
                                                end
                                        elseif (funcType ==  K_COLORPICKER) then
                                                value = state.color;
                                        end
                                        
                                        --If it's a button, then just call it
                                        if (funcType == K_BUTTON) then
                                                func();
                                        else
                                                --If it has a bool call it with the bool, and the value, otherwise, just the value
                                                if (funcInfo.hasbool) then
                                                        func(checked, value, name);
                                                else
                                                        func(value, name);
                                                end
                                        end
                                end
                        end
                end
        end;

        --------------------------------------------------
        --
        -- Hooked Functions
        --
        --------------------------------------------------
        MCom.ItemTextPrevPage = function ()
                --Switch to the previous page if there is one
                if ( type(MCom.CurText) == "table" ) then
                        local TextFrame = "MComText";
                        if ( not getglobal(TextFrame.."Frame") ) then
                                TextFrame = "ItemText";
                        end
                        if ( MCom.CurTextPage > 1 ) then
                                --Store the current position and range of the scrollbar so we can restore this, the next time the page is visited
                                MCom.CurText.Scroll[MCom.CurTextPage].Value = getglobal(TextFrame.."ScrollFrameScrollBar"):GetValue();
                                MCom.CurText.Scroll[MCom.CurTextPage].Range = getglobal(TextFrame.."ScrollFrame"):GetVerticalScrollRange();
                                --Flip the page
                                MCom.CurTextPage = MCom.CurTextPage - 1;
                                --If a scroll range was recorded for this page, then adjust to those values
                                if (MCom.CurText.Scroll[MCom.CurTextPage].Range) then
                                        getglobal(TextFrame.."ScrollFrameScrollBar"):SetMinMaxValues(0, MCom.CurText.Scroll[MCom.CurTextPage].Range);
                                end
                                --Update the page
                                MCom.UpdateTextPage();
                        end
                else
                        MCom.CurText = nil;
                end
        end;

        MCom.ItemTextNextPage = function ()
                --Switch to the previous page if there is one
                if ( type(MCom.CurText) == "table" ) then
                        local TextFrame = "MComText";
                        if ( not getglobal(TextFrame.."Frame") ) then
                                TextFrame = "ItemText";
                        end
                        if ( MCom.CurTextPage < table.getn(MCom.CurText) ) then
                                --Store the current position and range of the scrollbar so we can restore this, the next time the page is visited
                                MCom.CurText.Scroll[MCom.CurTextPage].Value = getglobal(TextFrame.."ScrollFrameScrollBar"):GetValue();
                                MCom.CurText.Scroll[MCom.CurTextPage].Range = getglobal(TextFrame.."ScrollFrame"):GetVerticalScrollRange();
                                --Flip the page
                                MCom.CurTextPage = MCom.CurTextPage + 1;
                                --If a scroll range was recorded for this page, then adjust to those values
                                if (MCom.CurText.Scroll[MCom.CurTextPage].Range) then
                                        getglobal(TextFrame.."ScrollFrameScrollBar"):SetMinMaxValues(0, MCom.CurText.Scroll[MCom.CurTextPage].Range);
                                end
                                --Update the page
                                MCom.UpdateTextPage();
                        end
                else
                        MCom.CurText = nil;
                end
        end;
        
        --When the item text is closed, let's reset it to normal, and confirm that MCom
        --can now make use of it
        MCom.CloseItemText = function ()
                local TextFrame = "MComText";
                if ( not getglobal(TextFrame.."Frame") ) then
                        TextFrame = "ItemText";
                end
                MCom.CurText = nil;
                MCom.NoTextAvail = nil;
                --Remove the vertex color
                getglobal(TextFrame.."MaterialTopLeft"):SetVertexColor(1,1,1);
                getglobal(TextFrame.."MaterialTopRight"):SetVertexColor(1,1,1);
                getglobal(TextFrame.."MaterialBotLeft"):SetVertexColor(1,1,1);
                getglobal(TextFrame.."MaterialBotRight"):SetVertexColor(1,1,1);
                
                --Resize the text to normal
                if (MCom.PageWidth and MCom.PageScale) then
                        getglobal(TextFrame.."PageText"):SetWidth(MCom.PageWidth);
                        getglobal(TextFrame.."PageText"):SetScale(MCom.PageScale);
                end
        end;

        MCom.ItemTextFrame_OnEvent = function (event)
                --If the game is doing something with the text frame, then clear the MCom text
                --and set the frame as unavailable for MCom to use
                if (    ( event == "ITEM_TEXT_BEGIN" ) or ( event == "ITEM_TEXT_TRANSLATION" ) or
                                        ( event == "ITEM_TEXT_READY" ) ) then
                        local TextFrame = "MComText";
                        if ( not getglobal(TextFrame.."Frame") ) then
                                TextFrame = "ItemText";
                                MCom.CurText = nil;
                                MCom.NoTextAvail = true;
                                --Remove the vertex color
                                getglobal(TextFrame.."MaterialTopLeft"):SetVertexColor(1,1,1);
                                getglobal(TextFrame.."MaterialTopRight"):SetVertexColor(1,1,1);
                                getglobal(TextFrame.."MaterialBotLeft"):SetVertexColor(1,1,1);
                                getglobal(TextFrame.."MaterialBotRight"):SetVertexColor(1,1,1);
                                
                                --Resize the text to normal
                                if (MCom.PageWidth and MCom.PageScale) then
                                        getglobal(TextFrame.."PageText"):SetWidth(MCom.PageWidth);
                                        getglobal(TextFrame.."PageText"):SetScale(MCom.PageScale);
                                end
                        end
                end
        end;
        
        MCom.myAddOnsFrame_OnEvent = function ()
                --If this is variables loaded, then load in the MCom registered addons
                if (event == "VARIABLES_LOADED") then
                        MCom.MyAddOnsLoaded = true;
                        --If this vesion of myAddons supports the registration method, then use it
                        if(myAddOnsFrame_Register) then
                                for curAddon in MCom.MyAddOnsList do
                                        local help = nil;
                                        --If we have a table of help, then get a copy of it, and add the slash command help if available
                                        if ( type(MCom.MyAddOnsList[curAddon].help) == "table" ) then
                                                help = MCom.table.copy(MCom.MyAddOnsList[curAddon].help);
                                                if (MCom.MyAddOnsList[curAddon].supercom) then
                                                        --Add the slash command info on to it
                                                        help[table.getn(help) + 1] = MCom.PrintSlashCommandInfo(MCom.getComID(MCom.MyAddOnsList[curAddon].supercom), true);
                                                end
                                        elseif ( ( MCom.MyAddOnsList[curAddon].help == "boolean" ) and MCom.MyAddOnsList[curAddon].help and MCom.MyAddOnsList[curAddon].supercom ) then
                                                --If help is a boolean and we have slash command info, then generate the help from the slash command info
                                                help = MCom.PrintSlashCommandInfo(MCom.getComID(MCom.MyAddOnsList[curAddon].supercom), true);
                                        end
                                         -- Register the addon in myAddOns
                                        myAddOnsFrame_Register(MCom.MyAddOnsList[curAddon].details, help);
                                end
                        else
                                --Use the old method of adding an addon to the list
                                for curAddon in MCom.MyAddOnsList do
                                        myAddOnsList[curAddon] = MCom.MyAddOnsList[curAddon].details;
                                end
                        end
                end
        end;

        MCom.UIParent_OnEvent = function ()
                if ( event == "VARIABLES_LOADED" ) then
                        if (not MCom.didVarsLoaded) then
                                MCom.didVarsLoaded = true;
                                --If we have anything that needs to be safe loaded, then load it now
                                if ( type(MCom.safeLoads) == "table" ) then
                                        local curConfig;
                                        if ( type(MCom.safeLoads.varsLoaded) == "table" ) then
                                                --Load any safe load that has changed
                                                for curLoad in MCom.safeLoads.varsLoaded do
                                                        --Get the variable for the current safe load
                                                        curConfig = MCom.getStringVar(curLoad);
                                                        --Load the stored data into the empty entries of the current config if the table has been replaced
                                                        if ( ( type(curConfig) == "table" ) and ( curConfig ~= MCom.safeLoads.varsLoaded[curLoad] ) ) then
                                                                MCom.LoadSafeTable( curConfig, MCom.safeLoads.varsLoaded[curLoad] );
                                                        end
                                                end
                                        end

                                        --Deal with any old style entries
                                        for curLoad in MCom.safeLoads do
                                                if ( ( curLoad ~= "addonLoaded" ) and ( curLoad ~= "varsLoaded" ) ) then
                                                        --Get the variable for the current safe load
                                                        curConfig = MCom.getStringVar(curLoad);
                                                        --Load the stored data into the empty entries of the current config
                                                        if ( ( type(curConfig) == "table" ) ) then
                                                                MCom.LoadSafeTable( curConfig, MCom.safeLoads[curLoad] );
                                                        end
                                                end
                                        end
                                end

                                --Clear the safe loads table
                                MCom.safeLoads = nil;

                                --If we are using this as the vars loaded event, then call the vars loaded callbacks
                                if (MCom.UseVarsLoadedEvent) then
                                        MCom.VariablesLoaded();
                                end
                        end
                end

                if ( event == "ADDON_LOADED" ) then
                        --If we have anything that needs to be safe loaded, then load it now
                        if ( type(MCom.safeLoads) == "table" ) then
                                local curConfig;
                                if ( type(MCom.safeLoads.addonLoaded) == "table" ) then
                                        --Load any safe load that has changed
                                        for curLoad in MCom.safeLoads.addonLoaded do
                                                --Get the variable for the current safe load
                                                curConfig = MCom.getStringVar(curLoad);
                                                --Load the stored data into the empty entries of the current config if the table has been replaced
                                                if ( ( type(curConfig) == "table" ) and ( curConfig ~= MCom.safeLoads.addonLoaded[curLoad] ) ) then
                                                        MCom.LoadSafeTable( curConfig, MCom.safeLoads.addonLoaded[curLoad] );
                                                        --Move the entry to the variables loaded table to be checked for loading once more
                                                        MCom.safeLoads.varsLoaded[curLoad] = MCom.safeLoads.addonLoaded[curLoad];
                                                        MCom.safeLoads.addonLoaded[curLoad] = nil;
                                                end
                                        end
                                end
                                
                                --Deal with any old style entries
                                for curLoad in MCom.safeLoads do
                                        if ( ( curLoad ~= "addonLoaded" ) and ( curLoad ~= "varsLoaded" ) ) then
                                                --Get the variable for the current safe load
                                                curConfig = MCom.getStringVar(curLoad);
                                                --Load the stored data into the empty entries of the current config
                                                if ( ( type(curConfig) == "table" ) ) then
                                                        MCom.LoadSafeTable( curConfig, MCom.safeLoads[curLoad] );
                                                end
                                        end
                                end
                        end
                end
        end

        --------------------------------------------------
        --
        -- Sea Wrapper Functions
        --
        --------------------------------------------------
        --Wrappers used to ensure MCom functions without Sea, for those who just
        --absolutely refuse to use Sea
        MCom.math = {};
        MCom.math.round = function (x)
                if (Sea and Sea.math and Sea.math.round) then
                        --Call origional
                        return Sea.math.round(x);
                else
                        --Same as origional
                        if(x - math.floor(x) > 0.5) then
                                x = x + 0.5;
                        end
                        return math.floor(x);
                end
        end;

        MCom.math.hexFromInt = function (intval, minlength)
                if (Sea and Sea.math and Sea.math.hexFromInt) then
                        --Call origional
                        return Sea.math.hexFromInt(intval, minlength);
                else
                        --Same as origional
                        if ( minlength == nil ) then 
                                minlength = "2";
                        end
                        return string.format("%"..minlength.."x", intval );
                end
        end;

        MCom.table = {};
        MCom.table.copy = function ( t, recursionList ) 
                if (Sea and Sea.table and Sea.table.copy) then
                        --Call origional
                        return Sea.table.copy(t, recursionList);
                else
                        --Same as origional
                        if ( not recursionList ) then recursionList = {} end;
                        if ( type(t) ~= "table" ) then 
                                return t;
                        end
        
                        local newTable = {};
                        if ( recursionList[t] ) then
                                return recursionList[t];
                        else
                                recursionList[t] = newTable;
                                for k,v in t do
                                        --If it's a table we want to recurse.  But the second half of this if checks to see if it
                                        --is a reference to a frame, which looks like a table, and does a normal copy in such a
                                        --case
                                        if ( ( type(v) == "table" ) and not ( v[0] and ( type(v[0]) == "userdata" ) ) ) then 
                                                newTable[k] = MCom.table.copy(v, recursionList);
                                        else
                                                newTable[k] = v;
                                        end
                                end
        
                                return newTable;
                        end
                end
        end;

        MCom.table.push = function ( table, val ) 
                if (Sea and Sea.table and Sea.table.copy) then
                        --Call origional
                        return Sea.table.push(table, val);
                else
                        --Same as origional
                        if(not table or not table.n) then
                                return nil;
                        end
                        table.n = table.n+1;
                        table[table.n] = val;
                end
        end;

        MCom.IO = {};
        MCom.IO.printc = function ( color, pString )
                if (Sea and Sea.IO and Sea.IO.printc) then
                        --Call origional
                        Sea.IO.printc(color, pString);
                else
                        --Simple colored print, not as capable as Sea's functions
                        if ( color == nil ) then 
                                color = NORMAL_FONT_COLOR;
                        end
                        ChatFrame1:AddMessage(pString, color.r, color.g, color.b);
                end
        end;
        
        MCom.util = {};
        MCom.util.split = function ( text, separator, oldTable, noPurge )
                if (Sea and Sea.util and Sea.util.split and Sea.version) then
                        --Call origional
                        return Sea.util.split( text, separator, oldTable, noPurge );
                else
                        --Using Legorols version
                        local value;
        local init, mstart, mend = 1;
                        local t, oldn = oldTable, 0;
                        
                        if ( not t ) then
                                t = {};
                        else
                                oldn = table.getn(t);
                                table.setn(t, 0);
                        end
                        
                        -- Using string.find instead of string.gfind to avoid garbage generation                
            repeat
                                mstart, mend, value = string.find(text, "([^"..separator.."]+)", init);
                                if ( value ) then
                                        table.insert(t, value)
                                        init = mend + 1;
                                end
            until not value;
                        
                        if ( not noPurge ) then
                                for i = table.getn(t)+1, oldn do
                                        t[i] = nil;
                                end
                        end
                        
                        return t;
                end
        end;
        
        MCom.util.hook = function (orig, new, hooktype, scriptElementName)
                if (Sea and Sea.util and Sea.util.hook and Sea.version and ( Sea.version >= 1.05 ) ) then
                        Sea.util.hook(orig, new, hooktype, scriptElementName);
                else
                        --Modified hook function from origional, uses Sea's hook list if available
                        if (not MCom.util.Hooks) then
                                MCom.util.Hooks = {};
                        end
                        local hookList = MCom.util.Hooks;

                        --If Sea is around, then use it's list
                        if (Sea and Sea.util and Sea.util.hook) then
                                if(not Sea.util.Hooks) then
                                        Sea.util.Hooks = {};
                                end
                                hookList = Sea.util.Hooks;
                        end

                        local origCopy = orig;
                        if (scriptElementName) then
                                orig = orig.."."..scriptElementName;
                        end

                        if(not hooktype) then
                                hooktype = "before";
                        end
                        if(not hookList[orig]) then
                                hookList[orig] = {};
                                hookList[orig].before = {};
                                hookList[orig].before.n = 0;
                                hookList[orig].after = {};
                                hookList[orig].after.n = 0;
                                hookList[orig].hide = {};
                                hookList[orig].hide.n = 0;
                                hookList[orig].replace = {};
                                hookList[orig].replace.n = 0;
                                hookList[orig].orig = MCom.getStringVar(orig);
                                -- Set up the hook the first time
                                if (scriptElementName) then
                                        hookList[orig].orig = MCom.getStringVar(origCopy):GetScript(scriptElementName);
                                        MCom.getStringVar(origCopy):SetScript(scriptElementName, function(a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17,a18,a19,a20) return MCom.util.hookHandler(orig,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17,a18,a19,a20); end);
                                else
                                        hookList[orig].orig = MCom.getStringVar(orig);
                                        MCom.setStringVar(orig,function(a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17,a18,a19,a20) return MCom.util.hookHandler(orig,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17,a18,a19,a20); end);
                                end
                        else
                                for key,value in hookList[orig][hooktype] do
                                        -- NOTE THIS SHOULD BE VALUE! VALUE! *NOT* KEY!
                                        if(value == MCom.getStringVar(new)) then
                                                return;
                                        end
                                end
                        end
                        -- intentionally will error if bad type is passed
                        MCom.table.push(hookList[orig][hooktype], MCom.getStringVar(new));
                end
        end;

        MCom.util.unhook = function (orig, new, hooktype, scriptElementName)
                if (Sea and Sea.util and Sea.util.unhook and Sea.version and ( Sea.version >= 1.05 ) ) then
                        Sea.util.unhook(orig, new, hooktype, scriptElementName);
                else
                        --Modified unhook function from origional, uses Sea's hook list if available
                        if (not MCom.util.Hooks) then
                                MCom.util.Hooks = {};
                        end             
                        local hookList = MCom.util.Hooks;
                        --If Sea is around, then use it's list
                        if (Sea and Sea.util and Sea.util.hook) then
                                if(not Sea.util.Hooks) then
                                        Sea.util.Hooks = {};
                                end
                                hookList = Sea.util.Hooks;
                        end

                        if(not hooktype) then
                                hooktype = "before";
                        end
                        local l,g;
                        local origCopy = orig;
                        if (scriptElementName) then
                                orig = orig.."."..scriptElementName;
                        end
                        if(not hookList[orig]) then
                                hookList[orig] = {};
                                hookList[orig].before = {};
                                hookList[orig].before.n = 0;
                                hookList[orig].after = {};
                                hookList[orig].after.n = 0;
                                hookList[orig].hide = {};
                                hookList[orig].hide.n = 0;
                                hookList[orig].replace = {};
                                hookList[orig].replace.n = 0;
                                if (scriptElementName) then
                                        hookList[orig].orig = MCom.getStringVar(origCopy):GetScript(scriptElementName);
                                        MCom.getStringVar(origCopy):SetScript(scriptElementName, function(a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17,a18,a19,a20) return MCom.util.hookHandler(orig,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17,a18,a19,a20); end);
                                else
                                        hookList[orig].orig = MCom.getStringVar(orig);
                                        MCom.setStringVar(orig,function(a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17,a18,a19,a20) return MCom.util.hookHandler(orig,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17,a18,a19,a20); end);
                                end
                        end
                        l = hookList[orig][hooktype];
                        g = MCom.getStringVar(new);
                        if ( l ) then 
                                for key,value in l do
                                        if(value == g) then
                                                l[key] = nil;
                                                return;
                                        end
                                end
                        end
                end
        end;

        if (Sea and Sea.util and Sea.util.hookHandler and Sea.version) then
                MCom.util.hookHandler = Sea.util.hookHandler;
        else
                MCom.util.hookHandler = function (name,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17,a18,a19,a20)
                        local called = false;
                        local continue = true;
                        local retval = nil;
                        local ra1,ra2,ra3,ra4,ra5,ra6,ra7,ra8,ra9,ra10,ra11,ra12,ra13,ra14,ra15,ra16,ra17,ra18,ra19,ra20;
                        local hookList = MCom.util.Hooks;

                        --If Sea is around, then use it's list
                        if (Sea and Sea.util and Sea.util.hook) then
                                hookList = Sea.util.Hooks;
                        end

                        if ( not hookList[name] ) then
                                hookList[name] = {};
                                hookList[name].before = {};
                                hookList[name].before.n = 0;
                                hookList[name].after = {};
                                hookList[name].after.n = 0;
                                hookList[name].hide = {};
                                hookList[name].hide.n = 0;
                                hookList[name].replace = {};
                                hookList[name].replace.n = 0;
                        end
                        for key,value in hookList[name].hide do
                                if(type(value) == "function") then
                                        if(not value(a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17,a18,a19,a20)) then
                                                continue = false;
                                        end
                                        called = true;
                                end
                        end
                        if(not continue) then
                                return;
                        end
                        for key,value in hookList[name].before do
                                if(type(value) == "function") then
                                        value(a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17,a18,a19,a20);
                                        called = true;
                                end
                        end
                        continue = false;
                        local replacedFunction = false;
                        for key,value in hookList[name].replace do
                                if(type(value) == "function") then
                                        replacedFunction = true;
                                        local callOrig = false;
                                        callOrig,ra1,ra2,ra3,ra4,ra5,ra6,ra7,ra8,ra9,ra10,ra11,ra12,ra13,ra14,ra15,ra16,ra17,ra18,ra19,ra20 = value(a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17,a18,a19,a20);
                                        if(callOrig) then
                                                continue = true;
                                        else
                                                retval = true;
                                        end
                                        called = true;
                                end
                        end
                        if(continue or (not replacedFunction)) then
                                if (hookList[name].orig) then
                                ra1,ra2,ra3,ra4,ra5,ra6,ra7,ra8,ra9,ra10,ra11,ra12,ra13,ra14,ra15,ra16,ra17,ra18,ra19,ra20 = hookList[name].orig(a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17,a18,a19,a20);
                        end
                        retval = true;
                        end
                        for key,value in hookList[name].after do
                                if(type(value) == "function") then
                                        value(a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17,a18,a19,a20);
                                        called = true;
                                end
                        end
                        if(not called) then
                                --[[ Disabled Complete Unhhoking Sept 17, 2005 - Incompatible with Frame Script Element Hooks - Liable to erase hooks loaded after the first hook.
                                MCom.setStringVar(name,hookList[name].orig);
                                hookList[name] = nil;
                                ]]--
                        end
                        if (retval) then
                                if (type(ra1) == "table") then
                                        return unpack(ra1);
                                else
                                        return ra1,ra2,ra3,ra4,ra5,ra6,ra7,ra8,ra9,ra10,ra11,ra12,ra13,ra14,ra15,ra16,ra17,ra18,ra19,ra20;
                                end
                        end
                end;
        end;

        MCom.wow = { tooltip = {}; };
        MCom.wow.tooltip.get = function ( tooltip, row, value )
                if (Sea and Sea.wow and Sea.wow.tooltip and Sea.wow.tooltip.get) then
                        --Call origional
                        return Sea.wow.tooltip.get( tooltip, row, value );
                else
                        --Default to GameTooltip
                        if (not tooltip) then
                                tooltip = "GameTooltip";
                        end
                        --Default to first row
                        if (not row) then
                                row = 1;
                        end

                        local text, left, right, leftRed, leftGreen, leftBlue, leftAlpha, rightRed, rightGreen, rightBlue, rightAlpha;

                        --Get the left tooltip
                        if ( ( value == nil ) or ( value == "left" ) or ( value == "leftColor" ) ) then
                                text = getglobal(tooltip.."TextLeft"..row);

                                --Get the left tooltip text
                                if ( ( value == nil ) or ( value == "left" ) ) then
                                        if ( text and text:IsVisible() ) then
                                                left = text:GetText();
                                        end
                                        --If this is all they want, then return it now
                                        if ( value == "left" ) then
                                                return left;
                                        end
                                end
                                --Get the left tooltip color
                                if ( ( value == nil ) or ( value == "leftColor" ) ) then
                                        if ( text and text:IsVisible() ) then
                                                leftRed, leftGreen, leftBlue, leftAlpha = text:GetTextColor();
                                        end
                                        --If this is all they want, then return it now
                                        if ( value == "leftColor" ) then
                                                return leftRed, leftGreen, leftBlue, leftAlpha;
                                        end
                                end
                        end
                        
                        --Get the right tooltip
                        if ( ( value == nil ) or ( value == "right" ) or ( value == "rightColor" ) ) then
                                text = getglobal(tooltip.."TextRight"..row);

                                --Get the right tooltip text
                                if ( ( value == nil ) or ( value == "right" ) ) then
                                        if ( text and text:IsVisible() ) then
                                                right = text:GetText();
                                        end
                                        --If this is all they want, then return it now
                                        if ( value == "right" ) then
                                                return right;
                                        end
                                end
                                --Get the right tooltip color
                                if ( ( value == nil ) or ( value == "rightColor" ) ) then

                                        if ( text and text:IsVisible() ) then
                                                rightRed, rightGreen, rightBlue, rightAlpha = text:GetTextColor();
                                        end
                                        --If this is all they want, then return it now
                                        if ( value == "rightColor" ) then
                                                return rightRed, rightGreen, rightBlue, rightAlpha;
                                        end
                                end
                        end

                        --If no individual value was specified, return the entire row
                        return left, right, leftRed, leftGreen, leftBlue, leftAlpha, rightRed, rightGreen, rightBlue, rightAlpha;
                end
        end;

        MCom.string = {};
        MCom.string.colorToString = function ( color )
                if (Sea and Sea.string and Sea.string.colorToString) then
                        --Call origional
                        return Sea.string.colorToString(color);

               else
                        if ( not color ) then 
                                return "FFFFFFFF";
                        end
                        local rString =  MCom.math.hexFromInt(math.floor(255*color.r));
                        local gString =  MCom.math.hexFromInt(math.floor(255*color.g));
                        local bString =  MCom.math.hexFromInt(math.floor(255*color.b));
                        local aString;
                
                        if ( color.a ) then 
                                aString = MCom.math.hexFromInt(math.floor(255*color.a));
                        elseif ( color.opacity ) then 
                                aString = MCom.math.hexFromInt(math.floor(255*color.opacity));
                        end
                
                        if ( aString ) then
                                return aString..rString..gString..bString;
                        else
                                return rString..gString..bString;
        
               end;
                end
        end;
end

Generated by GNU Enscript 1.6.5.90.