-- lx-bundle:true

-- This file is part of Lx, created by Liqube <www.liqube.com>
-- Copyright Liqube Audio. All rights reserved.
-- Lx Interim License. See LICENSE for details.

--- 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.register({
	-- 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, config.animate_page_scroll == true)
			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, config.animate_page_scroll == true)
			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_mode(active_view)
			local to_mode = (from_mode == "hex") and "symbols" or "hex"
			local anchor = BinaryViewer.get_top_byte_offset(active_view, from_mode)
			BinaryViewer.set_mode(active_view, to_mode, true)
			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_mode(active_view)
			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.bind("core", {
	binary_viewer = {
		["return"] = "binary-viewer:toggle-mode",
		["keypad enter"] = "binary-viewer:toggle-mode",
		["up"] = "binary-viewer:line-up",
		["down"] = "binary-viewer:line-down",
		-- Space follows the usual document-reading page controls
		["shift+space"] = "binary-viewer:page-up",
		["space"] = "binary-viewer:page-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",
	},
})
