-- lx-bundle:true

--- Binary viewer commands
-- Keep binary navigation and bindings owned by the binary surface
-- @module core.binary.commands

local core = require("core")
local command = require("core.command")
local config = require("core.config")
local keymap = require("core.keymap")
local BinaryViewer = require("core.binary.viewer")

--- Return the active binary viewer for explicit viewer-owned commands
-- @return table active_view current binary viewer
local function active_binary_view()
	return core.active_view
end

-- Register binary rendering commands for active BinaryViewer
command.add({
	-- Scroll one binary row upward
	["binary-viewer:line-up"] = {
		requires = { "binary_viewer" },
		perform = function()
			BinaryViewer.scroll_by(active_binary_view(), -BinaryViewer.get_line_height())
			return true
		end,
	},

	-- Scroll one binary row downward
	["binary-viewer:line-down"] = {
		requires = { "binary_viewer" },
		perform = function()
			BinaryViewer.scroll_by(active_binary_view(), BinaryViewer.get_line_height())
			return true
		end,
	},

	-- Scroll one binary page upward
	["binary-viewer:page-up"] = {
		requires = { "binary_viewer" },
		perform = function()
			local active_view = active_binary_view()
			local delta = math.max(1, active_view.size.y - BinaryViewer.get_line_height() * 2)
			BinaryViewer.scroll_by(active_view, -delta)
			return true
		end,
	},

	-- Scroll one binary page downward
	["binary-viewer:page-down"] = {
		requires = { "binary_viewer" },
		perform = function()
			local active_view = active_binary_view()
			local delta = math.max(1, active_view.size.y - BinaryViewer.get_line_height() * 2)
			BinaryViewer.scroll_by(active_view, delta)
			return true
		end,
	},

	-- Jump to the top of the binary view
	["binary-viewer:home"] = {
		requires = { "binary_viewer" },
		perform = function()
			BinaryViewer.scroll_to_ratio(active_binary_view(), 0)
			return true
		end,
	},

	-- Jump to the bottom of the binary view
	["binary-viewer:end"] = {
		requires = { "binary_viewer" },
		perform = function()
			BinaryViewer.scroll_to_ratio(active_binary_view(), 1)
			return true
		end,
	},

	-- Toggle between hex and symbol rendering modes
	["binary-viewer:toggle-mode"] = {
		requires = { "binary_viewer" },
		perform = function()
			local active_view = active_binary_view()
			local from_mode = BinaryViewer.get_session_mode()
			local to_mode = (from_mode == "hex") and "symbols" or "hex"
			local anchor = BinaryViewer.get_top_byte_offset(active_view, from_mode)
			BinaryViewer.set_session_mode(to_mode)
			BinaryViewer.sync_scroll_between_modes(active_view, from_mode, to_mode, anchor)
			core.redraw = true
		end,
	},

	-- Recreate doc state and file metadata cache
	["binary-viewer:reload"] = {
		requires = { "binary_viewer" },
		perform = function()
			local active_view = active_binary_view()
			BinaryViewer.reload_doc_state(active_view.doc)
			core.redraw = true
		end,
	},
	-- Toggle top ruler visibility
	["binary-viewer:toggle-ruler"] = {
		requires = { "binary_viewer" },
		perform = function()
			config.binary_viewer_show_ruler = not config.binary_viewer_show_ruler
			local active_view = active_binary_view()
			local from_mode = BinaryViewer.get_session_mode()
			local anchor = BinaryViewer.get_top_byte_offset(active_view, from_mode)
			BinaryViewer.sync_scroll_between_modes(active_view, from_mode, from_mode, anchor)
			core.redraw = true
		end,
	},
})

-- Keep binary navigation keys local to the binary surface context
keymap.add({
	["return"] = "binary-viewer:toggle-mode",
	["keypad enter"] = "binary-viewer:toggle-mode",
	["up"] = "binary-viewer:line-up",
	["down"] = "binary-viewer:line-down",
	["pageup"] = "binary-viewer:page-up",
	["pagedown"] = "binary-viewer:page-down",
	["home"] = "binary-viewer:home",
	["end"] = "binary-viewer:end",
	["ctrl+home"] = "binary-viewer:home",
	["ctrl+end"] = "binary-viewer:end",
	["ctrl+r"] = "binary-viewer:toggle-ruler",
	["ctrl+wheelup"] = "zoom:in",
	["ctrl+wheeldown"] = "zoom:out",
}, {
	context = "binary_viewer"
})
