/****************************************************************************
**
** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt3D module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** 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.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qnode.h"
#include "qnode_p.h"
#include "qscene_p.h"

#include <Qt3DCore/QComponent>
#include <Qt3DCore/qaspectengine.h>
#include <Qt3DCore/qdynamicpropertyupdatedchange.h>
#include <Qt3DCore/qentity.h>
#include <Qt3DCore/qnodedestroyedchange.h>
#include <Qt3DCore/qpropertynodeaddedchange.h>
#include <Qt3DCore/qpropertynoderemovedchange.h>
#include <Qt3DCore/qpropertyupdatedchange.h>
#include <QtCore/QChildEvent>
#include <QtCore/QEvent>
#include <QtCore/QMetaObject>
#include <QtCore/QMetaProperty>

#include <Qt3DCore/private/corelogging_p.h>
#include <Qt3DCore/private/qdestructionidandtypecollector_p.h>
#include <Qt3DCore/private/qnodevisitor_p.h>
#include <Qt3DCore/private/qpostman_p.h>
#include <Qt3DCore/private/qscene_p.h>
#include <Qt3DCore/private/qaspectengine_p.h>
#include <Qt3DCore/private/qaspectmanager_p.h>
#include <QtCore/private/qmetaobject_p.h>

QT_BEGIN_NAMESPACE

namespace Qt3DCore {

QNodePrivate::QNodePrivate()
    : QObjectPrivate()
    , m_changeArbiter(nullptr)
    , m_typeInfo(nullptr)
    , m_scene(nullptr)
    , m_id(QNodeId::createId())
    , m_blockNotifications(false)
    , m_hasBackendNode(false)
    , m_enabled(true)
    , m_notifiedParent(false)
    , m_defaultPropertyTrackMode(QNode::TrackFinalValues)
    , m_propertyChangesSetup(false)
    , m_signals(this)
{
}

QNodePrivate::~QNodePrivate()
{
}

void QNodePrivate::init(QNode *parent)
{
    if (!parent)
        return;

    // If we have a QNode parent that has a scene (and hence change arbiter),
    // copy these to this QNode. If valid, then also notify the backend
    // in a deferred way when the object is fully constructed. This is delayed
    // until the object is fully constructed as it involves calling a virtual
    // function of QNode.
    m_parentId = parent->id();
    const auto parentPrivate = get(parent);
    m_scene = parentPrivate->m_scene;
    Q_Q(QNode);
    if (m_scene) {
        // schedule the backend notification and scene registering -> set observers through scene
        m_scene->postConstructorInit()->addNode(q);
    }
}

/*!
 * \internal
 *
 * Sends QNodeCreatedChange events to the aspects.
 */
void QNodePrivate::createBackendNode()
{
    // Do nothing if we already have already sent a node creation change
    // and not a subsequent node destroyed change.
    if (m_hasBackendNode || !m_scene || !m_scene->engine())
        return;

    Q_Q(QNode);
    QAspectEnginePrivate::get(m_scene->engine())->addNode(q);
}

/*!
 * \internal
 *
 * Notify the backend that the parent lost this node as a child and
 * that this node is being destroyed. We only send the node removed
 * change for the parent's children property iff we have an id for
 * a parent node. This is set/unset in the _q_addChild()/_q_removeChild()
 * functions (and initialized in init() if there is a parent at
 * construction time).
 *
 * Likewise, we only send the node destroyed change, iff we have
 * previously sent a node created change. This is tracked via the
 * m_hasBackendNode member.
 */
void QNodePrivate::notifyDestructionChangesAndRemoveFromScene()
{
    Q_Q(QNode);

    // We notify the backend that the parent lost us as a child
    if (m_changeArbiter != nullptr && !m_parentId.isNull()) {
        const auto change = QPropertyNodeRemovedChangePtr::create(m_parentId, q);
        change->setPropertyName("children");
        notifyObservers(change);
    }

    // Tell the backend we are about to be destroyed
    if (m_hasBackendNode && m_scene && m_scene->engine())
        QAspectEnginePrivate::get(m_scene->engine())->removeNode(q);

    // We unset the scene from the node as its backend node was/is about to be destroyed
    QNodeVisitor visitor;
    visitor.traverse(q, this, &QNodePrivate::unsetSceneHelper);
}

/*!
 * \internal
 *
 * Sends a QNodeCreatedChange event to the aspects and then also notifies the
 * parent backend node of its new child. This is called in a deferred manner
 * by NodePostConstructorInit::processNodes to notify the backend of newly created
 * nodes with a parent that is already part of the scene.
 *
 * Also notify the scene of this node, so it may set it's change arbiter.
 */
void QNodePrivate::_q_postConstructorInit()
{
    Q_Q(QNode);

    // If we've already done the work then bail out. This can happen if the
    // user creates a QNode subclass with an explicit parent, then immediately
    // sets the new QNode as a property on another node. In this case, the
    // property setter will call this function directly, but as we can't
    // un-schedule a deferred invocation, this function will be called again
    // the next time the event loop spins. So, catch this case and abort.
    if (m_hasBackendNode)
        return;

    // Check that the parent hasn't been unset since this call was enqueued
    auto parentNode = q->parentNode();
    if (!parentNode)
        return;

    // Set the scene on this node and all children it references so that all
    // children have a scene set since createBackendNode will set
    // m_hasBackendNode to true for all children, which would prevent them from
    // ever having their scene set
    if (m_scene) {
        QNodeVisitor visitor;
        visitor.traverse(q, parentNode->d_func(), &QNodePrivate::setSceneHelper);
    }

    // Let the backend know we have been added to the scene
    createBackendNode();

    // Let the backend parent know that they have a new child
    Q_ASSERT(parentNode);
    QNodePrivate::get(parentNode)->_q_addChild(q);
}

/*!
 * \internal
 *
 * Called by _q_setParentHelper() or _q_postConstructorInit()
 * on the main thread.
 */
void QNodePrivate::_q_addChild(QNode *childNode)
{
    Q_ASSERT(childNode);
    Q_ASSERT_X(childNode->parent() == q_func(), Q_FUNC_INFO,  "not a child of this node");

    // Have we already notified the parent about its new child? If so, bail out
    // early so that we do not send more than one new child event to the backend
    QNodePrivate *childD = QNodePrivate::get(childNode);
    if (childD->m_notifiedParent == true)
        return;

    // Store our id as the parentId in the child so that even if the child gets
    // removed from the scene as part of the destruction of the parent, when the
    // parent's children are deleted in the QObject dtor, we still have access to
    // the parentId. If we didn't store this, we wouldn't have access at that time
    // because the parent would then only be a QObject, the QNode part would have
    // been destroyed already.
    childD->m_parentId = m_id;

    if (!m_scene)
        return;

    // We need to send a QPropertyNodeAddedChange to the backend
    // to notify the backend that we have a new child
    if (m_changeArbiter != nullptr) {
        // Flag that we have notified the parent. We do this immediately before
        // creating the change because that recurses back into this function and
        // we need to catch that to avoid sending more than one new child event
        // to the backend.
        childD->m_notifiedParent = true;
        const auto change = QPropertyNodeAddedChangePtr::create(m_id, childNode);
        change->setPropertyName("children");
        notifyObservers(change);
    }

    // Update the scene
    // TODO: Fold this into the QAspectEnginePrivate::addNode so we don't have to
    // traverse the sub tree three times!
    QNodeVisitor visitor;
    visitor.traverse(childNode, this, &QNodePrivate::addEntityComponentToScene);
}

/*!
 * \internal
 *
 * Called by _q_setParentHelper on the main thread.
 */
void QNodePrivate::_q_removeChild(QNode *childNode)
{
    Q_ASSERT(childNode);
    Q_ASSERT_X(childNode->parent() == q_func(), Q_FUNC_INFO, "not a child of this node");

    QNodePrivate::get(childNode)->m_parentId = QNodeId();

    // We notify the backend that we lost a child
    if (m_changeArbiter != nullptr) {
        const auto change = QPropertyNodeRemovedChangePtr::create(m_id, childNode);
        change->setPropertyName("children");
        notifyObservers(change);
    }
}

/*!
 * \internal
 *
 * Reparents the public QNode to \a parent. If the new parent is nullptr then this
 * QNode is no longer part of the scene and so we notify the backend of its removal
 * from its parent's list of children, and then send a QNodeDestroyedChange to the
 * aspects so that the corresponding backend node is destroyed.
 *
 * If \a parent is not null, then we must tell its new parent about this QNode now
 * being a child of it on the backend. If this QNode did not have a parent upon
 * entry to this function, then we must first send a QNodeCreatedChange to the backend
 * prior to sending the QPropertyNodeAddedChange to its parent.
 *
 * Note: This function should never be called from the ctor directly as the type may
 * not be fully created yet and creating creation changes involves calling a virtual
 * function on QNode. The function _q_notifyCreationAndChildChanges() is used
 * for sending initial notification when a parent is passed to the QNode ctor.
 * That function does a subset of this function with the assumption that the new object
 * had no parent before (must be true as it is newly constructed).
 */
void QNodePrivate::_q_setParentHelper(QNode *parent)
{
    Q_Q(QNode);
    QNode *oldParentNode = q->parentNode();

    // If we had a parent, we let him know that we are about to change
    // parent
    if (oldParentNode && m_hasBackendNode) {
        QNodePrivate::get(oldParentNode)->_q_removeChild(q);

        // If we have an old parent but the new parent is null or if the new
        // parent hasn't yet been added to the backend the backend node needs
        // to be destroyed
        // e.g:
        // QEntity *child = new QEntity(some_parent);
        // After some time, in a later event loop
        // QEntity *newSubTreeRoot = new QEntity(someGlobalExisitingRoot)
        // child->setParent(newSubTreeRoot)
        if (!parent || !QNodePrivate::get(parent)->m_hasBackendNode)
            notifyDestructionChangesAndRemoveFromScene();
    }

    // Flag that we need to notify any new parent
    m_notifiedParent = false;

    // Basically QObject::setParent but for QObjectPrivate
    QObjectPrivate::setParent_helper(parent);

    if (parent) {
        // If we had no parent but are about to set one,
        // we need to send a QNodeCreatedChange
        QNodePrivate *newParentPrivate = QNodePrivate::get(parent);

        // Set the scene helper / arbiter
        if (newParentPrivate->m_scene) {
            QNodeVisitor visitor;
            visitor.traverse(q, parent->d_func(), &QNodePrivate::setSceneHelper);
        }

        // We want to make sure that subTreeRoot is always created before
        // child.
        // Given a case such as below
        // QEntity *subTreeRoot = new QEntity(someGlobalExisitingRoot)
        // QEntity *child = new QEntity();
        // child->setParent(subTreeRoot)
        // We need to take into account that subTreeRoot needs to be
        // created in the backend before the child.
        // Therefore we only call createBackendNode if the parent
        // hasn't been created yet as we know that when the parent will be
        // fully created, it will also send the changes for all of its
        // children

        if (newParentPrivate->m_hasBackendNode)
            createBackendNode();

        // If we have a valid new parent, we let him know that we are its child
        QNodePrivate::get(parent)->_q_addChild(q);
    }
}

void QNodePrivate::registerNotifiedProperties()
{
    Q_Q(QNode);
    if (m_propertyChangesSetup)
        return;

    const int offset = QNode::staticMetaObject.propertyOffset();
    const int count = q->metaObject()->propertyCount();

    for (int index = offset; index < count; index++)
        m_signals.connectToPropertyChange(q, index);

    m_propertyChangesSetup = true;
}

void QNodePrivate::unregisterNotifiedProperties()
{
    Q_Q(QNode);
    if (!m_propertyChangesSetup)
        return;

    const int offset = QNode::staticMetaObject.propertyOffset();
    const int count = q->metaObject()->propertyCount();

    for (int index = offset; index < count; index++)
        m_signals.disconnectFromPropertyChange(q, index);

    m_propertyChangesSetup = false;
}

void QNodePrivate::propertyChanged(int propertyIndex)
{
    Q_UNUSED(propertyIndex)

    // Bail out early if we can to avoid the cost below
    if (m_blockNotifications)
        return;

    update();
}

/*!
    \internal
    Recursively sets and adds the nodes in the subtree of base node \a root to the scene.
    Also takes care of connecting Components and Entities together in the scene.
 */
void QNodePrivate::setSceneHelper(QNode *root)
{
    // Sets the scene
    root->d_func()->setScene(m_scene);
    // addObservable sets the QChangeArbiter
    m_scene->addObservable(root);

    // We also need to handle QEntity <-> QComponent relationships
    if (QComponent *c = qobject_cast<QComponent *>(root)) {
        const QVector<QEntity *> entities = c->entities();
        for (QEntity *entity : entities) {
            if (!m_scene->hasEntityForComponent(c->id(), entity->id())) {
                if (!c->isShareable() && !m_scene->entitiesForComponent(c->id()).isEmpty())
                    qWarning() << "Trying to assign a non shareable component to more than one Entity";
                m_scene->addEntityForComponent(c->id(), entity->id());
            }
        }
    }
}

/*!
    \internal

    Recursively unsets and remove nodes in the subtree of base node \a root from
    the scene. Also takes care of removing Components and Entities connections.
 */
void QNodePrivate::unsetSceneHelper(QNode *node)
{
    QNodePrivate *nodePrivate = QNodePrivate::get(node);

    // We also need to handle QEntity <-> QComponent relationships removal
    if (QComponent *c = qobject_cast<QComponent *>(node)) {
        const QVector<QEntity *> entities = c->entities();
        for (QEntity *entity : entities) {
            if (nodePrivate->m_scene)
                nodePrivate->m_scene->removeEntityForComponent(c->id(), entity->id());
        }
    }

    if (nodePrivate->m_scene != nullptr)
        nodePrivate->m_scene->removeObservable(node);
    nodePrivate->setScene(nullptr);
}

/*!
    \internal
 */
void QNodePrivate::addEntityComponentToScene(QNode *root)
{
    if (QEntity *e = qobject_cast<QEntity *>(root)) {
        const auto components = e->components();
        for (QComponent *c : components) {
            if (!m_scene->hasEntityForComponent(c->id(), e->id()))
                m_scene->addEntityForComponent(c->id(), e->id());
        }
    }
}

/*!
    \internal
 */
// Called in the main thread by QScene -> following QEvent::childAdded / addChild
void QNodePrivate::setArbiter(QLockableObserverInterface *arbiter)
{
    if (m_changeArbiter && m_changeArbiter != arbiter) {
        unregisterNotifiedProperties();

        // Remove node from dirtyFrontendNodeList on old arbiter
        Q_Q(QNode);
        m_changeArbiter->removeDirtyFrontEndNode(q);
    }
    m_changeArbiter = static_cast<QAbstractArbiter *>(arbiter);
    if (m_changeArbiter)
        registerNotifiedProperties();
}

/*!
 * \internal
 * Makes sure this node has a backend by traversing the tree up to the most distant ancestor
 * without a backend node and initializing that node. This is done to make sure the parent nodes
 * are always created before the child nodes, since child nodes reference parent nodes at creation
 * time.
 */
void QNodePrivate::_q_ensureBackendNodeCreated()
{
    if (m_hasBackendNode)
        return;

    Q_Q(QNode);

    QNode *nextNode = q;
    QNode *topNodeWithoutBackend = nullptr;
    while (nextNode != nullptr && !QNodePrivate::get(nextNode)->m_hasBackendNode) {
        topNodeWithoutBackend = nextNode;
        nextNode = nextNode->parentNode();
    }
    QNodePrivate::get(topNodeWithoutBackend)->_q_postConstructorInit();
}

/*!
    \class Qt3DCore::QNode
    \inherits QObject

    \inmodule Qt3DCore
    \since 5.5

    \brief QNode is the base class of all Qt3D node classes used to build a
    Qt3D scene.

    The owernship of QNode is determined by the QObject parent/child
    relationship between nodes. By itself, a QNode has no visual appearance
    and no particular meaning, it is there as a way of building a node based tree
    structure.

    The parent of a QNode instance can only be another QNode instance.

    Each QNode instance has a unique id that allows it to be recognizable
    from other instances.

    When properties are defined on a QNode subclass, their NOTIFY signal
    will automatically generate notifications that the Qt3D backend aspects will
    receive.

    \sa QEntity, QComponent
*/

/*!
 * Sends the \a change QSceneChangePtr to any QBackendNodes in the registered
 * aspects that correspond to this QNode.
 *
 * You only need to call this function if you wish to send a specific type of
 * change in place of the automatic handling.
 *
 * Note: as of Qt 5.14, change messages are deprecated and should not be used,
 * in particular for properties.
 */
void QNode::notifyObservers(const QSceneChangePtr &change)
{
    Q_D(QNode);
    d->notifyObservers(change);
}

/*!
    \obsolete

    Called when one or more backend aspects sends a notification \a change to the
    current Qt3DCore::QNode instance.

    \note This method should be reimplemented in your subclasses to properly
    handle the \a change.
*/
void QNode::sceneChangeEvent(const QSceneChangePtr &change)
{
    Q_UNUSED(change)
    if (change->type() == Qt3DCore::PropertyUpdated) {
        // TODO: Do this more efficiently. We could pass the metaobject and property
        //       index to the animation aspect via the QChannelMapping. This would
        //       allow us to avoid the propertyIndex lookup here by sending them in
        //       a new subclass of QPropertyUpdateChange.
        // Try to find property and call setter
        auto e = qSharedPointerCast<Qt3DCore::QPropertyUpdatedChange>(change);
        const QMetaObject *mo = metaObject();
        const int propertyIndex = mo->indexOfProperty(e->propertyName());
        QMetaProperty mp = mo->property(propertyIndex);
        bool wasBlocked = blockNotifications(true);
        mp.write(this, e->value());
        blockNotifications(wasBlocked);
    } else {
        // Nothing is handling this change, warn the user.
        qWarning() << Q_FUNC_INFO << "sceneChangeEvent should have been subclassed";
    }
}

/*!
    \internal
 */
void QNodePrivate::setScene(QScene *scene)
{
    if (m_scene != scene) {
        if (m_scene != nullptr)
            m_scene->removePropertyTrackDataForNode(m_id);
        m_scene = scene;
        // set PropertyTrackData in the scene
        updatePropertyTrackMode();
    }
}

/*!
    \internal
 */
QScene *QNodePrivate::scene() const
{
    return m_scene;
}

/*!
    \internal
 */
void QNodePrivate::notifyPropertyChange(const char *name, const QVariant &value)
{
    Q_UNUSED(name)
    Q_UNUSED(value)

    // Bail out early if we can to avoid operator new
    if (m_blockNotifications)
        return;

    update();
}

void QNodePrivate::notifyDynamicPropertyChange(const QByteArray &name, const QVariant &value)
{
    Q_UNUSED(name)
    Q_UNUSED(value)

    // Bail out early if we can to avoid operator new
    if (m_blockNotifications)
        return;

    update();
}

/*!
    \internal
 */
// Called by the main thread
void QNodePrivate::notifyObservers(const QSceneChangePtr &change)
{
    Q_ASSERT(change);

    // Don't send notifications if we are blocking
    if (m_blockNotifications && change->type() == PropertyUpdated)
        return;

    if (m_changeArbiter != nullptr) {
        QAbstractPostman *postman = m_changeArbiter->postman();
        if (postman != nullptr)
            postman->notifyBackend(change);
    }
}

// Inserts this tree into the main Scene tree.
// Needed when SceneLoaders provide a cloned tree from the backend
// and need to insert it in the main scene tree
// QNode *root;
// QNode *subtree;
// QNodePrivate::get(root)->insertTree(subtree);

/*!
    \internal
 */
void QNodePrivate::insertTree(QNode *treeRoot, int depth)
{
    if (m_scene != nullptr) {
        treeRoot->d_func()->setScene(m_scene);
        m_scene->addObservable(treeRoot);
    }

    for (QObject *c : treeRoot->children()) {
        QNode *n = nullptr;
        if ((n = qobject_cast<QNode *>(c)) != nullptr)
            insertTree(n, depth + 1);
    }

    if (depth == 0)
        treeRoot->setParent(q_func());
}

void QNodePrivate::updatePropertyTrackMode()
{
    if (m_scene != nullptr) {
        QScene::NodePropertyTrackData trackData;
        trackData.defaultTrackMode = m_defaultPropertyTrackMode;
        trackData.trackedPropertiesOverrides = m_trackedPropertiesOverrides;
        m_scene->setPropertyTrackDataForNode(m_id, trackData);
    }
}

void QNodePrivate::update()
{
    if (m_changeArbiter) {
        Q_Q(QNode);
        m_changeArbiter->addDirtyFrontEndNode(q);
    }
}

void QNodePrivate::updateNode(QNode *node, const char *property, ChangeFlag change)
{
    if (m_changeArbiter) {
        // Ensure node has its postConstructorInit called if we reach this
        // point, we could otherwise endup referencing a node that has yet
        // to be created in the backend
        QNodePrivate::get(node)->_q_ensureBackendNodeCreated();

        Q_Q(QNode);
        m_changeArbiter->addDirtyFrontEndNode(q, node, property, change);
    }
}

/*!
    \internal
 */
QNodePrivate *QNodePrivate::get(QNode *q)
{
    return q->d_func();
}

/*!
    \internal
 */
const QNodePrivate *QNodePrivate::get(const QNode *q)
{
    return q->d_func();
}

/*!
    \internal
 */
void QNodePrivate::nodePtrDeleter(QNode *q)
{
    QObject *p = q->parent();
    if (p == nullptr)
        p = q;
    p->deleteLater();
}

/*!
    \fn Qt3DCore::QNodeId Qt3DCore::qIdForNode(Qt3DCore::QNode *node)
    \relates Qt3DCore::QNode
    \return node id for \a node.
*/

/*!
    \fn template<typename T> Qt3DCore::QNodeIdVector Qt3DCore::qIdsForNodes(const T &nodes)
    \relates Qt3DCore::QNode
    \return vector of node ids for \a nodes.
*/

/*!
    \fn void Qt3DCore::QNodeCommand::setReplyToCommandId(CommandId id)

    Sets the command \a id to which the message is a reply.

*/
/*!
    \fn  Qt3DCore::QNode::PropertyTrackingMode Qt3DCore::QNode::defaultPropertyTrackingMode() const

    Returns the default property tracking mode which determines whether a
    QNode should be listening for property updates.

*/
/*!
    \fn Qt3DCore::QNode::clearPropertyTracking(const QString &propertyName)

    Clears the tracking property called \a propertyName.
*/
/*!
    \fn Qt3DCore::QNode::PropertyTrackingMode Qt3DCore::QNode::propertyTracking(const QString &propertyName) const

    Returns the tracking mode of \a propertyName.
*/

/*!
    \fn Qt3DCore::QNode::setPropertyTracking(const QString &propertyName, Qt3DCore::QNode::PropertyTrackingMode trackMode)

    Sets the property tracking for \a propertyName and \a trackMode.
*/

/*!
     Creates a new QNode instance with parent \a parent.

     \note The backend aspects will be notified that a QNode instance is
     part of the scene only if it has a parent; unless this is the root node of
     the Qt3D scene.

     \sa setParent()
*/
QNode::QNode(QNode *parent)
    : QNode(*new QNodePrivate, parent) {}

/*! \internal */
QNode::QNode(QNodePrivate &dd, QNode *parent)
    : QObject(dd, parent)
{
    Q_D(QNode);
    d->init(parent);
}

/*!
    \fn Qt3DCore::QNode::nodeDestroyed()
    Emitted when the node is destroyed.
*/

/*! \internal */
QNode::~QNode()
{
    Q_D(QNode);
    // Disconnect each connection that was stored
    for (const auto &nodeConnectionPair : qAsConst(d->m_destructionConnections))
        QObject::disconnect(nodeConnectionPair.second);
    d->m_destructionConnections.clear();
    Q_EMIT nodeDestroyed();

    // Notify the backend that the parent lost this node as a child and
    // that this node is being destroyed.
    d->notifyDestructionChangesAndRemoveFromScene();
}

/*!
    Returns the id that uniquely identifies the QNode instance.
*/
QNodeId QNode::id() const
{
    Q_D(const QNode);
    return d->m_id;
}

/*!
    \property Qt3DCore::QNode::parent

    Holds the immediate QNode parent, or null if the node has no parent.

    Setting the parent will notify the backend aspects about current QNode
    instance's parent change.

    \note if \a parent happens to be null, this will actually notify that the
    current QNode instance was removed from the scene.
*/
QNode *QNode::parentNode() const
{
    return qobject_cast<QNode*>(parent());
}

/*!
    Returns \c true if aspect notifications are blocked; otherwise returns \c false.
    By default, notifications are \e not blocked.

    \sa blockNotifications()
*/
bool QNode::notificationsBlocked() const
{
    Q_D(const QNode);
    return d->m_blockNotifications;
}

/*!
    If \a block is \c true, property change notifications sent by this object
    to aspects are blocked. If \a block is \c false, no such blocking will occur.

    The return value is the previous value of notificationsBlocked().

    Note that the other notification types will be sent even if the
    notifications for this object have been blocked.

    \sa notificationsBlocked()
*/
bool QNode::blockNotifications(bool block)
{
    Q_D(QNode);
    bool previous = d->m_blockNotifications;
    d->m_blockNotifications = block;
    return previous;
}

// Note: should never be called from the ctor directly as the type may not be fully
// created yet
void QNode::setParent(QNode *parent)
{
    Q_D(QNode);

    // If we already have a parent don't do anything. Be careful to ensure
    // that QNode knows about the parent, not just QObject (by checking the ids)
    if (parentNode() == parent &&
            ((parent != nullptr && d->m_parentId == parentNode()->id()) || parent == nullptr))
        return;

    // remove ourself from postConstructorInit queue. The call to _q_setParentHelper
    // will take care of creating the backend node if necessary depending on new parent.
    if (d->m_scene)
        d->m_scene->postConstructorInit()->removeNode(this);

    d->_q_setParentHelper(parent);

    // Block notifications as we want to let the _q_setParentHelper
    // manually handle them
    const bool blocked = blockNotifications(true);
    emit parentChanged(parent);
    blockNotifications(blocked);
}

/*!
    \typedef Qt3DCore::QNodePtr
    \relates Qt3DCore::QNode

    A shared pointer for QNode.
*/
/*!
    \typedef Qt3DCore::QNodeVector
    \relates Qt3DCore::QNode

    List of QNode pointers.
*/

/*!
 * Returns a list filled with the QNode children of the current
 * QNode instance.
 */
QNodeVector QNode::childNodes() const
{
    QNodeVector nodeChildrenList;
    const QObjectList &objectChildrenList = QObject::children();
    nodeChildrenList.reserve(objectChildrenList.size());

    for (QObject *c : objectChildrenList) {
        if (QNode *n = qobject_cast<QNode *>(c))
            nodeChildrenList.push_back(n);
    }

    return nodeChildrenList;
}
void QNode::setEnabled(bool isEnabled)
{
    Q_D(QNode);

    if (d->m_enabled == isEnabled)
        return;

    d->m_enabled = isEnabled;
    emit enabledChanged(isEnabled);
}

void QNode::setDefaultPropertyTrackingMode(QNode::PropertyTrackingMode mode)
{
    Q_D(QNode);
    if (d->m_defaultPropertyTrackMode == mode)
        return;

    d->m_defaultPropertyTrackMode = mode;
    // The backend doesn't care about such notification
    const bool blocked = blockNotifications(true);
    emit defaultPropertyTrackingModeChanged(mode);
    blockNotifications(blocked);
    d->updatePropertyTrackMode();
}

/*!
    \property Qt3DCore::QNode::enabled

    Holds the QNode enabled flag.
    By default a QNode is always enabled.

    \note the interpretation of what enabled means is aspect-dependent. Even if
    enabled is set to \c false, some aspects may still consider the node in
    some manner. This is documented on a class by class basis.
*/
bool QNode::isEnabled() const
{
    Q_D(const QNode);
    return d->m_enabled;
}

/*!
    \property Qt3DCore::QNode::defaultPropertyTrackingMode

    Holds the default property tracking mode which determines whether a QNode should
    be listening for property updates. This only applies to properties which
    haven't been overridden by a call to setPropertyTracking.

    By default it is set to QNode::TrackFinalValues
*/
QNode::PropertyTrackingMode QNode::defaultPropertyTrackingMode() const
{
    Q_D(const QNode);
    return d->m_defaultPropertyTrackMode;
}

void QNode::setPropertyTracking(const QString &propertyName, QNode::PropertyTrackingMode trackMode)
{
    Q_D(QNode);
    d->m_trackedPropertiesOverrides.insert(propertyName, trackMode);
    d->updatePropertyTrackMode();
}

QNode::PropertyTrackingMode QNode::propertyTracking(const QString &propertyName) const
{
    Q_D(const QNode);
    return d->m_trackedPropertiesOverrides.value(propertyName, d->m_defaultPropertyTrackMode);
}

void QNode::clearPropertyTracking(const QString &propertyName)
{
    Q_D(QNode);
    d->m_trackedPropertiesOverrides.remove(propertyName);
    d->updatePropertyTrackMode();
}

void QNode::clearPropertyTrackings()
{
    Q_D(QNode);
    d->m_trackedPropertiesOverrides.clear();
    d->updatePropertyTrackMode();
}

/*!
 * \obsolete
 */
QNodeCreatedChangeBasePtr QNode::createNodeCreationChange() const
{
    // Uncomment this when implementing new frontend and backend types.
    // Any classes that don't override this function will be noticeable here.
    // Note that some classes actually don't need to override as they have
    // no additional data to send. In those cases this default implementation
    // is perfectly fine.
    // const QMetaObject *mo = metaObject();
    // qDebug() << Q_FUNC_INFO << mo->className();
    return QNodeCreatedChangeBasePtr::create(this);
}

/*!
   \fn Qt3DCore::QNodeCommand::CommandId Qt3DCore::QNodeCommand::inReplyTo() const

   Returns the id of the original QNodeCommand message that
   was sent to the backend.

*/
/*!
    \fn void Qt3DCore::QNodeCommand::setData(const QVariant &data)

    Sets the data (\a data) in the backend node to perform
    the operations requested.
*/
/*!
    \fn void Qt3DCore::QNodeCommand::setName(const QString &name)


    Sets the data (\a name) in the backend node to perform
    the operations requested.
*/

/*!
    \enum Qt3DCore::QNode::PropertyTrackingMode

    Indicates how a QNode listens for property updates.

    \value TrackFinalValues
           Tracks final values
    \value DontTrackValues
           Does not track values
    \value TrackAllValues
           Tracks all values
*/
/*!
    \fn Qt3DCore::QNode::clearPropertyTrackings()

    Erases all values that have been saved by the property tracking.
*/
/*!
 * \brief Sends a command message to the backend node
 * \obsolete
 *
 * Creates a QNodeCommand message and dispatches it to the backend node. The
 * command is given and a \a name and some \a data which can be used in the
 * backend node to perform various operations.
 * This returns a CommandId which can be used to identify the initial command
 * when receiving a message in reply. If the command message is to be sent in
 * reply to another command, \a replyTo contains the id of that command.
 *
 * \sa QNodeCommand, QNode::sendReply
 */
QNodeCommand::CommandId QNode::sendCommand(const QString &name,
                                           const QVariant &data,
                                           QNodeCommand::CommandId replyTo)
{
    Q_D(QNode);

    // Bail out early, if we can, to avoid operator new
    if (d->m_blockNotifications)
        return QNodeCommand::CommandId(0);

    auto e = QNodeCommandPtr::create(d->m_id);
    e->setName(name);
    e->setData(data);
    e->setReplyToCommandId(replyTo);
    d->notifyObservers(e);
    return e->commandId();
}

/*!
 * \brief Send a \a command back to the backend node.
 * \obsolete
 *
 * Assumes the command is to be to sent back in reply to itself to the backend node.
 *
 * \sa QNodeCommand, QNode::sendCommand
 */
void QNode::sendReply(const QNodeCommandPtr &command)
{
    Q_D(QNode);
    command->setDeliveryFlags(QSceneChange::BackendNodes);
    d->notifyObservers(command);
}


namespace {

/*! \internal */
inline const QMetaObjectPrivate *priv(const uint* data)
{
    return reinterpret_cast<const QMetaObjectPrivate*>(data);
}

/*! \internal */
inline bool isDynamicMetaObject(const QMetaObject *mo)
{
    return (priv(mo->d.data)->flags & DynamicMetaObject);
}

} // anonymous

/*!
 * \internal
 *
 * Find the most derived metaobject that doesn't have a dynamic
 * metaobject farther up the chain.
 * TODO: Add support to QMetaObject to explicitly say if it's a dynamic
 * or static metaobject so we don't need this logic
 */
const QMetaObject *QNodePrivate::findStaticMetaObject(const QMetaObject *metaObject)
{
    const QMetaObject *lastStaticMetaobject = nullptr;
    auto mo = metaObject;
    while (mo) {
        const bool dynamicMetaObject = isDynamicMetaObject(mo);
        if (dynamicMetaObject)
            lastStaticMetaobject = nullptr;

        if (!dynamicMetaObject && !lastStaticMetaobject)
            lastStaticMetaobject = mo;

        mo = mo->superClass();
    }
    Q_ASSERT(lastStaticMetaobject);
    return lastStaticMetaobject;
}

/*!
 * \internal
 *
 * NodePostConstructorInit handles calling QNode::_q_postConstructorInit for
 * all nodes. By keeping track of nodes that need initialization we can
 * create them all together ensuring they get sent to the backend in a single
 * batch.
 */
NodePostConstructorInit::NodePostConstructorInit(QObject *parent)
    : QObject(parent)
    , m_requestedProcessing(false)
{
}

NodePostConstructorInit::~NodePostConstructorInit() {}

/*!
 * \internal
 *
 * Add a node to the list of nodes needing a call to _q_postConstructorInit
 * We only add the node if it does not have an ancestor already in the queue
 * because initializing the ancestor will initialize all it's children.
 * This ensures that all backend nodes are created from the top-down, with
 * all parents created before their children
 *
 */
void NodePostConstructorInit::addNode(QNode *node)
{
    Q_ASSERT(node);
    QNode *nextNode = node;
    while (nextNode != nullptr && !m_nodesToConstruct.contains(QNodePrivate::get(nextNode)))
        nextNode = nextNode->parentNode();

    if (!nextNode) {
        m_nodesToConstruct.append(QNodePrivate::get(node));
        if (!m_requestedProcessing){
            QMetaObject::invokeMethod(this, "processNodes", Qt::QueuedConnection);
            m_requestedProcessing = true;
        }
    }
}

/*!
 * \internal
 *
 * Remove a node from the queue. This will ensure none of its
 * children get initialized
 */
void NodePostConstructorInit::removeNode(QNode *node)
{
    Q_ASSERT(node);
    m_nodesToConstruct.removeAll(QNodePrivate::get(node));
}

/*!
 * \internal
 *
 * call _q_postConstructorInit for all nodes in the queue
 * and clear the queue
 */
void NodePostConstructorInit::processNodes()
{
    m_requestedProcessing = false;
    while (!m_nodesToConstruct.empty()) {
        auto node = m_nodesToConstruct.takeFirst();
        node->_q_postConstructorInit();
    }
}

} // namespace Qt3DCore

QT_END_NAMESPACE

#include "moc_qnode.cpp"
