Modulo:Sandbox/GiAnMMV/ConvertiNumeri

local unita = {
	[0] = 'zero',
	[1] = 'uno',
	[2] = 'due',
	[3] = 'tre',
	[4] = 'quattro',
	[5] = 'cinque',
	[6] = 'sei',
	[7] = 'sette',
	[8] = 'otto',
	[9] = 'nove',
	[10] = 'dieci',
	[11] = 'undici',
	[12] = 'dodici',
	[13] = 'tredici',
	[14] = 'quattordici',
	[15] = 'quindici',
	[16] = 'sedici',
	[17] = 'diciassette',
	[18] = 'diciotto',
	[19] = 'diciannove'
}

local decine = {
	[2] = 'venti',
	[3] = 'trenta',
	[4] = 'quaranta',
	[5] = 'cinquanta',
	[6] = 'sessanta',
	[7] = 'settanta',
	[8] = 'ottanta',
	[9] = 'novanta'
}

local gruppi = {
  [1] = 'cento',
  [2] = 'mille',
  [3] = 'mila'
}

local ordini = {
  [1] = 'm',
  [2] = 'b',
  [3] = 'tr',
  [4] = 'quadr',
  [5] = 'quint',
  [6] = 'sest',
  [7] = 'sett',
  [8] = 'ott',
  [9] = 'non',
  [10] = 'dec',
  [11] = 'undec',
  [12] = 'duodec',
  [13] = 'tredec',
  [14] = 'quattuordec',
  [15] = 'quindec',
  [16] = 'sedec',
  [17] = 'settendec',
  [18] = 'ottodec',
  [19] = 'novemdec',
  [20] = 'vigint',
  [21] = 'unvigint',
  [22] = 'duovigint',
  [23] = 'trevigint',
  [24] = 'quattuorvigint'
}

suff_sing = {
  [0] = 'ilione ',
  [1] = 'iliardo '
}

suff_plur = {
  [0] = 'ilioni ',
  [1] = 'iliardi '
}

local function duecifre(n)
  if n == 0 then
    return ''
  elseif n < 20 then
    return unita[n]
  elseif n < 100 then
    if (n % 10 == 1) or (n % 10 == 8) then
      return mw.ustring.sub(decine[math.floor(n / 10)], 1, -2) .. unita[n % 10]
    elseif n % 10 == 0 then
      return decine[math.floor(n / 10)]
    else
      return decine[math.floor(n / 10)] .. unita[n % 10]
    end
  end
end

local function centinaia(n)
  if n == 0 then
    return ''
  elseif n == 1 then
    return gruppi[1]
  else
    return unita[n] .. gruppi[1]
  end
end

local function trecifre(n,acc)
  local res = ''
  if math.floor(n % 100 / 10) == 8 then
    res = mw.ustring.sub(centinaia(math.floor(n / 100)), 1, -2) .. duecifre(n % 100)
  else
    res = centinaia(math.floor(n / 100)) .. duecifre(n % 100)
  end
  
  if (n ~= 3) and (mw.ustring.sub(res, -3, -1) == unita[3]) and acc then
    res = mw.ustring.sub(res, 1, -2) .. 'é'
  end
  
  return res
end

local p = {}

function p.converti(frame)
  local res = ''
  local value = frame.args[1]
  value = value:gsub('%.', '')
  value = value:gsub('%s', '')
  local dec = ''
  local potenza = ''
  local segno = ''
  
  if value:sub(1,1) == '-' then
    segno = 'meno '
    value = value:sub(2,-1)
  end
  
  if value:find('e') then
  	potenza = value:sub(value:find('e') + 1, -1)
  	value = value:sub(1, value:find('e') - 1)
  end
  
  if value:find(',') then
  	dec = value:sub(value:find(',') + 1, -1)
  	value = value:sub(1, value:find(',') - 1)
  end
  
  if potenza ~= '' then
    if tonumber(potenza) > 0 then
  	  dec = dec .. string.rep('0', tonumber(potenza) - dec:len())
  	  value = value .. dec:sub(1, tonumber(potenza))
  	  dec = dec:sub(tonumber(potenza) + 1, -1)
    elseif tonumber(potenza) < 0 then
  	  value = string.rep('0', -tonumber(potenza) - value:len()) .. value
  	  dec = value:sub(tonumber(potenza), -1) .. dec
  	  value = value:sub(1, tonumber(potenza) - 1)
    end
  end
  
  if dec ~= '' then
    res = res .. ' virgola'
    for a = 1, dec:len() do
      res = res .. ' ' .. unita[tonumber(dec:sub(a, a))]
    end
  end
  if tonumber(value) ~= 0 then
    value = mw.ustring.rep('0', 3 * math.ceil(value:len() / 3) - value:len()) .. value
    
    res = trecifre(tonumber(value:sub(-3, -1)), true) .. res
    
    if value:len() > 3 then
      local n = tonumber(value:sub(-6, -4))
      if n > 0 then
        if n == 1 then
          res = gruppi[2] .. res
        else
          res = trecifre(n, false) .. gruppi[3] .. res
        end
      end
    end
    
    if value:len() > 6 then
      for o = 3, math.floor(value:len() / 3) do
        local n = tonumber(value:sub(-o*3, -o*3+2))
        if n > 0 then
          if n == 1 then
            res = 'un ' .. ordini[math.floor((o - 1) / 2)] .. suff_sing[(o - 1) % 2] .. res
          else
            res = trecifre(n, true) .. ' ' .. ordini[math.floor((o - 1) / 2)] .. suff_plur[(o - 1) % 2] .. res
          end
        end
      end
    end

    return segno .. res
  else
    return frame.args['zero'] or unita[0]
  end
end

return p