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

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

command.register({
	-- CommandView command availability uses built-in requires token 'command_view'

	-- Submits the current command input
	["command:submit"] = {
		requires = { "command_view" },
		perform = function()
		core.active_view:submit()
		return true
		end,
	},

	-- Applies the current autocomplete suggestion
	["command:complete"] = {
		requires = { "command_view" },
		perform = function()
			if #core.active_view.suggestions == 0 then
				return false
			end
			core.active_view:complete()
			return true
		end,
	},

	-- Selects all command input text while keeping cursor at the end
	["command:select-all"] = {
		requires = { "command_view" },
		perform = function()
			core.active_view.doc:set_selection(math.huge, math.huge, 1, 1)
			return true
		end,
	},

	-- Closes the command input panel
	["command:escape"] = {
		requires = { "command_view" },
		perform = function()
			core.active_view:exit()
			return true
		end,
	},

	-- Moves command suggestion selection to the previous entry
	["command:select-previous"] = {
		requires = { "command_view" },
		perform = function()
			if #core.active_view.suggestions == 0 then
				return false
			end
			local before = core.active_view.suggestion_idx
			core.active_view:move_suggestion_idx(1)
			return core.active_view.suggestion_idx ~= before
		end,
	},

	-- Moves command suggestion selection to the next entry
	["command:select-next"] = {
		requires = { "command_view" },
		perform = function()
			if #core.active_view.suggestions == 0 then
				return false
			end
			local before = core.active_view.suggestion_idx
			core.active_view:move_suggestion_idx(-1)
			return core.active_view.suggestion_idx ~= before
		end,
	},

	-- Moves command suggestion selection to the first entry
	["command:select-first"] = {
		requires = { "command_view" },
		perform = function()
			if core.active_view:get_text() ~= "" then
				return false
			end
			if #core.active_view.suggestions == 0 then
				return false
			end
			local before = core.active_view.suggestion_idx
			core.active_view.suggestion_idx = 1
			core.active_view:clamp_suggestion_window()
			core.active_view.last_change_id = core.active_view.doc:get_change_id()
			return core.active_view.suggestion_idx ~= before
		end,
	},

	-- Moves command suggestion selection to the last entry
	["command:select-last"] = {
		requires = { "command_view" },
		perform = function()
			if core.active_view:get_text() ~= "" then
				return false
			end
			if #core.active_view.suggestions == 0 then
				return false
			end
			local before = core.active_view.suggestion_idx
			core.active_view.suggestion_idx = #core.active_view.suggestions
			core.active_view:clamp_suggestion_window()
			core.active_view.last_change_id = core.active_view.doc:get_change_id()
			return core.active_view.suggestion_idx ~= before
		end,
	},

	-- Moves command suggestion selection one visible page toward previous entries
	["command:page-up"] = {
		requires = { "command_view" },
		perform = function()
			if #core.active_view.suggestions == 0 then
				return false
			end
			local before = core.active_view.suggestion_idx
			core.active_view:move_suggestion_page(1)
			return core.active_view.suggestion_idx ~= before
		end,
	},

	-- Moves command suggestion selection one visible page toward next entries
	["command:page-down"] = {
		requires = { "command_view" },
		perform = function()
			if #core.active_view.suggestions == 0 then
				return false
			end
			local before = core.active_view.suggestion_idx
			core.active_view:move_suggestion_page(-1)
			return core.active_view.suggestion_idx ~= before
		end,
	},
})

-- Ensures Ctrl+A in command prompts uses command-selection semantics
keymap.extend("modal", {
	-- Scope prompt-only navigation keys to the command view instead of intercepting them globally
	command_view = {
		-- Escape closes the active command prompt instead of falling through to document actions
		["escape"] = "command:escape",
		["ctrl+w"] = "command:escape",

		-- Keep ordinary single-line editing available without inheriting document-only shortcuts
		["ctrl+z"] = "doc:undo",
		["ctrl+x"] = "doc:cut",
		["ctrl+c"] = "doc:copy",
		["ctrl+v"] = "doc:paste",
		["backspace"] = "doc:backspace",
		["shift+backspace"] = "doc:backspace",
		["ctrl+backspace"] = "doc:delete-to-previous-word-start",
		["ctrl+shift+backspace"] = "doc:delete-to-previous-word-start",
		["delete"] = "doc:delete",
		["shift+delete"] = "doc:delete",
		["ctrl+delete"] = "doc:delete-to-next-word-end",
		["ctrl+shift+delete"] = "doc:delete-to-next-word-end",
		["left"] = "doc:move-to-previous-char",
		["right"] = "doc:move-to-next-char",
		["ctrl+left"] = "doc:move-to-previous-word-start",
		["ctrl+right"] = "doc:move-to-next-word-end",
		["shift+left"] = "doc:select-to-previous-char",
		["shift+right"] = "doc:select-to-next-char",
		["ctrl+shift+left"] = "doc:select-to-previous-word-start",
		["ctrl+shift+right"] = "doc:select-to-next-word-end",
		["shift+home"] = "doc:select-to-start-of-line",
		["shift+end"] = "doc:select-to-end-of-line",
		["ctrl+shift+home"] = "doc:select-to-start-of-doc",
		["ctrl+shift+end"] = "doc:select-to-end-of-doc",

		-- Tab applies the current command suggestion inside the command prompt
		["tab"] = "command:complete",

		-- Enter submits the active command prompt
		["enter"] = "command:submit",
		["keypad enter"] = "command:submit",
		["ctrl+a"] = "command:select-all",

		-- Bottom-up popup orientation maps Home to top-row item and End to bottom-row item
		["home"] = { "command:select-last", "doc:move-to-start-of-line" },
		["end"] = { "command:select-first", "doc:move-to-end-of-line" },
		["ctrl+home"] = "doc:move-to-start-of-doc",
		["ctrl+end"] = "doc:move-to-end-of-doc",
		["pageup"] = "command:page-up",
		["pagedown"] = "command:page-down",
		["up"] = "command:select-previous",
		["down"] = "command:select-next",
	},
})
