/**
 * DynamicBooleanArray
 * 
 * Author: Jakob Svensson (2007)
 * 
 * But: almost completely copied from
 * http://www.javaworld.com/javaworld/jw-08-1999/jw-08-cooltools-p2.html 
 * 
 */

package algorithmrepository;


import java.io.Serializable;


/**
 * Implemements a dynamic array (that can change size) of the primitive int.
 * (basically taken from http://www.javaworld.com/javaworld/jw-08-1999/jw-08-cooltools-p2.html)
 *
 */
public class DynamicBooleanArray implements Serializable {
	    int sp = 0; // Array position
	    private boolean[] array;
	    private int growthSize;	    
	     
	    /**
	     * Default constructor. Creates an array
	     * with initial size 1024 and growth size 256.
	     */
	    public DynamicBooleanArray()
	    {
	        this(1024);
	    }

	    /**
	     * Constructs a dynamic array with a
	     * given initial size, and a growth size of a fourth
	     * of the initial size.
	     * 
	     * @param initialSize The initial size of the array.
	     */
	    public DynamicBooleanArray( int initialSize )
	    {
	        this(initialSize, (int)(initialSize/4));
	    }
	    
	    /**
	     * Constructs a dynamic array with a
	     * given initial size and growth size.
	     * 
	     * @param initialSize The initial size of the array.
	     * @param growthSize The size with which the array
	     * is expanded when writing over the upper bound.
	     */	    
	    public DynamicBooleanArray( int initialSize, int growthSize )
	    {
	        this.growthSize = growthSize;
	        array = new boolean[initialSize];
	    }
	    
	    /**
	     * Adds a value at the end of the array.
	     * 
	     * @param elem the primitive <code>double</code> to be added.
	     */
	    public void add(boolean elem)
	    {
	        if( sp >= array.length ) // time to grow!
	        {
	            boolean[] tmpArray = new boolean[array.length + growthSize];
	            System.arraycopy(array, 0, tmpArray, 0, array.length);
	            array = tmpArray;
	        }
	        array[sp] = elem;
	        sp += 1;
	    }
	    
        /**
         * Adds the given array at the end of the dynamic array.
         * 
         * @param elems the primitives <code>double</code> to be added.
         */
        
        public void addAll(boolean[] elems) {
            for(int i=0;i<elems.length;++i) add(elems[i]);
        }


	    /**
	     * Trims the array so that the stored array contains only
	     * elements up to the last added with add().
	     */
	    public void trim()
	    {
	    	if (array.length == sp) return;
	    	
	    	boolean[] trimmedArray = new boolean[sp];
	        System.arraycopy(array, 0, trimmedArray, 0, trimmedArray.length );
	        array = trimmedArray;	        
	    }
	    
	    /**
	     * Returns the raw array of values. To get an array 
	     * corresponding to the number of actually allocated elements,
	     * call {@link #trim() trim()} before
	     * this method is called.
	     * 
	     * @return The raw array of double values.
	     */
	    public boolean[] getArray() {
	    	return array;
	    }
	    
	    /**
	     * Returns the trimmed array (only containing the added
	     * elements).
	     * 
	     * @return The trimmed array containing only the added
	     * elements.
	     */
	    public boolean[] getTrimmedArray() {
	    	trim();
	    	return getArray();
	    }
	    
	    /**
	     * Returns the size the array.
	     * This value is the number of actual elements stored
	     * in the array, not neccessarily its current allocated size.
	     * 
	     * @return The size of the array.
	     */
	    public int size() {
	    	return sp;
	    }
	    
	    /**
	     * Resets the dynamic array so that the size is zero and the next element
	     * added is stored in the 0th position. Does not free the internal array.
	     *
	     */
	    public void reset() {
	        sp = 0;
	    }
}
