-- de Wikidata:Module:Linguistic
-- some simple internationalization that can be called by other modules
local p = {}
local lang = 'pt'
local langobj = mw.language.new(lang)

local vowels = 'aeiouyąăẵằẳặȃắâẫấầẩậãäǟāáàȁǎảẚåǻḁạǡæǣǽĕȇêễếềểệḙẽḛëēḕéḗèȅěẻẹęȩḝǝĭȋîĩḭïḯīíìȉǐỉịįıŏȏôỗốồổộõṏṍöōṑóṓòȍǒỏọǫǭơỡớờởợøǿŭȗûṷũṻṹṵüǖǘǜǚṳūúùȕǔủůụųưữứừửựŷỹÿȳýỳỷẙỵ'

-- i18n
local wordor = ' ou '
local wordand = ' e '
local comma = ', '
local fullstop = '. '
local wordsep = ' '

local function isin(str, pattern)
    if str and pattern and mw.ustring.find(str, pattern, 1, true ) then
        return true
    end
end


local function processgender(str)
    if (str == 'f') or (str == 'fem') or (str == 'feminino') then
        return 'feminino'
    elseif (str == 'n') or (str == 'neutro') then
        return 'neutro'
    else
        return 'masculino'
    end
end

local function processnumber(str)
    if (str == 'p') or (str == 'plural') then
        return 'plural'
    else
        return 'singular'
    end
end

function p.vowelfirst (str)
    if str and #str > 0 then return isin(vowels, mw.ustring.lower(mw.ustring.sub(str, 1, 1))) end
end

function p.inparentheses(str, lang, space)
    if (not str) or str == '' then
        return str
    end
    str = '(' .. str .. ')'
    if not space then
        space = ' '
    end
    return space .. str
end

function p.of(word, gender, number, determiner, raw)
    if not word then
        word = ''
    end
    word = mw.text.trim( word )
    if not raw then  --texte non mis en forme pour gérer les élisions
        raw = p.texteLien(word) or word
    end
    gender = processgender(gender)
    number = processnumber(number)
    local vowel = p.vowelfirst(raw)
    local feminine = (gender== 'feminino')
    -- raw is the string without the Wikiformatting so that it correctly analyses the string that is [[:fr:Italie|Italie]] -> 'italie'
    -- any way to automate this ?

  
    if number == 'plural' then
        return 'dos ' .. word
    elseif determiner and (determiner ~= '-') then-- de la, du // determiner ~= '-' veut dire renseigné comme vide
        if vowel then
            return 'da ' .. word
        elseif feminine then
            return 'de ' .. word
        else
            return 'do ' .. word
        end
    else
        if vowel then
            return 'de ' .. word
        else
            return 'de ' .. word
        end
    end
end

function p.noungroup(noun, adj)
    if not noun or noun == '' then
        return nil -- not '' so that it is not counted as a string by mw.listToText
    end
    return noun .. wordsep(lang) .. adj -- lorsque c'est en français
end

function p.quickconj(args, conjtype)
    local separator, conjunction
  
    -- cas où separator ~= conj
    if type(conjtype) == 'function' then
        conjtype = conjtype()  
    end
    if (not conjtype) or conjtype == 'and' then
        separator, conjunction = comma, wordand
    elseif conjtype == 'or' then
        separator, conjunction = comma, wordor
    end
    if (separator and conjunction) then
        return  mw.text.listToText(args, separator, conjunction)
    end
    -- autres cas
    if conjtype == 'comma' then
        separator = comma
    elseif conjtype == 'new line' then
        separator = '<br />'
        --for i, j in pairs(args) do -- ajoute une majuscule
        --    args[i] = p.lcfirst(j)
        --end
    else
        separator = conjtype
    end
    return table.concat(args, separator)
end

function p.conj(args, conjtype)
    if (not args) then
        return nil
    end
    local newargs = {}
    for i, j in pairs(args) do
        if type(j) ~= 'nil' then
            table.insert(newargs, j)
        end
    end
    if #newargs == 0 then
        return nil
    end
    return p.quickconj(newargs, conjtype, lang)
end
 
function p.conjfromWiki(frame)
    args = frame.args
    if not args or not args[1] then
        args = mw.getCurrentFrame():getParent().args
    end
    local conjtype = args.type
    newargs = {}  -- transform args metatable into a table so it can be concetenated
    for i, j in pairs(args) do
            if type(i) == 'number' then
                j = mw.text.trim(j)
                if j ~= '' then
                    table.insert(newargs, j)
                end
            else
                if i ~= 'type' and i ~= 'lang' then
                    return error('bad parameter in template:Conj:' .. i), '[[Categoria:!Páginas com uso incorrecto da predefinição/Conj|A]]'
                end
            end
    end
    return p.conj(newargs, conjtype)
end

local function findcomplement(str, beginswith) -- retourne le nom principal et le complément du nom ou nil et nil si échec
    local particles = {" da ", " de ", " das ", " do ", " dos "}
    if beginswith and (not mw.ustring.find(str, "^" .. beginswith)) then
        return nil
    end
    for i, pattern in pairs(particles) do
        local pos = mw.ustring.find(str, pattern)
        if pos then
            local main = mw.ustring.sub(str, 1, pos -1)
            local comp = mw.ustring.sub(str, pos + string.len(pattern))
            return main, comp
        end
    end
    return nil
end


function p.keepcomplement(str, beginswith) -- par exemple "gare de Lyon" -> "Lyon"
    local main, compl = findcomplement(str, beginswith)
    if compl then
        return compl
    end
    return str
end

function p.removecomplement(str, beginswith) -- par exemple "gare de Lyon" -> "gare"
    local main, compl = findcomplement(str, beginswith)
    if main then
        return main
    end
    return str
end

--[=[
    texteLien le lien intere initial '^[[lien|texte]]' de str et retourne : texte, lien
    Si le lien est '[[texte]]', retourne : texte, texte.
    Si str ne commence pas par un lien interwiki, retourne : nil
]=]
function p.texteLien( str )
    if type( str ) == 'string' then
        local lien, texte = str:match( '^%[%[ *([^%[%]|]*)|? *([^%[%]]*)%]%]' )
        if not lien then
            lien, texte = str:match( '^%b<>%[%[ *([^%[%]|]*)|? *([^%[%]]*)%]%]' )
        end
        if lien then
            local testlien = string.lower( lien )
            local fichier = string.match( testlien, '^ficheiro:' )
                or  string.match( testlien, '^imagem:' )
                or  string.match( testlien, '^file:' )
                or  string.match( testlien, '^image:' )
            if not fichier then
                texte = ( texte ~= '' and texte ) or lien
                return texte, lien
            end
        end
    end
    return nil
end

function p.ucfirst(str)
    if (type (str ) ~= 'string') or (string == "") then
        return str
    end
    local strTemp, tag, tagTemp = str, ''
        -- sépare les balises html initiales (span ou autres)
    while strTemp:match( '^%b<>' ) do
        tagTemp, strTemp = strTemp:match( '^(%b<>)(.*)$' )
        tag = tag .. tagTemp
    end
    local texte = p.texteLien( strTemp )
    if texte then
        -- ajoute les crochets de fin de lien pour être sur de ne remplacer que le texte du lien
        texte = texte .. ']]'
        -- échappe les caractère magique
        local pattern = texte:gsub( '([$%%()*+%-.?()^])', '%%%1' )
        -- ajoute la majuscule au texte du lien
        str = str:gsub( pattern, p.ucfirst( texte ), 1 )
    else
        str = tag .. langobj:ucfirst( strTemp )
    end
    return str
end

function p.lcfirst(str)
    if (type (str ) ~= 'string') or (string == "") then
        return str
    end
    local strTemp, tag, tagTemp = str, ''
        -- sépare les balises html initiales (span ou autres)
    while strTemp:match( '^%b<>' ) do
        tagTemp, strTemp = strTemp:match( '^(%b<>)(.*)$' )
        tag = tag .. tagTemp
    end
    local texte = p.texteLien( strTemp )
    if texte then
        -- ajoute les crochets de fin de lien pour être sur de ne remplacer que le texte du lien
        texte = texte .. ']]'
        -- échappe les caractère magique
        local pattern = texte:gsub( '([$%%()*+%-.?()^])', '%%%1' )
        -- ajuste a minuscula no texto do link
        str = str:gsub( pattern, p.lcfirst( texte ), 1 )
    else
        str = tag .. langobj:lcfirst( strTemp )
    end
    return str
end

function p.ucfirstE(frame)
    return p.ucfirst(frame.args[1])
end

function p.lcfirstE(frame)
    return p.lcfirst(frame.args[1])
end

--[[
function p.toascii(str)
    local convtable = mw.loadData("Módulo:Linguística/ASCII")
    for i, j in pairs(convtable) do -- manquent les majuscules
        str = mw.ustring.gsub(str, '[' .. i .. ']', j)
    end
    return str
end
]]--
return p