import { PointModel } from "../../point-component/models/point-model";
import { ELEMENTS_CLASS } from "../../../core/enums/elements-class-enum";
import { DrawerAggregator } from "../../../core/drawers/drawer-aggregator";
import { GeometricObject } from "../../../core/models/objects/geometric-object";

export class IntersectionModel extends PointModel {
  /**
   * 
   * @param {GeometricObject} r Geometric Object 
   * @param {GeometricObject} s Geometric Object
   * @param {boolean} visible Visiblity of Object 
   * @param {number} index Index position of Object ex (1)

   */
  constructor(posX, posY, label, r, s, visible, index, id) {
    super(posX, posY, label, id);
    this.r = r;
    this.s = s;
    super.setClass(ELEMENTS_CLASS.INTERSECTION_POINT);
    this.visible = visible;
    this.index = index;
    this.color = -65536;
    this.definitions = this.getDefinitions();
  }

  /**
   * Update properties of this Intersection
   * @param {DrawerAggregator} aggregator Drawer Aggregator 
   * @param {event} event 
  */
  update(aggregator, event) {
    const intersections = this.r.getIntersection(this.s);
    if (intersections.length == 1) {
      this.visible = true;
      const intersection = intersections[0];
      this.posX = parseFloat(intersection.posX.toFixed(2));
      this.posY = parseFloat(intersection.posY.toFixed(2));
      // this.visible = intersection.visible;
      if (!this.r.insideSegment(this.posX, this.posY)) {
        this.posX = Number.MAX_SAFE_INTEGER;
        this.posY = Number.MAX_SAFE_INTEGER;
        this.visible = false;
        this.definitions = this.getDefinitions();
        return;
      }
      if (!this.s.insideSegment(this.posX, this.posY)) {
        this.posX = Number.MAX_SAFE_INTEGER;
        this.posY = Number.MAX_SAFE_INTEGER;
        this.visible = false;
        this.definitions = this.getDefinitions();
        return;
      }
      return;
    }
    if (intersections.length > 1) {
      for (let index = 0; index < intersections.length; index++) {
        const intersection = intersections[index];
        if (this.index == index) {
          this.posX = parseFloat(intersection.posX.toFixed(2));
          this.posY = parseFloat(intersection.posY.toFixed(2));
          this.visible = intersection.visible;
        }
      }
    }
    this.definitions = this.getDefinitions();
  }

  getDefinitions() {
    return [{ id: this.r.id }, { id: this.s.id }, { id: this.index + 1 }, { id: this.posX + 5 }, { id: this.posY - 5 }, { id: this.visible ? 1 : 0 }];
  }

  /**
   * Create new Intersection By Line of Script .geo
   * @param {Map} map JavaScript Map
   * @param {[]} list List of Generic Objects
   */
  static do(map, list) {
    const id = map.get("id");
    const rId = map.get("param")[0];
    const sId = map.get("param")[1];
    const index = map.get("param")[2] - 1;
    const x = (map.get("param")[3]) - 5;
    const y = (map.get("param")[4]) + 5;
    const visible = map.get("param")[5] == 1;
    const label = map.get("label");
    const r = list.find(x => x.id == rId);
    const s = list.find(x => x.id == sId);
    return new IntersectionModel(x, y, label, r, s, visible, index, id);
  }
}