util.conversion = {}

util.conversion.DISTANCE = {
    m_km    = 1e3,
    m_m     = 1e0,
    m_dm    = 1e-1,
    m_cm    = 1e-2,
    m_mm    = 1e-3,
    m_mum   = 1e-6,

    i_nm    = 1852,
    i_m     = 1609.34,
    i_yd    = 0.9144,
    i_ft    = 0.3048,
    i_in    = 0.0254,
}

--- attempts to covert from supplied standard to meters
---
--- INFO: if no standard is supplied this function will assume the input as meter
--- @param d number distance you want to converts
--- @param standard string standard convert to. You may append "m_" (metric) or i_" (imperial) as a prefix for ambiguous units
--- @return number
function util.conversion.toM(d, standard)
    -- checking function arguments
    if not tonumber(d) then error(util.error.argErr(d, "number", 1)) end
    standard = type(standard) == "string" and standard or "m_m"

    -- local pointer to table (just to make it look a bit cleaner xd)
    local tbl = util.conversion.DISTANCE
    local factor = tbl[standard] or tbl["m_" .. standard] or tbl["i_" .. standard]

    if type(factor) ~= "number" then error(util.error.lookupErr(standard, tbl, factor, "number")) end
    return (d * factor)
 end

--- attempts to covert from metrs to supplied standard
---
--- INFO: if no standard is supplied this function will assume the input as meter
--- @param d number distance you want to converts
--- @param standard string standard convert to. You may append "m_" (metric) or i_" (imperial) as a prefix for ambiguous units
--- @return number
function util.conversion.fromM(d, standard)
    -- checking function arguments
    if not tonumber(d) then error(util.error.argErr(d, "number", 1)) end
    standard = type(standard) == "string" and standard or "m_m"

    -- local pointer to table (just to make it look a bit cleaner xd)
    local tbl = util.conversion.DISTANCE
    local factor = tbl[standard] or tbl["m_" .. standard] or tbl["i_" .. standard]

    if type(factor) ~= "number" then error(util.error.lookupErr(standard, tbl, factor, "number")) end
    return factor and (d / factor) or nil
end

--- attempts to convert a 3 dimensional vector (using DCD x,y,z format) into a vec2
---
--- INFO: correctly handles accidetal input of vec2 into function. All values default to 0
--- @param vec3 table input vector (DCS vec3 format)
--- @return table vec2
function util.conversion.vec3toVec2(vec3)
    if type(vec3) ~= "table" then error(util.error.argErr(vec3, "table", 1)) end

    return { x = vec3.x or 0, y = vec3.z or vec3.y or 0 }
end

--- attempts to convert a 2 dimensional vector (using DCD x,y format) into a vec3
---
--- INFO: correctly handles accidetal input of vec2 into function. All values default to 0
--- @param vec2 table input vector (DCS vec3 format)
--- @param alt? number altitude. Defaults to 0
--- @return table vec2
function util.conversion.vec2toVec3(vec2, alt)
    if type(vec2) ~= "table" then error(util.error.argErr(vec2, "table", 1)) end

    return { x = vec2.x or 0, y = alt or 0, z = vec2.y or 0}
end