-- lx-bundle:true

-- HTML entity utility commands:
-- - html:encode : encode text using common 5-char HTML entities
-- - html:decode : decode named/numeric entities via lib.entities_decode
local core = require("core")
local command = require("core.command")
local entities_encode = require("plugins.htmlentities.encode")
local entities_decode = require("plugins.htmlentities.decode")

local function notify(msg)
	if core.status_view and core.status_view.show_notice then
		core.status_view:show_notice("html: " .. msg)
	else
		core.log("html: %s", msg)
	end
end

local function transform_doc(doc, fn)
	if not doc then
		return
	end
	if doc:has_selection() then
		doc:replace(function(text)
			local out, err = fn(text)
			if not out then
				notify(err or "operation failed")
				return text
			end
			return out
		end)
		return
	end

	local line, col = doc:get_selection()
	local logical, had_lf = doc:get_logical_line(line)
	local out, err = fn(logical)
	if not out then
		notify(err or "operation failed")
		return
	end
	local end_col = #logical + 1
	if had_lf then
		end_col = end_col + 1
	end
	doc:replace_range(line, 1, line, end_col, function()
		return out
	end)
	doc:set_selection(line, math.min(col, #out + 1))
end

command.add({
	["html:encode"] = {
		requires = { "doc", "edit" },
		perform = function()
		local doc = core.active_view and core.active_view.doc
		transform_doc(doc, function(text)
			return entities_encode.encode_basic(text), nil
		end)
		end,
	},
	["html:encode-full"] = {
		requires = { "doc", "edit" },
		perform = function()
		local doc = core.active_view and core.active_view.doc
		transform_doc(doc, function(text)
			return entities_encode.encode_full(text), nil
		end)
		end,
	},
	["html:decode"] = {
		requires = { "doc", "edit" },
		perform = function()
		local doc = core.active_view and core.active_view.doc
		transform_doc(doc, function(text)
			return entities_decode.decode(text)
		end)
		end,
	},
})
