package net.phatcode.rel.utils;

import java.util.ArrayList;

/**
 * 
 */

/**
 * @author Richard Eric M. Lope
 *
 */
public class LinkedArray<T>
{

	public static final int OUT_OF_BOUNDS = -1;
	
	private ArrayList<T> elements = new ArrayList<T>();
	
	private int size;
	
	private int freeElements = 0;
	private int activeElements = 0;
	
	private int[] freeElementIndex;	
	
	public LinkedArray( int size, T e )
	{
		this.size = size;
		this.activeElements = 0;
		this.freeElements = size;
		this.freeElementIndex = new int[size];
		
		elements.ensureCapacity(size);
		
		for( int i = 0; i < size; i++ )
		{
			elements.add(e);
		}
		
		for( int i = 0; i < size; i++ )
		{
			freeElementIndex[i] = i;
		}
		
	}
	
	public int getSize()
	{
		return size;
	}
	
	public int getActiveElements()
	{
		return activeElements;
	}
	
	public T getFreeElement()
	{
		
		if( freeElements == 0 )
		{
			return null;
		}
		
		freeElements--;
		
		int index = freeElementIndex[freeElements];
		T e = elements.get( index );
		
		
		activeElements++;
		
		return e;
		
	}
	
	public int add( T e )
	{
		
		if( freeElements == 0 )
		{
			return OUT_OF_BOUNDS;
		}
		
		freeElements--;
		
		int index = freeElementIndex[freeElements];
		elements.set( index, e );
		
		
		activeElements++;
		
		return index;
		
	}
	
	public void remove( int index )
	{
		
		freeElementIndex[freeElements] = index;
   		freeElements++;
		activeElements--;
   		
	}
	
	public void reset( T e )
	{
		
		for( int i = 0; i < size; i++ )
		{
			elements.set( i, e );
		}
		
		for( int i = 0; i < size; i++ )
		{
			freeElementIndex[i] = i;
		}
	
		activeElements = 0;
		freeElements = size;
		
	}
	
	public T get( int index )
	{
		return elements.get( index );
	}
	
	public T set( int index, T e )
	{
		return elements.set( index, e );
	}
	
}
