<template>
  <div class="game">
    <canvas
      class="game-canvas"
      ref="canvas">
    </canvas>
  </div>
</template>

<script>
import { send } from '@/store/socketPlugin'
export default {
  name: 'Game',
  data () {
    return {
      mouse: {
        x: 0,
        y: 0
      },
      renderTimer: null
    }
  },
  computed: {
    canvas () {
      return this.$refs.canvas
    },
    context () {
      return this.canvas.getContext('2d')
    },
    settings () {
      return this.$store.state.game.settings
    },
    player () {
      return this.$store.state.game.player
    },
    players () {
      return this.$store.state.game.players
    },
    isPaused () {
      return this.$store.state.game.paused
    }
  },
  mounted () {
    this.canvas.width = window.innerWidth
    this.canvas.height = window.innerHeight
    this.canvas.addEventListener('mousemove', this.mouseEvent)
    this.canvas.addEventListener('touchmove', this.touchEvent)
    this.renderTimer = setInterval(this.render, 1000 / 60)
  },
  methods: {
    render () {
      this.context.clearRect(0, 0, this.canvas.width, this.canvas.height)
      this.renderBorders()

      this.players.forEach(player => {
        this.renderPlayer(player)
        this.renderWalls(player)
      })

      this.renderDebug(this.player)

      // this.checkPlayerColision()
      this.updatePlayer(this.player)
    },
    renderBorders () {
      this.context.strokeStyle = 'black'
      this.context.lineWidth = 1
      this.context.strokeRect(this.canvas.width / 2 - this.player.x, this.canvas.height / 2 - this.player.y, this.settings.arenaSize, this.settings.arenaSize)
    },
    renderPlayer (player) {
      this.context.save()

      const canvasX = this.canvas.width / 2 + player.x - this.player.x
      const canvasY = this.canvas.height / 2 + player.y - this.player.y

      this.context.translate(canvasX, canvasY)
      this.context.rotate(player.angle)
      this.context.fillStyle = player.color
      this.context.fillRect(-this.settings.playerSize, -this.settings.playerSize, this.settings.playerSize * 2, this.settings.playerSize * 2)
      this.context.translate(0, 0)

      this.context.restore()
    },
    renderWalls (player) {
      this.context.beginPath()
      this.context.lineWidth = this.settings.wallSize
      this.context.strokeStyle = player.color
      player.walls.forEach(wall => {
        const canvasX = this.canvas.width / 2 + wall.x - this.player.x
        const canvasY = this.canvas.height / 2 + wall.y - this.player.y
        this.context.lineTo(canvasX, canvasY)
      })
      this.context.lineTo(this.canvas.width / 2 + player.x - this.player.x, this.canvas.height / 2 + player.y - this.player.y)
      this.context.stroke()
    },
    renderDebug (player) {
      const canvasX = this.canvas.width / 2
      const canvasY = this.canvas.height / 2
      /*
      this.context.beginPath()
      this.context.lineTo(canvasX, canvasY)
      this.context.lineTo(this.mouse.x, this.mouse.y)
      this.context.lineWidth = 1
      this.context.strokeStyle = 'blue'
      this.context.stroke()

      const x = canvasX + 30 * Math.cos(player.angle) * 2
      const y = canvasY + 30 * Math.sin(player.angle) * 2
      this.context.beginPath()
      this.context.lineTo(canvasX, canvasY)
      this.context.lineTo(x, y)
      this.context.lineWidth = 1
      this.context.strokeStyle = 'yellow'
      this.context.stroke()

      const canvasX2 = this.canvas.width / 2
      const canvasY2 = this.canvas.height / 2
      this.context.beginPath()
      this.context.arc(canvasX2, canvasY2, this.settings.playerSize, 0, 2 * Math.PI, false)
      this.context.lineWidth = 1
      this.context.strokeStyle = 'purple'
      this.context.stroke()
      */

      this.context.fillText('player x: ' + player.x + ' y:' + player.y, 10, 10)
      this.context.fillText('a:' + player.angle + ' a_t' + player.targetAngle, 10, 20)
      this.context.fillText('canvasX: ' + canvasX + ' canvasY:' + canvasY, 10, 30)
      this.context.fillText('walls: ' + player.walls.length, 10, 40)

      this.context.beginPath()
      this.context.arc(this.mouse.x, this.mouse.y, 25, 0, 2 * Math.PI, false)
      this.context.lineWidth = 1
      this.context.strokeStyle = player.color
      this.context.stroke()
    },
    mouseEvent (event) {
      var rect = this.canvas.getBoundingClientRect()
      this.mouse.x = event.clientX - rect.left
      this.mouse.y = event.clientY - rect.top

      this.sendAngleUpdate()
    },
    touchEvent (event) {
      var rect = this.canvas.getBoundingClientRect()
      this.mouse.x = event.touch[0].clientX - rect.left
      this.mouse.y = event.touch[0].clientY - rect.top

      this.sendAngleUpdate()
    },
    sendAngleUpdate () {
      var dx = this.mouse.x - this.canvas.width / 2
      var dy = this.mouse.y - this.canvas.height / 2

      this.player.targetAngle = Math.atan2(dy, dx)
      send({ message: this.player, type: 'update' })
    },
    updatePlayer (player) {
      /*
      this.player.lastWall++
      if (this.player.lastWall > this.settings.wallUpdate) {
        this.player.walls.push({ x: this.player.x, y: this.player.y })
        this.player.lastWall = 0
      }
      */

      player.x += this.settings.playerSpeed * Math.cos(player.angle)
      player.y += this.settings.playerSpeed * Math.sin(player.angle)

      player.angle = player.targetAngle
      // angle lag
      /*
      if (this.player.targetAngle !== this.player.angle) {
        const delta = this.player.targetAngle - this.player.angle
        if (delta < 0) this.player.angle += delta / this.settings.playerTurnSpeed
        if (delta > 0) this.player.angle += delta / this.settings.playerTurnSpeed
        if (delta <= 0.1 && delta >= -0.1) this.player.angle = this.player.targetAngle
      }
      */
    },
    checkPlayerColision () {
      const playerX = this.player.x
      const playerY = this.player.y
      // BORDERS
      if (playerX - this.settings.playerSize < 0 ||
          playerX + this.settings.playerSize > this.settings.arenaSize ||
          playerY - this.settings.playerSize < 0 ||
          playerY + this.settings.playerSize > this.settings.arenaSize
      ) {
        this.context.fillText('DED BORDER', this.canvas.width / 2, this.canvas.height / 2)
      }

      // WALLS
      for (var i = 0; i < this.player.walls.length - 2; i++) {
        const wallA = this.player.walls[i]
        const wallB = this.player.walls[i + 1]
        if (this.isCloseToWall(wallA.x, wallA.y, wallB.x, wallB.y, playerX, playerY, this.settings.playerSize)) {
          if (this.isCrossingLine(wallA.x, wallA.y, wallB.x, wallB.y, playerX, playerY, this.settings.playerSize)) {
            this.context.fillText('DED WALL OWN', this.canvas.width / 2, this.canvas.height / 2)
            this.context.beginPath()
            const canvasX = this.canvas.width / 2 + wallA.x - this.player.x
            const canvasY = this.canvas.height / 2 + wallA.y - this.player.y
            this.context.lineTo(canvasX, canvasY)
            const canvasX2 = this.canvas.width / 2 + wallB.x - this.player.x
            const canvasY2 = this.canvas.height / 2 + wallB.y - this.player.y
            this.context.lineTo(canvasX2, canvasY2)
            this.context.lineWidth = this.settings.wallSize
            this.context.strokeStyle = 'purple'
            this.context.stroke()
          }
        }
      }
    },
    isCloseToWall (xa, ya, xb, yb, xc, yc, radius) {
      var xar = Math.min(xa, xb) - radius
      var yar = Math.min(ya, yb) - radius
      var xbr = Math.max(xa, xb) + radius
      var ybr = Math.max(ya, yb) + radius

      return ((xc >= xar && xc <= xbr) && (yc >= yar && yc <= ybr))
    },
    isCrossingLine (xa, ya, xb, yb, xc, yc, radius) {
      var a = xc - xa
      var b = xb - xa
      var c = yc - ya
      var d = yb - ya
      var result = (a * d - b * c) / Math.sqrt(Math.pow(xa - xb, 2) + Math.pow(ya - yb, 2))

      return result < radius
    }
  }
}
</script>
