import * as tslib_1 from "tslib";
import * as React from 'react';
import { BaseComponent, divProperties, getNativeProps, getId, getDocument, createRef, classNamesFunction } from '../../Utilities';
import { OpenCardMode, HoverCardType } from './HoverCard.types';
import { ExpandingCard } from './ExpandingCard';
import { ExpandingCardMode } from './ExpandingCard.types';
import { PlainCard } from './PlainCard/PlainCard';
var getClassNames = classNamesFunction();
var HoverCardBase = /** @class */ (function (_super) {
    tslib_1.__extends(HoverCardBase, _super);
    // Constructor
    function HoverCardBase(props) {
        var _this = _super.call(this, props) || this;
        // The wrapping div that gets the hover events
        _this._hoverCard = createRef();
        // Show HoverCard
        _this._cardOpen = function (ev) {
            if (_this._shouldBlockHoverCard() || (ev.type === 'keydown' && !(ev.which === _this.props.openHotKey))) {
                return;
            }
            _this._async.clearTimeout(_this._dismissTimerId);
            if (ev.type === 'mouseenter') {
                _this._currentMouseTarget = ev.currentTarget;
            }
            _this._executeCardOpen(ev);
        };
        _this._executeCardOpen = function (ev) {
            _this._async.clearTimeout(_this._openTimerId);
            _this._openTimerId = _this._async.setTimeout(function () {
                _this.setState(function (prevState) {
                    if (!prevState.isHoverCardVisible) {
                        return {
                            isHoverCardVisible: true,
                            mode: ExpandingCardMode.compact,
                            openMode: ev.type === 'keydown' ? OpenCardMode.hotKey : OpenCardMode.hover
                        };
                    }
                    return prevState;
                });
            }, _this.props.cardOpenDelay);
        };
        // Hide HoverCard
        _this._cardDismiss = function (ev) {
            if (ev.type === 'keydown' && ev.which !== 27 /* escape */) {
                return;
            }
            // Dismiss if not sticky and currentTarget is the same element that mouse last entered
            if (!_this.props.sticky && (_this._currentMouseTarget === ev.currentTarget || ev.which === 27 /* escape */)) {
                _this._executeCardDismiss();
            }
        };
        _this._executeCardDismiss = function () {
            _this._async.clearTimeout(_this._openTimerId);
            _this._async.clearTimeout(_this._dismissTimerId);
            _this._dismissTimerId = _this._async.setTimeout(function () {
                _this.setState({
                    isHoverCardVisible: false,
                    mode: ExpandingCardMode.compact,
                    openMode: OpenCardMode.hover
                });
            }, _this.props.cardDismissDelay);
        };
        _this._instantOpenAsExpanded = function (ev) {
            _this._async.clearTimeout(_this._dismissTimerId);
            _this.setState(function (prevState) {
                if (!prevState.isHoverCardVisible) {
                    return {
                        isHoverCardVisible: true,
                        mode: ExpandingCardMode.expanded
                    };
                }
                return prevState;
            });
        };
        _this.state = {
            isHoverCardVisible: false,
            mode: ExpandingCardMode.compact,
            openMode: OpenCardMode.hover
        };
        return _this;
    }
    HoverCardBase.prototype.componentDidMount = function () {
        var target = this._getTargetElement();
        this._events.on(target, 'mouseenter', this._cardOpen);
        this._events.on(target, 'mouseleave', this._cardDismiss);
        if (this.props.trapFocus) {
            this._events.on(target, 'keydown', this._cardOpen);
        }
        else {
            this._events.on(target, 'focus', this._cardOpen);
            this._events.on(target, 'blur', this._cardDismiss);
        }
        if (this.props.instantOpenOnClick) {
            this._events.on(target, 'click', this._instantOpenAsExpanded);
        }
        else {
            this._events.on(target, 'mousedown', this._cardDismiss);
            this._events.on(target, 'keydown', this._cardDismiss);
        }
    };
    HoverCardBase.prototype.componentDidUpdate = function (prevProps, prevState) {
        var _this = this;
        if (prevState.isHoverCardVisible !== this.state.isHoverCardVisible) {
            if (this.state.isHoverCardVisible) {
                this._async.setTimeout(function () {
                    _this.setState({
                        mode: ExpandingCardMode.expanded
                    });
                }, this.props.expandedCardOpenDelay);
                this.props.onCardVisible && this.props.onCardVisible();
            }
            else {
                this.setState({
                    mode: ExpandingCardMode.compact
                });
                this.props.onCardHide && this.props.onCardHide();
            }
        }
    };
    // Render
    HoverCardBase.prototype.render = function () {
        var _a = this.props, expandingCardProps = _a.expandingCardProps, children = _a.children, id = _a.id, _b = _a.setAriaDescribedBy, setAriaDescribedBy = _b === void 0 ? true : _b, customStyles = _a.styles, theme = _a.theme, className = _a.className, type = _a.type, plainCardProps = _a.plainCardProps, trapFocus = _a.trapFocus, setInitialFocus = _a.setInitialFocus;
        var _c = this.state, isHoverCardVisible = _c.isHoverCardVisible, mode = _c.mode, openMode = _c.openMode;
        var hoverCardId = id || getId('hoverCard');
        this._classNames = getClassNames(customStyles, {
            theme: theme,
            className: className
        });
        // Common props for both card types.
        var commonCardProps = tslib_1.__assign({}, getNativeProps(this.props, divProperties), { id: hoverCardId, trapFocus: !!trapFocus, firstFocus: setInitialFocus || openMode === OpenCardMode.hotKey, targetElement: this._getTargetElement(), onEnter: this._cardOpen, onLeave: this._executeCardDismiss });
        var finalExpandedCardProps = tslib_1.__assign({}, expandingCardProps, commonCardProps, { mode: mode });
        var finalPlainCardProps = tslib_1.__assign({}, plainCardProps, commonCardProps);
        return (React.createElement("div", { className: this._classNames.host, ref: this._hoverCard, "aria-describedby": setAriaDescribedBy && isHoverCardVisible ? hoverCardId : undefined, "data-is-focusable": !Boolean(this.props.target) },
            children,
            isHoverCardVisible &&
                (type === HoverCardType.expanding ? React.createElement(ExpandingCard, tslib_1.__assign({}, finalExpandedCardProps)) : React.createElement(PlainCard, tslib_1.__assign({}, finalPlainCardProps)))));
    };
    HoverCardBase.prototype._getTargetElement = function () {
        var target = this.props.target;
        switch (typeof target) {
            case 'string':
                return getDocument().querySelector(target);
            case 'object':
                return target;
            default:
                return this._hoverCard.current || undefined;
        }
    };
    HoverCardBase.prototype._shouldBlockHoverCard = function () {
        return !!(this.props.shouldBlockHoverCard && this.props.shouldBlockHoverCard());
    };
    HoverCardBase.defaultProps = {
        cardOpenDelay: 500,
        cardDismissDelay: 100,
        expandedCardOpenDelay: 1500,
        instantOpenOnClick: false,
        setInitialFocus: false,
        openHotKey: 67 /* c */,
        type: HoverCardType.expanding
    };
    return HoverCardBase;
}(BaseComponent));
export { HoverCardBase };
//# sourceMappingURL=HoverCard.base.js.map