local export = {}

local AC = mw.ustring.char(0x0301) -- acute =  ́

local rsubn = mw.ustring.gsub

local u = mw.ustring.char

-- version of rsubn() that discards all but the first return value
local function rsub(term, foo, bar)
	local retval = rsubn(term, foo, bar)
	return retval
end

local tt = {
	["А"]="ั", ["Б"]="บ", ["В"]="วฺ", ["Г"]="ฆ", ["Д"]="ด",
	["Е"]="ย↶แ", ["Ё"]="ยอ̂", ["Ж"]="ชฺ", ["З"]="ซฺ", ["І"]="ิ", ["И"]="ิ", ["Й"]="ย", -- И for Old Belarusian
	["К"]="ก", ["Л"]="ล", ["М"]="ม", ["Н"]="น", ["О"]="อ̂",
	["П"]="ป", ["Р"]="ร", ["С"]="ซ", ["Т"]="ต", ["У"]="ุ", ["Ў"]="ว", ["Ф"]="ฟ",
	["Х"]="ฅ", ["Ц"]="ต͜ซ", ["Ч"]="ช", ["Ш"]="ฌ",
	["Ы"]="ึ", ["Ь"]=u(0x02B9), ["Э"]="↶แ", ["Ю"]="ยุ", ["Я"]="ยั",

	["а"]="ั", ["б"]="บ", ["в"]="วฺ", ["г"]="ฆ", ["д"]="ด",
	["е"]="ย↶แ", ["ё"]="ยอ̂", ["ж"]="ชฺ", ["з"]="ซฺ", ["і"]="ิ", ["и"]="ิ", ["й"]="ย",
	["к"]="ก", ["л"]="ล", ["м"]="ม", ["н"]="น", ["о"]="อ̂",
	["п"]="ป", ["р"]="ร", ["с"]="ซ", ["т"]="ต", ["у"]="ุ", ["ў"]="ว", ["ф"]="ฟ",
	["х"]="ฅ", ["ц"]="ต͜ซ", ["ч"]="ช", ["ш"]="ฌ",
	["ы"]="ึ", ["ь"]=u(0x02B9), ["э"]="↶แ", ["ю"]="ยุ", ["я"]="ยั",

	["’"]='ʺ', ["ʼ"]='ʺ',
	-- currently non-standard, used in some older norms
	["Ґ"]='G', ["ґ"]='g',
	-- Belarusian style quotes
	['«']='“', ['»']='”',
};

local unstressed_vowels = "aeiyuAEIYU"
local unstressed_vowel = "[" .. unstressed_vowels .. "]"

local acute_decomposer = {
	["á"] = "a" .. AC,
	["é"] = "e" .. AC,
	["í"] = "i" .. AC,
	["ó"] = "o" .. AC,
	["ú"] = "u" .. AC,
	["ý"] = "y" .. AC,
	["Á"] = "A" .. AC,
	["É"] = "E" .. AC,
	["Í"] = "I" .. AC,
	["Ó"] = "O" .. AC,
	["Ú"] = "U" .. AC,
	["Ý"] = "Y" .. AC,
}

function export.tr(text, lang, sc)
    text = rsubn(text, "'+", { ["'"] = 'ʺ' }) -- neutral apostrophe
    text = rsubn(text, '.', tt)

	-- Mark word boundaries
	--text = rsubn(text, "(%s+)", "#%1#")
	--text = "#" .. text .. "#"

	-- Mark stress on <o>
	--text = rsubn(text, "(#[^#Oo" .. AC .. "]*)([Oo])([^#Oo" .. AC .. "]*" .. unstressed_vowel .. "[^#Oo" .. AC .. "]*#)", "%1%2" .. AC .. "%3")
	--text = rsubn(text, "(#[^#Oo" .. AC .. "]*" .. unstressed_vowel .. "[^#Oo" .. AC .. "]*)([Oo])([^#Oo" .. AC .. "]*#)", "%1%2" .. AC .. "%3")

	--Strip hashes
	--text = rsubn(text, "#", "")

	--Acute has no use here
	text = rsubn(text, AC, "")

	text = rsubn(text, "^([ัิึุ↶])", "อ%1")
	text = rsubn(text, "([%s%p])([ัิึุ↶])", "%1อ%2")
	text = rsubn(text, "([ัิุ])([ัิึุ↶])", "%1อ%2")
	text = rsubn(text, "^(อ̂)", "อ%1")
	text = rsubn(text, "([%s%p])(อ̂)", "%1อ%2")
	text = rsubn(text, "([ัิุ])(อ̂)", "%1อ%2")

	text = rsubn(text, "([ก-ฮ]ฺ?)↶(แ)", "%2%1")

	text = rsubn(text, "ั".."ั", "า")
	text = rsubn(text, "ั$", "า")
	text = rsubn(text, "ั([%s%p])", "า%1")

	text = rsubn(text, "ิ".."ิ", "ี")
	text = rsubn(text, "ิ$", "ี")
	text = rsubn(text, "ิ([%s%p])", "ี%1")

	text = rsubn(text, "ึ".."ึ", "ื")
	text = rsubn(text, "ึ$", "ื")
	text = rsubn(text, "ึ([%s%p])", "ื%1")

	text = rsubn(text, "ุ".."ุ", "ู")
	text = rsubn(text, "ุ$", "ู")
	text = rsubn(text, "ุ([%s%p])", "ู%1")

	text = rsubn(text, "ั([ก-ฮ]ฺ?)([ัาิีึืุู])", "า%1%2")
	text = rsubn(text, "ิ([ก-ฮ]ฺ?)([ัาิีึืุู])", "ี%1%2")
	text = rsubn(text, "ึ([ก-ฮ]ฺ?)([ัาิีึืุู])", "ื%1%2")
	text = rsubn(text, "ุ([ก-ฮ]ฺ?)([ัาิีึืุู])", "ู%1%2")
	text = rsubn(text, "ั([ก-ฮ]ฺ?)(อ̂)", "า%1%2")
	text = rsubn(text, "ิ([ก-ฮ]ฺ?)(อ̂)", "ี%1%2")
	text = rsubn(text, "ึ([ก-ฮ]ฺ?)(อ̂)", "ื%1%2")
	text = rsubn(text, "ุ([ก-ฮ]ฺ?)(อ̂)", "ู%1%2")

	text = rsubn(text, "ั([ก-ฮ]ฺ?)([ัาิีึืุู])", "า%1%2") --twice
	text = rsubn(text, "ิ([ก-ฮ]ฺ?)([ัาิีึืุู])", "ี%1%2")
	text = rsubn(text, "ึ([ก-ฮ]ฺ?)([ัาิีึืุู])", "ื%1%2")
	text = rsubn(text, "ุ([ก-ฮ]ฺ?)([ัาิีึืุู])", "ู%1%2")
	text = rsubn(text, "ั([ก-ฮ]ฺ?)(อ̂)", "า%1%2")
	text = rsubn(text, "ิ([ก-ฮ]ฺ?)(อ̂)", "ี%1%2")
	text = rsubn(text, "ึ([ก-ฮ]ฺ?)(อ̂)", "ื%1%2")
	text = rsubn(text, "ุ([ก-ฮ]ฺ?)(อ̂)", "ู%1%2")

	text = rsubn(text, "ั(แ)", "า%1")
	text = rsubn(text, "ิ(แ)", "ี%1")
	text = rsubn(text, "ึ(แ)", "ื%1")
	text = rsubn(text, "ุ(แ)", "ู%1")

    return text
end

function export.reverse_tr(text)--reverse-translit any words or phrases
	local reverse_tt = {}
	for k, v in pairs(tt) do
		reverse_tt[v] = k
	end
	reverse_tt['ʺ'] = "'"
	reverse_tt['ʹ'] = "ь"
	reverse_tt['i'] = "і"
	reverse_tt['I'] = "І"
	text = rsub(text, '.', acute_decomposer)
	text = rsub(text, '[Jj][aeou]', reverse_tt)
	text = rsub(text, '.', reverse_tt)
	return text
end

return export