    import { Zondy } from '../../../base'
    import { SceneServer } from '../../../service'
    import { defaultValue, Log } from '../../../util'
    import { LayerType, LoadStatus } from '../../../base/enum'
    import { SceneLayer } from '../baseLayer'
    import Scene from './Scene'
    import IGSSceneSubLayer from './IGSSceneSubLayer'

    /**
     * IGS的SceneLayer图层
     * @class IGSSceneLayer
     * @moduleEX LayerManagerModule
     * @extends SceneLayer
     * @param {Object} options 构造参数
     * @param {String} [options.url] 服务基地址
     * @param {Boolean} [options.autoReset = true] 模型加载后，是否自动跳转
     * @param {Number} [options.duration = 1] 跳转持续时间
     * @param {Number} [options.maximumScreenSpaceError = 16] 最大屏幕空间误差，用来控制模型加载数量
     * @param {Function} [options.callback] 最大屏幕空间误差，用来控制模型加载数量
     * @param {Function} [options.gltfParsedCallback] gltf解析完成回调，提供修改gltf对象能力，MapGISM3DSet中包含多个gltf,对所有的gltf应用同一个回调可能不合适
     * @param {Boolean} [options.fillClip = false] 是否需要填充M3D数据剖面，在MapGISM3DSet构造函数中给的原因是，要想支持剖面选取高亮必须统计primitive的oid列表,为了节省内存,原始数据在加载完成后就会释放，后续没有时机统计oid列表
     * @param {Boolean} [options.hasSectionGeometry = false] 是否会存在剖面几何，如果后续会addSectionGeometry方法给m3d图层设置剖切面设置为true
     * @param {Cartesian2} [options.textureCoordScale] 模型纹理拉伸比例，默认不发生变化
     */
    class IGSSceneLayer extends SceneLayer {
      constructor(options) {
        super(options)
        options = defaultValue(options, {})

        /**
         * 服务基地址
         * @member {String} IGSSceneLayer.prototype.url
         */
        this.url = defaultValue(options.url, '')
        /**
         * 图层类型
         * @member {String} IGSSceneLayer.prototype.type
         */
        this.type = LayerType.scene
        /**
         * 服务版本号
         * @member {String} IGSSceneLayer.prototype.version
         */
        this.version = undefined
        /**
         * 模型外包盒
         * @member {Object} IGSSceneLayer.prototype.boundingVolume
         */
        this.boundingVolume = undefined
        /**
         * 模型外包球
         * @readonly
         * @member {Object} IGSSceneLayer.prototype.boundingSphere
         */
        this.boundingSphere = undefined
        /**
         * 服务名
         * @member {String} IGSSceneLayer.prototype.sceneName
         */
        this.sceneName = undefined
        /**
         * 服务包含的表字段数组
         * @member {String} IGSSceneLayer.prototype.fieldInfo
         */
        this.fieldInfo = undefined
        /**
         * 模型位置
         * @member {Object} IGSSceneLayer.prototype.position
         */
        this.position = undefined
        /**
         * 模型坐标系
         * @member {Object} IGSSceneLayer.prototype.spatialReference
         */
        this.spatialReference = undefined
        /**
         * 描述信息
         * @member {String} IGSSceneLayer.prototype.description
         */
        this.description = '场景图层'
        /**
         * 模型加载后，是否自动跳转
         * @member {Boolean} IGSSceneLayer.prototype.autoReset
         */
        this.autoReset = defaultValue(options.autoReset, false)
        /**
         * 跳转持续时间
         * @member {Number} IGSSceneLayer.prototype.duration
         */
        this.duration = defaultValue(options.duration, 1)
        /**
         * 最大屏幕空间误差，用来控制模型加载数量
         * @member {Number} IGSSceneLayer.prototype.maximumScreenSpaceError
         */
        this.maximumScreenSpaceError = defaultValue(
          options.maximumScreenSpaceError,
          16
        )
        /**
         * MapGISM3DSet的每帧回调函数
         * @member {Function} IGSSceneLayer.prototype.callback
         */
        this.callback = defaultValue(options.callback, undefined)
        /**
         * gltf解析完成回调，提供修改gltf对象能力，MapGISM3DSet中包含多个gltf,对所有的gltf应用同一个回调可能不合适
         * @member {Function} IGSSceneLayer.prototype.gltfParsedCallback
         */
        this.gltfParsedCallback = defaultValue(
          options.gltfParsedCallback,
          undefined
        )
        /**
         * 是否需要填充M3D数据剖面，在MapGISM3DSet构造函数中给的原因是，要想支持剖面选取高亮必须统计primitive的oid列表,为了节省内存,原始数据在加载完成后就会释放，后续没有时机统计oid列表
         * @member {Boolean} IGSSceneLayer.prototype.fillClip
         */
        this.fillClip = defaultValue(options.fillClip, false)
        /**
         * 是否会存在剖面几何，如果后续会addSectionGeometry方法给m3d图层设置剖切面设置为true
         * @member {Boolean} IGSSceneLayer.prototype.hasSectionGeometry
         */
        this.hasSectionGeometry = defaultValue(options.hasSectionGeometry, false)
        /**
         * 模型纹理拉伸比例，默认不发生变化
         * @member {Cartesian2} IGSSceneLayer.prototype.textureCoordScale
         */
        this.textureCoordScale = defaultValue(options.textureCoordScale, undefined)

        this._sceneServer = new SceneServer({
          url: this.url
        })
      }

      load() {
        const self = this
        return this._sceneServer
          .queryServerInfo()
          .then((result) => {
            Log.info('SceneServer信息查询成功:', result)
            const data = result.data
            // igs2.0
            if (
              self.url.indexOf('/igs/rest/services/') > -1 &&
              self.url.indexOf('/SceneServer') > -1
            ) {
              const sceneOptions = JSON.parse(JSON.stringify(data))
              sceneOptions.layer = self

              self.sceneName = data.dataName
              self.scenes = [new Scene(sceneOptions)]
              self.activeScene = self.scenes[0]
              self.documentInfo = data
              const sceneRange = data.sceneRange
              self.boundingSphere = {}
              self.boundingSphere.center = Cesium.Cartesian3.fromDegrees(
                (sceneRange.xMin + sceneRange.xMax) / 2,
                (sceneRange.yMin + sceneRange.yMax) / 2
              )
              const diff = Cesium.Cartesian3.fromDegrees(
                sceneRange.xMax - sceneRange.xMin,
                sceneRange.yMax - sceneRange.yMin
              )
              self.boundingSphere.radius = Math.abs(Math.min(diff.x, diff.y))
              return self._sceneServer.queryLayerListInfo().then((listInfoData) => {
                const layers = listInfoData.data.layers
                function setLayers(layers, scene) {
                  for (let i = 0; i < layers.length; i++) {
                    if (
                      layers[i].layerType === '9' &&
                      Array.isArray(layers[i].children)
                    ) {
                      setLayers(layers[i].children, scene)
                    } else {
                      layers[i].layer = self
                      scene.sublayers.push(new IGSSceneSubLayer(layers[i]))
                    }
                  }
                }
                setLayers(layers, self.scenes[0])
                return new Promise((resolve) => {
                  self.loadStatus = LoadStatus.loaded
                  self.loaded = true
                  resolve(self)
                })
              })
            } else if (self.url.indexOf('/igs/rest/g3d/') > -1) {
              const sceneInfos = data.sceneInfos
              self.scenes = []
              for (let i = 0; i < sceneInfos.length; i++) {
                self.scenes.push(new Scene(sceneInfos[i]))
                const layers = sceneInfos[i].layers
                for (let j = 0; j < layers.length; j++) {
                  layers[j].layer = self
                  self.scenes[i].sublayers.push(new IGSSceneSubLayer(layers[j]))
                }
              }
              self.activeScene = self.scenes[0]
              self.sceneName = self.activeScene.sceneName
              self.documentInfo = data
              return new Promise((resolve) => {
                self.loadStatus = LoadStatus.loaded
                self.loaded = true
                resolve(self)
              })
            }
          })
          .catch((result) => {
            Log.info('SceneServer信息查询失败:', result)
          })
      }

      /**
       * @description 转换为json对象
       * @return {Object} json对象
       */
      toJSON() {
        const json = super.toJSON()
        json.url = this.url
        json.version = this.version
        json.boundingVolume = this.boundingVolume
        json.sceneName = this.sceneName
        json.fieldInfo = this.fieldInfo
        json.position = this.position
        json.autoReset = this.autoReset
        json.duration = this.duration
        json.maximumScreenSpaceError = this.maximumScreenSpaceError
        json.callback = this.callback
        json.gltfParsedCallback = this.gltfParsedCallback
        json.fillClip = this.fillClip
        json.hasSectionGeometry = this.hasSectionGeometry
        json.textureCoordScale = this.textureCoordScale
        return json
      }

      /**
       * @description 克隆方法
       * @return {IGSSceneLayer} 图层
       */
      clone() {
        return new IGSSceneLayer(this.toJSON())
      }
    }

    Zondy.Layer.IGSSceneLayer = IGSSceneLayer
    export default IGSSceneLayer