-- This file is part of Quant
--
-- (C) 2015 Scott Yeskie (Sasky)
--
-- This program is free software; you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation; either version 2 of the License, or
-- (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-- GNU General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program.  If not, see <http://www.gnu.org/licenses/>.

--- Used to extract set data into JSON format
--- Required: /quant itr-all-skills or /quant itr-class-skills and /quant skill-full in-game
--- Required: Rserve must be ruu.nning for this script

print("Loading libraries")
local cfg = cfg or assert(loadfile("cfg.lua"))()
local u = inc("util")
local sv = inc("loadfile")
local JSON = inc("JSON")
local r = inc("extract")

print("Account: " .. cfg.account)
print("Server: " .. cfg.server)

print("Loading saved variables")
sv:loadSavedVariables(cfg.account, cfg.server)

local skilldata = sv:getSVEntry("SkillsCurve")
local skillfull = sv:getSVEntry("SkillsFullInfo")
local skillref = r:initSkillData(sv)

print("Processing raw data into fit info")

local outfile = {
    skills = {},
    lines = {},
}

for skill_lvl,numbers in pairs(skilldata) do
    local skill = skill_lvl:gsub("..$","")
    local ref = skillref[skill]
    if ref then
        local data = skillfull[ref.type][ref.line][skill]

        local skillInfo = {
            name=skill,
            type=ref.type,
            line=ref.line,
            rank=data.rank or 4, --Hardcoding rank 4, though possible want different ranks later
            description=data.description,
            descriptionHeader=data.descriptionHeader,
            mechanic=u.getMechanicName(data.mechanic),
            cost=data.cost,
            target=data.targetDescription,
            minRange=data.minRangeCM,
            maxRange=data.maxRangeCM,
            radius=data.radiusCM,
            distance=data.distanceCM,
            channeled=data.channeled,
            castTime=data.castTime,
            channelTime=data.channelTime,
            durationMS=data.durationMS,
        }

        local lastFindPos = 1
        local formulaNum = 1
        local formulae = {}
        skillInfo.fit = {}
        for _,rawnumbers in ipairs(numbers) do
            local fit = r:getFitData(rawnumbers)
            local delta = 1E-5
            if fit.main < delta then fit.main = 0 end
            if fit.power < delta then fit.power = 0 end
            if (fit.health or 0) < delta then fit.health = 0 end
            if fit.int < delta then fit.int = 0 end

            local desc = skillInfo.description
            local start = desc:find("|c")
            local _,fin = desc:find("|r")
            local toReplace = desc:sub(start,fin)

            local formulasig = u.makeKey(fit.main, fit.power, fit.health, fit.int, fit.rsq)
            if fit.const then
                skillInfo.description = r:replaceNumberInDescription(desc, toReplace, fit.int)
            else
                if not formulae[formulasig] then
                    formulae[formulasig] = "##f" .. formulaNum .. "##"
                    skillInfo.fit[formulae[formulasig]] = {
                        mainCoef=fit.main,
                        powerCoef=fit.power,
                        healthCoef=fit.health,
                        intercept=fit.int,
                        rsq=fit.rsq,
                    }
                    formulaNum = formulaNum + 1
                end

                skillInfo.description = r:replaceNumberInDescription(desc, toReplace, formulae[formulasig])
            end
        end

        outfile.skills[skill] = skillInfo
        u.makeDepth(outfile.lines, { ref.type, ref.line });
        table.insert(outfile.lines[ref.type][ref.line], skill)
    else
        print("No lookup found for: " .. skill)
    end
end

print("Writing results to: skilldata.json")
local f = assert(io.open("skilldata.json", "w"))
f:write(JSON:encode_pretty(outfile))
f:close()