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

import static javaemul.internal.InternalPreconditions.checkCriticalArgument;
import static javaemul.internal.InternalPreconditions.checkNotNull;

import com.google.gwt.core.client.JavaScriptObject;
import java.io.Serializable;
import jsinterop.annotations.JsIgnore;
import jsinterop.annotations.JsNonNull;
import jsinterop.annotations.JsType;

/**
 * The first-class representation of an enumeration.
 *
 * @param <E>
 */
@JsType
public abstract class Enum<E extends Enum<E>> implements Comparable<E>, Serializable {

  @JsIgnore
  public static <T extends Enum<T>> T valueOf(Class<T> enumType, String name) {
    JavaScriptObject enumValueOfFunc = checkNotNull(enumType).enumValueOfFunc;
    checkCriticalArgument(enumValueOfFunc != null);
    checkNotNull(name);
    return invokeValueOf(enumValueOfFunc, name);
  }

  protected static <T extends Enum<T>> JavaScriptObject createValueOfMap(
      T[] enumConstants) {
    JavaScriptObject result = JavaScriptObject.createObject();
    for (T value : enumConstants) {
       put0(result, ":" + value.name(), value);
    }
    return result;
  }

  protected static <T extends Enum<T>> T valueOf(JavaScriptObject map, String name) {
    checkNotNull(name);

    T result = Enum.<T> get0(map, ":" + name);
    checkCriticalArgument(result != null, "Enum constant undefined: " + name);
    return result;
  }

  private static native <T extends Enum<T>> T get0(JavaScriptObject map,
      String name) /*-{
    return map[name];
  }-*/;

  private static native <T extends Enum<T>> T invokeValueOf(
      JavaScriptObject enumValueOfFunc, String name) /*-{
    return enumValueOfFunc(name);
  }-*/;

  private static native <T extends Enum<T>> void put0(JavaScriptObject map,
      String name, T value) /*-{
    map[name] = value;
  }-*/;

  private final String name;

  private final int ordinal;

  protected Enum(String name, int ordinal) {
    this.name = name;
    this.ordinal = ordinal;
  }

  @Override
  public final int compareTo(E other) {
    // TODO: will a bridge method do the cast for us?
    // if (this.getDeclaringClass() != other.getDeclaringClass()) {
    // throw new ClassCastException();
    // }
    return this.ordinal - ((Enum) other).ordinal;
  }

  @Override
  public final boolean equals(Object other) {
    return this == other;
  }

  @JsIgnore
  @SuppressWarnings("unchecked")
  public final Class<E> getDeclaringClass() {
    Class clazz = getClass();
    assert clazz != null : "clazz";

    // Don't use getSuperclass() to allow that method to be pruned for most
    // class types
    Class superclass = clazz.getEnumSuperclass();
    assert superclass != null : "superclass";

    return (superclass == Enum.class) ? clazz : superclass;
  }

  @Override
  public final int hashCode() {
    return super.hashCode();
  }

  public final @JsNonNull String name() {
    return name != null ? name : "" + ordinal;
  }

  public final int ordinal() {
    return ordinal;
  }

  @Override
  public String toString() {
    return name();
  }
}
