Module:Ethi-common


local export = {}

local m_str_utils = require("Module:string utilities")

local codepoint = m_str_utils.codepoint
local floor = math.floor
local u = m_str_utils.char

local labiovelars = {"ቈ", "ቘ", "ኈ", "ኰ", "ዀ", "ጐ"}
local palatals_to_base = {
    ["ፘ"] = "ረ",
    ["ፙ"] = "መ",
    ["ፚ"] = "ፈ"
}
local base_to_palatals = {}
for k, v in pairs(palatals_to_base) do
    base_to_palatals[v] = k
end

function export.to_components(char)
    local cp = codepoint(char)
    local base_cp, order = floor(cp / 8) * 8, (cp % 8) + 1
    local base = u(base_cp)
    local labiovelar = false
    local palatalized = false
    local alt = false
    if cp >= 0x1200 and cp <= 0x1357 then
        for _, c in ipairs(labiovelars) do
            local test_cp = codepoint(c)
            if order == 8 and (base_cp + 8) == test_cp then
                order = 4
                labiovelar = true
                alt = true
                break
            elseif base_cp == test_cp then
                base_cp = base_cp - 8
                labiovelar = true
                break
            end
        end
        if order == 8 then
            order = 4
            labiovelar = true
        end
        base = u(base_cp)
    elseif palatals_to_base[char] then
        base = palatals_to_base[char]
        order = 1
        palatalized = true
    else
        error("Only Ethiopic characters from ሀ - ፚ supported")
    end
    return {
        base = base,
        order = order,
        labiovelar = labiovelar,
        palatalized = palatalized,
        alt = alt
    }
end

function export.from_components(components)
    local base_cp = codepoint(components.base)
    local cp = base_cp + (components.order - 1)
    if components.palatalized then
        return base_to_palatals[components.base]
    elseif components.labiovelar then
        if components.alt then
            return u(base_cp + 7)
        else
            for _, c in ipairs(labiovelars) do
                if base_cp + 8 == codepoint(c) then
                    return u(base_cp + 8 + (components.order - 1))
                end
            end
            return u(base_cp + 7)
        end
    end
    return u(cp)
end

return export