-- lx-bundle:true

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

--- Provide a reusable Lua-owned visual Separator Control
-- A Separator divides nearby content without becoming spacing, layout, or an input target
-- @module qui.separator

local qui = require("qui")
local colors = require("qui.colors")
local metrics = require("qui.metrics")
local theme = require("qui.theme")

local Separator = {}

--- Keep one Separator thickness inside a useful positive DIP range
-- @param value number|nil requested value
-- @return integer thickness checked whole-DIP value
local function thickness_value(value)
	value = value == nil and theme.resolve_metric(metrics.separator_thickness) or value
	assert(type(value) == "number" and value > 0 and value < math.huge,
		"Separator thickness must be a positive number")

	return math.max(1, math.floor(value + 0.5))
end

--- Select the shared structural frame color used by every ordinary Separator
-- @param self table Separator control
-- @param type string requested visual type
-- @param flags table current Separator conditions
-- @return string|nil color_identifier
function Separator.default_color(self, type, flags)
	if type == "frame" then
		return colors.separator_frame
	end

	return nil
end

--- Create one horizontal or vertical divider for use inside 'qui.pane.controls'
-- @param options table orientation, thickness, color handling, and placement
-- @return table control unrestricted Lua Control declaration
function Separator.new(options)
	assert(type(options) == "table", "Separator expects a table")
	assert(options.orientation == nil or options.orientation == "horizontal" or options.orientation == "vertical",
		"Separator orientation must be 'horizontal' or 'vertical'")
	assert(options.on_color == nil or type(options.on_color) == "function",
		"Separator on_color must be a function")
	assert(options.default_color == nil, "Separator default_color is fixed; use on_color for dynamic changes")

	local control = options
	control.orientation = control.orientation or "horizontal"
	control.thickness = thickness_value(control.thickness)
	control.enabled = control.enabled ~= false
	control.focusable = false
	control.accepts_pointer = false
	control.default_color = Separator.default_color
	control.placement = control.placement or (
		control.orientation == "horizontal"
			and { horizontal = "stretch", vertical = "center" }
			or { horizontal = "center", vertical = "stretch" }
	)

	--- Measure only the divider's cross-axis thickness while its Pane supplies the long axis
	function control:measure(control_canvas, minimum_width, minimum_height, maximum_width, maximum_height)
		local natural_width = self.orientation == "vertical" and self.thickness or 0
		local natural_height = self.orientation == "horizontal" and self.thickness or 0
		local width = math.max(minimum_width, math.min(natural_width, maximum_width))
		local height = math.max(minimum_height, math.min(natural_height, maximum_height))

		return width, height
	end

	--- Draw the divider centered inside any extra space assigned by custom placement
	function control:draw(control_canvas)
		local width, height = control_canvas:size()
		local color = self:get_color("frame", { grayed = not self.enabled })
		if self.orientation == "horizontal" then
			local y = math.max(0, math.floor((height - self.thickness) / 2))
			control_canvas:fill_rect(0, y, width, math.min(self.thickness, height), color)
		else
			local x = math.max(0, math.floor((width - self.thickness) / 2))
			control_canvas:fill_rect(x, 0, math.min(self.thickness, width), height, color)
		end
	end

	return qui.control(control)
end

-- Callable module syntax keeps declarations readable as 'Separator { ... }'
setmetatable(Separator, {
	__call = function(_, options)
		return Separator.new(options)
	end,
})

return Separator
