    import { Zondy, defaultValue, Feature } from '@mapgis/webclient-common'
    import Widget from '../Widget'
    import {
      Circle,
      LineString,
      Polygon,
      Point
    } from '@mapgis/webclient-common/base/geometry'

    /**
     * 绘制工具
     * @class DrawControl
     * @moduleEX ToolModule
     * @extends Widget
     * @param {Object} options 构造参数
     * @param {complete} [options.complete] 绘制完成后的回调函数
     * @example <caption><h7>初始化绘制工具</h7></caption>
     * // ES5引入方式
     * const { Map, MapView } = Zondy
     * const { DrawControl } = Zondy.Widget
     * // ES6引入方式
     * import { Map, MapView, DrawControl } from "@mapgis/webclient-leaflet-plugin"
     * // 初始化图层管理容器
     * const map = new Map();
     * // 初始化地图视图对象
     * const mapView = new MapView({
     *   // 视图id
     *   viewId: "viewer-id",
     *   // 图层管理容器
     *   map: map
     * });
     * // 初始化绘制控件
     * const drawControl = new DrawControl({
     *   view: mapView,
     *   visible: true,
     *   complete: function (type, feature) {
     *     console.log("绘制类型:", type, ",绘制完成:", feature);
     *     featureLayer.add(feature);
     *   }
     * })
     * // 开始绘制
     * drawControl.start('lineString', {})
     *
     * @example <caption><h7>通过控件进行绘制</h7></caption>
     * // ES5引入方式
     * const { Map, MapView } = Zondy
     * const { DrawControl } = Zondy.Widget
     * // ES6引入方式
     * import { Map, MapView, DrawControl } from "@mapgis/webclient-leaflet-plugin"
     * // 初始化图层管理容器
     * const map = new Map();
     * // 初始化地图视图对象
     * const mapView = new MapView({
     *   // 视图id
     *   viewId: "viewer-id",
     *   // 图层管理容器
     *   map: map
     * });
     * // 初始化绘制控件
     * const drawControl = new DrawControl({
     *   view: mapView,
     *   visible: true,
     *   complete: function (type, feature) {
     *     console.log("绘制类型:", type, ",绘制完成:", feature);
     *     featureLayer.add(feature);
     *   }
     * })
     * // 添加控件
     * mapView.ui.add(drawControl)
     */

    /**
     * 绘制完成的回调函数
     * @callback complete
     * @param {Object} result 回调参数
     * @param {String} [result.type] 几何类型
     * @param {Feature} [result.feature] 绘制完成后返回的要素对象
     * @param {Object} [result.drawConfig] 绘制配置
     */
    class DrawControl extends Widget {
      constructor(options) {
        super(options)
        options = defaultValue(options, {})
        this.drawConfig = defaultValue(options.drawConfig, {
          polygon: {
            allowIntersection: false,
            showArea: true
          },
          circlemarker: false
        })
        this._complete = defaultValue(options.complete, function () {})
        this._drawHandler = null
        this._drawTool = null
        this._initHandler()
        this._initStyles()
      }

      _initHandler() {
        const mapView = this._view.getInnerView()
        this._processEvent = this._processEvent.bind(this)
        if (mapView) {
          mapView.on(L.Draw.Event.CREATED, this._processEvent)
        }
      }

      _initStyles() {
        this.styles = {
          circle: {
            shapeOptions: {
              stroke: true,
              color: '#3388ff',
              weight: 4,
              opacity: 0.5,
              fill: true,
              fillColor: null, // same as color by default
              fillOpacity: 0.2,
              clickable: true
            },
            showRadius: true,
            metric: true, // Whether to use the metric measurement system or imperial
            feet: true, // When not metric, use feet instead of yards for display
            nautic: false // When not metric, not feet use nautic mile for display
          },
          marker: {
            icon: new L.Icon.Default(),
            repeatMode: false,
            zIndexOffset: 2000 // This should be > than the highest z-index any markers
          },
          polygon: {
            showArea: false,
            showLength: false,
            shapeOptions: {
              stroke: true,
              color: '#3388ff',
              weight: 4,
              opacity: 0.5,
              fill: true,
              fillColor: null, // same as color by default
              fillOpacity: 0.2,
              clickable: true
            },
            // Whether to use the metric measurement system (truthy) or not (falsy).
            // Also defines the units to use for the metric system as an array of
            // strings (e.g. `['ha', 'm']`).
            metric: true,
            feet: true, // When not metric, to use feet instead of yards for display.
            nautic: false, // When not metric, not feet use nautic mile for display
            // Defines the precision for each type of unit (e.g. {km: 2, ft: 0}
            precision: {}
          },
          polyline: {
            allowIntersection: true,
            repeatMode: false,
            drawError: {
              color: '#b00b00',
              timeout: 2500
            },
            guidelineDistance: 20,
            maxGuideLineLength: 4000,
            shapeOptions: {
              stroke: true,
              color: '#3388ff',
              weight: 4,
              opacity: 0.5,
              fill: false,
              clickable: true
            },
            metric: true, // Whether to use the metric measurement system or imperial
            feet: true, // When not metric, to use feet instead of yards for display.
            nautic: false, // When not metric, not feet use nautic mile for display
            showLength: true, // Whether to display distance in the tooltip
            zIndexOffset: 2000, // This should be > than the highest z-index any map layers
            factor: 1, // To change distance calculation
            maxPoints: 0 // Once this number of points are placed, finish shape
          },
          rectangle: {
            shapeOptions: {
              stroke: true,
              color: '#3388ff',
              weight: 4,
              opacity: 0.5,
              fill: true,
              fillColor: null, // same as color by default
              fillOpacity: 0.2,
              clickable: true
            },
            showArea: true, // Whether to show the area in the tooltip
            metric: true // Whether to use the metric measurement system or imperial
          }
        }
      }

      _removeHandler() {
        const mapView = this._view.getInnerView()
        if (mapView) {
          mapView.off(L.Draw.Event.CREATED, this._processEvent)
        }
      }

      _processEvent(event) {
        if (event && event.layer) {
          // 查询几何类型
          let type, feature
          const geoJSON = event.layer.toGeoJSON()
          type = geoJSON.geometry.type
          switch (type) {
            case 'LineString':
              feature = new Feature({
                geometry: new LineString({
                  coordinates: geoJSON.geometry.coordinates
                })
              })
              break
            case 'Polygon':
              feature = new Feature({
                geometry: new Polygon({
                  coordinates: geoJSON.geometry.coordinates
                })
              })
              break
            case 'Point':
              let geometry
              if (event.layer._mRadius) {
                geometry = new Circle({
                  center: [
                    geoJSON.geometry.coordinates[0],
                    geoJSON.geometry.coordinates[1]
                  ],
                  radius: event.layer._mRadius
                })
              } else if (event.layer._radius) {
                geometry = new Circle({
                  center: [
                    geoJSON.geometry.coordinates[0],
                    geoJSON.geometry.coordinates[1]
                  ],
                  radius: event.layer._radius
                })
              } else {
                geometry = new Point({
                  coordinates: geoJSON.geometry.coordinates
                })
              }
              feature = new Feature({
                geometry: geometry
              })
              break
          }
          this._complete(type, feature)
        }
      }

      _addView() {
        super._addView()
        const mapView = this._view.getInnerView()
        if (mapView && this._visible) {
          // 添加绘制控件
          const drawnItems = L.featureGroup().addTo(mapView)
          this._drawTool = new L.Control.Draw({
            edit: {
              featureGroup: drawnItems,
              poly: {
                allowIntersection: false
              }
            },
            draw: this.drawConfig
          })

          mapView.addControl(this._drawTool)
        }
      }

      _removeView() {
        super._removeView()
        const mapView = this._view.getInnerView()
        if (mapView && this._visible) {
          this._removeHandler()
          if (this._drawTool) {
            mapView.removeControl(this._drawTool)
            this._print = null
          }
        }
      }

      /**
       * @description 开始绘制
       * @param {String} type 绘制类型，lineString，polygon，rectangle，marker，circle
       * @param drawOptions 绘制参数
       */
      start(type, drawOptions) {
        const mapView = this._view.getInnerView()
        if (!mapView) return
        if (this._drawHandler) {
          this._drawHandler.disable()
        }
        switch (type) {
          case 'lineString': {
            this._drawHandler = new L.Draw.Polyline(mapView, {
              ...this.styles['polyline'],
              ...drawOptions
            })
            this._drawHandler.enable()
            break
          }
          case 'polygon': {
            this._drawHandler = new L.Draw.Polygon(mapView, {
              ...this.styles['polygon'],
              ...drawOptions
            })
            this._drawHandler.enable()
            break
          }
          case 'rectangle': {
            this._drawHandler = new L.Draw.Rectangle(mapView, {
              ...this.styles['rectangle'],
              ...drawOptions
            })
            this._drawHandler.enable()
            break
          }
          case 'marker': {
            this._drawHandler = new L.Draw.Marker(mapView, {
              ...this.styles['marker'],
              ...drawOptions
            })
            this._drawHandler.enable()
            break
          }
          case 'circle': {
            this._drawHandler = new L.Draw.Circle(mapView, {
              ...this.styles['circle'],
              ...drawOptions
            })
            this._drawHandler.enable()
            break
          }
        }
      }

      /**
       * @description 结束绘制
       */
      end() {
        if (this._drawHandler) {
          this._drawHandler.disable()
          this._drawHandler = null
        }
      }

      /**
       * @description 销毁控件
       */
      destory() {}
    }

    Zondy.Widget.DrawControl = DrawControl
    export default DrawControl