import {
  GeometryType,
  Log,
  SimpleLineSymbol,
  SymbolType
} from '@mapgis/webclient-common'
import { BaseGraphic } from './index'

const {
  Color,
  ColorGeometryInstanceAttribute,
  GeometryInstance,
  PolylineGeometry,
  PolylineColorAppearance,
  Primitive,
  Material,
  PolylineMaterialAppearance,
  ArcType
} = Cesium

/**
 * SimpleLineGraphic
 * @private
 * @param option - {Object} 构造参数
 * @param {Feature} [option.feature = null] 构造Cesium几何的要素对象
 * */
class SimpleLineGraphic extends BaseGraphic {
  constructor(options) {
    super(options)
  }

  /**
   * 重载基类的checkSymbol方法
   * @public
   * @return {Boolean} 是否为支持的符号
   * */
  checkSymbol() {
    if (!(this._feature.symbol instanceof SimpleLineSymbol)) {
      Log.info('要素的符号类型不是SimpleLineSymbol！')
      return false
    }
    return true
  }

  /**
   * 重载基类的_createPrimitive方法
   * @private
   * */
  _createPrimitive() {
    // 获取线几何
    const _geometry = this._feature.geometry
    switch (_geometry.type) {
      case GeometryType.lineString:
        // 创建线的primitive
        const _primitive = this._primitivesCollection.add(
          this._createLinePrimitive(this._getPositions())
        )
        _primitive.id = this._feature.id
        this._primitives.push(_primitive)
        break
      case GeometryType.multiLineString:
        const _positions = this._getPositions()
        for (let i = 0; i < _positions.length; i++) {
          // 创建线的primitive
          const _primitive = this._primitivesCollection.add(
            this._createLinePrimitive(_positions[i])
          )
          _primitive.id = this._feature.id
          this._primitives.push(_primitive)
        }
        break
      default:
        break
    }
  }

  /**
   * 构造一个cesium的线primitive对象
   * @private
   * @param {Array<Cartesian3>} positions 线坐标数组
   * @return {Primitive} Cesium的线primitive对象
   * */
  _createLinePrimitive(positions) {
    // 获取线颜色
    const _symbol = this._feature.symbol
    const _color = this._getCesiumColor(_symbol.color)
    // 设置图层透明度
    _color.alpha *= this._layerOpacity
    return new Primitive({
      geometryInstances: new GeometryInstance({
        // 设置线几何
        geometry: new PolylineGeometry({
          positions,
          width: _symbol.width,
          arcType: ArcType.NONE
        }),
        // 在这里设置线颜色
        attributes: {
          color: ColorGeometryInstanceAttribute.fromColor(_color)
        }
      }),
      // 是否显示线
      show: this.show,
      // 设置线外观
      appearance: this._createAppearance(),
      // 是否是同步绘制，这里关闭，否则绘制会闪烁
      asynchronous: false
    })
  }

  /**
   * 通过feature构造一个Cesium几何的外观对象
   * @private
   * @return {Appearance} Cesium几何的外观对象
   * */
  _createAppearance() {
    // 获取Symbol
    const _symbol = this._feature.symbol
    // 获取几何
    const _geometry = this._feature.geometry

    // 构建材质与外观
    let _material = undefined
    switch (_geometry.type) {
      case GeometryType.lineString:
      case GeometryType.multiLineString:
        switch (_symbol.type) {
          case SymbolType.simpleLine:
            switch (_symbol.style) {
              case 'dash':
              case 'dash-dot':
              case 'dot':
              case 'long-dash':
              case 'long-dash-dot':
              case 'long-dash-dot-dot':
              case 'short-dash':
              case 'short-dash-dot':
              case 'short-dash-dot-dot':
                _material = this._createLineMaterial()
                // 构造外观
                return new PolylineMaterialAppearance({
                  material: _material,
                  translucent: false,
                  renderState: {
                    depthTest: {
                      enabled: true
                    }
                  }
                })
              case 'solid':
              default:
                _material = Material.fromType('Color', {
                  color: this._getCesiumColor(_symbol.color)
                })
                // 构造外观
                return new PolylineColorAppearance({
                  material: _material,
                  renderState: {
                    depthTest: {
                      enabled: true
                    }
                  }
                })
            }
          default:
            break
        }
        break
      default:
        Log.error('要素几何为不支持的类型！')
        break
    }
  }

  /**
   * 通过feature创建一个Cesium的线材质对象
   * @private
   * @return {Material} 创建好的cesium的线材质对象
   * */
  _createLineMaterial() {
    // 获取symbol
    const _symbol = this._feature.symbol
    // 获取线颜色
    const _color = this._getCesiumColor(_symbol.color)
    // 设置图层透明度
    _color.alpha *= this._layerOpacity
    let _material = undefined
    switch (_symbol.style) {
      case 'dash':
        _material = Material.fromType('PolylineDash', {
          // 线颜色
          color: new Color(0, 0, 0, 0),
          // 间隔颜色
          gapColor: _color,
          dashPattern: 120,
          dashLength: 32
        })
        break
      case 'dash-dot':
        _material = Material.fromType('PolylineDash', {
          // 线颜色
          color: new Color(0, 0, 0, 0),
          // 间隔颜色
          gapColor: _color,
          dashPattern: 120,
          dashLength: 32,
          maskIndexFactor: 2,
          maskTestFactor: 1.5
        })
        break
      case 'dot':
        _material = Material.fromType('PolylineDash', {
          // 线颜色
          color: _color,
          // 间隔颜色
          gapColor: new Color(0, 0, 0, 0),
          dashPattern: 240
        })
        break
      case 'long-dash':
        _material = Material.fromType('PolylineDash', {
          // 线颜色
          color: new Color(0, 0, 0, 0),
          // 间隔颜色
          gapColor: _color,
          dashPattern: 120,
          dashLength: 64
        })
        break
      case 'long-dash-dot':
        _material = Material.fromType('PolylineDash', {
          // 线颜色
          color: new Color(0, 0, 0, 0),
          // 间隔颜色
          gapColor: _color,
          dashPattern: 120,
          dashLength: 64,
          maskIndexFactor: 2,
          maskTestFactor: 1.5
        })
        break
      case 'long-dash-dot-dot':
        _material = Material.fromType('PolylineDash', {
          // 线颜色
          color: new Color(0, 0, 0, 0),
          // 间隔颜色
          gapColor: _color,
          dashPattern: 120,
          dashLength: 64,
          maskIndexFactor: 2.0
        })
        break
      case 'short-dash':
        _material = Material.fromType('PolylineDash', {
          // 线颜色
          color: new Color(0, 0, 0, 0),
          // 间隔颜色
          gapColor: _color,
          dashPattern: 120,
          dashLength: 16
        })
        break
      case 'short-dash-dot':
        _material = Material.fromType('PolylineDash', {
          // 线颜色
          color: new Color(0, 0, 0, 0),
          // 间隔颜色
          gapColor: _color,
          dashPattern: 120,
          dashLength: 32,
          maskIndexFactor: 2,
          maskTestFactor: 1.5
        })
        break
      case 'short-dash-dot-dot':
        _material = Material.fromType('PolylineDash', {
          // 线颜色
          color: new Color(0, 0, 0, 0),
          // 间隔颜色
          gapColor: _color,
          dashPattern: 120,
          dashLength: 32,
          maskIndexFactor: 2.0
        })
        break
      default:
        _material = Material.fromType('Color', {
          color: _color
        })
        break
    }

    return _material
  }
}

export default SimpleLineGraphic
