local core = require("core")
local command = require("core.command")
-- Text cursor translation helpers are scoped under core.text
local translate = require("core.text.translate")

local function gmatch_to_array(text, ptn)
	local res = {}
	for x in text:gmatch(ptn) do
		table.insert(res, x)
	end
	return res
end

local function tabularize_lines(lines, delim)
	local rows = {}
	local cols = {}

	-- split lines at delimiters and get maximum width of columns
	local ptn = "[^" .. delim:sub(1, 1):gsub("%W", "%%%1") .. "]+"
	for i, line in ipairs(lines) do
		rows[i] = gmatch_to_array(line, ptn)
		for j, col in ipairs(rows[i]) do
			cols[j] = math.max(#col, cols[j] or 0)
		end
	end

	-- pad columns with space
	for _, row in ipairs(rows) do
		for i = 1, #row - 1 do
			row[i] = row[i] .. string.rep(" ", cols[i] - #row[i])
		end
	end

	-- write columns back to lines array
	for i, line in ipairs(lines) do
		lines[i] = table.concat(rows[i], delim)
	end
end

command.add({
	["tabularize:tabularize"] = {
		requires = { "doc", "edit" },
		perform = function()
		core.command_view:enter({
			caption = "Tabularize On Delimiter",
			submit = function(delim)
			if delim == "" then
				delim = " "
			end

			local doc = core.active_view.doc
			local line1, col1, line2, col2, swap = doc:get_selection(true)
			line1, col1 = doc:position_offset(line1, col1, translate.start_of_line)
			line2, col2 = doc:position_offset(line2, col2, translate.end_of_line)
			doc:set_selection(line1, col1, line2, col2, swap)

			doc:replace(function(text)
				local lines = gmatch_to_array(text, "[^\n]*\n?")
				tabularize_lines(lines, delim)
				return table.concat(lines)
			end)
			end,
		})
		end,
	},
})
