-- 定位： 处理玩家分数排行榜，仅保持玩家分数有序
toplist = {}

toplist.loaded = false
toplist.data = {}

function toplist.init(game)
    toplist.game = game
end

function toplist.loadData()
    local file = io.open(toplist.game .. ".toplist", "r")
    if file == nil then
        return
    end
    local rawdata = file:read("*a")
    toplist.data = toplist.strToTable(rawdata)
    file:close()
    toplist.loaded = true
end

function toplist.saveData()
    local file = io.open(toplist.game .. ".toplist", "w")
    if file == nil then
        return
    end
    file:write(toplist.tableToStr(toplist.data))
    file:flush()
    file:close()
end

function toplist.addScore(p, s, otherInfo)
    if not toplist.loaded then
        toplist.loadData()
    end
    local flag = true
    for i = 1, #toplist.data do
        if toplist.data[i].player == p then
            toplist.data[i].score = s
            toplist.data[i].info = otherInfo
            flag = false
            break
        end
    end
    if flag then
        table.insert(toplist.data, {
            player = p,
            score = s,
            info = otherInfo
        })
    end
    table.sort(toplist.data, function(a, b) return a["score"] > b["score"] end)
    toplist.saveData()
end

function toplist.getTop(start, count)
    if not toplist.loaded then
        toplist.loadData()
    end

    local len = #toplist.data
    if start > len then
        return {}
    end

    if start < 1 then
        start = 1
    end

    if start + count - 1 > len then
        return table.unpack(toplist.data, start, len)
    else
        return table.unpack(toplist.data, start, start + count - 1)
    end
end


function toplist.toStringEx(value)
    if type(value)=='table' then
       return toplist.tableToStr(value)
    elseif type(value)=='string' then
        return "\'"..value.."\'"
    else
       return tostring(value)
    end
end

function toplist.tableToStr(t)
    if t == nil then return "" end
    local retstr= "{"

    local i = 1
    for key,value in pairs(t) do
        local signal = ","
        if i==1 then
          signal = ""
        end

        if key == i then
            retstr = retstr..signal..toplist.toStringEx(value)
        else
            if type(key)=='number' or type(key) == 'string' then
                retstr = retstr..signal..'['..toplist.toStringEx(key).."]="..toplist.toStringEx(value)
            else
                if type(key)=='userdata' then
                    retstr = retstr..signal.."*s"..toplist.tableToStr(getmetatable(key)).."*e".."="..toplist.toStringEx(value)
                else
                    retstr = retstr..signal..key.."="..toplist.toStringEx(value)
                end
            end
        end

        i = i+1
    end

     retstr = retstr.."}"
     return retstr
end

function toplist.strToTable(str)
    if str == nil or type(str) ~= "string" then
        return
    end

    return load("return " .. str)()
end

toplist.init("testgame")
print(table.pack(toplist.getTop(1, 10)))
toplist.addScore("test", 400, {abc = "56"})
print(table.pack(toplist.getTop(1, 10)))
