/* ====================================================================
   Licensed to the Apache Software Foundation (ASF) under one or more
   contributor license agreements.  See the NOTICE file distributed with
   this work for additional information regarding copyright ownership.
   The ASF licenses this file to You under the Apache License, Version 2.0
   (the "License"); you may not use this file except in compliance with
   the License.  You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
==================================================================== */

package org.apache.poi.util;

/**
 * A List of int's; as full an implementation of the java.util.List
 * interface as possible, with an eye toward minimal creation of
 * objects
 *
 * the mimicry of List is as follows:
 * <ul>
 * <li> if possible, operations designated 'optional' in the List
 *      interface are attempted
 * <li> wherever the List interface refers to an Object, substitute
 *      int
 * <li> wherever the List interface refers to a Collection or List,
 *      substitute IntList
 * </ul>
 *
 * the mimicry is not perfect, however:
 * <ul>
 * <li> operations involving Iterators or ListIterators are not
 *      supported
 * <li> remove(Object) becomes removeValue to distinguish it from
 *      remove(int index)
 * <li> subList is not supported
 * </ul>
 *
 * @author Marc Johnson
 */
public class IntList
{
    private int[]            _array;
    private int              _limit;
    private static final int _default_size = 128;

    /**
     * create an IntList of default size
     */

    public IntList()
    {
        this(_default_size);
    }

    public IntList(final int initialCapacity)
    {
        _array = new int[ initialCapacity ];
        _limit = 0;
    }


    /**
     * create a copy of an existing IntList
     *
     * @param list the existing IntList
     */

    public IntList(final IntList list)
    {
        this(list._array.length);
        System.arraycopy(list._array, 0, _array, 0, _array.length);
        _limit = list._limit;
    }

    /**
     * add the specified value at the specified index
     *
     * @param index the index where the new value is to be added
     * @param value the new value
     *
     * @exception IndexOutOfBoundsException if the index is out of
     *            range (index < 0 || index > size()).
     */

    public void add(final int index, final int value)
    {
        if (index > _limit)
        {
            throw new IndexOutOfBoundsException();
        }
        else if (index == _limit)
        {
            add(value);
        }
        else
        {
            // index < limit -- insert into the middle
            if (_limit == _array.length)
            {
                growArray(_limit * 2);
            }
            System.arraycopy(_array, index, _array, index + 1,
                             _limit - index);
            _array[ index ] = value;
            _limit++;
        }
    }

    /**
     * Appends the specified element to the end of this list
     *
     * @param value element to be appended to this list.
     *
     * @return true (as per the general contract of the Collection.add
     *         method).
     */

    public boolean add(final int value)
    {
        if (_limit == _array.length)
        {
            growArray(_limit * 2);
        }
        _array[ _limit++ ] = value;
        return true;
    }

    /**
     * Appends all of the elements in the specified collection to the
     * end of this list, in the order that they are returned by the
     * specified collection's iterator.  The behavior of this
     * operation is unspecified if the specified collection is
     * modified while the operation is in progress.  (Note that this
     * will occur if the specified collection is this list, and it's
     * nonempty.)
     *
     * @param c collection whose elements are to be added to this
     *          list.
     *
     * @return true if this list changed as a result of the call.
     */

    public boolean addAll(final IntList c)
    {
        if (c._limit != 0)
        {
            if ((_limit + c._limit) > _array.length)
            {
                growArray(_limit + c._limit);
            }
            System.arraycopy(c._array, 0, _array, _limit, c._limit);
            _limit += c._limit;
        }
        return true;
    }

    /**
     * Inserts all of the elements in the specified collection into
     * this list at the specified position.  Shifts the element
     * currently at that position (if any) and any subsequent elements
     * to the right (increases their indices).  The new elements will
     * appear in this list in the order that they are returned by the
     * specified collection's iterator.  The behavior of this
     * operation is unspecified if the specified collection is
     * modified while the operation is in progress.  (Note that this
     * will occur if the specified collection is this list, and it's
     * nonempty.)
     *
     * @param index index at which to insert first element from the
     *              specified collection.
     * @param c elements to be inserted into this list.
     *
     * @return true if this list changed as a result of the call.
     *
     * @exception IndexOutOfBoundsException if the index is out of
     *            range (index < 0 || index > size())
     */

    public boolean addAll(final int index, final IntList c)
    {
        if (index > _limit)
        {
            throw new IndexOutOfBoundsException();
        }
        if (c._limit != 0)
        {
            if ((_limit + c._limit) > _array.length)
            {
                growArray(_limit + c._limit);
            }

            // make a hole
            System.arraycopy(_array, index, _array, index + c._limit,
                             _limit - index);

            // fill it in
            System.arraycopy(c._array, 0, _array, index, c._limit);
            _limit += c._limit;
        }
        return true;
    }

    /**
     * Removes all of the elements from this list.  This list will be
     * empty after this call returns (unless it throws an exception).
     */

    public void clear()
    {
        _limit = 0;
    }

    /**
     * Returns true if this list contains the specified element.  More
     * formally, returns true if and only if this list contains at
     * least one element e such that o == e
     *
     * @param o element whose presence in this list is to be tested.
     *
     * @return true if this list contains the specified element.
     */

    public boolean contains(final int o)
    {
        for (int j = 0; j < _limit; j++)
        {
            if (_array[ j ] == o)
            {
                return true;
            }
        }
        return false;
    }

    /**
     * Returns true if this list contains all of the elements of the
     * specified collection.
     *
     * @param c collection to be checked for containment in this list.
     *
     * @return true if this list contains all of the elements of the
     *         specified collection.
     */

    public boolean containsAll(final IntList c)
    {
        if (this != c)
        {
            for (int j = 0; j < c._limit; j++)
            {
                if (!contains(c._array[ j ]))
                {
                    return false;
                }
            }
        }
        return true;
    }

    /**
     * Compares the specified object with this list for equality.
     * Returns true if and only if the specified object is also a
     * list, both lists have the same size, and all corresponding
     * pairs of elements in the two lists are equal.  (Two elements e1
     * and e2 are equal if e1 == e2.)  In other words, two lists are
     * defined to be equal if they contain the same elements in the
     * same order.  This definition ensures that the equals method
     * works properly across different implementations of the List
     * interface.
     *
     * @param o the object to be compared for equality with this list.
     *
     * @return true if the specified object is equal to this list.
     */

    public boolean equals(final Object o)
    {
        if (o == this) {
            return true;
        }

        if (!(o instanceof IntList)) {
            return false;
        }

        IntList other = ( IntList ) o;

        if (other._limit != _limit) {
            return false;
        }

        for (int i=0; i< _limit; i++) {
            if (other._array[i] != _array[i]) {
                return false;
            }
        }

        return true;
    }

    /**
     * Returns the element at the specified position in this list.
     *
     * @param index index of element to return.
     *
     * @return the element at the specified position in this list.
     *
     * @exception IndexOutOfBoundsException if the index is out of
     *            range (index < 0 || index >= size()).
     */

    public int get(final int index)
    {
        if (index >= _limit)
        {
            throw new IndexOutOfBoundsException(
                  index + " not accessible in a list of length " + _limit
            );
        }
        return _array[ index ];
    }

    /**
     * Returns the hash code value for this list.  The hash code of a
     * list is defined to be the result of the following calculation:
     *
     * <code>
     * hashCode = 1;
     * Iterator i = list.iterator();
     * while (i.hasNext()) {
     *      Object obj = i.next();
     *      hashCode = 31*hashCode + (obj==null ? 0 : obj.hashCode());
     * }
     * </code>
     *
     * This ensures that list1.equals(list2) implies that
     * list1.hashCode()==list2.hashCode() for any two lists, list1 and
     * list2, as required by the general contract of Object.hashCode.
     *
     * @return the hash code value for this list.
     */

    public int hashCode()
    {
        int hash = 0;

        for (int j = 0; j < _limit; j++)
        {
            hash = (31 * hash) + _array[ j ];
        }
        return hash;
    }

    /**
     * Returns the index in this list of the first occurrence of the
     * specified element, or -1 if this list does not contain this
     * element.  More formally, returns the lowest index i such that
     * (o == get(i)), or -1 if there is no such index.
     *
     * @param o element to search for.
     *
     * @return the index in this list of the first occurrence of the
     *         specified element, or -1 if this list does not contain
     *         this element.
     */

    public int indexOf(final int o)
    {
        for (int i=0; i<_limit; i++) {
            if (_array[i] == o) {
                return i;
            }
        }
        return -1;
    }

    /**
     * Returns true if this list contains no elements.
     *
     * @return true if this list contains no elements.
     */

    public boolean isEmpty()
    {
        return _limit == 0;
    }

    /**
     * Returns the index in this list of the last occurrence of the
     * specified element, or -1 if this list does not contain this
     * element.  More formally, returns the highest index i such that
     * (o == get(i)), or -1 if there is no such index.
     *
     * @param o element to search for.
     *
     * @return the index in this list of the last occurrence of the
     *         specified element, or -1 if this list does not contain
     *         this element.
     */

    public int lastIndexOf(final int o)
    {
        for (int i=_limit-1; i>=0; i--) {
            if (_array[i] == o) {
                return i;
            }
        }
        return -1;
    }

    /**
     * Removes the element at the specified position in this list.
     * Shifts any subsequent elements to the left (subtracts one from
     * their indices).  Returns the element that was removed from the
     * list.
     *
     * @param index the index of the element to removed.
     *
     * @return the element previously at the specified position.
     *
     * @exception IndexOutOfBoundsException if the index is out of
     *            range (index < 0 || index >= size()).
     */

    public int remove(final int index)
    {
        if (index >= _limit)
        {
            throw new IndexOutOfBoundsException();
        }
        int rval = _array[ index ];

        System.arraycopy(_array, index + 1, _array, index, _limit - index);
        _limit--;
        return rval;
    }

    /**
     * Removes the first occurrence in this list of the specified
     * element (optional operation).  If this list does not contain
     * the element, it is unchanged.  More formally, removes the
     * element with the lowest index i such that (o.equals(get(i)))
     * (if such an element exists).
     *
     * @param o element to be removed from this list, if present.
     *
     * @return true if this list contained the specified element.
     */

    public boolean removeValue(final int o)
    {
        for (int j = 0; j < _limit; j++)
        {
            if (o == _array[ j ])
            {
                if (j+1 < _limit) {
                    System.arraycopy(_array, j + 1, _array, j, _limit - j);
                }
                _limit--;
                return true;
            }
        }
        return false;
    }

    /**
     * Removes from this list all the elements that are contained in
     * the specified collection
     *
     * @param c collection that defines which elements will be removed
     *          from this list.
     *
     * @return true if this list changed as a result of the call.
     */

    public boolean removeAll(final IntList c)
    {
        boolean rval = false;

        for (int j = 0; j < c._limit; j++)
        {
            if (removeValue(c._array[ j ]))
            {
                rval = true;
            }
        }
        return rval;
    }

    /**
     * Retains only the elements in this list that are contained in
     * the specified collection.  In other words, removes from this
     * list all the elements that are not contained in the specified
     * collection.
     *
     * @param c collection that defines which elements this set will
     *          retain.
     *
     * @return true if this list changed as a result of the call.
     */

    public boolean retainAll(final IntList c)
    {
        boolean rval = false;

        for (int j = 0; j < _limit; )
        {
            if (!c.contains(_array[ j ]))
            {
                remove(j);
                rval = true;
            }
            else
            {
                j++;
            }
        }
        return rval;
    }

    /**
     * Replaces the element at the specified position in this list
     * with the specified element
     *
     * @param index index of element to replace.
     * @param element element to be stored at the specified position.
     *
     * @return the element previously at the specified position.
     *
     * @exception IndexOutOfBoundsException if the index is out of
     *            range (index < 0 || index >= size()).
     */

    public int set(final int index, final int element)
    {
        if (index >= _limit)
        {
            throw new IndexOutOfBoundsException();
        }
        int rval = _array[ index ];

        _array[ index ] = element;
        return rval;
    }

    /**
     * Returns the number of elements in this list. If this list
     * contains more than Integer.MAX_VALUE elements, returns
     * Integer.MAX_VALUE.
     *
     * @return the number of elements in this IntList
     */

    public int size()
    {
        return _limit;
    }

    /**
     * Returns an array containing all of the elements in this list in
     * proper sequence.  Obeys the general contract of the
     * Collection.toArray method.
     *
     * @return an array containing all of the elements in this list in
     *         proper sequence.
     */

    public int [] toArray()
    {
        int[] rval = new int[ _limit ];

        System.arraycopy(_array, 0, rval, 0, _limit);
        return rval;
    }

    /**
     * Returns an array containing all of the elements in this list in
     * proper sequence.  Obeys the general contract of the
     * Collection.toArray(Object[]) method.
     *
     * @param a the array into which the elements of this list are to
     *          be stored, if it is big enough; otherwise, a new array
     *          is allocated for this purpose.
     *
     * @return an array containing the elements of this list.
     */

    public int [] toArray(final int [] a)
    {
        int[] rval;

        if (a.length == _limit)
        {
            System.arraycopy(_array, 0, a, 0, _limit);
            rval = a;
        }
        else
        {
            rval = toArray();
        }
        return rval;
    }

    private void growArray(final int new_size)
    {
        int   size      = (new_size == _array.length) ? new_size + 1
                                                      : new_size;
        int[] new_array = new int[ size ];

        System.arraycopy(_array, 0, new_array, 0, _limit);
        _array = new_array;
    }
}
