/*

 */
import java.applet.Applet;
import java.awt.*;
import java.util.StringTokenizer;

class Pentacircle
{
  double Cr=1.0;
  double Cx[]=new double[7];
  double Cy[]=new double[7];
  double Direc[]=new double[6];
  double PCx,PCy;

  public Pentacircle(){
    Cx[0]=-Cr;Cy[0]=0.0;
    Cx[5]=-Cr;Cy[5]=0.0;
    Cx[1]= Cr;Cy[1]=0.0;
    Cx[3]=0.1*Cr;Cy[3]=4*Cr;

    Cx[6]=0.0;//noral pentagon potision
    Cy[6]=Cr*3.077683537;

  }
  public Pentacircle(double R){
    Cr=R;
    Cx[0]=-Cr;Cy[0]=0.0;
    Cx[5]=-Cr;Cy[5]=0.0;
    Cx[1]= Cr;Cy[1]=0.0;
    Cx[3]=0.1*Cr;Cy[3]=3*Cr;

    Cx[6]=0.0;//noral pentagon potision
    Cy[6]=Cr*3.077683537;
  }
  double  Leng(int p1,int p2)
  {
        return(Math.sqrt(Math.pow(Cx[p1]-Cx[p2],2)+Math.pow(Cy[p1]-Cy[p2],2)));
  }
  void  correct(int p1,int p2,double ratio)
  {
        Cx[p2]=Cx[p1]+(Cx[p2]-Cx[p1])*ratio;
        Cy[p2]=Cy[p1]+(Cy[p2]-Cy[p1])*ratio;
  }
  Pentacircle  top_move(int dx,int dy)
  {
        Cx[3]=Cx[3]+(double)dx;
        Cy[3]=Cy[3]+(double)dy;
        return(this);
  }
  boolean side(int px,int pb,int pa)  { // pb--__(px)___--->Pa
   double dx,dy,dr;
      dx=(Cx[pa]-Cx[pb])/2;
      dy=(Cy[pa]-Cy[pb])/2;
      dr=dx*dx+dy*dy ;
      if (4*Cr*Cr<dr) return(false);
      if(dr==0) dr=1;
      dr=Math.sqrt(4*Cr*Cr/dr-1);
      Cx[px]=Cx[pb]+dx+dy*dr;
      Cy[px]=Cy[pb]+dy-dx*dr;
      return(true);
  }
  public void adjust_circles()
  {
       if (Cy[3]<=0) Cy[3]=1;

       double  dr=Leng(1,3);
       if( dr>4*Cr) correct(1,3,4*Cr/dr);
       dr=Leng(0,3);
       if( dr>4*Cr) correct(0,3,4*Cr/dr);

       dr=Leng(3,6);
       if( dr==0 ) {dr=1;Cx[3]+=1;}
       if( dr<Cr*0.2) correct(6,3,0.2*Cr/dr);
    //-----------------TopSetted-----------
       side(2,1,3);
       side(4,3,0);
    //-----------------Side Setted ---------
    for(int i=0;i<5;i++) Direc[i]=Math.atan2(Cy[i+1]-Cy[i],Cx[i+1]-Cx[i]);
    Direc[5]=Direc[0];
  }
}

class Pentagons
{
  double Tx[]=new double[6];
  double Ty[]=new double[6];
  double Px[]=new double[6];
  double Py[]=new double[6];
  double Sleft[]=new double[6];
  double Sright[]=new double[6];
  double temp[]=new double[6];
  double th[]=new double[6];
  double v;

  Pentagons()
  {
     v=-1;
  }
  double make_pentagon( Pentacircle PC,int inout,int shift,double dth)
  {
     int k,itemp;
     double A11,A12,A21,A22,B1,B2,DET,vmin,vmax;

     if(shift>=0){ for(k=0;k<5;k++) th[k]=PC.Direc[(k+shift) % 5]+dth;}
     else { for(k=0;k<5;k++) th[k]=Math.PI-PC.Direc[(11-k+shift) % 5]-dth;}
     th[5]=th[0];
     itemp=inout;
     for(k=0;k<5;k++)
     {
       if((itemp & 1)==1) temp[k]=th[k]+Math.PI/2;else temp[k]=th[k]-Math.PI/2;
       itemp=itemp>>1;
     }
     temp[5]=temp[0];
     for(k=0;k<=5;k++)
     {
       Tx[k]=PC.Cx[k]+PC.Cr*Math.cos(temp[k]);
       Ty[k]=PC.Cy[k]+PC.Cr*Math.sin(temp[k]);
     }
     for(k=0;k<5;k++)
     {
       A11=Math.cos(th[k]);A12=-Math.cos(th[k+1]);B1=Tx[k+1]-Tx[k];
       A21=Math.sin(th[k]);A22=-Math.sin(th[k+1]);B2=Ty[k+1]-Ty[k];
       DET=A11*A22-A12*A21;
       if(DET==0) {v=-1;return(v);}
       Sleft[k+1]=(A11*B2-A21*B1)/DET;
       Sright[k]=(A22*B1-A12*B2)/DET;
       Px[k+1]=Tx[k+1]-Sleft[k+1]*A12;
       Py[k+1]=Ty[k+1]-Sleft[k+1]*A22;
     }
     Sleft[0]=Sleft[5];     Sright[5]=Sright[0];
     Px[0]=Px[5];
     Py[0]=Py[5];
     vmin=10000000;vmax=-10000000;
     for(k=0;k<5;k++)
     {
      if(Sleft[k]*Sright[k]<=0)
      {
        v=Math.abs(Sleft[k]-Sright[k]);
        if(v==0) {v=-1;return(v);}
        if(v>vmax) vmax=v;
        if(v<vmin) vmin=v;
      }else {v=-1;return(v);}
     }
     v=vmin/vmax;
     return(v);
  }
}

public class PentaPenta extends java.applet.Applet implements Runnable {
    Thread blinker;
    Pentacircle PC;
    Pentagons PG[]={new Pentagons(),new Pentagons(),new Pentagons(),
                    new Pentagons(),new Pentagons(),new Pentagons()};
    int shift,inout,up;
    int speed;
    double theat;
    int prevx, prevy;
    Rectangle r;
    Pentagons swap;
    int X0,Y0,XW,YW;

    int data[][]={new int[100],new int[100],new int[100],new int[100]};
    int Xdata[]=new int[100];

    int    Idata =0;
    double basey =0.8;

    Checkbox cbox[]={new Checkbox("C1"),new Checkbox("C2"),new Checkbox("N1"),new Checkbox("N2")};

    public void init() {
        int i,j;
        setBackground(Color.lightGray);

        this.add(cbox[0]);
	cbox[0].setBackground(Color.blue);
        cbox[0].setState(true);
        this.add(cbox[1]);
	cbox[1].setBackground(Color.cyan);
        cbox[1].setState(true);
        this.add(cbox[2]);
	cbox[2].setBackground(Color.red);
        cbox[2].setState(true);
        this.add(cbox[3]);
	cbox[3].setBackground(Color.pink);
        cbox[3].setState(true);

        r=bounds();
        PC=new Pentacircle(r.height/10);
        PC.adjust_circles();

 	String att = getParameter("speed");
	speed = (att == null) ? 100 : (1000 / Integer.valueOf(att).intValue());
        theat=0;
        X0=(int)(r.width*0.05);
        Y0=(int)(r.height*0.07);
        XW=(int)(r.width*0.9);
        YW=(int)(r.height*0.27);
        for(i=0;i<100;i++) Xdata[i]=X0+(int)(XW*i/100);
    }
    public void  put_C(double x,double y,double R,Graphics g)
       {
         int D=(int)(R*2);
         //g.setColor(Color.white);
         //g.fillOval((int)(x-R+r.width/2),(int)(basey*r.height-(y+R)),D,D);
         g.setColor(Color.black);
         g.drawOval((int)(x-R+r.width/2),(int)(basey*r.height-(y+R)),D,D);
       }
    public void  put_L(double xa,double ya,double xb,double yb,Graphics g)
       {
         g.drawLine((int)(xa+r.width/2),(int)(basey*r.height-(ya)),(int)(xb+r.width/2),(int)(basey*r.height-(yb)));
       }
    public void  put_T(double Ax,double Ay,double R,double Vx,double Vy,double LL,Graphics g)
       {
         double Tx,Ty,Sx,Sy;
         Tx=Ax-Vx*R;
         Ty=Ay-Vy*R;
         Sx=Tx-Vy*LL;
         Sy=Ty+Vx*LL;
         put_L(Tx,Ty,Sx,Sy,g);
         Sx=Tx+Vy*LL;
         Sy=Ty-Vx*LL;
         put_L(Tx,Ty,Sx,Sy,g);
       }
    public void  put_P5(double Px[],double Py[],Graphics g)
     {
             int i;
             for(i=0;i<5;i++)
             put_L(Px[i],Py[i],Px[i+1],Py[i+1],g);
     }
    public void paint(Graphics g) {
       int i,j;
       int imin=0;
       double lev,levmin,Vx,Vy,Q;
       g.setColor(Color.yellow);
       g.fillRect(X0,Y0,XW,YW);
       g.setColor(Color.lightGray);
       for(i=1;i<10;i++)
       g.drawLine(X0,Y0+YW*i/10,X0+XW,Y0+YW*i/10);
       g.setColor(Color.black);
       g.drawRect(X0,Y0,XW,YW);
       g.drawString("1.00",X0+15,Y0);
       g.drawString("0.90",X0+15,Y0+YW);

//--------   draw basic 5 circles  -----------------
       for(i=0;i<5;i++) {put_C(PC.Cx[i],PC.Cy[i],PC.Cr,g);}
//--------  draw base Pentagon    ------------------
       g.setColor(Color.green.darker());
       for(i=0;i<5;i++)
            { j=i+1;if(j>=5) j=0;    put_L(PC.Cx[i],PC.Cy[i],PC.Cx[j],PC.Cy[j],g);   }
//--------- dram Bottom Tangential Line ------------
       theat+=Math.PI/180.0;if (theat>=2*Math.PI) theat-=2*Math.PI;
          {
            /*    levmin=10000.;
                Vx=Math.cos(theat+PC.Direc[0]);
                Vy=Math.sin(theat+PC.Direc[0]);
                for(i=0;i<5;i++) {
                    lev=PC.Cx[i]*Vx+PC.Cy[i]*Vy;
                    if(levmin>lev) {levmin=lev;imin=i;}
                          }
                put_T(PC.Cx[imin],PC.Cy[imin],PC.Cr,Vx,Vy,(double)( r.width),g);
             */
                for(i=0;i<6;i++) PG[i].v=-1;

                for(shift=-5;shift<5;shift++)
                for(inout=0;inout<32;inout++)
                {
                  if(shift>=0) up=0;else up=3;
                  Q=PG[2+up].make_pentagon(PC,inout,shift,theat);
                  for(i=2;i>0;i--)
                  if(PG[i+up].v>=PG[i-1+up].v)
                  {
                     swap=PG[i-1+up];
                     PG[i-1+up]=PG[i+up];
                     PG[i+up]=swap;
                  }else break;
                }

                g.setColor(Color.cyan);
                if(PG[4].v>0 && cbox[1].getState()) put_P5(PG[4].Px,PG[4].Py,g);
                g.setColor(Color.pink);
                if(PG[1].v>0 && cbox[3].getState()) put_P5(PG[1].Px,PG[1].Py,g);
                g.setColor(Color.blue);
                if(PG[3].v>0 && cbox[0].getState()) put_P5(PG[3].Px,PG[3].Py,g);
                g.setColor(Color.red);
                if(PG[0].v>0 && cbox[2].getState()) put_P5(PG[0].Px,PG[0].Py,g);

                if(Idata==100)
                for(i=1;i<100;i++)
                {
                  data[0][i-1]=data[0][i];
                  data[1][i-1]=data[1][i];
                  data[2][i-1]=data[2][i];
                  data[3][i-1]=data[3][i];
                }
                Idata=Idata+1; if(Idata>=100) Idata=100;
                data[0][Idata-1]=(int)(Y0+YW*(1-PG[0].v)*10);
                data[1][Idata-1]=(int)(Y0+YW*(1-PG[1].v)*10);
                data[2][Idata-1]=(int)(Y0+YW*(1-PG[3].v)*10);
                data[3][Idata-1]=(int)(Y0+YW*(1-PG[4].v)*10);

                g.setColor(Color.cyan);
                g.drawPolyline(Xdata,data[3],Idata);
                g.setColor(Color.pink);
                g.drawPolyline(Xdata,data[1],Idata);
                g.setColor(Color.blue);
                g.drawPolyline(Xdata,data[2],Idata);
                g.setColor(Color.red);
                g.drawPolyline(Xdata,data[0],Idata);
           }
    }

    public void start() {
	blinker = new Thread(this);
	blinker.start();
    }
    public void stop() {
	blinker.stop();
    }
    public void run() {
	while (true) {
	try {Thread.currentThread().sleep(speed);} catch (InterruptedException e){}
	    repaint();
	}
    }
    public boolean mouseDown(Event e, int x, int y) {
	prevx = x;
	prevy = y;
	return true;
    }
    public boolean mouseDrag(Event e, int x, int y) {
        PC.top_move(x-prevx,-y+prevy);
        PC.adjust_circles();
	prevx = x;
	prevy = y;
	return true;
    }
}
