/**
 * Copyright IBM Corp. 2026
 *
 * This source code is licensed under the Apache-2.0 license found in the
 * LICENSE file in the root directory of this source tree.
 */

//#region src/globals/internal/radio-group-manager.ts
/**
* Copyright IBM Corp. 2019, 2023
*
* This source code is licensed under the Apache-2.0 license found in the
* LICENSE file in the root directory of this source tree.
*/
/**
* The navigation direction.
*/
let NAVIGATION_DIRECTION = /* @__PURE__ */ function(NAVIGATION_DIRECTION) {
	/**
	* Navigating backward.
	*/
	NAVIGATION_DIRECTION[NAVIGATION_DIRECTION["BACKWARD"] = -1] = "BACKWARD";
	/**
	* Navigating forward.
	*/
	NAVIGATION_DIRECTION[NAVIGATION_DIRECTION["FORWARD"] = 1] = "FORWARD";
	return NAVIGATION_DIRECTION;
}({});
/**
* An object that manages radio groups in a document.
* There must be only one instance for one document.
*/
var RadioGroupManager = class RadioGroupManager {
	constructor(document) {
		this._groups = {};
		this.constructor._instances.set(document, this);
	}
	/**
	* @param radio A radio button.
	* @returns
	*   `true` if the given radio button should be focusable, which is either:
	*   - The radio button is selected
	*   - No radio button is selected and the radio button is first one in the radio group
	*/
	shouldBeFocusable(radio) {
		if (radio.checked) return true;
		const { name } = radio;
		const group = this._groups[name];
		if (group && Array.from(group).some((item) => item.checked)) return false;
		return !group || group.size === 1 || this.getSortedGroup(radio)[0] === radio;
	}
	/**
	* @param radio A radio button.
	* @returns The sorted radio group the given radio button is in.
	*/
	getSortedGroup(radio) {
		const group = this._groups[radio.name];
		return group && Array.from(group).sort((lhs, rhs) => {
			const comparisonResult = lhs.compareDocumentPosition(rhs);
			if (comparisonResult & Node.DOCUMENT_POSITION_FOLLOWING || comparisonResult & Node.DOCUMENT_POSITION_CONTAINED_BY) return -1;
			if (comparisonResult & Node.DOCUMENT_POSITION_PRECEDING || comparisonResult & Node.DOCUMENT_POSITION_CONTAINS) return 1;
			return 0;
		});
	}
	/**
	* Manages a radio button.
	*
	* @param radio The radio button to manage.
	* @returns This object.
	*/
	add(radio) {
		const { name } = radio;
		if (name) {
			const groups = this._groups;
			if (!groups[name]) groups[name] = /* @__PURE__ */ new Set();
			groups[name].add(radio);
		}
		return this;
	}
	/**
	* Unmanages a radio button.
	*
	* @param radio The radio button to unmanage.
	* @param name The old name of the radio button to unmanage.
	* @returns `true` if `element` was actually managed.
	*/
	delete(radio, name = radio.name) {
		const group = this._groups[name];
		return !group ? false : group.delete(radio);
	}
	/**
	* Selects or focuses on a radio button.
	*
	* @param radio The radio button to select.
	* @param readOnly optional if radio button has readOnly.
	*/
	select(radio, readOnly) {
		const group = this._groups[radio.name];
		if (group) {
			if (radio.disabled) return;
			radio.checked = !readOnly || true;
			radio.tabIndex = 0;
			radio.focus();
			group.forEach((item) => {
				if (radio !== item) {
					item.checked = readOnly || false;
					item.tabIndex = -1;
				}
			});
		}
	}
	/**
	* @param radio The currently selected radio button.
	* @param direction The direction to navigate to.
	* @returns The radio button that should be selected next.
	*/
	navigate(radio, direction) {
		const sortedGroup = this.getSortedGroup(radio);
		const n = sortedGroup.length;
		let searchRadioIndex = sortedGroup.indexOf(radio);
		for (let i = 0; i < n; i++) {
			searchRadioIndex = (searchRadioIndex + direction + n) % n;
			const candidateRadio = sortedGroup[searchRadioIndex];
			if (!candidateRadio.disabled) return candidateRadio;
		}
		return radio;
	}
	static {
		this._instances = /* @__PURE__ */ new WeakMap();
	}
	/**
	* @param document A document element.
	* @returns The `RadioGroupManager` instance associated with the given document.
	*/
	static get(document) {
		return this._instances.get(document) || new RadioGroupManager(document);
	}
};
//#endregion
export { NAVIGATION_DIRECTION, RadioGroupManager as default };

//# sourceMappingURL=radio-group-manager.js.map