/**
 * DynamicIntArray
 * 
 * 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 byte.
 * (basically taken from http://www.javaworld.com/javaworld/jw-08-1999/jw-08-cooltools-p2.html)
 *
 */
public class DynamicByteArray implements Serializable {
        int sp = 0; // Array position
        private byte[] array;
        private int growthSize;     
         
        /**
         * Default constructor. Creates an array
         * with initial size 1024 and growth size 256.
         */
        public DynamicByteArray()
        {
            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 DynamicByteArray( 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 DynamicByteArray( int initialSize, int growthSize )
        {
            this.growthSize = growthSize;
            array = new byte[initialSize];
        }
        
        /**
         * Adds a value at the end of the array.
         * 
         * @param elem the primitive <code>byte</code> to be added.
         */
        public void add(byte elem)
        {
            if( sp >= array.length ) // time to grow!
            {
                byte[] tmpArray = new byte[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(byte[] 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;
            
            byte[] trimmedArray = new byte[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 byte values.
         */
        public byte[] getArray() {
            return array;
        }
        
        /**
         * Returns the trimmed array (only containing the added
         * elements).
         * 
         * @return The trimmed array containing only the added
         * elements.
         */
        public byte[] 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;
        }
}
