import { Vec3 } from 'cannon-es'
import * as RE from 'rogue-engine'
import CannonBody from '../../rogue_packages/rogue-cannon/Components/CannonBody.re'

export default class Player extends RE.Component {
  @RE.Prop("Number") speed = 6
  @RE.Prop("Number") angle = 0
  @RE.Prop("Number") rotationSpeed = Math.PI / 32

  @RE.Prop("Boolean") isThrusting = false

  @RE.Prop("Object3D") thrustFlames

  @RE.PropList("Object3D") shipTypes = []
  @RE.Prop("Object3D") activeShipType

  @RE.Prop("Color") shipColor
  @RE.Prop("Material") shipColorMaterial

  @RE.Prop("Audio") thrustSound
  
  awake() {
    // RE.Input.mouse.lock();
  }

  start() {
    this.bodyComponent = RE.getComponent(CannonBody, this.object3d)
    
    this.thrustFlames = this.object3d.getObjectByName("ThrustFlames")
    this.thrustFlames.visible = false
    this.targetAngle = this.angle

    this.refreshShipDisplay()

    window.addEventListener('keydown', event => { if(["Tab"].includes(event.code)) event.preventDefault() })
    // THREE.AudioContext.getContext().resume()

    this.thrustSound.setVolume(0)
    this.thrustSound.setLoop(true)
    this.thrustSound.play()
  }

  refreshShipDisplay() {
    this.shipTypes.forEach(obj3d => {
      obj3d.visible = false
    })

    this.activeShipType.visible = true
    this.shipColorMaterial.color = this.shipColor
  }

  worldInputControl() {
    let keysDown = false
    if(RE.Input.keyboard.getKeyPressed("KeyW")) {
      keysDown = true
      this.targetAngle = Math.PI / 2
      if(RE.Input.keyboard.getKeyPressed("KeyA")) {
        
        this.targetAngle = 3 * Math.PI / 4
      } else if (RE.Input.keyboard.getKeyPressed("KeyD")) {
        this.targetAngle = Math.PI / 4
      }
    } else if(RE.Input.keyboard.getKeyPressed("KeyS")) {
      keysDown = true
      this.targetAngle = -Math.PI / 2
      if(RE.Input.keyboard.getKeyPressed("KeyA")) {
        this.targetAngle = -3 * Math.PI / 4
      } else if (RE.Input.keyboard.getKeyPressed("KeyD")) {
        this.targetAngle = -Math.PI / 4
      }
    } else if(RE.Input.keyboard.getKeyPressed("KeyA")) {
      keysDown = true
      this.targetAngle = Math.PI
    } else if(RE.Input.keyboard.getKeyPressed("KeyD")) {
      keysDown = true
      this.targetAngle = 0
    }
    
    this.bodyComponent.body.quaternion.setFromAxisAngle(new Vec3(0,1,0), this.angle)

    if(keysDown) {
      if(this.targetAngle != this.angle) {
        this.rotateTowardsTarget()
      }
      this.thrust()
    }
  }

  thrust() {
    this.isThrusting = true
    let modelOffset = Math.PI
    this.bodyComponent.body.force.x = this.speed * Math.sin(this.angle + modelOffset)
    this.bodyComponent.body.force.z = this.speed * Math.cos(this.angle + modelOffset)
  }

  shipInputControl() {
    let keyControlled = false
    if(RE.Input.keyboard.getKeyPressed("KeyA") || RE.Input.keyboard.getKeyPressed("ArrowLeft")) {
      this.angle += this.rotationSpeed
      this.targetAngle = this.angle
      keyControlled = true
    }

    if(RE.Input.keyboard.getKeyPressed("KeyD") || RE.Input.keyboard.getKeyPressed("ArrowRight")) {
      this.angle -= this.rotationSpeed
      this.targetAngle = this.angle
      keyControlled = true
    }

    if(!keyControlled && this.targetAngle != this.angle) {
      this.rotateTowardsTarget()
    }
    if(RE.Input.keyboard.getKeyPressed("KeyW") || RE.Input.keyboard.getKeyPressed("ArrowUp") || RE.Input.mouse.getButtonPressed(0) ) {
      this.thrust()
    }

    if(this.bodyComponent.body) {
      this.bodyComponent.body.quaternion.setFromAxisAngle(new Vec3(0,1,0), this.angle)
    }
  }

  rotateTowardsTarget() {
    let delta = this.targetAngle - this.angle
    if(Math.abs(delta) > Math.PI) {
      this.angle += Math.sign(delta) * (2 * Math.PI)
    }
    if(Math.abs(delta) < this.rotationSpeed ) {
      this.angle += delta;
    } else {
      this.angle += Math.sign(delta) * this.rotationSpeed
    }
  }

  update() {
    if(RE.Input.keyboard.getKeyDown("Tab") || RE.Input.keyboard.getKeyDown("Digit1")) {      
      let index = this.shipTypes.indexOf(this.activeShipType) + 1
      this.activeShipType = this.shipTypes[index % this.shipTypes.length]
      this.refreshShipDisplay()
    }


    this.isThrusting = false
    // this.worldInputControl() 
    this.shipInputControl()
    this.thrustFlames.visible = this.isThrusting

    if (this.isThrusting && this.thrustSound && this.thrustSound.context.state === "running") {
      this.thrustSound.setVolume(1)
    } else {
      this.thrustSound.setVolume(0)
    }
    // this.bodyComponent.body.quaternion.setFromAxisAngle(new Vec3(0,0,1), 0.5 * Math.sin(0.01 * new Date().getTime()))
    // this.bodyComponent.body.position.y = 0.4 * Math.sin(0.001 * new Date().getTime())
  }
}

RE.registerComponent(Player)

