import {
  addM3DLayer,
  addTerrainLayer,
  appendLabelLayer,
  getM3DOptions,
  getTerrainOptions,
  zoomToM3DLayer
} from './support/utils'

class IGSSceneLayerUtil {}

/**
 * 添加场景图层
 * @param {Object} layer 基础图层对象
 * @param {View} innerView cesium的view对象
 * @param {SceneView} sceneView sceneView对象
 * @param {Function} callback 所有子图层加载完毕后的回调函数
 * @param {Function} errorCallback 加载失败的回调函数
 * */
IGSSceneLayerUtil.addSceneLayer = function (
  layer,
  innerView,
  sceneView,
  callback,
  errorCallback
) {
  const subLayers = layer.activeScene.sublayers
  let subLayerLength = 0
  const tileSets = []
  for (let i = 0; i < subLayers.length; i++) {
    switch (subLayers[i].type) {
      // 地形图层
      case '3':
        const terrainOption = getTerrainOptions(subLayers[i])
        terrainOption.url = layer.url
        tileSets.push(addTerrainLayer(innerView, terrainOption))
        subLayerLength++
        break
      // 注记图层
      case '4':
        let _url = `${layer.url}/GetLabels`
        _url += `${_url}sceneIndex=0&layerIndex=${subLayers[i].layerRenderIndex}&level=0&row=0&col=0&format=json&srsName=EPSG:4326`
        subLayerLength++
        const labelLayer = appendLabelLayer(
          _url,
          {},
          {
            labelLayer: subLayers[i].labelLayer
          },
          innerView
        )
        // 添加图层到图层管理容器中
        sceneView._layersMap.put(subLayers[i].id, labelLayer)
        tileSets.push(labelLayer)
        break
      // 模型图层
      case '2':
      case '10':
        const m3dOption = getM3DOptions(subLayers[i])
        m3dOption.url = layer.url
        // 确定是igs服务
        m3dOption.igserver = true
        // 传递剖切封边属性
        m3dOption.fillClip = layer.fillClip
        // G3D服务
        if (m3dOption.url.indexOf('/igs/rest/g3d/') > -1) {
          m3dOption.url = `${m3dOption.url}/GetDataStreams?sceneIndex=0&layerIndex=${subLayers[i].layerRenderIndex}&Level=0&Row=0&Col=0`
          addM3DLayer(
            m3dOption,
            innerView,
            sceneView,
            function (tileSet) {
              subLayerLength++
              tileSets.push(tileSet)
            },
            errorCallback
          )
        }
        // SceneServer服务
        else if (
          m3dOption.url.indexOf('/igs/rest/services/') > -1 &&
          m3dOption.url.indexOf('/SceneServer') > -1
        ) {
          addM3DLayer(
            m3dOption,
            innerView,
            sceneView,
            function (tileSet) {
              subLayerLength++
              tileSets.push(tileSet)
            },
            errorCallback
          )
        }
        break
      default:
        break
    }
  }

  // 等待所有图层加载完毕
  const internal = setInterval(function () {
    if (
      subLayerLength === subLayers.length &&
      callback &&
      callback instanceof Function
    ) {
      clearInterval(internal)
      // 请求完毕后自动跳转
      if (layer.autoReset) {
        // 取得所有tileSet的外包球
        const boundingSpheres = []
        for (let i = 0; i < tileSets.length; i++) {
          let boundingSphere = tileSets[i].boundingSphere
          // 暂时仅判断为地形数据的情况
          if (!boundingSphere) {
            boundingSphere = Cesium.BoundingSphere.fromCornerPoints(
              Cesium.Cartesian3.fromDegrees(
                tileSets[i].range3D.xMin,
                tileSets[i].range3D.yMin,
                tileSets[i].range3D.zMin
              ),
              Cesium.Cartesian3.fromDegrees(
                tileSets[i].range3D.xMax,
                tileSets[i].range3D.yMax,
                tileSets[i].range3D.zMax
              )
            )
          }
          boundingSpheres.push(boundingSphere)
        }
        // 合并外包球
        const mergeBoundingSphere =
          Cesium.BoundingSphere.fromBoundingSpheres(boundingSpheres)
        const m3dOption = getM3DOptions(layer)
        zoomToM3DLayer(mergeBoundingSphere, m3dOption, innerView)
      }
      callback(tileSets)
    }
  }, 50)
}

/**
 * 移除图层
 * @param {Array} tileSets tileSet数组
 * @param {SceneView} sceneView 场景视图对象
 * @param {Viewer} innerView Cesium的视图对象
 * */
IGSSceneLayerUtil.removeLayer = function (tileSets, sceneView, innerView) {
  for (let i = 0; i < tileSets.length; i++) {
    switch (tileSets[i].type) {
      case 'm3d':
        sceneView._layersMap.remove(tileSets[i].id)
        innerView.scene.primitives.removeAndDestroy(tileSets[i])
        break
      case 'terrain':
        innerView.scene.terrainProvider = new Cesium.EllipsoidTerrainProvider()
        break
      case 'label':
        tileSets[i].destroy(true)
        sceneView._layersMap.remove(tileSets[i].id)
        break
      default:
        break
    }
  }
  tileSets = []
}

export default IGSSceneLayerUtil
