local export = {}
local m_translit = require("Module:hi-translit")
local util = require("Module:hi")
local data = require("Module:hi-conj/data")

local gsub = mw.ustring.gsub
local sub = mw.ustring.sub
local match = mw.ustring.match
local len = mw.ustring.len

local hi_format = util.hi_format
local wordify = util.wordify

local test = {}

local vowel_conv = {
	['अ'] = "", ['आ']= "ा", ['इ'] = "ि", ['ई'] = "ी", ['उ'] = "ु", ['ऊ'] = "ू", ['ऋ'] = "ृ", ['ए'] = "े", ['ऐ'] = "ै", ['ओ'] = "ो", ['औ'] = "ौ"
}
local signs = "aिुृेोाीूैौॉॅॆॊ"

local irregular_perfects = {
	['कर'] = "की",
	['जा'] = "गय",
	['ले'] = "ली",
	['दे'] = "दी",
	['हो'] = "हु",
}

notes = {}

local function make_row(data, count, word)
	local rows = 0
	local name = data["name"]
	local abbrev = data["abbrev"]
	local cur = {}
	local cols = 1
	if data["data"] ~= nil then
		local has_entries = false
		local subcount = 1
		for index, value in ipairs(data["data"]) do
			if type(value) == "string" then
				has_entries = true
				
				-- make extra rows for masculine and feminine forms
				if #data["data"] == 12 then
					if index == 1 then
						table.insert(cur, '| style="width: 1em; background: #D4D4D4;" | <span class="gender"><abbr title="masculine gender">m</abbr></span>')
					end
					if index == 7 then
						table.insert(cur, '|- class="vsHide"')
						table.insert(cur, '| style="width: 1em; background: #D4D4D4;" | <span class="gender"><abbr title="feminine gender">f</abbr></span>')
					end
				else
					cols = 2
				end
				
				-- when the form doesn't exist (indicated by hyphen)
				-- also handles consonant-ending verb stem forcing vowel diacritic
				if value == '-' then
					table.insert(cur, "|")
				else
					local infl = ""
					local old_word = word
					local altform = nil

					-- sandhi
					if sub(word, -1) == "ी" then 
						if sub(value, 1, 1) == "आ" then
							altform = sub(word, 1, -2) .. "ि"
							word = sub(word, 1, -2) .. "िय"
						elseif sub(value, 1, 1) == "ए" then
							altform = sub(word, 1, -2) .. "ि"
							word = sub(word, 1, -2) .. "िय"
						elseif sub(value, 1, 1) == "ई" then
							word = sub(word, 1, -2)
						end
					end

					if match(sub(word, -1), '[' .. signs .. ']') then -- stem ends in a vowel diacritic
						infl = word .. value
						if altform then
							table.insert(notes, notes[infl] .. " " .. altform .. value)
						end
					elseif vowel_conv[sub(word, -1, -1)] == nil then -- stem ends in a consonant => merge vowels
						if vowel_conv[sub(value, 1, 1)] ~= nil then
							infl = word .. vowel_conv[sub(value, 1, 1)] .. sub(value, 2)
						else
							infl = word .. value
						end
					else -- full vowel
						infl = word .. value
					end
					infl = gsub(infl, " ", "]] [[")

					if #data["data"] == 1 then
						table.insert(cur, '| colspan="100%" | ' .. wordify(infl) .. (altform and " " .. wordify(altform .. value) or ""))
					else
						table.insert(cur, '| ' .. wordify(infl) .. (altform and " " .. wordify(altform .. value) or ""))
					end

					word = old_word
				end
				
			else
				
				-- recursion until it reaches actual forms; this is so all the various rowspans are correct
				local add = nil
				
				-- irregular root changes
				local old_word = word
				if (value["name"] == "Perfect") or (value["name"] == "Perfective") or
					(name == "Perfective") or (value["name"] == "Adjectival") then
					if irregular_perfects[word] ~= nil then
						add = make_row(value, subcount, irregular_perfects[word])
					else
						add = make_row(value, subcount, word)
					end
				else
					add = make_row(value, subcount, word)
				end
				if add[2] ~= 0 then
					subcount = subcount + 1
					rows = rows + add[2]
					table.insert(cur, add[1])
				end
				word = old_word
			end
		end
		
		-- masc+fem or no distinction, maintain rowspan
		if has_entries then
			if #data["data"] == 12 then
				rows = rows + 2
			else
				rows = rows + 1
			end
		end
		
	end
	
	-- debug, comment out if you want
	-- table.insert(test, "* " .. name .. " (" .. rows .. ")" .. " " .. count .. " " .. word)
	
	-- magic for making sure new rows are made at the right points
	local res = ""
	if count == 0 then
		cols = "100%"
		rows = 1
	end
	if count ~= 1 then res = res .. '\n|- class="vsHide"' end
	res = res .. '\n| style="width: 5em; background: #E6F2FF;" '
	res = res .. 'rowspan=' .. rows .. " colspan=" .. cols .. " | "
	res = res .. "''" .. (abbrev and ('<abbr style="font-variant: small-caps; text-transform: lowercase;" title=' .. name .. '>' .. abbrev .. '</abbr>') or name) .. "''\n"
	if count == 0 then res = res .. '\n|- class="vsHide"' end
	if name == "Participles" then
		res = res .. '\n|- class="vsHide"'
		res = res .. '\n| style="background:#E6F2FF" colspan=2 |'
		res = res .. '\n| style="background: #D4D4D4;" | <span class="gender"><abbr title="masculine gender">m</abbr></span> <span class="gender"><abbr title="singular number">sg</abbr></span>'
		res = res .. '\n| style="background: #D4D4D4;" | <span class="gender"><abbr title="feminine gender">m</abbr></span> <span class="gender"><abbr title="plural number">pl</abbr></span>'
		res = res .. '\n| style="background: #D4D4D4;" | <span class="gender"><abbr title="masculine gender">f</abbr></span> <span class="gender"><abbr title="masculine gender">m</abbr></span>'
		res = res .. '\n| style="background: #D4D4D4;" | <span class="gender"><abbr title="feminine gender">f</abbr></span> <span class="gender"><abbr title="plural number">pl</abbr></span>'
		res = res .. '\n|- class="vsHide"'
	end
	return {res .. table.concat(cur, "\n"), rows}
end

function export.show(frame)
	local args = frame:getParent().args
	local word = args[1] or mw.title.getCurrentTitle().text
	if word == 'hi-conj-auto' then word = 'करना' end
	word = sub(word, 1, -3)

	local res = {'{| class="inflection-table vsSwitcher" data-toggle-category="inflection" style="background:#F9F9F9; text-align:center; border: 1px solid #CCC; min-width: 20em"'}
	table.insert(res, '|- style="background: #d9ebff;"')
	table.insert(res, '! class="vsToggleElement" style="text-align: left;" colspan="100%" | Impersonal forms of ' .. hi_format(word .. "ना"))
	table.insert(res, make_row(data[5], 0, word)[1])
	table.insert(res, make_row(data[6], 0, word)[1])
	table.insert(res, "|}")

	table.insert(res, '{| class="inflection-table vsSwitcher" data-toggle-category="inflection" style="background:#F9F9F9; text-align:center; border: 1px solid #CCC; min-width: 20em"')
	table.insert(res, '|- style="background: #d9ebff;"')
	table.insert(res, '! class="vsToggleElement" style="text-align: left;" colspan="100%" | Personal forms of ' .. hi_format(word .. "ना"))
	table.insert(res, '|- class="vsHide" style="background: #DFEEFF;"')
	table.insert(res, '| rowspan=2 |')
	table.insert(res, '| rowspan=2 |')
	table.insert(res, '| rowspan=2 |')
	table.insert(res, "| colspan=3 | '''Singular'''")
	table.insert(res, "| colspan=3 | '''Plural'''")
	table.insert(res, '|- class="vsHide" style="background: #DFEEFF;"')
	table.insert(res, "| '''1<sup>st</sup>'''<br>" .. hi_format('मैं'))
	table.insert(res, "| '''2<sup>nd</sup>'''<br>" .. hi_format('तू'))
	table.insert(res, "| '''3<sup>rd</sup>'''<br>" .. hi_format('यह]]/[[वह'))
	table.insert(res, "| '''1<sup>st</sup>'''<br>" .. hi_format('हम'))
	table.insert(res, "| '''2<sup>nd</sup>'''<br>" .. hi_format('तुम'))
	table.insert(res, "| '''3<sup>rd</sup>'''<br>" .. hi_format('ये]]/[[वे]]/[[आप'))
	table.insert(res, make_row(data[1], 0, word)[1])
	table.insert(res, make_row(data[2], 0, word)[1])
	table.insert(res, make_row(data[3], 0, word)[1])
	table.insert(res, make_row(data[4], 0, word)[1])
	table.insert(res, "|}")
	for orig, alt in pairs(notes) do
		table.insert(hi_format(orig) .. ' may also be written ' .. hi_format(alt))
	end
	
	return table.concat(res, "\n")
end

return export