// -*- c++ -*-

/*
 *  Copyright (C) 2001-2003, Richard J. Moore <rich@kde.org>
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Library General Public
 *  License as published by the Free Software Foundation; either
 *  version 2 of the License, or (at your option) any later version.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Library General Public License for more details.
 *
 *  You should have received a copy of the GNU Library General Public License
 *  along with this library; see the file COPYING.LIB.  If not, write to
 *  the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 *  Boston, MA 02111-1307, USA.
 */

#ifndef KJSEMBEDJSCONSOLEPART_H
#define KJSEMBEDJSCONSOLEPART_H

#include <qstringlist.h>

#ifndef QT_ONLY
#include <kparts/part.h>
#endif

#include <kjs/interpreter.h>
#include <kjs/object.h>
#include <kjs/value.h>

#include <kjsembed/jsbinding.h>

#ifndef QT_ONLY
#include <kjsembed/xmlactionclient.h>
#else
#include <kjsembed/qtstubs.h>
#endif

class QWidget;

#define KJSEMBED_VERSION_STRING "0.3"
#define KJSEMBED_VERSION_MAJOR 0
#define KJSEMBED_VERSION_MINOR 3

/**
 * Namespace containing the KJSEmbed library.
 */
namespace KJSEmbed {

class JSObjectProxy;
class JSConsoleWidget;
class JSFactory;
class JSBuiltIn;

/**
 * A KPart for embedding KJS in an application.
 *
 * @version $Id: kjsembedpart.h,v 1.31 2004/04/16 23:47:08 rich Exp $
 * @author Richard Moore, rich@kde.org
 */
class KJSEmbedPart : public KParts::ReadOnlyPart
{
    Q_OBJECT
    Q_PROPERTY( QStringList constructorNames READ constructorNames )
    Q_PROPERTY( QCString versionString READ versionString )
    Q_PROPERTY( int versionMajor READ versionMajor )
    Q_PROPERTY( int versionMinor READ versionMinor )

public:
    /** Create a KJSEmbedPart. */
    KJSEmbedPart( QObject *parent=0, const char *name=0 );

    /** 
     * Creates a KJSEmbedPart for which the parents of the view and part are different. 
     *
     * Caution! you cannot use parent = [KQ]Application and wparent = 0L.
     * This will cause a crash on exit since the widget will not be destroyed
     * but the part will get destroyed at the end of the QApplication
     * constructor.  This results in the widget trying to do GUI related things
     * after the QPaint stuff is destroyed.
     */
    KJSEmbedPart( QWidget *wparent, const char *wname=0, QObject *parent=0, const char *name=0 );

    /**
     * Create a KJSEmbedPart with the specified interpreter.
     *
     * See warning above.
     */
    KJSEmbedPart( KJS::Interpreter *js, QWidget *wparent, const char *wname=0,
		  QObject *parent=0, const char *name=0 );

    /** Cleans up. */
    virtual ~KJSEmbedPart();

    //
    // Version information
    //

    /** Returns the version of KJSEmbed. */
    QCString versionString() const;

    /** Returns the minor version number of KJSEmbed. */
    int versionMajor() const;

    /** Returns the major version number of KJSEmbed. */
    int versionMinor() const;

    //
    // Script environment.
    //

    /** Returns the global object of the interpreter. */
    KJS::Object globalObject() const { return js->globalObject(); }

    /** Returns the completion object for the last script executed. */
    KJS::Completion completion() const { return res; }

    /** Returns the JS object of the part. */
    KJS::Object partObject() const { return partobj; }

    /**
     * Publishes 'obj' as property 'name' of the global object. If 'name' is
     * not specified then the name property of 'obj' is used instead.
     */
    KJS::Object addObject( QObject *obj, const char *name=0 );

    /**
     * Publishes 'obj' as property 'name' of object 'parent'. The binding is defined
     * using @ref JSObjectProxy, and is subject to the current default SecurityPolicy.
     */
    KJS::Object addObject( QObject *obj, KJS::Object &parent, const char *name=0 );

    /** Returns a JS::Object that provides a binding to the specified QObject. */
    KJS::Object bind( QObject *obj );

    //
    // Query the supported types
    //

    /** Returns a list of the names of the constructors of this interpreter. */
    QStringList constructorNames() const;

    /** Returns a JS Array of the constructors of this interpreter. */
    KJS::Value constructors() const;

    /** Returns a list of the constructors of this interpreter. */
    KJS::List constructorList() const;

public slots:
    //
    // Reimplement the KPart API.
    //

    /** Returns the view widget, creating one if required.*/
    virtual KJSEmbed::JSConsoleWidget *view();

    /** Opens a URL. If the URL has the protocol 'javascript' then it is executed. */
    virtual bool openURL( const KURL &url );

    //
    // XML Action Handling
    //

    /** Returns the current XMLActionClient. */
    KJSEmbed::XMLActionClient *actionClient() const { return xmlclient; }

    /** Loads the XML actions defined in the specified file to the default XMLActionClient. */
    bool loadActionSet( const QString &file );

    //
    // Script environemnt
    //

    /** Returns the current interpreter. */
    KJS::Interpreter *interpreter() const { return js; }

    /** Returns the execution context of the interpreter. */
    KJS::ExecState *globalExec() const { return js->globalExec(); }

    /** Returns the current factory object. */
    JSFactory *factory() const { return jsfactory; }

    /** Evaluates the specified string, with the specified value as 'this'. */
    virtual KJS::Value evaluate( const QString &script, const KJS::Value &self=KJS::Null() );

    /** Executes the specified string, with the specified value as 'this'. */
    bool execute( const QString &script, const KJS::Value &self=KJS::Null() );

    /**
     * Executes the specified string, with the specified value as 'this' and sets
     * result to the completion object returned by the interpreter.
     */
    virtual bool execute( KJS::Completion &result, const QString &script, const KJS::Value &self );

    /** Loads and runs the specified file. */
    virtual bool runFile( const QString &filename, const KJS::Value &self=KJS::Null() );

    /**
     * Loads but does not execute the specified script file. If the
     * first line of the file starts with the string '#!' then that
     * line will be omitted from the returned string.
     */
    QString loadFile( const QString &file );

protected:
    /** Creates the interpreter. */
    void createInterpreter();

    /**
     * Creates the built-in objects and methods in the specified parent object
     * normally the global object of the interpreter. This method is called
     * automatically unless you create the part with a custom interpreter, if
     * you do then you have to call this method yourself if you want the
     * built-ins to be available.
     */
    void createBuiltIn( KJS::ExecState *exec, KJS::Object &parent );

    /** Sets up the XMLActionClient. */
    void createActionClient();

    /** Reimplemented to disable file support. */
    virtual bool openFile() { return false; }

    /** @internal Hook for virtual that cannot break compatibility. */
    virtual void virtual_hook( int id, void *data );

private:
    XMLActionClient *xmlclient;
    JSConsoleWidget *jsConsole;
    JSFactory *jsfactory;
    JSBuiltIn *builtins;
    QWidget *widgetparent;
    QCString widgetname;

    KJS::Object partobj;
    KJS::Completion res;
    KJS::Interpreter *js;
    bool deletejs;

    class KJSEmbedPartPrivate *d;
};


} // namespace KJSEmbed

#endif // KJSEMBEDJSCONSOLEPART_H

// Local Variables:
// c-basic-offset: 4
// End:

