local export = {}

-- Collisions contained in submodules of [[Module:R:Perseus/collision-data]].
local m_params = require("Module:parameters")
local m_utils = require("Module:grc-utilities")
local m_scripts = require("Module:scripts")
local m_script_utils = require("Module:script utilities")
local m_languages = require("Module:languages")

local tag_greek = m_utils.tag

local function tag_latin(text)
	local lang = m_languages.getByCode("la")
	local sc = m_scripts.getByCode("Latn")
	return m_script_utils.tag_text(text, lang, sc, nil)
end

local function lower_dashed(w)
	return string.gsub(string.lower(w), " ", "-")
end

local function remove_diacritics(x)
	return mw.ustring.gsub(mw.ustring.toNFD(x),'%W+',"")
end

-- maybe there is a better way to do this
local function beta(w)
	return require("Module:R:Perseus/polytonic-to-perseus-betacode").polytonic_to_perseus_betacode(w)
end

--[[ Resources:
	template name, with "R:" removed = {
		[1] = Perseus resource id,
		[2] = collisions index name,
		[3] = f-query-entry-postprocess,
		[4] = query-entry-suffix,
		[5] = language name
	}
	]]
local resources = {
	["L&S"] = {
		"1999.04.0059",
		"LS",
		nil,
		nil,
		'latin',
	},
	["Elementary Lewis"] = {
		"1999.04.0060",
		"EL",
		nil,
		nil,
		'latin'
	},
	["Peck"] = {
		"1999.04.0062",
		nil,
		lower_dashed,
		'-harpers',
		'latin'
	},
	["PersEnc"] = {
		"1999.04.0004",
		nil,
		lower_dashed,
		"",
		'latin'
	},
	["Stillwell"] = {
		"1999.04.0006",
		"PECS",
		lower_dashed,
		"",
		'latin'
	},
	["Platner"] = {
		"1999.04.0054",
		"TDAR",
		lower_dashed,
		"",
		'latin'
	},
	["Smith's Antiquities"] = {
		"1999.04.0063",
		nil,
		lower_dashed,
		'-cn',
		'latin'
	},
	["Smith's Persons"] = {
		"1999.04.0104",
		nil,
		lower_dashed,
		'-bio-1',
		'latin'
	},
	["Smith's Geography"] = {
		"1999.04.0064",
		nil,
		lower_dashed,
		'-geo',
		'latin'
	},
	["LSJ"] = {
		"1999.04.0057",
		"LSJ",
		nil,
		nil,
		'greek'
	},
	["Middle Liddell"] = {
		"1999.04.0058",
		"ML",
		nil,
		nil,
		'greek'
	},
	["Harpocration"] = {
		"2013.01.0002",
		nil,
		function(w)
			return lower_dashed(remove_diacritics(w))
		end,
		"",
		'greek'
	},
	["Autenrieth"] = {
		"1999.04.0073",
		"Autenrieth",
		nil,
		nil,
		'greek'
	},
	["Slater"] = {
		"1999.04.0072",
		"Slater",
		nil,
		nil,
		"greek"
	},
	["Zoega"] = {
		"2003.02.0002",
		"Zoega",
		nil,
		nil,
		'non'
	},
}

local function get_language(template)
	return resources[template][5]
end

local function is_collision(x, template)
	local collisions_data = resources[template][2]
	local lhs_postprocess = resources[template][3] or x
	if collisions_data then
		return mw.loadData("Module:R:Perseus/collision-data/" .. resources[template][2])[lhs_postprocess] == true
	end
end

local function format_perseus_url(title, beta_or_latin, template, redirect)
	local harpo = template == 'Harpocration' and ":letter="..string.upper(string.sub(remove_diacritics(beta_or_latin),1,1)) or ""
	local resource = resources[template][1] or ''
	local url_redirect_lhs = 'http://www.perseus.tufts.edu/hopper/resolveform?type=exact&lookup='
	local url_entry_lhs = 'http://www.perseus.tufts.edu/hopper/text?doc=Perseus:text:'..resource..harpo..':entry='
	local url_rhs = redirect and '&lang='..get_language(template) or ''
	local postprocess
	if resources[template][3] ~= nil then
		postprocess =
			function(w)
				return resources[template][3](w)..(resources[template][4] or '')
			end
	else
		postprocess =
			function(w)
				return w
			end
	end
	return (redirect and url_redirect_lhs or url_entry_lhs)..postprocess(beta_or_latin)..url_rhs
end

local function is_polytonic(text)
	local lang = m_languages.getByCode("grc")
	if m_scripts.findBestScript(text, lang):getCode() == "polytonic" then
		return true
	else
		return false
	end
end

local function format_perseus_wikilink(title, beta_or_latin, template, redirect)
	local title_span = title
	
	if get_language(template) == 'greek' then
		if not is_polytonic(title_span) then
			-- [[Special:WhatLinksHere/Template:tracking/R:Perseus/wrong-script]]
			require("Module:debug").track('R:Perseus/wrong-script')
		end
		title_span = tag_greek(title_span)
	elseif get_language(template) == 'latin' then
		title_span = tag_latin(title_span)
	end
	return (
		beta_or_latin == '' and ''
		or '[' .. format_perseus_url(title, beta_or_latin, template, redirect) .. ' ' .. title_span .. '] dalam '
		)
end

local function f_word_perseus(arg1, word, force_word, latin)
	if latin then ---FOR LATIN TEMPLATES:
		return word		--latin template arguments sent directly to perseus
	else          ---FOR GREEK TEMPLATES:
		if arg1 and not is_polytonic(arg1) then
			-- Non-polytonic first arguments for greek templates are beta code; send directly to perseus.
			return arg1
		else 
			if force_word then 
				-- 'w' arguments sent directly to perseus unless arg1 is present
				return word
			else 
				-- otherwise polytonic; convert to beta-code and send to perseus
				return beta(word)
			end
		end
	end
end

local function f_word_display(arg1, force_word, latin)
	if force_word then 
		return force_word  -- 'w' argument is always the display word
	else
		if arg1 and (latin or is_polytonic(arg1)) then
			--[[	If no 'w' argument, arg1 is the display word unless it is beta-code
					(i.e., either if arg1 is polytonic, or if the calling template is Latin).	]]
			return arg1
		else
			-- otherwise, no explicit display-word, so use the title
			return mw.title.getCurrentTitle().text
		end
	end
end

function export.create(frame)
	local params = {
		[1] = {},
		[2] = {},
		["w"] = {},
	}
	local args = m_params.process(frame:getParent().args, params)
	local template = string.gsub(frame:getParent():getTitle(), "^Templat:R:", "")
	local latin = not (get_language(template) == 'greek')
	local word = args['w'] or args[2] or args[1] or mw.title.getCurrentTitle().text
	local word_display = f_word_display(args[1], args['w'], latin)
	local word_perseus = f_word_perseus(args[1], word, args['w'], latin)
	
	local redirect = is_collision(word,template) and not args[1] and not args['w']
	
	if word_display == template then
		return "" 
	else 
		return format_perseus_wikilink(word_display, word_perseus, template, redirect)
	end
end

return export