    // Maintain a set of Point objects representing a polygon.
    // Throw an exception if insufficient points are supplied.
    // Allow a deep-copy of the polygon to be created.
public class Polygon implements Cloneable {
    // A polygon must have at least three points.
    public static int minPoints = 3;

    public Polygon(Point[] points)
                        throws InvalidPolygonException {
        setPoints(points);
    }

        // Return a string containing the list of point details
        // held in the attribute Point[] points;
    public String toString(){
        Point[] points = getPoints();
        // Start with the first point.
        String result = "["+points[0];
        for(int i = 1; i < points.length; i++){
            // Add a separating space.
            result += " ";
            // points[i].toString() is implicitly called here:
            result += points[i];
        }
        result += "]";
        return result;
    }

        // Return true if o is a Polygon with equal Points
        // in the same order. Otherwise return false.
    public boolean equals(Object o){
        if(o == this){
            // The same object.
            return true;
        }
        else if(o == null){
            return false;
        }
        else if(o instanceof Polygon){
            Polygon p = (Polygon) o;
            // Make sure they have the same number of points.
            final int length = getNumPoints();
            if(length == p.getNumPoints()){
                final Point[] myPoints = getPoints(),
                              otherPoints = p.getPoints();
                for(int i = 0; i < length; i++){
                    if(!myPoints[i].equals(otherPoints[i])){
                        // Mismatch.
                        return false;
                    }
                }
                // No failure, so a complete match.
                return true;
            }
            else{
                return false;
            }
        }
        else{
            return false;
        }
    }
    
    public Object clone(){
        try{
            // Create a basic shallow copy.
            Polygon p = (Polygon) super.clone();
            // Replace p's shallow copy of points with a deep copy
            // that is returned by getCopyPoints.
            p.setPoints(getPointsCopy());
            return p;
        }
        catch(CloneNotSupportedException e){
            // This should never happen!
            throw new Error("Cloning error in Polygon: "+e);
        }
    }
    
        // Return a deep copy of the Point data.
    public Point[] getPointsCopy(){
        // Clone the array.
        Point[] copy = (Point[]) getPoints().clone();
        // Clone the points.
        final int numPoints = getNumPoints();
        for(int i = 0; i < numPoints; i++){
            copy[i] = (Point) points[i].clone();
        }
        return copy;
    }

    public int getNumPoints(){
        return points.length;
    }

    public Point[] getPoints(){
        return points;
    }

    private void setPoints(Point[] p){
        if(p != null){
            points = p;
        }
    }

    private Point[] points;
}
