/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#include "nsISupports.idl"
#include "nsIClassInfo.idl"

%{C++
#ifdef XP_WIN
#undef GetClassName
#endif

#include "js/TypeDecls.h"

struct JSFreeOp;
%}

interface nsIXPConnectWrappedNative;

[ptr] native JSContextPtr(JSContext);
[ptr] native JSObjectPtr(JSObject);
[ptr] native JSValPtr(JS::Value);
[ptr] native JSFreeOpPtr(JSFreeOp);
[ref] native JSCallArgsRef(const JS::CallArgs);

/**
 * Note: This is not really an XPCOM interface.  For example, callers must
 * guarantee that they set the *_retval of the various methods that return a
 * boolean to PR_TRUE before making the call.  Implementations may skip writing
 * to *_retval unless they want to return PR_FALSE.
 */
[uuid(187b7295-255d-469c-b7b3-ce91373df24b)]
interface nsIXPCScriptable : nsISupports
{
    /* bitflags used for 'flags' (only 32 bits available!) */

    const uint32_t WANT_PRECREATE                   = 1 <<  0;
    const uint32_t WANT_CREATE                      = 1 <<  1;
    const uint32_t WANT_POSTCREATE                  = 1 <<  2;
    const uint32_t WANT_ADDPROPERTY                 = 1 <<  3;
    const uint32_t WANT_DELPROPERTY                 = 1 <<  4;
    const uint32_t WANT_GETPROPERTY                 = 1 <<  5;
    const uint32_t WANT_SETPROPERTY                 = 1 <<  6;
    const uint32_t WANT_ENUMERATE                   = 1 <<  7;
    const uint32_t WANT_NEWENUMERATE                = 1 <<  8;
    const uint32_t WANT_NEWRESOLVE                  = 1 <<  9;
    const uint32_t WANT_CONVERT                     = 1 << 10;
    const uint32_t WANT_FINALIZE                    = 1 << 11;
    // unused bit here!
    const uint32_t WANT_CALL                        = 1 << 13;
    const uint32_t WANT_CONSTRUCT                   = 1 << 14;
    const uint32_t WANT_HASINSTANCE                 = 1 << 15;
    // Unused bit here!
    const uint32_t USE_JSSTUB_FOR_ADDPROPERTY       = 1 << 17;
    const uint32_t USE_JSSTUB_FOR_DELPROPERTY       = 1 << 18;
    const uint32_t USE_JSSTUB_FOR_SETPROPERTY       = 1 << 19;
    const uint32_t DONT_ENUM_STATIC_PROPS           = 1 << 20;
    const uint32_t DONT_ENUM_QUERY_INTERFACE        = 1 << 21;
    const uint32_t DONT_ASK_INSTANCE_FOR_SCRIPTABLE = 1 << 22;
    const uint32_t CLASSINFO_INTERFACES_ONLY        = 1 << 23;
    const uint32_t ALLOW_PROP_MODS_DURING_RESOLVE   = 1 << 24;
    const uint32_t ALLOW_PROP_MODS_TO_PROTOTYPE     = 1 << 25;
    const uint32_t IS_GLOBAL_OBJECT                 = 1 << 26;
    const uint32_t DONT_REFLECT_INTERFACE_NAMES     = 1 << 27;
    // Unused bit here!
    const uint32_t WANT_OUTER_OBJECT                = 1 << 29;

    // The high order bit is RESERVED for consumers of these flags. 
    // No implementor of this interface should ever return flags 
    // with this bit set.
    const uint32_t RESERVED                         = 1 << 31;

    readonly attribute string   className;
    [notxpcom,nostdcall] uint32_t getScriptableFlags();

    void   preCreate(in nsISupports nativeObj, in JSContextPtr cx,
                     in JSObjectPtr globalObj, out JSObjectPtr parentObj);

    void   create(in nsIXPConnectWrappedNative wrapper,
                  in JSContextPtr cx, in JSObjectPtr obj);

    // Both methods here are protected by WANT_POSTCREATE. If you want to do
    // something after a wrapper is created, there's a good chance you also
    // want to do something when the wrapper is transplanted to a new
    // compartment.
    void   postCreate(in nsIXPConnectWrappedNative wrapper,
                      in JSContextPtr cx, in JSObjectPtr obj);

    void postTransplant(in nsIXPConnectWrappedNative wrapper,
                        in JSContextPtr cx, in JSObjectPtr obj);

    boolean addProperty(in nsIXPConnectWrappedNative wrapper,
                       in JSContextPtr cx, in JSObjectPtr obj, in jsid id,
                       in JSValPtr vp);

    boolean delProperty(in nsIXPConnectWrappedNative wrapper,
                       in JSContextPtr cx, in JSObjectPtr obj, in jsid id);

    // The returnCode should be set to NS_SUCCESS_I_DID_SOMETHING if
    // this method does something.
    boolean getProperty(in nsIXPConnectWrappedNative wrapper,
                       in JSContextPtr cx, in JSObjectPtr obj, in jsid id,
                       in JSValPtr vp);

    // The returnCode should be set to NS_SUCCESS_I_DID_SOMETHING if
    // this method does something.
    boolean setProperty(in nsIXPConnectWrappedNative wrapper,
                       in JSContextPtr cx, in JSObjectPtr obj, in jsid id,
                       in JSValPtr vp);

    boolean enumerate(in nsIXPConnectWrappedNative wrapper,
                     in JSContextPtr cx, in JSObjectPtr obj);

    boolean newEnumerate(in nsIXPConnectWrappedNative wrapper,
                        in JSContextPtr cx, in JSObjectPtr obj,
                        in uint32_t enum_op, in JSValPtr statep, out jsid idp);

    boolean newResolve(in nsIXPConnectWrappedNative wrapper,
                      in JSContextPtr cx, in JSObjectPtr obj, in jsid id,
                      in uint32_t flags, out JSObjectPtr objp);

    boolean convert(in nsIXPConnectWrappedNative wrapper,
                   in JSContextPtr cx, in JSObjectPtr obj,
                   in uint32_t type, in JSValPtr vp);

    void   finalize(in nsIXPConnectWrappedNative wrapper,
                    in JSFreeOpPtr fop, in JSObjectPtr obj);

    boolean call(in nsIXPConnectWrappedNative wrapper,
                in JSContextPtr cx, in JSObjectPtr obj,
                in JSCallArgsRef args);

    boolean construct(in nsIXPConnectWrappedNative wrapper,
                     in JSContextPtr cx, in JSObjectPtr obj,
                     in JSCallArgsRef args);

    boolean hasInstance(in nsIXPConnectWrappedNative wrapper,
                       in JSContextPtr cx, in JSObjectPtr obj,
                       in jsval val, out boolean bp);

    JSObjectPtr outerObject(in nsIXPConnectWrappedNative wrapper,
                            in JSContextPtr cx, in JSObjectPtr obj);

    void postCreatePrototype(in JSContextPtr cx, in JSObjectPtr proto);
};

%{ C++

#include "nsAutoPtr.h"

#define NS_XPCCLASSINFO_IID \
{ 0x9a5b0342, 0x0f70, 0x4d31, \
 { 0xb7, 0xd7, 0x29, 0x68, 0xa5, 0x70, 0x4b, 0xd8 } }

class NS_NO_VTABLE nsXPCClassInfo : public nsIClassInfo,
                                    public nsIXPCScriptable
{
public:
  NS_DECLARE_STATIC_IID_ACCESSOR(NS_XPCCLASSINFO_IID)

  NS_IMETHOD_(nsrefcnt) AddRef() = 0;
  NS_IMETHOD_(nsrefcnt) Release() = 0;

  virtual void PreserveWrapper(nsISupports *aNative) = 0;

  virtual uint32_t GetInterfacesBitmap() = 0;
};

NS_DEFINE_STATIC_IID_ACCESSOR(nsXPCClassInfo, NS_XPCCLASSINFO_IID)

inline
nsresult
CallQueryInterface(nsISupports* aSourcePtr,
                   nsRefPtrGetterAddRefs<nsXPCClassInfo> aDestPtr)
{
  return CallQueryInterface(aSourcePtr,
                            static_cast<nsXPCClassInfo**>(aDestPtr));
}

%}
