/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
 *
 * ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (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.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is Mozilla Communicator client code, released
 * March 31, 1998.
 *
 * The Initial Developer of the Original Code is
 * Netscape Communications Corporation.
 * Portions created by the Initial Developer are Copyright (C) 1998
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *   John Bandhauer <jband@netscape.com> (original author)
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either of the GNU General Public License Version 2 or later (the "GPL"),
 * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 * in which case the provisions of the GPL or the LGPL are applicable instead
 * of those above. If you wish to allow use of your version of this file only
 * under the terms of either the GPL or the LGPL, and not to allow others to
 * use your version of this file under the terms of the MPL, indicate your
 * decision by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL or the LGPL. If you do not delete
 * the provisions above, a recipient may use your version of this file under
 * the terms of any one of the MPL, the GPL or the LGPL.
 *
 * ***** END LICENSE BLOCK ***** */

#include "nsISupports.idl"
#include "nsIXPConnect.idl"

[ptr] native JSTracerPtr(JSTracer);

%{ 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(9cadb17b-9990-461a-8e01-cf50aeffc2c5)]
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;
    const PRUint32 WANT_TRACE                       = 1 << 16;
    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 DONT_SHARE_PROTOTYPE             = 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;
    readonly attribute PRUint32 scriptableFlags;

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

    void   postCreate(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 JSContextPtr cx, 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);

    void trace(in nsIXPConnectWrappedNative wrapper,
               in JSTracerPtr trc, in JSObjectPtr obj);

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

    /**
     * Notify that we're about to create the prototype object for this class,
     * and ask what prototype we should use for that.
     */
    void preCreatePrototype(in JSContextPtr cx,
                            in JSObjectPtr globalObj,
                            out JSObjectPtr protoProtoObj);
};

%{ 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));
}

%}
