local m_IPA = require("Module:IPA")

local export = {}

local consonants = {
	["b"] = "ɓ", ["d"] = "ɗ", ["ŵ"] = "w⁽ᵝ⁾",
	["h"] = "ʰ", ["w"] = "ʷ", ["y"] = "ʲ",
	["l"] = "ɽ", ["r"] = "ɽ",
	["j"] = "d͡ʒ",
	["g"] = "ɡ"
}

local vowels = {"a", "e", "i", "o", "u", "á", "é", "í", "ó", "ú", "ń", "m'", "ḿ"}

local pre_replacements = {
	["awu"] = "a(w)u", ["ewu"] = "e(w)u", ["iwu"] = "i(w)u", ["owa"] = "o(w)a", ["uwa"] = "u(w)a",
	["áwu"] = "á(w)u", ["éwu"] = "é(w)u", ["íwu"] = "í(w)u", ["ówa"] = "ó(w)a", ["úwa"] = "ú(w)a",
	["awú"] = "a(w)ú", ["ewú"] = "e(w)ú", ["iwú"] = "i(w)ú", ["owá"] = "o(w)á", ["uwá"] = "u(w)á",
	["áwú"] = "á(w)ú", ["éwú"] = "é(w)ú", ["íwú"] = "í(w)ú", ["ówá"] = "ó(w)á", ["úwá"] = "ú(w)á"
}

local trigraphs = {["tcʰ"] = "t͡ʃʰ",
				   ["nɗz"] = "ⁿdz",
				   ["%(ʷ%)"] = "(w)",
				   }
				   
local digraphs = {["cʰ"] = "t͡ʃ",
			      ["sʰ"] = "ʃ",
			      ["zʲ"] = "ʒ",
			      ["ɗz"] = "d͡z",
			      ["dz"] = "d͡z",
			      ["ts"] = "t͡s",
			      ["ʰʷ"] =  "ʷʰ", 
			      ["ʰʲ"] = "ʲʰ", 
			      ["m'"] = "m",
			      ["ɓ'"] = "b",
			      ["ɗ'"] = "d",
			      ["ḿp"] = "ḿ'p",
			      ["pf"] = "p͡f",
			      ["ɓv"] = "b͡v"}
		
local nasals = {["mɓ"] = "ᵐb", ["mp"] = "ᵐp",
	            ["mv"] = "ᶬv", ["mf"] = "ᶬf",
	            ["nɗ"] = "ⁿd", ["nt"] = "ⁿt",
	            ["nɡ"] = "ᵑɡ", ["nɡ'"] = "ŋ", ["nk"] = "ᵑk",
	            ["nd͡ʒ"] = "ⁿd͡ʒ", 
	            ["nt͡ʃ"] =  "ⁿt͡ʃ",
	            ["nʲ"] = "ɲ",
	            ["ps"] = "psʲ",
	            ["ɓz"] = "bzʲ",
	            ["mb"] = "ᵐb",
	            ["nz"] = "ⁿz",
	            ["ns"] = "ⁿs",
            }
            
local syllable_ends = {}
for k,v in ipairs(vowels) do
	syllable_ends[v] = v .. " "
end

-- remove spaces from the end of a string
function rtrim(s)
	local n = #s
	while n > 0 and s:find("^%s", n) do n = n - 1 end
	return s:sub(1, n)
end

function export.IPA(text)
	
	text = rtrim(text)
	text = mw.ustring.lower(text)
	text = mw.ustring.gsub(text, "%-", "")
	
	-- if text contains spaces, recursively computer IPA for each part
	if (mw.ustring.match(text, "%s")) then
		local result = {}
		for i in mw.ustring.gmatch(text, '([^ ]+)') do
			table.insert(result, mw.ustring.sub(export.IPA(i),2,-2))	
		end
		return "/"..table.concat(result, " ").."/"
	end

	for k1,replacement in pairs(pre_replacements) do
		text = mw.ustring.gsub(text, k1, replacement)
	end
	
	text = mw.ustring.gsub(text, "m'", "m' ")
	text = mw.ustring.gsub(text, ".", syllable_ends)
	text = rtrim(text)

	local syllables = mw.text.split(text, " ", true)
	
	local result = {}

	for k1,syllable in ipairs(syllables) do
		local ipa = syllable
		
		ipa = mw.ustring.gsub(ipa, ".", consonants)

		for k2,trigraph in pairs(trigraphs) do
			ipa = mw.ustring.gsub(ipa, k2, trigraph)
		end
		
		for k2,digraph in pairs(digraphs) do
			ipa = mw.ustring.gsub(ipa, k2, digraph)
		end

		for k2,nasal in pairs(nasals) do
			ipa = mw.ustring.gsub(ipa, k2, nasal)
		end

		local first = mw.ustring.sub(ipa, 1, 1)
		
		if (first == "ʰ") then
			ipa = "h"..mw.ustring.sub(ipa,2)
		end
		if (first == "ʲ") then
			ipa = "j"..mw.ustring.sub(ipa,2)
		end
		if (first == "ʷ") then
			ipa = "w"..mw.ustring.sub(ipa,2)
		end
		
		table.insert(result, ipa)
		
	end
	
	if (#result >= 2) then
		local penultimate = result[#result-1]
		local first = mw.ustring.sub(penultimate, 1, 2)
		
		if (first ~= "ḿ'") then
			penultimate = "ˈ"..penultimate
		end

		result[#result-1] =  penultimate
	end
	
	result = table.concat(result, ".")
	
	result = mw.ustring.gsub(result, "'", "ˈ")
	result = mw.ustring.gsub(result, "%.ˈ", "ˈ")
	
	if (mw.ustring.sub(result, 1, 1) == ".") then result = mw.ustring.sub(result, 2) end

	result = "/" .. result .. "/"
	return result
	
end

function export.show(frame)
	local params = {
		[1] = {default = mw.title.getCurrentTitle().text, list=true}
	}
	
	local args = require("Module:parameters").process(frame:getParent().args, params)
	
	lang = require("Module:languages").getByCode("ny")
	local items = {}
	
	for _,text in ipairs(args[1]) do
		table.insert(items, {pron = export.IPA(text), note = nil})
	end
	
	local text = args[1]

	return m_IPA.format_IPA_full(lang, items)
	
end

return export