package  com.db4o.lib;

/**
 * The db4o collection is very similar to JDK 2 java.util.Collection.
 * The db4o collection will implement java.util.Collection in a coming release.
 * There is one difference to be noted: toArray(Object[])
 */
public class Collection implements Cloneable {
    protected Object i_first;					// First element of the linked list
    protected int i_size = 0;					// Number of elements collected

    /**
     * @param a_object
     */
    public final void add (Object a_object) {
        Object temp = i_first;
        i_first = new LinkedListObject((LinkedListObject)i_first,a_object);
        i_size++;
    }

    /**
     * @param a_objects
     */
    public void add (Object[] a_objects) {
        if (a_objects != null) {
            for (int i = 0; i < a_objects.length; i++) {
                add(a_objects[i]);
            }
        }
    }

    /**
     * @param a_Collection
     */
    public void addAll (Collection a_Collection) {
        addAll(a_Collection.iterator());
    }
	
    /**
     * Adds objects, if they are not present in the collection.
     * The equality test uses equals()
     * @param object
     */
	public void addUnique (Object object){
		Iterator i = iterator();
		while(i.hasNext()){
			if(i.next().equals(object)){
				return;
			}
		}
	}

	
    /**
     * @param a_Iterator
     */
    public void addAll (Iterator a_Iterator) {
        a_Iterator.reset();
        while (a_Iterator.hasNext()) {
            add(a_Iterator.next());
        }
    }

    /**
     */
    public void clear () {
        i_first = null;
        i_size = 0;
    }

    /**
     * deep clone
     * @return
     */
    public Object clone () {
        Collection collection = new Collection();
        collection.i_size = i_size;
        if (i_first != null) {
            collection.i_first = ((LinkedListObject)i_first)._clone();
        }
        return  collection;
    }

    /**
     * @param a_Object
     * @return
     */
    public boolean contains (Object a_Object) {
        Iterator i = iterator();
        while (i.hasNext()) {
			if (a_Object.equals(i.next())){
				return true;
			}
        }
        return  false;
    }

    /**
     * @param a_collection
     * @return
     */
    public boolean containsAll (Collection a_collection) {
        Iterator i = a_collection.iterator();
        while (i.hasNext()) {
            if (!(contains(i.next()))) {
                return  false;
            }
        }
        return  true;
    }

    /**
     * @return
     */
    Object getFirst () {
        return  i_first;
    }

    /**
     * @return
     */
    public boolean isEmpty () {
        return  !(size() > 0);
    }

    /**
     * @return
     */
    public Iterator iterator () {
		return  new LinkedListIterator(this, i_first);
    }

    /**
     * @param a_Equals
     */
    public void remove (Object a_Equals) {
        Iterator i = iterator();
        while (i.hasNext()) {
			if (a_Equals.equals(i.next())){
				i.remove();
			}
        }
    }

    /**
     * @param a_object
     */
    void setFirst (Object a_object) {
        i_first = a_object;
    }

    /**
     * @return
     */
    public int size () {
        return  i_size;
    }

    void sizeDecrement () {
        i_size--;
    }

    /**
     * @return
     */
    public Object[] toArray () {
        // TODO: If int is exceeded throw Exception
        // Backwards, because our sort is also backwards
        int j = (int)i_size;
        Object[] l_Objects = new Object[j];
        Iterator i = iterator();
        while (i.hasNext()) {
            l_Objects[--j] = i.next();
        }
        return  l_Objects;
    }

    /**
	 * Copies all objects in the collection to the passed array and returns it.
	 * There is a difference to JDK 1.2 Collection here.
	 * To avoid the necessity for reflection, the passed array has to be created to
	 * the size of the collection.
     * @param Object[]
     * @return
     */
    public Object[] toArray (Object[] a_array) {
        // this is the non reflection version, in contrast to suns implementation
        // the passed array has to be initialized to the right length
        int j = (int)i_size;
        Iterator i = iterator();
        while (i.hasNext()) {
            a_array[--j] = i.next();
        }
        return  a_array;
    }
}



