-- lx-bundle:true

--- Optional ICO and CUR preview registration
-- @module plugins.icopreview

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

--- Return whether the focused view is an ICO preview
-- @return boolean active
local function is_active_ico_preview()
	local active_view = core.active_view

	return active_view and active_view.is_ico_preview == true or false
end

--- Return the hovered or active ICO preview targeted by one command
-- @param context table|nil command input details
-- @return table|nil preview
local function get_target_ico_preview(context)
	local target_view = type(context) == "table" and context.target_view or nil

	if target_view and target_view.is_ico_preview == true then
		return target_view
	end

	return is_active_ico_preview() and core.active_view or nil
end

--- Return whether the current command context targets an ICO preview
-- @return boolean targeted
local function has_target_ico_preview()
	return get_target_ico_preview(command.get_context()) ~= nil
end

--- Create an ICO or CUR preview through the shared open handler
-- @param request table shared open request
-- @return table view ICO or CUR preview view
local function create_preview(request)
	local IcoPreview = require("plugins.icopreview.view")
	return IcoPreview(request.doc)
end

-- Multi-frame icon and cursor previews take priority over the ordinary single-image viewer
open_handler.register({
	name = "ico",
	formats = { "ico", "cur" },
	modes = { "view", "preview" },
	create_view = create_preview,
})

command.register({
	-- Step through the exact zoom levels declared by the ICO preview
	["ico-preview:zoom-in"] = {
		predicate = has_target_ico_preview,
		perform = function(context)
			local view = get_target_ico_preview(context)

			return view and view:step_zoom(1) or false
		end,
	},
	["ico-preview:zoom-out"] = {
		predicate = has_target_ico_preview,
		perform = function(context)
			local view = get_target_ico_preview(context)

			return view and view:step_zoom(-1) or false
		end,
	},
	["ico-preview:zoom-reset"] = {
		predicate = has_target_ico_preview,
		perform = function(context)
			local view = get_target_ico_preview(context)

			return view and view:set_zoom_multiplier(1) or false
		end,
	},
	-- Remember a pressed frame, then let the following command start normal panning
	["ico-preview:begin-image-click"] = {
		predicate = is_active_ico_preview,
		perform = function(context)
			if type(context) ~= "table" then
				return false
			end

			return core.active_view:begin_entry_click(context.mouse_x, context.mouse_y)
		end,
	},
	-- Cycle through columns, vertical and packed frame layouts
	["ico-preview:toggle-layout"] = {
		predicate = is_active_ico_preview,
		perform = function()
			return core.active_view:toggle_layout()
		end,
	},
})

-- ICO previews keep their controls local to the preview surface
keymap.bind("plugin", {
	ico_preview = {
		["lclick"] = {
			"ico-preview:begin-image-click",
			"doc:mouse-pan",
		},
		["mclick"] = "ico-preview:zoom-reset",
		["l"] = "ico-preview:toggle-layout",
		["+"] = "ico-preview:zoom-in",
		["-"] = "ico-preview:zoom-out",
		["0"] = "ico-preview:zoom-reset",
		["keypad +"] = "ico-preview:zoom-in",
		["keypad -"] = "ico-preview:zoom-out",
		["keypad *"] = "ico-preview:zoom-reset",
		["ctrl+wheelup"] = "ico-preview:zoom-in",
		["ctrl+wheeldown"] = "ico-preview:zoom-out",
	},
})
