import java.io.*;
import java.util.Vector;

/** Space maintains a collection of Points, and a current view point. 
 *  The points in space can be ordered by their distance from the current view
 *  point.
 */

public class Space {
    private Vector points;
    private Point view;
	
    public Space(){
	points = new Vector();
    }

    /**
     * Create 3d viewpoint.
     * @param x	
     * @param y
     * @param z
     */
    public void setView(int x, int y, int z) {
	view = new Point(x, y, z);
    }

    /**
     * Set the view point to be p.
     * @param p The new view point.
     */
    public void setView(Point p) {
	view = p;
    }
	
	
    /**
     * Get the point at position i in the collection ordered by
     * the current view point.
     * @param i The position of the point to retrieve.
     * @return The point found at position i, or null if i is not a valid
     * position.
     */
    public Point get(int i) {
	if(i < 0 || i > points.size()) {
	    return null;
	} else {
	    return (Point)points.get(i);
	}
    }
	
    /**
     * Create a string represenation of the object where the
     * collection is given in order of a point's distance from
     * the view point.
     * @return The string representation of the collection.
     */
    public String toString() {
	order();
	String result = ("View point: " + view + "\n");
	for(int i = 0; i < points.size(); i++) {
	    result += "(" + points.get(i) + ") ";
	}
	return result;
    }
	
    /**
     * Print the list of points that are in the same kth plane as
     * point p.
     * @param p The point to compare to.
     * @param k The index of the plane to report on.
     */
	 
    public Vector samePlane(int k) {
	Vector v = new Vector();
	for(int i = 0; i < points.size(); i++) {
	    if(view.sameDimension((Point)points.get(i), k)) {
		//System.out.println("View = " + view);
		//System.out.println("Point = " + (Point)points.get(i));
		v.add(points.get(i));
	    }
	}
	return v;
    }

    /**
     * Add Point p to this space.
     * @param p The point to add.
     */
    public void addPoint(Point p){
	points.add(p);
    }
	
    // sorts the points
    /** Sort the points in order of distance from the viewpoint.
     * Original source of the code is given below.
     *
     * A bubble sort demonstration algorithm 
     * SortAlgorithm.java, Thu Oct 27 10:32:35 1994 * 
     * @author James Gosling * @version 1.6, 31 Jan 1995 * 
     * Modified 23 Jun 1995 by Jason Harrison@cs.ubc.ca: 
     * Algorithm completes early when no items have been swapped in the 
     * last pass. 
     */ 
    public void order() {
	
	for (int i = points.size()-1; i >= 0; i--) { 
	    boolean flipped = false; 
	    for (int j = 0; j<i; j++) { 
		if (((Point)points.get(j)).distanceFrom(view) > 
		    ((Point)points.get(j+1)).distanceFrom(view)) { 
		    Point T = (Point)points.remove(j); 
		    points.add(j+1, T); 
		    flipped = true; 
		} 
	    } 
	    if (!flipped) { 
		return; 
	    } 
	}
    }

    /**
     * Print the list of points.
     * @param ps The PrintStream to print to.
     */
    public void printPoints(PrintStream ps) throws IOException {
	for(int i = 0; i < points.size(); i++) {
	    ps.println(points.get(i));		
	}		
    }

}
