/*
	oneQuad will show the length of each side of a quadralateral.
	User may click and drag each vertex to a new location between 
	-15 and +15 to form squares, rectnagles, rhombuses, parallelograms,
	trapeziods or irregular polygons.
	
	version 1.0 - 7 Nov 1998 Fr. Chris Thiel, OFMCap <cct@ktb.net>
	version 2.0 - 24 Nove 1998  added diagonals, changed interface to click on vertices
*/

import java.awt.*;
import java.applet.Applet;
import java.awt.Graphics;
import java.awt.event.*;
import java.lang.Math;

public class oneQuad extends java.applet.Applet {

    int mx, my, activeDot=3;
    int rx[];
	int ry[];
	int ang[];
	String colorItem;
	String vertex="ABCD";
	float dist[];
	Choice daMenu = new Choice();
	int fudge=7; //fudge factor for sensitivity

	
	boolean moving=false;
	boolean showLabels=true;
	boolean showDiags=false;
	boolean showAngles=false;
	boolean showLengths =false;
	
	
    public void init() {
   		rx = new int[4];
		ry = new int[4];
		dist = new float[4];
		ang = new int[4];
		
		daMenu.addItem("Quad only");
		daMenu.addItem("Quad with diagonals");
		daMenu.addItem("Quad with lengths");
		daMenu.addItem("Quad with angles");
		daMenu.addItem("Show all");
		
		add(daMenu);
	

        setBackground(new Color(0xF08080));
       
        	rx[0] = 100;rx[1] = 200;rx[2] = 200;rx[3] = 100;
        	ry[0] = 200; ry[1] = 200;ry[2] = 100;ry[3] = 100;
       
    }

    public void paint(Graphics g) {
     
    	switch (daMenu.getSelectedIndex()) {
    		case(0):
    			showDiags=false;
    			showAngles=false;
    			showLabels = true;
    			showLengths =false;
    			break;
    		case(1):
    			showDiags=true;
    			showAngles=false;
    			showLabels = true;
    			showLengths=false;
    			break;
        	case(2):
    			showDiags=false;
    			showAngles=false;
    			showLabels = true;
    			showLengths =true;
    			break;
    		case(3):
    			showDiags=false;
    			showAngles=true;
    			showLabels = true;
    			showLengths =false;
    			break;
    		case(4):
    			showDiags=true;
    			showAngles=true;
    			showLabels = true;
    			showLengths =true;
    			break;
    		
    		default:
    			showDiags=false;
    			showAngles=false;
    			showLabels = true;
    			showLengths =true;
    			
    	}
    	//draw the quad
        for (int i=0; i<4; i++)
        	g.drawLine(rx[i],ry[i], rx[(i+1)%4],ry[(i+1)%4]);
      
        if (showDiags){
        	g.setColor(Color.cyan);
        	g.drawLine(rx[0],ry[0], rx[2],ry[2]);
        	g.drawLine(rx[1],ry[1], rx[3],ry[3]);
        	
        }
        //vertices always red
        g.setColor(Color.red);
       
        for (int i=0; i<4; i++){
        	g.fillOval(rx[i]-3,ry[i]-3, 7,7);
        }

       if (moving) {
       		g.setColor(Color.blue);
       		int x = rx[activeDot]/10-15;
       		int y = 15 - ry[activeDot]/10;
        	g.drawString("Moving vertex "+vertex.charAt(activeDot)+" to ("+x+","+y+")", 10,290);
        	g.fillOval(rx[activeDot]-3,ry[activeDot]-3, 7,7);
        	} 
        else {
        	g.setColor(Color.black);
        	g.drawString("Click on vertex to move", 10,290);
        	for (int i=0; i<4; i++){ 
        		if (showLengths) { //show length of each side
        			g.setColor(Color.blue);
        			g.drawString(Float.toString(dist[i]), Math.round( (rx[i]+rx[(i+1)%4])/2) , Math.round( (ry[i]+ry[(i+1)%4])/2));
        		}
        		if (showAngles) {//show angle of each vertex
        			g.setColor(Color.white);
        			g.drawString(Integer.toString(ang[i]), rx[i]-14, ry[i]+10);
        		}
        		if (showLabels) { //show labels
        			g.setColor(Color.black);
        			g.drawString(vertex.substring(i,i+1), rx[i],ry[i]);
        		}
        		
       		}
        }
       
    }
	public boolean action(Event e, Object arg) {
                   if (e.target instanceof Choice) {
                     repaint();
                      return true;
                  } else { return false;}
               
    }
    
    public boolean handleEvent(Event e) {
                  return super.handleEvent(e);
    }
             
    /*
     * Mouse methods
     */
    public boolean mouseDown(java.awt.Event evt, int x, int y) {
      
        moving= !moving;
        if (moving){ 
        	
        	for ( int i=0; i<4; i++){
            if ( ( x > rx[i]-fudge && x < rx[i]+fudge)  &&
                 ( y > ry[i]-fudge && y < ry[i]+fudge) ) {
                 activeDot = i ;
                 moving=true; 
            }
          }
        } else {
  			for (int i=0; i< 4;i++){
  			    double d = Math.round(Math.sqrt( Math.pow((rx[i]-rx[(i+1)%4]),2) + Math.pow((ry[i]-ry[(i+1)%4]),2)));
  				dist[i]=(float)(d/10);
  			}
  			for (int i=0; i<4; i++){
  				/* use the law of cosines to find each angle */
  				double sideA2 = Math.pow(rx[(i+3)%4]-rx[i],2)+Math.pow(ry[(i+3)%4]-ry[i],2);
				double sideC2 = Math.pow(rx[(i+1)%4]-rx[i],2)+Math.pow(ry[(i+1)%4]-ry[i],2);
				double sideB2 = Math.pow(rx[(i+1)%4]-rx[(i+3)%4],2)+Math.pow(ry[(i+1)%4]-ry[(i+3)%4],2);
				double sideA  = Math.sqrt(sideA2);
				double sideC  = Math.sqrt(sideC2);
			
				double numerator=  sideA2 + sideC2 - sideB2 ;
				double denominator = 2 * sideA *sideC;
				double a = Math.round(  (180/Math.PI)*(Math.acos(numerator/denominator)) );
				ang[i] = (int)( a );
  				
  				
  			}

		}

        repaint();
        return true;
    }
	
  	
  	
    public boolean mouseMove(java.awt.Event evt, int x, int y) {
         x = (x/10)-15;
         y = 15-(y/10);
         getAppletContext().showStatus("Location of mouse: (" + x + ", " + y + ")");
        
         if (moving){
         	requestFocus();
         	rx[ activeDot] = (x+15)*10;
        	ry[ activeDot] = (15-y)*10;  
        	repaint();
         }
        return true;
    }

    public void mouseEnter() {
        repaint();
    }

    public void mouseExit() {
       
        repaint();
    }

    /**
     * Focus methods
     */
    public void keyDown(int key) {
    }
    
    
}//end applet

