// 通过碰撞 进行碰撞交互
// 没有具体业务逻辑，需要用户添加事件
class ColliderTrigger extends THING.Component {
  onAwake() {
    // 主动碰撞进入evts
    this.enterEvts = new Set()
    // 主动碰撞离开evts
    this.exitEvts = new Set()
    // 被动碰撞进入evts
    this.passiveEnterEvts = new Set()
    // 被动碰撞离开evts
    this.passiveExitEvts = new Set()

    this.enterMap = new Set()
    // 监听
    this.addColliderEvt(this.object.collider)
  }
  onStart() {
    const { object } = this
    object.waitForComplete().then(() => {
      // 碰撞包围盒大小设置
      const localBoundingBox = object.body.getLocalBoundingBox()
      object.collider.enable = true
      object.collider.mode = THING.ColliderType.Box
      object.collider.offset = localBoundingBox.center
      object.collider.halfSize = localBoundingBox.halfSize
    })
  }

  /**
   * 获取当前 碰撞未离开的所有对象(Array)
   */
  get colliderObjects() {
    return Array.from(this.enterMap)
  }
  /**
   * 移除碰撞体的enter exit事件
   */
  clearColliderEvt(collider) {
    const col = collider || this.object.collider
    this.clearColliderEnterEvt(col)
    this.clearColliderExitEvt(col)
    this.enterMap.clear()
  }

  /**
   * 移除碰撞体的 enter 事件
   */
  clearColliderEnterEvt(collider) {
    const col = collider || this.object.collider

    const self = this
    col.removeEventListener(THING.EventType.ColliderEnter, self.enterFn)
  }

  /**
   * 移除碰撞体的 exit 事件
   */
  clearColliderExitEvt(collider) {
    const col = collider || this.object.collider

    const self = this
    col.removeEventListener(THING.EventType.ColliderLeave, self.exitFn)
  }

  /**
   * 监听碰撞 Enter
   * @param {Object} collider 碰撞对象collider
   */
  addColliderEnterEvt(collider) {
    this.enterFn = this._enterFn.bind(this)
    const self = this
    collider.addEventListener(THING.EventType.ColliderEnter, self.enterFn)
  }

  /**
   * 监听碰撞 Exit
   * @param {Object} collider 碰撞对象collider
   */
  addColliderExitEvt(collider) {
    this.exitFn = this._exitFn.bind(this)
    const self = this
    collider.addEventListener(THING.EventType.ColliderLeave, self.exitFn)
  }
  _enterFn(ev) {
    // 这个物体已经碰撞后
    if (this.enterMap.has(ev.object)) {
      return
    }
    this.enterMap.add(ev.object)
    this.enter({
      objects: Array.from(this.enterMap),
      object: ev.object,
      colliderTrigger: ev.object.colliderTrigger,
    })
  }

  _exitFn(ev) {
    if (this.enterMap.has(ev.object)) {
      this.enterMap.delete(ev.object)
      this.exit({
        objects: Array.from(this.enterMap),
        object: ev.object,
        colliderTrigger: ev.object.colliderTrigger,
      })
    }
  }
  /**
   * 监听碰撞enter exit事件
   * @param {Object} collider 碰撞对象collider
   */
  addColliderEvt(collider) {
    this.addColliderEnterEvt(collider)
    this.addColliderExitEvt(collider)
  }
  // 主动碰撞进入触发
  enter(e) {
    this.enterEvts.forEach((evt) => evt(e))
  }
  // 主动碰撞离开触发
  exit(e) {
    this.exitEvts.forEach((evt) => evt(e))
  }

  // 被动触发 碰撞进入，碰撞发生，不会主动触发
  // 可以作为接口方法，被对象调用
  passiveEnter(e) {
    this.passiveEnterEvts.forEach((evt) => evt(e))
  }
  // 被动触发 碰撞离开，碰撞发生，不会主动触发
  // 可以作为接口方法，被对象调用
  passiveExit(e) {
    this.passiveExitEvts.forEach((evt) => evt(e))
  }

  /**
   * 添加碰撞进入的回调函数
   * @param {Function} evt
   */
  addEnterEvt(evt) {
    this.enterEvts.add(evt)
  }
  /**
   * 添加碰撞离开的回调函数
   * @param {Function} evt
   */
  addExitEvt(evt) {
    this.exitEvts.add(evt)
  }
  /**
   * 添加 被动 碰撞进入的回调函数
   * @param {Function} evt
   */
  addPassiveEnterEvt(evt) {
    this.passiveEnterEvts.add(evt)
  }
  /**
   * 添加 被动 碰撞进入的回调函数
   * @param {Function} evt
   */
  addPassiveExitEvt(evt) {
    this.passiveExitEvts.add(evt)
  }
}
