local p = {}

local variants = {hk = 1, jp = 2, us = 3}

local tileData = {
--               Uni-  Western name       Japanese name 
-- Name in MPSZ  code  for tooltip        iff useful    Reserved  Standard, JP, US images
	_1m = {'1m', '🀇', '1 crak',          '1 man',      nil,      'MJw1'},
	_2m = {'2m', '🀈', '2 craks',         '2 man',      nil,      'MJw2'},
	_3m = {'3m', '🀉', '3 craks',         '3 man',      nil,      'MJw3'},
	_4m = {'4m', '🀊', '4 craks',         '4 man',      nil,      'MJw4'},
	_5m = {'5m', '🀋', '5 craks',         '5 man',      nil,      'MJw5'},
	_6m = {'6m', '🀌', '6 craks',         '6 man',      nil,      'MJw6'},
	_7m = {'7m', '🀍', '7 craks',         '7 man',      nil,      'MJw7'},
	_8m = {'8m', '🀎', '8 craks',         '8 man',      nil,      'MJw8'},
	_9m = {'9m', '🀏', '9 craks',         '9 man',      nil,      'MJw9'},
	_1p = {'1p', '🀙', '1 dot',           '1 pin',      nil,      'MJt1', 'MJt1bv1', 'MJt1b'},
	_2p = {'2p', '🀚', '2 dots',          '2 pin',      nil,      'MJt2', 'MJt2b'},
	_3p = {'3p', '🀛', '3 dots',          '3 pin',      nil,      'MJt3', 'MJt3b'},
	_4p = {'4p', '🀜', '4 dots',          '4 pin',      nil,      'MJt4', 'MJt4b'},
	_5p = {'5p', '🀝', '5 dots',          '5 pin',      nil,      'MJt5', 'MJt5b'},
	_6p = {'6p', '🀞', '6 dots',          '6 pin',      nil,      'MJt6', 'MJt6b'},
	_7p = {'7p', '🀟', '7 dots',          '7 pin',      nil,      'MJt7', 'MJt7b'},
	_8p = {'8p', '🀠', '8 dots',          '8 pin',      nil,      'MJt8'},
	_9p = {'9p', '🀡', '9 dots',          '9 pin',      nil,      'MJt9', 'MJt9b'},
	_1s = {'1s', '🀐', '1 bam',           '1 sō',       nil,      'MJs1', 'MJs1b', 'MJs1b8'},
	_2s = {'2s', '🀑', '2 bams',          '2 sō',       nil,      'MJs2', nil, 'MJs2b'},
	_3s = {'3s', '🀒', '3 bams',          '3 sō',       nil,      'MJs3', nil, 'MJs3b'},
	_4s = {'4s', '🀓', '4 bams',          '4 sō',       nil,      'MJs4', nil, 'MJs4b'},
	_5s = {'5s', '🀔', '5 bams',          '5 sō',       nil,      'MJs5', nil, 'MJs5b'},
	_6s = {'6s', '🀕', '6 bams',          '6 sō',       nil,      'MJs6', nil, 'MJs6b'},
	_7s = {'7s', '🀖', '7 bams',          '7 sō',       nil,      'MJs7b', 'MJs7'},
	_8s = {'8s', '🀗', '8 bams',          '8 sō',       nil,      'MJs8', nil, 'MJs8b'},
	_9s = {'9s', '🀘', '9 bams',          '9 sō',       nil,      'MJs9', nil, 'MJs9b'},
	_1z = {'1z', '🀀', 'east',            nil,          nil,      'MJf1'},
	_2z = {'2z', '🀁', 'south',           nil,          nil,      'MJf2'},
	_3z = {'3z', '🀂', 'west',            nil,          nil,      'MJf3'},
	_4z = {'4z', '🀃', 'north',           nil,          nil,      'MJf4'},
	_5z = {'5z', '🀆', 'white',           nil,          nil,      'MJd3', 'MJd3e', 'MJd3b'},
	_6z = {'6z', '🀅', 'green',           nil,          nil,      'MJd2', 'MJd2v1', 'MJd2v3'},
	_7z = {'7z', '🀄︎', 'red',             nil,          nil,      'MJd1', nil, 'MJd1v2'},
	_1q = {'1q', '🀦', 'spring',          nil,          nil,      'MJh1'},
	_2q = {'2q', '🀧', 'summer',          nil,          nil,      'MJh2'},
	_3q = {'3q', '🀨', 'autumn',          nil,          nil,      'MJh3'},
	_4q = {'4q', '🀩', 'winter',          nil,          nil,      'MJh4'},
	_5q = {'5q', '🀢', 'plum',            nil,          nil,      'MJh5'},
	_6q = {'6q', '🀣', 'orchid',          nil,          nil,      'MJh6'},
	_7q = {'7q', '🀤', 'chrysanthemum',   nil,          nil,      'MJh7'},
	_8q = {'8q', '🀥', 'bamboo',          nil,          nil,      'MJh8'},
	
	_x  = {'X',  '🀫', 'tile back',       nil,          nil,      'MJhide'},
	_q  = {'?',  '🀫', 'unspecified tile',nil,          nil,      'MJxx-'}, -- Do not remove hyphen-minus (not a mistake)
	
	-- Used in variants only
	_J  = {'J',  '🀪', 'joker',           nil,          nil,      'MJj1v1-'}, -- Do not remove hyphen-minus (not a mistake)
	_0m = {'0m', '🀋', 'red 5 man',       nil,          nil,      'MJw5r'},
	_0p = {'0p', '🀝', 'red 5 pin',       nil,          nil,      'MJt5r'},
	_0s = {'0s', '🀔', 'red 5 sō',        nil,          nil,      'MJs5r'}
}
--[[
	Images are selected depending on the variant. If none is specified for the
	chosen variant, fall back to the standard image.
	
	A suffix, and then filetype, are added to the filename depending on how
	specifically the tile needs to be drawn. The files are named systematically.
	
	Players of Japanese mahjong will better understand man/pin/sō than crak/dot/bam.
	Using Japanese names of honors would not help most readers.
]]

-- Simple column names for the above table
local MPSZID = 1 -- not used directly right now
local UNICODE = 2
local SCREENREADER_NAME = 3
local SCREENREADER_NAME_JP = 4
local IMAGE = 6
local IMAGE_JP = 7
local IMAGE_US = 8

-- Screen reader descriptions to show only when the arguments call for one, large tile image.
local singleTileAlts = {
	MJw1 = 'A mahjong tile with the traditional Chinese characters 一 (blue) over 萬 (red).',
	MJw2 = 'A mahjong tile with the traditional Chinese characters 二 (blue) over 萬 (red).',
	MJw3 = 'A mahjong tile with the traditional Chinese characters 三 (blue) over 萬 (red).',
	MJw4 = 'A mahjong tile with the traditional Chinese characters 四 (blue) over 萬 (red).',
	MJw5 = 'A mahjong tile with the traditional Chinese characters 五 (blue) over 萬 (red).',
	MJw6 = 'A mahjong tile with the traditional Chinese characters 六 (blue) over 萬 (red).',
	MJw7 = 'A mahjong tile with the traditional Chinese characters 七 (blue) over 萬 (red).',
	MJw8 = 'A mahjong tile with the traditional Chinese characters 八 (blue) over 萬 (red).',
	MJw9 = 'A mahjong tile with the traditional Chinese characters 九 (blue) over 萬 (red).',
	MJt1 = 'A mahjong tile with a large circle, filled with smaller concentric circles of different colors and a floral pattern.',
	MJt1bv1 = 'A mahjong tile with a large blue circle, filled with smaller concentric circles and red in the center.',
	MJt1b = 'A mahjong tile with a large circle, filled with smaller concentric circles of different colors and a floral pattern.',
	MJt2 = 'A mahjong tile with a blue circle positioned above a green circle.',
	MJt2b = 'A mahjong tile with two blue circles arranged vertically.',
	MJt3 = 'A mahjong tile with three circles, in blue, red and green, diagonal from top left to bottom right.',
	MJt3b = 'A mahjong tile with three circles, in blue, red and blue, diagonal from top left to bottom right.',
	MJt4 = 'A mahjong tile with four circles in alternating blue and green colors.',
	MJt4b = 'A mahjong tile with four blue circles.',
	MJt5 = 'A mahjong tile with five circles in alternating blue and green colors; the red central circle is surrounded.',
	MJt5b = 'A mahjong tile with five circles; the red central circle is surrounded by four blue circles.',
	MJt6 = 'A mahjong tile with six circles in two columns of three. They are red, except for the top row, in green.',
	MJt6b = 'A mahjong tile with six circles in two columns of three. They are red, except for the top row, in blue.',
	MJt7 = 'A mahjong tile with seven circles; a square of four red circles below a diagonal row of three green circles.',
	MJt7b = 'A mahjong tile with seven circles; a square of four red circles below a diagonal row of three blue circles.',
	MJt8 = 'A mahjong tile with eight blue circles in two columns of four.',
	MJt9 = 'A mahjong tile with nine circles in three rows of three. The rows are colored blue, then red, then green.',
	MJt9b = 'A mahjong tile with nine circles in three rows of three. The circles are blue, except for the red middle row.',
	MJs1 = 'A mahjong tile with an abstract line drawing of a small bird perched on a horizontal branch.',
	MJs1b = 'A mahjong tile with a green peacock-like bird. Its blue tail feathers, speckled with red, fill the top half of the tile.',
	MJs1b1 = 'A mahjong tile with a blue peacock-like bird. Its green tail feathers, speckled with red, fill the top half of the tile.',
	MJs1b8 = 'A mahjong tile with an abstract line drawing of a small red bird perched on a diagonal branch.',
	Mjs2 = 'A mahjong tile with two green sticks arranged vertically.',
	Mjs2b = 'A mahjong tile with two sticks arranged vertically. A blue stick stands above a green stick.',
	Mjs3 = 'A mahjong tile with three vertical green sticks. One is above, while two side-by-side are below.',
	Mjs3b = 'A mahjong tile with three vertical sticks. A blue one is above, with two green ones side-by-side below.',
	Mjs4 = 'A mahjong tile with four vertical green sticks arranged in two columns of two.',
	Mjs4b = 'A mahjong tile with four vertical sticks arranged in two rows of two. The top row is blue and the bottom row is green.',
	Mjs5 = 'A mahjong tile with vertical green sticks arranged in two columns of two, flanking a red, fifth stick in the center.',
	Mjs5b = 'A mahjong tile with vertical sticks arranged in two rows of two, in alternating blue and green. There is a red, fifth stick in the center.',
	Mjs6 = 'A mahjong tile with six vertical green sticks, in two rows of three.',
	Mjs6b = 'A mahjong tile with six vertical sticks, in two rows of three. The top row is blue and the bottom row is green.',
	Mjs7 = 'A mahjong tile with seven vertical sticks. A red stick stands above three columns of two green sticks each.',
	Mjs7b = 'A mahjong tile with seven vertical sticks. A red stick stands above three columns of two sticks each. These columns are green, blue, and green.',
	Mjs8 = 'A mahjong tile with eight green sticks. Four are arranged in a diamond shape around the center, and four more stand vertically, two on each side.',
	Mjs8b = 'A mahjong tile with eight sticks. Four are arranged in a diamond shape around the center, and four more stand vertically, two on each side. The four in the top half of the tile are blue and the other four are green.',
	Mjs9 = 'A mahjong tile with nine sticks arranged in three columns of three. The sticks are green, except for the red ones in the middle column.',
	Mjs9b = 'A mahjong tile with nine sticks arranged in three columns of three. The columns are colored green, red and blue.',
	Mjf1 = 'A mahjong tile with the blue traditional Chinese character 東.',
	Mjf2 = 'A mahjong tile with the blue traditional Chinese character 南.',
	Mjf3 = 'A mahjong tile with the blue traditional Chinese character 西.',
	Mjf4 = 'A mahjong tile with the blue traditional Chinese character 北.',
	Mjd1 = 'A mahjong tile with the red traditional Chinese character 中.',
	Mjd1v2 = 'A mahjong tile with a red dragon.',
	Mjd2 = 'A mahjong tile with the green traditional Chinese character 發.',
	Mjd2v1 = 'A mahjong tile with the green traditional Chinese character 發. The 殳 element is replaced by 矢.',
	Mjd2v3 = 'A mahjong tile with a green dragon.',
	Mjd3 = 'A mahjong tile with a blue frame.',
	Mjd3b = 'A mahjong tile with a blue frame.',
	Mjd3e = 'A blank mahjong tile.',
	Mjh1 = 'A mahjong tile, labelled 1 春, with three tulips and a butterfly.',
	Mjh2 = 'A mahjong tile, labelled 2 夏, with a lotus and three small lilypads.',
	Mjh3 = 'A mahjong tile, labelled 3 秋, with three partially peeled fruits. A central, prominent fruit appears to be an orange.',
	Mjh4 = 'A mahjong tile, labelled 4 冬, with three daffodils.',
	Mjh5 = 'A mahjong tile, labelled 梅 1, with a large plum blossom.',
	Mjh6 = 'A mahjong tile, labelled 蘭 2, with a large orchid bulb.',
	Mjh7 = 'A mahjong tile, labelled 菊 3, with a large chrysanthemum flower.',
	Mjh8 = 'A mahjong tile, labelled 竹 4, with a closeup of a standing bamboo shoot. Leafy branches protrude from the shoot.',
	MJw5r = 'A mahjong tile with the traditional Chinese characters 五 over 萬 (both red).',
	MJt5r = 'A mahjong tile with five red circles. One central circle is surrounded by the other four.',
	MJs5r = 'A mahjong tile with vertical red sticks arranged in two columns of two, flanking a fifth stick in the center.',
	MJj1v1 = 'A mahjong tile with a green line drawing of a fish-like creature inside a blue circle, under a red "JOKER" label.',
	MJxx = 'A mahjong tile overlaid with a question mark.',
	MJhide = 'The reverse side of a mahjong tile.'
}

p.main = function(frame)
	local pargs = frame:getParent().args
	
	-- If {{{1}}} is a variant (hk, us, jp) take note of that and use {{{2}}} for the tiles.
	-- Otherwise, {{{1}}} is the tiles and just go with basic mahjong.
	local variant = pargs[1] or ''
	local mpsz = pargs[2] or ''
	
	if #mpsz == 0 then
		if #variant == 0 then
			-- Long ago, {{mahjong}} used to be a navbox, so let's not show an error if
			-- it's called with no arguments (it'd be in a lot of old page revisions).
			return ''
		end
		if not variants[variant] then
			mpsz = variant
			variant = 'hk' -- Default to "basic" Hong Kong style.
		else
			-- There are no tiles at all...
			return ''
		end
	end
	
	local root = mw.html.create(pargs['big'] and 'div' or 'span')
		:addClass('nowrap')
		:css('font-size', '0')
	
	-- Treat dash separators as their own "groups" for our loop
	mpsz = mpsz:gsub('-+',' - ')
	
	-- Are we drawing just one big tile?
	local bigDemo = false
	if pargs['big'] and (mpsz == 'X' or mpsz == '?' or tileData['_' .. mpsz]) then
		bigDemo = true
	else
		-- Get ready to be a container for overlaid images.
		if pargs['big'] then
			root:css('vertical-align','bottom')
		else
			root:css('padding-right', '4px')
				:css('position','relative')
				:css('top','-6px')
				:css('margin-bottom','-10px')
				:css('display','inline-block')
		end
		root:attr('role','text')
	end
	
	local a = ''
	for i in mpsz:gmatch('[^ ]+') do
		local suit = i:sub(-1)
		
		if suit == '-' then
			-- This is a spacer
			root:tag('span')
				:css('display','inline-block')
				:css('width',pargs['big'] and '12px' or '6px')
				:wikitext(' ')
		end
		
		if ('mpszX?qJ@'):find(suit) then -- It's a valid character to end a group on, isn't it?
			if suit == 'X' or suit == '?' or suit == 'J' then
				-- assert that mpsz only contains X/?/J
			end
			
			for tile in i:gmatch('[0123456789X%?J][\'"]?@?') do
				local filename = ''
				local alt = ''
				local modifier = tile:sub(-1)
				local ctrwidth = pargs['big'] and '36px' or '16px'
				local width = pargs['big'] and '45px' or '20px'
				local gray = false
				
				if modifier == '@' then
					gray = true
					tile = tile:sub(1,-2)
					modifier = tile:sub(-1)
				end
				
				-- Why is it that whenever there's some ugly looking code, it's always you three?
				if tile:sub(1,1) == 'X' then
					tile = '_x'
				elseif tile:sub(1,1) == '?' then
					tile = '_q'
				elseif tile:sub(1,1) == 'J' then
					tile = '_J'
				else
					tile = '_' .. tile:sub(1,1) .. suit
				end
				
				filename = tileData[tile][IMAGE]
				alt = tileData[tile][UNICODE] -- Select as the unicode tile, in case this is inline.
				if variant == 'us' then
					filename = tileData[tile][IMAGE_US] or filename
				end
				if tile ~= '_x' and tile ~= '_q' and tile ~= '_J' then
					if variant == 'jp' then
						-- Since it's Japanese mahjong, we have to account for the complicated rules.
						filename = tileData[tile][IMAGE_JP] or filename -- Use JP image, if it's different
						
						if (modifier == "'") then
							-- This tile needs to be tilted sideways, so prepare accordingly
							width = pargs['big'] and '54px' or '24px'
							ctrwidth = pargs['big'] and '45px' or '20px'
							filename = filename .. '-x'
						elseif modifier == '"' then
							-- This tile is going to be a stack of two, sideways tiles.
							width = pargs['big'] and '54px' or '24px'
							ctrwidth = pargs['big'] and '45px' or '20px'
							filename = filename .. (tile:sub(2,2) == '0' and '-=' or '=')
							alt = alt .. alt -- There's two now
						else
							filename = filename .. '-' -- Not sideways.
						end
						-- Sorry, one hopefully temporary bandaid.
						-- JP peacock feathers should probably be green, but the rotations don't have that.
						if filename == 'MJs1b-' then filename = 'MJs1b1-' end
					else
						filename = filename .. '-' -- Not Japanese, not sideways.
					end
				end
				
				if bigDemo then
					-- This is a big tile, and it's just one.
					ctrwidth = '' -- Do not try to accommodate a second tile
					alt = singleTileAlts[filename:gsub('%-','')] or alt -- Use very descriptive alt text
				end
				
				-- Add the tile to the page
				local tileSpan = root:tag('span')
					:css('display', 'inline-block')
					:css('filter', gray and 'brightness(80%)' or 'brightness(100%)') -- Gotta have both
					:wikitext(table.concat({
						'[[File:', filename, '.svg|', width,
						bigDemo and '' or '|link=', -- Suppress link for groups of tiles or small tiles
						'|alt=', alt,
						'|class=notpageimage]]'
					}))
				if #ctrwidth then
					tileSpan:css('width', ctrwidth)
				end
				if variant == 'jp' and pargs['big'] and modifier == "'" then
					-- Improve the appearance of Japanese calls
					tileSpan:css('height', '36px')
							:css('padding-top', '10px')
							:css('vertical-align', 'top')
				end
			end
		else
			-- This group doesn't have a valid suit! Complain about it.
		end
	end
	
	if pargs['big'] then
		return tostring(root)
	else
		-- For inline tiles, add word joiners so that they stick to parentheses
		return '⁠' .. tostring(root) .. '⁠'
	end
end
return p