/** @license MIT | @cube-dev/ui-kit v0.147.0 | Cube Dev Team */
//#region src/components/layout/Board/grid-core/constraints.ts
function clamp(value, min, max) {
	return Math.max(min, Math.min(max, value));
}
/**
* Grid boundary constraint. Ensures items stay within the grid bounds. This is
* the default position constraint.
*/
const gridBounds = {
	name: "gridBounds",
	constrainPosition(item, x, y, { cols, maxRows }) {
		return {
			x: clamp(x, 0, Math.max(0, cols - item.w)),
			y: clamp(y, 0, Math.max(0, maxRows - item.h))
		};
	},
	constrainSize(item, w, h, handle, { cols, maxRows }) {
		const maxW = handle === "w" || handle === "nw" || handle === "sw" ? item.x + item.w : cols - item.x;
		const maxH = handle === "n" || handle === "nw" || handle === "ne" ? item.y + item.h : maxRows - item.y;
		return {
			w: clamp(w, 1, Math.max(1, maxW)),
			h: clamp(h, 1, Math.max(1, maxH))
		};
	}
};
/**
* Min/max size constraint. Enforces per-item minW/maxW/minH/maxH.
*/
const minMaxSize = {
	name: "minMaxSize",
	constrainSize(item, w, h) {
		return {
			w: clamp(w, item.minW ?? 1, item.maxW ?? Infinity),
			h: clamp(h, item.minH ?? 1, item.maxH ?? Infinity)
		};
	}
};
/**
* Container bounds constraint. Constrains items to stay within the visible
* container (a replacement for the legacy `isBounded` prop).
*/
const containerBounds = {
	name: "containerBounds",
	constrainPosition(item, x, y, { cols, maxRows, containerHeight, rowHeight, margin }) {
		const visibleRows = containerHeight > 0 ? Math.floor((containerHeight + margin[1]) / (rowHeight + margin[1])) : maxRows;
		return {
			x: clamp(x, 0, Math.max(0, cols - item.w)),
			y: clamp(y, 0, Math.max(0, visibleRows - item.h))
		};
	}
};
/** Bounded X constraint. Only constrains horizontal position. */
const boundedX = {
	name: "boundedX",
	constrainPosition(item, x, y, { cols }) {
		return {
			x: clamp(x, 0, Math.max(0, cols - item.w)),
			y
		};
	}
};
/** Bounded Y constraint. Only constrains vertical position. */
const boundedY = {
	name: "boundedY",
	constrainPosition(item, x, y, { maxRows }) {
		return {
			x,
			y: clamp(y, 0, Math.max(0, maxRows - item.h))
		};
	}
};
/**
* Create an aspect ratio constraint (maintains width-to-height ratio in pixels).
*/
function aspectRatio(ratio) {
	return {
		name: `aspectRatio(${ratio})`,
		constrainSize(_item, w, _h, _handle, context) {
			const { cols, containerWidth, rowHeight, margin } = context;
			const pixelHeight = ((containerWidth - margin[0] * (cols - 1)) / cols * w + margin[0] * Math.max(0, w - 1)) / ratio;
			return {
				w,
				h: Math.max(1, Math.round((pixelHeight + margin[1]) / (rowHeight + margin[1])))
			};
		}
	};
}
/** Create a snap-to-grid constraint. */
function snapToGrid(stepX, stepY = stepX) {
	if (stepX <= 0 || stepY <= 0) throw new Error(`snapToGrid: step values must be positive (got stepX=${stepX}, stepY=${stepY})`);
	return {
		name: `snapToGrid(${stepX}, ${stepY})`,
		constrainPosition(_item, x, y) {
			return {
				x: Math.round(x / stepX) * stepX,
				y: Math.round(y / stepY) * stepY
			};
		}
	};
}
/** Create a minimum size constraint (grid-wide). */
function minSize(minW, minH) {
	return {
		name: `minSize(${minW}, ${minH})`,
		constrainSize(_item, w, h) {
			return {
				w: Math.max(minW, w),
				h: Math.max(minH, h)
			};
		}
	};
}
/** Create a maximum size constraint (grid-wide). */
function maxSize(maxW, maxH) {
	return {
		name: `maxSize(${maxW}, ${maxH})`,
		constrainSize(_item, w, h) {
			return {
				w: Math.min(maxW, w),
				h: Math.min(maxH, h)
			};
		}
	};
}
/** Default constraints applied when none are specified. */
const defaultConstraints = [gridBounds, minMaxSize];
/** Apply position constraints to a proposed position. */
function applyPositionConstraints(constraints, item, x, y, context) {
	let result = {
		x,
		y
	};
	for (const constraint of constraints) if (constraint.constrainPosition) result = constraint.constrainPosition(item, result.x, result.y, context);
	if (item.constraints) {
		for (const constraint of item.constraints) if (constraint.constrainPosition) result = constraint.constrainPosition(item, result.x, result.y, context);
	}
	return result;
}
/** Apply size constraints to a proposed size. */
function applySizeConstraints(constraints, item, w, h, handle, context) {
	let result = {
		w,
		h
	};
	for (const constraint of constraints) if (constraint.constrainSize) result = constraint.constrainSize(item, result.w, result.h, handle, context);
	if (item.constraints) {
		for (const constraint of item.constraints) if (constraint.constrainSize) result = constraint.constrainSize(item, result.w, result.h, handle, context);
	}
	return result;
}

//#endregion
export { applyPositionConstraints, applySizeConstraints, aspectRatio, boundedX, boundedY, containerBounds, defaultConstraints, gridBounds, maxSize, minMaxSize, minSize, snapToGrid };
//# sourceMappingURL=constraints.js.map