--[[  
  __  __           _       _        _   _                      
 |  \/  | ___   __| |_   _| | ___ _| \ | | __ _ _ __ ___   ___ 
 | |\/| |/ _ \ / _` | | | | |/ _ (_)  \| |/ _` | '_ ` _ \ / _ \
 | |  | | (_) | (_| | |_| | |  __/_| |\  | (_| | | | | | |  __/
 |_|  |_|\___/ \__,_|\__,_|_|\___(_)_| \_|\__,_|_| |_| |_|\___|
    
This module is intended for processing of people names.

Please do not modify this code without applying the changes first at Module:Name/sandbox and testing 
at Module:Name/sandbox/testcases

Authors and maintainers:
* User:Zolo - original version
* User:Jarekt - rewrite
]]

-- =======================================
-- === Dependencies ======================
-- =======================================
local i18n = require('Module:I18n/name')
local core = require('Module:Core')
local p = {}

-- lazy loading (load only if needed)
local function lang_of(name, lang)
	return require('Module:Linguistic').of(name, lang)
end

-- ===========================================================================
-- === Version of the function to be called from other LUA codes
-- ===========================================================================
function p._name(operation, base_name, lang)
  -- Error checking on "operation" parameter
	if operation == '' or base_name == '' then -- no operation provided -> return the name
		return base_name
	end
	operation = mw.ustring.lower(operation) -- convert operation to lower case
	if not i18n[operation] then -- if operation is not recognized than maybe it is an alias
		operation = i18n.Aliases[operation]
	end
	if not i18n[operation] then -- operation is still not recognized
		return "name not supported"
	end
	local colon = tostring(mw.message.new('colon'):inLanguage(lang))
	
	-- translation through Wikidata q-code
	if type(i18n[operation])=='string' then 
		-- usually operation is a translation table, but if it is a string than that is
		-- a wikidata q-code, so look up the label stored in wikidata
		return core.getLabel(i18n[operation], lang) .. colon .. base_name
	end
	
	-- translation through local LangSwitch which return language specific function or string
	local command = core.langSwitch(i18n[operation], lang)
	local full_name, part
	if type(command)=='function' then
		full_name = command(base_name)
	elseif type(command)=='string' then
		--command = mw.getLanguage(lang):ucfirst(command)
		command = mw.getCurrentFrame():callParserFunction( "ucfirst", { command } )
		if mw.ustring.find(command, '$of_name') then -- forms like Master of X
			base_name = lang_of(base_name, lang)
			part = mw.text.split(' '..command..' ', '$of_name', true )
			full_name = mw.text.trim(part[1] .. base_name .. part[2])
		elseif mw.ustring.find(command, '$name') then -- forms like Master X
			-- replace parts of the string '$name' with base_name strings
			part = mw.text.split(' '..command..' ', '$name', true )
			full_name = mw.text.trim(part[1] .. base_name .. part[2])
		else -- forms like Pseudonym: base_name, with a colon
			full_name = command .. colon .. base_name
		end
	end
	return full_name
end

-- ===========================================================================
-- === Functions to be called from template namespace
-- ===========================================================================
function p.name(frame)
	local args = core.getArgs(frame)
	local base_name = args.name or ''
	-- handle case where there is no "name" parameter but chinese names
	if base_name=='' and (args.trad or args.simp or args.PY) then
		 local Func = core.langSwitch(i18n.Chinese_name, args.lang)
		 base_name = Func(args.trad or '', args.simp or '', args.PY or '')
	end
	return p._name(args.operation or '', base_name, args.lang)
end

return p