
-- Helper functions ------------------------------------------------------------
-- Used to complete fields:
-- If field contains a number value or a single value in a table,
-- then the value is repeated n times, othewise, it does nothing
local function fill_values(field, size)
    if type(field) == 'number' then
        return rep(field, size)
    elseif type(field) == 'table' and #field == 1 then
        return rep(field[1], size)
    else return field end
end

--------------------------------------------------------------------------------
--------------------------- Fields Checking functions --------------------------
-- id --------------------------------------------------------------------------
local function id_check(id)
    assert_type(id, 'string', "Species id: Wrong type")
    return id
end

-- occurence probability ----------------------------------------------------------------------
local function probability_check(nLocus)
    assert_type(nLocus, 'number', "Event probability: Wrong type")
    assert(nLocus <= 1, "Event probability: Minimum value is 1")
    assert(nLocus >= 0, "Event probability: Maximum value is 0")
    return nLocus
end

-- isGlobal ----------------------------------------------------------------------
local function isGlobal_check(isGlobal)
    assert_type(isGlobal, 'boolean', "Event isGlobal: Wrong type")
    return isGlobal
end


-- trait ----------------------------------------------------------------------
local function trait_check(trait, traits)
    assert_type(trait, 'string', "Event trait: Wrong type")
    --TODO: assert if trait exists
    return trait
end

-- lethality ----------------------------------------------------------------------
local function lethality_check(lethality)
    assert_type(lethality, 'number', "Event probability: Wrong type")
    assert(lethality <= 1, "Event lethality: Minimum value is 1")
    assert(lethality >= 0, "Event lethality: Maximum value is 0")
    return lethality
end

local function handicap_check(handicap)
    assert_type(handicap, 'number', "Event probability: Wrong type")
    assert(handicap <= 1, "Event lethality: Minimum value is 1")
    assert(handicap >= 0, "Event lethality: Maximum value is 0")
    return handicap
end


local function law_check(law)
    assert_type(law, 'string', "Event: wrong type for law")
    return law
end

local function source_check(source)
    assert_type(source, 'string', "Event: wrong type for source")
    return source
end

local function param_check(p)
    assert_type(p, 'number', "Event: wrong type for param")
    return p
end

--------------------------------------------------------------------------------
-------------------------------  Main functions --------------------------------
--------------------------------------------------------------------------------
-- This Function checks  the basic validity of an event
local function check(event)
    print("Checking Event: "..event.id)
    --New specie object (empty table)
    local newEvent = {}

    ---- Simple checks ---------------------------------------------------------
    -- Some optional fields are only checked on use (mp, ms, ...)
    -- id
    newEvent.id = id_check(event.id)
    newEvent.isGlobal = isGlobal_check(event.isGlobal)
    newEvent.trait = trait_check(event.trait)
    newEvent.lethality = lethality_check(event.lethality)
    newEvent.handicap = handicap_check(event.handicap)
    --newEvent.probability = probability_check(event.probability)
    newEvent.law = law_check(event.law)
    assert_type(event.source, 'string', "Event: wrong type for source")
    if event.source == "userdata" then
        --zopt_check(zopt, mapLength, mapWidth, mapLength, mapWidth)
        print("NEED IMPLEM") --TODO
    elseif event.source == "value" then
        newEvent.offset = 0
        if newEvent.law == "normal" then
            newEvent.meanValue = param_check(event.meanValue)
            newEvent.varValue = param_check(event.varValue)
        elseif newEvent.law == "power" then
            newEvent.power_alpha = param_check(event.power_alpha)
            newEvent.power_xmin = param_check(event.power_xmin)
            if event.power_offset ~= nil then
                newEvent.offset = param_check(event.power_offset)
            end
        end
    else
        print("Event: source: Not a valid source ("..event.source..")")
        os.exit()
    end
    if event.vmax == nil then
        print("No vmax for event "..newEvent.id)
        newEvent.vmax = 10^5
    else
        newEvent.vmax = param_check(event.vmax)
    end
    return newEvent
end


-- Check a list of species
local function check_all(events)-- end, config)
    assert_type(events, 'table', "events: wrong type")
    newEvents = {}
    for _, evt in pairs(events) do
        for kse,subEvent in pairs(evt) do
            for key,value in pairs(subEvent) do
                print(key,value)
            end
            assert(newEvents[subEvent.id] == nil, "Same evt id used twice")
            newEvents[#newEvents + 1] = check(subEvent)
        end
    end

    return newEvents
end


--------------------------------------------------------------------------------
-------------------------------  Module interface ------------------------------
--------------------------------------------------------------------------------
local module = {}
module.check = check
module.check_all = check_all
return module
