#ifndef _H_NPVariantWrapper
#define _H_NPVariantWrapper

#include <string>
#include <ostream>

#ifdef sun
// Sun's cstring doesn't define strlen/etc
#include <string.h>
#endif
#include <cstring>
#include <stdio.h>

#include "Debug.h"
#include "Platform.h"

#include "mozincludes.h"

#include "Value.h"
#include "LocalObjectTable.h"
#include "Plugin.h"
#include "JavaObject.h"

/**
 * Contains NPVariantProxy, NPVariantWrapper, and NPVariantArray
 */

/**
 * Wraps an NPVariant and provides various conversion functions.  The variant
 * provided retained at create time.
 */
class NPVariantProxy {
  friend class NPVariantArray;
private:
  ScriptableInstance& plugin;
  NPVariant& variant;
public:
  NPVariantProxy(ScriptableInstance& plugin, NPVariant& variant)
      : plugin(plugin), variant(variant)
  {
    VOID_TO_NPVARIANT(variant);
  }
  
  NPVariantProxy(ScriptableInstance& plugin, NPVariant& variant, bool noinit)
      : plugin(plugin), variant(variant)
  {
  }

  ~NPVariantProxy() {
  }
  
  operator NPVariant() const {
    return variant;
  }
  
  const NPVariant* operator->() const {
	return &variant;
  }

  const NPVariant* address() const {
    return &variant;
  }

  int isBoolean() const {
    return isBoolean(variant);
  }

  static int isBoolean(const NPVariant& variant) {
    return NPVARIANT_IS_BOOLEAN(variant);
  }

  bool getAsBoolean() const {
    return getAsBoolean(variant);
  }

  static bool getAsBoolean(const NPVariant& variant) {
    return NPVARIANT_TO_BOOLEAN(variant);
  }

  int isInt() const {
    return isInt(variant);
  }
  
  static int isInt(const NPVariant& variant) {
    return NPVARIANT_IS_INT32(variant);
  }

  int getAsInt() const {
    return getAsInt(variant);
  }

  static int getAsInt(const NPVariant& variant) {
    if (NPVARIANT_IS_INT32(variant)) {
      return NPVARIANT_TO_INT32(variant);
    }
    Debug::log(Debug::Error) << "getAsInt: variant not int" << Debug::flush;
    return 0;
  }

  int isNull() const {
    return isNull(variant);
  }
  
  static int isNull(const NPVariant& variant) {
    return NPVARIANT_IS_NULL(variant);
  }

  int isObject() const {
    return isObject(variant);
  }
  
  static int isObject(const NPVariant& variant) {
    return NPVARIANT_IS_OBJECT(variant);
  }

  NPObject* getAsObject() const {
    return getAsObject(variant);
  }

  static NPObject* getAsObject(const NPVariant& variant) {
    if (NPVARIANT_IS_OBJECT(variant)) {
      return NPVARIANT_TO_OBJECT(variant);
    }
    Debug::log(Debug::Error) << "getAsObject: variant not object" << Debug::flush;
    return 0;
  }

  int isString() const {
    return isString(variant);
  }
  
  static int isString(const NPVariant& variant) {
    return NPVARIANT_IS_STRING(variant);
  }

  const NPString* getAsNPString() const {
    return getAsNPString(variant);
  }

  static const NPString* getAsNPString(const NPVariant& variant) {
    if (NPVARIANT_IS_STRING(variant)) {
      return &NPVARIANT_TO_STRING(variant);
    }
    Debug::log(Debug::Error) << "getAsNPString: variant not string" << Debug::flush;
    return 0;
  }

  Value getAsValue(ScriptableInstance& scriptInstance, bool unwrapJava = true) const {
    return getAsValue(variant, scriptInstance, unwrapJava);
  }

  static Value getAsValue(const NPVariant& variant, ScriptableInstance& scriptInstance,
      bool unwrapJava = true) {
    Value val;
    if (NPVARIANT_IS_VOID(variant)) {
      val.setUndefined();
    } else if (NPVARIANT_IS_NULL(variant)) {
      val.setNull();
    } else if (NPVARIANT_IS_BOOLEAN(variant)) {
      val.setBoolean(NPVARIANT_TO_BOOLEAN(variant));
    } else if (NPVARIANT_IS_INT32(variant)) {
      val.setInt(NPVARIANT_TO_INT32(variant));      
    } else if (NPVARIANT_IS_DOUBLE(variant)) {
      val.setDouble(NPVARIANT_TO_DOUBLE(variant));
    } else if (NPVARIANT_IS_STRING(variant)) {
      NPString str = NPVARIANT_TO_STRING(variant);
      val.setString(GetNPStringUTF8Characters(str), GetNPStringUTF8Length(str));
    } else if (NPVARIANT_IS_OBJECT(variant)) {
      NPObject* obj = NPVARIANT_TO_OBJECT(variant);
      if (unwrapJava && JavaObject::isInstance(obj)) {
        JavaObject* jObj = static_cast<JavaObject*>(obj);
        val.setJavaObject(jObj->getObjectId());
      } else {
        NPVariant result;
        VOID_TO_NPVARIANT(result);
        if (scriptInstance.tryGetStringPrimitive(obj, result)) {
          NPString str = NPVARIANT_TO_STRING(result);
          val.setString(GetNPStringUTF8Characters(str), GetNPStringUTF8Length(str));
          release(result);
        } else {
          val.setJsObjectId(scriptInstance.getLocalObjectRef(obj));
        }
      }
    } else {
      Debug::log(Debug::Error) << "Unsupported NPVariant type " << variant.type << Debug::flush;
    }
    return val;
  }
  
  /**
   * The incoming variant is not altered, and is not even required to have
   * its contents retained.  Any object will get an extra refcount on it
   * when copied to this variant, and strings will be copied.
   */
  NPVariantProxy& operator=(const NPVariant& newval) {
    assignFrom(variant, newval);
    return *this;
  }

  /**
   * The incoming variant is not altered, and is not even required to have
   * its contents retained.  Any object will get an extra refcount on it
   * when copied to this variant, and strings will be copied.
   */
  static void assignFrom(NPVariant& variant, const NPVariant& newval) {
    release(variant);
    variant = newval;
    if (NPVARIANT_IS_STRING(newval)) {
      int n = variant.value.stringValue.UTF8Length;
      char* strBytes = reinterpret_cast<char*>(NPN_MemAlloc(n));
      memcpy(strBytes, variant.value.stringValue.UTF8Characters, n);
      variant.value.stringValue.UTF8Characters = strBytes;
    } else {
      retain(variant);
    }
  }

  NPVariantProxy& operator=(NPObject* obj) {
    assignFrom(variant, obj);
    return *this;
  }
  
  static void assignFrom(NPVariant& variant, NPObject* obj) {
    release(variant);
    OBJECT_TO_NPVARIANT(obj, variant);
    retain(variant);
  }

  // Convenience method for C++ code
  NPVariantProxy& operator=(int intVal) {
    assignFrom(variant, intVal);
    return *this;
  }

  // Convenience method for C++ code
  static void assignFrom(NPVariant& variant, int intVal) {
    NPVariant newvar;
    INT32_TO_NPVARIANT(intVal, newvar);
    assignFrom(variant, newvar);
  }

  // Convenience method for C++ code
  NPVariantProxy& operator=(const std::string& strval) {
    assignFrom(variant, strval);
    return *this;
  }

  // Convenience method for C++ code
  static void assignFrom(NPVariant& variant, const std::string& strval) {
    NPVariant newvar;
    STDSTRING_TO_NPVARIANT(strval, newvar);
    assignFrom(variant, newvar);
  }
  
  // Convenience method for C++ code
  NPVariantProxy& operator=(const char* strval) {
    assignFrom(variant, strval);
    return *this;
  }

  // Convenience method for C++ code
  static void assignFrom(NPVariant& variant, const char* strval) {
    NPVariant newvar;
    STRINGZ_TO_NPVARIANT(strval, newvar);
    assignFrom(variant, newvar);
  }

  NPVariantProxy& operator=(const Value& newval) {
    assignFrom(plugin, variant, newval);
    return *this;
  }

  static void assignFrom(ScriptableInstance& plugin, NPVariant& variant, const Value& newval) {
    NPVariant newvar;
    VOID_TO_NPVARIANT(newvar);
    if (newval.isBoolean()) {
      BOOLEAN_TO_NPVARIANT(newval.getBoolean(), newvar);
    } else if (newval.isByte()) {
      INT32_TO_NPVARIANT(newval.getByte(), newvar);
    } else if (newval.isChar()) {
      INT32_TO_NPVARIANT(newval.getChar(), newvar);
    } else if (newval.isShort()) {
      INT32_TO_NPVARIANT(newval.getShort(), newvar);
    } else if (newval.isInt()) {
      int value = newval.getInt();
      // Firefox NPAPI bug: 32-bit ints get mapped to int jsvals, regardless of range.
      // However, int jsvals are 31 bits, so we need to use a double if the value is
      // not representable in a 31 bit signed 2's-complement value.
      if (value >= 0x40000000 || value < -0x40000000) {
        DOUBLE_TO_NPVARIANT(static_cast<double>(value), newvar);
      } else {
        INT32_TO_NPVARIANT(value, newvar);
      }
    } else if (newval.isFloat()) {
      DOUBLE_TO_NPVARIANT(newval.getFloat(), newvar);
    } else if (newval.isDouble()) {
      DOUBLE_TO_NPVARIANT(newval.getDouble(), newvar);
    } else if (newval.isNull()) {
      NULL_TO_NPVARIANT(newvar);
    } else if (newval.isUndefined()) {
      VOID_TO_NPVARIANT(newvar);
    } else if (newval.isString()) {
      assignFrom(variant, newval.getString());
      return;
    } else if (newval.isJavaObject()) {
      if (1) {
        JavaObject* jObj = plugin.createJavaWrapper(newval.getJavaObjectId());
        NPObject* obj = jObj;
        OBJECT_TO_NPVARIANT(obj, newvar);
      } else {
        VOID_TO_NPVARIANT(newvar);
      }
    } else if (newval.isJsObject()) {
      OBJECT_TO_NPVARIANT(plugin.getLocalObject(newval.getJsObjectId()),
    	  newvar);
    } else {
      Debug::log(Debug::Error) << "Unsupported NPVariant type " << newval.getType() << Debug::flush;
    }
    assignFrom(variant, newvar);
  }

  std::string toString() const {
    return toString(variant);
  }

  static std::string toString(const NPVariant& variant) {
    std::string retval;
    // TODO(jat): remove sprintfs
    char buf[40];
    NPObject* npObj;
    switch (variant.type) {
      case NPVariantType_Void:
        retval = "undef";
        break;
      case NPVariantType_Null:
        retval = "null";
        break;
      case NPVariantType_Bool:
        retval = "bool(";
        retval += (NPVARIANT_TO_BOOLEAN(variant) ? "true" : "false");
        retval += ')';
        break;
      case NPVariantType_Int32:
        retval = "int(";
        snprintf(buf, sizeof(buf), "%d)", NPVARIANT_TO_INT32(variant));
        retval += buf;
        break;
      case NPVariantType_Double:
        retval = "double(";
        snprintf(buf, sizeof(buf), "%g)", NPVARIANT_TO_DOUBLE(variant));
        retval += buf;
        break;
      case NPVariantType_String:
        {
          retval = "string(";
          NPString str = NPVARIANT_TO_STRING(variant);
          retval += std::string(str.UTF8Characters, str.UTF8Length);
          retval += ')';
        }
        break;
      case NPVariantType_Object:
        npObj = NPVARIANT_TO_OBJECT(variant);
        if (JavaObject::isInstance(npObj)) {
          JavaObject* javaObj = static_cast<JavaObject*>(npObj);
          snprintf(buf, sizeof(buf), "javaObj(id=%d, ", javaObj->getObjectId());
        } else {
          snprintf(buf, sizeof(buf), "jsObj(class=%p, ", npObj->_class);
        }
        retval = buf;
        snprintf(buf, sizeof(buf), "%p)", npObj);
        retval += buf;
        break;
      default:
        snprintf(buf, sizeof(buf), "Unknown type %d", variant.type);
        retval = buf;
        break;
    }
    return retval;
  }

public:
  void release() {
    release(variant);
  }

  static void release(NPVariant& variant) {
    NPN_ReleaseVariantValue(&variant);
  }

  void retain() {
    retain(variant);
  }

  static void retain(NPVariant& variant) {
    if (NPVARIANT_IS_OBJECT(variant)) {
      NPN_RetainObject(NPVARIANT_TO_OBJECT(variant));
    }
  }
};

inline Debug::DebugStream& operator<<(Debug::DebugStream& dbg, const NPVariant& var) {
  return dbg << NPVariantProxy::toString(var);
}

inline Debug::DebugStream& operator<<(Debug::DebugStream& dbg, const NPVariantProxy& var) {
  return dbg << var.toString();
}

/**
 * Variation of NPVariantProxy that provides its own variant and always frees it
 * when the wrapper goes away.
 */
class NPVariantWrapper  {
private:
  ScriptableInstance& plugin;
  NPVariant variant;
public:
  NPVariantWrapper(ScriptableInstance& plugin) : plugin(plugin) {
    VOID_TO_NPVARIANT(variant);
  }

  ~NPVariantWrapper() {
    release();
  }

  operator NPVariant() const {
    return variant;
  }

  const NPVariant* operator->() const {
  return &variant;
  }

  const NPVariant* address() const {
    return &variant;
  }

  /**
   * Get the address for use as a return value.  Since the value can be trashed,
   * we need to release any data we currently hold.
   */
  NPVariant* addressForReturn() {
    NPVariantProxy::release(variant);
    VOID_TO_NPVARIANT(variant);
    NPVariantProxy::retain(variant); // does nothing, present for consistency
    return &variant;
  }
  
  bool isBoolean() const {
    return NPVariantProxy::isBoolean(variant);
  }

  int isInt() const {
    return NPVariantProxy::isInt(variant);
  }
  
  int isObject() const {
    return NPVariantProxy::isObject(variant);
  }
  
  int isString() const {
    return NPVariantProxy::isString(variant);
  }
  
  bool getAsBoolean() const {
    return NPVariantProxy::getAsBoolean(variant);
  }

  int getAsInt() const {
    return NPVariantProxy::getAsInt(variant);
  }

  NPObject* getAsObject() const {
    return NPVariantProxy::getAsObject(variant);
  }

  const NPString* getAsNPString() const {
    return NPVariantProxy::getAsNPString(variant);
  }

  Value getAsValue(ScriptableInstance& scriptInstance, bool unwrapJava = true) const {
    return NPVariantProxy::getAsValue(variant, scriptInstance, unwrapJava);
  }

  /**
   * The incoming variant is not altered, and is not even required to have
   * its contents retained.  Any object will get an extra refcount on it
   * when copied to this variant, and strings will be copied.
   */
  NPVariantWrapper& operator=(const NPVariant& newval) {
    NPVariantProxy::assignFrom(variant, newval);
    return *this;
  }

  NPVariantWrapper& operator=(const Value& newval) {
    NPVariantProxy::assignFrom(plugin, variant, newval);
    return *this;
  }
  
  NPVariantWrapper& operator=(NPObject* obj) {
    NPVariantProxy::assignFrom(variant, obj);
    return *this;
  }
  
  // Convenience method for C++ code
  NPVariantWrapper& operator=(const std::string& strval) {
    NPVariantProxy::assignFrom(variant, strval);
    return *this;
  }

  // Convenience method for C++ code
  NPVariantWrapper& operator=(const char* strval) {
    NPVariantProxy::assignFrom(variant, strval);
    return *this;
  }

  // Convenience method for C++ code
  NPVariantWrapper& operator=(int intval) {
    NPVariantProxy::assignFrom(variant, intval);
    return *this;
  }

  void release() {
    NPVariantProxy::release(variant);
  }

  void retain() {
    NPVariantProxy::retain(variant);
  }

  std::string toString() const {
    return NPVariantProxy::toString(variant);
  }
};

inline Debug::DebugStream& operator<<(Debug::DebugStream& dbg, const NPVariantWrapper& var) {
  dbg << var.toString();
  return dbg;
}

/**
 * Maintains an array of NPVariants and cleans them up when it is destroyed.
 */
class NPVariantArray {
private:
	ScriptableInstance& plugin;
  int size;
  NPVariant* args;

public:
  NPVariantArray(ScriptableInstance& plugin, int size) : plugin(plugin), size(size) {
    args = new NPVariant[size];
    for (int i = 0; i < size; ++i) {
      VOID_TO_NPVARIANT(args[i]);
    }
  }

  ~NPVariantArray() {
    for (int i = 0; i < size; ++i) {
      NPN_ReleaseVariantValue(&args[i]);
    }
    delete [] args;
  }

  const NPVariant* getArray() const {
    return args;
  }

  int getSize() const {
    return size;
  }

  const NPVariant& operator[](int idx) const {
    if (idx >= size) {
      printf("NPVariantArray[idx=%d] const: size=%d\n", idx, size);
    }
    return args[idx];
  }

  NPVariantProxy operator[](int idx) {
    if (idx >= size) {
      printf("NPVariantArray[idx=%d]: size=%d\n", idx, size);
    }
    return NPVariantProxy(plugin, args[idx], true);
  }
};

inline Debug::DebugStream& operator<<(Debug::DebugStream& dbg, const NPVariantArray& var) {
  dbg << "[";
  for (int i = 0; i < var.getSize(); ++i) {
    dbg << " " << var[i]; 
  }
  dbg << " ]";
  return dbg;
}

#endif
