<template>
    <div class="nut-vert-scroll" ref="wrapper">
        <div class="nut-vert-list" ref="list">
            <div class="nut-vert-pulldown">
                <div class="nut-vert-pulldown-txt" v-if="!isLoading">{{pulldownTxt}}</div>
                <div class="nut-vert-pulldown-status" v-else>
                    <span class="nut-vert-loading"></span>
                    <span class="nut-vert-loading-txt">加载中...</span>
                </div>
            </div>
            <slot name="list"></slot>
            <div class="nut-vert-loadmore" v-if="!isUnMore && isShowLoadMore">
                <div class="nut-vert-load-txt" v-if="!isLoading">{{loadMoreTxt}}</div>
                <div class="nut-vert-load-status" v-else>
                    <span class="nut-vert-loading"></span>
                    <span class="nut-vert-loading-txt">加载中...</span>
                </div>
            </div>
            <div v-else-if="isUnMore" class="nut-vert-unloadmore" >
                <div class="nut-vert-unloadmore-txt">{{unloadMoreTxt}}</div>
            </div>
        </div>
    </div>
</template>
<script>
export default {
    name:'nut-vert-scroll',
    props: {
        stretch: {
            type: Number,
            default: 50
        },
        isUnMore: {
            type: Boolean,
            default: false
        },
        isLoading: {
            type: Boolean,
            default: false
        },
        pulldownTxt: {
            type: String,
            default: '下拉刷新'
        },
        loadMoreTxt: {
            type: String,
            default: '上拉加载'
        },
        unloadMoreTxt: {
            type: String,
            default: '没有更多了'
        },
        isLazyLoadImg: {
            type: Boolean,
            default: false
        }
    },
    watch: {
        'isLoading': function(status) {
            if (!status && this.realMove === 0) {
                clearTimeout(this.timer);
                this.setTransform(this.realMove, 'end', 0);
            }
        },
        'isUnMore': function() {
            this.isShow();
        }
    },
    data() {
        return {
            touchParams: {
                startY: 0, 
                endY: 0, 
                startTime: 0, 
                endTime: 0
            },
            translateY: 0,
            scrollDistance: 0,
            timer: null,
            timerEmit: null,
            realMove: 0,
            isShowLoadMore: false
        }
    },

    methods: {
        isShow() {
            let wrapH = this.$refs.wrapper.offsetHeight;
            let listH = this.$refs.list.offsetHeight;
            if (wrapH <= listH) {
                this.isShowLoadMore = true;
            } else {
                this.isShowLoadMore = false;
            }
        },

        setTransform(translateY = 0, type, time = 500) {
            if (type === 'end') {
                this.$refs.list.style.webkitTransition = `transform ${time}ms cubic-bezier(0.19, 1, 0.22, 1)`;
            } else {
                this.$refs.list.style.webkitTransition = '';
            }
            this.$refs.list.style.webkitTransform = `translate3d(0, ${translateY}px, 0)`;
            this.scrollDistance = translateY;
        },

        setMove(move, type, time) {
            let updateMove = move + this.translateY;
            let h = this.$refs.wrapper.offsetHeight;
            let maxMove = -this.$refs.list.offsetHeight + h;
            if (type === 'end') {
                if (updateMove > 0) {
                    updateMove = 50;
                    this.realMove = 0;
                    if (!this.isLoading) {
                        clearTimeout(this.timerEmit);
                        this.timerEmit = setTimeout(() => {
                            this.$emit('pulldown');
                        }, time / 2);
                    }
                } else if (updateMove < maxMove) {
                    if (maxMove <= 0) {
                        updateMove = maxMove;
                    } else {
                        updateMove = 0;
                    }
                    this.realMove = maxMove;
                    if (!this.isLoading && !this.isUnMore) {
                        clearTimeout(this.timerEmit);
                        this.timerEmit = setTimeout(() => {
                            this.$emit('loadMore');
                        }, time / 2);
                    }
                }
                if (updateMove == 50 && !this.isLoading) {
                    clearTimeout(this.timer);
                    this.timer = setTimeout(() => {
                        this.setTransform(this.realMove, 'end', null);
                    }, 3000);
                }
                this.setTransform(updateMove, type, time)
            } else {
                // if (updateMove > 0 && updateMove > this.stretch) {
                //     updateMove = this.stretc;
                // } else if (updateMove < maxMove - this.stretch) {
                //     updateMove = maxMove - this.stretch;
                // }
                this.setTransform(updateMove, null, null);
            }
        },
	
	    touchStart(event) {
            event.preventDefault();

            let changedTouches = event.changedTouches[0];
            this.touchParams.startY = changedTouches.pageY;
            this.touchParams.startTime = event.timestamp || Date.now();
            this.translateY = this.scrollDistance;
        },

        touchMove(event) {

            let changedTouches = event.changedTouches[0];
            this.touchParams.lastY = changedTouches.pageY;
            this.touchParams.lastTime = event.timestamp || Date.now();
            let move = this.touchParams.lastY - this.touchParams.startY;

            this.setMove(move);
        },

        touchEnd(event) {
            event.preventDefault();

            let changedTouches = event.changedTouches[0];
            this.touchParams.lastY = changedTouches.pageY;
            this.touchParams.lastTime = event.timestamp || Date.now();
            let move = this.touchParams.lastY - this.touchParams.startY;

            let moveTime = this.touchParams.lastTime - this.touchParams.startTime;
            let h = this.$refs.wrapper.offsetHeight;
            let maxMove = -this.$refs.list.offsetHeight + h;

            if (moveTime <= 300) {
                move = move * 2;
                if (move < 0 && move < maxMove) {
                    move = maxMove;
                }
                moveTime = moveTime + 500;
                this.setMove(move, 'end', moveTime);
            } else {
                this.setMove(move, 'end');
            }
        }
    },

    mounted() {
        this.$nextTick(() => {
            this.isShow();
            // 监听
            this.$el.addEventListener('touchstart', this.touchStart);
            this.$el.addEventListener('touchmove', this.touchMove);
            this.$el.addEventListener('touchend', this.touchEnd);
        });
    },
    beforeDestroy() {
        // 移除监听
        this.$el.removeEventListener('touchstart', this.touchStart);
        this.$el.removeEventListener('touchmove', this.touchMove);
        this.$el.removeEventListener('touchend', this.touchEnd);
        clearTimeout(this.timer);
        clearTimeout(this.timerEmit);
    }
}
</script>

