import _defineProperty from 'babel-runtime/helpers/defineProperty';
import _objectWithoutProperties from 'babel-runtime/helpers/objectWithoutProperties';
import _classCallCheck from 'babel-runtime/helpers/classCallCheck';
import _createClass from 'babel-runtime/helpers/createClass';
import _possibleConstructorReturn from 'babel-runtime/helpers/possibleConstructorReturn';
import _inherits from 'babel-runtime/helpers/inherits';
var _jsxFileName = 'src/affix/Affix.jsx';
/**
 * Affix.jsx
 *
 * @Author: zhangce
 * @Date: 18/3/23 下午4:20
 */

import React from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';

var getElementLeft = function getElementLeft(element) {
    var actualLeft = element.offsetLeft;
    var current = element.offsetParent;
    while (current !== null) {
        actualLeft += current.offsetLeft;
        current = current.offsetParent;
    }
    return actualLeft;
};
var getElementTop = function getElementTop(element) {
    var actualTop = element.offsetTop;
    var current = element.offsetParent;
    while (current !== null) {
        actualTop += current.offsetTop;
        current = current.offsetParent;
    }
    return actualTop;
};

/**
 * Affix
 * */

var Affix = function (_React$PureComponent) {
    _inherits(Affix, _React$PureComponent);

    function Affix(props, context) {
        _classCallCheck(this, Affix);

        var _this = _possibleConstructorReturn(this, (Affix.__proto__ || Object.getPrototypeOf(Affix)).call(this, props, context));

        _this.handleTargetScroll = function () {
            var _this$props = _this.props,
                offsetTop = _this$props.offsetTop,
                offsetBottom = _this$props.offsetBottom;

            var isWindowContainer = _this.targetEle === window;
            var affixHeight = _this.affix.clientHeight;
            var affixClientWidth = _this.affix.clientWidth;
            var scrollTop = isWindowContainer ? document.documentElement.scrollTop : _this.targetEle.scrollTop;
            var targetOffsetHeight = window.frameElement ? window.frameElement.offsetHeight : document.documentElement.clientHeight;
            var condition = void 0;
            var style = {
                position: 'fixed',
                left: getElementLeft(_this.affix),
                zIndex: 10
            };

            if (offsetBottom === void 0) {
                condition = scrollTop > getElementTop(_this.affix) - offsetTop;
                style.top = isWindowContainer ? offsetTop : getElementTop(_this.targetEle) + offsetTop;
            } else {
                condition = targetOffsetHeight - (getElementTop(_this.affix) - scrollTop) - affixHeight <= offsetBottom;
                style.bottom = isWindowContainer ? offsetBottom : getElementTop(_this.targetEle) + _this.targetEle.offsetHeight - _this.affix.offsetHeight - offsetBottom;
            }

            if (condition) {
                _this.setState({
                    style: style,
                    containerStyle: {
                        width: affixClientWidth,
                        height: affixHeight
                    },
                    affixed: true
                });
            } else {
                _this.setState({
                    style: {},
                    containerStyle: {},
                    affixed: false
                });
            }
        };

        _this.state = {
            style: {},
            containerStyle: {},
            affixed: false
        };
        return _this;
    }

    _createClass(Affix, [{
        key: 'componentDidMount',
        value: function componentDidMount() {
            var target = this.props.target;

            this.targetEle = target();
            this.targetEle.addEventListener('scroll', this.handleTargetScroll, false);
            this.handleTargetScroll();
        }
    }, {
        key: 'componentDidUpdate',
        value: function componentDidUpdate(prevProps, prevState) {
            var onChange = this.props.onChange;

            if (prevState.affixed !== this.state.affixed) {
                onChange && onChange(this.state.affixed);
            }
        }
    }, {
        key: 'render',
        value: function render() {
            var _this2 = this;

            var _props = this.props,
                children = _props.children,
                offsetBottom = _props.offsetBottom,
                offsetTop = _props.offsetTop,
                target = _props.target,
                onChange = _props.onChange,
                prefixCls = _props.prefixCls,
                other = _objectWithoutProperties(_props, ['children', 'offsetBottom', 'offsetTop', 'target', 'onChange', 'prefixCls']);

            var _state = this.state,
                style = _state.style,
                containerStyle = _state.containerStyle,
                affixed = _state.affixed;

            var classStr = classNames(_defineProperty({}, prefixCls, affixed));
            return React.createElement(
                'div',
                Object.assign({ style: containerStyle, ref: function ref(_ref) {
                        return _this2.affix = _ref;
                    } }, other, {
                    __source: {
                        fileName: _jsxFileName,
                        lineNumber: 134
                    },
                    __self: this
                }),
                React.createElement(
                    'div',
                    { className: classStr, style: style, __source: {
                            fileName: _jsxFileName,
                            lineNumber: 135
                        },
                        __self: this
                    },
                    children
                )
            );
        }
    }]);

    return Affix;
}(React.PureComponent);

Affix.displayName = 'NeatUI.Affix';
Affix.propTypes = {
    /**
     * 距离窗口底部达到指定偏移量后触发
     * */
    offsetBottom: PropTypes.number,
    /**
     * 距离窗口顶部达到指定偏移量后触发
     * */
    offsetTop: PropTypes.number,
    /**
     * 设置 `Affix` 需要监听其滚动事件的元素，值为一个返回对应 DOM 元素的函数
     * */
    target: PropTypes.func,
    /**
     * 固定状态改变时触发的回调函数
     * */
    onChange: PropTypes.func
};
Affix.defaultProps = {
    prefixCls: 'ne-affix',
    offsetTop: 0,
    target: function target() {
        return window;
    }
};


export default Affix;