/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the QtDeclarative module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this
** file. Please review the following information to ensure the GNU Lesser
** General Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "private/qdeclarativecontextscriptclass_p.h"

#include "private/qdeclarativeengine_p.h"
#include "private/qdeclarativecontext_p.h"
#include "private/qdeclarativetypenamescriptclass_p.h"
#include "private/qdeclarativelistscriptclass_p.h"
#include "private/qdeclarativeguard_p.h"

QT_BEGIN_NAMESPACE

struct ContextData : public QScriptDeclarativeClass::Object {
    ContextData() : overrideObject(0), isSharedContext(true) {}
    ContextData(QDeclarativeContextData *c, QObject *o) 
    : context(c), scopeObject(o), overrideObject(0), isSharedContext(false), isUrlContext(false) {}
    QDeclarativeGuardedContextData context;
    QDeclarativeGuard<QObject> scopeObject;
    QObject *overrideObject;
    bool isSharedContext:1;
    bool isUrlContext:1;

    QDeclarativeContextData *getContext(QDeclarativeEngine *engine) {
        if (isSharedContext) {
            return QDeclarativeEnginePrivate::get(engine)->sharedContext;
        } else {
            return context.contextData();
        }
    }

    QObject *getScope(QDeclarativeEngine *engine) {
        if (isSharedContext) {
            return QDeclarativeEnginePrivate::get(engine)->sharedScope;
        } else {
            return scopeObject.data();
        }
    }
};

struct UrlContextData : public ContextData {
    UrlContextData(QDeclarativeContextData *c, QObject *o, const QString &u) 
    : ContextData(c, o), url(u) {
        isUrlContext = true;
    }
    UrlContextData(const QString &u) 
    : ContextData(0, 0), url(u) {
        isUrlContext = true;
    }
    QString url;
};

/*
    The QDeclarativeContextScriptClass handles property access for a QDeclarativeContext
    via QtScript.
 */
QDeclarativeContextScriptClass::QDeclarativeContextScriptClass(QDeclarativeEngine *bindEngine)
: QScriptDeclarativeClass(QDeclarativeEnginePrivate::getScriptEngine(bindEngine)), engine(bindEngine),
  lastScopeObject(0), lastContext(0), lastData(0), lastPropertyIndex(-1)
{
}

QDeclarativeContextScriptClass::~QDeclarativeContextScriptClass()
{
}

QScriptValue QDeclarativeContextScriptClass::newContext(QDeclarativeContextData *context, QObject *scopeObject)
{
    QScriptEngine *scriptEngine = QDeclarativeEnginePrivate::getScriptEngine(engine);

    return newObject(scriptEngine, this, new ContextData(context, scopeObject));
}

QScriptValue QDeclarativeContextScriptClass::newUrlContext(QDeclarativeContextData *context, QObject *scopeObject, 
                                                           const QString &url)
{
    QScriptEngine *scriptEngine = QDeclarativeEnginePrivate::getScriptEngine(engine);

    return newObject(scriptEngine, this, new UrlContextData(context, scopeObject, url));
}

QScriptValue QDeclarativeContextScriptClass::newUrlContext(const QString &url)
{
    QScriptEngine *scriptEngine = QDeclarativeEnginePrivate::getScriptEngine(engine);

    return newObject(scriptEngine, this, new UrlContextData(url));
}

QScriptValue QDeclarativeContextScriptClass::newSharedContext()
{
    QScriptEngine *scriptEngine = QDeclarativeEnginePrivate::getScriptEngine(engine);

    return newObject(scriptEngine, this, new ContextData());
}

QDeclarativeContextData *QDeclarativeContextScriptClass::contextFromValue(const QScriptValue &v)
{
    if (scriptClass(v) != this)
        return 0;

    ContextData *data = (ContextData *)object(v);
    return data->getContext(engine);
}

QUrl QDeclarativeContextScriptClass::urlFromValue(const QScriptValue &v)
{
    if (scriptClass(v) != this)
        return QUrl();

    ContextData *data = (ContextData *)object(v);
    if (data->isUrlContext) {
        return QUrl(static_cast<UrlContextData *>(data)->url);
    } else {
        return QUrl();
    }
}

QObject *QDeclarativeContextScriptClass::setOverrideObject(QScriptValue &v, QObject *override)
{
    if (scriptClass(v) != this)
        return 0;

    ContextData *data = (ContextData *)object(v);
    QObject *rv = data->overrideObject;
    data->overrideObject = override;
    return rv;
}

QScriptClass::QueryFlags 
QDeclarativeContextScriptClass::queryProperty(Object *object, const Identifier &name, 
                                     QScriptClass::QueryFlags flags)
{
    Q_UNUSED(flags);
    
    lastScopeObject = 0;
    lastContext = 0;
    lastData = 0;
    lastPropertyIndex = -1;

    QDeclarativeContextData *bindContext = ((ContextData *)object)->getContext(engine);
    QObject *scopeObject = ((ContextData *)object)->getScope(engine);
    if (!bindContext)
        return 0;

    QObject *overrideObject = ((ContextData *)object)->overrideObject;
    if (overrideObject) {
        QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(engine);
        QScriptClass::QueryFlags rv = 
            ep->objectClass->queryProperty(overrideObject, name, flags, bindContext, 
                                           QDeclarativeObjectScriptClass::ImplicitObject | 
                                           QDeclarativeObjectScriptClass::SkipAttachedProperties);
        if (rv) {
            lastScopeObject = overrideObject;
            lastContext = bindContext;
            return rv;
        }
    }

    bool includeTypes = true;
    while (bindContext) {
        QScriptClass::QueryFlags rv = 
            queryProperty(bindContext, scopeObject, name, flags, includeTypes);
        scopeObject = 0; // Only applies to the first context
        includeTypes = false; // Only applies to the first context
        if (rv) return rv;
        bindContext = bindContext->parent;
    }

    return 0;
}

QScriptClass::QueryFlags 
QDeclarativeContextScriptClass::queryProperty(QDeclarativeContextData *bindContext, QObject *scopeObject,
                                              const Identifier &name,
                                              QScriptClass::QueryFlags flags, 
                                              bool includeTypes)
{
    QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(engine);

    lastPropertyIndex = bindContext->propertyNames?bindContext->propertyNames->value(name):-1;
    if (lastPropertyIndex != -1) {
        lastContext = bindContext;
        return QScriptClass::HandlesReadAccess;
    }

    if (includeTypes && bindContext->imports) { 
        QDeclarativeTypeNameCache::Data *data = bindContext->imports->data(name);

        if (data)  {
            lastData = data;
            lastContext = bindContext;
            lastScopeObject = scopeObject;
            return QScriptClass::HandlesReadAccess;
        }
    }

    if (scopeObject) {
        QScriptClass::QueryFlags rv = 
            ep->objectClass->queryProperty(scopeObject, name, flags, bindContext, 
                                           QDeclarativeObjectScriptClass::ImplicitObject | QDeclarativeObjectScriptClass::SkipAttachedProperties);
        if (rv) {
            lastScopeObject = scopeObject;
            lastContext = bindContext;
            return rv;
        }
    }

    if (bindContext->contextObject) {
        QScriptClass::QueryFlags rv = 
            ep->objectClass->queryProperty(bindContext->contextObject, name, flags, bindContext, 
                                           QDeclarativeObjectScriptClass::ImplicitObject | QDeclarativeObjectScriptClass::SkipAttachedProperties);

        if (rv) {
            lastScopeObject = bindContext->contextObject;
            lastContext = bindContext;
            return rv;
        }
    }

    return 0;
}

QDeclarativeContextScriptClass::Value
QDeclarativeContextScriptClass::property(Object *object, const Identifier &name)
{
    Q_UNUSED(object);

    QDeclarativeContextData *bindContext = lastContext;
    Q_ASSERT(bindContext);

    QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(engine);
    QScriptEngine *scriptEngine = QDeclarativeEnginePrivate::getScriptEngine(engine);

    if (lastData) {

        if (lastData->type) {
            return Value(scriptEngine, ep->typeNameClass->newObject(lastScopeObject, lastData->type));
        } else if (lastData->typeNamespace) {
            return Value(scriptEngine, ep->typeNameClass->newObject(lastScopeObject, lastData->typeNamespace));
        } else {
            int index = lastData->importedScriptIndex;
            if (index < bindContext->importedScripts.count()) {
                return Value(scriptEngine, bindContext->importedScripts.at(index));
            } else {
                return Value();
            }
        }

    } else if (lastScopeObject) {

        return ep->objectClass->property(lastScopeObject, name);

    } else if (lastPropertyIndex != -1) {

        QScriptValue rv;
        if (lastPropertyIndex < bindContext->idValueCount) {
            rv =  ep->objectClass->newQObject(bindContext->idValues[lastPropertyIndex].data());

            if (ep->captureProperties) 
                ep->capturedProperties << QDeclarativeEnginePrivate::CapturedProperty(&bindContext->idValues[lastPropertyIndex].bindings);
        } else {
            QDeclarativeContextPrivate *cp = bindContext->asQDeclarativeContextPrivate();
            const QVariant &value = cp->propertyValues.at(lastPropertyIndex);
            if (value.userType() == qMetaTypeId<QList<QObject*> >()) {
                rv = ep->listClass->newList(QDeclarativeListProperty<QObject>(bindContext->asQDeclarativeContext(), (void*)lastPropertyIndex, 0, QDeclarativeContextPrivate::context_count, QDeclarativeContextPrivate::context_at), qMetaTypeId<QDeclarativeListProperty<QObject> >());
            } else {
                rv = ep->scriptValueFromVariant(value);
            }

            if (ep->captureProperties) 
                ep->capturedProperties << QDeclarativeEnginePrivate::CapturedProperty(bindContext->asQDeclarativeContext(), -1, lastPropertyIndex + cp->notifyIndex);
        }

        return Value(scriptEngine, rv);

    } else {

        return Value(scriptEngine, lastFunction);

    }
}

void QDeclarativeContextScriptClass::setProperty(Object *object, const Identifier &name, 
                                        const QScriptValue &value)
{
    Q_UNUSED(object);
    Q_ASSERT(lastScopeObject);

    QDeclarativeContextData *bindContext = lastContext;
    Q_ASSERT(bindContext);

    QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(engine);

    ep->objectClass->setProperty(lastScopeObject, name, value, context(), bindContext);
}

QT_END_NAMESPACE
