import { Matrix4, Plane, Raycaster, Vector2, Vector3 } from "three";

export default class DragControls {
  constructor(_objects, _camera) {
    this._objects = _objects;
    this._camera = _camera;
    this._plane = new Plane();
    this._raycaster = new Raycaster();

    _mouse = new Vector2();
    this._offset = new Vector3();
    this._intersection = new Vector3();
    this._worldPosition = new Vector3();
    this._inverseMatrix = new Matrix4();
    this._intersections = [];

    this._selected = null;
  }

  getWrapper(selected) {
    for(let object of this._objects) {
      for(let child of object.children) {
        if(selected == child) {
          //console.log("found");
          return object;
        }
      }
    }
    return null;
  }

  addObject(object) {
    this._objects.push(object);
  } 

  /*updateChildPosition() {
    const group = this._selected ? this._selected : this.object;
    const groupVec = group.position;
    for(let child of group.children) {
      const childVec = child.position;
      const newPos = {
        x: childVec.x + groupVec.x,
        y: childVec.y + groupVec.y,
        z: childVec.z + groupVec.z
      };
      //console.log(child.position)
    }
  }*/

  onDocumentMouseMove(_mouse) {
	try {
	this._raycaster.setFromCamera(_mouse, this._camera);
    if (this._selected) {
      if (this._raycaster.ray.intersectPlane(this._plane, this._intersection)) {
        this._selected.position.copy(
          this._intersection.sub(this._offset).applyMatrix4(this._inverseMatrix)
        );
        this._selected.updateMatrixWorld();
      }
      return;
    }

    this._intersections.length = 0;

    this._raycaster.setFromCamera(_mouse, this._camera);
    this._raycaster.intersectObjects(this._objects, true, this._intersections);

    if (this._intersections.length > 0) {
      this.object = this.getWrapper(this._intersections[0].object);
      this.object = this.object ? this.object : this._intersection[0].object;
      this._plane.setFromNormalAndCoplanarPoint(
        this._camera.getWorldDirection(this._plane.normal),
        this._worldPosition.setFromMatrixPosition(this.object.matrixWorld)
      );
      this.object.updateMatrixWorld();
	}
} catch(e) {}
  }

  onDocumentMouseCancel() {
    if (this._selected) {
      this._selected = null;
    }
  }

  onDocumentTouchStart(_mouse) {
    try {
      this._intersections.length = 0;

      this._raycaster.setFromCamera(_mouse, this._camera);
      this._raycaster.intersectObjects(
        this._objects,
        true,
        this._intersections
      );

      if (this._intersections.length > 0) {
        //this._selected = this._objects[0]//this._intersections[0].object;
        this._selected = this.getWrapper(this._intersections[0].object);
      this._selected = this.object ? this._selected : this._intersection[0].object;
        this._plane.setFromNormalAndCoplanarPoint(
          this._camera.getWorldDirection(this._plane.normal),
          this._worldPosition.setFromMatrixPosition(this._selected.matrixWorld)
        );

        if (
          this._raycaster.ray.intersectPlane(this._plane, this._intersection)
        ) {
          this._inverseMatrix.getInverse(this._selected.parent.matrixWorld);
          this._offset
            .copy(this._intersection)
            .sub(
              this._worldPosition.setFromMatrixPosition(
                this._selected.matrixWorld
              )
            );
        }
        this._selected.updateMatrixWorld();
      }
    } catch (e) {}
  }
}