<template>
    <div 
        v-transfer-dom 
        :data-transfer="transfer" 
        :class="`${prefixCls}-wrapper`">
        <transition name="fade">
            <div 
                ref="dialogWrapper"
                v-if="value"
                :class="`${prefixCls}-mask`" 
                :style="zIndex"></div>
        </transition>
        <div 
            :style="zIndex"
            :class="prefixCls">
            <transition name="move-up">
                <div 
                    ref="selectFrame"
                     v-if="value"
                    :style="enableDrag && !fullscreen ? position : innerStyle"
                    :class="innerClasses">
                    <div ref="dragBar" :class="`${prefixCls}-inner-header`">
                        <div :class="`${prefixCls}-inner-title`">
                            <slot name="header">
                                {{title}}
                            </slot>
                        </div>
                        <div v-if="closeable" 
                            :class="`${prefixCls}-inner-close`"
                            @click="handleCancel">
                            <Icon type="close" size="14px"/>
                        </div>
                    </div>
                    <div :class="`${prefixCls}-inner-body`">
                        <Scroller>
                            <div :class="`${prefixCls}-inner-content`">
                                <slot></slot>
                            </div>
                        </Scroller>
                    </div>
                    <div :class="`${prefixCls}-inner-footer`">
                        <slot name="footer">
                            <Button
                                @click="handleCancel">
                                {{t('cancel')}}
                            </Button>
                            <Button
                                type="primary" 
                                @click="handleOk"
                                :loading="btnLoading"
                                style="margin-left: 4px">
                                {{t('ok')}}
                            </Button>
                        </slot>
                    </div>
                    <div v-if="enableDrag && !fullscreen" ref="resizeBar" class="resize-bar resize-br"></div>
                </div>
            </transition>
        </div>
    </div>
</template>
<script>
    import Button from '../../base/button/'
    import Icon from '../../base/icon/'
    import Scroller from '../../base/scroller/'
    import TransferDom from '../../../directives/transfer-dom'
    import Locale from '../../../mixins/locale'
    import { on, off } from '../../../utils/dom'
    import { oneOf } from '../../../utils/assist'
    import { transferIndex, transferIncrease } from '../../../utils/transfer-queue'
    import ScrollbarMixins from '../../../mixins/scrollbar'
    import Keydown from '../../../mixins/keydown'

    const prefixCls = 'yy-dialog'
    export default {
        name: 'YYDialog',
        mixins: [Locale, ScrollbarMixins, Keydown],
        components: {
            Button,
            Icon,
            Scroller
        },
        directives: {
            TransferDom
        },
        props: {
            value: {
                type: Boolean,
                default: false
            },
            loading: { // 是否异步
                type: Boolean,
                default: false
            },
            title: {
                type: [String, Number],
            },
            width: {
                type: String ,
                default: '800px'
            },
            height: {
                type: String,
                default: '600px'
            },
            transfer: {
                type: Boolean,
                default: true
            },
            closeable: { // 是否显示右上角关闭按钮
                type: Boolean,
                default: true
            },
            showLine: {
                type: Boolean,
                default: false
            },
            fullscreen: { // 是否全屏
                type: Boolean,
                default: false
            },
            enableDrag: { // 是否允许拖拽
                type: Boolean,
                default: false
            },
            enableResize: { // 是否允许自动计算匡高
                type: Boolean,
                default: false
            },
            enableWindowResizeListener: {
                type: Boolean,
                default: true
            },
            enableScrollControl: {
                type: Boolean,
                default: true
            }
        },
        data() {
            return {
                prefixCls: prefixCls,
                innerWidth: this.width,
                innerHeight: this.height,
                btnLoading: false,
                transferIndex: 0,
                position: null
            }
        },
        computed: {
            zIndex() {
                return {
                    'z-index': this.transferIndex
                }
            },
            innerStyle() {
                return {
                    'width': this.innerWidth,
                    'height': this.innerHeight
                }
            },
            innerClasses() {
                return [
                    `${prefixCls}-inner`,
                    {
                        [`${prefixCls}-inner-fullscreen`]: this.fullscreen,
                        [`${prefixCls}-inner-line`]: this.showLine
                    }
                ]
            }
        },
        watch: {
            value (newValue) {
                if(newValue) {
                    this.handleGetIndex()
                    if (this.enableScrollControl) this.addScrollEffect()
                    this.$emit('on-open')
                    if (this.enableWindowResizeListener) on(window, 'resize', this.setDialogHeight)
                    on(window, 'keydown', this.handleKeydown)
                    this.$nextTick(()=>{
                        if(this.enableDrag && !this.fullscreen) {
                            this.init()
                        }
                        this.setDialogHeight()
                    })
                } else {
                    if (this.enableWindowResizeListener) off(window, 'resize', this.setDialogHeight)
                    off(window, 'keydown', this.handleKeydown)
                    this.removeScrollEffect()
                }
            }
        },
        methods: {
            setDialogHeight() {
                if(this.fullscreen) {
                    this.innerWidth = '100%'
                    this.innerHeight = '100%'
                } else {
                    const wrapper = this.$refs.dialogWrapper
                    const wrapperHeight = wrapper.offsetHeight || 0
                    if(this.enableResize) {
                        this.innerHeight = wrapper.offsetHeight > 750 && this.innerHeight || wrapperHeight * .8 + 'px'
                    } else {
                        if(parseInt(this.innerHeight) > wrapperHeight) {
                            this.innerHeight = wrapperHeight + 'px'
                        }
                    }
                    
                }
            },
            handleCancel() {
                this.$emit('input', false)
                this.$emit('on-cancel')
            },
            handleOk() {
                if(this.btnLoading) return
                if(this.loading) {
                    this.btnLoading = true
                } else {
                    this.$emit('input', false)
                }
                this.$emit('on-ok')
            },
            handleGetIndex () {
                transferIncrease()
                this.transferIndex = transferIndex
            },
            setFramePosition(position) { // 设置当前窗体位置
                if(position.left || position.top) {
                    this.position['marginLeft'] = 0
                    this.position['marginTop'] = 0
                }
                this.position = {
                    ...this.position,
                    ...position
                }
            },
            initDrag() { // 初始化拖拽移动窗口
                if(!this.enableDrag) return
                const frame = this.$refs.selectFrame
                const handle = this.$refs.dragBar
                const docElement = document.documentElement
                const _this = this
                handle.onmousedown = function(event) {
                    let dEvent = event || window.event
                    let disX = dEvent.clientX - frame.offsetLeft
                    let disY = dEvent.clientY - frame.offsetTop

                    document.onmousemove = function(event) {
                        let mEvent = event || window.event
                        let iL = mEvent.clientX - disX
                        let iT = mEvent.clientY - disY
                        let maxL = docElement.clientWidth - frame.offsetWidth
                        let maxT = docElement.clientHeight - frame.offsetHeight
                        iL <= 0 && (iL = 0)
                        iT <= 0 && (iT = 0)
                        iL >= maxL && (iL = maxL)
                        iT >= maxT && (iT = maxT)
                
                        _this.setFramePosition({
                            left: iL + "px",
                            top: iT + "px",
                        })
                        return false
                    }

                    document.onmouseup = function() {
                        document.onmousemove = null;
                        document.onmouseup = null;
                    }
                    return false
                }
            },
            initResize() { // 初始化拖拽改变窗口大小
                if(!this.enableDrag) return
                const frame = this.$refs.selectFrame
                const resizeBar = this.$refs.resizeBar
                const _this = this
                let position = {
                    ...this.position
                }
                function resize(frame, handle, isLeft, isTop, lockX, lockY) {
                    handle.onmousedown = function(event) {
                        let dEvent = event || window.event
                        let disX = dEvent.clientX - handle.offsetLeft
                        let disY = dEvent.clientY - handle.offsetTop

                        let iParentTop = frame.offsetTop
                        let iParentLeft = frame.offsetLeft
                        let iParentWidth = frame.offsetWidth
                        let iParentHeight = frame.offsetHeight
                        let lastHeight = 0;

                        document.onmousemove = function(event) {
                            let mEvent = event || window.event
                            let iL = mEvent.clientX - disX
                            let iT = mEvent.clientY - disY

                            let maxW = document.documentElement.clientWidth - frame.offsetLeft - 2
                            let maxH = document.documentElement.clientHeight - frame.offsetTop - 2;
                            let maxL = document.documentElement.clientWidth - parseInt(position.width) - 2
                            let maxT = document.documentElement.clientHeight - parseInt(position.height) - 2

                            let iW = isLeft ? iParentWidth - iL : handle.offsetWidth + iL
                            mEvent.clientY > 0 && (lastHeight = iParentHeight - iT)
                            let iH = isTop ? (mEvent.clientY <= 0 ? lastHeight : iParentHeight - iT) : handle.offsetHeight + iT
                            isLeft && (position.left = Math.min((iParentLeft + iL), maxL) + "px")
                            isTop && (position.top = Math.max(Math.min((iParentTop + iT), maxT), 0) + "px")

                            iW < parseInt(position.minWidth) && (iW = parseInt(position.minWidth))
                            iW > maxW && (iW = maxW)
                            lockX || (position.width = iW + "px")
                            iH < parseInt(position.minHeight) && (iH = parseInt(position.minHeight))
                            iH > maxH && (iH = maxH)
                            lockY || (position.height = iH + "px")
                            if((isLeft && iW == parseInt(position.minWidth)) || (isTop && iH == parseInt(position.minHeight))) {
                                document.onmousemove = null
                            }
                           
                            _this.setFramePosition({
                                width: position.width,
                                height: position.height
                            })
                            return false
                        };

                        document.onmouseup = function() {
                            document.onmousemove = null
                            document.onmouseup = null
                        };
                        return false
                    }
                }

                const onresize = function() {
                    _this.initPostion()
                    resize(frame, resizeBar, false, false, false, false)
                    const docElement = document.documentElement
                    position.left = (docElement.clientWidth - 800) / 2 + "px";
                    position.top = (docElement.clientHeight - parseInt(_this.position.height)) / 2 + "px";
                    _this.setFramePosition({
                        width: '800px',
                        height: `${parseInt(_this.position.height)}px`,
                        left: position.left,
                        top: position.top
                    })
                }

                window.onresize = onresize
                onresize()
            },
            initRevert() { // 初始化是否可还原
                if(!this.enableDrag) return
                const handle = this.$refs.dragBar
                const _this = this
                let last = {}
                let isMax = false
                handle.ondblclick = function() {
                    if(!isMax) {
                        last = _this.position
                        isMax = true
                        _this.setFramePosition({
                            left: '0',
                            top: '0',
                            width: '100%',
                            height: '100%',
                        }) 

                    } else {
                        isMax = false
                        _this.setFramePosition(last) 
                    }
                }
            },
            initPostion() { // 初始化可拖拽位置
                const wrapper = this.$refs.dialogWrapper
                const wrapperHeight = wrapper.offsetHeight > 750 ? 750 : wrapper.offsetHeight
                const position = {
                    width: '800px',
                    height: `${wrapperHeight * .8}px`,
                    minWidth: '800px',
                    minHeight: `${wrapperHeight * .8}px`,
					left: '50%',
                    top: '50%',
                    marginLeft: '-400px',
                    marginTop: `-${wrapperHeight * .8/2}px`
                }
                this.position = position
                
            },
            init() {
                this.initPostion()
                this.initDrag()
                this.initResize()
                this.initRevert()
            }
        }
    }
</script>


