----------------------------------------------------------------------------------
--- Mudlet Debug Tools
----------------------------------------------------------------------------------



--- Function colorizes all matched regex capture groups on the screen.
--- This is very handy if you make complex regex and want to see what really matches in the text.
---
--- @see matches
function showCaptureGroups()
	for k, v in pairs ( matches ) do
		selectCaptureGroup( tonumber(k) )
		setFgColor( math.random(0,255), math.random(0,255), math.random(0,255) )
		setBgColor( math.random(0,255), math.random(0,255), math.random(0,255) )
	end
end



--- Prints the content of the table multimatches[n][m] to the screen. This is meant
--- as a tool to help write multiline trigger scripts. This helps you to easily see
--- what your multiline trigger actually captured in all regex. You can use these values
--- directly in your script by referring to it with multimatches[regex-number][capturegroup].
---
--- @usage Just call this s function from your trigger to show the info.
---   <pre>
---   showMultimatches()
---   </pre>
---
--- @see multimatches
function showMultimatches()
	echo("\n-------------------------------------------------------");
	echo("\nThe table multimatches[n][m] contains:");
	echo("\n-------------------------------------------------------");
	for k,v in ipairs(multimatches) do
		echo("\nregex " .. k .. " captured: (multimatches["..k .."][1-n])");
		for k2,v2 in ipairs(v) do
			echo("\n          key="..k2.." value="..v2);
		end
	end
	echo("\n-------------------------------------------------------\n");
end



--- get the Lua keywords as a set-like table.
-- So <code>res["and"]</code> etc would be <code>true</code>.
-- @return a table
local function get_keywords ()
    if not lua_keyword then
        lua_keyword = {
            ["and"] = true, ["break"] = true,  ["do"] = true,
            ["else"] = true, ["elseif"] = true, ["end"] = true,
            ["false"] = true, ["for"] = true, ["function"] = true,
            ["if"] = true, ["in"] = true,  ["local"] = true, ["nil"] = true,
            ["not"] = true, ["or"] = true, ["repeat"] = true,
            ["return"] = true, ["then"] = true, ["true"] = true,
            ["until"] = true,  ["while"] = true
        }
    end
    return lua_keyword
end

local function quote_if_necessary (v)
    if not v then return ''
    else
        if v:find ' ' then v = '"'..v..'"' end
    end
    return v
end

local keywords

local function is_identifier (s)
    return type(s) == 'string' and s:find('^[%a_][%w_]*$') and not keywords[s]
end

local function quote (s)
    if type(s) == 'table' then
        return prettywrite(s,'')
    else
        return ('%q'):format(tostring(s))
    end
end

local function index (numkey,key)
    if not numkey then key = quote(key) end
    return '['..key..']'
end

--- Create a string representation of a Lua table. (From Steve Donovans Penlight library)
--  This function never fails, but may complain by returning an
--  extra value. Normally puts out one item per line, using
--  the provided indent; set the second parameter to '' if
--  you want output on one line.
--  @param tbl {table} Table to serialize to a string.
--  @param space {string} (optional) The indent to use.
--  Defaults to two spaces; make it the empty string for no indentation
--  @param not_clever {bool} (optional) Use for plain output, e.g {['key']=1}.
--  Defaults to false.
--  @return a string
--  @return a possible error message
local append = table.insert
function prettywrite (tbl,space,not_clever)
    if type(tbl) ~= 'table' then
        if type(tbl) == "string" then
            return string.format("\"%s\"\n", tostring(tbl))
        else
            return string.format("%s\n", tostring(tbl))
        end
    end

    -- return a nice {} instead of {\n} on blanks
    if not next(tbl) then return '{}' end

    if not keywords then
        keywords = get_keywords()
    end
    local set = ' = '
    if space == '' then set = '=' end
    space = space or '  '
    local lines = {}
    local line = ''
    local tables = {}


    local function put(s)
        if #s > 0 then
            line = line..s
        end
    end

    local function putln (s)
        if #line > 0 then
            line = line..s
            append(lines,line)
            line = ''
        else
            append(lines,s)
        end
    end

    local function eat_last_comma ()
        local n,lastch = #lines
        local lastch = lines[n]:sub(-1,-1)
        if lastch == ',' then
            lines[n] = lines[n]:sub(1,-2)
        end
    end


    local writeit
    writeit = function (t,oldindent,indent)
        local tp = type(t)
        if tp ~= 'string' and  tp ~= 'table' then
            putln(quote_if_necessary(tostring(t))..',')
        elseif tp == 'string' then
            if t:find('\n') then
                putln('[[\n'..t..']],')
            else
                putln(quote(t)..',')
            end
        elseif tp == 'table' then
            if tables[t] then
                putln('<cycle>,')
                return
            end
            tables[t] = true
            local newindent = indent..space
            putln('{')
            local used = {}
            if not not_clever then
                for i,val in ipairs(t) do
                    put(indent)
                    writeit(val,indent,newindent)
                    used[i] = true
                end
            end
            for key,val in pairs(t) do
                local numkey = type(key) == 'number'
                if not_clever then
                    key = tostring(key)
                    put(indent..index(numkey,key)..set)
                    writeit(val,indent,newindent)
                else
                    if not numkey or not used[key] then -- non-array indices
                        if numkey or not is_identifier(key) then
                            key = index(numkey,key)
                        end
                        put(indent..key..set)
                        writeit(val,indent,newindent)
                    end
                end
            end
            tables[t] = nil
            eat_last_comma()
            putln(oldindent..'},')
        else
            putln(tostring(t)..',')
        end
    end
    writeit(tbl,'',space)
    eat_last_comma()
    return table.concat(lines,#space > 0 and '\n' or '')
end

function display(what)
    echo((prettywrite(what, '  ') or 'nil')..'\n')
end
