import java.awt.*;
import java.awt.geom.*;
import java.util.*;
class Sc
 {
  static M parent;
  static Te te=M.te0;
  static final double PI=Math.PI;
  static final double PIPI=2*Math.PI;
  static final double DR=PI/180;
  static final double RD=180/PI;
  String name="none";
  boolean autorender=true;
  double nV =400.0;
  double nP =-160.0;
  double tlUD=0;
  double tlLR=0;
  double rUD=0;
  double rLR=0;
  XYZ kLight = new XYZ(200.0,200.0,200.0);
  private Vector v;
  TSQuickSort tsqs = new TSQuickSort();
  LC lc;
  public Sc(M p,String n,LC l) 
   {
    parent=p;
    name=n;
    lc=l;
    v = new Vector();
   }
  public void add(Object o) { v.addElement(o); }
  public void remove(Object o) { v.removeElement(o); }
  public Enumeration elements() { return v.elements(); }
  public void transl(Translation tr)
   {
    Enumeration enu = v.elements();
    while (enu.hasMoreElements())
     {
      Object obj = enu.nextElement();
      if (obj instanceof Sc)
       {
        Sc chair=(Sc)obj;
        //tta("transl found Sc:"+chair.name);
        Enumeration en=chair.v.elements();
        while (en.hasMoreElements())
         {
          Object ob = en.nextElement();
          if (ob instanceof PP) ((PP)ob).transl(tr);
          else if (ob instanceof XYZ) tr.transl((XYZ)ob);
         }
       }
      else if (obj instanceof PP) ((PP)obj).transl(tr);
      else if (obj instanceof XYZ) tr.transl((XYZ)obj);
     }
   }
  public void rot(double a,double b,double c,double r)
   {
    Rotation tr=new Rotation(0,0,0,a,b,c,r*DR);
    Enumeration enu = v.elements();
    while (enu.hasMoreElements())
     {
      Object obj = enu.nextElement();
      if (obj instanceof Sc)
       {
        Sc chair=(Sc)obj;
        //tta("rot found Sc:"+chair.name);
        Enumeration en=chair.v.elements();
        while (en.hasMoreElements())
         {
          Object ob = en.nextElement();
          //if (ob instanceof PP) ((PP)ob).rot(tr);
          if (ob instanceof PP) XYZ.rotate(((PP)ob).a,a,b,c,r);
          else if (ob instanceof XYZ) tr.rot((XYZ)ob);
         }
       }
      if (obj instanceof PP) XYZ.rotate(((PP)obj).a,a,b,c,r);
      else if (obj instanceof XYZ) tr.rot((XYZ)obj);
     }
   }
  public void rot(Rotation tr)
   {
    Enumeration enu = v.elements();
    while (enu.hasMoreElements())
     {
      Object obj = enu.nextElement();
      if (obj instanceof Sc)
       {
        Sc chair=(Sc)obj;
        //tta("rot found Sc:"+chair.name);
        Enumeration en=chair.v.elements();
        while (en.hasMoreElements())
         {
          Object ob = en.nextElement();
          if (ob instanceof PP) ((PP)ob).rotate(tr);
          else if (ob instanceof XYZ) tr.rot((XYZ)ob);
         }
       }
      if (obj instanceof PP) ((PP)obj).rotate(tr);
      else if (obj instanceof XYZ) tr.rot((XYZ)obj);
     }
   }
  public void ar()
   {
    if(autorender) render();
   }
  public void render()
   {
    Vector vec = new Vector();
    Object o = null;
    Enumeration enu = elements();
    while (enu.hasMoreElements())
     {
      o = enu.nextElement();
      if (o instanceof PP) vec.addElement(o);
      else if(o instanceof Sc)
       {
        Sc chair=(Sc)o;
        Object ob=null;
        Enumeration e=chair.elements();
        while (e.hasMoreElements())
         {
          ob=e.nextElement();
          if(ob instanceof PP) vec.addElement(ob);
         }
       }
     }
    //Object [] rgo = new Object [ vec.size() ];
    //vec.copyInto(rgo);
    //tsqs.sort(rgo);
    PP[] rgo = new PP[ vec.size() ];
    //vec.copyInto(rgo);
    for (int i=0;i<vec.size(); i++)  rgo[i]=(PP)vec.elementAt(i); 
    tsqs.sort(rgo);
    for (int i = 0; i < rgo.length; i++)
     {
      o = rgo[i];
      if(o instanceof PP) renderPP((PP)o);
     }
    lc.myRepaint();
   }
  protected XYZ addPerspective(XYZ k)
   {
    if (k == null) return null;
    double a=nV/(nV+nP-k.z), b=nV/(nV+nP-k.z);
    tta("a:"+a+"  b:"+b);
    return new XYZ(k.x*(nV/(nV+nP-k.z)),k.y*(nV/(nV+nP-k.z)),k.z);
    //return new XYZ(k.x*Math.abs(nV/(nV+nP-k.z)),k.y*Math.abs(nV/(nV+nP-k.z)),k.z);
   }
  protected boolean isVisible(XYZ k) { return k.z < nV+nP; }
  public void rotateLeft(double f) 
   {
    //rot(new Rotation(0,0,0,0,1,0,f*DR)); 
    rot(0,1,0,f*DR); 
    ar();
   }
  public void rotateRight(double f) 
   {
    rot(new Rotation(0,0,0,0,1,0,-f*DR));
    ar();
   }
  public void rotateUp(double f) 
   {
    rUD-=f;
    rot(new Rotation(0,0,0,1,0,0,-f*DR));
    ar();
   }
  public void rotateDown(double f) 
   {
    rUD+=f;
    rot(new Rotation(0,0,0,1,0,0,f*DR)); 
    ar();
   }
  public void rotateUD(double d) 
   {
    rotateUp(rUD -d*DR);
    ar();
   }
  public void translateLeft(double f) 
   {
    tlLR-=f;
    transl(new Translation(-f,0,0)); 
    ar();
   }
  public void translateRight(double f) 
   {
    tlLR+=f;
    transl(new Translation(f,0,0));
    ar();
   }
  public void translateLR(double d) { translateLeft(tlLR -d); }
  public void translateUp(double f) 
   {
    tlUD-=f;
    transl(new Translation(0,-f,0)); 
    ar();
   }
  public void translateDown(double f) 
   {
    tlUD+=f;
    transl(new Translation(0,f,0));
    ar();
   }
  public void translateUD(double d) 
   {
    translateUp(tlUD -d);
    ar();
   }
  public double gettlUD() { return tlUD; }
  public void adjustView(double f) 
   {
    nV+=f;
    ar();
   }
  public void setView(double f) 
   {
    nV=f; 
    ar();
   }
  public double getView() { return nV; }
  public void adjustPort(double f)
   {
    nP+=f;
    ar();
   }
  public void setPort(double f) 
   {
    nP=f; 
    ar();
   }
  public double getPort() { return nP; }
  void renderPP(PP pp)
   {
    int l=pp.a.length;
    if(! pp.addPrespective(nV,nP)) return;
    pp.calc();
    XYZ n0=pp.centroid;
    if(l>2)
     {
      XYZ n1=pp.normal;
      XYZ n2=Algorithms.getLine(n0, kLight);
      float dot1=(float)Algorithms.dot(n1,n2);
      float dot=(float)(dot1/2.0+0.5);
      lc.spk(new K(dot,dot,dot));
      lc.offsg.fillPolygon(pp.xi,pp.yi,l);
      lc.offsg.setColor(new Color(0,0,0));
      lc.spw(1);
      lc.offsg.drawPolygon(pp.xi,pp.yi,l);
     }
    else
     {
      lc.offsg.draw(new Line2D.Double(pp.xi[0],pp.yi[0],pp.xi[1],pp.yi[1]));
     }
   }
  void oldrenderPP(PP pp)
   {
    int l=pp.a.length;
    XYZ[] c=new XYZ[l];
    int [] rgx=new int [l];
    int [] rgy=new int [l];
    int [] rgz=new int [l];
    int j=0;
    for(j=0;j<l;j++) 
     {
      c[j]=addPerspective(pp.a[j]);
      rgx[j]=(int)c[j].x;
      rgy[j]=(int)c[j].y;
      rgz[j]=(int)c[j].z;
      tta("z:"+c[j].z);
     }
    pp.calc();
    XYZ n0=pp.centroid;
    if(l>2)
     {
      XYZ n1=pp.normal;
      XYZ n2=Algorithms.getLine(n0, kLight);
      float dot1=(float)Algorithms.dot(n1,n2);
      float dot=(float)(dot1/2.0+0.5);
      //Color clr=new Color(dot, dot, dot);
      lc.spk(new K(dot,dot,dot));
      lc.offsg.fillPolygon(rgx,rgy,l);
      lc.offsg.setColor(new Color(0,0,0));
      lc.spw(1);
      lc.offsg.drawPolygon(rgx,rgy,l);
     }
    else
     {
      lc.offsg.draw(new Line2D.Double(rgx[0],rgy[0],rgx[1],rgy[1]));
     }
   }
  void ed()
   {
    // tta1(name+".d "+te.Svo(d));
   }
  static void tta1(String s) { parent.tta1(s); }
  static void tta(String s) { parent.tta(s); }
  static String Svo(Sc sce)
   {
    String ret="";
    Enumeration enu = sce.v.elements();
    while (enu.hasMoreElements())
     {
      Object obj = enu.nextElement();
      if (obj instanceof PP)
       {
        PP pp=(PP)obj;
        if(ret.equals("")) ret=Te.Svo(pp);
        else ret=ret+","+Te.Svo(pp);
       }
     }
    //return "sce.name:"+sce.name+" wacka wacka";
    return ret;
   }
 }
