--!strict


return function(TextService)
	--[[
		Takes a string and converts it into pages of text that fit within the given constraints

		Parameters:
		text: The text to paginate
		containerHeight: The height of the container the text should fit into
		containerWidth: The width of the container the text should fit into
		textSize: The size of the text
		font: The font used to display the text

		Returns:
		An array of strings representing the pages of text
	]]
	local function paginate(
		text: string,
		containerHeight: number,
		containerWidth: number,
		textSize: number,
		font: Enum.Font
	): { string }
		local paginatedText = {}

		local textBounds = Vector2.new(containerWidth, math.huge)

		-- Add to the string until it is too large, then paginate and start again
		local workingString = ""
		local word = ""

		if text:find(" ") then
			-- Iterate over words
			for first, last in utf8.graphemes(text) do
				local grapheme = text:sub(first, last)

				if grapheme:match("%s") then
					-- See if this word pushes the text size over the limit
					local newString = workingString .. word
					local bounds = TextService:GetTextSize(newString, textSize, font, textBounds)

					if bounds.Y > containerHeight then
						-- If the word made workingString go over the limit,
						-- add the workingString without the word
						table.insert(paginatedText, workingString)

						-- Set the new working string to the word
						workingString = word
					else
						-- Otherwise add the word to the workingString
						workingString = newString
					end

					word = grapheme
				else
					word = word .. grapheme
				end
			end

			-- Add the remaining words to the paginated list
			local newString = workingString .. word
			local bounds = TextService:GetTextSize(newString, textSize, font, textBounds)
			if bounds.Y > containerHeight then
				table.insert(paginatedText, workingString)
				table.insert(paginatedText, word)
			else
				table.insert(paginatedText, newString)
			end
		else
			-- Iterate over graphemes
			for first, last in utf8.graphemes(text) do
				local grapheme = text:sub(first, last)

				local newString = workingString .. grapheme
				local bounds = TextService:GetTextSize(newString, textSize, font, textBounds)
				if bounds.Y > containerHeight then
					table.insert(paginatedText, workingString)
					workingString = grapheme
				else
					workingString = newString
				end
			end

			table.insert(paginatedText, workingString)
		end

		return paginatedText
	end

	return paginate
end
