import SheencityAdapter from '../js/SheencityAdapter'
import WYAdapter from '../js/WYAdapter'
import { mapType } from '../js/MapLocalConfig'
import TacosAdapter from '../js/TacosAdapter'

/**
 * @class Map3DAdapter
 * @classdesc 3d地图接口适配器
 * 约定：
 * 1、id作为唯一标识
 */
export class Map3DAdapter {
  /**
   * 构造函数
   * @param {string} div 地图容器dom id
   */
  constructor(div) {
    switch (window.mapconfig.mapType) {
      case mapType.Diva:
        this.mapInstance = new SheencityAdapter(div, window.mapconfig.url, window.mapconfig.key)
        break
      case mapType.SuperAPI:
        this.mapInstance = new WYAdapter(div, window.mapconfig.url, window.mapconfig.key)
        break
      case mapType.TacosSDK:
        this.mapInstance = new TacosAdapter(
          div,
          window.mapconfig.url,
          window.mapconfig.mapping,
          window.mapconfig.modelPath
        )
        break
    }
  }
  /**
   * 加载地图实例
   * @param {Event} callback 加载地图实例回调函数
   */
  loading(callback) {
    this.mapInstance.initialInstance(function (map) {
      callback(map)
    })
  }
  /**
   * 加载场景
   * @param {string} scenename 场景名称
   * @param {function} callback 回调函数
   */
  loadScene(scenename, callback) {
    this.mapInstance.loadScene(scenename, function (e) {
      callback(e)
    })
  }

  /**
   * 设置镜头参数
   * @param {CameraInfo} info 镜头参数类
   * @returns 成功、失败回调
   */
  setCameraInfo(info) {
    return this.mapInstance.setCameraInfo(info)
  }
  /**
   * 获得镜头参数
   * @returns CameraInfo 镜头参数
   */
  getCameraInfo() {
    return this.mapInstance.getCameraInfo()
  }
  /**
   * 设置镜头绕场景中心点旋转
   * @param {number} time 旋转一周所需要的时间,单位秒
   * @param {RotateDirection} direction 旋转方向，clockwise:顺时针; anticlockwise:逆时针; stop:停止旋转
   * @returns 成功、失败回调
   */
  setCameraRotate(time, direction) {
    return this.mapInstance.setCameraRotate(time, direction)
  }
  /**
   * 场景镜头限制
   * @param {object} options 镜头参数
   * @param {number[]} options.pitch 俯仰角范围
   * @param {number[]} options.yaw 偏航角范围
   * @param {object} options.boundingBox {min:[x1,y1,z1],max:[x2,y2,z2]} 镜头坐标限制范围
   * @param {number} options.minDistance 最小镜头距离
   * @param {number} options.maxDistance 最大镜头距离
   */
  setCameraLimit(options) {
    this.mapInstance.setCameraLimit(
      options.pitch,
      options.yaw,
      options.boundingBox,
      options.minDistance,
      options.maxDistance
    )
  }
  /**
   * 设置渲染分辨率（51World和光辉城市支持）
   * @param {number} width 宽
   * @param {number} height 高
   */
  setResolution(width, height) {
    this.mapInstance.setResolution(width, height)
  }
  /**
   * 取消镜头限制
   */
  removeCameraLimit() {
    this.mapInstance.removeCameraLimit()
  }

  /**
   * 开启镜头移动
   * @param {object} options 镜头移动参数
   * @param {number} options.duaration 漫游持续时间
   * @param {number} options.speed 漫游速度，单位米/秒
   * @param {boolean} options.loop 是否循环
   * @param {number} options.armDistance 镜头沿视角到路径的距离，单位米
   * @param {number} options.roll 翻滚角
   * @param {number} options.pitch 俯仰角
   * @param {number} options.yaw 偏航角
   * @param {number[][]} options.path 路径点
   * @returns 成功、失败回调
   */
  startThirdPersonRoaming(options) {
    return this.mapInstance.startThirdPersonRoaming(
      options.duaration,
      options.speed,
      options.loop,
      options.armDistance,
      options.roll,
      options.pitch,
      options.yaw,
      options.path
    )
  }
  /**
   * 暂停镜头移动
   * @returns 成功、失败回调
   */
  pauseThirdPersonRoaming() {
    return this.mapInstance.pauseThirdPersonRoaming()
  }
  /**
   * 继续镜头移动
   * @returns 成功、失败回调
   */
  continueThirdPersonRoaming() {
    return this.mapInstance.continueThirdPersonRoaming()
  }
  /**
   * 停止镜头移动
   * @returns 成功、失败回调
   */
  stopThirdPersonRoaming() {
    return this.mapInstance.stopThirdPersonRoaming()
  }
  /**
   * 镜头聚焦实体
   * @param {string} id 聚焦目标实体的 id
   * @param {number} distance 距离，单位米
   * @param {EntityType} type 物体类型
   * @param {boolean} isFlashing 是否闪烁
   * @returns 成功、失败回调
   */
  focusEntity(id, distance, type, isFlashing) {
    return this.mapInstance.focusEntity(id, distance, type, isFlashing)
  }
  /**
   * 销毁实体
   * @param {string} id 需要销毁的实体id
   * @param {EntityType} type 物体类型
   * @returns 成功、失败回调
   */
  destroyEntity(id, type) {
    return this.mapInstance.destroyEntity(id, type)
  }
  /**
   * 高亮实体
   * @param {string} id 高亮实体id
   * @param {number[]} borderColor 高亮实体边颜色[r,g,b]
   * @returns 成功、失败回调
   */
  highlightEntity(id, borderColor) {
    return this.mapInstance.highlightEntity(id, borderColor)
  }
  /**
   * 取消高亮实体
   * @param {string} id 取消高亮实体id
   * @returns 成功、失败回调
   */
  restoreEntity(id) {
    return this.mapInstance.restoreEntity(id)
  }
  /**
   * 隐藏实体
   * @param {string} id 隐藏实体id
   * @returns 成功、失败回调
   */
  hideEntity(id) {
    return this.mapInstance.hideEntity(id)
  }
  /**
   * 显示实体
   * @param {string} id 显示实体id
   * @returns 成功、失败回调
   */
  showEntity(id) {
    return this.mapInstance.showEntity(id)
  }
  /**
   * 创建POI
   * @param {POI} poidata POI点数据类
   * @returns 成功、失败回调
   */
  addPOI(poidata) {
    return this.mapInstance.addPOI(poidata)
  }
  /**
   * 根据id获取实体信息
   * 【注：51world superapi 需要点击对应实体获得id】
   * @param {string} id 实体id
   * @returns 实体信息
   */
  getEntityByID(id) {
    return this.mapInstance.getEntityByID(id)
  }
  /**
   * 获取场景内所有实体
   * @returns 场景内所有实体信息
   */
  getAllEntityIds() {
    return this.mapInstance.getAllEntityIds()
  }

  // getClickPosition () {
  //     return this.mapInstance.getClickPosition()
  // }
  /**
   * 设置环境时间
   * @param {number} datetime 时间戳
   * @returns 成功、失败回调
   */
  setDateTime(datetime) {
    return this.mapInstance.setDateTime(datetime)
  }
  /**
   * 设置天气
   * @param {Weather} name 天气
   * @returns 成功、失败回调
   */
  setWeather(name) {
    return this.mapInstance.setWeather(name)
  }
  /**
   * 创建热力图
   * @param {object} options 热力图参数
   * @param {string} options.id 热力图id
   * @param {number} options.radius 热力半径，单位米
   * @param {number[]} options.minCoord 区域最小坐标 [x,y,z]
   * @param {number[]} options.maxCoord 区域最大坐标 [x,y,z]
   * @param {number[][]} options.posvalue 位置与数据，[[x,y,value],..]
   * @returns 成功、失败回调
   */
  createHeatmap(options) {
    return this.mapInstance.createHeatmap(
      options.id,
      options.radius,
      options.minCoord,
      options.maxCoord,
      options.posvalue
    )
  }
  /**
   * 创建弹窗
   * @param {object} options 弹窗参数
   * @param {string} options.poiId 需要创建弹窗的实体id
   * @param {string} options.windowID 创建弹窗的id
   * @param {string} options.windowUrl 弹窗内容html地址
   * @param {number} options.width 窗口宽，单位像素
   * @param {number} options.height 窗口高，单位像素
   * @param {number} options.xoffset 弹窗左上角相对横向偏移量，单位像素
   * @param {number} options.yoffset 弹窗左上角相对纵向偏移量，单位像素
   * @param {EntityType} options.type 要创建弹窗的实体类型
   * @returns 成功、失败回调
   */
  addInfowindow(options) {
    return this.mapInstance.addInfowindow(
      options.poiId,
      options.windowID,
      options.windowUrl,
      options.width,
      options.height,
      options.xoffset,
      options.yoffset,
      options.type
    )
  }
  /**
   * 销毁弹窗
   *【注：51world superapi存在无法取消实体选中状态问题，若再次addInfowindow需要点击两次，第一次取消实体焦点，第二次点击实体出现弹窗】
   * @param {string} poiId 绑定弹窗的实体id
   * @param {string} windowID 弹窗id
   * @param {EntityType} type 绑定弹窗的实体类型
   * @returns 成功、失败回调
   */
  destroyInfowindow(poiId, windowID, type) {
    return this.mapInstance.destroyInfowindow(poiId, windowID, type)
  }
  /**
   * 楼层展开
   * @param {object} options 展开楼层参数
   * @param {string} options.buildingId 需要展开的建筑id
   * @param {string[]} options.floorIds 需要展开的楼层id/楼层文件路径
   * @param {number} options.space 展开后楼层间间隔距离，单位米
   * @param {number} options.floor 楼层号
   * @returns 成功、失败回调
   */
  explodeEntity(options) {
    return this.mapInstance.explodeEntity(options.buildingId, options.floorIds, options.space, options.floor)
  }
  /**
   * 楼层还原
   * @param {string} buildingId 需要展开的建筑id
   * @param {string[]} floorIds 需要展开的楼层id
   * @param {number} floor 楼层号
   * @returns 成功、失败回调
   */
  unexplodedEntity(buildingId, floorIds) {
    return this.mapInstance.unexplodedEntity(buildingId, floorIds)
  }
  /**
   * 添加模型实体
   * @param {object} options 模型参数
   * @param {string} options.id 模型实体id
   * @param {number[]} options.position 位置 [x,y,z]
   * @param {string} options.resourceName  资源库中资源的名称
   * @param {number} options.roll 翻滚角
   * @param {number} options.pitch 俯仰角
   * @param {number} options.yaw 偏航角
   * @param {number[]} options.scale 比例 [scaleX,scaleY,scaleZ]
   * @returns 成功、失败回调
   */
  addModel(options) {
    return this.mapInstance.addModel(
      options.id,
      options.position,
      options.resourceName,
      options.roll,
      options.pitch,
      options.yaw,
      options.scale
    )
  }
  /**
   * 开启模型移动
   * @param {object} options 模型移动参数
   * @param {string} options.id 模型实体id
   * @param {number} options.duaration 移动持续时间
   * @param {number} options.speed 速度，单位米/秒
   * @param {boolean} options.loop 是否循环
   * @param {number[][]} options.path 路径点
   * @param {number} options.roll 翻滚角
   * @param {number} options.pitch 俯仰角
   * @param {number} options.yaw 偏航角
   * @returns 成功、失败回调
   */
  startEntityMoving(options) {
    return this.mapInstance.startEntityMoving(
      options.id,
      options.duaration,
      options.speed,
      options.loop,
      options.path,
      options.roll,
      options.pitch,
      options.yaw
    )
  }
  /**
   * 暂停模型移动
   * @param {string} id 模型实体id
   * @returns 成功、失败回调
   */
  pauseEntityMoving(id) {
    return this.mapInstance.pauseEntityMoving(id)
  }
  /**
   * 继续模型移动
   * @param {string} id 模型实体id
   * @returns 成功、失败回调
   */
  resumeEntityMoving(id) {
    return this.mapInstance.resumeEntityMoving(id)
  }
  /**
   * 停止模型移动
   * @param {string} id 模型实体id
   * @returns 成功、失败回调
   */
  stopEntityMoving(id) {
    return this.mapInstance.stopEntityMoving(id)
  }
  /**
   * 创建特效
   * @param {object} options 特效参数
   * @param {string} options.id 特效id
   * @param {string} options.resourceName 资源库中资源的名称
   * @param {number[]} options.position 特效位置，[x,y,z]
   * @param {number} options.roll 翻滚角
   * @param {number} options.pitch 俯仰角
   * @param {number} options.yaw 偏航角
   * @param {number[]} options.scale 比例 [scaleX,scaleY,scaleZ]
   * @returns 成功、失败回调
   */
  addEffect(options) {
    return this.mapInstance.addEffect(
      options.id,
      options.resourceName,
      options.position,
      options.roll,
      options.pitch,
      options.yaw,
      options.scale
    )
  }
  /**
   * 创建三维文字
   * @param {object} options 文字参数
   * @param {string} options.id 文字id
   * @param {string} options.text 文字内容
   * @param {number[]} options.position 文字位置,[x,y,z]
   * @param {number[]} options.color 颜色 [r,g,b,a]
   * @param {number} options.roll 翻滚角
   * @param {number} options.pitch 俯仰角
   * @param {number} options.yaw 偏航角
   * @param {number[]} options.scale 比例 [scaleX,scaleY,scaleZ]
   * @param {number} options.thickness 厚度
   * @returns 成功、失败回调
   */
  add3dText(options) {
    return this.mapInstance.add3dText(
      options.id,
      options.text,
      options.position,
      options.color,
      options.roll,
      options.pitch,
      options.yaw,
      options.scale,
      options.thickness
    )
  }
  /**
   * 创建路径
   * @param {object} options 路径参数
   * @param {string} id 路径id
   * @param {number[][]} path 路径点
   * @param {PathStyle} pathStyle 路径样式
   * @param {number[]} color 颜色 [r,g,b,a]
   * @param {number} width 宽度
   * @returns 成功、失败回调
   */
  addPath(options) {
    return this.mapInstance.addPath(options.id, options.path, options.pathStyle, options.color, options.width)
  }

  /**
   * 创建区域
   * @param {object} options 区域参数
   * @param {string} id 区域id
   * @param {number[][]} path 路径点
   * @param {AreaStyle} areaStyle 区域样式
   * @param {number[]} color 颜色 [r,g,b,a]
   * @param {number} height 区域高度，单位米
   * @returns 成功、失败回调
   */
  addArea(options) {
    return this.mapInstance.addArea(options.id, options.path, options.areaStyle, options.color, options.height)
  }
  /**
   * 销毁实例
   */
  destroyMap() {
    this.mapInstance.destroyMap()
  }
  /**
   *注册事件
   * @param {string} eventType mouseover,mouseout,click,
   * @param {function} callback
   */
  on(eventType, callback) {
    this.mapInstance.addEventListener(eventType, function (e) {
      callback(e)
    })
  }
  /**
   * 移除事件
   * @param {string} eventType mouseover,mouseout,click,
   */
  off(eventType) {
    this.mapInstance.removeEventListener(eventType)
  }
  // enableDragging (name) {
  //     this.mapInstance.mapEditor.enableDragging(name)
  // }
  // disableDragging () {

  // }
  // saveEditing () {

  // }
}
