"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var tslib_1 = require("tslib");
// Utilities
var React = require("react");
var Utilities_1 = require("../../Utilities");
var Styling_1 = require("../../Styling");
// Component Dependencies
var index_1 = require("./PositioningContainer/index");
var Beak_1 = require("./Beak/Beak");
var Coachmark_styles_1 = require("./Coachmark.styles");
var FocusZone_1 = require("../../FocusZone");
var getClassNames = Utilities_1.classNamesFunction();
var Coachmark = /** @class */ (function (_super) {
    tslib_1.__extends(Coachmark, _super);
    function Coachmark(props) {
        var _this = _super.call(this, props) || this;
        /**
         * The cached HTMLElement reference to the Entity Inner Host
         * element.
         */
        _this._entityInnerHostElement = Utilities_1.createRef();
        _this._translateAnimationContainer = Utilities_1.createRef();
        _this._positioningContainer = Utilities_1.createRef();
        _this._onFocusHandler = function () {
            _this._openCoachmark();
        };
        _this._openCoachmark = function () {
            _this.setState({
                collapsed: false
            });
            _this._translateAnimationContainer.value && _this._translateAnimationContainer.value.addEventListener('animationstart', function () {
                if (_this.props.onAnimationOpenStart) {
                    _this.props.onAnimationOpenStart();
                }
            });
            _this._translateAnimationContainer.value && _this._translateAnimationContainer.value.addEventListener('animationend', function () {
                if (_this.props.onAnimationOpenEnd) {
                    _this.props.onAnimationOpenEnd();
                }
            });
        };
        // Set defaults for state
        _this.state = {
            collapsed: props.collapsed,
            isBeaconAnimating: true,
            isMeasuring: true,
            entityInnerHostRect: {
                width: 0,
                height: 0
            },
            isMouseInProximity: false
        };
        return _this;
    }
    Coachmark.prototype.render = function () {
        var _a = this.props, children = _a.children, beakWidth = _a.beakWidth, beakHeight = _a.beakHeight, target = _a.target, width = _a.width, height = _a.height, color = _a.color, beaconColorOne = _a.beaconColorOne, beaconColorTwo = _a.beaconColorTwo;
        var classNames = getClassNames(Coachmark_styles_1.getStyles, {
            collapsed: this.state.collapsed,
            isBeaconAnimating: this.state.isBeaconAnimating,
            isMeasuring: this.state.isMeasuring,
            entityHostHeight: this.state.entityInnerHostRect.height + 'px',
            entityHostWidth: this.state.entityInnerHostRect.width + 'px',
            width: width + 'px',
            height: height + 'px',
            color: color,
            beaconColorOne: beaconColorOne,
            beaconColorTwo: beaconColorTwo
        });
        return (React.createElement(index_1.PositioningContainer, { target: target, offsetFromTarget: beakHeight, componentRef: this._positioningContainer },
            React.createElement("div", { className: classNames.root },
                React.createElement("div", { className: classNames.pulsingBeacon }),
                React.createElement("div", { className: classNames.translateAnimationContainer, ref: this._translateAnimationContainer },
                    React.createElement("div", { className: classNames.scaleAnimationLayer },
                        React.createElement("div", { className: classNames.rotateAnimationLayer },
                            this._positioningContainer.value && React.createElement(Beak_1.Beak, { width: beakWidth, height: beakHeight, left: this.state.beakLeft, top: this.state.beakTop }),
                            React.createElement(FocusZone_1.FocusZone, null,
                                React.createElement("div", { className: classNames.entityHost, "data-is-focusable": true, onFocus: this._onFocusHandler },
                                    React.createElement("div", { className: classNames.entityInnerHost, ref: this._entityInnerHostElement }, children)))))))));
    };
    Coachmark.prototype.componentWillReceiveProps = function (newProps) {
        if (this.props.collapsed && !newProps.collapsed) {
            // The coachmark is about to open
            this._openCoachmark();
        }
    };
    Coachmark.prototype.componentDidMount = function () {
        var _this = this;
        this._async.requestAnimationFrame((function () {
            if (_this._entityInnerHostElement.value && (_this.state.entityInnerHostRect.width + _this.state.entityInnerHostRect.width) === 0) {
                // @TODO Eventually we need to add the various directions
                var beakLeft = (_this.props.width / 2) - (_this.props.beakWidth / 2);
                var beakTop = 0;
                _this.setState({
                    isMeasuring: false,
                    entityInnerHostRect: {
                        width: _this._entityInnerHostElement.value.offsetWidth,
                        height: _this._entityInnerHostElement.value.offsetHeight
                    },
                    beakLeft: beakLeft + 'px',
                    beakTop: beakTop + 'px'
                });
                _this.forceUpdate();
            }
            // We dont want to the user to immediatley trigger the coachmark when it's opened
            _this._async.setTimeout(function () {
                _this._addProximityHandler(100);
            }, _this.props.delayBeforeMouseOpen);
        }));
    };
    Coachmark.prototype._addProximityHandler = function (mouseProximityOffset) {
        var _this = this;
        if (mouseProximityOffset === void 0) { mouseProximityOffset = 0; }
        /**
         * An array of cached ids returned when setTimeout runs during
         * the window resize event trigger.
         */
        var timeoutIds = [];
        /**
         * The target element the mouse would be in
         * proximity to
         */
        var targetElementRect;
        // Take the initial measure out of the initial render to prevent
        // an unnecessary render.
        this._async.setTimeout(function () {
            if (_this._entityInnerHostElement.value) {
                targetElementRect = _this._entityInnerHostElement.value.getBoundingClientRect();
            }
            // When the window resizes we want to async
            // get the bounding client rectangle.
            // Every time the event is triggered we want to
            // setTimeout and then clear any previous instances
            // of setTimeout.
            _this._events.on(window, 'resize', function () {
                timeoutIds.forEach(function (value) {
                    clearInterval(value);
                });
                timeoutIds.push(_this._async.setTimeout(function () {
                    if (_this._entityInnerHostElement.value) {
                        targetElementRect = _this._entityInnerHostElement.value.getBoundingClientRect();
                    }
                }, 100));
            });
        }, 10);
        // Every time the document's mouse move is triggered
        // we want to check if inside of an element and
        // set the state with the result.
        this._events.on(document, 'mousemove', function (e) {
            var mouseY = e.pageY;
            var mouseX = e.pageX;
            var isMouseInProximity = _this._isInsideElement(mouseX, mouseY, targetElementRect, mouseProximityOffset);
            if (isMouseInProximity !== _this.state.isMouseInProximity) {
                // We don't want to update the isMouseInProximtiy state because
                // The coachmark only opens and does not collapse.
                // Setting isMouseInProximity here will cause the coachmark to open and close
                _this.setState({
                    collapsed: !isMouseInProximity
                });
            }
            if (_this.props.onMouseMove) {
                _this.props.onMouseMove(e);
            }
        });
    };
    Coachmark.prototype._isInsideElement = function (mouseX, mouseY, elementRect, mouseProximityOffset) {
        if (mouseProximityOffset === void 0) { mouseProximityOffset = 0; }
        return mouseX > (elementRect.left - mouseProximityOffset) &&
            mouseX < ((elementRect.left + elementRect.width) + mouseProximityOffset) &&
            mouseY > (elementRect.top - mouseProximityOffset) &&
            mouseY < ((elementRect.top + elementRect.height) + mouseProximityOffset);
    };
    Coachmark.defaultProps = {
        collapsed: true,
        mouseProximityOffset: 100,
        beakWidth: 26,
        beakHeight: 12,
        delayBeforeMouseOpen: 3600,
        width: 36,
        height: 36,
        beaconColorOne: '#00FFEC',
        beaconColorTwo: '#005EDD',
        color: Styling_1.DefaultPalette.themePrimary
    };
    return Coachmark;
}(Utilities_1.BaseComponent));
exports.Coachmark = Coachmark;
//# sourceMappingURL=Coachmark.js.map