/* @(#)IntArrayList.java   31 October 2005 */

/**
 * An IntArrayList is a list that will store int data that may
 * be added only by append operations.  Internally, the list uses
 * a linked list of nodes each with an int[] of a fixed capacity.
 * 
 * An IntArrayList can supply an IntArrayListIterator for traversal.
 */
public class IntArrayList
{
    public static final int DEFAULT_CAPACITY = 16;
    
    IntArrayListNode head = null;
    
    IntArrayListNode tail = null;
    
    int length = 0;
    
    int capacity = DEFAULT_CAPACITY;
    
    
    /**
     * The default constructor that produces an empty list
     * with the default array capacity.
     */
    public IntArrayList() {
        head = tail = new IntArrayListNode(DEFAULT_CAPACITY);
    };
    
    
    /**
     * The constructor that produces a list with the default
     * array capacity and initial number.
     */
    public IntArrayList(int number) {
        append(number);
    }
    
    
    /**
     * The constructor that produces a list with the default
     * array capacity and initial numbers appended in order.
     */
    public IntArrayList(int[] numbers) {
        append(numbers);
    }
    
    
    /**
     * The constructor that produces a list with the given
     * array capacity and initial number.
     */
    public IntArrayList(int capacity, int number) {
        setCapacity(capacity);
        append(number);
    }
    
    
    /**
     * The constructor that produces a list with the given
     * array capacity and initial numbers appended in order.
     */
    public IntArrayList(int capacity, int[] numbers) {
        setCapacity(capacity);
        append(numbers);
    }
    
    
    /**
     * Appends the given number to the list.
     * 
     * This operation is done in constant time
     * independent of the current length of the list.
     */
    public void append(int number) {
        if (head == null) {
            head = tail = new IntArrayListNode(capacity, number);
        }
        else {
            tail = tail.append(number);
        }
        
        length++;
    }
    
    
    /**
     * Appends the given numbers to the list in order.
     * 
     * This operation is done in time proportional to
     * the number of items being added
     * independent of the current length of the list.
     */
    public void append(int[] numbers) {
        if (numbers == null)
            return;
        
        int n = numbers.length;
        
        for (int i = 0; i < n; i++)
            append(numbers[i]);
    }
    
    
    /**
     * Returns the number of data items in the list.
     */
    public int getLength() {
        return length;
    }
    
    
    /**
     * Returns the IntArrayListNode that forms the head of
     * the internal list structure.
     */
    public IntArrayListNode getHead() {
        return head;
    }
    
    
    /**
     * Returns a new iterator to traverse the list.
     */
    public IntArrayListIterator newIterator() {
        return new IntArrayListIterator(this);
    }
    
    
    /**
     * Sets the array capacity.
     */
    private void setCapacity(int capacity) {
        if (capacity < 1)
            capacity = 1;
        
        this.capacity = capacity;
    }
}
