import java.awt.*;

class MMpoly extends Panel {

    private final double pi_2 = Math.PI/2, pi = Math.PI;
    Graphics g;
//  private int lastx, lasty, x, y; 
    public boolean drawing;
    public MMdata temp;
    // which way the polygon is turning (reject or accept point)
    private int turn;
    public String name;

    MMpoly (String name) {
	this.name = name;
	temp = new MMdata();
	drawing = false;
	g = getGraphics();
    }

    public boolean mouseDown(Event e, int x, int y) {
//	System.out.println("x = "+Integer.toString(x)+" and y = "+Integer.toString(y)+
//		   " and drawing is "+(drawing?"true":"false"));
	if (!drawing) {
//	    System.out.println("I would if i could but i cannot i know (press the button)"); 
	} else {
//		System.out.println("Before repaint() echs (x) = "+Integer.toString(echs)+"("+Integer.toString(x)+") and wai(y) ="+
//		Integer.toString(wai)+"("+Integer.toString(y)+") lastx = "+Integer.toString(lastx)+" lasty = "+Integer.toString(lasty));

	    temp.addPoint(new MMpoint (x, y));

	    //
	    // to enforce convexity make point first and check angle is greater than last one
	    //
/*	    MMpoint p = new MMpoint (x, y); 
	    if (temp.size()<=2) { 
		temp.addPoint(p);
		if (temp.size()==3) {
		    if (temp.normalAt(1).getAngle()-temp.normalAt(0).getAngle() >= 0) turn = 1; else turn = -1;
    //		    System.out.println("First angle is "+Float.toString(temp.normalAt(0).getAngle())+" and turn = "+Integer.toString(turn));
		}	    
	    } else {
		MMnormal vec0 = new MMnormal(temp.pointAt(temp.size()-1), p); 
		MMnormal vec1 = new MMnormal(p, temp.pointAt(0));
		
		double angle0 = vec0.getAngle() - temp.normalAt(temp.size()-2).getAngle();
		double angle1 = vec1.getAngle() - vec0.getAngle();
		double angle2 = temp.normalAt(0).getAngle() - vec1.getAngle(); 
	    
		if (//angle0>=-Math.PI/2 && angle0 <= Math.PI/2 &&
//		    angle1>=0 && angle1 <= Math.PI &&
//		    (angle2 >= 3*pi_2 || (angle2 <= pi && angle2 >= pi_2))
		    turn * angle2 <= 0
		    ) {
//	    	    System.out.println("Adding point with angle 0 = "
//			+Float.toString(angle0)+" angle 1 = "+Float.toString(angle1)+" angle 2 = "+Float.toString(angle2)); 
		    System.out.println("Adding it coz angle 2 is "+Float.toString(angle2)); 
		    temp.addPoint(p);
		}
		else 
//		    System.out.println("Wouldn't be convex coz angles are: angle 0 = "
//			+Float.toString(angle0)+" angle 1 = "+Float.toString(angle1)+" angle 2 = "+Float.toString(angle2)); 
		    System.out.println("Wouldn't be convex coz angle 2 is "+Float.toString(angle2)); 
		}
	    */
	    	    
//	    System.out.println("After repaint() echs (x) = "+Integer.toString(echs)+"("+Integer.toString(x)+") and wai(y) ="+
//		Integer.toString(wai)+"("+Integer.toString(y)+") lastx = "+Integer.toString(lastx)+" lasty = "+Integer.toString(lasty));
//	    drawing = false; 
	    repaint();
	} 
	return true;
    }

    public void paint(Graphics g) {
	g.setColor(Color.black);

        if (temp.size() == 0) {
	  drawing = true; 
	}
	
	if (name.equals("Current")) {
	    centerData();
	    drawing = false;
//	    drawDataBounds(g);
	}
	
//      System.out.println("About to call g.drawLine (lastx, lasty, echs, wai) = ("+Integer.toString(lastx)+", "+Integer.toString(lasty)+", "+Integer.toString(echs)+", "+Integer.toString(wai)+")");
	if (temp.size() > 1) { 
	    MMpoint p1, p2;
//	    drawDataBounds(g);
	    for (int i = 0; i<temp.size()-1; i++) {
		connectPoints(g, temp.pointAt(i), temp.pointAt(i+1));
		drawNormal(g, temp.normalAt(i), temp.pointAt(i), temp.pointAt(i+1));
	    }
	    // handle the last segment
	    if (!drawing) {
		// drawing is false == user is done drawing
		// always connect the last segment
	      //		connectPoints(g, Color.magenta, temp.pointAt(temp.size()-1), temp.pointAt(0)); 
	      	connectPoints(g, temp.pointAt(temp.size()-1), temp.pointAt(0)); 
		drawNormal(g, temp.normalAt(temp.size()-1), temp.pointAt(temp.size()-1), temp.pointAt(0));
		g.setColor(Color.black);
		g.drawString(name+" Polygon", 5, 12);
	    } else {
		// drawing is true == user is still drawing
		g.setColor(Color.red);
		g.drawString("Press Set "+name+" When Done", 5, 12);
	    }    
	} else {
	    // there's enough points to draw it
	    g.setColor(Color.black);
	    if (!name.equals("Current")) 
		g.drawString("Click to Enter Points", 5, 12);
	    else 
		g.drawString("Current Polygon", 5, 12);
	}
    }

    private void connectPoints(Graphics g, MMpoint p1, MMpoint p2) {
	g.setColor(Color.black);
	g.drawLine((int) p1.x, (int) p1.y, (int) p2.x, (int) p2.y);
    }

    private void connectPoints(Graphics g, Color c, MMpoint p1, MMpoint p2) {
	g.setColor(c);
	g.drawLine((int) p1.x, (int) p1.y, (int) p2.x, (int) p2.y);
    }

    private void drawNormal (Graphics g, MMnormal vec, MMpoint p1, MMpoint p2) {
	MMpoint origin = new MMpoint((p1.x+p2.x)/2, (p1.y+p2.y)/2);
	MMpoint dest = new MMpoint(origin.x + (float).1*vec.x, origin.y + (float).1*vec.y);
	g.setColor(Color.red);
	g.drawLine((int) origin.x, (int) origin.y, (int) dest.x, (int) dest.y);
    }

    private void drawDataBounds(Graphics g) {
	g.setColor(Color.magenta);
	g.drawRect(temp.getBounds().x, temp.getBounds().y, temp.getBounds().width, temp.getBounds().height);
    }
    
    public boolean handleEvent(Event evt) {
	return super.handleEvent(evt);
    }

    public void clear () {
	getGraphics().setColor(this.getBackground());
	getGraphics().fillRect(0,0,bounds().width,bounds().height);
    }
    
    public void showWarning (String s) {
	getGraphics().setColor(Color.red); 
	getGraphics().drawString(s, 5, bounds().height-3);
    }
    
    public void centerData () {
	temp.centerIn(new Rectangle(0, 0, bounds().width, bounds().height));
    }    
}
