import java.awt.*;
import java.awt.geom.*;
//import java.awt.geom.PathIterator;
class QuCu 
 {
  boolean rw=false;
  QuadCurve2D c;
  PathIterator iterator;
  static M parent;
  Te te;
  static LC lc;
  static final double PI=Math.PI;
  static final double DR=PI/180;
  static final double RD=180/PI;
  int mi=-1;
  double x=0,y=0;
  int xi=0,yi=0;
  Point p;
  Point2D p2d;
  dP dp;
  dP[] dpa=new dP[0];
  Rec[] reca=new Rec[0];
  int msdp=-1;
  dP odp;
  Graphics2D g;
  boolean closed=false;
  boolean handles=true;
  boolean cs=true;
  String name;
  double snap=10;
  public QuCu() { }
  public QuCu(LC a) 
   {
    lc=a;
    g=lc.offsg;
   }
  public QuCu(String name,boolean closed,boolean handles,dP[] dpa)
   {
    g=lc.offsg;
    this.name=name;
    this.closed=closed;
    this.handles=handles;
    this.dpa=dpa;
    reca=new Rec[dpa.length];
    for(int i=0;i<dpa.length;i++) reca[i]=new Rec(dpa[i].sub(4,4),8,8);
   }
  void setclosed(boolean b)
   {
    closed=b;
    render();
   }
  void sethandles(boolean b)
   {
    handles=b;
    render();
   }
  void setdpa(dP[] a)
   {
    dpa=a;
    for(int i=0;i<dpa.length;i++) reca[i]=new Rec(dpa[i].sub(4,4),8,8);
    render();
   }
  void closeseg() 
   {
    closed=true; 
    render();
   }
  void addseg(dP a,dP b)
   {
    dP[] dpb=new dP[dpa.length];
    for(int i=0;i<dpa.length;i++) dpb[i]=dpa[i];
    dpa=new dP[2+dpa.length];
    reca=new Rec[dpa.length];
    int i=0;
    for(i=0;i<dpb.length;i++) dpa[i]=dpb[i];
    dpa[i++]=a;
    dpa[i++]=b;
    for(i=0;i<dpa.length;i++) reca[i]=new Rec(dpa[i].sub(4,4),8,8);
    render();
   }
  void snap(double d)
   {
    snap=d;
    if(snap==0) return;
    for(int i=0;i<dpa.length;i++) dpa[i]=dP.snap(dpa[i],snap);
    render();
   }
  void render()
   {
    if(dpa.length<=2) return;
    double opw=lc.pw;
    int i=0;
    //QuadCurve2D c = new QuadCurve2D.Double();
    c = new QuadCurve2D.Double();
    while(i+2<dpa.length)
     {
      c.setCurve(dpa[i].x,dpa[i].y,dpa[i+1].x,dpa[i+1].y,dpa[i+2].x,dpa[i+2].y);
      lc.offsgdraw(c);
      lc.spw(1);
      if(handles)
       {
        lc.offsgdraw(new Line2D.Double(dpa[i],dpa[i+1]));
        lc.offsgdraw(new Line2D.Double(dpa[i+1],dpa[i+2]));
       }
      i+=2;
      lc.spw(opw); 
     }
    if(closed)
     {
      i-=2;
      //c.setCurve(dpa[i+2].x,dpa[i+2].y,dpa[i+3].x,dpa[i+3].y,dpa[0].x,dpa[0].y);
      //lc.offsgdraw(c);
     }
    renderb();
   }
  void renderb()
   {
    if(handles)
     {
      for(int i=0;i<dpa.length;i++)
       {
        if(i==msdp) lc.offsgsetColor(Color.green);
        lc.offsgfill(reca[i].rect);
        if(i==msdp) lc.offsgsetColor(Color.black);
       }
     }
    lc.repaint();
   }
  boolean mmdp(dP dp)
   {
    for(int i=0;i<dpa.length;i++)
     {
      if(reca[i].contains(dp))
       {
        mi=i;
        lc.offsgsetColor(Color.blue);
        lc.offsgfill(reca[i].rect);
        lc.offsgsetColor(Color.black);
        lc.repaint();
        return true;
       }
      if(mi==i)
       {
        mi=-1;
        lc.offsgfill(reca[i].rect);
        lc.repaint();
       }
     }
    return false;
   }
  boolean mpdp(dP dp)
   {
    for(int i=0;i<dpa.length;i++) 
     {
      if(reca[i].contains(dp))
       {
        msdp=i;
        odp=new dP(dpa[msdp]);
        renderb();
        return true;
       }
     }
    return false;
   }
  void mddp(dP dp)
   {
    dpa[msdp]=dp;
    int j=msdp%3;
    if(j==100) dpa[msdp+2]=dpa[msdp+1].sym(dpa[msdp]);
    else if(j==101)
     {
      dpa[msdp+1]=dpa[msdp].sub(odp.sub(dpa[msdp+1]));
      dpa[msdp-1]=dpa[msdp].sub(odp.sub(dpa[msdp-1]));
     }
    else if(j==102) dpa[msdp-2]=dpa[msdp-1].sym(dpa[msdp]);
    for(int i=msdp-j;i<msdp-j+3;i++) reca[i]=new Rec(dpa[i].sub(4,4),8,8);
    odp=dp;
    if(cs)  lc.clearscreen();
    render();
   }
  void mrdp(dP dp)
   {
    msdp=-1;
    renderb();
   }
  void ed()
   {
    //tta1(name+".k "+Te.Svo(k));
    //tta1(name+".pw "+Te.Svo(pw));
    tta1(name+".closed "+Te.Svo(closed));
    tta1(name+".handles "+Te.Svo(handles));
    tta1(name+".dpa "+Te.Svo(dpa));
   }
  static void tta1(String s) { parent.tta1(s); }
  static void tta(String s) { parent.tta(s); }
  public void rewind() 
   {
    c = new QuadCurve2D.Double();
    int i=0;
    c.setCurve(dpa[i].x,dpa[i].y,dpa[i+1].x,dpa[i+1].y,dpa[i+2].x,dpa[i+2].y);
    iterator = c.getPathIterator(null, 0.001);
    rw=true;
   }
  public dP next() 
   {
    if(! rw) rewind();
    double[] da = new double[6];
    iterator.currentSegment(da);
    int i=0;
    if ((Math.round(da[0]) == dpa[i+2].x) && (Math.round(da[1]) == dpa[i+2].y)) 
     {
      rw=false;
      tta("at end");
      return null;
     }
    iterator.next();
    iterator.currentSegment(da);
    return new dP(da[0],da[1]);
   }
  public dP dPAt(int index) 
   {
    rewind();
    for (int j=0;j<index; j++) iterator.next();
    double[] da = new double[6];
    iterator.currentSegment(da);
    return new dP(da[0],da[1]);
   }
 }
