--[[
Lua-Curl script for Visionaire
(c) 13/6/2015
]]
curl_multi = curl.new_multi()
curls = {}
handles_count = 1
loadcount = 0
max_loadcount = 10
loadlist = {}
function GET(url, func,param, buf, startoffset, endoffset)
 if buf~=nil then
  table.insert(curls,{curl.new(),buf, func,param})
 else
  table.insert(curls,{curl.new(),{}, func,param})
 end
    c = curls[#curls][1]
    c:setopt(curl.OPT_URL, url)
 if startoffset ~= nil then
  c:setopt(curl.OPT_RANGE, startoffset.."-"..endoffset)
 end
    c:setopt(curl.OPT_FOLLOWLOCATION, true)
    c:setopt(curl.OPT_TIMEOUT, 300)
    c:setopt(curl.OPT_IOCTLFUNCTION, function (param, buf) return #buf end)
    c:setopt(curl.OPT_HEADERFUNCTION, function (param, buf) return #buf end)
    c:setopt(curl.OPT_WRITEDATA, {curls[#curls]})
    c:setopt(curl.OPT_WRITEFUNCTION, function (param, buf)
        table.insert(param[1][2], buf) -- store a chunk of data received
        return #buf
    end)
    c:setopt(curl.OPT_PROGRESSDATA, {curls[#curls]})
    c:setopt(curl.OPT_PROGRESSFUNCTION, function(param, dltotal, dlnow)
        if param[1][4][2]~=nil then
            param[1][4][2](dtotal, dnow)
        end
    end)
    c:setopt(curl.OPT_NOPROGRESS, false) -- use this to activate progress
    curl_multi:add(c)
    curl_multi:perform()
end
function POST(url,data,func,param, buf, startoffset, endoffset, userPassword)
    if buf~=nil then
        table.insert(curls,{curl.new(),buf, func,param})
    else
        table.insert(curls,{curl.new(),{}, func,param})
    end
    c = curls[#curls][1]
    c:setopt(curl.OPT_URL, url)
    if startoffset ~= nil then
        c:setopt(curl.OPT_RANGE, startoffset.."-"..endoffset)
    end
    c:setopt(curl.OPT_FOLLOWLOCATION, true)
    c:setopt(curl.OPT_TIMEOUT, 300)
    c:setopt(curl.OPT_WRITEDATA, {curls[#curls]})
    c:setopt(curl.OPT_WRITEFUNCTION, function (param, buf)
        table.insert(param[1][2], buf) -- store a chunk of data received
        return #buf
    end)
 c:setopt(curl.OPT_POST, true)
    c:setopt(curl.OPT_POSTFIELDS, data)
    c:setopt(curl.OPT_NOPROGRESS, false) -- use this to activate progress
 c:setopt(curl.OPT_HTTPHEADER, "Content-Type: application/json")
 if userPassword ~= nil then
  c:setopt(curl.OPT_USERPWD, userPassword)
 end
    curl_multi:add(c)
    curl_multi:perform()
end
function postRequest(httpurl, data, onFinish, onProgress, userPassword)
    POST(httpurl, data, onFinish, {nil, onProgress}, nil, nil, nil, userPassword)
end
function downloadFile(httpurl, file, onFinish, onProgress)
    GET(httpurl, function(s, param) 
        local file = io.open(param[1], "wb");file:write(s);file:close() 
        onFinish() 
    end, {file, onProgress})
end
function downloadMemory(httpurl, onFinish, onProgress)
    GET(httpurl, onFinish, {nil, onProgress})
end
function update_curl()
    while loadcount < max_loadcount and #loadlist > 0 do
        loadcount = loadcount + 1 
        GET(loadlist[1][1], function(s,param) loadcount = loadcount - 1; param[2](s,param[3]) end, loadlist[1])
        table.remove(loadlist, 1)
    end
    local handles = curl_multi:perform()
    local result = curl_multi:info()
    if result ~= -1 then
        for k,v in pairs(curls) do
            if tostring(v[1]) == tostring(result) then
                local size = v[1]:getinfo(curl.INFO_CONTENT_LENGTH_DOWNLOAD)
                local downsize = v[1]:getinfo(curl.INFO_SIZE_DOWNLOAD)
                if(size~=-1 and size~=downsize)then
                    print("not complete")
                    local element = table.remove(curls, k)
                else
                    v[3](table.concat(v[2]),v[4])
                    table.remove(curls, k)
                end
                break
            end
        end
    end
end
registerEventHandler("mainLoop", "update_curl")