# Source: bemap-leaflet/bemap-map-leaflet-circle.js

    /**
     * Add a bemap.Circle to the layer
     * @public
     * @param {bemap.Circle} bemap.Circle.
     * @param {object} options
     * @return {bemap.LeafletMap}
     */
    bemap.LeafletMap.prototype.addCircle = function(circle, options) {
      if (circle && bemap.inheritsof(circle, bemap.Circle)) {
        var style = circle.getStyle();
        var fillColor = style.getFillColor();
        var borderColor = style.getBorderColor();

        circle.native = L.circle(circle.getCoordinate().getLatLonArray(), circle.getRadius(), {
          fillColor: fillColor.getHex(),
          opacity: fillColor.getAlpha(),
          color: borderColor.getHex(),
          weight: style.getBorderWidth(),
        });

        if (circle.map === null) {
          circle.map = this;
        }

        var opts = options || {};
        var l = null;

        if (opts.layer !== undefined && (bemap.inheritsof(opts.layer, bemap.VectorLayer))) {
          l = opts.layer;
        } else {
          l = this.getLayerByName(bemap.Map.DEFAULT_LAYER.CIRCLE);
          if (l === null) {
            l = new bemap.VectorLayer({
              name: bemap.Map.DEFAULT_LAYER.CIRCLE
            });
            this.addLayer(l);
          }
        }

        if (circle.layer === null) {
          circle.layer = l;
        }

        circle.native.addTo(l.native);
      }

      return this;
    };

    /**
     * Set the coordinates of the circle.
     * @protected
     * @param {bemap.Circle} circle the circle object to remove.
     * @return {bemap.LeafletMap} this
     */
    bemap.LeafletMap.prototype.setCoordinateCircle = function(circle) {
      var c = circle.getCoordinate();
      circle.native.setLatLng(L.latLng(c.getLat(), c.getLon()));
      return this;
    };

    /**
     * Set the radius of the circle.
     * @protected
     * @param {bemap.Circle} circle the circle object to remove.
     * @return {bemap.LeafletMap} this
     */
    bemap.LeafletMap.prototype.setRadiusCircle = function(circle) {
      circle.native.setRadius(circle.getRadius());
      return this;
    };

    /**
     * Remove a circle from his layer.
     * @public
     * @param {bemap.Circle} circle the circle object to remove.
     */
    bemap.LeafletMap.prototype.removeCircle = function(circle) {
      if (circle && circle.layer && circle.layer.native && bemap.inheritsof(circle, bemap.Circle)) {
        circle.map.native.removeLayer(circle.native);
        circle.layer = null;
        circle.map = null;
      }
      return this;
    };

    /**
     * Set the listner when an specified eventType occur on bemap.Circle.
     * @public
     * @param {bemap.Circle} circle
     * @param {bemap.Map.EventType} eventType Event type.
     * @param {function} callback Function will be called when the specified eventType is occur.
     * @param {object} options options.
     * @return {bemap.Listener} this.
     */
    bemap.LeafletMap.prototype.onCircle = function(circle, eventType, callback, options) {

      var opts = options ? options : {};

      var nativeListener = circle.native.on(eventType, function(evt) {
        var mapEvent = new bemap.MapEvent({
          native: evt,
          bemapObject: circle,
          x: evt.containerPoint ? evt.containerPoint.x : undefined,
          y: evt.containerPoint ? evt.containerPoint.y : undefined,
          coordinate: evt.latlng ? new bemap.Coordinate(evt.latlng.lng, evt.latlng.lat) : undefined,
          properties: options,
          map: this
        });
        callback(mapEvent);
      });
      var listener = new bemap.Listener({
        native: nativeListener,
        callback: callback,
        key: eventType,
        bemapObject: circle
      });

      return listener;
    };

    /**
     * Define the draggable capability for bemap.Circle.
     * @protected
     * @param {bemap.Circle} circle bemap object.
     * @param {function} callback Function will be called when the specified eventType is occur.
     * @param {object} options Options.
     * @param {bemap.Layer} options.layerFilter set the bemap layer used as filter.
     * @return {bemap.Listener} bemap.listener.
     */
    bemap.LeafletMap.prototype.draggableCircle = function(circle, callback, options) {
      var _this = this,
        opts = options ? options : {},
        startPixel, startCoordinate;

      circle.native.on('mousedown', function(evt) {
        _this.native.dragging.disable();
        startPixel = evt.containerPoint;

        var latlng = circle.native._latlng;
        var circleStartingLat = latlng.lat;
        var circleStartingLng = latlng.lng;

        startCoordinate = new bemap.Coordinate(circleStartingLng, circleStartingLat);

        latlng = evt.latlng;
        var mouseStartingLat = latlng.lat;
        var mouseStartingLng = latlng.lng;

        _this.native.on('mousemove', function(evt) {
          latlng = evt.latlng;
          var mouseNewLat = latlng.lat;
          var mouseNewLng = latlng.lng;

          var latDifference = mouseStartingLat - mouseNewLat;
          var lngDifference = mouseStartingLng - mouseNewLng;
          var center = [circleStartingLat - latDifference, circleStartingLng - lngDifference];
          circle.native.setLatLng(center);
        });
      });

      this.native.on('mouseup', function(evt) {
        _this.native.dragging.enable();
        _this.native.removeEventListener('mousemove');

        var mapEvent = new bemap.MapEvent({
          native: evt,
          bemapObject: circle,
          x: evt.containerPoint ? evt.containerPoint.x : undefined,
          y: evt.containerPoint ? evt.containerPoint.y : undefined,
          coordinate: evt.latlng ? new bemap.Coordinate(evt.latlng.lng, evt.latlng.lat) : undefined,
          //startX: startPixel.x,
          //startY: startPixel.y,
          //startCoordinate: startCoordinate,
          properties: options,
          map: this
        });

        callback(mapEvent);
      });

      this.events.dragFeature = new bemap.Listener({
        native: null,
        key: "dragFeature",
        bemapObject: circle
      });

      return this.events.dragFeature;
    };