/*
 * 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;
}
