Your IP : 18.219.40.177


Current Path : /usr/local/mgr5/skins/orion/src/
Upload File :
Current File : //usr/local/mgr5/skins/orion/src/dcmap.js

 (function(exports) {
  'use strict';
  var init = function() {

    },

    checkData = function(data) {
      return true;
    },

    doc = document;
  /**
    * constructor DCMap
    * @param {String} cont id of wrapper
    * @constructor
    */
  var DCMap = function(cont) {
    this.name = 'dcmap';
    this.elem = 'elem';
    this.cont = cont;
    this.selectedElems = {};
    this.changedElems = {};
    this.bound = {};
    this.beforeChangeView = {};
    this.toSaveElems = {};
  };

  DCMap.fn = DCMap.prototype;

  /**
    * init function
    *
    * @param {Object} data data of map
    */
  DCMap.fn.init = function(data) {
    if (checkData(data)) {
      this.mdata = data;
    }
  };

  /**
    * set handler by select event element
    * @param {Function} selectCallback
    */
  DCMap.fn.onSelect = function(selectCallback) {
    this.selectCallback = selectCallback;
  };

  DCMap.fn.onDblClick = function(callback) {
    this.dblClickCallback = callback;
  };

  /**
    * set handler by change event element
    * @param {Function} changeCallback
    */
  DCMap.fn.onChange = function(changeCallback) {
    this.changeCallback = changeCallback;
  };

  /**
    * set handler by change event element
    * @param {Function} changeCallback
    */
  DCMap.fn.onSave = function(saveCallback) {
    this.saveCallback = saveCallback;
  };

  /**
    * render scale ruler and workarea,
    * append in page
    */
  DCMap.fn.renderWorkarea = function() {
    var width = this.mdata.width,
      height = this.mdata.height,
      scale = this.mdata.scale;
    this.papper = new Svg(this.cont, width, height, scale);
    this.papper.master = this;
    this.papper.append();
    this.papper.zoomCallback = this.renderScaleRuler;
    this.renderScaleRuler();
  };

  /**
    * get order of number
    * @param {Number} number
    * @return {*} order or false if is not number
    */
  DCMap.fn.getOrder = function(number) {
    var n = number - 0, p = 0;
    if (typeof n !== 'number') {
      return false;
    }

    while (n > 10) {
      n /= 10;
      p++;
    }
    return p;

  };

  /**
    * get number of scale
    * @param {Number} maxSize
    * @return {number}
    */
  DCMap.fn.getMagicNumber = function(maxSize) {
    var order = this.getOrder(maxSize),
      n = order - 2;
    if (n < 0) {
      return 1;
    } else {
      return Math.pow(10, n);
    }
  };

    /**
    * render Toolbar for change views
    * @param {Array} views views of map
    */
  DCMap.fn.renderToolbar = function(views) {
    if (views && views.length > 0) {
      var l = views.length, a,
        self = this,
        wrapper = doc.createElement('div'),
        clickHandler = this.changeView.bind(this),
        saveHandler = this.saveData.bind(this),
        zoomInHandler = function() {
          self.papper.viewBoxZoom({ direction: 1, preventDefault: function() {} });
        },
        zoomOutHandler = function() {
          self.papper.viewBoxZoom({ direction: -1, preventDefault: function() {} });
        };
      wrapper.className = 'b-map-toolbar';
      if (this.mdata.edit) {
        a = doc.createElement('a');
        a.href = '#';
        a.className = 'b-map-toolbar__button b-map-toolbar__button_save_yes b-map-toolbar__button_disable_yes';
        a.setAttribute('data-state', 'notactive');
        a.innerHTML = this.mdata.msg.save;
        wrapper.appendChild(a);
        a.addEventListener('click', saveHandler);
      }
      for (var i = 0; i < l; i++) {
        a = doc.createElement('a');
        a.href = '#';
        a.className = 'b-map-toolbar__button';
        a.setAttribute('data-view', views[i].name);
        a.innerHTML = views[i].localName;
        wrapper.appendChild(a);
        a.addEventListener('click', clickHandler);
      }

      //zoomIn
      a = doc.createElement('a');
      a.href = '#';
      a.className = 'b-map-toolbar__button b-map-toolbar__button_zoomin';
      a.innerHTML = '+';
      wrapper.appendChild(a);
      a.addEventListener('click', zoomInHandler);
      //zoomOut
      a = doc.createElement('a');
      a.href = '#';
      a.className = 'b-map-toolbar__button b-map-toolbar__button_zoomout';
      a.innerHTML = '-';
      wrapper.appendChild(a);
      a.addEventListener('click', zoomOutHandler);

      var contWrapper = doc.getElementById(this.cont);

      var span = doc.createElement('span');
      span.className = 'b-map-status';
      span.innerHTML = this.mdata.msg.unsave;
      wrapper.appendChild(span);
      contWrapper.insertBefore(wrapper, contWrapper.lastChild);
      this.renderLegend(views);
    }
  };
  /**
    * change view of map
    * @param {Object} e object event
    */
  DCMap.fn.changeView = function(e) {
    var elem = e.target,
      name = elem.getAttribute('data-view'),
      viewElem, actBtn, legend,
      actIdClass = 'b-map-toolbar__button_t_' + this.cont,
      actClass = ' b-map-toolbar__button_active ' + actIdClass;
    //detect current state
    //this view is active
    if (this.activeView === name) {
      viewElem = doc.querySelectorAll('.view-' + name);
      this.hideElements(viewElem);
      this.activeView = null;
      elem.className = elem.className.replace(actClass, '');
      legend = doc.querySelector('.b-rack-legend_name_' + name);
      if (legend) {
        legend.style.display = 'none';
      }
    //active other view
    } else {
      if (this.activeView) {
        viewElem = doc.querySelectorAll('.view-' + this.activeView);
        this.hideElements(viewElem);
        actBtn = doc.querySelector('.' + actIdClass);
        actBtn.className = actBtn.className.replace(actClass, '');
        legend = doc.querySelector('.b-rack-legend_name_' + this.activeView);
        if (legend) {
          legend.style.display = 'none';
        }
      }
      viewElem = doc.querySelectorAll('.view-' + name);
      if (this.beforeChangeView[name]) {
        var hook = this.beforeChangeViewGetArgs(name);
        this.visibleElements(viewElem, hook);
        this.beforeChangeView[name] = false;
      } else {
        this.visibleElements(viewElem);
      }
      legend = doc.querySelector('.b-rack-legend_name_' + name);
      if (legend) {
        legend.style.display = 'block';
      }

      this.activeView = name;
      elem.className += actClass;
    }

    e.preventDefault();
  };

  /**
    * Save Data
    */
  DCMap.fn.saveData = function() {
    if (typeof this.saveCallback === 'function') {
      this.saveCallback.apply({}, [this.toSaveElems, this.tabId]);
    }
    this.toSaveElems = {};
    var status = doc.querySelector('#' + this.cont + ' .b-map-status');
    if (status) {
      status.classList.remove('b-map-status_active');
    }
  };

  DCMap.fn.hideElements = function(elems) {
    var l = elems.length;
    while (l--) {
      elems[l].setAttribute('visibility', 'hidden');
    }
  };

  DCMap.fn.visibleElements = function(elems, hook) {

    var l = elems.length;

    if (hook && typeof this[hook.func] === 'function') {
      var args = [''],
        argLen = hook.arg.length || 0;
      for (var i = 0; i < argLen; i++) {
        args.push(hook.arg[i]);
      }
      while (l--) {
        elems[l].setAttribute('visibility', 'visible');
        args[0] = elems[l];
        this[hook.func].apply(this, args);
      }
    } else {
      while (l--) {
        elems[l].setAttribute('visibility', 'visible');
      }
    }

  };

  DCMap.fn.renderScaleRuler = function() {
    if (!this) { return; }
    var width = this.papper.width,
      height = this.papper.height,
      scale = this.papper.scale,
      maxSize = (width > height) ? width : height,
      magicNumber = this.getMagicNumber(maxSize),
      countW = Math.round(width / magicNumber),
      countH = Math.round(height / magicNumber),
      count = (countW > countH) ? countW : countH,
      g = this.papper.group('scale-ruler', { id: 'scaleruler' }),
      scaleruler = this.papper.elems.scaleruler,
      elem, y2, x;
    //@todo uniq name
    //remove if exist
    if (scaleruler) {
      scaleruler.elem.parentNode.removeChild(scaleruler.elem);
    }

    for (var i = 0; i < count; i++) {
      if (i % 10 === 0) {
        y2 = 5 * scale;
      } else if (i % 5 === 0) {
        y2 = 3 * scale;
      } else {
        y2 = 2 * scale;
      }
      x = i * magicNumber;
      if (i < countW) {
        elem = this.papper.line('scaleruler-x-' + i, { x1: x, x2: x, y1: '0', y2: y2, stroke: '#000', 'stroke-width': scale });
        g.appendChild(elem);
      }
      if (i < countH) {
        elem = this.papper.line('scaleruler-y-' + i, { x1: 0, x2: y2, y1: x, y2: x, stroke: '#000', 'stroke-width': scale });
        g.appendChild(elem);
      }
    }
    this.papper.appendChild(g);
    this.papper.elems.scaleruler = g;
  };

    /**
    * render layer
    * @param {Object} current current layer
    * @param {Object} layer layers data
    * @param {Array} views array with objects views
    * @param {Object} objects object with object type on the map
    */
  DCMap.fn.renderLayer = function(current, layer, views, objects) {
    var elems = layer.elems,
      childLayer = layer.layers,
      viewsLen = views ? views.length : 0, viewElem,
      eLen, elem, cObj, shape, attr, svgElem, gEl, innerObj, innerElem,
      transform, innerAttr, line, lineAttr, transformProp,
      scale = this.mdata.scale || 1,
      g = this.papper.group(layer.name, { id: layer.name }),
      showHint;
    if (elems) {
      eLen = elems.length;
      //go to elements
      for (var j = 0; j < eLen; j++) {
        elem = elems[j];
        cObj = objects[elem.oName];
        //detect shape
        shape = cObj.shape;
        if (!this.papper[shape]) {
          console.log("don't have this shape: " + shape);
          continue;
        }
        attr = {
          'class': cObj.name,
          width: elem.width,
          height: elem.height,
          y: elem.top,
          x: elem.left,
          'stroke-width': 1 * scale,
          stroke: '#666'
        };
        //set transform
        if (elem.direction && elem.direction !== 360) {
          transform = 'rotate(' + elem.direction + ', ' + (elem.left - 0 + elem.width / 2) + ', ' + (elem.top - 0 + elem.height / 2) + ')';
          transformProp = { 'direction': elem.direction };
        } else {
          transform = null;
        }
        if (transform) { attr.transform = transform; }

        if (elem.elid) { attr.elid = elem.elid; }
        if (cObj.color) { attr.fill = cObj.color; }
        if (shape === 'image') { attr.href = { ns: 'xlink', v: pageInfo.commonDir + 'img/' + cObj.img + '.png' }; }

        svgElem = this.papper[shape](cObj.name, attr, transformProp);
        //overlay for hint
        delete attr.color;
        delete attr.stroke;
        attr.fill = '#FFFFFF';
        attr['fill-opacity'] = '0.0';
        var overlay = this.papper[shape](cObj.name, attr, transformProp);
        svgElem.children.push(overlay);
        overlay.parent = svgElem;
        delete attr['fill-opacity'];
        //render inner elems
        if (cObj.innerObj || cObj.edit) {
          gEl = this.papper.group('g-' + cObj.name, { id: 'g-' + elem.elid });
          gEl.appendChild(svgElem);
          innerObj = cObj.innerObj;
          //render inner objects
          /* jslint forin:true */
          for (var keyVar in innerObj) {
            innerAttr = { y: elem.top - 0 + 20 * scale, x: elem.left - 0 + 15 * scale, 'font-size': 20 * scale };
            if (transform) {
              if (keyVar !== 'text') {
                innerAttr.transform = transform;
              } else if (elem.direction > 125 && elem.direction < 225) {
                innerAttr.transform = 'rotate(' + 0 + ', ' + (elem.left - 0 + elem.width / 2) + ', ' + (elem.top - 0 + elem.height / 2) + ')';
              } else {
                innerAttr.transform = transform;
              }
            }
            if (this.papper[keyVar]) {
              innerElem = this.papper[keyVar](innerObj[keyVar], elem[innerObj[keyVar]], innerAttr, transformProp);
              gEl.appendChild(innerElem);
              svgElem.children.push(innerElem);
              innerElem.parent = svgElem;
            }
          }
          var parentEl, value, l;
          //append in element view state
          for (var i = 0; i < viewsLen; i ++) {
            if (elem[views[i].name] || elem[views[i].name + '_used']) {
              parentEl = {};
              parentEl.attr = attr;
              parentEl.shape = shape;
              parentEl.transformProp = transformProp;
              value = elem[views[i].name] ? elem[views[i].name] : elem;
              viewElem = this.renderViewElem(value, views[i], parentEl);
              if (views[i].type === 'color' && views[i].gradient === 'relative') {
                this.getBounds(views[i].name, elem[views[i].name]);
                this.beforeChangeView[views[i].name] = 'relativeGradient';
              }
              if (viewElem) {
                l = viewElem.length;
                if (l) {
                  gEl.appendChild(viewElem[0]);
                  for (var k = 1; k < l; k++) {
                    svgElem.children.push(viewElem[k]);
//                    viewElem.parent = svgElem;
                  }
                } else {
                  gEl.appendChild(viewElem);
                  svgElem.children.push(viewElem);
                  viewElem.parent = svgElem;
                }

              }
            }
          }

          //render line direction
          lineAttr = { y: elem.top, x: elem.left, width: elem.width, height: 5 * scale, stroke: '#ccc' };
          if (transform) { lineAttr.transform = transform; }
          line = this.papper.rect('line-' + elem.elid, lineAttr, transformProp);
          gEl.appendChild(line);
          svgElem.children.push(line);
          line.parent = svgElem;
          //add event listerner
          if (cObj.edit) {
//            svgElem.onDrag(this, this.dragElemHandler, this.moveElemHandler, this.dropElemHandler);
            svgElem.onDrag(this, this.dragElemHandler, this.moveElemHandler, this.dropElemHandler);
            svgElem.changeFunc = cObj.drag;
            svgElem.draged = true;
          }
          //add direction control
          if (cObj.edit) {
            svgElem.rotated = true;
            var rcAttr = {
              y: (elem.top - 8 * scale) + (elem.height - 0),
              x: (elem.left - 8 * scale) + (elem.width - 0),
              stroke: '#ccc',
              height: 16 * scale,
              width: 16 * scale };
            if (transform) {
              rcAttr.transform = transform;
            }
            var rotateControl = this.papper.rect('rotate-' + elem.elid, rcAttr, transformProp);

            gEl.appendChild(rotateControl);
            svgElem.children.push(rotateControl);
            rotateControl.parent = svgElem;
            rotateControl.onRotate(this, null, null, this.dropRotateElemHandler);
            svgElem.dropRotateCallback = this.dropRotateElemHandler;
          }
        }
        //append overlay after all children
        gEl.appendChild(overlay);

        //add select listern
        if (elem.elid !== undefined) {
          svgElem.onSelect(this, this.selectElem);
        }
        if (elem.elid !== undefined && !cObj.edit) {
          svgElem.onSelectOnly(overlay);
        }
        //add listener dblclick
        if (elem.elid !== undefined) {
          svgElem.onDblclick(this, this.dblClickCallback);
          if (overlay) {
            overlay.onDblclick(this, this.dblClickCallback);
          }
        }
        if (cObj.edit) {
          elem.msg = this.mdata.msg;
          showHint = this.showHint.bind(elem);
          overlay.elem.addEventListener('mouseover', showHint);
          overlay.elem.addEventListener('mouseout', this.hideHint);
        } else if (innerObj && innerObj.hint && overlay) {
          var showActHint = this.showActHint.bind(elem);
          overlay.elem.addEventListener('mouseover', showActHint);
          overlay.elem.addEventListener('mouseout', this.hideHint);
          overlay.elem.setAttribute('data-elid', elem.elid);
          overlay.elem.setAttribute('data-name', elem.oName);
          overlay.elem.setAttribute('data-func', innerObj.hint);
        }

        //if edit elements
        if (gEl) {
          svgElem = gEl;
        }
        g.appendChild(svgElem);
      }
    }

    current.appendChild(g);

    if (childLayer) {
      eLen = childLayer.length;
      for (var ii = 0; ii < eLen; ii++) {
        this.renderLayer(g, childLayer[ii], views, objects);
      }
    }
  };

  /**
    * render view element, visible:hidden by default
    * @param {String} value Value of parameter
    * @param {Object} view view object
    * @param {Object} parentEl Props of parent
  */
  DCMap.fn.renderViewElem = function(value, view, parentEl) {
    if (parentEl.shape !== 'image') {
      var attr = parentEl.attr,
        x, y;
      attr.visibility = undefined;
      attr['class'] = undefined;
      attr.fill = undefined;
      attr['font-size'] = undefined;
      attr['data-value'] = undefined;
      if (view.type === 'color') {
        attr.visibility = 'hidden';
        attr['class'] = 'view-' + view.name;
        if (view.gradient === 'fixed') {
          attr.fill = this.gradientGreenToRed(value, 0, 100);
          return this.papper[parentEl.shape]('name', attr, parentEl.transformProp);
        } else if (view.gradient === 'relative') {
          attr['data-value'] = value;
          return this.papper[parentEl.shape]('name', attr, parentEl.transformProp);
        }
      } else if (view.type === 'indicator') {
        x = attr.x;
        y = attr.y;
        var group = this.papper.group('name', { 'class': 'view-' + view.name, 'visibility': 'hidden' }),
          wrapper = this.papper[parentEl.shape]('name', attr, parentEl.transformProp),
          text,
          used = value[view.name + '_used'],
          total = value[view.name + '_total'];
        wrapper.attr('fill', this.gradientGreenToRed(used, 0, total));
        attr['font-size'] = 20 * this.papper.scale;
        attr.x = attr.x - 0 + (7 * this.papper.scale);
        attr.y = attr.y - 0 + (20 * this.papper.scale);
        if (parentEl.transformProp) {
          if (parentEl.transformProp.direction > 125 && parentEl.transformProp.direction < 225) {
            var regex = new RegExp(parentEl.transformProp.direction);
            attr.transform = attr.transform.replace(regex, 0);
          }
        }

        text = this.papper.text('name', used + ' / ' + total, attr, parentEl.transformProp);
        attr.x = x;
        attr.y = y;
        group.appendChild(wrapper);
        group.appendChild(text);
        return [group, wrapper, text];
      }
    }
  };

  DCMap.fn.getBounds = function(id, value) {
    value = value - 0;
    if (!this.bound[id]) {
      this.bound[id] = {};
      this.bound[id].min = value;
      this.bound[id].max = value;
    } else {
      var min = this.bound[id].min,
        max = this.bound[id].max;
      this.bound[id].min = (min > value) ? value : min;
      this.bound[id].max = (max < value) ? value : max;
    }
  };


  DCMap.fn.beforeChangeViewGetArgs = function(name) {
    if (this.beforeChangeView[name] === 'relativeGradient') {
      return { 'func': this.beforeChangeView[name], arg: [this.bound[name].min, this.bound[name].max] };
    }
  };

  DCMap.fn.renderLegend = function(views) {
    var l = views.length,
      bl, br;
    while (l--) {
      if (views[l].type === 'color') {
        if (views[l].gradient === 'fixed') {
          bl = views[l].boundleft - 0;
          br = views[l].boundright - 0;
        } else {
          bl = this.bound[views[l].name].min;
          br = this.bound[views[l].name].max;
        }

        var step = Math.floor(((br - bl) / 10)),
          html = '<h3 class="b-rack-legend__title">' + views[l].localName + '</h3>',
          curValue = bl,
          toTen = step % 10,
          count = 10;
        if (toTen !== 0) {
          if ((curValue % 10) !== 0) {
            curValue -= (curValue % 10);
          }
          toTen = 10 - toTen;
          step = step + toTen;
          count = Math.floor(br / step);
        }

        for (var i = 0; i <= count; i++) {
          html += '<div class="b-rack-legend__item"><span class="b-rack-legend__color" style="background-color: ' + this.gradientGreenToRed(curValue, bl, br) + ';">' +
            '</span><span class="b-rack-legend__value">' + Math.floor(curValue) + '</span></div>';
          curValue += step;
        }
        var div = doc.createElement('div');
        div.className = 'b-rack-legend b-rack-legend_dcmap b-rack-legend_name_' + views[l].name;
        div.innerHTML = html;
        this.papper.cont.appendChild(div);
      }
    }
  };
  /**
    * trigger event for show hint
    * @param {Object} e
    */
  DCMap.fn.showHint = function(e) {
    var hintElem = doc.querySelector('body'),
      event = new CustomEvent('showHintMap', { 'detail': { props: this, elem: e.srcElement }});
    hintElem.dispatchEvent(event);
  };

  DCMap.fn.showActHint = function(e) {
    var hintElem = doc.querySelector('body'),
      event = new CustomEvent('hintActiveShowHandler', { 'detail': { elem: e.srcElement }});
    hintElem.dispatchEvent(event);
  };

  /**
    * trigger event for hide hint
    */
  DCMap.fn.hideHint = function() {
    var hintElem = doc.querySelector('body'),
      event = new CustomEvent('hideHint');
    hintElem.dispatchEvent(event);
  };

  /**
    *
    */
  DCMap.fn.stopShowHint = function() {
    if (this.runHandler !== true) {
      setTimeout(function() {
        var hintElem = doc.querySelector('body'),
          event = new CustomEvent('stopShowHint');
        hintElem.dispatchEvent(event);
      }, 200);
    }
  };


  DCMap.fn.relativeGradient = function(elem, min, max) {
    var value = elem.getAttribute('data-value');
    elem.setAttribute('fill', this.gradientGreenToRed(value, min, max));

  };
  /**
    * get color from number
    * @param {Number} n current value
    * @param {Number} m max value
    * @return {string}
    */
  DCMap.fn.gradientGreenToRed = function(value, min, max) {
    // value is a value between 0 and max;
    // 0 = green, max/2 = yellow, max = red.
    var R, G,
      B = 0,
      bound = max - min,
      halfMax = bound / 2;

    if (value > halfMax) {
      //yellow to red
      R = 255;
      G = Math.round((255 * (bound - value)) / halfMax);
    } else {
      //green to yellow
      G = 255;
      R = Math.round((255 * value) / halfMax);
    }
    return 'rgb(' + R + ',' + G + ',' + B + ')';
  };

    /**
    * render Layers
    * @param {Object} dataLayer
    */
  DCMap.fn.renderLayers = function(dataLayer) {
    var layers = dataLayer.layers,
      objects = dataLayer.objects,
      views = dataLayer.views,
      l = layers.length;
    if (l === 1) {
      this.renderLayer(this.papper, layers[0], views, objects);
    }
    this.renderToolbar(views);
  };

  /**
    * resize map to actual page size
    * @param {Object} sizeObj
    */
  DCMap.fn.resize = function(sizeObj) {
    var width = sizeObj.width,
      height = sizeObj.height;
    if (width || height) {
      if (width) {
        this.papper.setWidth(width);
      }
      if (height) {
        this.papper.setHeight(height);
      }
    }
  };

  /**
    * Select element handler
    * @param {jQuery object} elem
    * @param {Boolean} ctrl
    */
  DCMap.fn.selectElem = function(elem, ctrl) {
    if (!ctrl) {
      /* jslint forin:true */
      for (var keyVar in this.selectedElems) {
        this.selectedElems[keyVar].removeClass('selected');
        this.selectedElems[keyVar].selected = false;
        delete this.selectedElems[keyVar];
      }
    }
    if (elem.selected || elem.dblclicked) {
      elem.addClass('selected');
      elem.selected = true;
      this.selectedElems[elem.id] = elem;
    } else {
      elem.removeClass('selected');
      delete this.selectedElems[elem.id];
    }
    if (typeof this.selectCallback === 'function') {
      this.selectCallback.apply({}, [this.selectedElems, this]);
    }
  };

  /**
    * Drag element handler
    * @param {jQuery object} elem
    * @param {Object} event
    */
  DCMap.fn.dragElemHandler = function(elem, event) {
    var curElem;
    for (var keyVar in this.selectedElems) {
      if (elem.elid !== keyVar) {
        curElem = this.selectedElems[keyVar];
        curElem.drag.apply(curElem, [event, true]);
      }
    }
    this.hideHint();
    this.stopShowHint();
  };

    /**
    * Move element handler
    * @param {jQuery object} elem
    * @param {Object} event
    */
  DCMap.fn.moveElemHandler = function(elem, event) {
    var curElem;
    for (var keyVar in this.selectedElems) {
      if (elem.id !== keyVar) {
        curElem = this.selectedElems[keyVar];
        curElem.move.apply(curElem, [event, true]);
      }
    }
    this.stopShowHint();
    this.runHandler = true;
  };

  /**
    * Drop element handler
    * @param {jQuery object} elem
    * @param {Object} event
    */
  DCMap.fn.dropElemHandler = function(elem, event) {
    if (typeof this.changeCallback === 'function') {
      this.changeCallback.apply({}, [this.selectedElems]);
    }
    this.preSaveData(this.selectedElems);
    this.runHandler = false;
  };
    /**
    * Presave changed data
    * @param {Object} elems
    */
  DCMap.fn.preSaveData = function(elems) {
    /* jslint forin:true */
    for (var keyVar in elems) {
      this.toSaveElems[keyVar] = this.selectedElems[keyVar];
    }
    var status = doc.querySelector('#' + this.cont + ' .b-map-status');
    if (status) {
      status.classList.add('b-map-status_active');
    }
  };
  /**
    *
    * @param {jQuery object} elem
    * @param {Object} event
    */
  DCMap.fn.dropRotateElemHandler = function(elem, event) {
    if (typeof this.changeCallback === 'function') {
      this.changeCallback.apply({}, [{ 't': elem }]);
    }
    var o = {};
    o[elem.elid] = elem;
    this.preSaveData(o);
  };

  /**
    *
    */
  DCMap.fn.forceRotate = function() {
    var curElem;
    /* jslint forin:true */
    for (var keyVar in this.selectedElems) {
      curElem = this.selectedElems[keyVar];
      if (curElem.rotated) {
        curElem.forceRotate();
      }
    }
  };

  /**
    *
    * @param {String} direction
    */
  DCMap.fn.forceMove = function(direction) {
    var curElem;
    /* jslint forin:true */
    for (var keyVar in this.selectedElems) {
      curElem = this.selectedElems[keyVar];
      if (curElem.draged) {
        curElem.forceMove(direction);
      }
    }
  };



  exports.DCMap = DCMap;


} (window));