import java.util.*;
import java.awt.*;
import java.awt.event.*;
import java.net.*;
import java.applet.*;

/* 

   RinR -- little dynamic geometry applet for the Rhombus in Rectangle problem from 
           the March Six.

     


*/

public class Rhomb extends Applet implements MouseListener, MouseMotionListener {
    Image offImage;
    Dimension offDimension;
    Graphics offGraphics;
    
    int STARTX = 30;
    int STARTY = 80;
    int STARTHEIGHT = 100;
    int STARTWIDTH = 125;

    int POINTRADIUS = 3;
    int CLICKRANGE = 7;

    Pair p[];

    int width;
    int height;
    int MINDIST = 13;

    int pickedup;
    int rightmost;
    int topmost;
    int bottommost;
    int leftmost;

    public class Pair {
	int x,y;
	Pair() {}

	Pair(int newx, int newy){ 
	    x=newx;
	    y=newy;
	}
    }

    public void init() {
	p = new Pair[6];
	for (int i = 0;i<6;i++) {
	    p[i]= new Pair();
	}

	p[0].x=STARTX;
	p[0].y = STARTY;

	p[1].x = STARTX+STARTWIDTH;
	p[1].y = STARTY;

	p[2].x = STARTX+STARTWIDTH;
	p[2].y=STARTY+STARTHEIGHT;

	p[3].x = STARTX;
	p[3].y=STARTY+STARTHEIGHT;

	p[4].x = (int)(STARTX+0.25*STARTWIDTH);
	p[4].y = STARTY;

	p[5].x = (int)(STARTX+0.4*STARTWIDTH);
	p[5].y = STARTY + STARTHEIGHT;


	addMouseListener(this);
	addMouseMotionListener(this);

	Graphics g = getGraphics();
	update(g);
    }


    public void paint(Graphics g) {

	update(g);
    }

    public void update(Graphics g) {


	Dimension d = getSize() ;
            
	if ( (offGraphics == null)
	     || (d.width != offDimension.width)
	     || (d.height != offDimension.height) ) {
	    offDimension = d;
	    offImage = createImage(d.width, d.height);
	    offGraphics = offImage.getGraphics();
	}
	
	//Erase the previous image.
	//    offGraphics.setColor(getBackground());
	offGraphics.setColor(Color.white);
	offGraphics.fillRect(0, 0, d.width, d.height);
	offGraphics.setColor(Color.black);
	
	drawSelf(offGraphics);

	// give some instructions
	Font font = g.getFont();
	int style = font.getStyle();
	font = new Font("Helvetica", font.ITALIC, 10);
	offGraphics.setFont(font);

	offGraphics.setColor(Color.black);
	offGraphics.drawString("You may move the points P, Q, and C by", STARTX+10, STARTY+STARTHEIGHT+40);
	offGraphics.drawString("clicking on them and dragging them.", STARTX+10, STARTY+STARTHEIGHT+52);
	font = new Font("Helvetica", style,10);
	offGraphics.setFont(font);
	
	if(g==null) {
	    g=getGraphics();
	}
	g.drawImage(offImage, 0, 0, null);
           
    }

    void drawSelf(Graphics g) {
	

	// draw the rectangle
	g.drawLine(p[0].x, p[0].y, p[1].x, p[1].y);
	g.drawLine(p[1].x, p[1].y, p[2].x, p[2].y);
	g.drawLine(p[2].x, p[2].y, p[3].x, p[3].y);
	g.drawLine(p[3].x, p[3].y, p[0].x, p[0].y);

	// draw the lines
	g.drawLine(p[4].x, p[4].y, p[3].x, p[3].y);
	g.drawLine(p[5].x, p[5].y, p[1].x, p[1].y);

	// draw some points
	g.setColor(Color.blue);
	for(int i = 0;i<4;i++) {
	    g.fillOval(p[i].x-POINTRADIUS, p[i].y-POINTRADIUS,
		       POINTRADIUS*2, POINTRADIUS*2);
	}

	//at the moment, because 2 is the distinguished movable node...
	g.setColor(Color.magenta);
	g.fillOval(p[1].x-POINTRADIUS, p[1].y-POINTRADIUS,
		       POINTRADIUS*2, POINTRADIUS*2);


	g.setColor(Color.red);
	for(int i = 4; i<6;i++) {
	    g.fillOval(p[i].x-POINTRADIUS, p[i].y-POINTRADIUS,
		       POINTRADIUS*2, POINTRADIUS*2);
	}

	Font font = g.getFont();
	font = new Font("Helvetica", font.getStyle(), 14);
	g.setFont(font);

	FontMetrics fontMetrics = g.getFontMetrics();

	g.setColor(Color.blue);
	// label the points
	g.drawString("D", p[0].x-8, p[0].y-5);
	g.drawString("C", p[1].x+8, p[1].y-5);
	g.drawString("B", p[2].x+8, p[2].y+5+fontMetrics.getAscent());
	g.drawString("A", p[3].x-8, p[3].y+5+fontMetrics.getAscent());

	g.setColor(Color.red);
	g.drawString("Q", p[4].x+8, p[4].y-5);
	g.drawString("P", p[5].x-8, p[5].y+5+fontMetrics.getAscent());

	Dimension sz = getSize();
	rightmost = sz.width-8 -fontMetrics.stringWidth("C");
	topmost = fontMetrics.getAscent()+5;
	bottommost = sz.height-fontMetrics.getAscent()-5;
	leftmost = fontMetrics.stringWidth("A")+8;
    }

    public void mousePressed(MouseEvent e) {
	int x = e.getX();
	int y = e.getY();
	int dist;
	int mindist = 50000;
	int which=-1;

	int li[]={1,4,5};
	for(int j=0;j<3;j++) {
	    int i=li[j];
	    dist = (x-p[i].x)*(x-p[i].x)+(y-p[i].y)*(y-p[i].y);
	    if(dist<mindist) {
		which = i;
		mindist = dist;
	    }
	}
	if(((x-p[which].x)*(x-p[which].x)<CLICKRANGE*CLICKRANGE)&&
	((y-p[which].y)*(y-p[which].y)<CLICKRANGE*CLICKRANGE)){
	    pickedup = which;
	}
	else {pickedup = -1;}
    }
    
    public void mouseClicked(MouseEvent e) {
    }


    public void mouseReleased(MouseEvent e) {
	pickedup = -1;
    }


    public void mouseEntered(MouseEvent e) {
    }


    public void mouseExited(MouseEvent e) {
    }





    public void mouseDragged(MouseEvent e) {
	int x = e.getX();
	int y = e.getY();

	int i = pickedup;

	double palongside, qalongside;

	Dimension d = getSize();
	if(x>rightmost) {
	    x=rightmost;
	}
	else if (x<leftmost) {
	    x=leftmost;
	}

	if(y>=bottommost) {
	    y=bottommost;
	}
	else if(y<=topmost) {
	    y=topmost;
	}

	if(i==1) {
	    palongside = (p[5].x-p[3].x)/(double)(p[2].x-p[3].x);
	    qalongside = (p[4].x-p[0].x)/(double)(p[1].x-p[0].x);

	    if(x-p[0].x>=2*MINDIST) {
		p[i].x=x;
	    }
	    else {
		p[i].x=p[0].x+2*MINDIST;
	    }

	    if(p[2].y-y>=2*MINDIST){
		if(Math.abs(y-p[2].y)<Math.abs(p[i].x-p[0].x)) {
		    p[i].y=y;
		}
		else {
		    p[i].y=p[2].y-Math.abs(p[i].x-p[0].x);
		}
	    }
	    else { p[i].y = p[2].y-2*MINDIST;}


	    p[2].x=p[i].x;

	    p[0].y=p[i].y;
	    p[4].y = p[i].y;

	    p[4].x = (int)(qalongside*(p[1].x-p[0].x) +p[0].x);
	    if(p[1].x-p[4].x<MINDIST) {
		p[4].x=p[1].x-MINDIST;}
	    p[5].x = (int)(palongside*(p[1].x-p[0].x) +p[0].x);
	    if(p[2].x-p[5].x<MINDIST) {
		p[5].x=p[2].x-MINDIST;}
	}
	/*	// Got A, B, C or D
	if((0<=i) && (i<=3)) {
	    if(Math.abs(x-p[i].x)>=MINDIST) {
		p[i].x = x;
	    }
	    if(Math.abs(y-p[i].y)>=MINDIST) {
		p[i].y = y;
	    }

	    // Move P and Q accordingly
	}

	// if Q is not too close to the edges
	*/

	else if(i==4) {
	    if((x>p[0].x) && (p[1].x>x)) {
		p[i].x= x;
	    }
	    else if(x<p[0].x) {
		p[i].x=p[0].x;}
	    else if(p[1].x<x) {
		p[i].x=p[1].x;
	    }
	    if(p[1].x-x<=2*CLICKRANGE) {
		p[i].x = p[1].x-2*CLICKRANGE;
	    }
	}
	else if((i==5) ) {
	    if((x>p[3].x) && (p[2].x>x)) {
		p[i].x=x;}
	    else if(x<=p[3].x) {
		p[i].x=p[3].x;
	    }
	    else if(x>=p[2].x) {
		p[i].x=p[2].x;
	    }
	}
	Graphics g = getGraphics();
	update(g);
	    
	}

    public void mouseMoved(MouseEvent e) {

    }

}
