-- 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.

--- Image viewer commands
-- Keeps image navigation local to the image surface
-- @module core.image.commands

local core = require("core")
local command = require("core.command")
local keymap = require("core.keymap")

local PAGE_SCROLL_RATIO = 0.85

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

--- Return one page-sized scroll delta for the active image view
-- @param view table image viewer
-- @return number delta page scroll delta
local function get_page_scroll_delta(view)
	local _, _, _, viewport_height = view:get_content_viewport_rect()

	return math.max(view:get_line_height(), math.floor(viewport_height * PAGE_SCROLL_RATIO))
end

command.register({
	-- Scroll one step upward
	["image-viewer:line-up"] = {
		requires = { "image_viewer" },
		perform = function()
			active_image_view():scroll_by(0, -active_image_view():get_line_height())
			return true
		end,
	},

	-- Scroll one step downward
	["image-viewer:line-down"] = {
		requires = { "image_viewer" },
		perform = function()
			active_image_view():scroll_by(0, active_image_view():get_line_height())
			return true
		end,
	},

	-- Scroll one step left
	["image-viewer:line-left"] = {
		requires = { "image_viewer" },
		perform = function()
			active_image_view():scroll_by(-active_image_view():get_line_height(), 0)
			return true
		end,
	},

	-- Scroll one step right
	["image-viewer:line-right"] = {
		requires = { "image_viewer" },
		perform = function()
			active_image_view():scroll_by(active_image_view():get_line_height(), 0)
			return true
		end,
	},

	-- Scroll one viewport page upward
	["image-viewer:page-up"] = {
		requires = { "image_viewer" },
		perform = function()
			active_image_view():scroll_by(0, -get_page_scroll_delta(active_image_view()))
			return true
		end,
	},

	-- Scroll one viewport page downward
	["image-viewer:page-down"] = {
		requires = { "image_viewer" },
		perform = function()
			active_image_view():scroll_by(0, get_page_scroll_delta(active_image_view()))
			return true
		end,
	},

	-- Jump to the top-left corner of the image
	["image-viewer:home"] = {
		requires = { "image_viewer" },
		perform = function()
			active_image_view():scroll_to_edge(false)
			return true
		end,
	},

	-- Jump to the bottom-right corner of the image
	["image-viewer:end"] = {
		requires = { "image_viewer" },
		perform = function()
			active_image_view():scroll_to_edge(true)
			return true
		end,
	},
})

keymap.bind("core", {
	image_viewer = {
		["lclick"] = "doc:mouse-pan",
		["up"] = "image-viewer:line-up",
		["down"] = "image-viewer:line-down",
		["left"] = "image-viewer:line-left",
		["right"] = "image-viewer:line-right",
		-- Space follows the usual document-reading page controls
		["shift+space"] = "image-viewer:page-up",
		["space"] = "image-viewer:page-down",
		["pageup"] = "image-viewer:page-up",
		["pagedown"] = "image-viewer:page-down",
		["home"] = "image-viewer:home",
		["end"] = "image-viewer:end",
		["ctrl+home"] = "image-viewer:home",
		["ctrl+end"] = "image-viewer:end",
	},
})

return true
