import java.applet.*;
import java.awt.*;
import java.lang.Math;
public class Geom2 extends Applet {
   private int angl=360;
   private int last_x=0;
   private int last_y=0;
   private Color current_color=Color.black;
   private boolean current_seg=true;
   private Button clear_button;
   private Button square_button;
   private Button circ_button;
   private Button int_button;
   private Choice color_choices;
   private Choice arc_choices;
   private Choice line_choices;
   private Choice select_choices;




    public class point implements Cloneable{
                 public int x;
                 public int y;

                  public Object clone(){ //begin clone
                    try{ //begin try
                        return super.clone();
                        } //end try
                         
                    catch(CloneNotSupportedException e){ // begin catch
                        return null;  //if there is a catch
                         } //end catch
                    } //end cloning structure for point
             
                 }  //end point def


     public class Vcirc implements Cloneable{
                 
                 public point c=new point();
                 public point v=new point();
                 public int s;
                 public boolean sel=false;
                 public Color cl=Color.black;

                  public Object clone(){ //begin clone
                    try{ //begin try
                        Vcirc vc=(Vcirc)super.clone();
                        vc.c=(point)c.clone();
                        vc.v=(point)v.clone();
                        return vc;
                        } catch(CloneNotSupportedException e){
                           return null;
                          }//end catch

                    } //end cloning structure for virtual circle c is center, v is vector
  
   
           } //end virtual circle def

      public class Vline implements Cloneable{
                public point a=new point();
                public point b=new point();
                public point c=new point();
                public int s;
                public Color cl=Color.black;
                public boolean seg=true;
                public boolean sel=false;

                 
                    public Object clone(){ // begin clone def
                         try{ //begin try
                            Vline vl=(Vline)super.clone();
                             vl.a=(point)a.clone();
                             vl.b=(point)b.clone();
                             vl.c=(point)c.clone();
                            return vl;
                          } catch(CloneNotSupportedException e){
                             return null;
                            } // end catch
                     } // end clone structure
        } // end virtual line def
        
      public class Ipoint implements Cloneable{
                 public point a=new point(); //point location
                 public point o=new point(); //two objects 0-19 circles 20-39 lines
                 public Color cl=Color.black;

                   public Object clone(){ // begin clone def
                          try{ //begin try
                            Ipoint ip=(Ipoint)super.clone();
                              ip.a=(point)a.clone();
                              ip.o=(point)o.clone();
                            return ip;
                          } catch(CloneNotSupportedException e){
                              return null;
                            } //end catch
                    } // end clone structure
          } // end intersection point

      public int linemax=19;
      public int circmax=19;
      public int ipmax=49;
      public Vcirc circ1=new Vcirc();
      public Vcirc circ[]=new Vcirc[circmax];
      public Vline line1=new Vline();
      public Vline lin[]=new Vline[linemax];
      public Ipoint point1=new Ipoint();
      public Ipoint poi[]=new Ipoint[ipmax];
      public int circount=0;
      public int lincount=0;
      public int selcount=0;
      public int i;
      public int j;
      public int cur_circ;
      public int cur_line;

//init applet
   public void init(){

//set backgd color
    this.setBackground(Color.white);

                circ1.c.x=30;
                circ1.c.y=30;
                circ1.v.x=0;
                circ1.v.y=20;
                circ1.s=20;
                circ1.cl=Color.black;
 for(i=0;i<circmax;i++) {circ[i]=(Vcirc)circ1.clone();}
 
                line1.a.x=40;
                line1.a.y=50;
                line1.b.x=140;
                line1.b.y=50;
                line1.c.x=90;
                line1.c.y=50;
                line1.s=100;
                line1.cl=Color.black;
                line1.seg=true;
 for(i=0;i<linemax;i++) {lin[i]=(Vline)line1.clone();}

                point1.a.x=-10;
                point1.a.y=-10;
                point1.o.x=-1;
                point1.o.y=-1;
                point1.cl=Color.black;

 for(i=0;i<ipmax;i++) {poi[i]=(Ipoint)point1.clone();}



//create a restart button
    clear_button=new Button("Clear");
    clear_button.setForeground(Color.black);
    clear_button.setBackground(Color.lightGray);
    this.add(clear_button);

//create a intersect button
    int_button=new Button("Join");
    int_button.setForeground(Color.black);
    int_button.setBackground(Color.lightGray);
    this.add(int_button);


//create square button
     square_button=new Button("Square");
     square_button.setForeground(Color.black);
     square_button.setBackground(Color.lightGray);
     this.add(square_button);

//create circle button
     circ_button=new Button("Circle");
     circ_button.setForeground(Color.black);
     circ_button.setBackground(Color.lightGray);
     this.add(circ_button);

//create menu of colors
    color_choices=new Choice();
    color_choices.addItem("black");
    color_choices.addItem("red");
    color_choices.addItem("blue");
    color_choices.addItem("green");
    color_choices.addItem("yellow");
    color_choices.setForeground(Color.black);
    color_choices.setBackground(Color.lightGray);
    this.add(new Label("Color:"));
    this.add(color_choices);

//create menu of lines
     line_choices=new Choice();
     line_choices.addItem("segment");
     line_choices.addItem("line");
     line_choices.setForeground(Color.black);
     line_choices.setBackground(Color.lightGray);
     this.add(new Label("Lines:"));
     this.add(line_choices);

//create menu of selections
     select_choices=new Choice();
     select_choices.addItem("select circle");
     select_choices.addItem("select segment");
     select_choices.addItem("select 2 points");
     select_choices.addItem("select 2 circles");
     select_choices.addItem("select line and circle");
     select_choices.addItem("select all");
     select_choices.setForeground(Color.black);
     select_choices.setBackground(Color.lightGray);
     this.add(new Label("Select:"));
     this.add(select_choices);

   }
//end init applet


//called when mouse click
    public boolean mouseDown(Event e, int x, int y){
        last_x=x; last_y=y;
          for (i=0;i<circount;i++){
            if((circ[i].c.x-3<last_x)  &  (last_x<circ[i].c.x+3)
             & (circ[i].c.y-3<last_y) & (last_y<circ[i].c.y+3)){
             Graphics g=this.getGraphics();
             g.setColor(circ[i].cl);
             cur_circ=i;
            } //end if circ center
            if((circ[i].c.x +circ[i].v.x-3<last_x)  
                &  (last_x<circ[i].c.x+circ[i].v.x+3)
                 & (circ[i].c.y+circ[i].v.y-3<last_y) 
                   & (last_y<circ[i].c.y+circ[i].v.y+3)){
             Graphics g=this.getGraphics();
             g.setColor(circ[i].cl);
             cur_circ=i;
             } //end if circ vector 
        } //end for i

          for (j=0;j<lincount;j++){
            if((lin[j].c.x-3<last_x)  &  (last_x<lin[j].c.x+3)
             & (lin[j].c.y-3<last_y) & (last_y<lin[j].c.y+3)){
             Graphics g=this.getGraphics();
             g.setColor(lin[j].cl);
             cur_line=j;
             } //end if line center 

            if((lin[j].a.x-3<last_x)  &  (last_x<lin[j].a.x+3)
             & (lin[j].a.y-3<last_y) & (last_y<lin[j].a.y+3)){
             Graphics g=this.getGraphics();
             g.setColor(lin[j].cl);
             cur_line=j;
             } //end if line center 

            if((lin[j].b.x-3<last_x)  &  (last_x<lin[j].b.x+3)
             & (lin[j].b.y-3<last_y) & (last_y<lin[j].b.y+3)){
             Graphics g=this.getGraphics();
             g.setColor(lin[j].cl);
             cur_line=j;
             } //end if line center 



          } //end for j
        return true;
       }


//called when mouse moves
    public boolean mouseDrag(Event e, int x, int y){
          Graphics g=this.getGraphics();      
           if((circ[cur_circ].c.x-3<last_x)  &  (last_x<circ[cur_circ].c.x+3)
             & (circ[cur_circ].c.y-3<last_y) & (last_y<circ[cur_circ].c.y+3)){
              g.setColor(Color.white);
                g.drawArc(circ[cur_circ].c.x-circ[cur_circ].s,circ[cur_circ].c.y -circ[cur_circ].s,2*circ[cur_circ].s,2*circ[cur_circ].s,0,360);
                //draw center
                g.drawArc(circ[cur_circ].c.x-2,circ[cur_circ].c.y-2,4,4,0,360);
                // draw radial point
                g.drawArc(circ[cur_circ].c.x+ circ[cur_circ].v.x-2,circ[cur_circ].c.y+circ[cur_circ].v.y-2,4,4,0,360);
          circ[cur_circ].c.x=x;
          circ[cur_circ].c.y=y;


               for(i=0;i<circount;i++){
                g.setColor(circ[i].cl);
                g.drawArc(circ[i].c.x-circ[i].s,circ[i].c.y -circ[i].s,2*circ[i].s,2*circ[i].s,0,360);
                //draw center
                g.drawArc(circ[i].c.x-2,circ[i].c.y-2,4,4,0,360);
                // draw radial point
                g.drawArc(circ[i].c.x +circ[i].v.x-2,circ[i].c.y+circ[i].v.y-2,4,4,0,360);
               } //end for i circles

               for(i=0;i<lincount;i++){
                g.setColor(lin[i].cl);
                g.drawLine(lin[i].a.x+2,lin[i].a.y+2,lin[i].b.x+2,lin[i].b.y+2);
                g.drawArc(lin[i].a.x,lin[i].a.y,4,4,0,360);
                g.drawArc(lin[i].b.x,lin[i].b.y,4,4,0,360);
                 g.drawRect(lin[i].c.x,lin[i].c.y,4,4);
               } //end for i line
          } //end if circ center


           if((lin[cur_line].a.x-3<last_x)  &  (last_x<lin[cur_line].a.x+3)
             & (lin[cur_line].a.y-3<last_y) & (last_y<lin[cur_line].a.y+3)){
              g.setColor(Color.white);
                g.drawLine(lin[cur_line].a.x+2,lin[cur_line].a.y+2,lin[cur_line].b.x+2,lin[cur_line].b.y+2);
                g.drawArc(lin[cur_line].a.x,lin[cur_line].a.y,4,4,0,360);
                g.drawArc(lin[cur_line].b.x,lin[cur_line].b.y,4,4,0,360);
                 g.drawRect(lin[cur_line].c.x,lin[cur_line].c.y,4,4);
          lin[cur_line].a.x=x;         
          lin[cur_line].a.y=y;         
          lin[cur_line].c.x=(int)((lin[cur_line].a.x + lin[cur_line].b.x)/2);
          lin[cur_line].c.y=(int)((lin[cur_line].a.y + lin[cur_line].b.y)/2);
     
          for(i=0;i<circount;i++){
                g.setColor(circ[i].cl);
                g.drawArc(circ[i].c.x-circ[i].s,circ[i].c.y -circ[i].s,2*circ[i].s,2*circ[i].s,0,360);
                //draw center
                g.drawArc(circ[i].c.x-2,circ[i].c.y-2,4,4,0,360);
                // draw radial point
                g.drawArc(circ[i].c.x +circ[i].v.x-2,circ[i].c.y+circ[i].v.y-2,4,4,0,360);
               } //end for i circles

               for(i=0;i<lincount;i++){
                g.setColor(lin[i].cl);
                g.drawLine(lin[i].a.x+2,lin[i].a.y+2,lin[i].b.x+2,lin[i].b.y+2);
                g.drawArc(lin[i].a.x,lin[i].a.y,4,4,0,360);
                g.drawArc(lin[i].b.x,lin[i].b.y,4,4,0,360);
                 g.drawRect(lin[i].c.x,lin[i].c.y,4,4);
               } //end for i line

          } //end if lin a point



           if((lin[cur_line].b.x-3<last_x)  &  (last_x<lin[cur_line].b.x+3)
             & (lin[cur_line].b.y-3<last_y) & (last_y<lin[cur_line].b.y+3)){
              g.setColor(Color.white);
                g.drawLine(lin[cur_line].a.x+2,lin[cur_line].a.y+2,lin[cur_line].b.x+2,lin[cur_line].b.y+2);
                g.drawArc(lin[cur_line].a.x,lin[cur_line].a.y,4,4,0,360);
                g.drawArc(lin[cur_line].b.x,lin[cur_line].b.y,4,4,0,360);
                 g.drawRect(lin[cur_line].c.x,lin[cur_line].c.y,4,4);
          lin[cur_line].b.x=x;         
          lin[cur_line].b.y=y;         
          lin[cur_line].c.x=(int)((lin[cur_line].a.x + lin[cur_line].b.x)/2);
          lin[cur_line].c.y=(int)((lin[cur_line].a.y + lin[cur_line].b.y)/2);
     
          for(i=0;i<circount;i++){
                g.setColor(circ[i].cl);
                g.drawArc(circ[i].c.x-circ[i].s,circ[i].c.y -circ[i].s,2*circ[i].s,2*circ[i].s,0,360);
                //draw center
                g.drawArc(circ[i].c.x-2,circ[i].c.y-2,4,4,0,360);
                // draw radial point
                g.drawArc(circ[i].c.x +circ[i].v.x-2,circ[i].c.y+circ[i].v.y-2,4,4,0,360);
               } //end for i circles

               for(i=0;i<lincount;i++){
                g.setColor(lin[i].cl);
                g.drawLine(lin[i].a.x+2,lin[i].a.y+2,lin[i].b.x+2,lin[i].b.y+2);
                g.drawArc(lin[i].a.x,lin[i].a.y,4,4,0,360);
                g.drawArc(lin[i].b.x,lin[i].b.y,4,4,0,360);
                 g.drawRect(lin[i].c.x,lin[i].c.y,4,4);
               } //end for i line

          } //end if lin b point




           if((lin[cur_line].c.x-3<last_x)  &  (last_x<lin[cur_line].c.x+3)
             & (lin[cur_line].c.y-3<last_y) & (last_y<lin[cur_line].c.y+3)){
              g.setColor(Color.white);
                g.drawLine(lin[cur_line].a.x+2,lin[cur_line].a.y+2,lin[cur_line].b.x+2,lin[cur_line].b.y+2);
                g.drawArc(lin[cur_line].a.x,lin[cur_line].a.y,4,4,0,360);
                g.drawArc(lin[cur_line].b.x,lin[cur_line].b.y,4,4,0,360);
                 g.drawRect(lin[cur_line].c.x,lin[cur_line].c.y,4,4);
          lin[cur_line].a.x=x + lin[cur_line].a.x - lin[cur_line].c.x;
          lin[cur_line].b.x=x + lin[cur_line].b.x - lin[cur_line].c.x;
          lin[cur_line].a.y=y + lin[cur_line].a.y - lin[cur_line].c.y;
          lin[cur_line].b.y=y + lin[cur_line].b.y - lin[cur_line].c.y;
          lin[cur_line].c.x=x;
          lin[cur_line].c.y=y;


               for(i=0;i<circount;i++){
                g.setColor(circ[i].cl);
                g.drawArc(circ[i].c.x-circ[i].s,circ[i].c.y -circ[i].s,2*circ[i].s,2*circ[i].s,0,360);
                //draw center
                g.drawArc(circ[i].c.x-2,circ[i].c.y-2,4,4,0,360);
                // draw radial point
                g.drawArc(circ[i].c.x +circ[i].v.x-2,circ[i].c.y+circ[i].v.y-2,4,4,0,360);
               } //end for i circles

               for(i=0;i<lincount;i++){
                g.setColor(lin[i].cl);
                g.drawLine(lin[i].a.x+2,lin[i].a.y+2,lin[i].b.x+2,lin[i].b.y+2);
                g.drawArc(lin[i].a.x,lin[i].a.y,4,4,0,360);
                g.drawArc(lin[i].b.x,lin[i].b.y,4,4,0,360);
                 g.drawRect(lin[i].c.x,lin[i].c.y,4,4);
               } //end for i line



          } //end if lin center

          if((circ[cur_circ].c.x +circ[cur_circ].v.x-3<last_x)  
                &  (last_x<circ[cur_circ].c.x+circ[cur_circ].v.x+3)
                 & (circ[cur_circ].c.y+circ[cur_circ].v.y-3<last_y) 
                   & (last_y<circ[cur_circ].c.y+circ[cur_circ].v.y+3)){
              g.setColor(Color.white);
                g.drawArc(circ[cur_circ].c.x-circ[cur_circ].s,circ[cur_circ].c.y -circ[cur_circ].s,2*circ[cur_circ].s,2*circ[cur_circ].s,0,360);
                //draw center
                g.drawArc(circ[cur_circ].c.x-2,circ[cur_circ].c.y-2,4,4,0,360);
                // draw radial point
                g.drawArc(circ[cur_circ].c.x+circ[cur_circ].v.x-2,circ[cur_circ].c.y+circ[cur_circ].v.y-2,4,4,0,360);
          circ[cur_circ].v.y=circ[cur_circ].v.y-last_y+y;
          circ[cur_circ].v.x=circ[cur_circ].v.x-last_x+x;
          circ[cur_circ].s=(int)Math.sqrt(circ[cur_circ].v.x*circ[cur_circ].v.x + circ[cur_circ].v.y*circ[cur_circ].v.y);
 
            for(i=0;i<circount;i++){
                g.setColor(circ[i].cl);
                g.drawArc(circ[i].c.x-circ[i].s,circ[i].c.y -circ[i].s,2*circ[i].s,2*circ[i].s,0,360);
                //draw center
                g.drawArc(circ[i].c.x-2,circ[i].c.y-2,4,4,0,360);
                // draw radial point
                g.drawArc(circ[i].c.x+circ[i].v.x-2,circ[i].c.y+circ[i].v.y-2,4,4,0,360);
              } //end for i
            for(i=0;i<lincount;i++){
                g.setColor(lin[i].cl);
                g.drawLine(lin[i].a.x+2,lin[i].a.y+2,lin[i].b.x+2,lin[i].b.y+2);
                g.drawArc(lin[i].a.x,lin[i].a.y,4,4,0,360);
                g.drawArc(lin[i].b.x,lin[i].b.y,4,4,0,360);
                 g.drawRect(lin[i].c.x,lin[i].c.y,4,4);

               } //end for i line

       } // end if circ vector
          last_x=x;
          last_y=y;
          return true;
      }


//user clicks button or chooses a color
     public boolean action(Event event, Object arg){
          // in case of click
          if(event.target==clear_button){
               Graphics g=this.getGraphics();
               Rectangle r=this.bounds();
               g.setColor(this.getBackground());
               g.fillRect(r.x,r.y,r.width,r.height);
               circount=0;
               for(i=0;i<circmax;i++){circ[i]=(Vcirc)circ1.clone();}
               lincount=0;
               for(i=0;i<linemax;i++){lin[i]=(Vline)line1.clone();} 
               return true;
              }
            
 
          // else do for color choices
           else if(event.target==color_choices){
                 if(arg.equals("black")) current_color=Color.black;
                 else if(arg.equals("red")) current_color=Color.red;
                 else if(arg.equals("blue")) current_color=Color.blue;
                 else if(arg.equals("green")) current_color=Color.green;
                 else if(arg.equals("yellow")) current_color=Color.yellow;

                 return true;
                }

          // else do for line choices
           else if(event.target==line_choices){
                 if(arg.equals("segment")) current_seg=true;
                 else if(arg.equals("line")) current_seg=false;
                 Graphics g=this.getGraphics();
                 j=lincount;
                 lin[j].cl=current_color;
                 g.setColor(lin[j].cl);
                 g.drawLine(lin[j].a.x+2,lin[j].a.y+2,lin[j].b.x+2,lin[j].b.y+2);
                 g.drawArc(lin[j].a.x,lin[j].a.y,4,4,0,360);
                 g.drawArc(lin[j].b.x,lin[j].b.y,4,4,0,360);
                 g.drawRect(lin[j].c.x,lin[j].c.y,4,4);
                  if(lincount<linemax){lincount++;}
                 return true;
                }
 
        
           // else do
           else if(event.target==square_button){
                Graphics g=this.getGraphics();
                g.setColor(current_color);
                g.drawRect(10,10,40,40);
                return true;    
               }
            // else do
           else if(event.target==circ_button){
                Graphics g=this.getGraphics();
                cur_circ=circount;
                j=circount;
                circ[j].cl=current_color;
                g.setColor(circ[j].cl);
                // draw new circle
                g.drawArc(circ[j].c.x-circ[j].s,circ[j].c.y -circ[j].s,2*circ[j].s,2*circ[j].s,0,360);
                //draw center
                g.drawArc(circ[j].c.x-2,circ[j].c.y-2,4,4,0,360);
                // draw radial point
                g.drawArc(circ[j].c.x+circ[j].v.x-2,circ[j].c.y+circ[j].v.y-2,4,4,0,360);
                if (circount<circmax){circount++;}
                return true;    
               }
           // note that the last two args in drawArc 
           // tell the angle to start and the angular length.
           // the first four arguments discribe a square

           // Otherwise let the superclass handle it.
           else return super.action(event, arg);
     }
}

