import { MolangVariableMap, Vector3, world } from "@minecraft/server";
import { Vector3Add } from "../utils/vectorUtils";
import { TrailType } from "./trailTypes";
import { PARTICLES, spawnParticle } from "../utils/particleUtils";

class TrailPoint {
  postion: Vector3;
  index: number;

  constructor(position: Vector3, index: number) {
    this.postion = position;
    this.index = index;
  }

  spawn() {
    // let spawnPosition: Vector3 = Vector3Add(this.postion, { x: 0.5, y: 0.5, z: 0.5 });
    let spawnPosition: Vector3 = this.postion;
    try {
      spawnParticle(spawnPosition, PARTICLES.balloon_gas_particle, new MolangVariableMap());
    } catch (e) {}
  }
}

class Trail {
  id: string;
  points: TrailPoint[] = [];
  currentPoint: number = 0;
  wrapIndex: number = 0;
  nextParticleTimer: number = 0;
  currentParticleCounter: number = 0;

  calculatedLength: number = 0;
  constructor(id: string, nextParticleTimer: number = 5, wrapIndex: number = 0) {
    this.id = id;
    this.nextParticleTimer = nextParticleTimer;
    this.wrapIndex = wrapIndex;
  }

  addPoint(point: TrailPoint) {
    this.points.push(point);

    this.calculatedLength = this.points.length;
  }

  fromTrail(trail: TrailType) {
    let currentIndex = 0;
    trail.points.forEach((point) => {
      this.addPoint(new TrailPoint(point.position, currentIndex));
      currentIndex++;
    });
  }

  spawnNext() {
    if (this.currentParticleCounter >= this.nextParticleTimer) {
      this.currentParticleCounter = 0;
      //wrapindex is in how many segments the trail is divided into
      let pointsPerInterval = this.wrapIndex > 0 ? this.calculatedLength / this.wrapIndex : 0;
      this.points
        .filter((point) => {
          if (this.wrapIndex > 0) {
            return point.index % this.wrapIndex == this.currentPoint;
          } else {
            return point.index == this.currentPoint;
          }
        })
        .forEach((point) => {
          point.spawn();
        });

      this.currentPoint++;
      let actualLength = this.wrapIndex > 0 ? this.wrapIndex : this.calculatedLength;
      if (this.currentPoint >= actualLength) {
        this.currentPoint = 0;
      }
    } else {
      this.currentParticleCounter++;
    }
  }
}

export { Trail, TrailPoint };
