import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.*;


public class SimplePoly extends JFrame implements MouseListener
{
  ArrayList<Point> points = new ArrayList<Point>();// storage for points
  Point[] pointArray;
  Point origin = new Point();                      // origin

  public static void main(String[] args)
  {
    SimplePoly application = new SimplePoly();
    application.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  }

  public SimplePoly()
  {
    Toolkit toolkit = Toolkit.getDefaultToolkit();
    Dimension screenSize = toolkit.getScreenSize();
    int screenWidth = screenSize.width;
    int screenHeight = screenSize.height;
    setSize(3*screenWidth/4, 3*screenHeight/4);
    setLocation(screenWidth/8, screenHeight/8);
    setTitle("Simple Polygon");

    Container pane = getContentPane();
    pane.setBackground(new Color(0xffffcc));       // applet background
    addMouseListener(this);
    setVisible(true);
  }
  
  public void mousePressed(MouseEvent e) 
  { 
    if (e.getButton() == MouseEvent.BUTTON1)       // left button pressed
    {
      points.add(new Point(e.getX(), e.getY()));   // save the new point
      constructPoly();                              // update polygon
      repaint();                                   // display it
    }
    else if (e.getButton() == MouseEvent.BUTTON3)  // right button pressed
    {
      points.clear();                              // delete all points
      repaint();                                   // clear the screen
    }
  }

  public void constructPoly()
  {
    pointArray = points.toArray(new Point[points.size()]);
    if (pointArray.length < 3) return;
    origin.x = (pointArray[0].x + pointArray[1].x + pointArray[2].x) / 3;
    origin.y = (pointArray[0].y + pointArray[1].y + pointArray[2].y) / 3;
                                                   // an array for sorting
    Comparator<Point> c = new Comparator<Point>()  // comparator that orders
    {                                              // the points according to
      public int compare(Point p1, Point p2)       // increasing angle for
      {                                            // sorting
        double arg1 = Math.atan2(p1.y - origin.y, p1.x - origin.x);
        double arg2 = Math.atan2(p2.y - origin.y, p2.x - origin.x);
        if (arg1 < arg2) return(-1);               // compare the tangents
        else if (arg1 > arg2) return(1);
        else                                       // tangents are the same
        {                                          // compare the distances
          double dist1 = (p1.x - origin.x)*(p1.x - origin.x) +
                         (p1.y - origin.y)*(p1.y - origin.y);
          double dist2 = (p2.x - origin.x)*(p2.x - origin.x) +
                         (p2.y - origin.y)*(p2.y - origin.y);
          if (dist1 < dist2) return(-1);
          else if (dist1 > dist2) return(1);
          else return(0);
        }
      }
    };

    Arrays.sort(pointArray, c);                // MergeSort the points
//    points = removeDuplicates(ptsArray);     // remove possible duplicates
  }

  public void paint(Graphics g)
  {
    super.paint(g);
    g.setColor(Color.red);                   // draw points
    if (points.size() < 3)
      for (int i=0; i < points.size(); i++)
      {
        Point p = points.get(i);
        g.fillRect(p.x-1, p.y-1, 3, 3);
      }
    else
      for (int i=0; i < pointArray.length; i++)
      {
        Point p = pointArray[i];
        g.setColor(Color.red);
        g.fillRect(p.x-1, p.y-1, 3, 3);
        g.setColor(Color.black);
        g.drawString((i+1) + "", p.x+1, p.y+1);
      }

    if (points.size() >= 3)                  // draw poly
    {
      g.fillOval(origin.x-4, origin.y-4, 8, 8);

      g.setColor(Color.blue);                // poly color        
      Point p1 = pointArray[0];  // retrieve the staring point
      for (int i=1; i<pointArray.length; i++)
      {
        Point p2 = pointArray[i];
        g.drawLine(p1.x, p1.y, p2.x, p2.y);
        p1 = p2;
      }
      g.drawLine(p1.x, p1.y, pointArray[0].x, pointArray[0].y);
    }
  }

  public void mouseEntered(MouseEvent e) { }     // empty methods needed for 
  public void mouseExited(MouseEvent e) { }      // the MouseListener
  public void mouseReleased(MouseEvent e) { }    // interface implementation
  public void mouseClicked(MouseEvent e) { }
}
