<template>
    <div ref="hook_wrap"
        class="nus_video"
        :style="myAspect && !isClass && {paddingTop: myAspect}"
        :class="[isClass && myAspect, isPlay && 'nu_video-play', isFloat && isDisplay && 'nu_video-hide' , (isActive || videoUrl && !imgUrl) && 'nu_video-active']">
        <div class="nu_contain">
            <slot name="hook_img">
                <nu-imgb
                    class="nu_video-pic"
                    :aspect="myAspect"
                    :isLazy="isLazy"
                    :lazyOptions="myLazyOptions"
                    :imgUrl="imgUrl"
                    @imgLoading="_onImgLoading"
                    @click="_play">
                    <slot>
                        <play-btn></play-btn>
                    </slot>
                </nu-imgb>
            </slot>
            <div class="nu_video-wrap">
                <nu-icon
                    v-if="isFloat"
                    @click.stop="_onClose"
                    class="nu_video-close"
                    :icon="'\ue606'">
                </nu-icon>
                <nu-aspect
                    :aspect="myAspect">
                    <video
                        v-numble-video="{isAutoplay: isAutoplay, videoAttr: videoAttr, init: _videoInit}"
                        class="nu_video"
                        ref="hook_video"
                        style="object-fit: contain;"
                        v-lazy="{src: videoUrl, onlyCut: true}"
                        :muted="myIsMuted"
                        :controls="isControls"
                        :loop="isLoop"
                        :src="videoUrl"
                        @play="_onPlay"
                        @pause="_onPause"
                        @volumechange="_onVolumeChange">
                    </video>
                    <slot name="hook_videoCont"></slot>
                </nu-aspect>
            </div>
        </div>
    </div>
</template>

<script>
import { VideoPlay, callFn } from 'nimble-lib';
import attrSync from '../../../Mixins/attrSync/attrSync';
import UtilTmp from '../_comm/UtilTmp';
import NuAspect from '../../widget/aspect';
import NuImgb from '../../widget/img/imgb';
import NuIcon from '../../widget/icon';
import PlayBtn from './playBtn/PlayBtn';
let _videoPlay = VideoPlay();
export default {
    extends: UtilTmp,
    name: 'NuVideo',
    components: {
        NuAspect,
        NuImgb,
        NuIcon,
        PlayBtn
    },
    props: {
        /**
         * 设置视频属性
         */
        videoAttr: {
            type: Object
        },
        /**
         * 是否显示播放控件
         */
        isControls: {
            type: Boolean,
            default: true
        },
        /**
         * 是否开启自动播放
         */
        isAutoplay: {
            type: Boolean,
            default: false
        },
        /**
         * 是否循环播放
         */
        isLoop: {
            type: Boolean,
            default: false
        },
        // 纵横比
        aspect: {
            default: 'nu_video-cont'
        },
        /**
         * 图片地址
         */
        imgUrl: {
            type: String
        },
        /**
         * 视频地址
         */
        videoUrl: {
            type: String
        },
        /**
         * 是否浮
         */
        isFloat: {
            type: Boolean,
            default: false
        },
        /**
         * 是否需要lazy
         */
        isLazy: {
            default: true
        },
        /**
         * lazy选项
         */
        lazyOptions: {}
    },
    data() {
        return {
            /**
             * 是否在播放
             */
            isPlay: false,
            /**
             * 是否浮动显示
             */
            isDisplay: false,
            /**
             * 是否活动状态
             */
            isActive: false,
            /**
             * aspect是否为class名称
             */
            isClass: false
        };
    },
    computed: {
        myLazyOptions() {
            return Object.assign({cutter: 'contain'}, this.lazyOptions || {});
        },
        /**
         * 纵横比
         * @returns {String}
         */
        myAspect() {
            let _that = this;
            let _aspect = _that.aspect;
            if (_aspect === true) {
                _aspect = 'nu_video-aspect';
                _that.isClass = true;
            } else {
                _aspect = ((_aspect || '') + '').replace('%', '');
                let _num = parseFloat(_aspect, 10);
                if (!isNaN(_num)) {
                    if (typeof _num === 'number') {
                        _aspect = Math.abs(_aspect);
                        if (_aspect > 5) {
                            _aspect = _aspect + '%';
                        } else if (_aspect > 0) {
                            _aspect = (_aspect * 100) + '%';
                        }
                    }
                } else {
                    _that.isClass = true;
                }
            }
            return _aspect;
        }
    },
    mixins: [
        /**
         * 是否开启静音
         */
        attrSync('isMuted', {
            type: Boolean,
            default: false
        })
    ],
    created() {
        let _that = this;
        this._videoPlay = _videoPlay;
        // 播放事件
        _videoPlay.$on('play', (evt) => {
            let hookVideo = _that.$refs.hook_video;
            if (evt && evt.el === hookVideo) {
                _that.isPlay = true;
                _that.isActive = true;
            }
        });

        // 暂停事件
        _videoPlay.$on('pause', (evt) => {
            let hookVideo = _that.$refs.hook_video;
            if (evt && evt.el === hookVideo) {
                _that.isPlay = false;
            }
        });

        // 显示事件
        _videoPlay.$on('display', (evt) => {
            let hookVideo = _that.$refs.hook_video;
            if (evt && evt.el === hookVideo) {
                _that.$emit('display', evt);
                _that.isDisplay = true;
            } else {
                _that.isDisplay = false;
            }
        });
    },
    methods: {
        /**
         * 初始化
         * @param {Object} evtData 事件数据
         */
        _videoInit(evtData) {
            this.$emit('init', evtData);
        },
        /**
         * 图片加载
         * @param {Event} evt 事件对象
         * @param {String} type 点击内容的类型
         */
        _onImgLoading(evt) {
            this.$emit('imgLoading', evt);
        },
        /**
         * 音量变化的回调
         * @param {Event} evt 事件对象
         */
        _onVolumeChange (evt) {
            const _that = this;
            _that.$emit('volumechange', evt);
            const _target = evt && evt.target;
            if (_target) {
                _that.myIsMuted = _target.muted;
            }
        },
        /**
         * 播放事件
         * @param {Event} evt 事件对象
         */
        _onPlay(evt) {
            this.$emit('play', evt);
        },
        /**
         * 暂时事件
         * @param {Event} evt 事件对象
         */
        _onPause(evt) {
            this.$emit('pause', evt);
        },
        /**
         * 点击关闭按钮
         */
        _onClose() {
            this._pause();
        },
        /**
         * 播放
         */
        _play() {
            let _that = this;
            let hookVideo = _that.$refs.hook_video;
            _that._videoPlay.play(hookVideo);
        },
        /**
         * 暂停播放
         */
        _pause() {
            this._videoPlay.pause();
        }
    },
    directives: {
        numbleVideo: {
            inserted (el, binding) {
                let opts = Object.assign({}, (binding && binding.value) || {}, {
                    videoEl: el
                });
                if (opts && !opts.videoAttr) {
                    delete opts.videoAttr;
                }
                callFn(opts.init, [{
                    type: 'inserted',
                    video: el
                }]);
                _videoPlay && _videoPlay.push(getWrapEl(el), opts);
            },
            update (el, binding) {
                let opts = Object.assign({}, (binding && binding.value) || {}, {
                    videoEl: el
                });
                if (opts && !opts.videoAttr) {
                    delete opts.videoAttr;
                }
                callFn(opts.init, [{
                    type: 'update',
                    video: el
                }]);
                _videoPlay && _videoPlay.update(getWrapEl(el), opts);
            },
            unbind (el, binding) {
                let opts = Object.assign((binding && binding.value) || {});
                callFn(opts.init, [{
                    type: 'unbind',
                    video: null
                }]);
                _videoPlay.remove(getWrapEl(el), {
                    videoEl: el
                });
            }
        }
    }
};

/**
 * 获取元素
 * @param {HTMLElement} el 当前元素
 * @returns {HTMLElement|undefined}
 */
function getWrapEl (el) {
    let i = 5;
    let wrapEl = el;
    while (i > 0 && wrapEl.parentNode) {
        i--;
        wrapEl = wrapEl.parentNode;
    }
    if (i <= 0) {
        return wrapEl;
    }
}
</script>

<style lang='scss'>
    @import './_video.scss';
</style>
