'use strict';

Object.defineProperty(exports, "__esModule", {
    value: true
});

var _jsx = function () { var REACT_ELEMENT_TYPE = typeof Symbol === "function" && Symbol.for && Symbol.for("react.element") || 0xeac7; return function createRawReactElement(type, props, key, children) { var defaultProps = type && type.defaultProps; var childrenLength = arguments.length - 3; if (!props && childrenLength !== 0) { props = {}; } if (props && defaultProps) { for (var propName in defaultProps) { if (props[propName] === void 0) { props[propName] = defaultProps[propName]; } } } else if (!props) { props = defaultProps || {}; } if (childrenLength === 1) { props.children = children; } else if (childrenLength > 1) { var childArray = Array(childrenLength); for (var i = 0; i < childrenLength; i++) { childArray[i] = arguments[i + 3]; } props.children = childArray; } return { $$typeof: REACT_ELEMENT_TYPE, type: type, key: key === undefined ? null : '' + key, ref: null, props: props, _owner: null }; }; }();

var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var _View = require('../View');

var _View2 = _interopRequireDefault(_View);

var _Teleport = require('../Teleport');

var _Teleport2 = _interopRequireDefault(_Teleport);

var _Popup = require('../Popup');

var _Popup2 = _interopRequireDefault(_Popup);

var _Transition = require('../Transition');

var _Transition2 = _interopRequireDefault(_Transition);

var _AutoClosable = require('../AutoClosable');

var _AutoClosable2 = _interopRequireDefault(_AutoClosable);

var _styles = require('../helpers/styles');

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var Modal = function (_React$Component) {
    _inherits(Modal, _React$Component);

    function Modal(props) {
        var _ref;

        _classCallCheck(this, Modal);

        for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
            args[_key - 1] = arguments[_key];
        }

        var _this = _possibleConstructorReturn(this, (_ref = Modal.__proto__ || Object.getPrototypeOf(Modal)).call.apply(_ref, [this, props].concat(args)));

        _this.state = {
            isShown: false
        };

        _this._onShowHandler = _this._onShowHandler.bind(_this);
        _this._onCloseHandler = _this._onCloseHandler.bind(_this);
        _this._onDidLeaveHandler = _this._onDidLeaveHandler.bind(_this);
        _this._isBodyScrollDisabled = null;
        _this._prevBodyOverflow = null;

        _this._onDidShowCallbacks = [];
        _this._onDidHideCallbacks = [];
        return _this;
    }

    _createClass(Modal, [{
        key: 'componentDidMount',
        value: function componentDidMount() {
            this.props.isShown && this.show();
        }
    }, {
        key: 'componentWillUnmount',
        value: function componentWillUnmount() {
            this._enableRootScroll();
        }
    }, {
        key: 'componentWillReceiveProps',
        value: function componentWillReceiveProps(nextProps) {
            if (nextProps.isShown !== this.props.isShown) {
                nextProps.isShown ? this.show() : this.hide();
            }
        }
    }, {
        key: 'show',
        value: function show(callback) {
            var _this2 = this;

            callback && this._onDidShowCallbacks.push(callback);

            this.setState({ isShown: true }, function () {
                return _this2._disableRootScroll();
            });
        }
    }, {
        key: 'hide',
        value: function hide(callback) {
            callback && this._onDidHideCallbacks.push(callback);

            this.setState({ isShown: false });
        }
    }, {
        key: '_renderChildren',
        value: function _renderChildren() {
            var props = this.props;

            return _react2.default.Children.map(props.children, function (child) {
                if (child && child.type && child.type.__MODAL_HEADER__) {
                    return _react2.default.cloneElement(child, {
                        onClose: props.onClose
                    });
                }

                return child;
            });
        }
    }, {
        key: '_disableRootScroll',
        value: function _disableRootScroll() {
            if (typeof document !== 'undefined' && !this._isBodyScrollDisabled) {
                var parentDOMNodeWithScroll = this._getParentDOMNodeWithScroll();

                this._isBodyScrollDisabled = true;
                this._prevBodyOverflow = parentDOMNodeWithScroll.style.overflow;
                parentDOMNodeWithScroll.style.overflow = 'hidden';
            }
        }
    }, {
        key: '_enableRootScroll',
        value: function _enableRootScroll() {
            if (typeof document !== 'undefined' && this._isBodyScrollDisabled) {
                this._isBodyScrollDisabled = false;

                this._getParentDOMNodeWithScroll().style.overflow = this._prevBodyOverflow;
            }
        }
    }, {
        key: '_onShowHandler',
        value: function _onShowHandler() {
            var callbacks = this._onDidShowCallbacks;

            this._onDidShowCallbacks = [];

            callbacks.forEach(function (callback) {
                return callback();
            });

            this.props.onDidShow && this.props.onDidShow();
        }
    }, {
        key: '_onCloseHandler',
        value: function _onCloseHandler() {
            var _props = this.props,
                isAutoClosable = _props.isAutoClosable,
                onClose = _props.onClose;


            isAutoClosable && onClose && onClose();
        }
    }, {
        key: '_onDidLeaveHandler',
        value: function _onDidLeaveHandler() {
            var callbacks = this._onDidHideCallbacks;

            this._onDidHideCallbacks = [];
            callbacks.forEach(function (callback) {
                return callback();
            });

            this._enableRootScroll();
            this.props.onDidClose && this.props.onDidClose();
        }
    }, {
        key: '_getParentDOMNodeWithScroll',
        value: function _getParentDOMNodeWithScroll() {
            if (!this._parentDOMNodeWithScroll) {
                var rootDOMNode = this._getRootDOMNode();

                this._parentDOMNodeWithScroll = rootDOMNode && getParentDOMNodeWithScroll(rootDOMNode) || document.getElementsByTagName('body')[0];
            }

            return this._parentDOMNodeWithScroll;
        }
    }, {
        key: '_getRootDOMNode',
        value: function _getRootDOMNode() {
            if (!this._teleport) {
                return null;
            }

            if (!this._rootDOMNode) {
                this._rootDOMNode = this._teleport.getRootDOMNode();
            }

            return this._rootDOMNode;
        }
    }, {
        key: 'render',
        value: function render() {
            var _this3 = this;

            var _props2 = this.props,
                zIndex = _props2.zIndex,
                popupStyles = _props2.popupStyles;


            return _react2.default.createElement(
                _Teleport2.default,
                { ref: function ref(c) {
                        return _this3._teleport = c;
                    } },
                _jsx(_Transition2.default, {
                    timeout: 200,
                    leaveTimeout: 400,
                    onDidEnter: this._onShowHandler,
                    onDidLeave: this._onDidLeaveHandler
                }, void 0, this.state.isShown && function (_ref2) {
                    var isEnter = _ref2.isEnter,
                        isLeave = _ref2.isLeave;
                    return _jsx(_View2.default, {
                        style: { zIndex: zIndex },
                        styles: [styles.overlay, isEnter && styles.shownOverlay, isLeave && styles.leaveOverlay]
                    }, void 0, _jsx(_View2.default, {
                        styles: [styles.inner, isEnter && styles.shownInner, isLeave && styles.leaveInner]
                    }, void 0, _jsx(_AutoClosable2.default, {
                        onClose: _this3._onCloseHandler
                    }, void 0, _jsx(_Teleport.TeleportContext, {}, void 0, _jsx(_View2.default, {
                        styles: [styles.popupWrapper]
                    }, void 0, _jsx(_Popup2.default, {
                        popupStyles: popupStyles,
                        isRounded: true
                    }, void 0, _this3._renderChildren()))))));
                })
            );
        }
    }]);

    return Modal;
}(_react2.default.Component);

Modal.defaultProps = {
    zIndex: 999,
    popupStyles: {
        padding: 0,
        minHeight: 400,
        minWidth: 720,
        flexDirection: 'column',
        overflow: 'hidden'
    }
};
exports.default = Modal;


function getParentDOMNodeWithScroll(parentDOMNode) {
    if (!parentDOMNode) {
        return null;
    }

    var clientWidth = parentDOMNode.clientWidth;
    var clientHeight = parentDOMNode.clientHeight;

    var scrollWidth = parentDOMNode.scrollWidth;
    var scrollHeight = parentDOMNode.scrollHeight;

    if (clientWidth === undefined) {
        return null;
    }

    if (clientWidth || clientHeight) {

        var isCanScroll = ['overflow', 'overflow-x', 'overflow-y'].some(function (key) {
            return (/auto|scroll/.test(window.getComputedStyle(parentDOMNode)[key])
            );
        });

        if (isCanScroll && (clientWidth !== scrollWidth || clientHeight !== scrollHeight)) {
            return parentDOMNode;
        }
    }

    return getParentDOMNodeWithScroll(parentDOMNode.parentNode);
}

var styles = _styles.StyleSheet.create({
    overlay: {
        position: 'fixed',
        top: 0,
        right: 0,
        left: 0,
        bottom: 0,
        transform: 'translate3d(0, 0, 0)',
        transition: 'all .2s ease-out',
        background: 'rgba(0, 0, 0, 0)',
        overflow: 'auto'
    },
    inner: {
        minWidth: '100%',
        alignItems: 'flex-start',
        justifyContent: 'center',
        transition: 'all .2s cubic-bezier(0.175, 0.885, 0.32, 1.275)',
        transform: 'translate3d(0, 0, 0) scale(.9)',
        opacity: 0
    },
    popupWrapper: {
        margin: '4.4rem 140px 5rem 140px'
    },
    shownOverlay: {
        background: 'rgba(0, 0, 0, .4)'
    },
    shownInner: {
        transform: 'translate3d(0, 0, 0) scale(1)',
        opacity: 1
    },
    leaveInner: {
        transition: 'all .4s cubic-bezier(0.165, 0.84, 0.44, 1)'
    },
    leaveOverlay: {
        transition: 'all .4s cubic-bezier(0.165, 0.84, 0.44, 1)'
    }
});