Documentation for this module may be created at Module:Damage/doc

require('Module:CommonFunctions')
local getArgs = require('Module:Arguments').getArgs
local p = {}
function string.starts(String,Start)
    return string.sub(String,1,string.len(Start))==Start
end

-- Function wrapper for vardefine syntax in MW.
function var(name, dmg)
    return '{{#vardefine:{{formatnum:'..name..'|'..round(dmg)..'}}%}}'
end

-- Main process
function p.main(frame)
    local args = getArgs(frame)
    return p._main(args)
end

function p._main(args)
    function inArgs(key)
        if args[key] ~= nil then
            return true
        end
    end

    function inArgsStarts(key)
        for k,v in spairs(args) do
            if string.starts(k, key) then
                return true
            end
        end
    end

    -- Define tables that hold the subsequent damage values.
    -- I know this isn't the best, but I don't want to work with nested tables in this language.
    local fvals = {}
    local tvals = {}
    local pvals1 = {}
    local pvals2 = {}
    local pvals12 = {}
    local vars = {}
    
    -- Handle trait table
    local traits = {}

    if (inArgs('heavy')) then
        traits.heavy = 1.44
    end

    if (inArgs('enhanced')) then
        traits.enhanced = 0.8
    end

    -- Customizable for empowered, it had to be special lol.
    if (inArgs('empowered')) then
        if (args.empowered == 'true') then
            traits.empowered = 1.2
        else
            traits.empowered = args.empowered
        end
    end

    -- Define total/average damage calculation based on damage per hit and hit amount.
    function getTotal(dmg, hits, fval)
        local i = 1
        fvals[fval] = 0
        for k,v in spairs(args) do
            if string.starts(k, 'dmg') then
                -- Proceed to combine
                fvals[fval] = fvals[fval] + args[dmg .. i] * args[hits .. i]
                i = i + 1
            end
        end
        -- Apply Useful modifier.
        if string.find(fval, 'useful') then
             fvals[fval] = fvals[fval] * args.useful_penalty
        end
    end

    -- Actually generate the values depending on arguments provided.
    getTotal('dmg', 'hits', 'total_damage')

    if inArgsStarts('avg_hits') then
        getTotal('dmg', 'avg_hits', 'average_damage')
    end

    if inArgsStarts('awk_dmg') then
        getTotal('awk_dmg', 'awk_hits', 'total_damage_awk')
    end

    if inArgsStarts('avg_awk_hits') then
        getTotal('awk_dmg', 'avg_awk_hits', 'average_damage_awk')
    end

    -- Handling traits
    -- Useful handled separately
    if inArgs('useful_penalty') then
        getTotal('dmg', 'hits_useful', 'total_damage_useful')

        if (inArgsStarts('avg_hits_useful')) then
            getTotal('dmg', 'avg_hits_useful', 'average_damage_useful')
        end
    end

    -- Multiply all values with traits and store them in another table.
    for k,v in spairs(fvals) do
        if not string.find(k, 'useful') then
            for kt,vt in spairs(traits) do
                if inArgs(kt) then
                    local dmg_name = k..'_'..kt
                    local dmg_formula = v * vt
                    tvals[dmg_name] = dmg_formula
                end
            end
        end
    end

    -- Define passives and fill the respective tables.
    local passive2 = 0
    if inArgs('passive2') then
        passive2 = split(args.passive2)

        for k,v in spairs(tvals) do
            local dmg_name = k..'_passive2'
            local dmg_formula = v * passive2[1]
            pvals2[dmg_name] = dmg_formula
        end

        -- Useful separately.
        for k,v in spairs(fvals) do
            if (string.find(k, 'useful')) then
                pvals2[k..'_passive2'] = v * passive2[1]
            end
        end
    end

    local passive1 = 0
    if inArgs('passive1') then
        passive1 = split(args.passive1)

        for k,v in spairs(tvals) do
            local dmg_name = k..'_passive1'
            local dmg_formula = v * passive1[1]
            pvals1[dmg_name] = dmg_formula
        end

        -- Useful separately
        for k,v in spairs(fvals) do
            if (string.find(k, 'useful')) then
                pvals1[k..'_passive1'] = v * passive1[1]
            end
        end

        -- Combine both passives.
        if inArgs('passive2') then
            for k,v in spairs(pvals1) do
                pvals12[k..'_passive2'] = v * passive2[1]
            end
        end

    end

    -- Merge all tables into one.
    tableMerge(fvals, tvals)
    tableMerge(fvals, pvals1)
    tableMerge(fvals, pvals2)
    tableMerge(fvals, pvals12)

    -- Get the actual variables with MW syntax.
    for k,v in spairs(fvals) do
        table.insert(vars, var(k, v))
    end

    -- Dump all values.
    local ret = {}
    for k,v in spairs(fvals) do
        table.insert(ret, k..': '..v)
    end

    return frame:preprocess(table.concat(ret, "<br/>"))

    -- Dump all variables
    -- return table.concat(vars)

    -- Parse all variables
    -- return frame:preprocess(table.concat(vars))
    
end

return p