import { Diva } from '@sheencity/diva-sdk'
import { CameraInfo, PathStyle, AreaStyle, Weather } from '../export/BasicClass'
import { map, filter } from 'rxjs'

/**
 * @class SheencityAdapter
 * @classdesc 光辉城市接口类
 */
export default class SheencityAdapter {
  constructor(div, url, key) {
    this.div = div
    this.url = url
    this.key = key
    this.cloudRender = null
    this.eventSubscription = null
  }
  /**
   * 初始化地图实例
   */
  initialInstance(callback) {
    var that = this
    const element = document.getElementById(that.div)
    const diva = new Diva({
      mode: 'cloud',
      apiKey: that.key, // API 调用密钥 <small>_（开发版暂不需要，发布项目需要）
      container: element, // 用于绘制 DIVA 世界画面的 DOM 占位元素
      url: new URL(that.url), // 信令服务器地址
      logType: 'resolved', // 可选，日志类型；'resolved'：在控制台以字符串形式打印；'raw'：以二进制形式打印；'none'：不打印。默认：'resolved'
      suppressBrowserKeys: true // [>= sdk v1.1.0]可选，是否禁用浏览器键的默认行为；包含 F1~F12 及 Tab 键。默认：true
    })

    diva.init().then((render) => {
      that.cloudRender = render
      var rect = document.getElementById(that.div)
      if (rect) {
        that.setResolution(rect.clientWidth, rect.clientHeight)
      }
      callback(that.cloudRender)
    })
  }
  /**
   * 加载场景
   * @param {string} scenename 场景名称
   * @param {function} callback 回调函数
   */
  loadScene(scenename, callback) {
    // var _this = this

    this.cloudRender
      .request('ApplyScene', {
        name: scenename
      })
      .then((result) => {
        callback(result)
      })
  }
  /**
   * 设置镜头参数
   * @param {CameraInfo} info 镜头参数类
   *  * {number} pitch 镜头俯仰角
   * {number} yaw 镜头偏航角
   * {array}  position 镜头位置 [x,y,z]
   * {array}  lonlat 镜头经纬度 [lon,lat,z]
   * {number} duration 镜头移动时间，单位秒
   * {number} distance 镜头离中心点的距离
   */
  setCameraInfo(cameraInfo) {
    return this.cloudRender.request('SetCamera', {
      pitch: cameraInfo.pitch, // 镜头俯仰角
      yaw: cameraInfo.yaw, // 镜头偏航角
      position: cameraInfo.position, // 镜头位置，[x, y, z]，单位：cm
      coordinate: cameraInfo.lonlat || undefined, // 镜头位置，[经度,纬度,高度(单位: m)]，仅CIM模式下支持，指定 coordinate 时可不指定 position
      duration: cameraInfo.duration // 可选，单位（秒），默认为 2；如设置为 0，则为瞬移
    })
  }
  /**
   * 获得镜头参数
   * @returns CameraInfo 镜头参数
   */
  async getCameraInfo() {
    var respos = await this.cloudRender.request('GetCamera').then((res) => {
      var c = res.result
      return new CameraInfo(c.pitch, c.yaw, c.position, c.coordinate, 0, 0)
    })
    return respos
  }
  /**
   * 设置镜头绕场景中心点旋转
   * @param {number} time 旋转一周所需要的时间,单位秒
   * @param {string} direction 旋转方向，clockwise:顺时针; anticlockwise:逆时针; stop:停止旋转
   */
  setCameraRotate(time, direction) {
    return this.cloudRender.request('SetOrbit', {
      enabled: true && !(direction == 'stop'),
      direction: direction,
      duration: time
    })
  }
  /**
   *
   * @param {array} pitch  镜头俯仰角范围
   * @param {array} yaw 镜头偏航角
   * @param {object} boundingBox 目标对象的外包围盒 {min:[],max:[]}
   * @param {number} minDistance
   * @param {number} maxDistance
   * @returns
   */
  setCameraLimit(pitch, yaw, boundingBox, minDistance, maxDistance) {
    return this.cloudRender.request('SetCameraLimit', {
      pitch: pitch,
      yaw: yaw,
      boundingBox: boundingBox
    })
  }
  /**
   * 取消镜头限制
   */
  removeCameraLimit() {
    this.cloudRender.request('RemoveCameraLimit')
  }
  /**
   * 设置渲染分辨率
   * @param {number} width 宽
   * @param {number} height 高
   */
  setResolution(width, height) {
    this.cloudRender.request('SetResolution', {
      width: width || 1920,
      height: height || 1080
    })
  }
  /**
   * 根据id获取实体信息
   * @param {string} id 实体id
   * @returns 实体信息
   */
  async getEntityByID(id) {
    var respos = await this.cloudRender
      .request('GetEntityById', {
        id: id
      })
      .then((res) => {
        return res.result
      })
    return respos
  }
  /**
   * 获取根目录下所有资源id
   * @returns 根目录下所有资源id
   */
  getAllEntityIds() {
    return this.cloudRender.request('GetEntityIds', {
      group: ''
    })
  }
  /**
   * 镜头聚焦物体
   * @param {string} id 聚焦目标的 id
   * @param {number} distance 距离，单位米
   */
  focusEntity(id, distance, type = null, isFlashing = false) {
    return this.cloudRender.request('FocusOnEntity', {
      id: id,
      distance: distance * 100 || 50, // 镜头到聚焦目标对象 boundingBox 中心的距离，单位 cm
      pitch: -30.0 // 镜头俯仰角，取值范围 [-89.9, 89.9]
    })
  }
  /**
   * 销毁实体
   * @param {string} id 需要销毁的实体id
   * @param {EntityType} type 物体类型
   */
  destroyEntity(id, type = null) {
    return this.cloudRender.request('DestroyEntity', {
      id: id
    })
  }
  /**
   * 隐藏实体
   * @param {string} id 隐藏实体id
   */
  hideEntity(id) {
    return this.cloudRender.request('UpdateEntityStatus', {
      id: id,
      visible: false
    })
  }
  /**
   * 显示实体
   * @param {string} id 显示实体id
   */
  showEntity(id) {
    return this.cloudRender.request('UpdateEntityStatus', {
      id: id,
      visible: true
    })
  }
  /**
   * 高亮实体
   * @param {string} id 高亮实体id
   * @param {array} borderColor 高亮实体边颜色[r,g,b]
   */
  highlightEntity(id, borderColor) {
    var that = this
    return new Promise((resolve) => {
      this.cloudRender
        .request('SetHighlightStyle', {
          // color: [255, 0, 0, 150], // 叠加颜色，[r,g,b,a]，元素范围是 0 ~ 255，以 alpha 值设置透明度
          borderColor: borderColor || [255, 255, 0, 150], // 可选, 边缘色，[r,g,b]，取值范围 [0,0,0]~[255,255,255]，默认 [0,0,0]
          borderSize: 6 // 可选, 边缘宽，值域[0, 10]，默认 0
        })
        .then(() => {
          resolve(
            that.cloudRender.request('SetEntityRenderMode', {
              id: id,
              mode: 'highlight' // 叠色高亮模式
            })
          )
        })
    })
  }
  /**
   * 取消高亮实体
   * @param {string} id 取消高亮实体id
   */
  restoreEntity(id) {
    return this.cloudRender.request('SetEntityRenderMode', {
      id: id,
      mode: 'default' // 目前支持：原始-"default"；红色闪烁-"alarm"；蓝色半透明-"translucence"
    })
  }
  /**
   * 创建热力图
   * @param {string} id 热力图id
   * @param {number} radius 热力半径，单位米
   * @param {array} minCoord 区域最小坐标 [x,y,z]
   * @param {array} maxCoord 区域最大坐标 [x,y,z]
   * @param {array} data 位置与数据，[x,y,z,value]
   */
  createHeatmap(id, radius, minCoord, maxCoord, data) {
    var hdata = data.map((item) => {
      return [item[0], item[1], item[3]]
    })
    return this.cloudRender.request('CreateEntity', {
      id: id, //对象标识符，必须全局唯一，建议使用 GUID
      type: 'heatMap', // 指定类型，热力图类型为 heatMap
      property: {
        radius: radius * 100, // 热力半径, 单位：m
        minOpacity: 0.0, // [>=v4.5.2] 可选，最低透明度，默认为 0.0
        maxOpacity: 1.0, // [>=v4.5.2] 可选，热力图最大不透明度，默认为 1.0
        height: 0, // 可选，热力高度，单位：cm；默认为 0 即面积热力图, > 1 时为立体热力图
        plane: {
          // [>=v4.5.3] 可选，热力点放置平面; 未填时将根据输入的数据自动计算平面范围，默认高度为 0
          min: [minCoord.x, minCoord.y, minCoord.z], // 区域最小坐标, min 和 max 必须 height 值相等; [lng, lat, height], height 单位为 m
          max: [maxCoord.x, maxCoord.y, maxCoord.z] // 区域最大坐标, min 和 max 必须 height 值相等; [lng, lat, height], height 单位为 m
        },
        dataSet: {
          min: 0.0, // 可选，数据正规化下限，为空时自动计算最小值
          max: 100.0, // 可选，数据正规化上限，为空时自动计算最大值
          data: hdata
        }
      }
    })
  }
  /**
   * 创建POI
   * @param {POI} poidata POI点数据类
   */
  addPOI(poidata) {
    return this.cloudRender.request('CreateEntity', {
      id: poidata.id, //对象标识符，必须全局唯一，建议使用 GUID
      type: 'poi', // 指定类型
      resourceName: poidata.resourceName || '', // DIVA 资源库中资源的名称
      position: poidata.position || [0, 0, 0], // 可选，[x, y, z]，单位：cm，默认为 [0,0,0] 即项目原点
      scale: poidata.scale || [1.0, 1.0, 1.0], // [scaleX,scaleY,scaleZ] 可选，默认
      property: {
        iconURL: poidata.iconUrl,
        title: poidata.label || '', // 可选，标题文字，默认无标题（注：部分 POI 资源不支持标题文字）
        autoSize: false // 可选，默认关闭；开启时以屏幕运算，无论远近像素大小固定；关闭时以三维空间运算，近大远小
      }
    })
    // this.mapLayers.push(new Map3DOverLayer(poidata.id, true, MapLayerType.POI))
  }
  /**
   * 设置天气
   * @param {Weather} name 天气
   */
  setWeather(weather) {
    var w = 'default'
    switch (weather) {
      case Weather.晴天:
        w = 'sunny'
        break
      case Weather.阴天:
        w = 'overcast'
        break
      case Weather.小雨:
      case Weather.中雨:
      case Weather.大雨:
        w = 'rain'
        break
      case Weather.小雪:
      case Weather.中雪:
      case Weather.大雪:
        w = 'snow'
        break
      case Weather.雾霾:
        w = 'smog'
        break
      case Weather.少云:
      default:
        w = 'default'
        break
    }
    return this.cloudRender.request('SetWeather', {
      name: w
    })
  }
  /**
   * 设置环境时间
   * @param {int} datetime 时间戳
   */
  setDateTime(date) {
    var time = new Date(date * 1000)
    // var h = time.getHours() + 8
    // time.setHours(h)
    var stime = time.toISOString()
    return this.cloudRender.request('SetTime', {
      time: stime // 时间格式：ISO8601，其中日期部分将会自动忽略
    })
  }
  /**
   * 开启镜头移动
   * @param {number} duaration 漫游持续时间
   * @param {number} speed 漫游速度，单位米/秒
   * @param {boolean} loop 是否循环
   * @param {number} armDistance 镜头沿视角到路径的距离，单位米
   * @param {number} roll 翻滚角
   * @param {number} pitch 俯仰角
   * @param {number} yaw 偏航角
   * @param {array} path 路径点
   */
  startThirdPersonRoaming(duaration, speed = null, loop, armDistance, roll, pitch, yaw, path) {
    return this.cloudRender.request('PlayCameraPath', {
      duration: duaration || 10, // 必填，动画持续时间，单位（秒）
      loop: loop || false, // 可选，是否循环，默认false
      armLength: armDistance || 200, // 可选，摇臂长度，镜头沿视角到路径的距离，单位cm，默认为200cm
      relativeRotation: [roll || 0, pitch || 0, yaw || 0], // 可选，相对路线的旋转角度 [roll,pitch俯仰角,yaw偏航角(0沿路线，180反向)]
      path: {
        positions: path // 非CIM模式下必填，元素格式 [x,y,z]，单位cm
      }
    })
  }
  /**
   * 暂停镜头移动
   */
  pauseThirdPersonRoaming() {
    return this.cloudRender.request('PauseCameraPath')
  }
  /**
   * 继续镜头移动
   */
  continueThirdPersonRoaming() {
    return this.cloudRender.request('PlayCameraPath')
  }
  /**
   * 停止镜头移动
   */
  stopThirdPersonRoaming() {
    return this.cloudRender.request('StopCameraPath')
  }
  /**
   * 创建弹窗
   * @param {string} poiId 需要创建弹窗的实体id
   * @param {string} windowID 创建弹窗的id
   * @param {string} windowUrl 弹窗内容html地址
   * @param {number} width 窗口宽，单位像素
   * @param {number} height 窗口高，单位像素
   * @param {number} xoffset 弹窗左上角相对横向偏移量，单位像素
   * @param {number} yoffset 弹窗左上角相对纵向偏移量，单位像素
   */
  addInfowindow(poiID, windowID, windowUrl, width, height, xOffset, yOffset, type = null) {
    return this.cloudRender.request('CreateWebWidget', {
      entityId: poiID, // 指定要绑定 webwidget 的目标 Entity 的 id
      widget: {
        // 弹窗控制属性
        url: windowUrl, // 弹窗打开的网页路由，支持本地路由
        width: width, // 弹窗宽度，单位（px）
        height: height, // 弹窗高度，单位（px）
        position: 'right', // 可选，"left" "right"，指定弹出界面在模型的哪侧
        angle: 35, // 可选，以竖直方向为基准，竖直连线向左/右偏移角度，单位：角度
        transparent: true, // 可选，是否启用透明度，开启后配合内嵌网页背景为透明以支持异形窗口
        closable: true, // 可选，是否启用右上方关闭按钮
        dismissable: false, // 可选，是否启用单击窗口外自动关闭（右键或左键长按拖动不会触发关闭）
        mouseInput: false, // [>=v0.2.3] 可选，是否接收鼠标事件，默认 false
        keyboardInput: false, // [>=v0.2.3] 可选，是否接收键盘事件，默认 false，单独开启键盘事件不生效，需同时开启鼠标事件
        line: {
          visible: true, // 可选，连线是否显示
          color: [72, 209, 204], // 可选，连线颜色
          horizontalLineLength: 30, // 可选，水平连线长度，单位：像素
          verticalLineLength: 250, // 可选，竖直连线长度，单位：像素
          connectorVisible: true // 可选，连接点是否显示
        }
        // offset: {
        //   // [>=v4.4.2] 可选，以偏移量方式指定相对实体位置，启用时，position/angle/line 属性不生效
        //   x: xOffset, // 弹窗左上角相对实体锚点的横向偏移量，单位: px
        //   y: yOffset // 弹窗左上角相对实体锚点的纵向偏移量，单位: px
        // }
      }
    })
  }
  /**
   * 销毁弹窗
   * @param {string} poiId 绑定弹窗的实体id
   * @param {string} windowID 弹窗id
   * @param {EntityType} type 要创建弹窗的实体类型
   */
  destroyInfowindow(poiId, windowId = null, type = null) {
    return this.cloudRender.request('DestroyWebWidget', {
      entityId: poiId
    })
  }
  /**
   *楼层展开
   * @param {string} buildingId 需要展开的建筑id
   * @param {array} floorIds 需要展开的楼层id,id为string类型
   * @param {number} space 展开后楼层间间隔距离，单位米
   * @param {number} floor 楼层号
   */
  explodeEntity(buildingId = null, floorIds, space, floor = null) {
    return this.cloudRender.request('Explode', {
      enabled: true, // true 时炸开
      duration: 5, // 过渡动画持续时长，单位（秒）
      ids: floorIds, // 待处理目标的 entityId 数组
      floorSpace: space * 100 || 300, // 指定炸开后楼层间间隔距离，单位（cm）
      floorHeight: 290 // 指定原始楼层高度，单位（cm）
    })
  }
  /**
   * 楼层还原
   * @param {string} buildingId 需要展开的建筑id
   * @param {array} floorIds 需要展开的楼层id,id为string类型
   */
  unexplodedEntity(buildingId = null, floorIds) {
    return this.cloudRender.request('Explode', {
      enabled: false,
      ids: floorIds
    })
  }
  /**
   * 添加模型实体
   * @param {string} id 模型实体id
   * @param {array} position 位置 [x,y,z]
   * @param {string} resourceName  资源库中资源的名称
   * @param {number} roll 翻滚角
   * @param {number} pitch 俯仰角
   * @param {number} yaw 偏航角
   * @param {array} scale 比例 [scaleX,scaleY,scaleZ]
   */
  addModel(id, position, resourceName, roll, pitch, yaw, scale) {
    return this.cloudRender.request('CreateEntity', {
      id: id, //对象标识符，必须全局唯一，建议使用 GUID
      type: 'model', // 指定类型
      resourceName: resourceName || '', // DIVA 资源库中资源的名称
      visible: true, // 可选，可见性
      locked: false, // 可选，锁定状态
      position: position || [0, 0, 0], // 可选，[x, y, z]，单位：cm，默认为 [0,0,0] 即项目原点
      rotation: [roll || 0.0, pitch || 0.0, yaw || 0.0], // [roll,pitch,yaw]       可选，默认[0.0,0.0,0.0]
      scale: scale || [1.0, 1.0, 1.0] // [scaleX,scaleY,scaleZ] 可选，默认[1.0,1.0,1.0]
    })
  }
  /**
   * 开启模型移动
   * @param {string} id 模型实体id
   * @param {number} duaration 移动持续时间
   * @param {number} speed 速度，单位米/秒
   * @param {boolean} loop 是否循环
   * @param {array} path 路径点
   * @param {number} roll 翻滚角
   * @param {number} pitch 俯仰角
   * @param {number} yaw 偏航角
   */
  startEntityMoving(id, duration, speed = null, loop, path, roll, pitch, yaw) {
    return this.cloudRender.request('SetPathAnimation', {
      id: id, // 目标对象的 id
      duration: duration || 10, // 必填，动画持续时间，单位（秒）
      loop: loop || false, // 可选，是否循环，默认false
      path: {
        positions: path // 非CIM模式下必填，元素格式 [x,y,z]，单位cm
      },
      interpMode: 'curve', // 可选，插值算法，"curve"、"linear" 默认 "curve",
      relativeRotation: [roll, pitch, yaw], // 可选，相对路线的旋转角度 [roll,pitch俯仰角,yaw偏航角(0沿路线，180反向)]
      // property: {
      //     action: {                       // 特殊，仅当实体类型为 character 时可支持
      //         name: "跑"                    // 路径动画的特定动作，name 选项："走"、"跑"、"骑单车"
      //     }
      // },
      vertical: false // [>=4.5.2] 可选，是否垂直于地面, 默认 false
    })
  }
  /**
   * 暂停模型移动
   * @param {string} id 模型实体id
   */
  pauseEntityMoving(id) {
    return this.cloudRender.request('PausePathAnimation', {
      id: id
    })
  }
  /**
   * 继续模型移动
   * @param {string} id 模型实体id
   */
  resumeEntityMoving(id) {
    return this.cloudRender.request('PlayPathAnimation', {
      id: id
    })
  }
  /**
   * 停止模型移动
   * @param {string} id 模型实体id
   */
  stopEntityMoving(id) {
    return this.cloudRender.request('RemovePathAnimation', {
      id: id
    })
  }
  /**
   * 创建特效
   * @param {string} id 特效id
   * @param {string} resourceName 资源库中资源的名称
   * @param {array} position 特效位置，[x,y,z]
   * @param {number} roll 翻滚角
   * @param {number} pitch 俯仰角
   * @param {number} yaw 偏航角
   * @param {array} scale 比例 [scaleX,scaleY,scaleZ]
   */
  addEffect(id, resourceName, position, roll, pitch, yaw, scale) {
    return this.cloudRender.request('CreateEntity', {
      id: id, //对象标识符，必须全局唯一，建议使用 GUID
      type: 'effect', // 指定类型
      resourceName: resourceName || '', // DIVA 资源库中资源的名称
      visible: true, // 可选，可见性，默认 true
      locked: false, // 可选，锁定状态，默认 false
      position: position || [0, 0, 0], // 可选，[x, y, z]，单位：cm，默认为 [0,0,0] 即项目原点
      rotation: [roll || 0, pitch || 0, yaw || 0], // [roll,pitch,yaw]       可选，默认[0.0,0.0,0.0]
      scale: scale || [1.0, 1.0, 1.0] // [scaleX,scaleY,scaleZ] 可选，默认[1.0,1.0,1.0]
    })
  }
  /**
   * 创建三维文字
   * @param {string} id 文字id
   * @param {string} text 文字内容
   * @param {array} position 文字位置,[x,y,z]
   * @param {array} color 颜色 [r,g,b,a]
   * @param {number} roll 翻滚角
   * @param {number} pitch 俯仰角
   * @param {number} yaw 偏航角
   * @param {array} scale 比例 [scaleX,scaleY,scaleZ]
   * @param {number} thickness 厚度
   */
  add3dText(id, text, position, color, roll, pitch, yaw, scale, thickness) {
    var c = color != undefined ? color.slice(0, 3) : [0, 0, 200]
    var opacity = color != undefined ? color.slice(-1)[0] : 1

    return this.cloudRender.request('CreateEntity', {
      id: id, // 对象标识符，必须全局唯一，建议使用 GUID
      type: 'text3d', // 指定类型
      visible: true, // 可选，可见性，默认 true
      locked: false, // 可选，锁定状态，默认 false
      position: position || [0, 0, 0], // 可选，[x, y, z]，单位：cm，默认为 [0,0,0] 即项目原点
      //coordinate: [116.445,39.918,0],  // 可选，[经度,纬度,高度(单位: m)]，仅CIM模式下支持，指定 coordinate 时可不指定 position
      rotation: [roll || 0, pitch || 0, yaw || 0], // 可选，[roll,pitch,yaw]，默认[0.0,0.0,0.0]
      scale: scale || [1.0, 1.0, 1.0], // 可选，[scaleX,scaleY,scaleZ]，默认[1.0,1.0,1.0]
      property: {
        text: {
          content: text, // 必填，文字内容
          align: 'center', // 可选，水平对齐，center、left、right，默认 center
          verticalAlign: 'bottom', // 可选，垂直对齐，top、middle、bottom，默认 bottom
          letterSpacing: 0, // 可选，scale为1时的字间距，单位cm，默认0，支持负数
          wordSpacing: 0, // 可选，scale为1时的词间距，单位cm，默认0，支持负数
          lineSpacing: 0 // 可选，scale为1时的行间距，单位cm，默认0，支持负数
        },
        style: '自发光', // 必填，样式类型，详细选项见下文描述
        material: {
          // 可选，不填的话，默认使用默认材质对象
          color: c, // 可选，材质颜色，默认为选定风格的预定义
          emissive: 1.0, // 可选，自发光强度，默认为选定风格的预定义
          opacity: opacity // 可选，不透明度，默认为选定风格的预定义
          // speed: 0.5,                  // 可选，动效速度，默认为选定风格的预定义
        },
        thickness: thickness || 5
      }
    })
  }
  /**
   * 创建路径
   * @param {string} id 路径id
   * @param {array} path 路径点
   * @param {PathStyle} pathStyle 路径样式
   * @param {array} color 颜色 [r,g,b,a]
   * @param {number} width 宽度
   */
  addPath(id, path, pathStyle, color, width) {
    var style = '自发光'
    switch (pathStyle) {
      case PathStyle.Dashed:
        style = '管道'
        break
      case PathStyle.Arrow:
        style = 'V形'
        break
      case PathStyle.Flash:
        style = '流动'
        break
      case PathStyle.Solid:
      default:
        style = '自发光'
        break
    }
    var c = color != undefined ? color.slice(0, 3) : [0, 200, 100]
    var opacity = color != undefined ? color.slice(-1)[0] : 0.2

    return this.cloudRender.request('CreateEntity', {
      id: id, //对象标识符，必须全局唯一，建议使用 GUID
      type: 'polyline', // 指定类型
      visible: true, // 可选，可见性，默认 true
      locked: false, // 可选，锁定状态，默认 false
      property: {
        positions: path,
        style: style, // 必填，样式类型，详细选项见下文描述
        interpMode: 'linear', // 可选，"curve"、"linear"，默认"curve"
        mode: 'plane', // [>=v4.5.3] 可选，"plane"、"box"，默认"plane"  [>=v4.5.4] 可选"pipe"
        width: width * 100, // 可选，线宽，单位cm，默认100
        material: {
          color: c, // 可选，材质颜色，默认为选定风格的预定义
          emissive: 1.0, // 可选，自发光强度，默认为选定风格的预定义
          opacity: opacity, // 可选，不透明度，默认为选定风格的预定义
          speed: 0.5 // 可选，动效速度，默认为选定风格的预定义
          // tiling: 30.0,              // 可选，纹理重复数，默认为选定风格的预定义
        }
      }
    })
  }
  /**
   * 创建区域
   * @param {string} id 区域id
   * @param {array} path 路径点
   * @param {AreaStyle} areaStyle 区域样式
   * @param {array} color 颜色 [r,g,b,a]
   * @param {number} height 区域高度，单位米
   */
  addArea(id, path, areaStyle, color, height) {
    var style = '自发光'
    switch (areaStyle) {
      case AreaStyle.Strip:
        style = '围栏条纹渐出'
        break
      case AreaStyle.Grid:
        style = '网格'
        break
      case AreaStyle.Solid:
      default:
        style = '围栏穿透'
        break
    }

    var c = color != undefined ? color.slice(0, 3) : [0, 100, 200]
    var opacity = color != undefined ? color.slice(-1)[0] : 0.2

    return this.cloudRender.request('CreateEntity', {
      id: id, // 对象标识符，必须全局唯一，建议使用 GUID
      type: 'polygon', // 指定类型
      visible: true, // 可选，可见性，默认 true
      locked: false, // 可选，锁定状态，默认 false
      property: {
        positions: path,
        style: style, // 必填，样式类型，详细选项见下文描述
        height: height * 100 || 1000, // 可选，体高度，单位cm，默认100cm(1m)
        material: {
          // 可选，材质属性，如果直接复用默认样式，可不配置
          color: c, // 可选，材质颜色，默认为选定风格的预定义
          emissive: 1.0, // 可选，自发光强度，默认为选定风格的预定义
          opacity: opacity // 可选，不透明度，默认为选定风格的预定义
          // speed: 0.5,                  // 可选，动效速度，默认为选定风格的预定义
          //scale: 1.0,                // 可选，纹理缩放，默认为选定风格的预定义，预设风格中侧面和地面可能配置不同的缩放，配置该参数会覆盖效果
        }
      }
    })
  }
  /**
   * 销毁实例
   */
  async destroyMap() {
    const element = document.getElementById(this.div)
    const diva = new Diva({
      mode: 'cloud',
      apiKey: this.key, // API 调用密钥 <small>_（开发版暂不需要，发布项目需要）
      container: element, // 用于绘制 DIVA 世界画面的 DOM 占位元素
      url: new URL(this.url), // 信令服务器地址
      logType: 'resolved', // 可选，日志类型；'resolved'：在控制台以字符串形式打印；'raw'：以二进制形式打印；'none'：不打印。默认：'resolved'
      suppressBrowserKeys: true, // [>= sdk v1.1.0]可选，是否禁用浏览器键的默认行为；包含 F1~F12 及 Tab 键。默认：true
      receiveVideo: false
    })

    await diva.init()
  }
  addEventListener(eventType, callback) {
    var that = this
    this.cloudRender
      .request('AddGlobalEventListener', {
        type: eventType // 事件类型：click 单击；dblclick 双击；mousedown 按下；mouseup 抬起；mousemove 移动；wheel 滚轮
      })
      .then((e) => {
        const eventBus = that.cloudRender.adapter.messageBus.pipe(
          map((msg) => msg.payload.params),
          filter((params) => params?.event)
        )
        this.eventSubscription = eventBus.subscribe((params) => {
          callback(params)
        })
      })
  }
  removeEventListener(eventType) {
    this.cloudRender
      .request('RemoveGlobalEventListener', {
        type: eventType
      })
      .then(() => {
        this.eventSubscription.unsubscribe()
      })
  }
}
