import * as TWEEN from '@tweenjs/tween.js'
import { amtMount, amtRemove } from './center'

export default class Car {
  car
  direct = null // 隧道编码
  curves = null // 隧道引导线
  infos = null // 车辆基础信息
  dir_sign = 1 // 变道符

  lanex // 车道
  distance = 0 // 行驶距离
  miles = 0 // 隧道长
  speed = 0 // 车速

  // long = 0 // 隧道长
  direct = null // 加偏符

  followed = false
  camera = null

  xSpeed = 0.02 // 速度

  lanes = [0, 3.5]
  turnning = false // 变道状态
  taglane = null // 目标车道
  // torque = 0.05 // 转向速度
  // tadd = 0 // 转向增量
  tsign = 0 // 转向符号
  tag_pgress = 0
  start_radian = 0 // 偏转初始弧度
  tag_radian = (Math.PI / 180) * 30 // 转向弧度


  constructor (context, configs) {

    this.car = configs.model.scene.clone()
    this.direct = configs.infos.direct
    this.dir_sign = this.direct ? 1 : -1
    this.curves = configs.curves
    this.miles = configs.miles
    this.distance = configs.infos.distance
    this.speed = configs.infos.speed * 1000 / 3600
    this.infos = configs.infos

    this.lanex = configs.infos.lanex
    
    this.car.scale.set(0.2, 0.2, 0.2)

    const progress = this.distance / this.miles

    const nowCurver = this.curves[this.lanex]
    const position = nowCurver.getPointAt(progress)
    const direction = nowCurver.getTangentAt(progress).add(position)
    
    // position.z = position.z + this.lanes[this.lanex - 1] * this.dir_sign

    // direction.z += 10

    this.car.position.copy(position)
    this.car.lookAt(direction)

    context.scene.add(this.car)

  }

  run (delay) {

    this.distance += delay * this.speed
    const progress = this.distance / this.miles
    const nowCurver = this.curves[this.lanex]
    const position = nowCurver.getPointAt(progress)

    // 转向
    if (this.turnning) {

      // 转向超距
      /* const outTunnning = (this.tsign > 0 && (this.lanes[this.lane - 1] + this.tadd * this.tsign > this.lanes[this.taglane - 1])) ||
                          (this.tsign < 0 && (this.lanes[this.lane - 1] + this.tadd * this.tsign) < this.lanes[this.taglane - 1])

      if (outTunnning) {
        this.turnning = false
        this.lane = this.taglane
        this.turnning = false
        this.taglane = null
        this.tadd = 0
        this.tsign = 0
      } else {
        this.tadd += this.torque
      }*/

      const otherCurver = this.curves[this.taglane]
      const _position = otherCurver.getPointAt(progress)

      const vx = (_position.x - position.x) * this.tag_pgress
      const vy = (_position.y - position.y) * this.tag_pgress
      const vz = (_position.z - position.z) * this.tag_pgress

      position.x = position.x + vx
      position.y = position.y + vy
      position.z = position.z + vz

      // 转向超距
      if (this.tag_pgress === 1) {
        this.lanex = this.taglane
        this.turnning = false
        this.taglane = null
        this.tag_pgress = 0
        this.start_radian = 0
      }
      
    }

    const direction = nowCurver.getTangentAt(progress).add(position)

    this.car.position.copy(position)
    this.car.lookAt(direction)

    // 添加转向角
    if (this.turnning) {
      const d_radian = this.tag_radian * Math.sin(this.tag_pgress * Math.PI) * this.tsign
      this.car.rotation.y = this.start_radian + d_radian
    }


  }

  // 基础信息更新（速度、车道、桩米号）
  update (newcar) {

    this.infos = newcar
    this.speed = newcar.speed * 1000 / 3600
    
    if (this.lanex !== newcar.lanex) {
      this.laneChange(newcar.lanex)
    }

  }

  follow (camera) {

    this.followed = true
    this.camera = camera
   
    this.camera.position.set(0, 10, -15)
    this.camera.lookAt(0, 5, 0)
    this.car.add(camera)
    
  }

  stopFollow () {
    this.car.remove(this.camera)
    this.camera = null
    this.followed = false
  }

  laneChange (target) {

    if (this.turnning) return

    this.turnning = true
    this.taglane = 1 - this.lanex
    this.tsign = this.taglane - this.lanex
    this.start_radian = this.car.rotation.y

    const tween = new TWEEN.Tween({ rate: 0 })
      .to({ rate: 1 }, 1000)
      .easing(TWEEN.Easing.Quadratic.InOut)
    const key = amtMount(() => {
      tween.update()
    })
    tween.onUpdate(e => {
      this.tag_pgress = e.rate
    })
    tween.onComplete(() => {
      amtRemove(key)
    })

    tween.start()
    
  }

}