local export = {}
local gsub = mw.ustring.gsub
local match = mw.ustring.match
local sub = mw.ustring.sub
local u = mw.ustring.char

local c = {
	["Deva"] = {
	['k']='क', ['ɡ']='ग', ['kʰ']='ख', ['ɡʱ']='घ',  ['ŋ']='ङ',
    ['ɲ']='ञ', ['ç']='च', ['ʐ']='ज', ['çʰ']='छ', ['ʐʱ']='झ', 
    ['ʦ']='च', ['ʣ']='ज', ['ʦʰ']='छ', ['ʣʱ']='झ', 
	['ʈ']='ट', ['ɖ']='ड', ['ʈʰ']='ठ', ['ɖʱ']='ढ', ['ɳ']='ण', 
	['t̪']='त', ['d̪']='द', ['t̪ʰ']='थ', ['d̪ʱ']='ध', ['n']='न', ['n̪']='न',
	['l̪']='ल', ['t']='त', ['d']='द', ['tʰ']='थ', ['dʱ']='ध', 
	['p']='प', ['b']='ब', ['pʰ']='फ', ['bʱ']='भ', ['m']='म',
	['j']='य', ['r']='र', ['l']='ल', ['w']='व', ['v']='व',  ['ʃ']='श',
    ['ʂ']='ष', ['s']='स', ['z']='ज़', ['ɦ']='ह', ['ʒ']='ॹ', 
    ['ɽ']='ड', ['ɽʱ']='ढ', ['ɸ']='फ', ['f']='फ', ['x']='ख़', 
    ['β']='ब', ['ɣ']='ग', ['ɡ̞']='ग', ['k̞ʰ']='ख',  ['ɾ']='र', 
    ['.']='',  ['̪']='', ['͡']='', ['t̚t͡s']='च्च', ['d̚d͡z']='ज्ज', 
    ['t̚t͡sʰ']='च्छ', ['d̚d͡zʱ']='ज्झ', ['ɭ']='ळ', 
	['ä']='आ', ['i']='इ', ['ī']='ई',  ['u']='उ', ['ū']='ऊ', 
    ['e']='ए', ['o']='ओ',  ['ɔ']='ऑ', ['ɛ']='ऍ', 
    ['ɑ']='ऑ', ['æ']='ऍ',  ['ʌu̯']='औ', ['ʌi̯']='ऐ', 

	['ʌ']='अ',

    ['ä̃']='आँ', ['ĩ']='इँ', ['ī̃']='ईं',  ['ũ']='उँ', ['ū̃']='ऊँ', 
    ['ẽ']='एँ', ['õ']='ओं',  ['ʌ̃ũ̯']='औं', ['ʌ̃ĩ̯']='ऐं', 
	['ʌ̃']='अँ‌', ['̤ː̃']='ँः', ['ä̤ː̃']='आँः',
	-- chandrabindu    
	['̃']='ँ',
	-- visarga    
    ['ː']='ः', ['̤']='', ['̚']='',

		[""] = "",
	},
	
}

local v = {
	["Deva"] = {
		["ʌ"] = "", ["ä"] = "ा", 
		["i"] = "ि", ["ī"] = "ी",
		["u"] = "ु", ["ū"] = "ू", 
		["e"] = "े",
     	["ʌ̃"] = "ँ", ["ä̃"] = "ाँ", ["ä̤ː̃"] = "ाँः", ['̤ː̃']='ँः',
		["ĩ"] = "िं", ["ī̃"] = "ीं",
		["ũ"] = "ुुँ", ["ū̃"] = "ूूँ", 
		["ẽ"] = "ेें", ["ɛ"] = "ॅ", ["æ"] = "ॅ", 
		["o"] = "ो",	["õ"] = "ों", ["ɔ"] = "ॉ", ["ɑ"] = "ॉ", 
		[""] = "", ["ʌu̯"] = "ौ", ["ʌi̯"] = "ै",  ["ʌ̃ũ̯"] = "ौं", ["ʌ̃ĩ̯"] = "ैैं", 
	},

}

local s = {
	["Deva"] = {
		["0"] = "०", ["1"] = "१", ["2"] = "२", ["3"] = "३", ["4"] = "४",
		["5"] = "५", ["6"] = "६", ["7"] = "७", ["8"] = "८", ["9"] = "९", 
		["."] = "", [","] = "।", ["-"] = "",
	},

}

local join = {
	["Deva"] = "्", 
}

local kill = {
	["Deva"] = "्",
}

local nukta = u(0x09bc) -- Just list all those used here.

local function return_error(text)
	return error(("Unrecognised part: \"%s\""):format(text))
end

function export.tr(text, script, options)
	if type(text) == "table" then
		options = {}
		text, script = text.args[1], text.args[2]
	end

	local easy_syllable_pattern =
		"^([khɡgʰʱɽɦṅcjñːṭḍṇtdçʦʣɭʐɸnɾt̚d̚t̪d̪m͡mʌu̯ʌi̯ŋɲɳɖʈzqxcɣʒβðθʃpbwmyrlḷvs]*)([aʌäāʌ̃ä̃ĩũẽõiīuūeoʌu̯ʌi̯ɛɔæɑä̤̃ɑ̤])(̃?)("..kill[script].."?)$"

	text = gsub(text, "[0-9%.,%-]", s[script])
-- Compose patterns for processing onsets. 
	local letter = "[^"..join[script]..nukta.."]["..nukta.."]?"
	local letter_pair = "("..letter..")("..letter..")"
	
	for word in mw.ustring.gmatch(text, "[ʌäiīuɛæʌi̯ʌu̯ɔʌ̃ä̃ĩũẽõɡɭɑä̤̃ɑ̤ūeoːt̚d̚t̪d̪m͡ṃɦʰʱkhʐçʣʦgṅcjñṭḍṇtɾŋɽɲɳɖʈzqxcɣʒβɸðθʃdnpbmwyrlḷvs]+") do
		local word_conv, orig_word = {}, word
		word = gsub(word, "([aāäʌiīuūeoɛʌ̃ä̃ĩũẽõæɔʌi̯ʌu̯ɑä̤̃ɑ̤]ṃ?)", "%1 ")
		word = gsub(word, " $", "")
		
		for syllable in mw.text.gsplit(word, " ") do
			if not match(syllable, "[aāäʌiīuūeoṃɛæʌ̃ä̃ĩũẽõʌi̯ʌu̯ɔɑä̤̃ɑ̤]$") then
				syllable = syllable .. "ʌ" .. kill[script]
			end
			syllable = gsub(syllable, easy_syllable_pattern,
							function(onset, vowel, coda, optJoin)
				if onset == "" then
					onset = vowel
					vowel = ""
				end
				if not c[script][onset] then
					onset = gsub(onset, ".ʰ", c[script])
                    onset = gsub(onset, ".ʱ", c[script])
                    onset = gsub(onset, ".͡", c[script])
                    onset = gsub(onset, "..ʱ", c[script])
                    onset = gsub(onset, "..ʰ", c[script])

				 	onset = gsub(onset, ".", c[script])
-- Join pairs of consonants
					onset = gsub(onset, letter_pair, "%1"..join[script].."%2")
-- Join adjacent consonants that were in different pairs.
					onset = gsub(onset, letter_pair, "%1"..join[script].."%2")
				else
					onset = c[script][onset]
				end
				
				return onset .. (v[script][vowel] or return_error(vowel)) .. c[script][coda] .. optJoin
			end)
				
			table.insert(word_conv, syllable)
		end
		word = table.concat(word_conv, "")

		word = gsub(word, "इः्", "ई")
		word = gsub(word, "उः्", "ऊ")
		word = gsub(word, "ः्", "ः")
		word = gsub(word, "िः्", "ी")
		word = gsub(word, "ुः्", "ू")
		word = gsub(word, "त्स्ʰ", "छ")
		word = gsub(word, "द्ज़््", "ज्")
		word = gsub(word, "अउ̯", "औ")
		word = gsub(word, "अइ̯", "ऐ")
		word = gsub(word, "उ̯", "ौ")
		word = gsub(word, "इ̯", "ै")
		word = gsub(word, "अँइँ̯", "ऐं")
		word = gsub(word, "अँउँ̯", "औं")
		word = gsub(word, "ँइँ̯", "ैं")
		word = gsub(word, "ँउँ̯", "ौं")
		word = gsub(word, "ॺ", "ढ़")
		word = gsub(word, "([कखगघचछजझटठडढढ़ख़ड़णतथदधनपफबभमयरलवशषसहङञॾॺफ़ज़ॹ])्ः", "%1्%1")
		word = gsub(word, "([कखगघचछजझटठडढढ़ख़ड़णतथदधनपफबभमयरलवशषसहङञॾॺफ़ज़ॹ])(्)य([कखगघचछजझटठडढढ़ख़ड़णतथदधनपफबभमयरलवशषसहङञॾॺफ़ज़ॹ])", "%1े%3")
		word = gsub(word, "([कखगघचछजझटठडढढ़ख़ड़णतथदधनपफबभमयरलवशषसहङञॾॺफ़ज़ॹ]?)य([कखगघचछजझटठडढढ़ख़ड़णतथदधनपफबभमयरलवशषसहङञॾॺफ़ज़ॹ])", "%1ए%2")
		word = gsub(word, "([कखगघचछजझटठडढढ़ख़ड़णतथदधनपफबभमयरलवशषसहङञॾॺफ़ज़ॹिीुूेैोौा])य$", "%1ए")
		word = gsub(word, "([कखगघचछजझटठडढढ़ख़ड़णतथदधनपफबभमयरलवशषसहङञॾॺफ़ज़ॹ]?)व([कखगघचछजझटठडढढ़ख़ड़णतथदधनपफबभमयरलवशषसहङञॾॺफ़ज़ॹ])", "%1ओ%2")
		word = gsub(word, "([कखगघचछजझटठडढढ़ख़ड़णतथदधनपफबभमयरलवशषसहङञॾॺफ़ज़ॹ])(्)व([कखगघचछजझटठडढढ़ख़ड़णतथदधनपफबभमयरलवशषसहङञॾॺफ़ज़ॹ])", "%1ो%3")
		word = gsub(word, "ड़््", "ड़्")

		text = gsub(text, orig_word, word, 1)
	end
	return text
end

return export