/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the ActiveQt framework of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** BSD License Usage
** Alternatively, you may use this file under the terms of the BSD license
** as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
**   * Redistributions of source code must retain the above copyright
**     notice, this list of conditions and the following disclaimer.
**   * Redistributions in binary form must reproduce the above copyright
**     notice, this list of conditions and the following disclaimer in
**     the documentation and/or other materials provided with the
**     distribution.
**   * Neither the name of The Qt Company Ltd nor the names of its
**     contributors may be used to endorse or promote products derived
**     from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qaxscript.h"
#include "../shared/qaxutils_p.h"

#if defined(Q_CC_GNU) && (__MINGW64_VERSION_MAJOR == 3 && __MINGW64_VERSION_MINOR > 0 || __MINGW64_VERSION_MAJOR >= 4)
// Workaround for mingw-w64 bug #464
// See https://sourceforge.net/p/mingw-w64/bugs/464/
# define _NO_SCRIPT_GUIDS
#endif

#include <qapplication.h>
#include <qfile.h>
#include <qhash.h>
#include <qmetaobject.h>
#include <quuid.h>
#include <qwidget.h>
#include <qvector.h>

#include <qt_windows.h>
#ifndef QT_NO_QAXSCRIPT
#include <initguid.h>
#include <activscp.h>
#endif

#include "../shared/qaxtypes.h"

QT_BEGIN_NAMESPACE

struct QAxEngineDescriptor { QString name, extension, code; };
static QVector<QAxEngineDescriptor> engines;

class QAxScriptManagerPrivate
{
public:
    QHash<QString, QAxScript*> scriptDict;
    QHash<QString, QAxBase*> objectDict;
};

/*
    \class QAxScriptSite
    \brief The QAxScriptSite class implements a Windows Scripting Host
    \internal

    The QAxScriptSite is used internally to communicate callbacks from the script
    engine to the script manager.
*/

#ifndef QT_NO_QAXSCRIPT

class QAxScriptSite : public IActiveScriptSite, public IActiveScriptSiteWindow
{
    Q_DISABLE_COPY_MOVE(QAxScriptSite)
public:
    QAxScriptSite(QAxScript *script);
    virtual ~QAxScriptSite() = default;

    ULONG WINAPI AddRef() override;
    ULONG WINAPI Release() override;
    HRESULT WINAPI QueryInterface(REFIID iid, void **ppvObject) override;

    HRESULT WINAPI GetLCID(LCID *plcid) override;
    HRESULT WINAPI GetItemInfo(LPCOLESTR pstrName, DWORD dwReturnMask,
                               IUnknown **ppiunkItem, ITypeInfo **ppti) override;
    HRESULT WINAPI GetDocVersionString(BSTR *pbstrVersion) override;

    HRESULT WINAPI OnScriptTerminate(const VARIANT *pvarResult, const EXCEPINFO *pexcepinfo) override;
    HRESULT WINAPI OnStateChange(SCRIPTSTATE ssScriptState) override;
    HRESULT WINAPI OnScriptError(IActiveScriptError *pscripterror) override;
    HRESULT WINAPI OnEnterScript() override;
    HRESULT WINAPI OnLeaveScript() override;

    HRESULT WINAPI GetWindow(HWND *phwnd) override;
    HRESULT WINAPI EnableModeless(BOOL fEnable) override;

protected:
    QWidget *window() const;

private:
    QAxScript *script;
    LONG ref = 1;
};

/*
    Constructs the site for the \a s.
*/
QAxScriptSite::QAxScriptSite(QAxScript *s) : script(s)
{
}

/*
    Implements IUnknown::AddRef
*/
ULONG WINAPI QAxScriptSite::AddRef()
{
    return InterlockedIncrement(&ref);
}

/*
    Implements IUnknown::Release
*/
ULONG WINAPI QAxScriptSite::Release()
{
    LONG refCount = InterlockedDecrement(&ref);
    if (!refCount)
        delete this;

    return refCount;
}

/*
    Implements IUnknown::QueryInterface
*/
HRESULT WINAPI QAxScriptSite::QueryInterface(REFIID iid, void **ppvObject)
{
    *ppvObject = nullptr;
    if (iid == IID_IUnknown)
        *ppvObject = static_cast<IUnknown *>(static_cast<IActiveScriptSite *>(this));
    else if (iid == IID_IActiveScriptSite)
        *ppvObject = static_cast<IActiveScriptSite *>(this);
    else if (iid == IID_IActiveScriptSiteWindow)
        *ppvObject = static_cast<IActiveScriptSiteWindow *>(this);
    else
        return E_NOINTERFACE;

    AddRef();
    return S_OK;
}

/*
    Implements IActiveScriptSite::GetLCID

    This method is not implemented. Use the system-defined locale.
*/
HRESULT WINAPI QAxScriptSite::GetLCID(LCID * /*plcid*/)
{
    return E_NOTIMPL;
}

/*
    Implements IActiveScriptSite::GetItemInfo

    Tries to find the QAxBase for \a pstrName and returns the
    relevant interfaces in \a item and \a type as requested through \a mask.
*/
HRESULT WINAPI QAxScriptSite::GetItemInfo(LPCOLESTR pstrName, DWORD mask, IUnknown **item, ITypeInfo **type)
{
    if (item)
        *item = nullptr;
    else if (mask & SCRIPTINFO_IUNKNOWN)
        return E_POINTER;

    if (type)
        *type = nullptr;
    else if (mask & SCRIPTINFO_ITYPEINFO)
        return E_POINTER;

    QAxBase *object = script->findObject(QString::fromWCharArray(pstrName));
    if (!object)
        return TYPE_E_ELEMENTNOTFOUND;

    if (mask & SCRIPTINFO_IUNKNOWN)
        object->queryInterface(IID_IUnknown, reinterpret_cast<void **>(item));
    if (mask & SCRIPTINFO_ITYPEINFO) {
        IProvideClassInfo *classInfo = nullptr;
        object->queryInterface(IID_IProvideClassInfo, reinterpret_cast<void **>(&classInfo));
        if (classInfo) {
            classInfo->GetClassInfo(type);
            classInfo->Release();
        }
    }
    return S_OK;
}

/*
    Implements IActiveScriptSite::GetDocVersionString

    This method is not implemented. The scripting engine should assume
    that the script is in sync with the document.
*/
HRESULT WINAPI QAxScriptSite::GetDocVersionString(BSTR * /*version*/)
{
    return E_NOTIMPL;
}

/*
    Implements IActiveScriptSite::OnScriptTerminate

    This method is usually not called, but if it is it fires
    QAxScript::finished().
*/
HRESULT WINAPI QAxScriptSite::OnScriptTerminate(const VARIANT *result, const EXCEPINFO *exception)
{
    emit script->finished();

    if (result && result->vt != VT_EMPTY)
        emit script->finished(VARIANTToQVariant(*result, nullptr));
    if (exception)
        emit script->finished(exception->wCode,
                              QString::fromWCharArray(exception->bstrSource),
                              QString::fromWCharArray(exception->bstrDescription),
                              QString::fromWCharArray(exception->bstrHelpFile)
                             );
    return S_OK;
}

/*
    Implements IActiveScriptSite::OnEnterScript

    Fires QAxScript::entered() to inform the host that the
    scripting engine has begun executing the script code.
*/
HRESULT WINAPI QAxScriptSite::OnEnterScript()
{
    emit script->entered();
    return S_OK;
}

/*
    Implements IActiveScriptSite::OnLeaveScript

    Fires QAxScript::finished() to inform the host that the
    scripting engine has returned from executing the script code.
*/
HRESULT WINAPI QAxScriptSite::OnLeaveScript()
{
    emit script->finished();
    return S_OK;
}

/*
    Implements IActiveScriptSite::OnScriptError

    Fires QAxScript::error() to inform the host that an
    that an execution error occurred while the engine was running the script.
*/
HRESULT WINAPI QAxScriptSite::OnScriptError(IActiveScriptError *error)
{
    EXCEPINFO exception;
    memset(&exception, 0, sizeof(exception));
    DWORD context;
    ULONG lineNumber;
    LONG charPos;
    BSTR bstrLineText;
    QString lineText;

    error->GetExceptionInfo(&exception);
    error->GetSourcePosition(&context, &lineNumber, &charPos);
    HRESULT hres = error->GetSourceLineText(&bstrLineText);
    if (hres == S_OK) {
        lineText = QString::fromWCharArray(bstrLineText);
        SysFreeString(bstrLineText);
    }
    SysFreeString(exception.bstrSource);
    SysFreeString(exception.bstrDescription);
    SysFreeString(exception.bstrHelpFile);

    emit script->error(exception.wCode, QString::fromWCharArray(exception.bstrDescription),
                       int(lineNumber), lineText);

    return S_OK;
}

/*
    Implements IActiveScriptSite::OnStateChange

    Fires QAxScript::stateChanged() to inform the
    the host that the scripting engine has changed states.
*/
HRESULT WINAPI QAxScriptSite::OnStateChange(SCRIPTSTATE ssScriptState)
{
    emit script->stateChanged(ssScriptState);
    return S_OK;
}

/*
    \internal
    Returns the toplevel widget parent of this script, or
    the application' active window if there is no widget parent.
*/
QWidget *QAxScriptSite::window() const
{
    QWidget *w = nullptr;
    QObject *p = script->parent();
    while (!w && p) {
        w = qobject_cast<QWidget*>(p);
        p = p->parent();
    }

    if (w)
        w = w->window();
    if (!w && qApp)
        w = QApplication::activeWindow();

    return w;
}

/*
    Implements IActiveScriptSiteWindow::GetWindow

    Retrieves the handle to a window that can act as the owner of a
    pop-up window that the scripting engine must display.
*/
HRESULT WINAPI QAxScriptSite::GetWindow(HWND *phwnd)
{
    if (!phwnd)
        return E_POINTER;

    *phwnd = nullptr;
    QWidget *w = window();
    if (!w)
        return E_FAIL;

    // FIXME: 4.10.2011 Does this work with the parent's HWND?
    *phwnd = hwndForWidget(w);
    return S_OK;
}

/*
    Implements IActiveScriptSiteWindow::EnableModeless

    Causes the host to enable or disable its main window
    as well as any modeless dialog boxes.
*/
HRESULT WINAPI QAxScriptSite::EnableModeless(BOOL fEnable)
{
    QWidget *w = window();
    if (!w)
        return E_FAIL;

    // FIXME: 4.10.2011 Does this work with the parent's HWND?
    EnableWindow(hwndForWidget(w), fEnable);
    return S_OK;
}

#endif //QT_NO_QAXSCRIPT


/*!
    \class QAxScriptEngine
    \brief The QAxScriptEngine class provides a wrapper around a script engine.
    \inmodule QAxContainer

    Every instance of the QAxScriptEngine class represents an interpreter
    for script code in a particular scripting language. The class is usually
    not used directly. The QAxScript and QAxScriptManager classes provide
    convenient functions to handle and call script code.

    Direct access to the script engine is provided through
    queryInterface().

    \warning This class is not available with the bcc5.5 compiler.

    \sa QAxScript, QAxScriptManager, QAxBase, {ActiveQt Framework}
*/

/*!
    \enum QAxScriptEngine::State

    The State enumeration defines the different states a script
    engine can be in.

    \value Uninitialized The script has been created, but not yet initialized
    \value Initialized The script has been initialized, but is not running
    \value Started The script can execute code, but does not yet handle events
    \value Connected The script can execute code and is connected so
    that it can handle events
    \value Disconnected The script is loaded, but is not connected to
    event sources
    \value Closed The script has been closed.
*/

/*!
    \fn QAxScriptEngine::QAxScriptEngine(const QString &language, QAxScript *script)

    Constructs a QAxScriptEngine object interpreting script code in \a language
    provided by the code in \a script. This is usually done by the QAxScript
    class when \link QAxScript::load() loading a script\endlink.

    Instances of QAxScriptEngine should always have both a language and a
    script.
*/
QAxScriptEngine::QAxScriptEngine(const QString &language, QAxScript *script)
: QAxObject(script), script_code(script), engine(nullptr), script_language(language)
{
#ifdef QT_CHECK_STATE
    if (language.isEmpty())
        qWarning("QAxScriptEngine: created without language");

    if (!script_code)
        qWarning("QAxScriptEngine: created without script");
#endif
    setObjectName(QLatin1String("QAxScriptEngine_") + language);
    disableClassInfo();
    disableEventSink();
}

/*!
    \fn QAxScriptEngine::~QAxScriptEngine()
    Destroys the QAxScriptEngine object, releasing all allocated
    resources.
*/
QAxScriptEngine::~QAxScriptEngine()
{
#ifndef QT_NO_QAXSCRIPT
    if (engine) {
        engine->SetScriptState(SCRIPTSTATE_DISCONNECTED);
        engine->Close();
        engine->Release();
    }
#endif
}

/*!
    \fn QString QAxScriptEngine::scriptLanguage() const
    Returns the scripting language, for example "VBScript",
    or "JScript".
*/

/*!
    \fn bool QAxScriptEngine::initialize(IUnknown **ptr)
    \reimp
*/
bool QAxScriptEngine::initialize(IUnknown **ptr)
{
    *ptr = nullptr;

#ifndef QT_NO_QAXSCRIPT
    if (!script_code || script_language.isEmpty())
        return false;

    CLSID clsid;
    HRESULT hres = CLSIDFromProgID(reinterpret_cast<const wchar_t *>(script_language.utf16()), &clsid);
    if(FAILED(hres))
        return false;

    CoCreateInstance(clsid, nullptr, CLSCTX_INPROC_SERVER, IID_IActiveScript, reinterpret_cast<void **>(&engine));
    if (!engine)
        return false;

    IActiveScriptParse *parser = nullptr;
    engine->QueryInterface(IID_IActiveScriptParse, reinterpret_cast<void **>(&parser));
    if (!parser) {
        engine->Release();
        engine = nullptr;
        return false;
    }

    if (engine->SetScriptSite(script_code->script_site) != S_OK) {
        engine->Release();
        engine = nullptr;
        return false;
    }
    if (parser->InitNew() != S_OK) {
        parser->Release();
        engine->Release();
        engine = nullptr;
        return false;
    }

    BSTR bstrCode = QStringToBSTR(script_code->scriptCode());
#ifdef Q_OS_WIN64
    hres = parser->ParseScriptText(bstrCode, nullptr, nullptr, nullptr, DWORDLONG(this), 0, SCRIPTTEXT_ISVISIBLE, nullptr, nullptr);
#else
    hres = parser->ParseScriptText(bstrCode, 0, 0, 0, DWORD(this), 0, SCRIPTTEXT_ISVISIBLE, 0, 0);
#endif
    SysFreeString(bstrCode);

    parser->Release();
    parser = nullptr;

    script_code->updateObjects();

    if (engine->SetScriptState(SCRIPTSTATE_CONNECTED) != S_OK) {
        engine = nullptr;
        return false;
    }

    IDispatch *scriptDispatch = nullptr;
    engine->GetScriptDispatch(nullptr, &scriptDispatch);
    if (scriptDispatch) {
        scriptDispatch->QueryInterface(IID_IUnknown, reinterpret_cast<void **>(ptr));
        scriptDispatch->Release();
    }
#endif

    return *ptr != nullptr;
}

/*!
    \fn bool QAxScriptEngine::isValid() const

    Returns true if the script engine has been initialized
    correctly; otherwise returns false.
*/

/*!
    \fn bool QAxScriptEngine::hasIntrospection() const
    Returns true if the script engine supports introspection;
    otherwise returns false.
*/
bool QAxScriptEngine::hasIntrospection() const
{
    if (!isValid())
        return false;

    IDispatch *scriptDispatch = nullptr;
    QAxBase::queryInterface(IID_IDispatch, reinterpret_cast<void **>(&scriptDispatch));
    if (!scriptDispatch)
        return false;

    UINT tic = 0;
    HRESULT hres = scriptDispatch->GetTypeInfoCount(&tic);
    scriptDispatch->Release();
    return hres == S_OK && tic > 0;
}

/*!
    \fn long QAxScriptEngine::queryInterface(const QUuid &uuid, void **iface) const
    Requests the interface \a uuid from the script engine object and
    sets the value of \a iface to the provided interface, or to 0 if
    the requested interface could not be provided.

    Returns the result of the QueryInterface implementation of the COM
    object.
*/
long QAxScriptEngine::queryInterface(const QUuid &uuid, void **iface) const
{
    *iface = nullptr;
    if (!engine)
        return E_NOTIMPL;

#ifndef QT_NO_QAXSCRIPT
    return engine->QueryInterface(uuid, iface);
#else
    Q_UNUSED(uuid);
    Q_UNUSED(iface);
    return E_NOTIMPL;
#endif
}

/*!
    \fn QAxScriptEngine::State QAxScriptEngine::state() const
    Returns the state of the script engine.
*/
QAxScriptEngine::State QAxScriptEngine::state() const
{
    if (!engine)
        return Uninitialized;

#ifndef QT_NO_QAXSCRIPT
    SCRIPTSTATE state;
    engine->GetScriptState(&state);
    return State(state);
#else
    return Uninitialized;
#endif
}

/*!
    \fn void QAxScriptEngine::setState(State st)
    Sets the state of the script engine to \a st.
    Calling this function is usually not necessary.
*/
void QAxScriptEngine::setState(State st)
{
#ifndef QT_NO_QAXSCRIPT
    if (!engine)
        return;

    engine->SetScriptState(SCRIPTSTATE(st));
#else
    Q_UNUSED(st);
#endif
}

/*!
    \fn void QAxScriptEngine::addItem(const QString &name)
    Registers an item with the script engine. Script code can
    refer to this item using \a name.
*/
void QAxScriptEngine::addItem(const QString &name)
{
#ifndef QT_NO_QAXSCRIPT
    if (!engine)
        return;

    engine->AddNamedItem(reinterpret_cast<const wchar_t *>(name.utf16()),
                         SCRIPTITEM_ISSOURCE|SCRIPTITEM_ISVISIBLE);
#else
    Q_UNUSED(name);
#endif
}

/*!
    \class QAxScript
    \brief The QAxScript class provides a wrapper around script code.
    \inmodule QAxContainer

    Every instance of the QAxScript class represents a piece of
    scripting code in a particular scripting language. The code is
    loaded into the script engine using load(). Functions declared
    in the code can be called using call().

    The script provides scriptEngine() provides feedback to the
    application through signals. The most important signal is the
    error() signal. Direct access to the QAxScriptEngine is provided
    through the scriptEngine() function.

    \warning This class is not available with the bcc5.5 compiler.

    \sa QAxScriptEngine, QAxScriptManager, QAxBase, {ActiveQt Framework}
*/

/*!
    \enum QAxScript::FunctionFlags

    This FunctionFlags enum describes formatting for function introspection.

    \value FunctionNames Only function names are returned.
    \value FunctionSignatures Returns the functions with signatures.
*/

/*!
    \fn QAxScript::QAxScript(const QString &name, QAxScriptManager *manager)

    Constructs a QAxScript object called \a name and registers
    it with the QAxScriptManager \a manager. This is usually done by the
    QAxScriptManager class when \link QAxScriptManager::load() loading a
    script\endlink.

    A script should always have a name. A manager is necessary to allow
    the script code to reference objects in the application. The \a manager
    takes ownership of the object.
*/
QAxScript::QAxScript(const QString &name, QAxScriptManager *manager)
: QObject(manager), script_name(name), script_manager(manager),
script_engine(nullptr)
{
    if (manager) {
        manager->d->scriptDict.insert(name, this);
        connect(this, SIGNAL(error(int,QString,int,QString)),
            manager, SLOT(scriptError(int,QString,int,QString)));
    }

#ifndef QT_NO_QAXSCRIPT
    script_site = new QAxScriptSite(this);
#else
    script_site = 0;
#endif
}

/*!
    \fn QAxScript::~QAxScript()

    Destroys the object, releasing all allocated resources.
*/
QAxScript::~QAxScript()
{
    delete script_engine;
    script_engine = nullptr;

#ifndef QT_NO_QAXSCRIPT
    script_site->Release();
#endif
}

/*!
    \fn bool QAxScript::load(const QString &code, const QString &language)

    Loads the script source \a code written in language \a language
    into the script engine. Returns true if \a code was successfully
    entered into the script engine; otherwise returns false.

    If \a language is empty (the default) it will be determined
    heuristically. If \a code contains the string \c {End Sub} it will
    be interpreted as VBScript, otherwise as JScript. Additional
    scripting languages can be registered using
    QAxScriptManager::registerEngine().

    This function can only be called once for each QAxScript object,
    which is done automatically when using QAxScriptManager::load().
*/
bool QAxScript::load(const QString &code, const QString &language)
{
    if (script_engine || code.isEmpty())
        return false;

    script_code = code;
    QString lang = language;
    if (lang.isEmpty()) {
        if (code.contains(QLatin1String("End Sub"), Qt::CaseInsensitive))
            lang = QLatin1String("VBScript");

        for (const QAxEngineDescriptor &engine : qAsConst(engines)) {
            if (!engine.code.isEmpty() && code.contains(engine.code)) {
                lang = engine.name;
                break;
            }
        }
    }
    if (lang.isEmpty())
        lang = QLatin1String("JScript");

    script_engine = new QAxScriptEngine(lang, this);
    // trigger call to initialize
    script_engine->metaObject();

    return script_engine->isValid();
}

/*!
    \fn QStringList QAxScript::functions(FunctionFlags flags) const

    Returns a list of all the functions in this script if the respective
    script engine supports introspection; otherwise returns an empty list.
    The functions are either provided with full prototypes or only as
    names, depending on the value of \a flags.

    \sa QAxScriptEngine::hasIntrospection()
*/
QStringList QAxScript::functions(FunctionFlags flags) const
{
    QStringList functions;

    const QMetaObject *mo = script_engine->metaObject();
    for (int i = mo->methodOffset(); i < mo->methodCount(); ++i) {
       const QMetaMethod slot(mo->method(i));
       if (slot.methodType() != QMetaMethod::Slot || slot.access() != QMetaMethod::Public)
            continue;
        QString slotname = QString::fromLatin1(slot.methodSignature());
        if (slotname.contains(QLatin1Char('_')))
            continue;

        if (flags == FunctionSignatures)
            functions << slotname;
        else
            functions << slotname.left(slotname.indexOf(QLatin1Char('(')));
    }

    return functions;
}

/*!
    \fn QVariant QAxScript::call(const QString &function, const QVariant &var1, const QVariant &var2, const QVariant &var3, const QVariant &var4, const QVariant &var5, const QVariant &var6, const QVariant &var7, const QVariant &var8)

    Calls \a function, passing the parameters \a var1, \a var1,
    \a var2, \a var3, \a var4, \a var5, \a var6, \a var7 and \a var8
    as arguments and returns the value returned by the function, or an
    invalid QVariant if the function does not return a value or when
    the function call failed.

    See QAxScriptManager::call() for more information about how to call
    script functions.
*/
QVariant QAxScript::call(const QString &function, const QVariant &var1,
                         const QVariant &var2,
                         const QVariant &var3,
                         const QVariant &var4,
                         const QVariant &var5,
                         const QVariant &var6,
                         const QVariant &var7,
                         const QVariant &var8)
{
    QVariantList vars = QAxBase::argumentsToList(var1, var2, var3, var4, var5, var6, var7, var8);
    return call(function, vars);
}

/*!
    \fn QVariant QAxScript::call(const QString &function, QList<QVariant> &arguments)
    \overload

    Calls \a function passing \a arguments as parameters, and returns
    the result. Returns when the script's execution has finished.

    See QAxScriptManager::call() for more information about how to call
    script functions.
*/
QVariant QAxScript::call(const QString &function, QList<QVariant> &arguments)
{
    if (!script_engine)
        return QVariant();

    return script_engine->dynamicCall(function.toLatin1(), arguments,
                                      QAxBase::NoPropertyGet);
}

/*! \internal
    Registers all objects in the manager with the script engine.
*/
void QAxScript::updateObjects()
{
    if (!script_manager)
        return;

    script_manager->updateScript(this);
}

/*! \internal
    Returns the object \a name registered with the manager.
*/
QAxBase *QAxScript::findObject(const QString &name)
{
    if (!script_manager)
        return nullptr;

    return script_manager->d->objectDict.value(name);
}

/*! \fn QString QAxScript::scriptName() const
    Returns the name of the script.
*/

/*! \fn QString QAxScript::scriptCode() const
    Returns the script's code, or the null-string if no
    code has been loaded yet.

    \sa load()
*/

/*! \fn QAxScriptEngine* QAxScript::scriptEngine() const
    Returns a pointer to the script engine.

    You can use the object returned to connect signals to the
    script functions, or to access the script engine directly.
*/

/*! \fn void QAxScript::entered()

    This signal is emitted when a script engine has started executing code.
*/

/*! \fn void QAxScript::finished()

    This signal is emitted when a script engine has finished executing code.
*/

/*!
    \fn void QAxScript::finished(const QVariant &result)
    \overload

    \a result contains the script's result. This will be an invalid
    QVariant if the script has no return value.
*/

/*! \fn void QAxScript::finished(int code, const QString &source,
                                 const QString &description, const QString &help)
    \overload

    \a code, \a source, \a description and \a help contain exception information
    when the script terminated.
*/

/*! \fn void QAxScript::stateChanged(int state);

    This signal is emitted when a script engine changes state.
    \a state can be any value in the \c QAxScriptEngine::State enumeration.
*/

/*!
    \fn void QAxScript::error(int code, const QString &description,
    int sourcePosition, const QString &sourceText)

    This signal is emitted when an execution error occurred while
    running a script.

    \a code, \a description, \a sourcePosition and \a sourceText
    contain information about the execution error.
*/



/*!
    \class QAxScriptManager
    \brief The QAxScriptManager class provides a bridge between application objects
    and script code.
    \inmodule QAxContainer

    The QAxScriptManager acts as a bridge between the COM objects embedded
    in the Qt application through QAxObject or QAxWidget, and the scripting
    languages available through the Windows Script technologies, usually JScript
    and VBScript.

    Create one QAxScriptManager for each separate document in your
    application, and add the COM objects the scripts need to access
    using addObject(). Then load() the script sources and invoke the
    functions using call().

    \warning This class is not available with the bcc5.5 compiler.

    \sa QAxScript, QAxScriptEngine, QAxBase, {ActiveQt Framework}
*/

/*!
    \fn QAxScriptManager::QAxScriptManager(QObject *parent)

    Creates a QAxScriptManager object. \a parent is passed on to the
    QObject constructor.

    It is usual to create one QAxScriptManager for each document in an
    application.
*/
QAxScriptManager::QAxScriptManager(QObject *parent)
: QObject(parent)
{
    d = new QAxScriptManagerPrivate;
}

/*!
    \fn QAxScriptManager::~QAxScriptManager()

    Destroys the objects, releasing all allocated resources.
*/
QAxScriptManager::~QAxScriptManager()
{
    delete d;
}

/*!
    \fn QStringList QAxScriptManager::functions(QAxScript::FunctionFlags flags) const

    Returns a list with all the functions that are available.
    Functions provided by script engines that don't support
    introspection are not included in the list.
    The functions are either provided with full prototypes or
    only as names, depending on the value of \a flags.
*/
QStringList QAxScriptManager::functions(QAxScript::FunctionFlags flags) const
{
    QStringList functions;
    functions.reserve(d->scriptDict.size());
    for (auto it = d->scriptDict.cbegin(), end = d->scriptDict.cend(); it != end; ++it)
        functions.append(it.value()->functions(flags));
    return functions;
}

/*!
    \fn QStringList QAxScriptManager::scriptNames() const

    Returns a list with the names of all the scripts.
*/
QStringList QAxScriptManager::scriptNames() const
{
    return d->scriptDict.keys();
}

/*!
    \fn QAxScript *QAxScriptManager::script(const QString &name) const

    Returns the script called \a name.

    You can use the returned pointer to call functions directly
    through QAxScript::call(), to access the script engine directly, or
    to delete and thus unload the script.
*/
QAxScript *QAxScriptManager::script(const QString &name) const
{
    return d->scriptDict.value(name);
}

/*!
    \fn void QAxScriptManager::addObject(QAxBase *object)

    Adds \a object to the manager. Scripts handled by this manager
    can access the object in the code using the object's
    \l{QObject::objectName}{objectName} property.

    You must add all the necessary objects before loading any scripts.
*/
void QAxScriptManager::addObject(QAxBase *object)
{
    QObject *obj = object->qObject();
    QString name = obj->objectName();
    if (d->objectDict.contains(name))
        return;

    d->objectDict.insert(name, object);
    connect(obj, SIGNAL(destroyed(QObject*)), this, SLOT(objectDestroyed(QObject*)));
}

/*! \fn void QAxScriptManager::addObject(QObject *object)
    \overload

    Adds a generic COM wrapper for \a object to the manager. \a object
    must be exposed as a COM object using the functionality provided
    by the QAxServer module. Applications
    using this function you must link against the qaxserver library.
*/

/*!
    \fn QAxScript *QAxScriptManager::load(const QString &code, const QString &name, const QString &language)

    Loads the script source \a code using the script engine for \a
    language. The script can later be referred to using its \a name
    which should not be empty.

    The function returns a pointer to the script for the given
    \a code if the \a code was loaded successfully; otherwise it
    returns 0.

    If \a language is empty it will be determined heuristically. If \a
    code contains the string "End Sub" it will be interpreted as
    VBScript, otherwise as JScript. Additional script engines can be
    registered using registerEngine().

    You must add all the objects necessary (using addObject()) \e
    before loading any scripts. If \a code declares a function that is
    already available (no matter in which language) the first function
    is overloaded and can no longer be called via call(); but it will
    still be available by calling its \link script() script \endlink
    directly.

    \sa addObject(), scriptNames(), functions()
*/
QAxScript *QAxScriptManager::load(const QString &code, const QString &name, const QString &language)
{
    QAxScript *script = new QAxScript(name, this);
    if (script->load(code, language))
        return script;

    delete script;
    return nullptr;
}

/*!
    \fn QAxScript *QAxScriptManager::load(const QString &file, const QString &name)
    \overload

    Loads the source code from the \a file. The script can later be
    referred to using its \a name which should not be empty.

    The function returns a pointer to the script engine for the code
    in \a file if \a file was loaded successfully; otherwise it
    returns 0.

    The script engine used is determined from the file's extension. By
    default ".js" files are interpreted as JScript files, and ".vbs"
    and ".dsm" files are interpreted as VBScript. Additional script
    engines can be registered using registerEngine().
*/
QAxScript *QAxScriptManager::load(const QString &file, const QString &name)
{
    QFile f(file);
    if (!f.open(QIODevice::ReadOnly))
        return nullptr;
    QByteArray data = f.readAll();
    QString contents = QString::fromLocal8Bit(data, data.size());
    f.close();

    if (contents.isEmpty())
        return nullptr;

    QString language;
    if (file.endsWith(QLatin1String(".js"))) {
        language = QLatin1String("JScript");
    } else {
        for (const QAxEngineDescriptor &engine : qAsConst(engines)) {
            if (!engine.extension.isEmpty() && file.endsWith(engine.extension)) {
                language = engine.name;
                break;
            }
        }
    }

    if (language.isEmpty())
        language = QLatin1String("VBScript");

    QAxScript *script = new QAxScript(name, this);
    if (script->load(contents, language))
        return script;

    delete script;
    return nullptr;
}

/*!
    \fn QVariant QAxScriptManager::call(const QString &function, const QVariant &var1, const QVariant &var2, const QVariant &var3, const QVariant &var4, const QVariant &var5, const QVariant &var6, const QVariant &var7, const QVariant &var8)

    Calls \a function, passing the parameters \a var1, \a var1,
    \a var2, \a var3, \a var4, \a var5, \a var6, \a var7 and \a var8
    as arguments and returns the value returned by the function, or an
    invalid QVariant if the function does not return a value or when
    the function call failed. The call returns when the script's
    execution has finished.

    In most script engines the only supported parameter type is "const
    QVariant&", for example, to call a JavaScript function
    \snippet src_activeqt_container_qaxscript.cpp 0
    use
    \snippet src_activeqt_container_qaxscript.cpp 1
    As with \link QAxBase::dynamicCall() dynamicCall \endlink the
    parameters can directly be embedded in the function string.
    \snippet src_activeqt_container_qaxscript.cpp 2
    However, this is slower.

    Functions provided by script engines that don't support
    introspection are not available and must be called directly
    using QAxScript::call() on the respective \link script()
    script \endlink object.

    Note that calling this function can be significantely slower than
    using call() on the respective QAxScript directly.
*/
QVariant QAxScriptManager::call(const QString &function, const QVariant &var1,
                                const QVariant &var2,
                                const QVariant &var3,
                                const QVariant &var4,
                                const QVariant &var5,
                                const QVariant &var6,
                                const QVariant &var7,
                                const QVariant &var8)
{
    QAxScript *s = script(function);
    if (!s) {
#ifdef QT_CHECK_STATE
        qWarning("QAxScriptManager::call: No script provides function %s, or this function\n"
            "\tis provided through an engine that does not support introspection", function.latin1());
#endif
        return QVariant();
    }

    return s->call(function, var1, var2, var3, var4, var5, var6, var7, var8);
}

/*!
    \fn QVariant QAxScriptManager::call(const QString &function, QList<QVariant> &arguments)
    \overload

    Calls \a function passing \a arguments as parameters, and returns
    the result. Returns when the script's execution has finished.
*/
QVariant QAxScriptManager::call(const QString &function, QList<QVariant> &arguments)
{
    QAxScript *s = script(function);
    if (!s) {
#ifdef QT_CHECK_STATE
        qWarning("QAxScriptManager::call: No script provides function %s, or this function\n"
            "\tis provided through an engine that does not support introspection", function.latin1());
#endif
        return QVariant();
    }

    QVariantList args(arguments);
    return s->call(function, args);
}

/*!
    \fn bool QAxScriptManager::registerEngine(const QString &name, const QString &extension, const QString &code)
    Registers the script engine called \a name and returns true if the
    engine was found; otherwise does nothing and returns false.

    The script engine will be used when loading files with the given
    \a extension, or when loading source code that contains the string
    \a code.
*/
bool QAxScriptManager::registerEngine(const QString &name, const QString &extension, const QString &code)
{
    if (name.isEmpty())
        return false;

    CLSID clsid;
    const HRESULT hres = CLSIDFromProgID(reinterpret_cast<const wchar_t *>(name.utf16()), &clsid);
    if (hres != S_OK)
        return false;

    QAxEngineDescriptor engine;
    engine.name = name;
    engine.extension = extension;
    engine.code = code;

    engines.prepend(engine);
    return true;
}

/*!
    \fn QString QAxScriptManager::scriptFileFilter()

    Returns a file filter listing all the supported script languages.
    This filter string is convenient for use with QFileDialog.
*/
QString QAxScriptManager::scriptFileFilter()
{
    QString allFiles = QLatin1String("Script Files (*.js *.vbs *.dsm");
    QString specialFiles = QLatin1String(";;VBScript Files (*.vbs *.dsm)"
        ";;JavaScript Files (*.js)");

    for (const QAxEngineDescriptor &engine : qAsConst(engines)) {
        if (!engine.extension.isEmpty()) {
            allFiles += QLatin1String(" *") + engine.extension;
            specialFiles += QLatin1String(";;") + engine.name
                + QLatin1String(" Files (*") + engine.extension + QLatin1Char(')');
        }
    }
    allFiles += QLatin1Char(')');

    return allFiles + specialFiles + QLatin1String(";;All Files (*.*)");
}

/*!
    \fn void QAxScriptManager::error(QAxScript *script, int code, const QString &description,
    int sourcePosition, const QString &sourceText)

    This signal is emitted when an execution error occurred while
    running \a script.

    \a code, \a description, \a sourcePosition and \a sourceText
    contain information about the execution error.

    \warning Do not delete \a script in a slot connected to this signal. Use deleteLater()
    instead.
*/

/*!
    \fn QAxScript *QAxScriptManager::scriptForFunction(const QString &function) const
    \internal

    Returns a pointer to the first QAxScript that knows
    about \a function, or 0 if this function is unknown.
*/
QAxScript *QAxScriptManager::scriptForFunction(const QString &function) const
{
    // check full prototypes if included
    if (function.contains(QLatin1Char('('))) {
        for (auto it = d->scriptDict.cbegin(), end = d->scriptDict.cend(); it != end; ++it) {
            if (it.value()->functions(QAxScript::FunctionSignatures).contains(function))
                return it.value();
        }
    }

    QString funcName = function;
    funcName.truncate(funcName.indexOf(QLatin1Char('(')));
    // second try, checking only names, not prototypes
    for (auto it = d->scriptDict.cbegin(), end = d->scriptDict.cend(); it != end; ++it) {
        if (it.value()->functions(QAxScript::FunctionNames).contains(funcName))
            return it.value();
    }

    return nullptr;
}

/*!
    \internal
*/
void QAxScriptManager::updateScript(QAxScript *script)
{
    if (QAxScriptEngine *engine = script->scriptEngine()) {
        for (auto it = d->objectDict.constBegin(), end = d->objectDict.constEnd(); it != end; ++it)
            engine->addItem(it.key());
    }
}

/*!
    \internal
*/
void QAxScriptManager::objectDestroyed(QObject *o)
{
    d->objectDict.take(o->objectName());
}

/*!
    \internal
*/
void QAxScriptManager::scriptError(int code, const QString &desc, int spos, const QString &stext)
{
    QAxScript *source = qobject_cast<QAxScript*>(sender());
    emit error(source, code, desc, spos, stext);
}

QT_END_NAMESPACE
