package Geometry;
import java.util.Vector;

/**
 * Class to represent an arbitrary hull in 3D.
 * Written by Chris Studholme
 * Licenced for redistribution under the GNU General Public Licence
 */
public class Hull {

    /** Some facet to use as starting point to find all facets.
     */
    protected Facet face;

    /** Default constructor.
     */
    protected Hull() {
    }

    /**
     * Construct a copy of an existing Hull object.  All facets and edges
     * are copied to ensure that this new hull can be modified without
     * changing the original.
     * @param other some other hull
     */
    public Hull(Hull other) {
	Facet[] facets = other.getFacets();
	// create copies
	for (int i=0; i<facets.length; ++i)
	    facets[i] = new Facet(facets[i]);
	face=facets[0];
	// connect them all up
	for (int i=0; i<facets.length; ++i)
	    for (int j=i+1; j<facets.length; ++j)
		facets[i].connectTo(facets[j]);
    }

    /**
     * Enumerate all facets starting with face.
     * @return array of facets
     */
    public Facet[] getFacets() {
	Vector v = new Vector();
	addFacet(v,face);
	Facet[] result = new Facet[v.size()];
	return (Facet[])v.toArray(result);
    }

    /**
     * Recursive algorithm to enumerate facets.
     * @param v vector to add facet
     * @param face facet to add to v
     */
    private static void addFacet(Vector v, Facet face) {
	v.add(face);
	// find all neighbouring faces
	HalfEdge e=face.outer;
	do {
	    if ((e.twin!=null)&&
		(e.twin.facet!=null)&&
		(!v.contains(e.twin.facet)))
		addFacet(v,e.twin.facet);
	    e=e.next;
	} while (e!=face.outer);
    }

    /**
     * General method to swap two elements of an array.
     * @param array some array
     * @param i1 index of first object
     * @param i2 index of second object
     */
    protected static void swap(Object[] array, int i1, int i2) {
	Object o = array[i1];
	array[i1] = array[i2];
	array[i2] = o;
    }


}
