import * as THREE from 'three';

const EPSILON = 0.001;

class TaperedLink extends THREE.Group {

  constructor(baseMaterial, colour_i, n1, n2, r1, r2) {
    super();
    const geometry = new THREE.ConeGeometry( 1, 1, 16, true );
    const cplane = new THREE.Plane(new THREE.Vector3(0, -1, 0), 0.5);
    this.colour_i = colour_i;
    this.material = baseMaterial.clone();
    this.material.clippingPlanes = [ cplane ];
    this.object = new THREE.Mesh( geometry, this.material );
    this.add( this.object );
    this.update(n1, n2, r1, r2);
   }

   update(n1, n2, r1, r2) {
    const kraw = r1 - r2;
    let k = ( Math.abs(kraw) < EPSILON ) ? EPSILON : kraw;
    let nbase = n1.v3;
    let napex = n2.v3;
    let rbase = r1;
    let rapex = r2;
    if( k < 0 ) {
      nbase = n2.v3;
      napex = n1.v3;
      rbase = r2;
      rapex = r1;
      k = -k;
    }

    const l = nbase.distanceTo(napex);
    const lapex = l * rapex / k;
    const h = l + lapex;
    this.scale.copy(new THREE.Vector3(rbase, rbase, h));
    const h_offset = 0.5 * h / l;
    const pos = new THREE.Vector3();
    pos.lerpVectors(nbase, napex, h_offset);

    this.position.copy(pos); // the group, not the cone!! 

    this.lookAt(nbase);
    this.children[0].rotation.x = 3 * Math.PI / 2.0;
    this.visible = true;
    const clipnorm = new THREE.Vector3();
    clipnorm.copy(napex);
    clipnorm.sub(nbase);
    clipnorm.negate();
    clipnorm.normalize();
    this.material.clippingPlanes[0].setFromNormalAndCoplanarPoint(
      clipnorm, napex
    );


    }  

    set_colour(colours) {
        console.log(`taperedLink.set_colour {this.colour_i} {colours[this.colour_i]}`);
        this.material.color = new THREE.Color(colours[this.colour_i]);
    }

}


export { TaperedLink };
