<script>
/* eslint-disable */
import { callFn } from 'nimble-lib';
import DrawerBase from './DrawerBase';
import { REG_NUM, STATUS_TYPE, MOVING_DIRECTION } from './constants';
export default {
    extends: DrawerBase,
    methods: {
        /**
         * 计算每个模块的宽度增加／减少的比例
         * @param {Array} listWidth 列表中的每个模块的宽度
         * @returns {Array} 返回每个模块的宽度增加／减少的比例
         */
        _calculateRatio (listWidth) {
            const _that = this;
            let _ratios;
            if (listWidth.length > 0) {
                const _maxW = Math.max(_that.maxDisWidth, Math.max.apply(null, listWidth));
                _ratios = [];
                listWidth.forEach((item) => {
                    if (item) {
                        const _ratio = (item / _maxW).toFixed(6);
                        _ratios.push(parseFloat(_ratio));
                    }
                });
            }
            return _ratios;
        },
        /**
         * 计算每个模块的宽度
         * @param {Array} listItems 模块dom元素列表
         * @returns {Array} 返回每个模块的宽度
         */
        _calculateWidth (listItems) {
            let _res = [];
            if (listItems && listItems.length > 0) {
                for (let i = 0; i < listItems.length; i++) {
                    const _item = listItems[i] || {};
                    let _width = 0;
                    if (typeof _item.offsetWidth !== 'undefined') {
                        _width = _item.offsetWidth;
                    } else {
                        _width = (_item.elm && _item.elm.offsetWidth) || 0;
                    }
                    _res.push(_width);
                }
            }
            return _res;
        },
        /**
         * 设置每个模块的宽度和主内容的位置
         */
        _resetWidthPos () {
            const _that = this;
            if (_resetWidthPos()) {
                if (_that.bounce) {
                    _that._setTransiton(_that.bounceTime);
                }
                return;
            }
            let _dir = _isShowR();
            if (_dir === 1) {
                _that._showR(_that.duration);
            } else if (_dir === -1) {
                _that._hideR(_that.duration);
            }
            /**
             * 是否展开右边
             * @returns {String} 返回是否展开右边
             */
            function _isShowR () {
                let _rate = Math.abs(_that.distX) / _that.maxDisWidth;
                if (_that.movingDirection === MOVING_DIRECTION.RIGHT) {
                    return _rate >= _that.rate ? -1 : 1;
                } else if (_that.movingDirection === MOVING_DIRECTION.LEFT) {
                    return _rate >= _that.rate ? 1 : -1;
                }
            }
            /**
             * 重置每个模块的宽度
             * @returns {Boolean} 返回是否修改了主内容区的位置／每个模块的宽度
             */
            function _resetWidthPos () {
                let _itemWidth = _that.itemWidth;
                const _maxDisWidth = _that.maxItemWidth;
                let _res = false;
                _itemWidth = _itemWidth.map((item, index) => {
                    if (item < 0) {
                        item = 0;
                        _res = true;
                    } else if (item > (_maxDisWidth[index] || 0)) {
                        item = _maxDisWidth[index] || 0;
                        _res = true;
                    }
                    return item;
                });
                let _newX = _that.x;
                let _absNewX = Math.abs(_that.x);
                if (_absNewX > _that.maxDisWidth) {
                    _newX = -(_that.maxDisWidth);
                    _res = true;
                }
                if (_res) {
                    _that._setWidthPos(null, _itemWidth, _newX);
                }
                return _res;
            }
        },
        /**
         * 设置每个模块的宽度和左边内容块的位置
         * @param {Number} deltaX 滑动偏移量
         * @param {Number} newW 每个模块的新的大小
         * @param {Number} newX 新的位置
         */
        _setWidthPos (deltaX, newW, newX) {
            const _that = this;
            const _fixed = (_that.fixed || 0) + '';
            let _widthDeltaX = deltaX;
            if (_that.type + '' === '1') {
                if (_fixed === '-1') {
                    newX = 0;
                    deltaX = 0;
                } else if (_fixed === '1') {
                    newW = null;
                    _widthDeltaX = 0;
                }
            }
            _that._setContPos(deltaX, newX);
            _that._setItemWidth(_widthDeltaX, newW);
        },
        /**
         * 设置左边内容块的位置
         * @param {Number} deltaX 偏移位置
         * @param {Number} newX 新的位置
         */
        _setContPos (deltaX, newX) {
            const _that = this;
            let _newX = 0;
            if (newX || newX === 0) {
                _newX = newX;
            } else {
                _newX = _that.x + deltaX;
            }
            if (_newX === _that.x) {
                return;
            }
            if (_newX <= 0) {
                if (Math.abs(_newX) > _that.maxDisWidth) {
                    if (_that.bounce) {
                        _newX = _that.x + deltaX / 6;
                    } else {
                        _newX = -_that.maxDisWidth;
                    }
                }
            } else {
                _newX = 0;
            }
            _that.x = _newX;
        },
        /**
         * 设置按钮的大小
         * @param {Number} offsetX 偏移位置
         * @param {Array} newW 每个模块的新的大小
         */
        _setItemWidth (offsetX, newW) {
            const _that = this;
            offsetX = -offsetX;
            if (newW && newW.length > 0) {
                _that.itemWidth = newW.map((item, index) => {
                    return _filterItemWidth(index, item);
                });
            } else {
                _that.itemWidth = _that.itemWidth.map((item, index) => {
                    const _ratios = _that.ratios || [];
                    const _ratio = _ratios[index] || 1;
                    item = _filterNum(item);
                    offsetX = _filterNum(offsetX);
                    const _deltaW = _ratio * offsetX;
                    return _filterItemWidth(index, item + _deltaW, item, _deltaW);
                });
            }
            /**
             * 计算每项模块的宽度
             * @param {Number} index 索引
             * @param {Number} _newW 新的模块宽度
             * @param {Number} width 模块宽度
             * @param {Number} mOffsetX 变化的宽度
             * @returns {Number} 返回模块的新的宽度
             */
            function _filterItemWidth (index, _newW, width, mOffsetX) {
                const _maxItemW = _that.maxItemWidth[index];
                if (_newW < 0) {
                    _newW = 0;
                } else if (_newW > _maxItemW) {
                    if (_that.bounce && mOffsetX) {
                        _newW = width + mOffsetX / 6;
                    } else {
                        _newW = _maxItemW;
                    }
                }

                return _newW;
            }
            /**
             * 过滤数字
             * @param {Number} num 数字
             * @returns {Number} 返回过滤后的数字
             */
            function _filterNum (num) {
                let _num = (num || '0') + '';
                if (!REG_NUM.test(_num)) {
                    _num = '0';
                }
                _num = parseFloat(_num);
                return _num;
            }
        },
        /**
         * 设置基础数据
         * @param {Function} cb 回调方法
         */
        _setBasicData (cb) {
            const _that = this;
            _that.x = 0; // 初始的滚动位置
            _that.listItems = _that._getListItemsDom(); // 获取右边内容快的元素
            _that.maxItemWidth = callFn(cb || [], [_that.listItems], _that); // 每项模块的默认宽度
            _getMaxWidth(); // 最大可以滑动的距离
            _filterMaxItemW();
            _that.ratios = _that._calculateRatio(_that.maxItemWidth); // 每项模块的宽度增加／减少比率
            _that.itemWidth = new Array((_that.listItems && _that.listItems.length) || 0).fill(0); // 每项模块的当前宽度
            _that.status = STATUS_TYPE.HIDDEN;
            /**
             * 获取右侧最大宽度
             */
            function _getMaxWidth () {
                // 最大可以滑动的距离
                let _totalW = _that.maxItemWidth.reduce((total, item) => {
                    return total + item;
                }, 0);
                let _rootElW = _that.$el.offsetWidth;
                let _maxDisWidth = _totalW;
                if (_that.myMinWidth) {
                    _maxDisWidth = Math.max(_maxDisWidth, _that.myMinWidth * _rootElW);
                }
                if (_that.myMaxWidth) {
                    _maxDisWidth = Math.min(_maxDisWidth, _that.myMaxWidth * _rootElW);
                }
                _that.maxDisWidth = _maxDisWidth;
                _that.scale = _that.maxDisWidth / _totalW;
            }
            /**
             * 过滤每个模块最大的宽度
             */
            function _filterMaxItemW () {
                let _scale = _that.scale || 1;
                _that.maxItemWidth = _that.maxItemWidth.map((item) => {
                    return item ? item * _scale : _that.maxDisWidth;
                });
            }
        },
        /**
         * 处理水平／垂直方向的偏移量
         * @param {Event} evt 事件对象
         * @returns {Number} 返回水平偏移量
         */
        _handleDelta (evt) {
            const _that = this;
            let _point = evt.touches ? evt.touches[0] : evt;
            let _deltaX = _point.pageX - _that.pointX;
            _that.pointX = _point.pageX;
            let _deltaY = _point.pageY - _that.pointY;
            _that.pointY = _point.pageY;
            let absDistX = Math.abs(_that.distX + _deltaX);
            let absDistY = Math.abs(_that.distY + _deltaY);
            if (!_that.directionLocked) {
                if (absDistX >= absDistY) { // lock horizontally
                    _that.directionLocked = 'h';
                } else { // lock vertically
                    _that.directionLocked = 'v';
                }
            }
            if (_that.directionLocked === 'v') {
                _deltaX = 0;
            } else if (_that.directionLocked === 'h') {
                _deltaY = 0;
                evt.cancelable && evt.preventDefault();
            }
            if (!_that.movingDirection) {
                if (_deltaX > 0) {
                    _that.movingDirection = MOVING_DIRECTION.RIGHT;
                } else if (_deltaX < 0) {
                    _that.movingDirection = MOVING_DIRECTION.LEFT;
                }
            }
            if (_that.movingDirection === MOVING_DIRECTION.LEFT) {
                const _itemsWidth = (_that.itemWidth || []).reduce((total, item) => {
                    return total + item;
                }, 0);
                if (_itemsWidth >= _that.maxDisWidth) {
                    _that.movingDirection = MOVING_DIRECTION.NO;
                }
            }
            _that.distX += _deltaX;
            _that.distY += _deltaY;
            return _deltaX;
        }
    }
};
</script>
