local export = {}

local function remove_duplicates(ls) 
	local hash = {}
	local ls0 = {}
	for i, v in ipairs(ls) do
   		if not hash[v] then
    		table.insert(ls0, v)
       		hash[v] = true
       	end 
    end
	return ls0
end

local function concat(l1,l2)
	local l3 = {}
	if l1 then for i,v in pairs(l1) do l3[#l3+1] = v end end
	if l2 then for i,v in pairs(l2) do l3[#l3+1] = v end end
	return l3
end

local function b_search(ys, x, L, H)
    L = L or 1
    H = H or #ys
    
    if L < 0 then
    	error('L < 0')
    end
    
    while L < H do
        M = math.floor((L+H) / 2)
        if ys[M] < x then L = M+1 else H = M end
    end
    
    return L
 end

--comment for calculate_page_number_divergence:
--page_number_divergence results from a few buffer pages before the first
--headword, and subsequently, a few multi-page entries leaving some pages
--without headwords.  Each time this latter takes place, the index of 
--page-initial headwords drifts from the physical page number.
local function calculate_page_number_divergence(w0, is_proper)
	return 4 + ((is_proper and 4) or ((w0 >= 'taking' and 4) or (w0 >= 'setting' and 3) or (w0 >= 'putrefaction' and 2) or 1))
end

local function get_page(page_headwords, page_headwords_proper, w)
	local is_proper = mw.getLanguage('en'):ucfirst(w) == w
	local w0 = mw.getLanguage('en'):lcfirst(w)
	local p_n_divergence = calculate_page_number_divergence(w0, is_proper)
	if not is_proper then
		return  (b_search(page_headwords, w0, 0, 995) - 1) + p_n_divergence
	else
		return (b_search(page_headwords_proper, w0, 0, 32) - 1) + 995 + p_n_divergence
	end
end

local function uc1_eng(x)
	return mw.getLanguage('en'):ucfirst(x)
end

local function f_reverse_index(proper_or_both,reverse_index,title)
	local headwords_eng = {}
	local rix = reverse_index[title]
	if not (rix == nil) then 
		for i, v in pairs(rix) do 
			local pbc = proper_or_both[v]
			if pbc == nil then
				headwords_eng[#headwords_eng+1] = v
			else
				headwords_eng[#headwords_eng+1] = uc1_eng(v)
				if pbc == "b" then
					headwords_eng[#headwords_eng+1] = v
				end
			end
		end
	end
	return headwords_eng
end

local function f_reverse_index_tab_delimited(proper_or_both,reverse_index_tab_delimited,title)
	local headwords_eng = {}
	for English_words in reverse_index_tab_delimited:gmatch(
			"%f[^%z\n]" .. require("Module:string utilities").pattern_escape(title)
			.. "\t([^\n]+)%f[%z\n]") do
		for word in English_words:gmatch("[^\t]+") do
			table.insert(headwords_eng, word)
		end
	end
	return headwords_eng
end


local function load_infinitives(w)
    --return mw.loadData("Mô đun:R:Woodhouse/psia1_to_infs")[w]
	return require("Mô đun:data tables").index_table("grc_RWoodhouse_lemma_to_infinitives", w)
end

--grc_RWoodhouse_lemma_to_headwords
local function print_html(title)
	--local psia1_to_infs = mw.loadData("Mô đun:R:Woodhouse/psia1_to_infs")                    --for calculating title_addenda
	--local reverse_index = mw.loadData("Mô đun:R:Woodhouse/reverse_index") 				   --for f_reverse_index_
	local reverse_index_tab_delimited = require("Mô đun:R:Woodhouse/reverse_index_tab_delimited")    --for f_reverse_index_tab_delimited
	local proper_or_both = mw.loadData("Mô đun:R:Woodhouse/proper_or_both")                  --for f_reverse_index
	local page_headwords = mw.loadData("Mô đun:R:Woodhouse/page_headwords")                  --for get_page
	-- page_headwords also requires a select_all function in data_tables to work efficiently
	local page_headwords_proper = mw.loadData("Mô đun:R:Woodhouse/page_headwords_proper")    --for get_page
	
	local title_uc = mw.getContentLanguage():ucfirst(title)
	local title_addenda = load_infinitives(title) --psia1_to_infs[title]
	local titles = concat({title, title_uc}, title_addenda)
	
	local headwords_eng = {}
	for i, title in ipairs(titles) do
		headwords_eng = concat(headwords_eng, f_reverse_index_tab_delimited(proper_or_both, reverse_index_tab_delimited, title)) --changed reverse_index to reverse_index_tab_delineated
	end
	headwords_eng = remove_duplicates(headwords_eng)
	table.sort(headwords_eng)
	
	local lst = {}
	local count = 0
	for k, v in pairs(headwords_eng) do
		local nPage = get_page(page_headwords, page_headwords_proper, v)
		table.insert(lst, "<li>[https://artflsrv03.uchicago.edu/cgi-bin/efts/sqldbs/WOODHOUSE/woodhouse.py?pagenumber="..string.format(nPage-5).."&pageturn=1 "..v.."] idem, page "..(nPage-5)..".</li>")
		count = count + 1
	end
	
	local expandtext = count .. " headword" .. ( count == 1 and "" or "s" )
	
	table.insert(lst, 1, "<div class='mw-collapsible mw-collapsed' style='display: inline' data-expandtext='"..expandtext.."><ul>")
    table.insert(lst, "</ul></div>")
	return table.concat(lst)
end

function export.reverse_index(frame)
	local args = frame:getParent().args
	local title = args['w'] or mw.title.getCurrentTitle().text
	if (not args['w'] or args['w'] == "") and mw.title.getCurrentTitle().nsText == "Template" then
		return ""
	else
		return print_html(title)
	end
end

return export