/*
 * Copyright 2007 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.
 */

#include <jni.h>
#include "JsRootedValue.h"
#include "gwt-jni.h"
#include "ExternalWrapper.h"
#include "Tracer.h"

// include javah-generated header to make sure things match
#include "JsValueMoz.h"

/*
 * Returns the value of a field on a Java object.
 * 
 * context - JavaScript context
 * clazz - class of obj
 * obj - Java object to retreive field from
 * fieldName - name of field on Java object to retrieve
 * 
 * Returns null on failure.  Caller is responsible for deleting
 * returned JsRootedValue when done with it.
 */
JsRootedValue* GetFieldAsRootedValue(JSContext* context, jclass clazz,
    jobject obj, jstring fieldName)
{
  jmethodID getFieldMeth = savedJNIEnv->GetMethodID(clazz, "getField",
      "(Ljava/lang/String;I)V");
  if (!getFieldMeth || savedJNIEnv->ExceptionCheck())
    return 0;

  JsRootedValue* jsRootedValue = new JsRootedValue(context);
  savedJNIEnv->CallVoidMethod(obj, getFieldMeth, fieldName,
  	 reinterpret_cast<jint>(jsRootedValue));
  if (savedJNIEnv->ExceptionCheck()) {
  	 delete jsRootedValue;
    return 0;
  }
  return jsRootedValue;
}
  
/*
 * Sets the value of a field on a Java object.
 * 
 * context - JavaScript context
 * clazz - class of obj
 * obj - Java object to store into field
 * fieldName - name of field on Java object to store into
 * jsRootedValue - the value to store in the field
 * 
 * returns true on success, false on failure
 */
bool SetFieldFromRootedValue(JSContext* context, jclass clazz,
    jobject obj, jstring fieldName, JsRootedValue* jsRootedValue)
{
  jmethodID getFieldMeth = savedJNIEnv->GetMethodID(clazz, "setField",
      "(Ljava/lang/String;I)V");
  if (!getFieldMeth || savedJNIEnv->ExceptionCheck())
    return false;

  savedJNIEnv->CallVoidMethod(obj, getFieldMeth, fieldName,
  	 reinterpret_cast<jint>(jsRootedValue));
  if (savedJNIEnv->ExceptionCheck())
    return false;

  return true;
}

/*
 * Throws a HostedModeException with the specified message.
 */
static void ThrowHostedModeException(JNIEnv* jniEnv, const char* msg) {
  jclass exceptionClass
      = jniEnv->FindClass("com/google/gwt/dev/shell/HostedModeException");
  jniEnv->ThrowNew(exceptionClass, msg);
}


enum JsValueType {
  JSVAL_TYPE_VOID=0,
  JSVAL_TYPE_NULL,
  JSVAL_TYPE_BOOLEAN,
  JSVAL_TYPE_NUMBER,
  JSVAL_TYPE_STRING,
  JSVAL_TYPE_OBJECT,
  JSVAL_TYPE_UNKNOWN,
};

static const char* JsValueTypeStrings[]={
  "undefined",
  "null",
  "boolean",
  "number",
  "string",
  "object",
  "unknown",
};

static JsValueType GetValueType(jsval val) {
  if(JSVAL_IS_VOID(val)) {
    return JSVAL_TYPE_VOID;
  } else if(JSVAL_IS_NULL(val)) {
    return JSVAL_TYPE_NULL;
  } else if(JSVAL_IS_BOOLEAN(val)) {
    return JSVAL_TYPE_BOOLEAN;
  } else if(JSVAL_IS_NUMBER(val)) {
    return JSVAL_TYPE_NUMBER;
  } else if(JSVAL_IS_STRING(val)) {
    return JSVAL_TYPE_STRING;
  } else if(JSVAL_IS_OBJECT(val)) {
    return JSVAL_TYPE_OBJECT;
  } else {
    return JSVAL_TYPE_UNKNOWN;
  } 
}

/*
 * Class:     com_google_gwt_dev_shell_moz_JsValueMoz
 * Method:    _createJsRootedValue()
 * Signature: (II)I
 */
extern "C" JNIEXPORT jint JNICALL
Java_com_google_gwt_dev_shell_moz_JsValueMoz__1createJsRootedValue
  (JNIEnv* jniEnv, jclass, jint scriptObjInt, jint jsval)
{
  Tracer tracer("JsValueMoz._createJsRootedValue");
  nsIScriptGlobalObject* scriptObject = NS_REINTERPRET_CAST(nsIScriptGlobalObject*, scriptObjInt);
  nsCOMPtr<nsIScriptContext> scriptContext(scriptObject->GetContext());
  if (!scriptContext) {
    ThrowHostedModeException(jniEnv, "Unable to get script context");
    tracer.setFail("Unable to get script context");
    return 0;
  }
  JSContext* context = NS_REINTERPRET_CAST(JSContext*, scriptContext->GetNativeContext());
  JsRootedValue* jsRootedValue = new JsRootedValue(context, jsval);
  return NS_REINTERPRET_CAST(jint, jsRootedValue);
}

/*
 * Class:     com_google_gwt_dev_shell_moz_JsValueMoz
 * Method:    _copyJsRootedValue()
 * Signature: (I)I
 */
extern "C" JNIEXPORT jint JNICALL
Java_com_google_gwt_dev_shell_moz_JsValueMoz__1copyJsRootedValue
  (JNIEnv* jniEnv, jclass, jint jsRootedValueInt)
{
  const JsRootedValue* jsRootedValue = reinterpret_cast<const JsRootedValue*>
      (jsRootedValueInt);
  Tracer tracer("JsValueMoz._copyJsRootedValue", jsRootedValue);
  JsRootedValue* newRootedValue = new JsRootedValue(*jsRootedValue);
  return NS_REINTERPRET_CAST(jint, newRootedValue);
}

/*
 * Class:     com_google_gwt_dev_shell_moz_JsValueMoz
 * Method:    _destroyJsRootedValue()
 * Signature: (I)V
 */
extern "C" JNIEXPORT void JNICALL
Java_com_google_gwt_dev_shell_moz_JsValueMoz__1destroyJsRootedValue
  (JNIEnv* jniEnv, jclass, jint jsRootedValueInt)
{
  JsRootedValue* jsRootedValue = reinterpret_cast<JsRootedValue*>
      (jsRootedValueInt);
  Tracer tracer("JsValueMoz._destroyJsRootedValue", jsRootedValue);
  delete jsRootedValue;
}

/*
 * Class:     com_google_gwt_dev_shell_moz_JsValueMoz
 * Method:    _getBoolean()
 * Signature: (I)Z
 * 
 * TODO(jat): unboxing Javascript Boolean type?
 */
extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_gwt_dev_shell_moz_JsValueMoz__1getBoolean
  (JNIEnv* jniEnv, jclass, jint jsRootedValueInt)
{
  JsRootedValue* jsRootedValue = reinterpret_cast<JsRootedValue*>
      (jsRootedValueInt);
  Tracer tracer("JsValueMoz._getBoolean", jsRootedValue);
  return jsRootedValue->getBoolean();
}

/**
 * Class:     com_google_gwt_dev_shell_moz_JsValueMoz
 * Method:    _getInt()
 * Signature: (I)I
 * 
 * @see com.google.gwt.dev.shell.moz.JsValueMoz#getInt()
 * 
 * TODO(jat): unboxing Javascript Integer type?
 */
extern "C" JNIEXPORT jint JNICALL
Java_com_google_gwt_dev_shell_moz_JsValueMoz__1getInt
  (JNIEnv* jniEnv, jclass, jint jsRootedValueInt)
{
  JsRootedValue* jsRootedValue = reinterpret_cast<JsRootedValue*>
      (jsRootedValueInt);
  Tracer tracer("JsValueMoz._getInt", jsRootedValue);
  int val = jsRootedValue->getInt();
  tracer.log("value=%d", val);
  return val;
}

/**
 * Return a Javascript number as a Java double.
 * 
 * Class:     com_google_gwt_dev_shell_moz_JsValueMoz
 * Method:    _getNumber()
 * Signature: (I)D
 */
extern "C" JNIEXPORT jdouble JNICALL
Java_com_google_gwt_dev_shell_moz_JsValueMoz__1getNumber
  (JNIEnv* jniEnv, jclass, jint jsRootedValueInt)
{
  JsRootedValue* jsRootedValue = reinterpret_cast<JsRootedValue*>
      (jsRootedValueInt);
  Tracer tracer("JsValueMoz._getNumber", jsRootedValue);
  return jsRootedValue->getDouble();
}

/**
 * Return a Javascript string as a Java string.
 * 
 * Class:     com_google_gwt_dev_shell_moz_JsValueMoz
 * Method:    _getString()
 * Signature: (I)Ljava/lang/String;
 * 
 * Note that this relies on jschar being assignment compatible with jchar
 */
extern "C" JNIEXPORT jstring JNICALL
Java_com_google_gwt_dev_shell_moz_JsValueMoz__1getString
  (JNIEnv* jniEnv, jclass, jint jsRootedValueInt)
{
  JsRootedValue* jsRootedValue = reinterpret_cast<JsRootedValue*>
      (jsRootedValueInt);
  Tracer tracer("JsValueMoz._getString", jsRootedValue);
  const JSString* str = jsRootedValue->getString();
  int len = JS_GetStringLength(const_cast<JSString*>(str));
  jstring javaStr =jniEnv->NewString(reinterpret_cast<const jchar*>(
      JS_GetStringChars(const_cast<JSString*>(str))), len);
  return javaStr;
}

/*
 * Returns a human-readable Java string describing the type of a
 * JavaScript object.
 * 
 * Class:     com_google_gwt_dev_shell_moz_JsValueMoz
 * Method:    _getTypeString
 * Signature: (I)Ljava/lang/String;
 */
extern "C" JNIEXPORT jstring JNICALL
Java_com_google_gwt_dev_shell_moz_JsValueMoz__1getTypeString
  (JNIEnv* jniEnv, jclass, jint jsRootedValueInt)
{
  JsRootedValue* jsRootedValue = reinterpret_cast<JsRootedValue*>
      (jsRootedValueInt);
  Tracer tracer("JsValueMoz._getTypeString", jsRootedValue);
  jsval val = jsRootedValue->getValue();
  JSContext* context = jsRootedValue->getContext();
  JsValueType valueType = GetValueType(val);
  const char* typeString = 0;
  char buf[256];
  if(valueType == JSVAL_TYPE_OBJECT) {
    JSObject* jsObject = JSVAL_TO_OBJECT(val);
    JSClass* objClass = JS_GET_CLASS(context, jsObject);
    if (JS_InstanceOf(context, jsObject,
        &gwt_nativewrapper_class, 0)) {
      typeString = "Java object";
    } else {
      snprintf(buf, sizeof(buf), "class %s", objClass->name);
      typeString = buf;
    }
  } else {
    typeString = JsValueTypeStrings[valueType];
  }
  jstring returnValue = jniEnv->NewStringUTF(typeString);
  return returnValue;
}

/*
 * Unwraps a wrapped Java object from a JS object.
 * 
 * Class:     com_google_gwt_dev_shell_moz_JsValueMoz
 * Method:    _getWrappedJavaObject
 * Signature: (I)Ljava/lang/Object;
 */
extern "C" JNIEXPORT jobject JNICALL
Java_com_google_gwt_dev_shell_moz_JsValueMoz__1getWrappedJavaObject
  (JNIEnv* jniEnv, jclass, jint jsRootedValueInt)
{
  JsRootedValue* jsRootedValue = reinterpret_cast<JsRootedValue*>
      (jsRootedValueInt);
  Tracer tracer("JsValueMoz._getWrappedJavaObject", jsRootedValue);
  jsval val = jsRootedValue->getValue();
  if(!JSVAL_IS_OBJECT(val)) {
    tracer.throwHostedModeException(jniEnv, "Javascript value not an object");
    return 0;
  }
  JSObject* jsObject = JSVAL_TO_OBJECT(val);
  JSContext* context = jsRootedValue->getContext();
  if(!JS_InstanceOf(context, jsObject, &gwt_nativewrapper_class, 0)) {
    tracer.throwHostedModeException(jniEnv,
      "Javascript object not a Java object");
    return 0;
  } 
  jobject javaObject
      = NS_REINTERPRET_CAST(jobject, JS_GetPrivate(context, jsObject));
  return javaObject;
} 

/*
 * Class:     com_google_gwt_dev_shell_moz_JsValueMoz
 * Method:    _isBoolean()
 * Signature: (I)Z
 */
extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_gwt_dev_shell_moz_JsValueMoz__1isBoolean
  (JNIEnv* jniEnv, jclass, jint jsRootedValueInt)
{
  JsRootedValue* jsRootedValue = reinterpret_cast<JsRootedValue*>
      (jsRootedValueInt);
  Tracer tracer("JsValueMoz._isBoolean", jsRootedValue);
  return jsRootedValue->isBoolean();
}

/*
 * Class:     com_google_gwt_dev_shell_moz_JsValueMoz
 * Method:    _isInt()
 * Signature: (I)Z
 */
extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_gwt_dev_shell_moz_JsValueMoz__1isInt
  (JNIEnv* jniEnv, jclass, jint jsRootedValueInt)
{
  JsRootedValue* jsRootedValue = reinterpret_cast<JsRootedValue*>
      (jsRootedValueInt);
  Tracer tracer("JsValueMoz._isBoolean", jsRootedValue);
  return jsRootedValue->isInt();
}

/*
 * Checks if a JS object is a JavaScript object.
 * 
 * Class:     com_google_gwt_dev_shell_moz_JsValueMoz
 * Method:    _isJavaScriptObject
 * Signature: (I)Z
 */
extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_gwt_dev_shell_moz_JsValueMoz__1isJavaScriptObject
  (JNIEnv* jniEnv, jclass, jint jsRootedValueInt)
{
  JsRootedValue* jsRootedValue = reinterpret_cast<JsRootedValue*>
      (jsRootedValueInt);
  Tracer tracer("JsValueMoz._isJavaScriptObject", jsRootedValue);
  jsval val = jsRootedValue->getValue();
  bool returnValue = false;
  if(JSVAL_IS_OBJECT(val)) {
    JSObject* jsObject = JSVAL_TO_OBJECT(val);
    returnValue = !JS_InstanceOf(jsRootedValue->getContext(), jsObject,
        &gwt_nativewrapper_class, 0);
    tracer.log("jsobject=%08x, isJSObject=%s", unsigned(jsObject),
        returnValue ? "true" : "false");
  } else {
    tracer.log("not an object");
  }
  return returnValue;
} 

/*
 * Checks if a JS object is a JavaScript String object.
 * 
 * Class:     com_google_gwt_dev_shell_moz_JsValueMoz
 * Method:    _isJavaScriptString
 * Signature: (I)Z
 */
extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_gwt_dev_shell_moz_JsValueMoz__1isJavaScriptString
  (JNIEnv* jniEnv, jclass, jint jsRootedValueInt)
{
  JsRootedValue* jsRootedValue = reinterpret_cast<JsRootedValue*>
      (jsRootedValueInt);
  Tracer tracer("JsValueMoz._isJavaScriptString", jsRootedValue);
  bool returnValue = jsRootedValue->isJavaScriptStringObject();
  tracer.log("value=%s", returnValue ? "true" : "false");
  return returnValue;
} 

/*
 * Class:     com_google_gwt_dev_shell_moz_JsValueMoz
 * Method:    _isNull()
 * Signature: (I)Z
 */
extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_gwt_dev_shell_moz_JsValueMoz__1isNull
  (JNIEnv* jniEnv, jclass, jint jsRootedValueInt)
{
  JsRootedValue* jsRootedValue = reinterpret_cast<JsRootedValue*>
      (jsRootedValueInt);
  Tracer tracer("JsValueMoz._isNull", jsRootedValue);
  return jsRootedValue->isNull();
}

/*
 * Class:     com_google_gwt_dev_shell_moz_JsValueMoz
 * Method:    _isNumber()
 * Signature: (I)Z
 */
extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_gwt_dev_shell_moz_JsValueMoz__1isNumber
  (JNIEnv* jniEnv, jclass, jint jsRootedValueInt)
{
  JsRootedValue* jsRootedValue = reinterpret_cast<JsRootedValue*>
      (jsRootedValueInt);
  Tracer tracer("JsValueMoz._isNumber", jsRootedValue);
  return jsRootedValue->isNumber();
}

/*
 * Class:     com_google_gwt_dev_shell_moz_JsValueMoz
 * Method:    _isString()
 * Signature: (I)Z
 * 
 * Handles the case of JavaScript String objects as well
 */
extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_gwt_dev_shell_moz_JsValueMoz__1isString
  (JNIEnv* jniEnv, jclass, jint jsRootedValueInt)
{
  JsRootedValue* jsRootedValue = reinterpret_cast<JsRootedValue*>
      (jsRootedValueInt);
  Tracer tracer("JsValueMoz._isString", jsRootedValue);
  return jsRootedValue->isString();
}

/*
 * Checks if a JS object is undefined (void)
 * 
 * Class:     com_google_gwt_dev_shell_moz_JsValueMoz
 * Method:    _isUndefined
 * Signature: (I)Z
 */
extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_gwt_dev_shell_moz_JsValueMoz__1isUndefined
  (JNIEnv* jniEnv, jclass, jint jsRootedValueInt)
{
  JsRootedValue* jsRootedValue = reinterpret_cast<JsRootedValue*>
      (jsRootedValueInt);
  Tracer tracer("JsValueMoz._isUndefined", jsRootedValue);
  return jsRootedValue->isUndefined();
} 

/*
 * Checks if a JS object is a wrapped Java object.
 * 
 * Class:     com_google_gwt_dev_shell_moz_JsValueMoz
 * Method:    _isWrappedJavaObject
 * Signature: (I)Z
 */
extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_gwt_dev_shell_moz_JsValueMoz__1isWrappedJavaObject
  (JNIEnv* jniEnv, jclass, jint jsRootedValueInt)
{
  JsRootedValue* jsRootedValue = reinterpret_cast<JsRootedValue*>
      (jsRootedValueInt);
  Tracer tracer("JsValueMoz._isWrappedJavaObject", jsRootedValue);
  jsval val = jsRootedValue->getValue();
  bool returnValue = false;
  if(JSVAL_IS_OBJECT(val)) {
    JSObject* jsObject = JSVAL_TO_OBJECT(val);
    returnValue = JS_InstanceOf(jsRootedValue->getContext(), jsObject,
        &gwt_nativewrapper_class, 0);
    tracer.log("jsobject=%08x, wrappedJava=%s", unsigned(jsObject),
        returnValue ? "true" : "false");
  } else {
    tracer.log("not an object");
  }
  return returnValue;
} 

/*
 * Set the JavaScript value to be a boolean of the supplied value.
 * 
 * Class:     com_google_gwt_dev_shell_moz_JsValueMoz
 * Method:    _setBoolean()
 * Signature: (IZ)V
 */
extern "C" JNIEXPORT void JNICALL
Java_com_google_gwt_dev_shell_moz_JsValueMoz__1setBoolean
  (JNIEnv* jniEnv, jclass, jint jsRootedValueInt, jboolean val)
{
  JsRootedValue* jsRootedValue = reinterpret_cast<JsRootedValue*>
      (jsRootedValueInt);
  Tracer tracer("JsValueMoz._setBoolean", jsRootedValue);
  jsRootedValue->setBoolean(val == JNI_TRUE);
  return;
}

/*
 * Set the JavaScript value to be a double of the supplied value.
 * 
 * Class:     com_google_gwt_dev_shell_moz_JsValueMoz
 * Method:    _setDouble()
 * Signature: (ID)V
 */
extern "C" JNIEXPORT void
JNICALL Java_com_google_gwt_dev_shell_moz_JsValueMoz__1setDouble
  (JNIEnv* jniEnv, jclass, jint jsRootedValueInt, jdouble val)
{
  JsRootedValue* jsRootedValue = reinterpret_cast<JsRootedValue*>
      (jsRootedValueInt);
  Tracer tracer("JsValueMoz._setDouble", jsRootedValue);
  if(!jsRootedValue->setDouble(val)) {
    tracer.throwHostedModeException(jniEnv, "Unable to allocate JS double");
    return;
  }
}

/*
 * Set the Javascript value to be an integer.
 * 
 * Class:     com_google_gwt_dev_shell_moz_JsValueMoz
 * Method:    _setInt()
 * Signature: (II)V
 */
extern "C" JNIEXPORT void JNICALL
Java_com_google_gwt_dev_shell_moz_JsValueMoz__1setInt
  (JNIEnv* jniEnv, jclass, jint jsRootedValueInt, jint val)
{
  JsRootedValue* jsRootedValue = reinterpret_cast<JsRootedValue*>
      (jsRootedValueInt);
  Tracer tracer("JsValueMoz._setInt", jsRootedValue);
  tracer.log("val=%d", val);
  jsRootedValue->setInt(val);
}

/*
 * Set the Javascript value to be another JsRootedValue's value.
 * 
 * Class:     com_google_gwt_dev_shell_moz_JsValueMoz
 * Method:    _setJsRootedValue()
 * Signature: (II)V
 */
extern "C" JNIEXPORT void JNICALL
Java_com_google_gwt_dev_shell_moz_JsValueMoz__1setJsRootedValue
  (JNIEnv* jniEnv, jclass, jint jsRootedValueInt, jint jsOtherRootedValueInt)
{
  JsRootedValue* jsRootedValue = reinterpret_cast<JsRootedValue*>
      (jsRootedValueInt);
  JsRootedValue* jsOtherRootedValue = reinterpret_cast<JsRootedValue*>
      (jsOtherRootedValueInt);
  Tracer tracer("JsValueMoz._setJsRootedValue", jsRootedValue);
  jsRootedValue->setContextValue(jsOtherRootedValue->getContext(),
      jsOtherRootedValue->getValue());
}

/*
 * Set the JavaScript value to be null.
 * 
 * Class:     com_google_gwt_dev_shell_moz_JsValueMoz
 * Method:    _setNull()
 * Signature: (I)V
 */
extern "C" JNIEXPORT void JNICALL
Java_com_google_gwt_dev_shell_moz_JsValueMoz__1setNull
  (JNIEnv* jniEnv, jclass, jint jsRootedValueInt)
{
  JsRootedValue* jsRootedValue = reinterpret_cast<JsRootedValue*>
      (jsRootedValueInt);
  Tracer tracer("JsValueMoz._setNull", jsRootedValue);
  jsRootedValue->setNull();
}

/*
 * Set the JavaScript value to be a string of the supplied value.
 * 
 * Class:     com_google_gwt_dev_shell_moz_JsValueMoz
 * Method:    _setString()
 * Signature: (ILjava/lang/String;)V
 */
extern "C" JNIEXPORT void JNICALL
Java_com_google_gwt_dev_shell_moz_JsValueMoz__1setString
  (JNIEnv* jniEnv, jclass, jint jsRootedValueInt, jstring val)
{
  JsRootedValue* jsRootedValue = reinterpret_cast<JsRootedValue*>
      (jsRootedValueInt);
  Tracer tracer("JsValueMoz._setString", jsRootedValue);
  JStringWrap strVal(jniEnv, val);
  const jchar* stringUTF16 = strVal.jstr();
  if(!stringUTF16) {
    tracer.throwHostedModeException(jniEnv, "Unable to retrieve Java string");
    return;
  }
  tracer.log("string=%s", strVal.str());
  if(!jsRootedValue->setString(reinterpret_cast<const wchar_t*>(stringUTF16))) {
    tracer.throwHostedModeException(jniEnv, "Unable to allocate JS string");
    return;
  }
}

/*
 * Set the JavaScript value to be undefined (void).
 * 
 * Class:     com_google_gwt_dev_shell_moz_JsValueMoz
 * Method:    _setUndefined()
 * Signature: (I)V
 */
extern "C" JNIEXPORT void JNICALL
Java_com_google_gwt_dev_shell_moz_JsValueMoz__1setUndefined
  (JNIEnv* jniEnv, jclass, jint jsRootedValueInt)
{
  JsRootedValue* jsRootedValue = reinterpret_cast<JsRootedValue*>
      (jsRootedValueInt);
  Tracer tracer("JsValueMoz._setUndefined", jsRootedValue);
  jsRootedValue->setUndefined();
}

/*
 * Wraps a Java object in a JS object.
 * 
 * Class:     com_google_gwt_dev_shell_moz_JsValueMoz
 * Method:    _setWrappedJavaObject
 * Signature: (ILjava/lang/Object)V
 */
extern "C" JNIEXPORT void JNICALL
Java_com_google_gwt_dev_shell_moz_JsValueMoz__1setWrappedJavaObject
  (JNIEnv* jniEnv, jclass, jint jsRootedValueInt, jobject obj)
{
  JsRootedValue* jsRootedValue = reinterpret_cast<JsRootedValue*>
      (jsRootedValueInt);
  Tracer tracer("JsValueMoz._setWrappedJavaObject", jsRootedValue);
  JSContext* context = jsRootedValue->getContext();
  JSObject* scriptWindow = JS_GetGlobalObject(context);
  JSObject* newObj = JS_NewObject(context, &gwt_nativewrapper_class, 0,
      scriptWindow);
  if (!newObj) {
    tracer.throwHostedModeException(jniEnv,
        "Unable to allocate JS object to wrap Java object");
    return;
  }
  tracer.log("jsobject=%08x", unsigned(newObj));
  
  // TODO(jat): how does this globalref get freed?
  jobject dispObjRef = jniEnv->NewGlobalRef(obj);
  if (!dispObjRef || jniEnv->ExceptionCheck()) {
    tracer.throwHostedModeException(jniEnv,
        "Unable to allocate global reference for JS wrapper");
    return;
  } 
  if (!JS_SetPrivate(context, newObj, dispObjRef)) {
    jniEnv->DeleteGlobalRef(dispObjRef);
    tracer.throwHostedModeException(jniEnv,
        "Unable to allocate global reference for JS wrapper");
    return;
  } 
  // forcibly setup a "toString" method to override the default
  jclass dispClass = jniEnv->GetObjectClass(obj);
  if (jniEnv->ExceptionCheck()) {
    jniEnv->DeleteGlobalRef(dispObjRef);
    tracer.setFail("can't get object class");
    return;
  } 
  jmethodID getFieldMeth = jniEnv->GetMethodID(dispClass, "getField",
      "(Ljava/lang/String;I)V");
  if (!getFieldMeth || jniEnv->ExceptionCheck()) {
    jniEnv->DeleteGlobalRef(dispObjRef);
    tracer.setFail("can't get getField method");
    return;
  } 
  jstring ident = jniEnv->NewStringUTF("@java.lang.Object::toString()");
  if (!ident || jniEnv->ExceptionCheck()) {
    jniEnv->DeleteGlobalRef(dispObjRef);
    tracer.setFail("can't create Java string for toString method name");
    return;
  }
  // allocate a new root to hold the result of the getField call
  JsRootedValue* toStringFunc = new JsRootedValue(context, JSVAL_VOID); 
  jniEnv->CallVoidMethod(obj, getFieldMeth, ident,
      NS_REINTERPRET_CAST(jint, toStringFunc));
  if (toStringFunc->isUndefined() || jniEnv->ExceptionCheck()) {
    jniEnv->DeleteGlobalRef(dispObjRef);
    tracer.setFail("getField(toString) failed");
    return;
  } 
  if (!JS_DefineProperty(context, newObj, "toString", toStringFunc->getValue(),
      JS_PropertyStub, JS_PropertyStub, JSPROP_READONLY | JSPROP_PERMANENT)) {
    jniEnv->DeleteGlobalRef(dispObjRef);
    tracer.setFail("can't define JS toString method");
    return;
  }
  jsRootedValue->setObject(newObj); 
} 

/*
 * Wraps a Java function in a JS object.
 * 
 * Class:     com_google_gwt_dev_shell_moz_JsValueMoz
 * Method:    _setWrappedFunction
 * Signature: (ILjava/lang/String;Lcom/google/gwt/dev/shell/moz/DispatchMethod;)V
 */
extern "C" JNIEXPORT void JNICALL
Java_com_google_gwt_dev_shell_moz_JsValueMoz__1setWrappedFunction
    (JNIEnv* jniEnv, jclass, jint jsRootedValueInt, jstring methodName,
     jobject dispatchMethod)
{
  JsRootedValue* jsRootedValue = reinterpret_cast<JsRootedValue*>
      (jsRootedValueInt);
  Tracer tracer("JsValueMoz._setWrappedFunction", jsRootedValue);
  JSContext* context = jsRootedValue->getContext();
  JSObject* scriptWindow = JS_GetGlobalObject(context);
  JStringWrap nameStr(jniEnv, methodName);
  if (!nameStr.str()) {
    tracer.throwHostedModeException(jniEnv,
       "null method name passed to setWrappedFunction");
    return;
  }
  tracer.log("JsRootedValue=%08x, method=%s, obj=%08x", jsRootedValueInt,
      nameStr.str(), unsigned(dispatchMethod));
  JSFunction* function = JS_NewFunction(context, invokeJavaMethod, 0, JSFUN_LAMBDA, 0,
      nameStr.str());
  if (!function) {
    tracer.throwHostedModeException(jniEnv, "JS_NewFunction failed");
    return;
  }
  JSObject* funObj = JS_GetFunctionObject(function);
  if (!funObj) {
    tracer.throwHostedModeException(jniEnv, "JS_GetFunctionObject failed");
    return;
  }
  // Create a wrapper object to hold and clean up dispMeth
  JSObject* cleanupObj = JS_NewObject(context, &gwt_functionwrapper_class, 0,
      scriptWindow);
  if (!cleanupObj) {
    tracer.throwHostedModeException(jniEnv, "JS_NewObject failed");
    return;
  }
  jobject dispMethRef = jniEnv->NewGlobalRef(dispatchMethod);
  if (!dispMethRef || jniEnv->ExceptionCheck()) {
    return;
  }

  // Store our global ref in the wrapper object
  if (!JS_SetPrivate(context, cleanupObj, dispMethRef)) {
    jniEnv->DeleteGlobalRef(dispMethRef);
    tracer.throwHostedModeException(jniEnv, "JS_SetPrivate(cleanupObj) failed");
    return;
  }
  // Store the wrapper object in funObj's reserved slot
  if(!JS_SetReservedSlot(context, funObj, 0, OBJECT_TO_JSVAL(cleanupObj))) {
    // TODO(jat): what to do with global ref?
    tracer.throwHostedModeException(jniEnv, "JS_SetReservedSlot failed");
    return;
  }
  jsRootedValue->setObject(funObj);
}      

/*
 * Returns a JavaScript value as a string.
 * 
 * Class:     com_google_gwt_dev_shell_moz_JsValueMoz
 * Method:    _toString
 * Signature: (I)Ljava/lang/String;
 */
extern "C" JNIEXPORT jstring JNICALL
Java_com_google_gwt_dev_shell_moz_JsValueMoz__1toString
  (JNIEnv* jniEnv, jclass, jint jsRootedValueInt)
{
  JsRootedValue* jsRootedValue = reinterpret_cast<JsRootedValue*>
      (jsRootedValueInt);
  Tracer tracer("JsValueMoz._toString", jsRootedValue);
  jsval val = jsRootedValue->getValue();
  JSContext* cx = jsRootedValue->getContext();

  // if it is a JavaScript object that has a toString member function
  // call that, otherwise call JS_ValueToString
  if(JSVAL_IS_OBJECT(val)) {
    JSObject* jsObject = JSVAL_TO_OBJECT(val);
    jsval fval;
    jsval rval;
    if (!JS_InstanceOf(cx, jsObject, &gwt_nativewrapper_class, 0)
        && JS_GetProperty(cx, jsObject, "toString", &fval)
        && JS_ValueToFunction(cx, fval)
        && JS_CallFunctionValue(cx, jsObject, fval, 0, 0, &rval)) {
      // all the steps succeeded, so use the result of toString() instead
      // of the value for JS_ValueToString below
      val = rval;
    }
  }
  JSString* str = JS_ValueToString(cx, val);
  if (!str) {
    return 0;
  }
  int len = JS_GetStringLength(str);
  jstring javaStr =jniEnv->NewString(reinterpret_cast<const jchar*>(
      JS_GetStringChars(str)), len);
  return javaStr;
} 
