--判断是windows还是unix
function isUnix(  )
    return package.config:sub(1,1) == '/'
end

function listFile(path, pattern)
    local dirFile = nil
    local cmd = nil
    if isUnix() then
        cmd = "ls "
    else
        cmd = "dir "
        path = string.gsub(path, "/", "\\")
    end
    cmd = cmd .. path
    dirFile = io.popen(cmd, "r", path)
    local ret = {}
    for line in dirFile:lines() do
        local cap = string.match(line, pattern)
        if cap then
            table.insert(ret, cap)
        end
    end
    return ret
end

--输出table
function printTable(t, isCompress, writer)
    local result = ""
    local function addLine( deep, line )
        if isCompress then
            result = result .. line
        else
            for i=1,deep do
                result = result .. "\t"
            end
            result = result .. line .. "\n"
        end
    end
    local function formatKey( k )
        if type(k) == "number" then
            return string.format("[%d]", k)
        else
            return string.format("%s", tostring(k))
        end
    end
    local function formatValue( v )
        if type(v) == "number" then
            return tostring(v)
        else
            return string.format("\"%s\"", tostring(v))
        end
    end
    if writer == nil then
        writer = print
    end
    local function serial(key, value, deep)
        if deep > 20 then
            addLine(deep,string.format("%s=%s,", formatKey(key), "too fucking deep,maybe has circle")) 
        end
        local typ = type(value);
        if (typ == "table") then
            if key then
                addLine(deep, string.format("%s={", formatKey(key)))
            else
                addLine(deep, "{")
            end
            for i,v in ipairs(value) do
                serial(i, v, deep + 1)
            end
            for k, v in pairs(value) do
                if type(k) == "string" then
                    serial(k, v, deep + 1)
                end
            end
            addLine(deep, "},")
        else
            addLine(deep, string.format("%s=%s,", formatKey(key), formatValue(value)))
        end

    end

    serial(nil, t, 0);
    if string.match(result, ",$") then
        result = string.sub(result, 1, -2)
    elseif string.match(result, ",\n$") then
        result = string.sub(result, 1, -3)
    end
    writer(result)
end

-- 生成[1-n]的随机数
function RandMod(n)
    local mutli = 1
    if n < 1 then
        while true do
            n = n * 10
            mutli = mutli * 10
            if n >= 1 then
                break
            end
        end
    end
    --math.randomseed(tostring(os.time()+GameConfig.GetGobalRamdomIdx()):reverse():sub(1, 6))
    return math.mod(math.random(1,os.time()),n) / mutli
end

--洗牌算法
function knuthShuffle( list )
    if type(list)  ~= "table" then
        return
    end
    for i=1,#list do
        local randNum = math.random(i, len)
        list[i], list[randNum] = list[randNum], list[i]
    end
end

--从M个里取N个,返回index列表
function getNFromM(src, n)
    local ret = {}

    if type(src)  ~= "table" then
        return ret
    end
    local total = #src
    if total == 0 then
        return ret
    end

    local len = math.min(n, total)
    len = math.max(len, 1)
    --蓄水池算法
    for i=1,total do
        if i <= len then
            table.insert(ret, src[i])
        else
            local randNum = math.random(1, i)
            if randNum <= len then
                local swapIndex = math.random(1, len)
                ret[swapIndex] = src[i]
            end
        end
    end
    
    return ret
end

function contain( t, e, comp )
    if not comp then
        comp = function ( a, b )
            return a == b
        end
    end
    for k,v in pairs(t) do
        if comp(v, e) then
            return true
        end
    end
    return false;
end

function filt( t, filter, map )
    if not map then
        map = function ( r, k, v )
            r[k] = v
        end
    end
    local ret = {}
    for k,v in pairs(t) do
        if filter(k,v) then
            map(ret, k, v)
        end
    end
    return ret
end

function grep( file, filter, map )
    if not map then
        map = function ( r, line)
            table.insert(r, line)
        end
    end

    local ret = {}
    for line in file:lines() do
        if filter(line) then
            map(ret, line)
        end
    end

    return ret
end

function split(input, sep)
    if sep == nil then
        sep = "%s"
    end
    local t={} ; i=1
    for str in string.gmatch(input, "([^"..sep.."]+)") do
        t[i] = str
        i = i + 1
    end
    return t
end