package actor;

import render.*;

/**
 * Polly's eyes
 *
 * Basically a repacking of Ken's code to easily
 * fit into the ActorFramework.
 *
 * All you have to do is create them and call animate with the
 * current time (not elapsed)
 *
 * @author  Perlin, Wang
 */
public class Eyes extends Geometry{

  private static Material white = (new Material()).setAmbient(1,1,1);
  private static Material black = (new Material()).setAmbient(0,0,0).setDiffuse(0,0,0);
  
  private Geometry body;
  
  // given body of polly
  public Eyes(Geometry body) {
    
    this.body = body;
    
    body.add(this);
    
    add().ball(3).setMaterial(white);
    add().ball(3).setMaterial(white);
     
    add().ball(3).setMaterial(black);
    add().ball(3).setMaterial(black);
  }
  
   double eyes_apart  = .5;
   double eyes_height = .5;
   double eyes_dilate = .5;
   double eyes_tilt   = .5;
   double eyes_width  = .5;

   private double blinkStartTime = 0;
   
   private double ab[] = new double[3];
   private double v[] = new double[3];
   private double e[] = new double[3];

   
   public void animate(double time) {

      // BLINKING

      getMatrix().identity();
      if (time - blinkStartTime > .3 && time % 2 < 0.7 && time % 2.3 < 0.9)
	 blinkStartTime = time;
      if (time - blinkStartTime < .1)
	 getMatrix().scale(0,0,0);

      // CONVERT PARAMETERS TO ACTUAL VALUES

      double tilt    = -.78 + 1.56 * eyes_tilt;
      double apart   =  .10 +  .10 * eyes_apart;
      double height  =  .05 +  .15 * eyes_height;
      double width   =  .05 +  .15 * eyes_width;
      double dilate  =  .03 +  .09 * eyes_dilate;

      // LOCATE THE CENTER POINT BETWEEN THE EYES

      double a[] = body.vertices[7], b[] = body.vertices[8];
      double head_tilt = b[1] - a[1];
      for (int i = 0 ; i < 3 ; i++)
         ab[i] = L(.5, a[i], b[i]);

      a = body.vertices[6]; b = body.vertices[9];
      for (int i = 0 ; i < 3 ; i++)
         v[i] = L(.5, a[i], b[i]) - ab[i];
      double h = Vec.norm(v);

      Matrix m0 = child(0).getMatrix();
      Matrix m1 = child(1).getMatrix();
      Matrix m2 = child(2).getMatrix();
      Matrix m3 = child(3).getMatrix();

      // LEFT EYE

      e[0] = -apart;
      e[1] = .2 - .5 * h;
      e[2] = .03 - .15 * Math.max(0,b[2]-.5);
      Vec.rotate(e, 2, head_tilt);

      m0.identity();
      m0.translate(ab[0] + e[0], ab[1] + e[1], ab[2] + e[2]);
      m0.rotateX(-.5);
      m0.rotateZ(head_tilt + tilt);
      m2.copy(m0);
      m0.scale(width,height,.05);
      m2.translate(0,.02,-.05);
      m2.scale(dilate,dilate,.04);

      // RIGHT EYE

      e[0] = apart;
      e[1] = .2 - .5 * h;
      e[2] = .03 - .15 * Math.max(0,a[2]-.5);
      Vec.rotate(e, 2, head_tilt);

      m1.identity();
      m1.translate(ab[0] + e[0], ab[1] + e[1], ab[2] + e[2]);
      m1.rotateX(-.5);
      m1.rotateZ(head_tilt - tilt);
      m3.copy(m1);
      m1.scale(width,height,.05);
      m3.translate(0,.02,-.05);
      m3.scale(dilate,dilate,.04);
   }

   private double L(double t,double a,double b) { return a + t * (b - a); }


   
  
}