/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
 *
 * 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.org code
 * 
 * The Initial Developer of the Original Code is
 * Netscape Communications Corporation
 * Portions created by Netscape are
 * Copyright (C) 1998 Netscape Communications Corporation.
 *
 * Alternatively, the contents of this file may be used under the
 * terms of the GNU Public License (the "GPL"), in which case the
 * provisions of the GPL are applicable instead of those above.
 * If you wish to allow use of your version of this file only
 * under the terms of the GPL and not to allow others to use your
 * version of this file under the MPL, indicate your decision by
 * deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL.  If you do not delete
 * the provisions above, a recipient may use your version of this
 * file under either the MPL or the GPL.
 *
 * Contributor(s):
 *   Robert Ginda, <rginda@netscape.com>
 *
 */
    
#include "nsISupports.idl"

%{ C++
#include "jsdebug.h"
#include "nsAReadableString.h"
%}
    
[ptr] native JSDContext(JSDContext);
[ptr] native JSDObject(JSDObject);
[ptr] native JSDProperty(JSDProperty);
[ptr] native JSDScript(JSDScript);
[ptr] native JSDStackFrameInfo(JSDStackFrameInfo);
[ptr] native JSDThreadState(JSDThreadState);
[ptr] native JSDValue(JSDValue);
[ptr] native JSRuntime(JSRuntime);

native jsuword(jsuword);

interface jsdIValue;

/* handle objects */

/*
[scriptable, uuid(a2dd25a4-1dd1-11b2-bda6-ed525acd4c35)]
interface jsdIContext : nsISupports
{
    [noscript] readonly attribute JSDContext JSDContext;
};
*/

[scriptable, uuid(d500e8b8-1dd1-11b2-89a1-cdf55d91cbbd)]
interface jsdIObject : nsISupports
{
    [noscript] readonly attribute JSDContext JSDContext;
    [noscript] readonly attribute JSDObject  JSDObject;

    readonly attribute string        creatorURL;
    readonly attribute unsigned long creatorLine;
    readonly attribute string        constructorURL;
    readonly attribute unsigned long constructorLine;
    readonly attribute jsdIValue     value;
};

[scriptable, uuid(e7c8ea2c-1dd1-11b2-9242-f2768e04e92e)]
interface jsdIPC : nsISupports
{
    [noscript] readonly attribute jsuword pc;
};

[scriptable, uuid(b8816e56-1dd1-11b2-81dc-8ba99a833d9e)]
interface jsdIProperty : nsISupports
{
    [noscript] readonly attribute JSDContext  JSDContext;
    [noscript] readonly attribute JSDProperty JSDProperty;

    const unsigned long FLAG_ENUMERATE = 0x01;  /* visible to for/in loop */
    const unsigned long FLAG_READONLY  = 0x02;  /* assignment is error */
    const unsigned long FLAG_PERMANENT = 0x04;  /* property cannot be deleted */
    const unsigned long FLAG_ALIAS     = 0x08;  /* property has an alias id */
    const unsigned long FLAG_ARGUMENT  = 0x10;  /* argument to function */
    const unsigned long FLAG_VARIABLE  = 0x20;  /* local variable in function */
    const unsigned long FLAG_HINTED    = 0x800; /* found via explicit lookup */

    readonly attribute jsdIValue     alias;
    readonly attribute unsigned long flags;
    readonly attribute jsdIValue     name;
    readonly attribute jsdIValue     value;
    readonly attribute unsigned long varArgSlot;
};

[scriptable, uuid(a38f65ca-1dd1-11b2-95d5-ff2947e9c920)]
interface jsdIScript : nsISupports
{
    [noscript] readonly attribute JSDContext JSDContext;
    [noscript] readonly attribute JSDScript  JSDScript;

    /* Releases the private data held by the wrapped JSDScript, and clears the
     * wrapped JSDScript.
     * This jsdIScript instance will no longer be useful.
     * This should ONLY be called internally, in response to a JSDScript's 
     * destruction by the jsd library.
     */
    [noscript] void invalidate(); 

    readonly attribute boolean       isActive;
    readonly attribute string        fileName;
    readonly attribute string        functionName;
    readonly attribute unsigned long baseLineNumber;
    readonly attribute unsigned long lineExtent;

    unsigned long pcToLine (in jsdIPC pc);
    jsdIPC lineToPc (in unsigned long line);    
    void setBreakpoint (in jsdIPC pc);
    void clearBreakpoint (in jsdIPC pc);
    void clearAllBreakpoints ();
};

[scriptable, uuid(a47adad2-1dd1-11b2-b9e9-8e67a47beca5)]
interface jsdISourceText : nsISupports
{};

[scriptable, uuid(b6d50784-1dd1-11b2-a932-882246c6fe45)]
interface jsdIStackFrame : nsISupports
{
    [noscript] readonly attribute JSDContext        JSDContext;
    [noscript] readonly attribute JSDThreadState    JSDThreadState;
    [noscript] readonly attribute JSDStackFrameInfo JSDStackFrameInfo;
    
    readonly attribute jsdIStackFrame callingFrame;
    readonly attribute jsdIScript     script;
    readonly attribute jsdIPC         pc;
    readonly attribute unsigned long  line;
    readonly attribute jsdIValue      callee;
    readonly attribute jsdIValue      scope;
    readonly attribute jsdIValue      thisValue;

    jsdIValue eval (in AString bytes, in string fileName,
                    in unsigned long line);

};

/*
[scriptable, uuid(b6d1c006-1dd1-11b2-b9d8-b4d1ccfb74d8)]
interface jsdIThreadState : nsISupports
{
    [noscript] readonly attribute JSDContext     JSDContext;
    [noscript] readonly attribute JSDThreadState JSDThreadState;
    
    readonly attribute unsigned long  frameCount;
    readonly attribute jsdIStackFrame topFrame;
    
    attribute jsdIValue pendingException;
};
*/

[scriptable, uuid(b7964304-1dd1-11b2-ba20-cf4205772e9d)]
interface jsdIValue : nsISupports
{
    [noscript] readonly attribute JSDContext JSDContext;
    [noscript] readonly attribute JSDValue   JSDValue;

    readonly attribute boolean isNative;
    readonly attribute boolean isNumber;
    readonly attribute boolean isPrimitive;

    const unsigned long TYPE_BOOLEAN  = 0;
    const unsigned long TYPE_DOUBLE   = 1;
    const unsigned long TYPE_INT      = 2;
    const unsigned long TYPE_FUNCTION = 3;
    const unsigned long TYPE_NULL     = 4;
    const unsigned long TYPE_OBJECT   = 5;
    const unsigned long TYPE_STRING   = 6;
    const unsigned long TYPE_VOID     = 7;
    const unsigned long TYPE_UNKNOWN  = 8;
    
    readonly attribute unsigned long jsType;
    readonly attribute jsdIValue     jsPrototype;
    readonly attribute jsdIValue     jsParent;
    readonly attribute string        jsClassName;
    readonly attribute jsdIValue     jsConstructor;
    readonly attribute string        jsFunctionName;
    
    readonly attribute boolean    booleanValue;
    readonly attribute double     doubleValue;
    readonly attribute long       intValue;
    readonly attribute jsdIObject objectValue;
    readonly attribute string     stringValue;

    readonly attribute long propertyCount;
    
    void getProperties ([array, size_is(length)] out jsdIProperty propArray,
                        out unsigned long length);
    jsdIProperty getProperty (in string name);

    void refresh();    
};

/* callback interfaces */
[scriptable, uuid(ae89a7e2-1dd1-11b2-8c2f-af82086291a5)]
interface jsdIScriptHook : nsISupports
{
    void onScriptCreated (in jsdIScript script);
    void onScriptDestroyed (in jsdIScript script);
};

[scriptable, uuid(9a7b6ad0-1dd1-11b2-a789-fcfae96356a2)]
interface jsdIExecutionHook : nsISupports
{
    const unsigned long TYPE_INTERRUPTED      = 0;
    const unsigned long TYPE_BREAKPOINT       = 1;
    const unsigned long TYPE_DEBUG_REQUESTED  = 2;
    const unsigned long TYPE_DEBUGGER_KEYWORD = 3;
    const unsigned long TYPE_THROW            = 4;
    
    const unsigned long RETURN_HOOK_ERROR     = 0;
    const unsigned long RETURN_CONTINUE       = 1;
    const unsigned long RETURN_ABORT          = 2;
    const unsigned long RETURN_RET_WITH_VAL   = 3;
    const unsigned long RETURN_THROW_WITH_VAL = 4;
    const unsigned long RETURN_CONTINUE_THROW = 5;

    /* val is current exception (if any) when this method is called.  If you
     * return with RETURN_THROW_WITH_VAL, whatever you set |val| to will be
     * thrown.  If you return with RETURN_RET_WITH_VAL, whatever you set |val|
     * to will be the return value of this script. 
     */
    unsigned long onExecute (in jsdIStackFrame frame, 
                             in unsigned long type, inout jsdIValue val);
};

/* script enumeration callback */
[scriptable, uuid(4c2f706e-1dd2-11b2-9ebc-85a06e948830)]
interface jsdIScriptEnumerator : nsISupports
{
    boolean enumerateScript (in jsdIScript script);
};

/* debugger service */
[scriptable, uuid(01be7f9a-1dd2-11b2-9d55-aaf919b27c73)]
interface jsdIDebuggerService : nsISupports
{
    attribute jsdIExecutionHook breakpointHook;
    attribute jsdIExecutionHook debuggerHook;
    attribute jsdIExecutionHook errorHook;
    attribute jsdIExecutionHook interruptHook;
    attribute jsdIScriptHook    scriptHook;
    attribute jsdIExecutionHook throwHook;
    
    void on ();  /* this function should only be called from js */
    [noscript] void onForRuntime (in JSRuntime rt); /* native version of on() */
    void off ();

    void enumerateScripts (in jsdIScriptEnumerator enumerator);
    void clearAllBreakpoints ();
    
    /* XXX temporary hacks */
    unsigned long enterNestedEventLoop ();
    unsigned long exitNestedEventLoop ();
};
