/* -*- 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 "nsIXPConnect.idl"

%{ C++
#define NS_SUCCESS_I_DID_SOMETHING \
   (NS_ERROR_GENERATE_SUCCESS(NS_ERROR_MODULE_XPCONNECT,1))

/**
 * Classes that want to only be touched by chrome (or from code whose filename
 * begins with chrome://global/) shoudl return this from their scriptable
 * helper's PreCreate hook.
 */
#define NS_SUCCESS_CHROME_ACCESS_ONLY \
   (NS_ERROR_GENERATE_SUCCESS(NS_ERROR_MODULE_XPCONNECT,2))

/**
 * Classes that want slim wrappers should return NS_SUCCESS_ALLOW_SLIM_WRAPPERS
 * from their scriptable helper's PreCreate hook. They must also force a parent
 * for their wrapper (from the PreCreate hook), they must implement
 * nsWrapperCache and their scriptable helper must implement nsXPCClassInfo and
 * must return DONT_ASK_INSTANCE_FOR_SCRIPTABLE in the flags.
 */
#define NS_SUCCESS_ALLOW_SLIM_WRAPPERS \
   (NS_ERROR_GENERATE_SUCCESS(NS_ERROR_MODULE_XPCONNECT,3))
%}

/**
 * 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(c4788e02-3239-490a-8aeb-60fad08303fd)]
interface nsIXPCScriptable : nsISupports
{
    /* bitflags used for 'flags' (only 32 bits available!) */

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

    // 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 PRUint32 RESERVED                         = 1 << 31;

    readonly attribute string   className;
    [notxpcom,nostdcall] PRUint32 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,
                       in JSValPtr vp);

    // 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 PRUint32 enum_op, in JSValPtr statep, out jsid idp);

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

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

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

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

    boolean call(in nsIXPConnectWrappedNative wrapper,
                in JSContextPtr cx, in JSObjectPtr obj,
                in PRUint32 argc, in JSValPtr argv, in JSValPtr vp);

    boolean construct(in nsIXPConnectWrappedNative wrapper,
                     in JSContextPtr cx, in JSObjectPtr obj,
                     in PRUint32 argc, in JSValPtr argv, in JSValPtr vp);

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

    boolean equality(in nsIXPConnectWrappedNative wrapper,
                    in JSContextPtr cx, in JSObjectPtr obj, in jsval val);

    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 PRUint32 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));
}

%}
