import Image from './Image.vue';

/**
 * 滚动回调函数
 * this指向创建时的对象
 */
function handleScroll() {
    this.items.forEach(image => {
        const el = image.$el;
        const boundingClientRect = el.getBoundingClientRect();
        image.visible = !(
            boundingClientRect.top > window.innerHeight ||
            boundingClientRect.top + boundingClientRect.height < 0 ||
            boundingClientRect.left > window.innerWidth ||
            boundingClientRect.left + boundingClientRect.width < 0
        );
    });
}


/**
 * 找到滚动父元素
 *
 */
function findScrollParents(vnode) {
    let result = [document];
    let parent = vnode.$parent;

    // 找到滚动父元素
    while (parent) {
        if (parent.$vnode) {
            const componentName = parent.$vnode.tag.match(/vue-component-\d+-(.+)$/)[1];
            switch (componentName) {
            case 'Bili_ScrollView':
                result.push(parent.$el);
                break;

            case 'Bili_Swiper':
                result.push(parent);
                break;
            }
        }
        parent = parent.$parent;
    }

    return result;
}

Image.LazyloadMap = [];

Image.install = function (Vue) {
    Vue.component('BImage', Image);

    // 注册Lazyload事件
    Vue.prototype.$_registerLazyload = function () {
        const parents = findScrollParents(this);

        parents.forEach(watchParent => {
            // 添加scroll事件监听
            if (!Image.LazyloadMap.some(curr => curr.targetParent === watchParent)) {
                const self = {
                    targetParent: watchParent,
                    items: []
                };

                Image.LazyloadMap.push(self);
                if (watchParent instanceof Vue) {
                    watchParent.$on('change', handleScroll.bind(self));
                    watchParent.$on('animationfinish', handleScroll.bind(self));
                } else {
                    let scrollTop;
                    if (watchParent === document) {
                        scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
                    } else {
                        scrollTop = self.targetParent.scrollTop;
                    }

                    if (scrollTop !== 0) {
                        handleScroll.call(self);
                    }

                    watchParent.addEventListener('scroll', handleScroll.bind(self));
                }
            }

            // 添加到该dom监听事件回调中的计算对象
            const watchObject = Image.LazyloadMap.filter((item) => item.targetParent === watchParent)[0];
            watchObject.items.push(this);

            // 先触发一次
            setTimeout(() => {
                handleScroll.call(watchObject);
            }, 0);
        });
    };

    // 销毁Lazyload事件
    Vue.prototype.$_removeLazyload = function () {
        const parents = findScrollParents(this);

        parents.forEach(watchParent => {
            const self = Image.LazyloadMap.filter(item => item.targetParent === watchParent)[0];
            self.items.forEach((item, index) => {
                if (item._uid === this._uid) {
                    self.items.splice(index, 1);
                }
            });
        });
    };
};

export default Image;
