local export = {}

local lang = require("Module:languages").getByCode("ary")
local m_IPA = require("Module:IPA")
local gsub = mw.ustring.gsub

local correspondences = {
	["g"] = "ɡ",
	["ḵ"] = "x",
	["ḥ"] = "ħ",
	["ḡ"] = "ɣ",
	["ṣ"] = "sˤ",
	["ḍ"] = "dˤ",
	["ẓ"] = "ðˤ",
	["ṭ"] = "tˤ",
	["š"] = "ʃ",
	["j"] = "ʒ",
	["ā"] = "aː",
	["ū"] = "uː",
	["ō"] = "oː",
	["ī"] = "iː",
	["e"] = "ɪ",
	["y"] = "j"
}

local vowels = "aeiuoāīūōɪ"
local vowel = "[" .. vowels .. "]"
local long_vowels = "āīūō"
local long_vowel = "[" .. long_vowels .. "]"
local consonant = "[^" .. vowels .. ". -]"
local tie = "‿"
local syllabify_pattern = "(" .. vowel .. ")(" .. consonant .. "?)(" ..
		consonant .. "?)(" .. vowel .. ")"

local function parse_params(item)
	local term = item
	local note
	local qualifier = {}
	while true do
		local new_term, angle_bracketed = term:match("^(.-)(%b<>)$")
		if not new_term then
			break
		end
		local prefix, content = angle_bracketed:match "^<(%w+):(.+)>$"
		if not prefix then
			break
		end
		if prefix == "q" then
			table.insert(qualifier, 1, content)
		elseif prefix == "n" then
			note = content
		else
			error("Unrecognized prefix '" .. prefix .. "'")
			break
		end
		term = new_term
	end
	return term, note, qualifier
end

local function syllabify(text)
	text = gsub(text, "%-(" .. consonant .. ")%-(" .. consonant .. ")", "%1.%2")
	text = gsub(text, "%-", ".")

	-- Add syllable breaks.
	for _ = 1, 2 do
		text = gsub(text, syllabify_pattern, function(a, b, c, d)
			if c == "" and b ~= "" then
				c, b = b, ""
			end

			return a .. b .. "." .. c .. d
		end)
	end

	text = gsub(text, "(" .. consonant .. ") (" .. vowel .. ")%.?(" ..
			consonant .. ")", ".%1" .. tie .. "%2%3")
	text = gsub(text, "(" .. vowel .. ") (" .. consonant .. ")%.?(" ..
			consonant .. ")", "%1" .. tie .. "%2.%3")

	return text
end

local function pronunciation(word)

	word = syllabify(word)
	word = gsub(word, '.', correspondences)

	return word
end

function export.show(frame)

	local args = require "Module:parameters".process(frame:getParent().args, {
		[1] = { list = true }
	})

	local Array = require "Module:array"

	local words = args[1]

	local transcriptions = Array(words):map(function(word, _)
		local term, note, qualifiers = parse_params(word)
		return {
			pron = "/" .. pronunciation(term) .. "/",
			qualifiers = #qualifiers > 0 and qualifiers or nil,
			note = note
		}
	end)

	return m_IPA.format_IPA_full(lang, transcriptions)
end

return export