local p = {}
local _ppoem = require("Module:Ppoem")._ppoem
local getArgs = require("Module:Arguments").getArgs
function p._tpp(args)
	local res = ""
	args.text = args.text or args[2]
	local notitle = false
	local notext = false
	if not args.text then
		notitle = true
		args.text = args[1]
	end
	if not args.text then
		notext = true
	end
	if not notitle then
		args.title = args.title or args[1]
	end
	args["end"] = args["end"] or args.e
	args.start = args.start or args.st -- s used to be taken
	args.quote = args.quote or args.q
	if args.title and args.title ~= "" then
		res = res .. '<div class="wst-tpp-title">' .. args.title:gsub("\n\n", '<span style="visibility:hidden; line-height:1em;display:block">&nbsp;</span>') .. '</div>'
	end
	if args.quote then -- for backwards compatibility
		args.text = args.quote .. "\n>><<\n" .. args.text
	end
	if args.text then
		local newArgs = {}
		for k, v in pairs(args) do
			if not (k == "text" or k == "title" or k == 1  or k == "quote" or k == "q" or k == "e" or k == "s" or k == "size" or k == "st" or k == 2 or k == "start" or k == "end") then
				newArgs[k] = v -- pass on every other parameter (ppoem's got a lot of them)
			end
		end
		local poems = mw.text.split(args.text, "\n>><<\n", true)
		for k, v in pairs(poems) do
			local paddingleft = 0
			v = (v:gsub("%^>", "+2>")):gsub("+>", "+1>")
			local t = mw.text.split(v, "\n", true)
			newArgs.class = args.class or ""
			if k == 1 then
				newArgs.start = args.start
			else
				newArgs.start = nil
				newArgs.class = newArgs.class .. " wst-tpp-not-first-poem"
			end
			if k == #poems then
				newArgs["end"] = args["end"]
			else
				newArgs["end"] = nil
			end
			local parsed = {}
			for a, b in pairs(t) do
				if b:sub(1, 1) == "+" and b:sub(3, 3) == ">" and tonumber(b:sub(2, 2)) and #parsed >= tonumber(b:sub(2, 2)) then
					table.insert(parsed, '<span style="visibility:hidden">' .. parsed[#parsed-tonumber(b:sub(2, 2))+1] .. '</span>' .. b:sub(4, #b))
				elseif mw.ustring.find(b, "^_+$") then
					for i=1,#b-1,1 do
						table.insert(parsed, '<span style="visibility:hidden>&nbsp;</span>')
					end
					table.insert(parsed, "")
				elseif b:find('^;+') then
						local i, j = b:find('^;+')
						table.insert(parsed, '<span style="margin-left:-' .. tostring(j) .. 'em">' ..  b:sub(j+1, #b) .. "</span>")
						paddingleft = math.max(paddingleft, j)
				elseif k == 1 and a == 1 and newArgs.start == nil and not (b:match("[><{}]") or b:match("''") or b:match("%[%[")) then -- very hacky, not doing it if there's already HTML/mw/ppoem formatting
						local _, firstletter = b:find("^[^%a]*")
						firstletter = (firstletter or 0) + 1
						local _, enough = b:find("^.-%a.-%a.- ")
						enough = enough or #b
						table.insert(parsed, b:sub(1, firstletter-1) .. '<span class="wst-tpp-first-words">' .. b:sub(firstletter, enough) .. '</span>' .. b:sub(enough+1, #b))
				else
					table.insert(parsed, b)
				end
			end
			if paddingleft ~= 0 then
				if args.style then
					if args.style:find("padding%-left") then
						local oldpadding = mw.text.trim(mw.text.split(mw.text.split(args.style, "padding%-left *:")[2], ";")[1])
						newArgs.style = args.style:gsub("padding%-left:.-;", "") .. ";padding-left:calc(" .. tostring(paddingleft) .. "em + " .. oldpadding .. ");"
					else
						newArgs.style = args.style .. ";padding-left:" .. tostring(paddingleft) .. "em;"
					end
				else
					newArgs.style = "padding-left:" .. tostring(paddingleft) .. "em;"
				end
			else
				newArgs.style = args.style
			end
			newArgs[1] = table.concat(parsed, "\n")
			if newArgs[1] ~= "" then
				res = res .. _ppoem(newArgs)
			end
		end
	end
	return res
end
function p.tpp(frame)
	local args = getArgs(frame)
	return p._tpp(args)
end
return p