<!-- 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;
};
const isiOS = /iPad|iPhone|iPod/i.test(navigator.userAgent);
var needPolyfill = false;
// 期望匹配 ./xxxx /xxxx xxxx
const srcReg = [ /^https?:\/\//, /^data:.+?;base64,/, /^\/\// ];
const readFileSync = function(filePath) {
    const result = GLOBAL_OBJECT._callNative('fs.readFileSync', JSON.stringify({ filePath, encoding: 'base64' }), '');
    try {
        const { code, data } = JSON.parse(result);

        if (code !== 0) {
            return null;
        }

        return data;
    } catch (e) {
        return null;
    }
}

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}')` : '',
                //  'background-color': this.lazyLoad && this.imageSrc ? 'transparent' : '#eeeeee'
            });
        }
    },
    beforeCreate() {
        if (!SmallApp.hasCheckedNeedImagePolyfill) {
            needPolyfill = isiOS && !(window.bl && window.bl.getSystemInfoSync && window.bl.getSystemInfoSync().SDKVersion >= '1.5.2');
            SmallApp.hasCheckedNeedImagePolyfill = true;
        }
    },
    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: {
        // 处理安卓下的路径 /
        dealPath(path) {
            let output = path
            if (/^\/(?!\/)/.test(path)) {
                output = output.replace(/^\//, '')
            }
            return output
        },
        loadImage() {
            let tempSrc = this.dealPath(this.src);
            let _src = this.imageSrc;
            if (needPolyfill && tempSrc && !srcReg.reduce((result, reg) => result || reg.test(tempSrc), false)) {
                const result = readFileSync(tempSrc);
                _src = `data:${result.type};base64,${result.data}`;
            } else {
                _src = /^\/\//.test(tempSrc) ? 'https:' + tempSrc : tempSrc;
            }
            if (!this.lazyLoad || this.visible || this.imageSrc !== _src) {
                this.image.src = _src;
                this.imageSrc = _src;
            }
        },
        imgLoaded () {
            if (!this.lazyLoad || this.visible) {
                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>
