/*
 * Copyright (C) 2004 TiongHiang Lee
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not,  write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 * Email: thlee@onemindsoft.org
 */

package org.onemind.commons.java.datastructure;

/**
 * Represents a list of long
 * @author TiongHiang Lee (thlee@onemindsoft.org)
 * @version $Id: LongList.java,v 1.2 2004/08/26 12:33:16 thlee Exp $ $Name:  $
 */
public class LongList
{

    /** the initial capacity * */
    private static final int INITIAL_CAPACITY = 10;

    /** the growth rate * */
    private static final int GROW = 10;

    /** the count of longs in the list * */
    private int _count;

    /** the list * */
    private long[] _list = new long[INITIAL_CAPACITY];

    /**
     * {@inheritDoc}
     */
    public LongList()
    {
        this(INITIAL_CAPACITY);
    }

    /**
     * {@inheritDoc}
     * @param capacity initial capacity
     */
    public LongList(int capacity)
    {
        _list = new long[INITIAL_CAPACITY];
    }

    /**
     * Add a long to the list
     * @param l the long
     */
    public void add(long l)
    {
        ensureCapacity(_count + 1);
        _list[_count] = l;
        _count++;
    }

    /**
     * Get the long on index i in the list
     * @param i the index
     * @return the long
     */
    public long get(int i)
    {
        if ((i < 0) || (i >= _count))
        {
            throw new IndexOutOfBoundsException("Invalid index " + i);
        } else
        {
            return _list[i];
        }
    }

    /**
     * Add a long at index i
     * @param l the long
     * @param i the index
     */
    public void add(long l, int i)
    {
        if ((i < 0) || (i > _count))
        {
            throw new IndexOutOfBoundsException("Invalid index " + i);
        } else if (i == _count)
        {
            add(l);
        } else
        {
            ensureCapacity(_count + 1);
            for (int j = _count; j > i; j--)
            {
                _list[j] = _list[j - 1];
            }
            _count++;
            _list[i] = l;
        }
    }

    /**
     * ensure the capacity of the long
     * @param size the size
     */
    private void ensureCapacity(int size)
    {
        if (_list.length < size)
        {
            long[] newlist = new long[_list.length + GROW];
            for (int i = 0; i < _list.length; i++)
            {
                newlist[i] = _list[i];
            }
            _list = newlist;
        }
    }

    /**
     * Remove the long at index i
     * @param i the index
     * @return the long at index i
     */
    public long remove(int i)
    {
        if ((i < 0) || (i >= _count))
        {
            throw new IndexOutOfBoundsException("Invalid index " + i);
        } else
        {
            long save = _list[i];
            for (int j = i; j < (_count - 2); j--)
            {
                _list[j] = _list[j + 1];
            }
            _count--;
            return save;
        }
    }

    /**
     * Return the first long in the list
     * @return the first long
     */
    public long first()
    {
        return _list[0];
    }

    /**
     * Return the last long in the list
     * @return the last long
     */
    public long last()
    {
        return _list[_count - 1];
    }
}