/*
 * This file is part of Jstacs.
 * 
 * Jstacs is free software: you can redistribute it and/or modify it under the
 * terms of the GNU General Public License as published by the Free Software
 * Foundation, either version 3 of the License, or (at your option) any later
 * version.
 * 
 * Jstacs is distributed in the hope that it will be useful, but WITHOUT ANY
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
 * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License along with
 * Jstacs. If not, see <http://www.gnu.org/licenses/>.
 * 
 * For more information on Jstacs, visit http://www.jstacs.de
 */

package de.jstacs.utils;

/**
 * A simple list of primitive type <code>int</code>.
 * 
 * @author Jens Keilwagen
 */
public final class IntList implements Cloneable {

	private int size;

	private int[] array;

	/**
	 * This is the default constructor that creates an {@link IntList} with
	 * initial length 10.
	 */
	public IntList() {
		this( 10 );
	}

	/**
	 * This is the default constructor that creates an {@link IntList} with
	 * initial length <code>size</code>.
	 * 
	 * @param size
	 *            the initial size, has to be positive
	 * 
	 * @throws IllegalArgumentException
	 *             if <code>size</code> is less than 1
	 */
	public IntList( int size ) throws IllegalArgumentException {
		super();
		if( size <= 0 ) {
			throw new IllegalArgumentException( "The size has to be positive." );
		}
		this.size = 0;
		array = new int[size];
	}
	
	public IntList clone() throws CloneNotSupportedException {
		IntList clone = (IntList) super.clone();
		clone.array = array.clone();
		return clone;
	}

	/**
	 * Adds the element <code>val</code> at the end of the list.
	 * 
	 * @param val
	 *            the element that should be inserted
	 */
	public void add( int val ) {
		if( array.length == size ) {
			int[] help = new int[2 * array.length];
			System.arraycopy( array, 0, help, 0, size );
			array = help;
		}
		array[size++] = val;
	}

	/**
	 * Removes all elements from the list.
	 */
	public void clear() {
		size = 0;
	}

	/**
	 * Returns the element with the specified <code>index</code>.
	 * 
	 * @param index
	 *            the specified index of the element to return
	 * 
	 * @return the corresponding element
	 */
	public int get( int index ) {
		if( index < size ) {
			return array[index];
		} else {
			throw new ArrayIndexOutOfBoundsException( index );
		}
	}

	/**
	 * Returns the number of inserted elements.
	 * 
	 * @return the number of inserted elements
	 */
	public int length() {
		return size;
	}

	/**
	 * This method returns an <code>int</code> array containing all elements of
	 * the list.
	 * 
	 * @return an <code>int</code> array containing all elements of the list
	 */
	public int[] toArray() {
		int[] res = new int[size];
		System.arraycopy( array, 0, res, 0, size );
		return res;
	}
	
	/**
	 * This method reverses the list, i.e., after invoking this method the formerly
	 * first element is than the last, the formerly second element is than the last but one, ... 
	 */
	public void reverse() {
		int i = 0, n = size/2, help;
		while( i < n ) {
			help = array[i];
			array[i] = array[size-1-i];
			array[size-1-i++] = help;
		}
	}
}
