/*
 * @author Ranides Atterwim <ranides@gmail.com>
 * @copyright Ranides Atterwim
 * @license WTFPL
 * @url http://ranides.net/projects/assira
 */
package net.ranides.assira.collection.sets;

import java.util.Set;
import net.ranides.assira.collection.AIntCollection;
import net.ranides.assira.collection.IntCollection;
import net.ranides.assira.collection.iterators.IntIterator;

/**
 * An abstract base class for sets of primitive int values. 
 * Designed to avoid autoboxing.
 */
public abstract class AIntSet extends AIntCollection implements IntSet, java.io.Serializable {
    
    private static final long serialVersionUID = 1L;

    protected AIntSet() {
        // do nothing
    }
    

    @Override
    public boolean equals(Object other) {
        if (other == this) {
            return true;
        }
        if (!(other instanceof Set)) {
            return false;
        }
        Set<?> oset = (Set<?>) other;
        if (oset.size() != size()) {
            return false;
        }
        if(other instanceof IntCollection) {
            return containsAll((IntCollection)other);
        }
        return containsAll(oset);
    }

    /**
     * Returns a hash code for this set.
     *
     * The hash code of a set is computed by summing the hash codes of its
     * elements.
     *
     * @return a hash code for this set.
     */
    @Override
    public int hashCode() {
        int h = 0, n = size();
        IntIterator itr = iterator();
        while (n-- != 0) {
            h += itr.nextInt();
        }
        return h;
    }

    @Override
    public boolean remove(int k) {
        throw new UnsupportedOperationException();
    }

    @Override
    public boolean rem(int k) {
        return remove(k);
    }

    @Override
    public boolean remove(Object value) {
        return value instanceof Integer ? remove(((Integer) value).intValue()) : false;
    }
    
    @Override
    public String toString() {
        IntIterator itr = iterator();
        if ( !itr.hasNext() ) {
            return "{}";
        }
        StringBuilder builder = new StringBuilder();
        builder.append('{');
        for (;;) {
            builder.append(itr.nextInt());
            if ( !itr.hasNext() ) {
                return builder.append('}').toString();
            }
            builder.append(", ");
        }
    }
}
