require('strict')
local getArgs = require('Module:Arguments').getArgs

local patterns = {
	'(%d+)°(%d+)'([%d%.]+)"([NS]),%s*(%d+)°(%d+)'([%d%.]+)"([EW])',		-- if the returned data looks like 55°13'12"N, 23°17'17"E
	'(%d+)°(%d+)'([NS]),%s*(%d+)°(%d+)'([EW])',									-- if the returned data looks like 54°24'N, 25°25'E
	'(%d+)°(%d+)[′\']([%d%.]+)[″\"]([NS]),?%s*(%d+)°(%d+)[′\']([%d%.]+)[″\"]([EW])',	-- when args[1] is a dms string that uses quotes or primes
	'(%d+)°(%d+)[′\']([NS]),?%s*(%d+)°(%d+)[′\']([EW])',								-- when args[1] is a dms string that uses quotes or primes, bit shorter format
	'(%d+%.?%d*)°([NS]),?%s*(%d+%.?%d*)°([EW])',										-- when args[1] is a decimal degrees string
	}

local params = {'display', 'format', 'name', 'notes'};							-- ((coord)) template paramters


--[[--------------------------< I S _ S E T >------------------------------------------------------------------

Whether variable is set or not.  A variable is set when it is not nil and not empty.

]]

local function is_set( var )
	return not (var == nil or var == '');
end


--[[--------------------------< M A I N >----------------------------------------------------------------------

Template entry point.  This function takes up to two unnamed positional parameters:
	1 = coordinate string typically from a call to Wikidata like this: ((#property:P625|from=Q...))
	2 = coordinate parameters; see Template:Coord
	
Also takes the named parameters |display=, |format=, |name=, |notes= which it passes on to ((coord))

Reformats the Wikidata coordinate string into unnamed parameters for ((coord))

((#invoke:WikidataCoord|main|((#property:P625|from=(({1))))}|(({2))}|display=(({display))}|format=(({format))}|name=(({name))}|notes=(({notes))))}

]]

local function main (frame)
	local args = getArgs(frame);
	local lat_long = {};														-- table of lat/long coords extracted from wikidata return 
	
	if not is_set (args[1]) then												-- in case wikidata returns nothing (happens when Q... is wrong)
		return '<span style="font-size:100%" class="error">((WikidataCoord)) – missing coordinate data</span>';		-- error message and quit
	else
		for _, pattern in ipairs (patterns) do
			lat_long[1], lat_long[2], lat_long[3], lat_long[4], lat_long[5], lat_long[6], lat_long[7], lat_long[8] =
				mw.ustring.match (args[1], pattern)
			if lat_long[1] then
				break;
			end
		end
	end

	if not lat_long[1] then
		return '<span style="font-size:100%" class="error">((WikidataCoord)) – malformed coordinate data</span>';	-- wikidata returned something else
	end
	
	if is_set (args[2]) then													-- coordinate parameters are in second unnammed positional parameter
		table.insert (lat_long, args[2]);										-- add coordinate parameters as next positional parameter after coordnates
	end

	for _, param in ipairs (params) do
		if is_set (args[param]) then
			lat_long[param] = args[param];										-- add the named parameters if they have a value
		end
	end

	if args._debug then
		return table.concat ({'<code style="color:inherit; background:inherit; border:none;">((coord|', table.concat (lat_long, '|' ), '))</code>'});
	end
	return frame:expandTemplate ({title = 'coord', args=lat_long});				-- invoke template ((coord)) with wikidata lat/long
end


--[[--------------------------< E X P O R T E D   F U N C T I O N >--------------------------------------------
]]

return {main = main}