export const DRAW_TYPE = Object.freeze({
  POINT: Symbol('POINT'),
  LINE: Symbol('LINE'),
  AREA: Symbol('AREA'),
})

class AbstractDraw {
  layer_name = 'DRAW_LAYER'
  $onStart = null
  $onMove = null
  $onEnd = null
  $dataSource = null
  $entities = null
  $isMouseDown = false
  $drawType = null

  constructor(options) {
    this.$options = options

    options.layer_name && (this.layer_name = options.layer_name)

    this.$viewer = options.viewer
    this.$drawType = options.drawType
    this.$init()
    this.$createEventHandler()
  }

  $init() {
    this.$onStart = new Cesium.Event()
    this.$onMove = new Cesium.Event()
    this.$onEnd = new Cesium.Event()

    // 不创建重复的 dataSource
    let dataSource = this.$viewer.dataSources.getByName(this.layer_name)
    if (!dataSource.length) {
      dataSource = new Cesium.CustomDataSource(this.layer_name)
      this.$viewer.dataSources.add(dataSource)
    }
    this.$dataSource = dataSource
    this.$entities = dataSource.entities
  }

  $createEventHandler() {
    if (this.$drawType) {
      let handler = (this.handler = new Cesium.ScreenSpaceEventHandler(
        this.$viewer.canvas
      ))
      handler.setInputAction((moment) => {
        this.$isMouseDown = true
        this.$onStart.raiseEvent(moment)
      }, Cesium.ScreenSpaceEventType.LEFT_CLICK)

      // 绘制点的时候没有移动事件监听
      if (this.$drawType !== DRAW_TYPE.POINT) {
        handler.setInputAction((moment) => {
          if (this.$isMouseDown) {
            this.$onMove.raiseEvent(moment)
          }
        }, Cesium.ScreenSpaceEventType.MOUSE_MOVE)
        handler.setInputAction((moment) => {
          this.$onEnd.raiseEvent(moment)
          this.$isMouseDown = false
        }, Cesium.ScreenSpaceEventType.RIGHT_CLICK)
      }
    }
  }

  $createDrawPoint(position, options) {
    let entity = new Cesium.Entity()
    entity.position = position
    entity.point = {
      pixelSize: 6,
      color: Cesium.Color.YELLOWGREEN,
      outlineColor: Cesium.Color.ORANGE,
      outlineWidth: 2,
      disableDepthTestDistance: Number.POSITIVE_INFINITY,
    }
    if (options && options.label) {
      entity.label = {
        text: options.text,
        show: true,
        showBackground: true,
        font: '14px monospace',
        horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
        verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
        pixelOffset: new Cesium.Cartesian2(-3, -20),
        disableDepthTestDistance: Number.POSITIVE_INFINITY,
      }
    }
    return entity
  }

  $createDrawPolyline(positions, options) {
    let entity = new Cesium.Entity()
    entity.polyline = {
      positions,
      arcType: Cesium.ArcType.NONE,
      width: 2,
      material: new Cesium.PolylineOutlineMaterialProperty({
        color: Cesium.Color.RED,
      }),
      depthFailMaterial: new Cesium.PolylineOutlineMaterialProperty({
        color: Cesium.Color.RED,
      }),
      ...options,
    }
    return entity
  }

  $createDrawPolygon(positions, options) {
    let entity = new Cesium.Entity()
    entity.polygon = {
      show: true,
      hierarchy: positions,
      // classificationType: Cesium.ClassificationType.CESIUM_3D_TILE,
      material: new Cesium.ColorMaterialProperty(
        Cesium.Color.YELLOWGREEN.withAlpha(0.7)
      ),
      perPositionHeight: true,
      arcType: undefined,
      zIndex: Number.POSITIVE_INFINITY,
    }
    return entity
  }

  $createDrawRectangle() {}

  $addLabelOnDrawEntity(entity, options) {
    entity.label = {
      text: 'label',
      show: true,
      showBackground: true,
      font: '14px monospace',
      horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
      verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
      pixelOffset: new Cesium.Cartesian2(-3, -20),
      disableDepthTestDistance: Number.POSITIVE_INFINITY,
      ...options,
    }
    return entity
  }

  $addLabelOnEntityByCenter(drawType, entity, options) {
    // 算出中点
    let positions = null

    if (drawType === DRAW_TYPE.LINE) {
      positions = entity.polyline.positions.getValue(Cesium.JulianDate.now())
    } else if (drawType === DRAW_TYPE.AREA) {
      let hierarchy = entity.polygon.hierarchy.getValue(Cesium.JulianDate.now())
      positions = hierarchy.positions
    }

    if (positions) {
      let center = Cesium.BoundingSphere.fromPoints(positions).center
      entity.position = center

      // 添加 label
      this.$addLabelOnDrawEntity(entity, {
        text: '默认标注',
        ...options,
      })
    }
  }
}

export default AbstractDraw
