import { Wall } from './Wall';
import { GameSettings } from './GameSettings';

export class Player {

  private gameSettings = new GameSettings();
  public bestScore = 0;
  public angle = 0;
  public score = 0;
  public color = '#' + (0x1000000 + (Math.random()) * 0xffffff).toString(16).substr(1, 6);
  public x = this.gameSettings.arenaSize * (0.25 + Math.random() * 0.5);
  public y = this.gameSettings.arenaSize * (0.25 + Math.random() * 0.5);
  public walls: Wall[] = [];
  public lastWall = 0;
  public state = 'ALIVE';

  constructor (public id: string, public name: string) {
    this.reset();
  }

  reset () {
    this.score = 0;
    this.color = '#' + (0x1000000 + (Math.random()) * 0xffffff).toString(16).substr(1, 6);
    this.x = this.gameSettings.arenaSize * (0.25 + Math.random() * 0.5);
    this.y = this.gameSettings.arenaSize * (0.25 + Math.random() * 0.5);
    this.walls = [];
    this.lastWall = 0;
    this.state = 'ALIVE';
  }

  kill () {
    this.state = 'DEAD';
    if (this.bestScore < this.score) this.bestScore = this.score;
  }

  isOutOfBorders () {
    return this.x - this.gameSettings.playerSize < 0 ||
    this.x + this.gameSettings.playerSize > this.gameSettings.arenaSize ||
    this.y - this.gameSettings.playerSize < 0 ||
    this.y + this.gameSettings.playerSize > this.gameSettings.arenaSize
  }

  isCloseToWall (wallA: Wall, wallB: Wall) {
    const xar = Math.min(wallA.x, wallB.x) - this.gameSettings.playerSize
    const yar = Math.min(wallA.y, wallB.y) - this.gameSettings.playerSize
    const xbr = Math.min(wallA.x, wallB.x) + this.gameSettings.playerSize
    const ybr = Math.min(wallA.y, wallB.y) + this.gameSettings.playerSize

    return ((this.x >= xar && this.x <= xbr) && (this.y >= yar && this.y <= ybr))
  }

  isCrossingLine (wallA: Wall, wallB: Wall) {
    const xa = wallA.x
    const ya = wallA.y
    const xb = wallB.x
    const yb = wallB.y
    const xc = this.x
    const yc = this.y
    const radius = this.gameSettings.playerSize

    return Math.abs((yb - ya) * xc - (xb - xa) * yc + xb * ya - yb * xa) / Math.sqrt(Math.pow(xb - xa, 2) + Math.pow(yb - ya, 2)) < radius
  }

  step (tickToSimulate: number) {
    if (this.state === 'DEAD') return

    for (let i = 0; i < tickToSimulate; i++) {
      this.lastWall++

      if (this.lastWall > this.gameSettings.wallUpdate) {
        this.walls.push(new Wall(this.x, this.y))
        this.score++
        this.lastWall = 0
      }

      this.x = this.x + this.gameSettings.playerSpeed * Math.cos(this.angle)
      this.y = this.y + this.gameSettings.playerSpeed * Math.sin(this.angle)
    }
  }
}
