import { Num, Optional } from '@ephox/katamari';
import { Attribute, SugarNode } from '@ephox/sugar';
import * as DomPinpoint from './DomPinpoint';
const f = (container, selector, current, delta, getNewIndex) => {
    const isDisabledButton = (candidate) => SugarNode.name(candidate) === 'button' && Attribute.get(candidate, 'disabled') === 'disabled';
    const tryNewIndex = (initial, index, candidates) => getNewIndex(initial, index, delta, 0, candidates.length - 1, candidates[index], (newIndex) => isDisabledButton(candidates[newIndex]) ?
        tryNewIndex(initial, newIndex, candidates) :
        Optional.from(candidates[newIndex]));
    // I wonder if this will be a problem when the focused element is invisible (shouldn't happen)
    return DomPinpoint.locateVisible(container, current, selector).bind((identified) => {
        const index = identified.index;
        const candidates = identified.candidates;
        return tryNewIndex(index, index, candidates);
    });
};
const horizontalWithoutCycles = (container, selector, current, delta) => f(container, selector, current, delta, (prevIndex, v, d, min, max, oldCandidate, onNewIndex) => {
    const newIndex = Num.clamp(v + d, min, max);
    return newIndex === prevIndex ? Optional.from(oldCandidate) : onNewIndex(newIndex);
});
const horizontal = (container, selector, current, delta) => f(container, selector, current, delta, (prevIndex, v, d, min, max, _oldCandidate, onNewIndex) => {
    const newIndex = Num.cycleBy(v, d, min, max);
    // If we've cycled back to the original index, we've failed to find a new valid candidate
    return newIndex === prevIndex ? Optional.none() : onNewIndex(newIndex);
});
export { horizontal, horizontalWithoutCycles };
//# sourceMappingURL=DomNavigation.js.map