-------------------------- LUA UTILS ---------------------------
LuaUtils = {}

function LuaUtils:split(pString, pPattern)
    local Table = {}
    local fpat = "(.-)" .. pPattern
    local last_end = 1
    local s, e, cap = pString:find(fpat, 1)
    
    while s do
        if s ~= 1 or cap ~= "" then
            table.insert(Table, cap)
        end
        last_end = e + 1
        s, e, cap = pString:find(fpat, last_end)
    end
    
    if last_end <= #pString then
        cap = pString:sub(last_end)
        table.insert(Table, cap)
    end
    
    return Table
end

function LuaUtils:separateCamelCase(aString)
    aString = aString:gsub( "(%l)(%u)", "%1 %2" )
    aString = aString:gsub( "(%u)(%u)(%l)", "%1 %2%3" )
    local result = ""
    
    aString:gsub( "%a+", function(item) 
        result = result..item.." "
    end)
    
    return LuaUtils:trim(result)
end

function LuaUtils:trim(text)
    return text:gsub("^%s*(.-)%s*$", "%1")
end

function LuaUtils:IsNilOrEmpty(text)
    return text == nil or self:trim(text) == ""
end

function LuaUtils:matchString(input, pattern)
    local val = input:match(pattern)
    
    if val == nil then
        val = ""
    end
    
    return val
end

function LuaUtils:foreach(items, func)
    local index = 1
    for key, value in pairs (items) do
      func(value, key, index)
      index = index + 1
    end 
end

function LuaUtils:loop(times, func, unpackResults)
    local results = {}
    for i = 1, times do
      results[i] = func(i)
    end 
    if unpackResults ~= true then
        return results
    else
        return unpack(results)
    end
end

function LuaUtils:loopAndUnpack(times, func)
    return self:loop(times, func, true)
end

function LuaUtils:isInTable(item, tbl)
    for key, value in pairs(tbl) do
        if value == item then return key end
    end
    return false
end


function LuaUtils:dumpVar ( t )
    local print_r_cache={}
    local function sub_print_r(t,indent)
        if (print_r_cache[tostring(t)]) then
        print(indent.."*"..tostring(t))
        else
            print_r_cache[tostring(t)]=true
            if (type(t)=="table") then
                for pos,val in pairs(t) do
                    if (type(val)=="table") then
                        print(indent.."["..pos.."] => "..tostring(t).." {")
                        sub_print_r(val,indent..string.rep(" ",string.len(pos)+8))
                        print(indent..string.rep(" ",string.len(pos)+6).."}")
                    else
                        print(indent.."["..pos.."] => "..tostring(val))
                    end
                end
            else
                print(indent..tostring(t))
            end
        end
    end
    sub_print_r(t," ")
end      


function pringlobals()

 for n,v in pairs(_G) do              
 print (n,v);              
 end  

 
 end
 
LuaUtils.Profiler = {}

function LuaUtils.Profiler:A()
    LuaUtils.Profiler.ATime = debugprofilestart()
end

function LuaUtils.Profiler:B(label)
    print(label, ": ", debugprofilestop())
end

function IsFrameVisible(frameName)
    return _G[frameName]~= nil and _G[frameName]:IsVisible()
end

-- threadThrottle (if == 1 then one execution per second)
function LuaUtils:CreateThread(threadName, threadFunction, onEnd, resumeAmountPerFrame, threadThrottle)

    threadName = "thread_"..threadName

	local threadFrame = CreateFrame("Frame")
	local threadCounter = 0
    
    if threadThrottle == nil then
        threadThrottle = 0.01
    end  
    
    if resumeAmountPerFrame == nil then
        resumeAmountPerFrame = 40
    end
    
	threadFrame:SetScript("OnUpdate" , function(self, elapsed)
		threadCounter = threadCounter + elapsed
		if threadCounter >= threadThrottle then
			threadCounter = threadCounter - threadThrottle
            
            if _G[threadName] ~= nil then
                if coroutine.status(_G[threadName]) ~= "dead" then
                    for i=1, resumeAmountPerFrame do
                        coroutine.resume(_G[threadName])
                    end
                else
                    if onEnd then
                        onEnd()
                    end
                    _G[threadName] = nil
                end
            end
		end
	end) 

    _G[threadName] = coroutine.create(threadFunction)
end

