/*
 * Copyright 2008 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.lang;

import com.google.gwt.core.client.JavaScriptObject;

/**
 * This is a magic class the compiler uses as a base class for injected array
 * classes.
 */
public final class Array {

  private static final class ExpandoWrapper {
    /**
     * A JS array containing the names of any expandos we need to add to arrays
     * (such as "hashCode", "equals", "toString").
     */
    private static final Object expandoNames = makeEmptyJsArray();

    /**
     * A JS array containing the values of any expandos we need to add to arrays
     * (such as hashCode(), equals(), toString()).
     */
    private static final Object expandoValues = makeEmptyJsArray();

    static {
      initExpandos(new Array(), expandoNames, expandoValues);
    }

    public static void wrapArray(Array array) {
      wrapArray(array, expandoNames, expandoValues);
    }

    private static native void initExpandos(Array protoType,
        Object expandoNames, Object expandoValues) /*-{
      var i = 0, value;
      for ( var name in protoType) {
        // Only copy non-null values over; this generally means only functions
        // will get copied over, and not fields, which is good because we will
        // setup the fields manually and it's best if length doesn't get blown
        // away.
        if (value = protoType[name]) {
          expandoNames[i] = name;
          expandoValues[i] = value;
          ++i;
        }
      }
    }-*/;

    private static native Object makeEmptyJsArray() /*-{
      return [];
    }-*/;

    private static native void wrapArray(Array array, Object expandoNames,
        Object expandoValues) /*-{
      for ( var i = 0, c = expandoNames.length; i < c; ++i) {
        array[expandoNames[i]] = expandoValues[i];
      }
    }-*/;
  }

  /*
   * TODO: static init instead of lazy init when we can elide the clinit calls.
   */

  static final int FALSE_SEED_TYPE = 2;

  static final int LONG_SEED_TYPE = 3;

  static final int NULL_SEED_TYPE = 0;

  static final int ZERO_SEED_TYPE = 1;

  /**
   * Creates a copy of the specified array.
   */
  public static <T> T[] clone(T[] array) {
    return cloneSubrange(array, 0, array.length);
  }

  /**
   * Creates a copy of a subrange of the specified array.
   */
  public static <T> T[] cloneSubrange(T[] array, int fromIndex, int toIndex) {
    Array a = asArrayType(array);
    Array result = arraySlice(a, fromIndex, toIndex);
    initValues(a.getClass(), Util.getCastableTypeMap(a), a.queryId, result);
    // implicit type arg not inferred (as of JDK 1.5.0_07)
    return Array.<T> asArray(result);
  }

  /**
   * Creates a new array of the exact same type and length as a given array.
   */
  public static <T> T[] createFrom(T[] array) {
    return createFrom(array, array.length);
  }

  /**
   * Creates an empty array of the exact same type as a given array, with the
   * specified length.
   */
  public static <T> T[] createFrom(T[] array, int length) {
    Array a = asArrayType(array);
    Array result = createFromSeed(NULL_SEED_TYPE, length);
    initValues(a.getClass(), Util.getCastableTypeMap(a), a.queryId, result);
    // implicit type arg not inferred (as of JDK 1.5.0_07)
    return Array.<T> asArray(result);
  }

  /**
   * Creates an array like "new T[a][b][c][][]" by passing in a native JSON
   * array, [a, b, c].
   * 
   * @param arrayClass the class of the array
   * @param castableTypeMap the map of types to which this array can be casted,
   *          in the form of a JSON map object
   * @param queryId the queryId of the array
   * @param length the length of the array
   * @param seedType the primitive type of the array; 0: null; 1: zero; 2: false; 3: long
   * @return the new array
   */
  public static Array initDim(Class<?> arrayClass, 
        JavaScriptObject castableTypeMap, int queryId, int length, int seedType) {
    Array result = createFromSeed(seedType, length);
    initValues(arrayClass, castableTypeMap, queryId, result);
    return result;
  }

  /**
   * Creates an array like "new T[a][b][c][][]" by passing in a native JSON
   * array, [a, b, c].
   * 
   * @param arrayClasses the class of each dimension of the array
   * @param castableTypeMapExprs the JSON castableTypeMap of each dimension,
   *          from highest to lowest
   * @param queryIdExprs the queryId of each dimension, from highest to lowest
   * @param dimExprs the length of each dimension, from highest to lower
   * @param seedType the primitive type of the array; 0: null; 1: zero; 2: false; 3: long
   * @return the new array
   */
  public static Array initDims(Class<?> arrayClasses[], 
      JavaScriptObject[] castableTypeMapExprs, int[] queryIdExprs, 
      int[] dimExprs, int count, int seedType) {
    return initDims(arrayClasses, castableTypeMapExprs, queryIdExprs, 
        dimExprs, 0, count, seedType);
  }

  /**
   * Creates an array like "new T[][]{a,b,c,d}" by passing in a native JSON
   * array, [a, b, c, d].
   * 
   * @param arrayClass the class of the array
   * @param castableTypeMap the map of types to which this array can be casted,
   *          in the form of a JSON map object
   * @param queryId the queryId of the array
   * @param array the JSON array that will be transformed into a GWT array
   * @return values; having wrapped it for GWT
   */
  public static Array initValues(Class<?> arrayClass,
      JavaScriptObject castableTypeMap, int queryId, Array array) {
    ExpandoWrapper.wrapArray(array);
    array.arrayClass = arrayClass;
    Util.setCastableTypeMap(array, castableTypeMap);
    array.queryId = queryId;
    return array;
  }

  /**
   * Performs an array assignment, checking for valid index and type.
   */
  public static Object setCheck(Array array, int index, Object value) {
    if (value != null) {
      if (array.queryId > 0 && !Cast.canCastUnsafe(value, array.queryId)) {
        throw new ArrayStoreException();
      }
      if (array.queryId < 0 && Cast.isJavaObject(value)) {
        throw new ArrayStoreException();
      }
    }
    return set(array, index, value);
  }

  private static native Array arraySlice(Array array, int fromIndex, int toIndex) /*-{
    return array.slice(fromIndex, toIndex);
  }-*/;

  /**
   * Use JSNI to effect a castless type change.
   */
  private static native <T> T[] asArray(Array array) /*-{
    return array;
  }-*/;

  /**
   * Use JSNI to effect a castless type change.
   */
  private static native <T> Array asArrayType(T[] array) /*-{
    return array;
  }-*/;

  /**
   * Creates a primitive JSON array of a given seedType.
   * 
   * @param seedType the primitive type of the array; 0: null; 1: zero;
   *     2: false; 3: (long) 0
   * @param length the requested length
   * @see #NULL_SEED_TYPE
   * @see #ZERO_SEED_TYPE
   * @see #FALSE_SEED_TYPE
   * @see #LONG_SEED_TYPE
   * @return the new JSON array
   */
  private static native Array createFromSeed(int seedType, int length) /*-{
    var array = new Array(length);
    if (seedType == 3) {
      // Fill array with the type used by LongLib
      for ( var i = 0; i < length; ++i) {
        var value = new Object();
        value.l = value.m = value.h = 0;
        array[i] = value;
      }
    } else if (seedType > 0) {
      var value = [null, 0, false][seedType];
      for ( var i = 0; i < length; ++i) {
        array[i] = value;
      }
    }
    return array;
  }-*/;

  private static Array initDims(Class<?> arrayClasses[],
      JavaScriptObject[] castableTypeMapExprs, int[] queryIdExprs, int[] dimExprs, 
      int index, int count, int seedType) {
    int length = dimExprs[index];
    boolean isLastDim = (index == (count - 1));

    Array result = createFromSeed(isLastDim ? seedType : NULL_SEED_TYPE, length);
    initValues(arrayClasses[index], castableTypeMapExprs[index], 
        queryIdExprs[index], result);

    if (!isLastDim) {
      // Recurse to next dimension.
      ++index;
      for (int i = 0; i < length; ++i) {
        set(result, i, initDims(arrayClasses, castableTypeMapExprs,
            queryIdExprs, dimExprs, index, count, seedType));
      }
    }
    return result;
  }

  /**
   * Sets a value in the array.
   */
  private static native Object set(Array array, int index, Object value) /*-{
    return array[index] = value;
  }-*/;

  /*
   * Explicitly initialize all fields to JS false values; see comment in
   * ExpandoWrapper.initExpandos().
   */
  
  /**
   * Holds the real type-specific Class object for a given array instance. The
   * compiler produces a magic implementation of getClass() which returns this
   * field directly.
   */
  protected Class<?> arrayClass = null;

  /**
   * The necessary cast target for objects stored into this array. Attempting to
   * store an object that cannot satisfy the query id throws and
   * {@link ArrayStoreException}.
   */
  protected int queryId = 0;
}
