    import {
      Feature,
      createSimpleFillSymbolCanvas,
      GeometryType,
      MultiLineString,
      Log,
      SimpleFillSymbol
    } from '@mapgis/webclient-common'
    import { BaseGraphic, SimpleLineGraphic } from './index'

    const {
      Cartesian2,
      ColorGeometryInstanceAttribute,
      GeometryInstance,
      Primitive,
      Material,
      PolygonGeometry,
      PolygonHierarchy,
      MaterialAppearance
    } = Cesium

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

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

      /**
       * 重载基类的_createPrimitive方法
       * @private
       * */
      _createPrimitive() {
        // 不存在style，则不绘制几何
        if (!this._feature.symbol.style) return
        this._createAllPolygonPrimitive()
        this._createAllOutlinePrimitive()
      }

      /**
       * 创建并返回所有的cesium的多边形Primitive对象
       * @private
       * @return {Array<Primitive>} Cesium的多边形Primitive对象数组
       * */
      _createAllPolygonPrimitive() {
        // 获取几何
        const _geometry = this._feature.geometry
        // 获取cesium几何坐标
        const _positions = this._getPositions()
        // 获取所有的polygon的primitive数组
        switch (_geometry.type) {
          case GeometryType.polygon:
          case GeometryType.extent:
          case GeometryType.circle:
            const _primitive = this._createPolygonPrimitive(_positions)
            _primitive.id = this._feature.id
            this._primitives.push(_primitive)
            break
          case GeometryType.multiPolygon:
            for (let i = 0; i < _positions.length; i++) {
              const _primitive = this._createPolygonPrimitive(_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对象
       * */
      _createPolygonPrimitive(positions) {
        // 获取symbol
        const _symbol = this._feature.symbol
        // 获取color
        const _color = this._getCesiumColor(_symbol.color)
        // 构造cesium几何对象
        // 构造多边形内圈
        const holes = []
        for (let i = 1; i < positions.length; i++) {
          holes.push(new PolygonHierarchy(positions[i]))
        }
        // 获取拉伸高度
        let _extrudedHeight = undefined
        const _geometry = this._feature.geometry
        if (_geometry.type === GeometryType.extent) {
          _extrudedHeight = _geometry.zmax
        }
        const _polygonGeometry = new PolygonGeometry({
          // 多边形几何结构
          polygonHierarchy: new PolygonHierarchy(positions[0], holes),
          // 额外抬升高度高度
          height: 0,
          // 拉伸高度
          extrudedHeight: _extrudedHeight,
          // 是否使用单个点的高度
          perPositionHeight: true
        })

        // 构造多边形外观
        const _appearance = new MaterialAppearance({
          // 几何材质
          material: this._createPolygonMaterial(),
          // 是否透明
          translucent: false,
          // 是否参与深度检测
          renderState: {
            depthTest: {
              enabled: true
            }
          }
        })
        // 构造cesium的多边形primitive对象
        let _polygonPrimitive = new Primitive({
          // 几何实例
          geometryInstances: new GeometryInstance({
            geometry: _polygonGeometry,
            attributes: {
              color: ColorGeometryInstanceAttribute.fromColor(_color)
            }
          }),
          // 几何外观
          appearance: _appearance,
          asynchronous: false
        })

        _polygonPrimitive = this._primitivesCollection.add(_polygonPrimitive)

        return _polygonPrimitive
      }

      /**
       * 创建并返回所有的cesium的线Primitive对象数组
       * @private
       * @return {Array<Primitive>} Cesium的线Primitive对象数组
       * */
      _createAllOutlinePrimitive() {
        // 获取几何
        const _geometry = this._feature.geometry
        // 构造所有外边线
        let _primitives = []
        switch (_geometry.type) {
          case GeometryType.polygon:
            _primitives = this._createPolygonOutlineGraphic(_geometry.coordinates)
            break
          case GeometryType.extent:
            const _positions = this._getPositions()
            _primitives = this._createPolygonOutlineGraphic(_positions)
            break
          case GeometryType.circle:
            _primitives = this._createPolygonOutlineGraphic([])
            break
          case GeometryType.multiPolygon:
            for (let i = 0; i < _geometry.coordinates.length; i++) {
              const _lines = this._createPolygonOutlineGraphic(
                _geometry.coordinates[i]
              )
              _primitives = _primitives.concat(_lines)
            }
            break
          default:
            Log.info('要素为未支持的几何类型')
            break
        }
        this._primitives = this._primitives.concat(_primitives)
      }

      /**
       * 创建并返回一个SimpleLineGraphic对象
       * @private
       * @param {Array<Cartesian3>} positions 线坐标数组
       * @return {SimpleLineGraphic} SimpleLineGraphic对象
       * */
      _createPolygonOutlineGraphic(positions) {
        // 获取symbol
        const _symbol = this._feature.symbol
        // 构造所有外边线
        let _positions = []
        const _geometry = this._feature.geometry
        if (_geometry.type === GeometryType.extent) {
          _positions.push([])
          _positions[0].push([_geometry.xmin, _geometry.ymin, _geometry.zmin])
          _positions[0].push([_geometry.xmax, _geometry.ymin, _geometry.zmin])
          _positions[0].push([_geometry.xmax, _geometry.ymax, _geometry.zmin])
          _positions[0].push([_geometry.xmin, _geometry.ymax, _geometry.zmin])
          _positions[0].push([_geometry.xmin, _geometry.ymin, _geometry.zmin])
          _positions[0].push([
            _positions[0][0][0] +
              (_positions[0][1][0] - _positions[0][0][0]) / 10000,
            _positions[0][0][1] +
              (_positions[0][1][1] - _positions[0][0][1]) / 10000,
            _positions[0][0][2] +
              (_positions[0][1][2] - _positions[0][0][2]) / 10000
          ])
        } else if (_geometry.type === GeometryType.circle) {
          const _circleGeometry = _geometry.toPolygon()
          _positions = _circleGeometry.coordinates
        } else {
          for (let i = 0; i < positions.length; i++) {
            _positions.push([])
            for (let j = 0; j < positions[i].length; j++) {
              _positions[i].push(positions[i][j])
            }
            _positions[i].push([
              _positions[i][0][0] +
                (_positions[i][1][0] - _positions[i][0][0]) / 10000,
              _positions[i][0][1] +
                (_positions[i][1][1] - _positions[i][0][1]) / 10000,
              _positions[i][0][2] +
                (_positions[i][1][2] - _positions[i][0][2]) / 10000
            ])
          }
        }

        // 重新构造一个线几何
        const _lineString = new MultiLineString({
          coordinates: _positions
        })
        // 构造一个线要素
        const _outLineFeature = new Feature({
          geometry: _lineString,
          symbol: _symbol.outline
        })
        const _outline = new SimpleLineGraphic({
          feature: _outLineFeature,
          layerOpacity: this._layerOpacity,
          primitivesCollection: this._primitivesCollection
        })
        return _outline._primitives
      }

      /**
       * 根据要素创建多边形材质
       * @private
       * @return {Cesium.Material} 一个创建好的多边形材质
       * */
      _createPolygonMaterial() {
        const _symbol = this._feature.symbol
        let _material
        switch (_symbol.style) {
          case 'backward-diagonal':
          case 'cross':
          case 'diagonal-cross':
          case 'forward-diagonal':
          case 'horizontal':
          case 'vertical':
            // 没有构造canvas，则构造并保存canvas
            if (!this._canvas) {
              this._canvas = createSimpleFillSymbolCanvas(_symbol)
            }
            // canvas已经构造过了
            else {
              // 初始化时，会调用一次此方法，需要个this._symbol赋值
              if (!this._symbol) {
                this._symbol = this._feature.symbol
              }
              // 判断新旧两个symbol是否相等
              const _isSymbolEqual = this._symbolEquals(_symbol, this._symbol)
              // 不相等，则重新构造canvas
              if (!_isSymbolEqual) {
                this._canvas = createSimpleFillSymbolCanvas(_symbol)
                this._symbol = _symbol
              }
            }
            _material = Material.fromType('TextImage', {
              image: this._canvas,
              repeat: new Cartesian2(4.0, 4.0),
              alpha: this._layerOpacity
            })
            break
          default:
            const _color = this._getCesiumColor(_symbol.color)
            // 设置图层透明度
            _color.alpha *= this._layerOpacity
            _material = Material.fromType('Color', {
              color: _color
            })
            break
        }
        return _material
      }

      /**
       * 判断新旧两个符号的属性是否相等
       * @private
       * @param {Symbol} symbol1 第一个符号
       * @param {Symbol} symbol2 第二个符号
       * @return {Boolean} 符号是否相等
       * */
      _symbolEquals(symbol1, symbol2) {
        if (
          symbol1.style !== symbol2.style ||
          symbol1.color.red !== symbol2.color.red ||
          symbol1.color.green !== symbol2.color.green ||
          symbol1.color.blue !== symbol2.color.blue ||
          symbol1.color.alpha !== symbol2.color.alpha ||
          symbol1.outline.width !== symbol2.outline.width ||
          symbol1.outline.color.red !== symbol2.outline.color.red ||
          symbol1.outline.color.green !== symbol2.outline.color.green ||
          symbol1.outline.color.blue !== symbol2.outline.color.blue ||
          symbol1.outline.color.alpha !== symbol2.outline.color.alpha
        ) {
          return false
        }

        return true
      }
    }

    export default SimpleFillGraphic