/*
 * Copyright 2007 Google Inc.
 * 
 * Licensed 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 java.util;

import com.google.gwt.lang.Array;

import java.io.Serializable;

/**
 * Resizeable array implementation of the List interface. <a
 * href="http://java.sun.com/j2se/1.5.0/docs/api/java/util/ArrayList.html">[Sun
 * docs]</a>
 * 
 * <p>
 * This implementation differs from JDK 1.5 <code>ArrayList</code> in terms of
 * capacity management. There is no speed advantage to pre-allocating array
 * sizes in JavaScript, so this implementation does not include any of the
 * capacity and "growth increment" concepts in the standard ArrayList class.
 * Although <code>ArrayList(int)</code> accepts a value for the initial
 * capacity of the array, this constructor simply delegates to
 * <code>ArrayList()</code>. It is only present for compatibility with JDK
 * 1.5's API.
 * </p>
 * 
 * @param <E> the element type.
 */
public class ArrayList<E> extends AbstractList<E> implements List<E>,
    Cloneable, RandomAccess, Serializable {

  private static native void setCapacity(Object[] array, int newSize) /*-{
    array.length = newSize;
  }-*/;

  private static native void splice(Object[] array, int index, int deleteCount) /*-{
    array.splice(index, deleteCount);
  }-*/;

  private static native void splice(Object[] array, int index, int deleteCount,
      Object value) /*-{
    array.splice(index, deleteCount, value);
  }-*/;

  private static native void spliceArray(Object[] array, int index,
      int deleteCount, Object[] values) /*-{
    Array.prototype.splice.apply(array, [index, deleteCount].concat(values));
  }-*/;

  /**
   * This field holds a JavaScript array.
   */
  private transient E[] array = (E[]) new Object[0];

  /**
   * Ensures that RPC will consider type parameter E to be exposed. It will be
   * pruned by dead code elimination.
   */
  @SuppressWarnings("unused")
  private E exposeElement;

  /**
   * The size of the array.
   */
  private int size = 0;

  public ArrayList() {
  }
  
  public ArrayList(Collection<? extends E> c) {
    // Avoid calling overridable methods from constructors
    spliceArray(array, 0, 0, c.toArray());
    size = array.length;
  }

  public ArrayList(int initialCapacity) {
    // Avoid calling overridable methods from constructors
    assert (initialCapacity >= 0);
    setCapacity(array, initialCapacity);
  }

  @Override
  public boolean add(E o) {
    array[size++] = o;
    return true;
  }

  @Override
  public void add(int index, E o) {
    if (index < 0 || index > size) {
      indexOutOfBounds(index, size);
    }
    splice(array, index, 0, o);
    ++size;
  }

  @Override
  public boolean addAll(Collection<? extends E> c) {
    Object[] cArray = c.toArray();
    int len = cArray.length;
    if (len == 0) {
      return false;
    }
    spliceArray(array, size, 0, cArray);
    size += len;
    return true;
  }

  public boolean addAll(int index, Collection<? extends E> c) {
    if (index < 0 || index > size) {
      indexOutOfBounds(index, size);
    }
    Object[] cArray = c.toArray();
    int len = cArray.length;
    if (len == 0) {
      return false;
    }
    spliceArray(array, index, 0, cArray);
    size += len;
    return true;
  }

  @Override
  public void clear() {
    array = (E[]) new Object[0];
    size = 0;
  }

  public Object clone() {
    return new ArrayList<E>(this);
  }

  @Override
  public boolean contains(Object o) {
    return (indexOf(o) != -1);
  }

  public void ensureCapacity(int capacity) {
    if (capacity > size) {
      setCapacity(array, capacity);
    }
  }

  @Override
  public E get(int index) {
    checkIndex(index, size);
    return array[index];
  }

  @Override
  public int indexOf(Object o) {
    return indexOf(o, 0);
  }

  @Override
  public boolean isEmpty() {
    return size == 0;
  }

  @Override
  public int lastIndexOf(Object o) {
    return lastIndexOf(o, size() - 1);
  }

  @Override
  public E remove(int index) {
    E previous = get(index);
    splice(array, index, 1);
    --size;
    return previous;
  }

  @Override
  public boolean remove(Object o) {
    int i = indexOf(o);
    if (i == -1) {
      return false;
    }
    remove(i);
    return true;
  }

  @Override
  public E set(int index, E o) {
    E previous = get(index);
    array[index] = o;
    return previous;
  }

  @Override
  public int size() {
    return size;
  }

  @Override
  public Object[] toArray() {
    return Array.cloneSubrange(array, 0, size);
  }

  /*
   * Faster than the iterator-based implementation in AbstractCollection.
   */
  @SuppressWarnings("unchecked")
  @Override
  public <T> T[] toArray(T[] out) {
    if (out.length < size) {
      out = Array.createFrom(out, size);
    }
    for (int i = 0; i < size; ++i) {
      out[i] = (T) array[i];
    }
    if (out.length > size) {
      out[size] = null;
    }
    return out;
  }

  public void trimToSize() {
    setCapacity(array, size);
  }

  @Override
  protected void removeRange(int fromIndex, int endIndex) {
    checkIndex(fromIndex, size);
    if (endIndex < fromIndex || endIndex > size) {
      indexOutOfBounds(endIndex, size);
    }
    int count = endIndex - fromIndex;
    splice(array, fromIndex, count);
    size -= count;
  }

  /**
   * Used by Vector.
   */
  int capacity() {
    return array.length;
  }

  /**
   * Used by Vector.
   */
  int indexOf(Object o, int index) {
    for (; index < size; ++index) {
      if (Utility.equalsWithNullCheck(o, array[index])) {
        return index;
      }
    }
    return -1;
  }

  /**
   * Used by Vector.
   */
  int lastIndexOf(Object o, int index) {
    for (; index >= 0; --index) {
      if (Utility.equalsWithNullCheck(o, array[index])) {
        return index;
      }
    }
    return -1;
  }

  /**
   * Used by Vector.
   */
  void setSize(int newSize) {
    setCapacity(array, newSize);
    size = newSize;
  }
}
