local p = {}

-- use mw.html?

local _ppoem = require("Module:Ppoem")._ppoem
local getArgs = require("Module:Arguments").getArgs

function p._tpp(args)
	local res = ""
	-- if not args.text and not args[2] then args[1] is assumed to be the text, but args.title will always be the title.
	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="ws-poem-tpp-title">' .. args.title .. '</div>'
	end
	if args.quote then
		args.text = args.quote .. "\n>><<\n" .. args.text
	end
	if args.text then
		local newArgs = {}
		for k, v in pairs(args) do
			if 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
				-- do nothing
			else
				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", true)
		for k, v in pairs(poems) do
			local paddingleft = 0
			v = string.gsub(v, "%^>", "+2>")
			v = string.gsub(v, "+>", "+1>")
			local t = mw.text.split(v, "\n", true)
			if k == 1 then
				newArgs.start = args.start
			else
				newArgs.start = nil
			end
			if k == #poems then
				newArgs["end"] = args["end"]
				if args["end"] == nil then
					newArgs.class = args.class
				elseif mw.title.getCurrentTitle().nsText ~= "page" then
					newArgs.class = "ws-poem-tpp-not-first-poem"
				end
			else
				newArgs["end"] = nil
				if args.class then
					newArgs.class = args.class .. " ws-poem-tpp-not-first-poem"
				else
					newArgs.class = "ws-poem-tpp-not-first-poem"
				end
			end
			local parsed = {}
			for a, b in pairs(t) do
				if string.sub(b, 1, 1) == "+" and string.sub(b, 3, 3) == ">" and tonumber(string.sub(b, 2, 2)) and #parsed > tonumber(string.sub(b, 2, 2)) then
					table.insert(parsed, '<span style="visibility:hidden">' .. parsed[#parsed-tonumber(string.sub(b, 2, 2))+1] .. '</span>' .. string.sub(b, 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 mw.ustring.find(b, '^;+') then
						table.insert(parsed, '<span style="margin-left:-' .. tostring(j) .. 'em">' ..  mw.ustring.sub(b, j+1, #b) .. "</span>")
						paddingleft = math.max(paddingleft, j)
				elseif k == 1 and a == 1 and newArgs.start == nil and not (string.match(b, "[><{}%[%]]") or string.match(b, "''")) then -- very hacky, not doing it if there's already HTML/mw formatting
						local i, j = string.find(b, "^.-%a.-%a.- ")
						if j then
							table.insert(parsed, '<span class="ws-tpp-first-words">' .. b:sub(i, j) .. '</span>' .. b:sub(j, #b))
						else
							table.insert(parsed, '<span class="ws-tpp-first-words">' .. b .. '</span>')
						end
				elseif mw.ustring.find(b, "%[<") then
					local temp = mw.text.split(b, "%[<")
					table.insert(parsed, temp[1] .. '<span style="position:absolute;left:0">' .. temp[2] .. '</span>')
				else 
					table.insert(parsed, b)
				end
			end
			if paddingleft ~= 0 then
				if args.style then
					if string.find(args.style, "padding%-left") then
						local oldpadding = mw.text.trim(mw.text.split(mw.text.split(args.style, "padding%-left *:")[2], ";")[1])
						newArgs.style = string.gsub(args.style, "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 #parsed == 1 and (k ~= 1 or newArgs.start == nil) and (k ~= #poems or newArgs["end"] == nil) and parsed[1] ~= "" then
				res = res .. '<div class="ws-poem-tpp-separate-line">' .. parsed[1] .. '</div>' -- no point doing a one-line poem, and this avoids having to put a c for the title, a c for some sort of first-line comment, and then a poem
			elseif 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