/****************************************************************************
**
** 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/qdeclarativevmemetaobject_p.h"

#include "qdeclarative.h"
#include "private/qdeclarativerefcount_p.h"
#include "qdeclarativeexpression.h"
#include "private/qdeclarativeexpression_p.h"
#include "private/qdeclarativecontext_p.h"
#include "private/qdeclarativebinding_p.h"

Q_DECLARE_METATYPE(QScriptValue);

QT_BEGIN_NAMESPACE

class QDeclarativeVMEVariant
{
public:
    inline QDeclarativeVMEVariant();
    inline ~QDeclarativeVMEVariant();

    inline const void *dataPtr() const;
    inline void *dataPtr();
    inline int dataType() const;

    inline QObject *asQObject();
    inline const QVariant &asQVariant();
    inline int asInt();
    inline bool asBool();
    inline double asDouble();
    inline const QString &asQString();
    inline const QUrl &asQUrl();
    inline const QColor &asQColor();
    inline const QTime &asQTime();
    inline const QDate &asQDate();
    inline const QDateTime &asQDateTime();
    inline const QScriptValue &asQScriptValue();

    inline void setValue(QObject *);
    inline void setValue(const QVariant &);
    inline void setValue(int);
    inline void setValue(bool);
    inline void setValue(double);
    inline void setValue(const QString &);
    inline void setValue(const QUrl &);
    inline void setValue(const QColor &);
    inline void setValue(const QTime &);
    inline void setValue(const QDate &);
    inline void setValue(const QDateTime &);
    inline void setValue(const QScriptValue &);
private:
    int type;
    void *data[4]; // Large enough to hold all types

    inline void cleanup();
};

QDeclarativeVMEVariant::QDeclarativeVMEVariant()
: type(QVariant::Invalid)
{
}

QDeclarativeVMEVariant::~QDeclarativeVMEVariant()
{
    cleanup();
}

void QDeclarativeVMEVariant::cleanup()
{
    if (type == QVariant::Invalid) {
    } else if (type == QMetaType::Int ||
               type == QMetaType::Bool ||
               type == QMetaType::Double) {
        type = QVariant::Invalid;
    } else if (type == QMetaType::QObjectStar) {
        ((QDeclarativeGuard<QObject>*)dataPtr())->~QDeclarativeGuard<QObject>();
        type = QVariant::Invalid;
    } else if (type == QMetaType::QString) {
        ((QString *)dataPtr())->~QString();
        type = QVariant::Invalid;
    } else if (type == QMetaType::QUrl) {
        ((QUrl *)dataPtr())->~QUrl();
        type = QVariant::Invalid;
    } else if (type == QMetaType::QColor) {
        ((QColor *)dataPtr())->~QColor();
        type = QVariant::Invalid;
    } else if (type == QMetaType::QTime) {
        ((QTime *)dataPtr())->~QTime();
        type = QVariant::Invalid;
    } else if (type == QMetaType::QDate) {
        ((QDate *)dataPtr())->~QDate();
        type = QVariant::Invalid;
    } else if (type == QMetaType::QDateTime) {
        ((QDateTime *)dataPtr())->~QDateTime();
        type = QVariant::Invalid;
    } else if (type == qMetaTypeId<QVariant>()) {
        ((QVariant *)dataPtr())->~QVariant();
        type = QVariant::Invalid;
    } else if (type == qMetaTypeId<QScriptValue>()) {
        ((QScriptValue *)dataPtr())->~QScriptValue();
        type = QVariant::Invalid;
    }

}

int QDeclarativeVMEVariant::dataType() const
{
    return type;
}

const void *QDeclarativeVMEVariant::dataPtr() const
{
    return &data;
}

void *QDeclarativeVMEVariant::dataPtr() 
{
    return &data;
}

QObject *QDeclarativeVMEVariant::asQObject() 
{
    if (type != QMetaType::QObjectStar) 
        setValue((QObject *)0);

    return *(QDeclarativeGuard<QObject> *)(dataPtr());
}

const QVariant &QDeclarativeVMEVariant::asQVariant() 
{
    if (type != QMetaType::QVariant)
        setValue(QVariant());

    return *(QVariant *)(dataPtr());
}

int QDeclarativeVMEVariant::asInt() 
{
    if (type != QMetaType::Int)
        setValue(int(0));

    return *(int *)(dataPtr());
}

bool QDeclarativeVMEVariant::asBool() 
{
    if (type != QMetaType::Bool)
        setValue(bool(false));

    return *(bool *)(dataPtr());
}

double QDeclarativeVMEVariant::asDouble() 
{
    if (type != QMetaType::Double)
        setValue(double(0));

    return *(double *)(dataPtr());
}

const QString &QDeclarativeVMEVariant::asQString() 
{
    if (type != QMetaType::QString)
        setValue(QString());

    return *(QString *)(dataPtr());
}

const QUrl &QDeclarativeVMEVariant::asQUrl() 
{
    if (type != QMetaType::QUrl)
        setValue(QUrl());

    return *(QUrl *)(dataPtr());
}

const QColor &QDeclarativeVMEVariant::asQColor() 
{
    if (type != QMetaType::QColor)
        setValue(QColor());

    return *(QColor *)(dataPtr());
}

const QTime &QDeclarativeVMEVariant::asQTime() 
{
    if (type != QMetaType::QTime)
        setValue(QTime());

    return *(QTime *)(dataPtr());
}

const QDate &QDeclarativeVMEVariant::asQDate() 
{
    if (type != QMetaType::QDate)
        setValue(QDate());

    return *(QDate *)(dataPtr());
}

const QDateTime &QDeclarativeVMEVariant::asQDateTime() 
{
    if (type != QMetaType::QDateTime)
        setValue(QDateTime());

    return *(QDateTime *)(dataPtr());
}

const QScriptValue &QDeclarativeVMEVariant::asQScriptValue() 
{
    if (type != qMetaTypeId<QScriptValue>())
        setValue(QScriptValue());

    return *(QScriptValue *)(dataPtr());
}

void QDeclarativeVMEVariant::setValue(QObject *v)
{
    if (type != QMetaType::QObjectStar) {
        cleanup();
        type = QMetaType::QObjectStar;
        new (dataPtr()) QDeclarativeGuard<QObject>();
    }
    *(QDeclarativeGuard<QObject>*)(dataPtr()) = v;
}

void QDeclarativeVMEVariant::setValue(const QVariant &v)
{
    if (type != qMetaTypeId<QVariant>()) {
        cleanup();
        type = qMetaTypeId<QVariant>();
        new (dataPtr()) QVariant(v);
    } else {
        *(QVariant *)(dataPtr()) = v;
    }
}

void QDeclarativeVMEVariant::setValue(int v)
{
    if (type != QMetaType::Int) {
        cleanup();
        type = QMetaType::Int;
    }
    *(int *)(dataPtr()) = v;
}

void QDeclarativeVMEVariant::setValue(bool v)
{
    if (type != QMetaType::Bool) {
        cleanup();
        type = QMetaType::Bool;
    }
    *(bool *)(dataPtr()) = v;
}

void QDeclarativeVMEVariant::setValue(double v)
{
    if (type != QMetaType::Double) {
        cleanup();
        type = QMetaType::Double;
    }
    *(double *)(dataPtr()) = v;
}

void QDeclarativeVMEVariant::setValue(const QString &v)
{
    if (type != QMetaType::QString) {
        cleanup();
        type = QMetaType::QString;
        new (dataPtr()) QString(v);
    } else {
        *(QString *)(dataPtr()) = v;
    }
}

void QDeclarativeVMEVariant::setValue(const QUrl &v)
{
    if (type != QMetaType::QUrl) {
        cleanup();
        type = QMetaType::QUrl;
        new (dataPtr()) QUrl(v);
    } else {
        *(QUrl *)(dataPtr()) = v;
    }
}

void QDeclarativeVMEVariant::setValue(const QColor &v)
{
    if (type != QMetaType::QColor) {
        cleanup();
        type = QMetaType::QColor;
        new (dataPtr()) QColor(v);
    } else {
        *(QColor *)(dataPtr()) = v;
    }
}

void QDeclarativeVMEVariant::setValue(const QTime &v)
{
    if (type != QMetaType::QTime) {
        cleanup();
        type = QMetaType::QTime;
        new (dataPtr()) QTime(v);
    } else {
        *(QTime *)(dataPtr()) = v;
    }
}

void QDeclarativeVMEVariant::setValue(const QDate &v)
{
    if (type != QMetaType::QDate) {
        cleanup();
        type = QMetaType::QDate;
        new (dataPtr()) QDate(v);
    } else {
        *(QDate *)(dataPtr()) = v;
    }
}

void QDeclarativeVMEVariant::setValue(const QDateTime &v)
{
    if (type != QMetaType::QDateTime) {
        cleanup();
        type = QMetaType::QDateTime;
        new (dataPtr()) QDateTime(v);
    } else {
        *(QDateTime *)(dataPtr()) = v;
    }
}

void QDeclarativeVMEVariant::setValue(const QScriptValue &v)
{
    if (type != qMetaTypeId<QScriptValue>()) {
        cleanup();
        type = qMetaTypeId<QScriptValue>();
        new (dataPtr()) QScriptValue(v);
    } else {
        *(QScriptValue *)(dataPtr()) = v;
    }
}

QDeclarativeVMEMetaObject::QDeclarativeVMEMetaObject(QObject *obj,
                                                     const QMetaObject *other, 
                                                     const QDeclarativeVMEMetaData *meta,
                                                     QDeclarativeCompiledData *cdata)
: object(obj), compiledData(cdata), ctxt(QDeclarativeData::get(obj, true)->outerContext),
  metaData(meta), data(0), methods(0), parent(0)
{
    compiledData->addref();

    *static_cast<QMetaObject *>(this) = *other;
    this->d.superdata = obj->metaObject();

    QObjectPrivate *op = QObjectPrivate::get(obj);
    if (op->metaObject)
        parent = static_cast<QAbstractDynamicMetaObject*>(op->metaObject);
    op->metaObject = this;

    propOffset = QAbstractDynamicMetaObject::propertyOffset();
    methodOffset = QAbstractDynamicMetaObject::methodOffset();

    data = new QDeclarativeVMEVariant[metaData->propertyCount];

    aConnected.resize(metaData->aliasCount);
    int list_type = qMetaTypeId<QDeclarativeListProperty<QObject> >();

    // ### Optimize
    for (int ii = 0; ii < metaData->propertyCount; ++ii) {
        int t = (metaData->propertyData() + ii)->propertyType;
        if (t == list_type) {
            listProperties.append(List(methodOffset + ii));
            data[ii].setValue(listProperties.count() - 1);
        } 
    }
}

QDeclarativeVMEMetaObject::~QDeclarativeVMEMetaObject()
{
    compiledData->release();
    delete parent;
    delete [] data;
    delete [] methods;
}

int QDeclarativeVMEMetaObject::metaCall(QMetaObject::Call c, int _id, void **a)
{
    int id = _id;
    if(c == QMetaObject::WriteProperty) {
        int flags = *reinterpret_cast<int*>(a[3]);
        if (!(flags & QDeclarativePropertyPrivate::BypassInterceptor)
            && !aInterceptors.isEmpty()
            && aInterceptors.testBit(id)) {
            QPair<int, QDeclarativePropertyValueInterceptor*> pair = interceptors.value(id);
            int valueIndex = pair.first;
            QDeclarativePropertyValueInterceptor *vi = pair.second;
            int type = property(id).userType();

            if (type != QVariant::Invalid) {
                if (valueIndex != -1) {
                    QDeclarativeEnginePrivate *ep = ctxt?QDeclarativeEnginePrivate::get(ctxt->engine):0;
                    QDeclarativeValueType *valueType = 0;
                    if (ep) valueType = ep->valueTypes[type];
                    else valueType = QDeclarativeValueTypeFactory::valueType(type);
                    Q_ASSERT(valueType);

                    valueType->setValue(QVariant(type, a[0]));
                    QMetaProperty valueProp = valueType->metaObject()->property(valueIndex);
                    vi->write(valueProp.read(valueType));

                    if (!ep) delete valueType;
                    return -1;
                } else {
                    vi->write(QVariant(type, a[0]));
                    return -1;
                }
            }
        }
    }
    if(c == QMetaObject::ReadProperty || c == QMetaObject::WriteProperty) {
        if (id >= propOffset) {
            id -= propOffset;

            if (id < metaData->propertyCount) {
               int t = (metaData->propertyData() + id)->propertyType;
                bool needActivate = false;

                if (t == -1) {

                    if (c == QMetaObject::ReadProperty) {
                        *reinterpret_cast<QVariant *>(a[0]) = readVarPropertyAsVariant(id);
                    } else if (c == QMetaObject::WriteProperty) {
                        writeVarProperty(id, *reinterpret_cast<QVariant *>(a[0]));
                    }

                } else {

                    if (c == QMetaObject::ReadProperty) {
                        switch(t) {
                        case QVariant::Int:
                            *reinterpret_cast<int *>(a[0]) = data[id].asInt();
                            break;
                        case QVariant::Bool:
                            *reinterpret_cast<bool *>(a[0]) = data[id].asBool();
                            break;
                        case QVariant::Double:
                            *reinterpret_cast<double *>(a[0]) = data[id].asDouble();
                            break;
                        case QVariant::String:
                            *reinterpret_cast<QString *>(a[0]) = data[id].asQString();
                            break;
                        case QVariant::Url:
                            *reinterpret_cast<QUrl *>(a[0]) = data[id].asQUrl();
                            break;
                        case QVariant::Color:
                            *reinterpret_cast<QColor *>(a[0]) = data[id].asQColor();
                            break;
                        case QVariant::Date:
                            *reinterpret_cast<QDate *>(a[0]) = data[id].asQDate();
                            break;
                        case QVariant::DateTime:
                            *reinterpret_cast<QDateTime *>(a[0]) = data[id].asQDateTime();
                            break;
                        case QMetaType::QObjectStar:
                            *reinterpret_cast<QObject **>(a[0]) = data[id].asQObject();
                            break;
                        default:
                            break;
                        }
                        if (t == qMetaTypeId<QDeclarativeListProperty<QObject> >()) {
                            int listIndex = data[id].asInt();
                            const List *list = &listProperties.at(listIndex);
                            *reinterpret_cast<QDeclarativeListProperty<QObject> *>(a[0]) = 
                                QDeclarativeListProperty<QObject>(object, (void *)list,
                                                                  list_append, list_count, list_at, 
                                                                  list_clear);
                        }

                    } else if (c == QMetaObject::WriteProperty) {

                        switch(t) {
                        case QVariant::Int:
                            needActivate = *reinterpret_cast<int *>(a[0]) != data[id].asInt();
                            data[id].setValue(*reinterpret_cast<int *>(a[0]));
                            break;
                        case QVariant::Bool:
                            needActivate = *reinterpret_cast<bool *>(a[0]) != data[id].asBool();
                            data[id].setValue(*reinterpret_cast<bool *>(a[0]));
                            break;
                        case QVariant::Double:
                            needActivate = *reinterpret_cast<double *>(a[0]) != data[id].asDouble();
                            data[id].setValue(*reinterpret_cast<double *>(a[0]));
                            break;
                        case QVariant::String:
                            needActivate = *reinterpret_cast<QString *>(a[0]) != data[id].asQString();
                            data[id].setValue(*reinterpret_cast<QString *>(a[0]));
                            break;
                        case QVariant::Url:
                            needActivate = *reinterpret_cast<QUrl *>(a[0]) != data[id].asQUrl();
                            data[id].setValue(*reinterpret_cast<QUrl *>(a[0]));
                            break;
                        case QVariant::Color:
                            needActivate = *reinterpret_cast<QColor *>(a[0]) != data[id].asQColor();
                            data[id].setValue(*reinterpret_cast<QColor *>(a[0]));
                            break;
                        case QVariant::Date:
                            needActivate = *reinterpret_cast<QDate *>(a[0]) != data[id].asQDate();
                            data[id].setValue(*reinterpret_cast<QDate *>(a[0]));
                            break;
                        case QVariant::DateTime:
                            needActivate = *reinterpret_cast<QDateTime *>(a[0]) != data[id].asQDateTime();
                            data[id].setValue(*reinterpret_cast<QDateTime *>(a[0]));
                            break;
                        case QMetaType::QObjectStar:
                            needActivate = *reinterpret_cast<QObject **>(a[0]) != data[id].asQObject();
                            data[id].setValue(*reinterpret_cast<QObject **>(a[0]));
                            break;
                        default:
                            break;
                        }
                    }

                }

                if (c == QMetaObject::WriteProperty && needActivate) {
                    activate(object, methodOffset + id, 0);
                }

                return -1;
            }

            id -= metaData->propertyCount;

            if (id < metaData->aliasCount) {

                QDeclarativeVMEMetaData::AliasData *d = metaData->aliasData() + id;

                if (d->flags & QML_ALIAS_FLAG_PTR && c == QMetaObject::ReadProperty) 
                        *reinterpret_cast<void **>(a[0]) = 0;

                if (!ctxt) return -1;

                QDeclarativeContext *context = ctxt->asQDeclarativeContext();
                QDeclarativeContextPrivate *ctxtPriv = QDeclarativeContextPrivate::get(context);

                QObject *target = ctxtPriv->data->idValues[d->contextIdx].data();
                if (!target) 
                    return -1;

                connectAlias(id);

                if (d->isObjectAlias()) {
                    *reinterpret_cast<QObject **>(a[0]) = target;
                    return -1;
                } 
                
                // Remove binding (if any) on write
                if(c == QMetaObject::WriteProperty) {
                    int flags = *reinterpret_cast<int*>(a[3]);
                    if (flags & QDeclarativePropertyPrivate::RemoveBindingOnAliasWrite) {
                        QDeclarativeData *targetData = QDeclarativeData::get(target);
                        if (targetData && targetData->hasBindingBit(d->propertyIndex())) {
                            QDeclarativeAbstractBinding *binding = QDeclarativePropertyPrivate::setBinding(target, d->propertyIndex(), d->isValueTypeAlias()?d->valueTypeIndex():-1, 0);
                            if (binding) binding->destroy();
                        }
                    }
                }
                
                if (d->isValueTypeAlias()) {
                    // Value type property
                    QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(ctxt->engine);

                    QDeclarativeValueType *valueType = ep->valueTypes[d->valueType()];
                    Q_ASSERT(valueType);

                    valueType->read(target, d->propertyIndex());
                    int rv = QMetaObject::metacall(valueType, c, d->valueTypeIndex(), a);
                    
                    if (c == QMetaObject::WriteProperty)
                        valueType->write(target, d->propertyIndex(), 0x00);

                    return rv;

                } else {
                    return QMetaObject::metacall(target, c, d->propertyIndex(), a);
                }

            }
            return -1;

        }

    } else if(c == QMetaObject::InvokeMetaMethod) {

        if (id >= methodOffset) {

            id -= methodOffset;
            int plainSignals = metaData->signalCount + metaData->propertyCount +
                               metaData->aliasCount;
            if (id < plainSignals) {
                QMetaObject::activate(object, _id, a);
                return -1;
            }

            id -= plainSignals;

            if (id < metaData->methodCount) {
                if (!ctxt->engine)
                    return -1; // We can't run the method

                QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(ctxt->engine);

                QScriptValue function = method(id);

                QScriptValueList args;
                QDeclarativeVMEMetaData::MethodData *data = metaData->methodData() + id;
                if (data->parameterCount) {
                    for (int ii = 0; ii < data->parameterCount; ++ii) {
                        args << ep->scriptValueFromVariant(*(QVariant *)a[ii + 1]);
                    }
                }
                QScriptValue rv = function.call(ep->objectClass->newQObject(object), args);

                if (a[0]) *reinterpret_cast<QVariant *>(a[0]) = ep->scriptValueToVariant(rv);

                return -1;
            }
            return -1;
        }
    }

    if (parent)
        return parent->metaCall(c, _id, a);
    else
        return object->qt_metacall(c, _id, a);
}

QScriptValue QDeclarativeVMEMetaObject::method(int index)
{
    if (!methods) 
        methods = new QScriptValue[metaData->methodCount];

    if (!methods[index].isValid()) {
        QDeclarativeVMEMetaData::MethodData *data = metaData->methodData() + index;

        const QChar *body = 
            (const QChar *)(((const char*)metaData) + data->bodyOffset);

        QString code = QString::fromRawData(body, data->bodyLength);

        // XXX Use QScriptProgram
        // XXX We should evaluate all methods in a single big script block to 
        // improve the call time between dynamic methods defined on the same
        // object
        methods[index] = QDeclarativeExpressionPrivate::evalInObjectScope(ctxt, object, code, ctxt->url.toString(),
                                                                          data->lineNumber, 0);
    }

    return methods[index];
}

QScriptValue QDeclarativeVMEMetaObject::readVarProperty(int id)
{
    if (data[id].dataType() == qMetaTypeId<QScriptValue>())
        return data[id].asQScriptValue();
    else if (data[id].dataType() == QMetaType::QObjectStar) 
        return QDeclarativeEnginePrivate::get(ctxt->engine)->objectClass->newQObject(data[id].asQObject());
    else
        return QDeclarativeEnginePrivate::get(ctxt->engine)->scriptValueFromVariant(data[id].asQVariant());
}

QVariant QDeclarativeVMEMetaObject::readVarPropertyAsVariant(int id)
{
    if (data[id].dataType() == qMetaTypeId<QScriptValue>())
        return QDeclarativeEnginePrivate::get(ctxt->engine)->scriptValueToVariant(data[id].asQScriptValue());
    else if (data[id].dataType() == QMetaType::QObjectStar) 
        return QVariant::fromValue(data[id].asQObject());
    else 
        return data[id].asQVariant();
}

void QDeclarativeVMEMetaObject::writeVarProperty(int id, const QScriptValue &value)
{
    data[id].setValue(value);
    activate(object, methodOffset + id, 0);
}

void QDeclarativeVMEMetaObject::writeVarProperty(int id, const QVariant &value)
{
    bool needActivate = false;
    if (value.userType() == QMetaType::QObjectStar) {
        QObject *o = qvariant_cast<QObject *>(value);
        needActivate = (data[id].dataType() != QMetaType::QObjectStar || data[id].asQObject() != o);
        data[id].setValue(qvariant_cast<QObject *>(value));
    } else {
        needActivate = (data[id].dataType() != qMetaTypeId<QVariant>() || 
                        data[id].asQVariant().userType() != value.userType() || 
                        data[id].asQVariant() != value);
        data[id].setValue(value);
    }
    if (needActivate)
        activate(object, methodOffset + id, 0);
}

void QDeclarativeVMEMetaObject::listChanged(int id)
{
    activate(object, methodOffset + id, 0);
}

void QDeclarativeVMEMetaObject::list_append(QDeclarativeListProperty<QObject> *prop, QObject *o)
{
    List *list = static_cast<List *>(prop->data);
    list->append(o);
    QMetaObject::activate(prop->object, list->notifyIndex, 0);
}

int QDeclarativeVMEMetaObject::list_count(QDeclarativeListProperty<QObject> *prop)
{
    return static_cast<List *>(prop->data)->count();
}

QObject *QDeclarativeVMEMetaObject::list_at(QDeclarativeListProperty<QObject> *prop, int index)
{
    return static_cast<List *>(prop->data)->at(index);
}

void QDeclarativeVMEMetaObject::list_clear(QDeclarativeListProperty<QObject> *prop)
{
    List *list = static_cast<List *>(prop->data);
    list->clear();
    QMetaObject::activate(prop->object, list->notifyIndex, 0);
}

void QDeclarativeVMEMetaObject::registerInterceptor(int index, int valueIndex, QDeclarativePropertyValueInterceptor *interceptor)
{
    if (aInterceptors.isEmpty())
        aInterceptors.resize(propertyCount() + metaData->propertyCount);
    aInterceptors.setBit(index);
    interceptors.insert(index, qMakePair(valueIndex, interceptor));
}

int QDeclarativeVMEMetaObject::vmeMethodLineNumber(int index)
{
    if (index < methodOffset) {
        Q_ASSERT(parent);
        return static_cast<QDeclarativeVMEMetaObject *>(parent)->vmeMethodLineNumber(index);
    }

    int plainSignals = metaData->signalCount + metaData->propertyCount + metaData->aliasCount;
    Q_ASSERT(index >= (methodOffset + plainSignals) && index < (methodOffset + plainSignals + metaData->methodCount));

    int rawIndex = index - methodOffset - plainSignals;

    QDeclarativeVMEMetaData::MethodData *data = metaData->methodData() + rawIndex;
    return data->lineNumber;
}

QScriptValue QDeclarativeVMEMetaObject::vmeMethod(int index)
{
    if (index < methodOffset) {
        Q_ASSERT(parent);
        return static_cast<QDeclarativeVMEMetaObject *>(parent)->vmeMethod(index);
    }
    int plainSignals = metaData->signalCount + metaData->propertyCount + metaData->aliasCount;
    Q_ASSERT(index >= (methodOffset + plainSignals) && index < (methodOffset + plainSignals + metaData->methodCount));
    return method(index - methodOffset - plainSignals);
}

void QDeclarativeVMEMetaObject::setVmeMethod(int index, const QScriptValue &value)
{
    if (index < methodOffset) {
        Q_ASSERT(parent);
        return static_cast<QDeclarativeVMEMetaObject *>(parent)->setVmeMethod(index, value);
    }
    int plainSignals = metaData->signalCount + metaData->propertyCount + metaData->aliasCount;
    Q_ASSERT(index >= (methodOffset + plainSignals) && index < (methodOffset + plainSignals + metaData->methodCount));

    if (!methods) 
        methods = new QScriptValue[metaData->methodCount];
    methods[index - methodOffset - plainSignals] = value;
}

QScriptValue QDeclarativeVMEMetaObject::vmeProperty(int index)
{
    if (index < propOffset) {
        Q_ASSERT(parent);
        return static_cast<QDeclarativeVMEMetaObject *>(parent)->vmeProperty(index);
    }
    return readVarProperty(index - propOffset);
}

void QDeclarativeVMEMetaObject::setVMEProperty(int index, const QScriptValue &v)
{
    if (index < propOffset) {
        Q_ASSERT(parent);
        static_cast<QDeclarativeVMEMetaObject *>(parent)->setVMEProperty(index, v);
    }
    return writeVarProperty(index - propOffset, v);
}

bool QDeclarativeVMEMetaObject::aliasTarget(int index, QObject **target, int *coreIndex, int *valueTypeIndex) const
{
    Q_ASSERT(index >= propOffset + metaData->propertyCount);

    *target = 0;
    *coreIndex = -1;
    *valueTypeIndex = -1;

    if (!ctxt)
        return false;

    QDeclarativeVMEMetaData::AliasData *d = metaData->aliasData() + (index - propOffset - metaData->propertyCount);
    QDeclarativeContext *context = ctxt->asQDeclarativeContext();
    QDeclarativeContextPrivate *ctxtPriv = QDeclarativeContextPrivate::get(context);

    *target = ctxtPriv->data->idValues[d->contextIdx].data();
    if (!*target)
        return false;

    if (d->isObjectAlias()) {
    } else if (d->isValueTypeAlias()) {
        *coreIndex = d->propertyIndex();
        *valueTypeIndex = d->valueTypeIndex();
    } else {
        *coreIndex = d->propertyIndex();
    }

    return true;
}

void QDeclarativeVMEMetaObject::connectAlias(int aliasId)
{
    if (!aConnected.testBit(aliasId)) {
        aConnected.setBit(aliasId);

        QDeclarativeContext *context = ctxt->asQDeclarativeContext();
        QDeclarativeContextPrivate *ctxtPriv = QDeclarativeContextPrivate::get(context);

        QDeclarativeVMEMetaData::AliasData *d = metaData->aliasData() + aliasId;

        QObject *target = ctxtPriv->data->idValues[d->contextIdx].data();
        if (!target) 
            return;

        int sigIdx = methodOffset + aliasId + metaData->propertyCount;
        QMetaObject::connect(context, d->contextIdx + ctxtPriv->notifyIndex, object, sigIdx);

        if (!d->isObjectAlias()) {
            QMetaProperty prop = target->metaObject()->property(d->propertyIndex());
            if (prop.hasNotifySignal())
                QDeclarativePropertyPrivate::connect(target, prop.notifySignalIndex(), object, sigIdx);
        }
    }
}

void QDeclarativeVMEMetaObject::connectAliasSignal(int index)
{
    int aliasId = (index - methodOffset) - metaData->propertyCount;
    if (aliasId < 0 || aliasId >= metaData->aliasCount)
        return;

    connectAlias(aliasId);
}

QT_END_NAMESPACE
