#ifndef _H_ScriptableInstance
#define _H_ScriptableInstance
/*
 * 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.
 */

#include <vector>
#include <set>

#include "Debug.h"

#include "mozincludes.h"
#include "HostChannel.h"
#include "LoadModuleMessage.h"
#include "LocalObjectTable.h"
#include "SessionHandler.h"
#include "HashMap.h"

using std::vector;

class JavaObject;
class JavaClass;
class Plugin;

class ScriptableInstance : public NPObjectWrapper<ScriptableInstance>, SessionHandler {
  friend class JavaObject;
public:
  ScriptableInstance(NPP npp);
  ~ScriptableInstance();

  void pluginDeath() {
    // our local objects will get freed anyway when the plugin dies
    localObjects.freeAll();
    localObjects.setDontFree(true);
    // TODO(jat): leaving this in causes SEGV upon plugin destruction in the
    // NPN_ReleaseObject call.
//    if (window) {
//      NPN_ReleaseObject(window);
//      window = 0;
//    }
  }
  
  // NPObjectWrapper methods
  bool enumeration(NPIdentifier** values, uint32_t* count);
  bool getProperty(NPIdentifier name, NPVariant* result);
  bool setProperty(NPIdentifier name, const NPVariant* value);
  bool invoke(NPIdentifier name, const NPVariant* args, unsigned argCount, NPVariant* result);
  bool invokeDefault(const NPVariant* args, unsigned argCount, NPVariant* result);
  bool hasMethod(NPIdentifier name);
  bool hasProperty(NPIdentifier name);
  
  void dumpJSresult(const char* js);
  
  int getLocalObjectRef(NPObject* obj);
  NPObject* getLocalObject(int refid) { return localObjects.get(refid); }
  
  bool tryGetStringPrimitive(NPObject* obj, NPVariant& result);

  JavaObject* createJavaWrapper(int objectId);
  void destroyJavaWrapper(JavaObject*);

  static const uint32_t VERSION = 1;

protected:
  virtual void disconnectDetectedImpl();

private:  
  // Map of object ID to JavaObject
  hash_map<int, JavaObject*> javaObjects;
  std::set<int> javaObjectsToFree;
  
  vector<JavaClass*> classes;
  
  Plugin& plugin;
  HostChannel* _channel;
  LocalObjectTable localObjects;

  int savedValueIdx;

  // Identifiers
  const NPIdentifier _connectId;
  const NPIdentifier initID;
  const NPIdentifier toStringID;
  
  const NPIdentifier connectedID;
  const NPIdentifier statsID;
  const NPIdentifier gwtId;

  const NPIdentifier jsDisconnectedID;
  const NPIdentifier jsInvokeID;
  const NPIdentifier jsResultID;
  const NPIdentifier jsTearOffID;
  const NPIdentifier jsValueOfID;
  const NPIdentifier idx0;
  const NPIdentifier idx1;
  
  NPObject* window;
  void dupString(const char* str, NPString& npString);
  void dumpObjectBytes(NPObject* obj);
  bool makeResult(bool isException, const Value& value, NPVariant* result);
  
  // SessionHandler methods
  virtual bool invoke(HostChannel& channel, const Value& thisObj,
      const std::string& methodName, int numArgs, const Value* const args,
      Value* returnValue);
  virtual bool invokeSpecial(HostChannel& channel, SpecialMethodId dispatchId,
      int numArgs, const Value* const args, Value* returnValue);
  virtual void freeValue(HostChannel& channel, int idCount, const int* ids);
  virtual void sendFreeValues(HostChannel& channel);
  virtual void loadJsni(HostChannel& channel, const std::string& js);
  virtual void fatalError(HostChannel& channel, const std::string& message);

  void connect(const NPVariant* args, unsigned argCount, NPVariant* result);
  void init(const NPVariant* args, unsigned argCount, NPVariant* result);
  
  Value clientMethod_getProperty(HostChannel& channel, int numArgs, const Value* const args);
  Value clientMethod_setProperty(HostChannel& channel, int numArgs, const Value* const args);
  
  void JavaObject_invalidate(int objectId);
  bool JavaObject_invoke(int objectId, int dispId, const NPVariant* args,
      uint32_t numArgs, NPVariant* result);
  bool JavaObject_getProperty(int objectId, int dispId, NPVariant* result);
  bool JavaObject_setProperty(int objectId, int dispId, const NPVariant* value);
  bool JavaObject_getToStringTearOff(NPVariant* result);

private:
  std::string computeTabIdentity();
};

#endif
