package ovm.util;

import java.io.Serializable;

import ovm.core.OVMBase;


public class S3Set extends OVMBase {
    //---------------------i vars ---------------------

    private IHTObject set;
    private Filter idFilter = new Filter() {
            public Object visit(Object o) { return o;}
        };
    private Filter filter = idFilter;

    // --------------- constructors -------------------
    public S3Set() {
	set = new IHTObject();
    }
    public S3Set(int expectedSize) {
	set = new IHTObject(expectedSize);
    }
    public S3Set(IHTObject set) {
	this.set = set;
    }
    public S3Set(Set hs) {
	this(hs.size());
        Iterator it = hs.iterator();
        while (it.hasNext())
            add(it.next());
    }
    public S3Set(Object[] v) {
	this(v.length);
        int size = v.length;
        for (int i = 0; i < size;)
            add(v[i++]);
    }
    //----------------- i methods ---------------------

    public void add(Object o) { set.add(o); }
    public void registerFilter(Filter f) { this.filter = f;  }
    public void clearFilters() { filter = idFilter; }
    public boolean contains(Object o) { return set.contains(o); }
    public void union(S3Set other) {
	set.addAll(other.set);
    }
    public S3Set copy() {
        S3Set newset = new S3Set();
        IHTObject.Iterator iter = set.getIterator();
        while (iter.hasNext()) {
            Object o = filter.visit(iter.next());
            if (o != null)
                newset.add(o);
        }
        return newset;
    }
    public S3Set filteredCopy(Filter f) {
        S3Set newset = new S3Set();
        IHTObject.Iterator iter = set.getIterator();
        while (iter.hasNext()) {
            Object o = f.visit(filter.visit(iter.next()));
            if (o != null)
                newset.add(o);
        }
        return newset;
    }
    public int size() { return set.size(); }
    public void forAllFiltered(Filter f, Visitor v) {
        registerFilter(f); forAll(v); clearFilters();
    }
    public void forAll(Visitor v) {
        IHTObject.Iterator iter = set.getIterator();
        while (iter.hasNext()) {
            Object o = filter.visit(iter.next());
            if (o != null)
                v.visit(o);
        }
    }
    public void dumpCollisions() {
	set.dumpCollisions();
    }

    public void addAll(Collection collection) {
	for (Iterator i = collection.iterator(); i.hasNext(); ) {
	    this.add(i.next());
	}
    }

    public static interface Visitor extends Serializable { void visit(Object o); }
    public static interface Filter extends Serializable { Object visit(Object o); }

    public String toString() {
	IHTObject.Iterator itr = set.getIterator();
	int size = size();
	String r = "[";
	for (int pos = 0; pos < size; pos++) {
	    r += itr.next();
	    if (pos < size - 1)
		r += ", ";
	}
	r += "]";
	return r;
    }

} // End of S3Set
