package eworks.RDF.model;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

/**
 * <p>An abstract base class for implementations of the {@link Tuples} interface.
 * Represents a set of tuples and provides methods to manage instances that implement
 * the {@link Tuple} interface.</p>
 * 
 * <p>This implementation does not support the grouping of tuples as defined by
 * the methods {@link Tuples#getNumberOfGroups} and {@link Tuples#getTuplesByGroup},
 * derive classes should overwrite this methods, if they need real tuple grouping.</p>

 * @author Fabian Wleklinski (<a href="mailto:fabian@wleklinski.de">fabian@wleklinski.de</a>)
 * @version 1.00 (2003-11-03)
 */
public abstract class AbstractTuples extends ArrayList implements Tuples {

	/**
	 * Creates a new and empty set of tuples.
	 */
	public AbstractTuples() {
		super();
	}

	/**
	 * Creates a new and empty set of tuples with a given initial capacity.
	 * 
	 * @param initialCapacity The initial capacity.
	 */
	public AbstractTuples(int initialCapacity) {
		super(initialCapacity);
	}

	/**
	 * Creates a new set of tuples and initializes it with a given set of tuples.
	 * 
	 * @param c The set of tuples to initialize the new tuple set.
	 */
	public AbstractTuples(Collection c) {
		super(c);
	}

	/**
	 * Adds the {@link Tuple} <code>t</code>. The tuples is added even if it
	 * is already contained, so it can be contained multiple times.
	 * 
	 * @param t The tuple to add.
	 * @return <code>true</code> if and only if the set of tuples has changed.
	 */
	public boolean add(Tuple t) {
		return super.add(t);
	}
	
	/**
	 * Returns the number of tuple goups, always 1 in this implementation.
	 * 
	 * @return The number of tuple groups, always 1.
	 */
	public int getNumberOfGroups() {
		return 1;
	}
	
	/**
	 * Returns all tuples of a certain tuple group.
	 * 
	 * @param groupIndex The group's numerical index, has to be the value 1 in
	 *        this implementation.
	 * @return All tuples of the tuple group, that are all tuples that are
	 *         enclosed.
	 * @throws ArrayIndexOutOfBoundsException if the <code>groupIndex</code>
	 *         is unequal to 1.
	 */
	public Tuples getTuplesByGroup( int groupIndex ) {
		if (groupIndex != 0)
			throw new ArrayIndexOutOfBoundsException();
		
		return this;
	}

	/**
	 * Adds all tuples that are contained inside the given collection <code>c</code>.
	 * 
	 * @param c The tuples to add.
	 * @param distinct If set to <code>true</code>, there will no duplicates be added.
	 * @return <code>true</code> if and only if at least one tuple was added.
	 */
	public boolean addAll(Collection c, boolean distinct) {
		if (distinct && this.size() > 0) {
			Iterator i = c.iterator();
			Tuple t;
			boolean result = false;
			while (i.hasNext()) {
				if (! this.contains(t = (Tuple) i.next())) {
					this.add(t);
					result = true;
				}
			}
			return result;
		} else {
			return super.addAll(c);
		}
	}
	
	/**
	 * Returns a certain tuple specified by it's numerical index.
	 * 
	 * @param index The numerical index of the tuple to return.
	 * @return The tuple with the given <code>index</code>.
	 * @throws ArrayIndexOutOfBoundsException if this tuple does not exist,
	 *         see {@link #size()}.
	 */
	public Tuple getTuple(int index) {
		return (Tuple) super.get(index);
	}
}
