import commonTool from './utils.js';
const Dragbox = (($) => {
    const tpl = {
            DRAG_BOX: `
                <div class="{{boxSelector}} hotspots-box {{class}}" style="left: {{left}}px; top: {{top}}px; width: {{width}}px; height: {{height}}px; background: #fff url({{picUrl}}) no-repeat -{{left}}px -{{top}}px; background-size: {{bgSize}};">
                    <div class="j-l-t-bar"></div>
                    <div class="j-r-t-bar"></div>
                    <div class="j-r-b-bar"></div>
                    <div class="j-l-b-bar"></div>
                    <div class="j-t-bar"></div>
                    <div class="j-r-bar"></div>
                    <div class="j-b-bar"></div>
                    <div class="j-l-bar"></div>
                    <p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p>
                </div>
            `,
            DRAGGING_TIP_BAR: `
                <section class="d-drag-info-bar d-hidden J_drag-info-bar">
                    <div><span class="d-one">W：</span><span class="d-two J_width-val">{{width}}</span><span>px</span></div>
                    <div><span class="d-one">H：</span><span class="d-two J_height-val">{{height}}</span><span>px</span></div>
                </section>
            `
        },
        EVENT_SUFFIX = '.areaDrag' + Date.now();     
    let defaultConfig = {
            boxSelector: '.j-hotspots-box',  
            dragTipSelector: '.J_drag-info-bar',     
            container: '.j-container',
            compute: '',                   
            pannel: '.j-container-pannel',
            draggingClass: 'dragging',
            canOverlay: false,
            left: 0,
            top: 0,
            width: 60,
            height: 60,
            minWidth: 60,
            minHeight: 60,
            needUpdateBg: false,        
            addCallback: null,
            doubleClick: null,
            changeCallback: null        
        };
    return class Dragbox {
        
        constructor(config) {
            this._config = this._getConfig(config);
            this.addObj = {jTarget: null, isDragging: false, hasAdded: false};	
            this.disable = false;
            this.dragObj = {
                'isMoving': false,
                'movingTarget': null,
                'moveCallback': false,
                'upCallback': false
            };
            this.jDraggingBox = null;
            this.jContainer = $(this._config.container);
            this.index = 0;
            this._initData();
            this._bindEvent();
        }
        
        _initData() {
            this._updateOffset();
            let data = {width: this._config.width, height: this._config.height, left: this._config.left, top: this._config.top, },
                html = this._replace(tpl.DRAGGING_TIP_BAR, data);
            $(this._config.boxSelector, this.jContainer).append(html);
        }
        
        _bindEvent() {
            let that = this;
            $(document).on('mouseup' + EVENT_SUFFIX, function(e) {
                if (!!that.dragObj.isMoving) {
                    that.addObj.isDragging = false;
                    that.jDraggingBox.removeClass(that._config.draggingClass);
                    let callback = that.dragObj.upCallback || function(){};
                    callback.call(that, e);
                    $.extend(that.dragObj, {
                        'isMoving': false,
                        'movingTarget': null,
                        'moveCallback': false,
                        'upCallback': false
                    });
                }
                if(that.addObj.isDragging){
                    let jHot = that.addObj.jTarget;
                    if(jHot){
                        if(jHot.width() < that._config.minWidth || jHot.height() < that._config.minHeight){
                            jHot.remove();
                            that.index--;
                        }else{
                            typeof that._config.addCallback === 'function' && that._config.addCallback(jHot);
                        }
                        jHot.removeClass(that._config.draggingClass);
                    }
                    $.extend(that.addObj, {isDragging: false, jTarget: null, hasAdded: false});
                }
                $(that._config.dragTipSelector, that.jContainer).addClass('d-hidden');
            });
            this.jContainer.closest(this._config.pannel).on('mousemove' + EVENT_SUFFIX, (function(e) {
                if (!!that.dragObj.isMoving) {
                    let posix = !that.dragObj.movingTarget ? {'x': 0, 'y': 0} : that.dragObj.movingTarget.posix,
                        callback = that.dragObj.moveCallback || function() {
                            let left = that._getVal(0, posix.l + e.pageX - posix.x, that.offset.containerWidth - posix.w),
                                top = that._getVal(0, posix.t + e.pageY - posix.y, that.offset.containerHeight - posix.h);
                            let width = posix.w,
                                height = posix.h,
                                cssSet = {
                                    'left': left,
                                    'top': top,
                                    'width': width,
                                    'height': height
                                };
                            let newCssSet = that._getBoxCoords(cssSet, true);
                            $(that.dragObj.movingTarget).css(newCssSet);
                            if(that._config.needUpdateBg){
                                that._updateBgPosition(newCssSet);
                            }
                            if(that._config.changeCallback){
                                that._config.changeCallback(newCssSet);
                            }
                        };
                    callback.call(this, e, posix);
                }
                else if(that.addObj.isDragging){
                    if(that.addObj.hasAdded){
                        let cssSet = {
                            left: that.addObj.posix.x,
                            top: that.addObj.posix.y,
                            width: Math.min(that.offset.containerRight, e.pageX) - that.addObj.x,
                            height: Math.min(that.offset.containerBottom, e.pageY) - that.addObj.y
                        };
                        that.jDraggingBox = that.addObj.jTarget;
                        that.addObj.jTarget.css(that._getBoxCoords(cssSet));
                    }else{
                        let left = that.addObj.x - that.offset.containerLeft,
                            top = that.addObj.y - that.offset.containerTop + that.offset.containerScrollTop;
                        that.addObj.hasAdded = true;
                        that.addObj.posix = {x: left, y: top};
                        that.addObj.jTarget = that.addBox(that._config.draggingClass, left, top);
                    }
                }
            })).on('mousedown' + EVENT_SUFFIX, function(e) {
                if(!that.disable){
                    that._updateHeight();
                    $.extend(that.addObj, {isDragging: true, x: e.pageX, y: e.pageY});
                }
                return false;
            }).on('mousedown' + EVENT_SUFFIX, that._config.boxSelector, function(e) {
                that.jDraggingBox = $(this).addClass(that._config.draggingClass);
                this.posix = {
                    'x': e.pageX,
                    'y': e.pageY,
                    'l': parseFloat(that.jDraggingBox.css('left')),
                    't': parseFloat(that.jDraggingBox.css('top')),
                    'w': that.jDraggingBox.outerWidth(),
                    'h': that.jDraggingBox.outerHeight()
                };
                $.extend(that.dragObj, {'isMoving': true, 'movingTarget': this});
            }).on('dblclick' + EVENT_SUFFIX, that._config.boxSelector, function(e) {
                typeof that._config.doubleClick === 'function' && that._config.doubleClick(this);
            }).on('click' + EVENT_SUFFIX, '.j-close-btn', function(e) {
                that.removeBox($(this).closest(that._config.boxSelector));
            }).on('mousedown' + EVENT_SUFFIX, '.j-l-t-bar', function(e) {
                that.jDraggingBox = $(this).parent().addClass(that._config.draggingClass);
                $(that._config.dragTipSelector, that.jContainer).removeClass('d-top d-right d-bottom d-left d-top-left d-top-right d-bottom-left d-bottom-right').addClass('d-top-left').removeClass('d-hidden');
                let posix = {
                        'w': that.jDraggingBox.outerWidth(),
                        'h': that.jDraggingBox.outerHeight(),
                        'x': e.pageX,
                        'y': e.pageY,
                        'l': parseFloat(that.jDraggingBox.css('left')),
                        't': parseFloat(that.jDraggingBox.css('top'))
                    },
                    nowLockScale = that.nowLockScale;
                $.extend(that.dragObj, {'isMoving': true, 'moveCallback': function(e) {
                    let incrementX = posix.x - Math.max(e.pageX, that.offset.containerLeft),
                        incrementY = nowLockScale? (incrementX / nowLockScale): (posix.y - Math.max(e.pageY, that.offset.containerTop)),
                        tempWidth = Math.max(that._config.minWidth, incrementX + posix.w),
                        tempHeight = Math.max(that._config.minHeight, incrementY + posix.h);
                    if(tempWidth > posix.w + posix.l){
                        tempWidth = posix.w + posix.l;
                        if(nowLockScale){
                            tempHeight = tempWidth / nowLockScale;
                        }
                    }
                    if(tempHeight > posix.h + posix.t){
                        tempHeight = posix.h + posix.t;
                        if(nowLockScale){
                            tempWidth = tempHeight * nowLockScale;
                        }
                    }
                    let cssSet = {
                        left: Math.min(Math.max(0, posix.l - incrementX), that.offset.containerWidth - that._config.minWidth),
                        top: Math.min(Math.max(0, posix.t - incrementY), that.offset.containerHeight - that._config.minHeight),
                        width: tempWidth,
                        height: tempHeight
                    };
                    let nowLimit = that.limitRange;
                    if(nowLimit){
                        if(cssSet.width > nowLimit.maxWidth){
                            cssSet.width = nowLimit.maxWidth;
                        }
                        if(cssSet.width < nowLimit.minWidth){
                            cssSet.width = nowLimit.minWidth;
                        }
                        if(cssSet.height > nowLimit.maxHeight){
                            cssSet.height = nowLimit.maxHeight;
                        }
                        if(cssSet.height < nowLimit.minHeight){
                            cssSet.height = nowLimit.minHeight
                        }
                        let fixedLeft = posix.l + posix.w,
                            fixedTop = posix.t + posix.h;
                        if(cssSet.left + cssSet.width !== fixedLeft){
                            cssSet.left = fixedLeft - cssSet.width;
                        }
                        if(cssSet.top + cssSet.height !== fixedTop){
                            cssSet.top = fixedTop - cssSet.height;
                        }
                    }
                    if(!(nowLockScale && (that.jDraggingBox.outerWidth() === cssSet.width || that.jDraggingBox.outerHeight() === cssSet.height))){
                        let newCssSet = that._getBoxCoords(cssSet);
                        that.jDraggingBox.css(newCssSet);
                        if(that._config.needUpdateBg){
                            that._updateBgPosition(newCssSet);
                        }
                        if(that._config.changeCallback){
                            that._config.changeCallback(newCssSet);
                        }
                    }
                }});
                return false;
            }).on('mousedown' + EVENT_SUFFIX, '.j-r-t-bar', function(e) {
                that.jDraggingBox = $(this).parent().addClass(that._config.draggingClass);
                $(that._config.dragTipSelector, that.jContainer).removeClass('d-top d-right d-bottom d-left d-top-left d-top-right d-bottom-left d-bottom-right').addClass('d-top-right').removeClass('d-hidden');
                let posix = {
                        'w': that.jDraggingBox.outerWidth(),
                        'h': that.jDraggingBox.outerHeight(),
                        'x': e.pageX,
                        'y': e.pageY,
                        'l': parseFloat(that.jDraggingBox.css('left')),
                        't': parseFloat(that.jDraggingBox.css('top'))
                    },
                    nowLockScale = that.nowLockScale;
                $.extend(that.dragObj, {'isMoving': true, 'moveCallback': function(e) {
                        let incrementX = Math.min(e.pageX, that.offset.containerRight) - posix.x,
                            incrementY = nowLockScale? (incrementX / nowLockScale): (posix.y - Math.max(e.pageY, that.offset.containerTop)),
                            tempWidth = Math.max(that._config.minWidth, incrementX + posix.w),
                            tempHeight = Math.max(that._config.minHeight, incrementY + posix.h);
                        if(tempWidth > that.offset.containerWidth - posix.l){
                            tempWidth = that.offset.containerWidth - posix.l;
                            if(nowLockScale){
                                tempHeight = tempWidth / nowLockScale;
                            }
                        }
                        if(tempHeight > posix.h + posix.t){
                            tempHeight = posix.h + posix.t;
                            if(nowLockScale){
                                tempWidth = tempHeight * nowLockScale;
                            }
                        }
                        let cssSet = {
                            left: posix.l,
                            top: Math.min(Math.max(0, posix.t - incrementY), posix.t + (posix.h - that._config.minHeight)),
                            width: tempWidth,
                            height: tempHeight
                        };
                        let nowLimit = that.limitRange;
                        if(nowLimit){
                            if(cssSet.width > nowLimit.maxWidth){
                                cssSet.width = nowLimit.maxWidth;
                            }
                            if(cssSet.width < nowLimit.minWidth){
                                cssSet.width = nowLimit.minWidth;
                            }
                            if(cssSet.height > nowLimit.maxHeight){
                                cssSet.height = nowLimit.maxHeight;
                            }
                            if(cssSet.height < nowLimit.minHeight){
                                cssSet.height = nowLimit.minHeight
                            }
                            let fixedLeft = posix.l,
                                fixedTop = posix.t + posix.h;
                            if(cssSet.left !== fixedLeft){
                                cssSet.left = fixedLeft;
                            }
                            if(cssSet.top + cssSet.height !== fixedTop){
                                cssSet.top = fixedTop - cssSet.height;
                            }
                        }
                        if(!(nowLockScale && (that.jDraggingBox.outerWidth() === cssSet.width || that.jDraggingBox.outerHeight() === cssSet.height))){
                            let newCssSet = that._getBoxCoords(cssSet);
                            that.jDraggingBox.css(newCssSet);
                            if (that._config.needUpdateBg) {
                                that._updateBgPosition(newCssSet);
                            }
                            if (that._config.changeCallback) {
                                that._config.changeCallback(newCssSet);
                            }
                        }
                    }});
                return false;
            }).on('mousedown' + EVENT_SUFFIX, '.j-r-b-bar', function(e) {
                that.jDraggingBox = $(this).parent().addClass(that._config.draggingClass);
                $(that._config.dragTipSelector, that.jContainer).removeClass('d-top d-right d-bottom d-left d-top-left d-top-right d-bottom-left d-bottom-right').addClass('d-bottom-right').removeClass('d-hidden');
                let posix = {
                        'w': that.jDraggingBox.outerWidth(),
                        'h': that.jDraggingBox.outerHeight(),
                        'x': e.pageX,
                        'y': e.pageY,
                        'l': parseFloat(that.jDraggingBox.css('left')),
                        't': parseFloat(that.jDraggingBox.css('top'))
                    },
                    nowLockScale = that.nowLockScale;
                $.extend(that.dragObj, {'isMoving': true, 'moveCallback': function(e) {
                        let incrementX = Math.min(that.offset.containerRight, e.pageX) - posix.x,
                            incrementY = nowLockScale? (incrementX / nowLockScale): (Math.min(that.offset.containerBottom, e.pageY) - posix.y),
                            newWidth = incrementX + posix.w,
                            newHeight = incrementY + posix.h;
                        let tempWidth = Math.max(that._config.minWidth, newWidth),
                            tempHeight = Math.max(that._config.minHeight, newHeight);
                        if(tempWidth > that.offset.containerWidth - posix.l){
                            tempWidth = that.offset.containerWidth - posix.l;
                            if(nowLockScale){
                                tempHeight = tempWidth / nowLockScale;
                            }
                        }
                        if(tempHeight > that.offset.containerHeight - posix.t){
                            tempHeight = that.offset.containerHeight - posix.t;
                            if(nowLockScale){
                                tempWidth = tempHeight * nowLockScale;
                            }
                        }
                        let cssSet = {
                            left: posix.l,
                            top: posix.t,
                            width: tempWidth,
                            height: tempHeight
                        };
                        let nowLimit = that.limitRange;
                        if(nowLimit){
                            if(cssSet.width > nowLimit.maxWidth){
                                cssSet.width = nowLimit.maxWidth;
                            }
                            if(cssSet.width < nowLimit.minWidth){
                                cssSet.width = nowLimit.minWidth;
                            }
                            if(cssSet.height > nowLimit.maxHeight){
                                cssSet.height = nowLimit.maxHeight;
                            }
                            if(cssSet.height < nowLimit.minHeight){
                                cssSet.height = nowLimit.minHeight
                            }
                            let fixedLeft = posix.l,
                                fixedTop = posix.t;
                            if(cssSet.left > fixedLeft){
                                cssSet.left = fixedLeft;
                            }
                            if(cssSet.top > fixedTop){
                                cssSet.top = fixedTop;
                            }
                        }
                        if(!(nowLockScale && (that.jDraggingBox.outerWidth() === cssSet.width || that.jDraggingBox.outerHeight() === cssSet.height))){
                            that.jDraggingBox.css(that._getBoxCoords(cssSet));
                            if (that._config.changeCallback) {
                                that._config.changeCallback(cssSet);
                            }
                        }
                    }});
                return false;
            }).on('mousedown' + EVENT_SUFFIX, '.j-l-b-bar', function(e) {
                that.jDraggingBox = $(this).parent().addClass(that._config.draggingClass);
                $(that._config.dragTipSelector, that.jContainer).removeClass('d-top d-right d-bottom d-left d-top-left d-top-right d-bottom-left d-bottom-right').addClass('d-bottom-left').removeClass('d-hidden');
                let posix = {
                        'w': that.jDraggingBox.outerWidth(),
                        'h': that.jDraggingBox.outerHeight(),
                        'x': e.pageX,
                        'y': e.pageY,
                        'l': parseFloat(that.jDraggingBox.css('left')),
                        't': parseFloat(that.jDraggingBox.css('top'))
                    },
                    nowLockScale = that.nowLockScale;
                $.extend(that.dragObj, {'isMoving': true, 'moveCallback': function(e) {
                        let incrementX = posix.x - Math.max(that.offset.containerLeft, e.pageX),
                            incrementY = nowLockScale? (incrementX / nowLockScale): (Math.min(e.pageY, that.offset.containerBottom) - posix.y),
                            newWidth = incrementX + posix.w,
                            newHeight = incrementY + posix.h;
                        let newLeft = Math.min(posix.l - incrementX, posix.l + posix.w - that._config.minWidth),
                            tempWidth = Math.max(that._config.minWidth, newWidth),
                            tempHeight = Math.max(that._config.minHeight, newHeight);
                        if(tempWidth > posix.l + posix.w - newLeft){
                            tempWidth = posix.l + posix.w - newLeft;
                            if(nowLockScale){
                                tempHeight = tempWidth / nowLockScale;
                            }
                        }
                        if(tempHeight > that.offset.containerHeight - posix.t){
                            tempHeight = that.offset.containerHeight - posix.t;
                            if(nowLockScale){
                                tempWidth = tempHeight * nowLockScale;
                            }
                        }
                        let cssSet = {
                            left: Math.max(0, newLeft),
                            top: posix.t,
                            width: tempWidth,
                            height: tempHeight
                        };
                        let nowLimit = that.limitRange;
                        if(nowLimit){
                            if(cssSet.width > nowLimit.maxWidth){
                                cssSet.width = nowLimit.maxWidth;
                            }
                            if(cssSet.width < nowLimit.minWidth){
                                cssSet.width = nowLimit.minWidth;
                            }
                            if(cssSet.height > nowLimit.maxHeight){
                                cssSet.height = nowLimit.maxHeight;
                            }
                            if(cssSet.height < nowLimit.minHeight){
                                cssSet.height = nowLimit.minHeight
                            }
                            let fixedLeft = posix.l + posix.w,
                                fixedTop = posix.t;
                            if(cssSet.left + cssSet.width !== fixedLeft){
                                cssSet.left = fixedLeft - cssSet.width;
                            }
                            if(cssSet.top > fixedTop){
                                cssSet.top = fixedTop;
                            }
                        }
                        if(!(nowLockScale && (that.jDraggingBox.outerWidth() === cssSet.width || that.jDraggingBox.outerHeight() === cssSet.height))){
                            let newCssSet = that._getBoxCoords(cssSet);
                            that.jDraggingBox.css(newCssSet);
                            if(that._config.needUpdateBg){
                                that._updateBgPosition(newCssSet);
                            }
                            if(that._config.changeCallback){
                                that._config.changeCallback(newCssSet);
                            }
                        }
                    }});
                return false;
            }).on('mousedown' + EVENT_SUFFIX, '.j-t-bar', function(e) {
                that.jDraggingBox = $(this).parent().addClass(that._config.draggingClass);
                $(that._config.dragTipSelector, that.jContainer).removeClass('d-top d-right d-bottom d-left d-top-left d-top-right d-bottom-left d-bottom-right').addClass('d-top').removeClass('d-hidden');
                let posix = {
                    'w': that.jDraggingBox.outerWidth(),
                    'h': that.jDraggingBox.outerHeight(),
                    'x': e.pageX,
                    'y': e.pageY,
                    'l': parseFloat(that.jDraggingBox.css('left')),
                    't': parseFloat(that.jDraggingBox.css('top'))
                };
                $.extend(that.dragObj, {'isMoving': true, 'moveCallback': function(e) {
                        let incrementY = posix.y - Math.max(that.offset.containerTop, e.pageY),
                            cssSet = {
                                'top': Math.min(Math.max(0, posix.t - incrementY), posix.t + (posix.h - that._config.minHeight)),
                                'left': posix.l,
                                'width': posix.w,
                                'height': Math.min(Math.max(that._config.minHeight, incrementY + posix.h), posix.t + posix.h)
                            };
                        let nowLimit = that.limitRange;
                        if(nowLimit){
                            if(cssSet.height > nowLimit.maxHeight){
                                cssSet.height = nowLimit.maxHeight;
                            }
                            if(cssSet.height < nowLimit.minHeight){
                                cssSet.height = nowLimit.minHeight
                            }
                            let fixedMaxTop = posix.t + posix.h - nowLimit.minHeight,
                                fixedMinTop = posix.t + posix.h - nowLimit.maxHeight;
                            if(cssSet.top > fixedMaxTop){
                                cssSet.top = fixedMaxTop;
                            }
                            if(cssSet.top < fixedMinTop){
                                cssSet.top = fixedMinTop;
                            }
                        }
                        let newCssSet = that._getBoxCoords(cssSet);
                        that.jDraggingBox.css(newCssSet);
                        if(that._config.needUpdateBg){
                            that._updateBgPosition(newCssSet);
                        }
                        if(that._config.changeCallback){
                            that._config.changeCallback(newCssSet);
                        }
                    }});
                return false;
            }).on('mousedown' + EVENT_SUFFIX, '.j-r-bar', function(e) {
                that.jDraggingBox = $(this).parent().addClass(that._config.draggingClass);
                $(that._config.dragTipSelector, that.jContainer).removeClass('d-top d-right d-bottom d-left d-top-left d-top-right d-bottom-left d-bottom-right').addClass('d-right').removeClass('d-hidden');
                let posix = {
                    'w': that.jDraggingBox.outerWidth(),
                    'h': that.jDraggingBox.outerHeight(),
                    'x': e.pageX,
                    'y': e.pageY,
                    'l': parseFloat(that.jDraggingBox.css('left')),
                    't': parseFloat(that.jDraggingBox.css('top'))
                };
                $.extend(that.dragObj, {'isMoving': true, 'moveCallback': function(e) {
                    let incrementX = Math.min(that.offset.containerRight, e.pageX) - posix.x,
                        newWidth = incrementX + posix.w;
                    let cssSet = {
                        left: posix.l,
                        top: posix.t,
                        width: Math.min(Math.max(that._config.minWidth, newWidth), that.offset.containerWidth - posix.l),
                        height: posix.h
                    };
                    let nowLimit = that.limitRange;
                    if(nowLimit){
                        if(cssSet.width > nowLimit.maxWidth){
                            cssSet.width = nowLimit.maxWidth;
                        }
                        if(cssSet.width < nowLimit.minWidth){
                            cssSet.width = nowLimit.minWidth;
                        }
                        if(cssSet.left < posix.l){
                            cssSet.left = posix.l;
                        }
                    }
                    that.jDraggingBox.css(that._getBoxCoords(cssSet));
                    if(that._config.changeCallback){
                        that._config.changeCallback(cssSet);
                    }
                }});
                return false;
            }).on('mousedown' + EVENT_SUFFIX, '.j-b-bar', function(e) {
                that.jDraggingBox = $(this).parent().addClass(that._config.draggingClass);
                $(that._config.dragTipSelector, that.jContainer).removeClass('d-top d-right d-bottom d-left d-top-left d-top-right d-bottom-left d-bottom-right').addClass('d-bottom').removeClass('d-hidden');
                let posix = {
                    'w': that.jDraggingBox.outerWidth(),
                    'h': that.jDraggingBox.outerHeight(),
                    'x': e.pageX,
                    'y': e.pageY,
                    'l': parseFloat(that.jDraggingBox.css('left')),
                    't': parseFloat(that.jDraggingBox.css('top'))
                };
                $.extend(that.dragObj, {'isMoving': true, 'moveCallback': function(e) {
                        let incrementY = Math.min(that.offset.containerBottom, e.pageY) - posix.y,
                            newHeight = incrementY + posix.h;
                        let cssSet = {
                            left: posix.l,
                            top: posix.t,
                            width: posix.w,
                            height: Math.min(Math.max(that._config.minHeight, newHeight), that.offset.containerHeight - posix.t)
                        };
                        let nowLimit = that.limitRange;
                        if(nowLimit){
                            if(cssSet.height > nowLimit.maxHeight){
                                cssSet.height = nowLimit.maxHeight;
                            }
                            if(cssSet.height < nowLimit.minHeight){
                                cssSet.height = nowLimit.minHeight
                            }
                            let fixedMaxTop = posix.t,
                                fixedMinTop = posix.t;
                            if(cssSet.top > fixedMaxTop){
                                cssSet.top = fixedMaxTop;
                            }
                            if(cssSet.top < fixedMinTop){
                                cssSet.top = fixedMinTop;
                            }
                        }
                        that.jDraggingBox.css(that._getBoxCoords(cssSet));
                        if(that._config.changeCallback){
                            that._config.changeCallback(cssSet);
                        }
                    }});
                return false;
            }).on('mousedown' + EVENT_SUFFIX, '.j-l-bar', function(e) {
                that.jDraggingBox = $(this).parent().addClass(that._config.draggingClass);
                $(that._config.dragTipSelector, that.jContainer).removeClass('d-top d-right d-bottom d-left d-top-left d-top-right d-bottom-left d-bottom-right').addClass('d-left').removeClass('d-hidden');
                let posix = {
                    'w': that.jDraggingBox.outerWidth(),
                    'h': that.jDraggingBox.outerHeight(),
                    'x': e.pageX,
                    'y': e.pageY,
                    'l': parseFloat(that.jDraggingBox.css('left')),
                    't': parseFloat(that.jDraggingBox.css('top'))
                };
                $.extend(that.dragObj, {'isMoving': true, 'moveCallback': function(e) {
                        let incrementX = posix.x - Math.max(that.offset.containerLeft, e.pageX),
                            newLeft = Math.min(posix.l - incrementX, posix.l + posix.w - that._config.minWidth),
                            cssSet = {
                                top: posix.t,
                                left: Math.max(0, newLeft),
                                width: Math.max(that._config.minWidth, incrementX + posix.w),
                                height: posix.h
                            };
                        let nowLimit = that.limitRange;
                        if(nowLimit){
                            if(cssSet.width > nowLimit.maxWidth){
                                cssSet.width = nowLimit.maxWidth;
                            }
                            if(cssSet.width < nowLimit.minWidth){
                                cssSet.width = nowLimit.minWidth;
                            }
                            let fixedLeft = posix.l + posix.w;
                            if(cssSet.left + cssSet.width !== fixedLeft){
                                cssSet.left = fixedLeft - cssSet.width;
                            }
                        }
                        let newCssSet = that._getBoxCoords(cssSet);
                        that.jDraggingBox.css(newCssSet);
                        if(that._config.needUpdateBg){
                            that._updateBgPosition(newCssSet);
                        }
                        if(that._config.changeCallback){
                            that._config.changeCallback(newCssSet);
                        }
                    }});
                return false;
            }).on('scroll' + EVENT_SUFFIX, function(){
                that.offset.containerScrollTop = that.jContainer.scrollTop();
            });
        }
        
        _getBoxCoords(cssSet, isMoving) {
            if(cssSet.width < 0){
                cssSet.left = cssSet.left + cssSet.width;
                cssSet.width = -cssSet.width;
            }
            if(cssSet.height < 0){
                cssSet.top = cssSet.top + cssSet.height;
                cssSet.height = -cssSet.height;
            }
            return cssSet;
        }
        
        _updateOffset() {
            let offsetObj = $(this._config.compute).offset(),
                containerWidth = $(this._config.compute).width(),
                containerHeight = $(this._config.compute).height();
            this.offset = {
                containerWidth: containerWidth,
                containerHeight: containerHeight,
                containerLeft: offsetObj.left,
                containerTop: offsetObj.top,
                containerRight: offsetObj.left + containerWidth,
                containerBottom: offsetObj.top + containerHeight,
                containerScrollTop: 0
            };
        }
        
        _updateHeight() {
            let height = this.jContainer.height();
            this.offset.containerHeight = height;
            this.offset.containerBottom = this.offset.containerTop + height;
        };
        
        _updateBgPosition(cssSet) {
            let jTarget = this.jContainer.find(this._config.boxSelector);
            jTarget.css('background-position', -cssSet.left + 'px ' + -cssSet.top + 'px');
        }
        
        _getConfig(config) {
            return $.extend({}, defaultConfig, config);
        }
        
        _replace(template, data) {
            for(let a in data){
                let reg = new RegExp("\\{\\{" + a + "\\}\\}", "g");
                template = template.replace(reg, data[a] === null? "": data[a]);
            }
            return template;
        }
        
        _getVal(min, val, max) {
            if(val < min){
                return min;
            }else if(val > max){
                return max;
            }else{
                return val;
            }
        };
        
        setDisable(val) {
            this.disable = val;
            return true;
        }
        
        addBox(classname, startX, startY, width, height, picUrl) {
            let that = this,
                data = {
                    boxSelector: this._config.boxSelector.replace(/^\./,''),
                    'class': classname || '',
                    index: ++that.index,
                    left: startX,
                    top: startY,
                    width: width || 0,
                    height: height || 0,
                    picUrl: picUrl || '',
                    bgSize: width + 'px ' + height + 'px'
                };
            this._updateOffset();
            return $(that._replace(tpl.DRAG_BOX, data)).appendTo(this.jContainer);
        }
        
        updateRuleDesc(limitRange){
            if(limitRange){
                this.limitRange = limitRange;
                let widthDesc = '宽：' + limitRange.minWidth,
                    heightDesc = '高：' + limitRange.minHeight;
                if(limitRange.minWidth !== limitRange.maxWidth){
                    widthDesc += ' ~ ' + limitRange.maxWidth;
                }
                if(limitRange.minHeight !== limitRange.maxHeight){
                    heightDesc += ' ~ ' + limitRange.maxHeight;
                }
                $('.J_ruleDesc').html(widthDesc + '<br>' + heightDesc);
            }
        }
        
        lockByFixPx(css, duringClass, needToFix, picWidth, picHeight, nowMinZoom, callback, limitRange) {
            let jArea = this.jContainer.find(this._config.boxSelector);
            css.left = css.left || (this.jContainer.width() - css.width) / 2;
            css.top = css.top || (this.jContainer.height() - css.height) / 2;
            css.left = Math.round(css.left);
            css.top = Math.round(css.top);
            let nowPicZoom = -1;
            this.updateRuleDesc(limitRange);
            if(picWidth && picHeight && (css.width > picWidth || css.height > picHeight)){
                let jPic = $('.J_pic-wrap:visible'),
                    picOriginWidth = jPic.width(),
                    picOriginHeight = jPic.height();
                if(css.width / picWidth > css.height / picHeight){
                    css.left = 0;
                    css.top = (picOriginHeight * css.width / picOriginWidth - css.height) / 2;
                    commonTool.picZoom(nowPicZoom = css.width / picOriginWidth, nowMinZoom, true);
                }else{
                    css.left = (picOriginWidth * css.height / picOriginHeight - css.width) / 2;
                    css.top = 0;
                    commonTool.picZoom(nowPicZoom = css.height / picOriginHeight, nowMinZoom, true);
                }
            }
            jArea.addClass((needToFix? 'd-fixed-px ': '') + (duringClass || ''));
            setTimeout(function(){
                jArea.removeClass(duringClass || '');
            }, 400);
            jArea.css(css);
            this._updateBgPosition(css);
            if(this._config.changeCallback){
                this._config.changeCallback(css);
            }
            typeof callback === 'function' && nowPicZoom !== -1 && callback(nowPicZoom);
        }
        
        lockByFixRange(limitRange, duringClass, picWidth, picHeight, nowMinZoom, callback) {
            this.updateRuleDesc(limitRange);
            this.lockByFixPx({width: Math.max(Math.min(picWidth, limitRange.maxWidth), limitRange.minWidth), height: Math.max(Math.min(picHeight, limitRange.maxHeight), limitRange.minHeight)}, duringClass, false, picWidth, picHeight, nowMinZoom, callback, limitRange);
        }
        
        lockByFixScale(scale, duringClass, duringTime) {
            let css = {},
                jArea = this.jContainer.find(this._config.boxSelector),
                jPannel = this.jContainer.closest(this._config.pannel),
                areaWidth = jArea.width(),
                areaHeight = jArea.height(),
                width = this.jContainer.width() * 0.5,
                height = this.jContainer.height() * 0.5;
            jArea.addClass('d-fixed-scale ' + (duringClass || ''));
            setTimeout(function(){
                jArea.removeClass(duringClass || '');
            }, duringTime || 400);
            this.nowLockScale = scale;
            if(width > jPannel.width()){
                let newWidth = jPannel.width();
                height = newWidth / (width / height);
                width = newWidth;
            }
            if(height > jPannel.height()){
                let newHeight = jPannel.height();
                width = newHeight * (width / height);
                height = newHeight;
            }
            if(scale > width / height){
                height = width / scale;
            }else{
                width = height * scale;
            }
            let newLeft = Math.round((this.jContainer.width() - width) / 2),
                newTop = Math.round((this.jContainer.height() - height) / 2);
            css = {width: Math.round(width), height: Math.round(height), left: newLeft, top: newTop};
            jArea.css(css);
            this._updateBgPosition(css);
            if(this._config.changeCallback){
                this._config.changeCallback(css);
            }
        }
        
        unlockFixed() {
            this.nowLockScale = null;
            this.limitRange = null;
            this.jContainer.find(this._config.boxSelector).removeClass('d-fixed-px d-fixed-scale');
        }
        
        clearBox() {
            this.jContainer.find(this._config.boxSelector).remove();
        }
        
        dispose() {
            $(document).off('mouseup' + EVENT_SUFFIX);
            this.jContainer.closest(this._config.pannel).off('mousemove' + EVENT_SUFFIX).off('mousedown' + EVENT_SUFFIX).off('dblclick' + EVENT_SUFFIX).off('click' + EVENT_SUFFIX).off('scroll' + EVENT_SUFFIX);
            $(this._config.boxSelector, this.jContainer).remove();
        }
    };
})($);
export default Dragbox;