<!-- webview only --><!-- slot -->
<template>
    <section :class="['bl___image-container', {'lazyload': !!lazyLoad}]" :style="isWidthFix ? imageStyle : {}" @click.capture="$emit('click', $event)" @touchstart.capture="$emit('touchstart', $event)" @touchmove.capture="$emit('touchmove', $event)" @touchend.capture="$emit('touchend', $event)" @touchcancel.capture="$emit('touchcancel', $event)">
        <img :src="imageSrc" v-show="!!imageSrc" ref="image" :style="imageStyle" v-if="isWidthFix" class="bl___image" @load="imgLoaded" />
        <section class="bl___image-wrapper" :style="styleObj" v-else></section>
        <section class="bl___image-content-wrapper">
            <slot></slot>
        </section>
    </section>
</template>

<script>
const parseDataset = function (dataset) {
    let result = {};
    for (let key in dataset) {
        try {
            result[key] = JSON.parse(dataset[key]);
        } catch (e) {
            result[key] = dataset[key];
        }
    }
    return result;
};

export default {
    name: 'Bili_Image',
    props: {
        src: {
            type: String
        },
        mode: {
            type: String,
            default: 'scaleToFill',
        },
        lazyLoad: {
            type: [Boolean, String],
            default: false
        }
    },
    data() {
        return {
            image: new Image(),
            imageSrc: false,
            visible: false,
        }
    },
    watch: {
        src(value) {
            this.loadImage();
        },
        visible(value) {
            value && this.loadImage();
        }
    },
    computed: {
        isWidthFix() {
            return this.mode === 'widthFix';
        },
        imageStyle() {
            switch (this.mode) {
                case 'scaleToFill': {
                    return {
                        'background-size': '100% 100%',
                    }
                }

                case 'aspectFit': {
                    return {
                        'background-position': 'center',
                        'background-size': 'contain'
                    }
                }

                case 'aspectFill': {
                    return {
                        'background-position': 'center',
                        'background-size': 'cover'
                    }
                }

                case 'widthFix': {
                    return { 'height': 'auto !important' }
                }

                case 'top':
                case 'bottom':
                case 'center':
                case 'left':
                case 'right':
                case 'top left':
                case 'top right':
                case 'bottom left':
                case 'bottom right': {
                    return {
                        'background-position': this.mode
                    }
                }

                default: {
                    return {
                        'background-size': '100% 100%',
                    }
                }
            }
        },
        styleObj() {
            Vue.nextTick(this.imgLoaded.bind(this));
            return Object.assign({},
             this.imageStyle,
             {
                 'background-image': this.imageSrc ? `url('${this.imageSrc}')` : '',
            });
        }
    },
    created() {
        // 触发事件
        this.image.onload = () => {
            const elementInfo = {id: this.$el.id, dataset: parseDataset(this.$el.dataset)};
            const event = {
                target: elementInfo,
                currentTarget: elementInfo,
                detail: { width: this.image.width, height: this.image.height }
            };
            this.$emit('load', event);
            this.imageSrc = this.image.src;
        };
        this.image.onerror = (e) => {
            const elementInfo = {id: this.$el.id, dataset: parseDataset(this.$el.dataset)};
            const event = {
                target: elementInfo,
                currentTarget: elementInfo,
                detail: { errMsg: e.message ? e.message : e.toString() }
            };
            this.$emit('error', event);
            this.imageSrc = false;
        };
        this.loadImage();
    },
    mounted () {
        // 注册lazyload
        if (this.lazyLoad) {
            this.$_registerLazyload();
        }
    },
    beforeDestroy() {
        // 销毁lazyload监听
        if (this.lazyLoad) {
            this.$_removeLazyload();
        }
    },
    methods: {
        loadImage() {
            if (!this.lazyLoad || this.visible) {
                this.image.src = /^\/\//.test(this.src) ? 'https:' + this.src : this.src;
                this.imageSrc = this.image.src;
            }
        },
        imgLoaded () {
            if (!this.lazyLoad || this.visible) {
                if (this.imageSrc) {
                    this.$emit('blimgload', Date.now());
                }
            }
        }
    }
}
</script>

<style lang="less">
.bl___image-container {
    width: 300px;
    height: 225px;
    overflow: hidden;
    display: inline-block;
    position: relative;

    .bl___image-wrapper {
        width: 100%;
        height: 100%;
        background: no-repeat;
    }

    .bl___image {
        width: 100%;
        display: block;
    }

    .bl___image-content-wrapper {
        z-index: 2;
    }
}
</style>
