/*
 * Copyright 2009 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 com.google.gwt.collections;

import java.util.Arrays;

/**
 * An array whose content and length can change over time.
 * 
 * @param <E> The type stored in the array elements
 */
public class MutableArray<E> extends Array<E> {

  // TODO: refactor the unchecked elems construction into a separate method
  // The elements in the array
  E[] elems;

  // Tracks when this array is frozen (for assertion enforcement only)
  private boolean frozen;

  /**
   * Can only be constructed via {@link CollectionFactory}.
   */
  MutableArray() {
  }

  @ConstantTime
  public void add(E elem) {
    insert(size(), elem);
  }

  @ConstantTime
  public void clear() {
    Assertions.assertNotFrozen(this);
    elems = null;
  }
  
  /**
   * Creates an immutable array based on this one. Also marks this object as read-only. 
   * After calling {@code freeze()}, only use methods from {@link Array} or the returned 
   * {@link ImmutableArray} should be to access the elements 
   * of the array is preferred.
   */
  public ImmutableArray<E> freeze() {
    Assertions.markFrozen(this);

    ImmutableArray<E> r;
    if (elems != null) {
      r = new ImmutableArrayImpl<E>(elems);
    } else {
      r = ImmutableArray.getEmptyInstance();
    }
    
    return r;
  }

  @Override
  @ConstantTime
  public E get(int index) {
    Assertions.assertIndexInRange(index, 0, size());
    if (elems != null) {
      return elems[index];
    } else {
      return null;
    }
  }

  /**
   * Inserts {@code element} before the element residing at {@code index}.
   * 
   * @param index in the range [0, this.size()], inclusive; if index is equal
   *          to the array's current size, the result is equivalent to calling
   *          {@link #add(Object)}
   * @param elem the element to insert or {@code null}
   */
  @SuppressWarnings("unchecked")
  @LinearTime
  public void insert(int index, E elem) {
    Assertions.assertNotFrozen(this);
    Assertions.assertIndexInRange(index, 0, size() + 1);

    // TODO benchmark to see if we need to grow smartly (2x size?)
    // TODO benchmark to see if we need to consider single element arrays separately
    if (elems != null) {
      int oldLen = elems.length;
      E[] newElems = (E[]) new Object[oldLen + 1];
      System.arraycopy(elems, 0, newElems, 0, index);
      System.arraycopy(elems, index, newElems, index + 1, oldLen - index);
      newElems[index] = elem;
      elems = newElems;
    } else {
      elems = (E[]) (new Object[] {elem});
    }
  }

  /**
   * Removes the element at the specified index.
   */
  @SuppressWarnings("unchecked")
  @LinearTime
  public void remove(int index) {
    Assertions.assertNotFrozen(this);
    Assertions.assertIndexInRange(index, 0, size());
    if (elems != null && elems.length >= 1) {
      int oldLen = elems.length;
      E[] newElems = (E[]) new Object[oldLen - 1];
      System.arraycopy(elems, 0, newElems, 0, index);
      System.arraycopy(elems, index + 1, newElems, index, oldLen - index - 1);
      elems = newElems;
    } else if (elems != null && elems.length == 1) {
      elems = null;
    } else {
      assert false : "index " + index + " in range [0, " + size() + "), but remove(int) failed";
    }
  }

  /**
   * Replaces the element at the specified index.
   * 
   * @param index in the range [0, this.size()), exclusive
   * @param elem the element to insert or {@code null}
   */
  @ConstantTime
  public void set(int index, E elem) {
    Assertions.assertNotFrozen(this);
    Assertions.assertIndexInRange(index, 0, size());
    if (elems != null) {
      elems[index] = elem;
    } else {
      assert false : "index " + index + " in range [0, " + size() + "), but set(int,E) failed";
    }
  }
  
  /**
   * Changes the array size. If {@code newSize} is less than the current size, the array is 
   * truncated. If {@code newSize} is greater than the current size the array is grown and
   * the new elements of the array filled up with {@code fillValue}.
   */
  @SuppressWarnings("unchecked")
  @LinearTime
  public void setSize(int newSize, E fillValue) {
    Assertions.assertNotFrozen(this);
    assert newSize >= 0 : "expecting newSize >= 0, got " + newSize;
    
    int fillStart;

    if (newSize == size()) {
      return;
    } else if (newSize == 0) {
      elems = null;
      return;
    }
    
    if (elems == null) {
      fillStart = 0;
    } else if (newSize < elems.length) {
      // nothing to fill
      fillStart = newSize;      
    } else {
      fillStart = elems.length;
    }
    
    E[] newElems = (E[]) new Object[newSize];
    
    if (fillStart != 0) {
      System.arraycopy(elems, 0, newElems, 0, fillStart);
    }
    
    Arrays.fill(newElems, fillStart, newSize, fillValue);
    
    elems = newElems;
  }

  @Override
  @ConstantTime
  public int size() {
    if (elems != null) {
      return elems.length;
    } else {
      return 0;
    }
  }

  // Only meant to be called from within Assertions
  boolean isFrozen() {
    return frozen;
  }

  // Only meant to be called from within Assertions
  void markFrozen() {
    frozen = true;
  }
}
