#ifndef SCRIPTABLEPLUGINOBJECTBASE_H
#define SCRIPTABLEPLUGINOBJECTBASE_H

#include <Javascript/NPApi.h>

//---------------------------------------------------------------------------------------
// 
// Helper class that can be used to map calls to the NPObject hooks
// into virtual methods on instances of classes that derive from this
// class.
//
//---------------------------------------------------------------------------------------

namespace Awesomium
{
  class WebView;
};

class CppNpObject : public NPObject
{
public:
  explicit CppNpObject(Awesomium::WebView* view)
  : m_view(view)
  {
  }

  virtual ~CppNpObject()
  {
  }

  // Virtual NPObject hooks called through this base class. Override
  // as you see fit.
  virtual void Invalidate();
  virtual bool HasMethod(NPIdentifier name);
  virtual bool Invoke(NPIdentifier name, const NPVariant *args,
                      uint32_t argCount, NPVariant *result);
  virtual bool InvokeDefault(const NPVariant *args, uint32_t argCount,
                             NPVariant *result);
  virtual bool HasProperty(NPIdentifier name);
  virtual bool GetProperty(NPIdentifier name, NPVariant *result);
  virtual bool SetProperty(NPIdentifier name, const NPVariant *value);
  virtual bool RemoveProperty(NPIdentifier name);

public:
  static void _Deallocate(NPObject *npobj);
  static void _Invalidate(NPObject *npobj);
  static bool _HasMethod(NPObject *npobj, NPIdentifier name);
  static bool _Invoke(NPObject *npobj, NPIdentifier name,
                      const NPVariant *args, uint32_t argCount,
                      NPVariant *result);
  static bool _InvokeDefault(NPObject *npobj, const NPVariant *args,
                             uint32_t argCount, NPVariant *result);
  static bool _HasProperty(NPObject * npobj, NPIdentifier name);
  static bool _GetProperty(NPObject *npobj, NPIdentifier name,
                           NPVariant *result);
  static bool _SetProperty(NPObject *npobj, NPIdentifier name,
                           const NPVariant *value);
  static bool _RemoveProperty(NPObject *npobj, NPIdentifier name);

protected:
  Awesomium::WebView* m_view;
};

//----------------------------------------------------------------------------

#define DECLARE_NPOBJECT_CLASS(_class)                        \
public: static NPClass _NPClass;

//----------------------------------------------------------------------------

#define DEFINE_NPOBJECT_CLASS(_class, ctor)                         \
NPClass _class::_NPClass = {                                                  \
  NP_CLASS_STRUCT_VERSION,                                                    \
  ctor,                                                                       \
  CppNpObject::_Deallocate,                                    \
  CppNpObject::_Invalidate,                                    \
  CppNpObject::_HasMethod,                                     \
  CppNpObject::_Invoke,                                        \
  CppNpObject::_InvokeDefault,                                 \
  CppNpObject::_HasProperty,                                   \
  CppNpObject::_GetProperty,                                   \
  CppNpObject::_SetProperty,                                   \
  CppNpObject::_RemoveProperty                                 \
}

//----------------------------------------------------------------------------

#define GET_NPOBJECT_CLASS(_class) &_class::_NPClass

//----------------------------------------------------------------------------

#endif