local categoryData = require("Module:Storm categories/categories")
local colors = require("Module:Storm categories/colors").colors
local icons = require("Module:Storm categories/icons").icons
local cats = categoryData.cats
local defaultCategory = categoryData.defaultCategory
local p = {}

function p.color(frame)
	return p._color(frame.args[1] or frame:getParent().args[1], false)
end

function p.name(frame)
	return p._name(
		frame.args[1] or frame:getParent().args[1],
		frame.args[2] or frame:getParent().args[2],
		false
	)
end

function p.sortkey(frame)
	return p._sortkey(frame.args[1] or frame:getParent().args[1], false)
end

function p.icon(frame)
	return p._icon(frame.args[1] or frame:getParent().args[1], false)
end

function p._color(colorCode, nullIfMissing)
	-- This looks confusing, but it's actually nested ternaries (for nil checks)
	local color = (colorCode ~= nil and string.len(colorCode) ~= 0) and 
		string.gsub(string.lower(colorCode), "[^%w]", "")
		or defaultCategory
		
	return colors[color] or ((cats[color] or (
		nullIfMissing
		and { color = nil }
		or cats[defaultCategory]
	)).color)
end

function p._name(category, basin, nullIfMissing)
	local name_def = (cats[
		(category ~= nil and string.len(category) ~= 0) and 
			string.gsub(string.lower(category), "[^%w]", "")
			or defaultCategory
	] or cats[defaultCategory]).name
	return type(name_def) == "table" and 
		(
			name_def[string.lower(basin or "default")]
			or name_def["default"]
			or (nullIfMissing and nil or error("No default name for basin-based category name."))
		) 
		or name_def
end

function p._sortkey(category, nullIfMissing)
	-- This looks confusing, but it's actually nested ternaries (for nil checks)
	return (cats[
		(category ~= nil and string.len(category) ~= 0) and 
			string.gsub(string.lower(category), "[^%w]", "")
			or defaultCategory
	] or (nullIfMissing and { sortkey = nil } or cats[defaultCategory])).sortkey
end

function p._icon(iconCode, nullIfMissing)
	-- This looks confusing, but it's actually nested ternaries (for nil checks)
	local icon = (iconCode ~= nil and string.len(iconCode) ~= 0) and 
		string.gsub(string.lower(iconCode), "[^%w]", "")
		or defaultCategory
		
	return icons[icon] or (cats[icon] ~= nil and (
		cats[icon].icon or cats["tropicalcyclone"].icon
	) or (nullIfMissing and nil or cats[defaultCategory].icon))
end

function p.demo(frame)
	return require("Module:Storm categories/demo").demo(frame)
end

return p