import { Entity, EntityNames } from ".";
import {
  Colliding,
  ComponentNames,
  FacingDirection,
  Grid,
  RadialObserve,
} from "../components";
import { Game } from "../Game";
import { Coord2D, Direction } from "../interfaces";

export class Piston extends Entity {
  constructor(gridPosition: Coord2D, direction: Direction) {
    super(EntityNames.Piston);

    const radius = 1;
    this.addComponent(new RadialObserve(this.onObservation.bind(this), radius));

    this.addComponent(new FacingDirection(direction));

    this.addComponent(new Grid(gridPosition));

    this.addComponent(new Colliding());
  }

  private onObservation(_game: Game, entity: Entity) {
    const facingDirection = this.getComponent<FacingDirection>(
      ComponentNames.FacingDirection,
    );

    const myPosition = this.getComponent<Grid>(
      ComponentNames.Grid,
    ).gridPosition;
    const observingGrid = entity.getComponent<Grid>(ComponentNames.Grid);
    const observingPosition = observingGrid.gridPosition;

    const [dx, dy] = [
      myPosition.x - observingPosition.x,
      myPosition.y - observingPosition.y,
    ].map((x) => Math.round(x));
    const v: Record<typeof dx, Record<typeof dy, Direction>> = {
      [-1]: {
        [dy]: Direction.RIGHT,
      },
      [1]: {
        [dy]: Direction.LEFT,
      },
      [0]: {
        [-1]: Direction.UP,
        [1]: Direction.DOWN,
      },
    };

    if (facingDirection.currentDirection !== v[dx][dy]) {
      return;
    }

    observingGrid.movingDirection = facingDirection.currentDirection;
    entity.addComponent(observingGrid);
  }
}
