/*
 * 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.dev.shell;

/**
 * Represents a JavaScript value.
 * 
 * Note that in general the various get*() methods will return
 * platform-independent values only if the corresponding is*() method returns
 * true. In some cases, an IllegalStateException may be thrown if the JavaScript
 * value is not of the appropriate type or bogus values may be returned. Note
 * that getString will try very hard to return a reasonable result for any
 * value, but it is intended only for human consumption and the exact format for
 * anything besides a string value cannot be relied upon.
 */
public abstract class JsValue {

  /**
   * Provides interface for methods to be exposed on JavaScript side.
   */
  public interface DispatchMethod {
    boolean invoke(JsValue jsthis, JsValue[] jsargs, JsValue returnValue);
  }

  /**
   * Provides interface for objects to be exposed on JavaScript side.
   */
  public interface DispatchObject {
    JsValue getField(int dispatchId);

    JsValue getField(String name);

    int getFieldId(String name);

    Object getTarget();

    void setField(int dispatchId, JsValue value);

    void setField(String name, JsValue value);
  }

  /**
   * Get the value of the object as a boolean. May attempt to convert the value
   * to a boolean if it is not a boolean.
   * 
   * @return the value of the underlying object as a boolean
   */
  public abstract boolean getBoolean();

  /**
   * Get the value of the object as an integer. May attempt to convert the value
   * to an integer if it is not an integer.
   * 
   * @return the value of the underlying object as an int
   */
  public abstract int getInt();

  /**
   * Get the wrapper object for a wrapped Java object. Only valid if
   * isWrappedJavaObject() is true.
   * 
   * @return the Java object wrapper
   */
  public abstract DispatchObject getJavaObjectWrapper();

  /**
   * Returns a unique value corresponding to the underlying JavaScript object.
   * In general, two different JsValues will return the same value IFF the
   * underlying JavaScript objects are identical (===).
   * 
   * @return a unique number corresponding to the underlying object, or
   *         <code>0</code> if {@link #isJavaScriptObject()} is
   *         <code>false</code>
   */
  public abstract int getJavaScriptObjectPointer();

  /**
   * Get the value of the object as a double. May attempt to convert the value
   * to a double if it is not a double.
   * 
   * @return the value of the underlying object as a double
   */
  public abstract double getNumber();

  /**
   * Get the value of the object as a string. Will coerce the underlying type to
   * a string, but stable cross-platform behavior is only guaranteed when
   * {@link #isString()} is <code>true</code>.
   * 
   * @return the value of the underlying object as a string
   */
  public abstract String getString();

  /**
   * Returns a human-readable string describing the type of the JS object. This
   * is intended only for human consumption and may vary across platforms.
   */
  public abstract String getTypeString();

  /**
   * Returns a wrapped Java method.
   */
  public abstract DispatchMethod getWrappedJavaFunction();

  /**
   * Unwrap a wrapped Java object.
   * 
   * @return the original Java object wrapped in this JS object
   */
  public abstract Object getWrappedJavaObject();

  /**
   * Returns true if the JS value is a boolean.
   */
  public abstract boolean isBoolean();

  /**
   * Returns true if getInt() can be used on this value.
   */
  public abstract boolean isInt();

  /**
   * Returns true if the JS value is a native JS object.
   */
  public abstract boolean isJavaScriptObject();

  /**
   * Returns true if the JS value is null.
   */
  public abstract boolean isNull();

  /**
   * Returns true if the JS value is a numeric type.
   */
  public abstract boolean isNumber();

  /**
   * Returns true if the JS value is a string.
   */
  public abstract boolean isString();

  /**
   * Returns true if the JS value is undefined (void).
   */
  public abstract boolean isUndefined();

  /**
   * Returns true if the JS value contains a wrapped Java method.
   */
  public abstract boolean isWrappedJavaFunction();

  /**
   * Returns true if the JS value is a wrapped Java object.
   */
  public abstract boolean isWrappedJavaObject();

  /**
   * Sets the JS object to be a boolean value.
   * 
   * @param val the boolean value to set
   */
  public abstract void setBoolean(boolean val);

  /**
   * Sets the JS object to be a number, passed as an byte.
   * 
   * @param val the value to store
   */
  public abstract void setByte(byte val);

  /**
   * Sets the JS object to be a number, passed as a char.
   * 
   * @param val the value to store
   */
  public abstract void setChar(char val);

  /**
   * Sets the JS object to be a number, passed as a double.
   * 
   * @param val the value to store
   */
  public abstract void setDouble(double val);

  /**
   * Sets the JS object to be a number, passed as an int.
   * 
   * @param val the value to store
   */
  public abstract void setInt(int val);

  /**
   * Set the JS object to be null.
   * 
   * @throws com.google.gwt.dev.shell.HostedModeException
   */
  public abstract void setNull();

  /**
   * Sets the JS object to be a number, passed as a short.
   * 
   * @param val the value to store
   */
  public abstract void setShort(short val);

  /**
   * Set the JS object to the supplied string.
   * 
   * @param val the string to put in the JS object
   * @throws HostedModeException on JS allocation failures
   */
  public abstract void setString(String val);

  /**
   * Set the JS object to be undefined (void).
   * 
   * @throws HostedModeException on JS allocation failures
   */
  public abstract void setUndefined();

  /**
   * Make this JsValue refer to the same underlying object as another JsValue.
   * 
   * @param other JsValue to copy JS object from
   */
  public abstract void setValue(JsValue other);

  /**
   * Set the JS object to the supplied object, which will be wrapped in a
   * platform-dependent JavaScript class.
   * 
   * @param <T> the type of the Java object to wrap
   * @param cl the classloader to create the wrapper object with
   * @param val the Java object to wrap
   * @throws HostedModeException
   */
  public abstract <T> void setWrappedJavaObject(CompilingClassLoader cl, T val);

  /**
   * Produce a string representation of the JsValue.
   */
  @Override
  public String toString() {
    if (isUndefined()) {
      return "void";
    } else if (isNull()) {
      return "null";
    } else if (isBoolean()) {
      return "bool: " + (getBoolean() ? "true" : "false");
    } else if (isInt()) {
      return "int: " + Integer.toString(getInt());
    } else if (isNumber()) {
      return "double: " + Double.toString(getNumber());
    } else if (isWrappedJavaObject()) {
      Object wrappedObject = getWrappedJavaObject();
      if (wrappedObject == null) {
        return "Java static dispatch";
      }
      // avoid calling toString on the wrapped object, as this can be expensive
      return "Java object: " + wrappedObject.getClass().getName() + '@'
          + System.identityHashCode(wrappedObject);
    } else if (isJavaScriptObject()) {
      return getTypeString();
    } else if (isString()) {
      return "string: '" + getString() + "'";
    } else if (isWrappedJavaFunction()) {
      return "Java method: " + getWrappedJavaFunction().toString();
    }
    return getTypeString();
  }
}
