local export = {}
local PAGENAME = mw.title.getCurrentTitle().text
local find = mw.ustring.find
local sub = mw.ustring.sub
local gsub = mw.ustring.gsub
local rhyme

local lang = require("Module:languages").getByCode("lo")

-- for easier processing
local pre = {
	[1] = { "ຫງ", "໠" }, -- faux hng
	[2] = { "ຫ[ຍຽ]", "໡" }, -- faux hny
	[3] = { "ຫນ", "ໜ" },
	[4] = { "ຫມ", "ໝ" },
	[5] = { "ຫ[ຣລຼ]", "໢" }, -- faux hl
	[6] = { "ຫວ", "໣" }, -- faux hw
	[7] = {"([ເແໂໃໄ])([ກ-ຮໜໝ໠໡໢໣][ຣລວຼ]?)", "%2%1"},
	[8] = {"(.*)([່້໊໋])(.*)", "%1%3%2"},
}

local initials = {
	["ກ"] = "k", ["ຂ"] = "kʰ", ["ຄ"] = "kʰ", ["໠"] = "ŋ", ["ງ"] = "ŋ",
	["ຈ"] = "t͡ɕ", ["ສ"] = "s", ["ຊ"] = "s", ["໡"] = "ɲ", ["ຍ"] = "ɲ",
	["ດ"] = "d", ["ຕ"] = "t", ["ຖ"] = "tʰ", ["ທ"] = "tʰ", ["ໜ"] = "n", ["ນ"] = "n",
	["ບ"] = "b", ["ປ"] = "p", ["ຜ"] = "pʰ", ["ພ"] = "pʰ",
	["ຝ"] = "f", ["ຟ"] = "f", ["ໝ"] = "m", ["ມ"] = "m",
	["ຢ"] = "j", ["ຣ"] = "l", ["໢"] = "l", ["ລ"] = "l",
	["໣"] = "ʋ", ["ວ"] = "ʋ", ["ຫ"] = "h", ["ຮ"] = "h", ["ອ"] = "ʔ",
	["ກວ"] = "kʷ", ["ຂວ"] = "kʷʰ", ["ຄວ"] = "kʷʰ", ["ງວ"] = "ŋʷ",
	["ຈວ"] = "t͡ɕʷ", ["ສວ"] = "sʷ", ["ຊວ"] = "sʷ",
	["ຖວ"] = "tʷʰ", ["ທວ"] = "tʷʰ", ["ລວ"] = "lʷ", ["ອວ"] = "ʔʷ", ["ຮວ"] = "hʷ",
}

local vowels = {
	[""] = "#",
	["ະ"] = "aʔ", ["ັ"] = "a", ["າ"] = "aː",
	["ິ*"] = "iʔ", ["ິ"] = "i", ["ີ"] = "iː",
	["ຶ*"] = "ɯʔ", ["ຶ"] = "ɯ", ["ື"] = "ɯː",
	["ຸ*"] = "uʔ", ["ຸ"] = "u", ["ູ"] = "uː",
	["ເະ"] = "eʔ", ["ເັ"] = "e", ["ເ"] = "eː",
	["ແະ"] = "ɛʔ", ["ແັ"] = "ɛ", ["ແ"] = "ɛː",
	["ໂະ"] = "oʔ", ["ົ"] = "o", ["ໂ"] = "oː",
	["ເາະ"] = "ɔʔ", ["ັອ"] = "ɔ", ["ອ"] = "ɔː", ["ໍ"] = "ɔː",
	["ເິ*"] = "ɤʔ", ["ເິ"] = "ɤ", ["ເີ"] = "ɤː",
	["ົວະ"] = "uə̯ʔ", ["ົວ"] = "uːə̯", ["ວ"] = "uːə̯", ["'ວ"] = "uːə̯",
	["ເັຍ"] = "iə̯ʔ", ["ເັຽະ"] = "iə̯ʔ", ["ັຽ"] = "iə̯",
	["ເຍ"] = "iːə̯", ["ເັຽ"] = "iːə̯", ["ຽ"] = "iːə̯", ["'ຍ"] = "iːə̯", ["'ຽ"] = "iːə̯",
	["ເຶອ*"] = "ɯə̯ʔ", ["ເຶອ"] = "ɯə̯", ["ເືອ"] = "ɯːə̯",
	["ຳ"] = "am", ["ໃ"] = "aɰ", ["ໄ"] = "aj", ["ເົາ"] = "aw",
}

local finals = {
	[""] = "", ["ກ"] = "k̚", ["ດ"] = "t̚", ["ບ"] = "p̚",
	["ງ"] = "ŋ", ["ນ"] = "n", ["ມ"] = "m",
	["ຍ"] = "j", ["ຽ"] = "j", ["ວ"] = "w", ["ສ"] = "s",
	--force final
	["+ກ"] = "k̚", ["+ດ"] = "t̚", ["+ບ"] = "p̚",
	["+ງ"] = "ŋ", ["+ນ"] = "n", ["+ມ"] = "m",
	["+ຍ"] = "j", ["+ວ"] = "w", ["+ສ"] = "s",
}


-- เวียงจันทน์
local vt_unmarked_tones = { -- M,L,H
	live       = { "˩(˧)", "˧˥", "˩(˧)" },
	dead_short = { "˧˥", "˧", "˧˥" },
	dead_long  = { "˧˩", "˥˨", "˧˩" },
}

local vt_marked_tones = { -- M,L,H
	["່"] = { "˧", "˧", "˧" },
	["້"] = { "˥˨", "˥˨", "˧˩" },
	["໊"] = { "˧˥", "˧˥", "˧˥" },
	["໋"] = { "˩˧", "˩˧", "˩˧" },
}

-- หลวงพระบาง
local lp_unmarked_tones = { -- M,L,H
	live       = { "˩˨", "˩˨", "˥˧˧" },
	dead_short = { "˩˨", "˧˨", "˩˨" },
	dead_long  = { "˥˥˨", "˧˦", "˥˥˨" },
}

local lp_marked_tones = { -- M,L,H
	["່"] = { "˧˨", "˧˨", "˧˨" },
	["້"] = { "˧˦", "˧˦", "˥˥˨" },
	["໊"] = { "˧˦", "˧˦", "˧˦" },
	["໋"] = { "˩˨", "˩˨", "˩˨" },
}


function export.show(frame)

	local accents = {"เวียงจันทน์", "หลวงพระบาง"}
	local output = {}

	for _,accent in ipairs(accents) do
		table.insert(output, toIPA(frame, accent))
	end

	-- reduced hyphenation (FIXME: Use the standard module)
	table.insert(output, "* การแบ่งพยางค์: <span class='Laoo lo-reading' lang='lo'>" .. (frame:getParent().args[1] or PAGENAME) .. "</span>")

	-- global var trick (FIXME: YUCK, clean this up)
	local rhymes
	if rhyme == "aɰ" then
		rhymes = {{rhyme = "aj"}, {rhyme = rhyme}}
	elseif rhyme and not find(rhyme, "^#") then
		rhymes = {{rhyme = rhyme}}
	end
	table.insert(output, "* " .. require("Module:rhymes").format_rhymes {
		lang = lang,
		rhymes = rhymes,
	})

	return table.concat(output, "\n")
end

function toIPA(frame, accent)

	local args = frame:getParent().args
	local text = args[1] or PAGENAME -- supports only one pronunciation
	local debug = args["d"] or nil

	local unmarked_tones, marked_tones
	if accent == "เวียงจันทน์" then
		unmarked_tones, marked_tones = vt_unmarked_tones, vt_marked_tones
		text = gsub(text, "ໃ", "ໄ")
	elseif accent == "หลวงพระบาง" then
		unmarked_tones, marked_tones = lp_unmarked_tones, lp_marked_tones
	else
		error("The accent " .. accent .. " is not accepted.")
	end

	local ipa = {}

	for syl in mw.text.gsplit(text, "[ %.%-]") do
		for _, v in ipairs(pre) do
			syl = mw.ustring.gsub(syl, v[1], v[2])
		end

		local i, v, f, t = mw.ustring.match(syl, "^([ກ-ຮໜໝ໠໡໢໣][ຣລວຼ]?)('?[ະ-ູົ-ໄໍຍວອຽ]*)(%+?[ກດບງນມຍຽວສ]?)([່້໊໋]?)$")

		if find(i, ".[ຣລຼ]$") then
			error("The -ຣ-, -ລ- medials are either unpronounced or disyllabic. Please respell.")
		end

		if find(i, "^[ກຈດຕບປຢອ]ວ?$") then -- middle class
			tn = 1
		elseif find(i, "^[ຄຊທພຟຮງຍນມຣລວ]ວ?$") then -- low class
			tn = 2
		else --high class
			tn = 3
		end

		if find(i, ".ວ$") then
			if v == "" then
				i = sub(i, 1, -2)
				v = "ວ"
			elseif v == "ຍ" then
				i = sub(i, 1, -2)
				v = "ວ"
				f = "ຍ"
			elseif v == "າ" then -- Cwaa > Cuua
				i = sub(i, 1, -2)
				v = "ວ"
			elseif v == "າຍ" then -- Cwaa > Cuua
				i = sub(i, 1, -2)
				v = "ວ"
				f = "ຍ"
			end
		end

		if find(v, "ວ$") and v ~= "ົວ" and v ~= "ວ" and v ~= "'ວ" then
			v = sub(v, 1, -2)
			f = "ວ"
		end

		if find(v, "ຍ$") and v ~= "ເຍ" and v ~= "ເັຍ" and v ~= "'ຍ" then
			v = sub(v, 1, -2)
			f = "ຍ"
		end

		if find(v, "ຽ$") and v ~= "ັຽ" and v ~= "ເັຽ" and v ~= "ຽ" and v ~= "'ຽ" then
			v = sub(v, 1, -2)
			f = "ຍ"
		end

		if f == "" and (v == "ິ" or v == "ຶ" or v == "ຸ" or v == "ເິ" or v == "ເຶອ") then
			v = v .. "*" -- added ʔ
		end

		if t ~= "" then
			tm = marked_tones[t]
		else
			dead = (find(f, "%+?[ກດບ]") or find(vowels[v], "ʔ$"))
			long = find(vowels[v], "ː")
			tm = unmarked_tones[(dead and (long and "dead_long" or "dead_short") or "live")]
		end

		if debug then
			table.insert(ipa, "["..(i or "-").."]["..(v or "-").."]["..(f or "-").."]["..(t or "-").."]")
		else
			table.insert(ipa, initials[i] .. vowels[v] .. finals[f] .. tm[tn])
			rhyme = vowels[v] .. finals[f] -- It becomes rhyme after the last iteration
		end
	end

	local ipa_final = table.concat(ipa, ".")
	ipa_final = gsub(ipa_final, "a(ʔ[˥-˩]+)%.", "a(%1).")
	ipa_final = "[" .. ipa_final .. "]"

	return "* " .. require("Module:IPA").format_IPA_full {
		lang = lang,
		items = {{pron = ipa_final}},
		a = {accent},
	} .. (#ipa > 0 and require("Module:utilities").format_categories({"ศัพท์ภาษาลาวที่มี " .. #ipa .. " พยางค์"}, lang) or "")
end

return export