-- lx-bundle:true

-- This file is part of Lx, created by Liqube <www.liqube.com>
-- Copyright Liqube Audio. All rights reserved.
-- Lx Interim License. See LICENSE for details.

--- Conventional Roman numeral formatting
-- @module core.lib.roman

local roman = {}

local values = {
	{ 1000, "M" },
	{ 900, "CM" },
	{ 500, "D" },
	{ 400, "CD" },
	{ 100, "C" },
	{ 90, "XC" },
	{ 50, "L" },
	{ 40, "XL" },
	{ 10, "X" },
	{ 9, "IX" },
	{ 5, "V" },
	{ 4, "IV" },
	{ 1, "I" },
}

--- Format one positive integer as an uppercase Roman numeral
-- @param value number integer from 1 through 3999
-- @return string|nil numeral conventional Roman numeral
function roman.upper(value)
	if type(value) ~= "number" or value % 1 ~= 0 or value < 1 or value > 3999 then
		return nil
	end

	local out = {}

	for _, pair in ipairs(values) do
		local count = value // pair[1]
		if count > 0 then
			out[#out + 1] = pair[2]:rep(count)
			value = value % pair[1]
		end
	end

	return table.concat(out)
end

--- Format one positive integer as a lowercase Roman numeral
-- @param value number integer from 1 through 3999
-- @return string|nil numeral conventional Roman numeral
function roman.lower(value)
	local numeral = roman.upper(value)

	return numeral and numeral:lower() or nil
end

return roman
