var __extends = (this && this.__extends) || function (d, b) {
    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
    function __() { this.constructor = d; }
    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
define(["require", "exports", 'react', '../../utilities/KeyCodes', '../../utilities/eventGroup/EventGroup', '../../utilities/focus'], function (require, exports, React, KeyCodes_1, EventGroup_1, focus_1) {
    "use strict";
    var FocusTrapZone = (function (_super) {
        __extends(FocusTrapZone, _super);
        function FocusTrapZone(props) {
            _super.call(this, props);
            this._onKeyboardHandler = this._onKeyboardHandler.bind(this);
            this._events = new EventGroup_1.EventGroup(this);
        }
        FocusTrapZone.prototype.componentDidMount = function () {
            var _a = this.props, elementToFocusOnDismiss = _a.elementToFocusOnDismiss, _b = _a.isClickableOutsideFocusTrap, isClickableOutsideFocusTrap = _b === void 0 ? false : _b, _c = _a.forceFocusInsideTrap, forceFocusInsideTrap = _c === void 0 ? true : _c;
            this._previouslyFocusedElement = elementToFocusOnDismiss ? elementToFocusOnDismiss : document.activeElement;
            this._focusOnFirstChildInZone();
            if (forceFocusInsideTrap) {
                this._events.on(window, 'focus', this._forceFocusInTrap, true);
            }
            if (!isClickableOutsideFocusTrap) {
                this._events.on(window, 'click', this._forceClickInTrap, true);
            }
        };
        FocusTrapZone.prototype.componentWillUnmount = function () {
            var ignoreExternalFocusing = this.props.ignoreExternalFocusing;
            this._events.dispose();
            if (!ignoreExternalFocusing && this._previouslyFocusedElement) {
                this._previouslyFocusedElement.focus();
            }
        };
        FocusTrapZone.prototype.render = function () {
            var _a = this.props, className = _a.className, ariaLabelledBy = _a.ariaLabelledBy;
            return (React.createElement("div", React.__spread({}, this.props, {className: className, ref: 'root', "aria-labelledby": ariaLabelledBy, onKeyDown: this._onKeyboardHandler}), this.props.children));
        };
        FocusTrapZone.prototype._onKeyboardHandler = function (ev) {
            if (ev.which !== KeyCodes_1.KeyCodes.tab) {
                return;
            }
            var root = this.refs.root;
            var _firstFocusableChild = focus_1.getFirstFocusable(root, root.firstChild, true);
            var _lastFocusableChild = focus_1.getLastFocusable(root, root.lastChild, true);
            if (ev.shiftKey && _firstFocusableChild === ev.target) {
                _lastFocusableChild.focus();
                ev.preventDefault();
                ev.stopPropagation();
            }
            else if (!ev.shiftKey && _lastFocusableChild === ev.target) {
                _firstFocusableChild.focus();
                ev.preventDefault();
                ev.stopPropagation();
            }
        };
        FocusTrapZone.prototype._focusOnFirstChildInZone = function () {
            var firstFocusableSelector = this.props.firstFocusableSelector;
            var _firstFocusableChild;
            var root = this.refs.root;
            if (firstFocusableSelector) {
                _firstFocusableChild = root.querySelector('.' + firstFocusableSelector);
            }
            else {
                _firstFocusableChild = focus_1.getNextElement(root, root.firstChild, true, false, false, true);
            }
            if (_firstFocusableChild) {
                _firstFocusableChild.focus();
            }
        };
        FocusTrapZone.prototype._forceFocusInTrap = function (ev) {
            var focusedElement = document.activeElement;
            if (!this.refs.root.contains(focusedElement)) {
                this._focusOnFirstChildInZone();
                ev.preventDefault();
                ev.stopPropagation();
            }
        };
        FocusTrapZone.prototype._forceClickInTrap = function (ev) {
            var clickedElement = ev.target;
            if (clickedElement && !this.refs.root.contains(clickedElement)) {
                this._focusOnFirstChildInZone();
                ev.preventDefault();
                ev.stopPropagation();
            }
        };
        return FocusTrapZone;
    }(React.Component));
    exports.FocusTrapZone = FocusTrapZone;
});
