/****************************************************************************
**
** Copyright (C) 2017 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL3$
** 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 http://www.qt.io/terms-conditions. For further
** information use the contact form at http://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.LGPLv3 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.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 later 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 2.0 requirements will be
** met: http://www.gnu.org/licenses/gpl-2.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qquickattachedobject_p.h"

#include <QtCore/qpointer.h>
#include <QtQuick/qquickwindow.h>
#include <QtQuick/private/qquickitem_p.h>
#include <QtQuick/private/qquickitemchangelistener_p.h>
#include <QtQuickTemplates2/private/qquickpopup_p.h>

QT_BEGIN_NAMESPACE

static QQuickAttachedObject *attachedObject(const QMetaObject *type, QObject *object, bool create = false)
{
    if (!object)
        return nullptr;
    auto func = qmlAttachedPropertiesFunction(object, type);
    return qobject_cast<QQuickAttachedObject *>(qmlAttachedPropertiesObject(object, func, create));
}

static QQuickAttachedObject *findAttachedParent(const QMetaObject *type, QObject *object)
{
    QQuickItem *item = qobject_cast<QQuickItem *>(object);
    if (item) {
        // lookup parent items and popups
        QQuickItem *parent = item->parentItem();
        while (parent) {
            QQuickAttachedObject *attached = attachedObject(type, parent);
            if (attached)
                return attached;

            QQuickPopup *popup = qobject_cast<QQuickPopup *>(parent->parent());
            if (popup)
                return attachedObject(type, popup);

            parent = parent->parentItem();
        }

        // fallback to item's window
        QQuickAttachedObject *attached = attachedObject(type, item->window());
        if (attached)
            return attached;
    } else {
        // lookup popup's window
        QQuickPopup *popup = qobject_cast<QQuickPopup *>(object);
        if (popup)
            return attachedObject(type, popup->popupItem()->window());
    }

    // lookup parent window
    QQuickWindow *window = qobject_cast<QQuickWindow *>(object);
    if (window) {
        QQuickWindow *parentWindow = qobject_cast<QQuickWindow *>(window->parent());
        if (parentWindow) {
            QQuickAttachedObject *attached = attachedObject(type, window);
            if (attached)
                return attached;
        }
    }

    // fallback to engine (global)
    if (object) {
        QQmlEngine *engine = qmlEngine(object);
        if (engine) {
            QByteArray name = QByteArray("_q_") + type->className();
            QQuickAttachedObject *attached = engine->property(name).value<QQuickAttachedObject *>();
            if (!attached) {
                attached = attachedObject(type, engine, true);
                engine->setProperty(name, QVariant::fromValue(attached));
            }
            return attached;
        }
    }

    return nullptr;
}

static QList<QQuickAttachedObject *> findAttachedChildren(const QMetaObject *type, QObject *object)
{
    QList<QQuickAttachedObject *> children;

    QQuickItem *item = qobject_cast<QQuickItem *>(object);
    if (!item) {
        QQuickWindow *window = qobject_cast<QQuickWindow *>(object);
        if (window) {
            item = window->contentItem();

            const auto &windowChildren = window->children();
            for (QObject *child : windowChildren) {
                QQuickWindow *childWindow = qobject_cast<QQuickWindow *>(child);
                if (childWindow) {
                    QQuickAttachedObject *attached = attachedObject(type, childWindow);
                    if (attached)
                        children += attached;
                }
            }
        }
    }

    if (item) {
        const auto childItems = item->childItems();
        for (QQuickItem *child : childItems) {
            QQuickAttachedObject *attached = attachedObject(type, child);
            if (attached)
                children += attached;
            else
                children += findAttachedChildren(type, child);
        }
    }

    return children;
}

static QQuickItem *findAttachedItem(QObject *parent)
{
    QQuickItem *item = qobject_cast<QQuickItem *>(parent);
    if (!item) {
        QQuickPopup *popup = qobject_cast<QQuickPopup *>(parent);
        if (popup)
            item = popup->popupItem();
    }
    return item;
}

class QQuickAttachedObjectPrivate : public QObjectPrivate, public QQuickItemChangeListener
{
    Q_DECLARE_PUBLIC(QQuickAttachedObject)

public:
    static QQuickAttachedObjectPrivate *get(QQuickAttachedObject *attachedObject)
    {
        return attachedObject->d_func();
    }

    void attachTo(QObject *object);
    void detachFrom(QObject *object);

    void itemWindowChanged(QQuickWindow *window);
    void itemParentChanged(QQuickItem *item, QQuickItem *parent) override;

    QList<QQuickAttachedObject *> attachedChildren;
    QPointer<QQuickAttachedObject> attachedParent;
};

void QQuickAttachedObjectPrivate::attachTo(QObject *object)
{
    QQuickItem *item = findAttachedItem(object);
    if (item) {
        connect(item, &QQuickItem::windowChanged, this, &QQuickAttachedObjectPrivate::itemWindowChanged);
        QQuickItemPrivate::get(item)->addItemChangeListener(this, QQuickItemPrivate::Parent);
    }
}

void QQuickAttachedObjectPrivate::detachFrom(QObject *object)
{
    QQuickItem *item = findAttachedItem(object);
    if (item) {
        disconnect(item, &QQuickItem::windowChanged, this, &QQuickAttachedObjectPrivate::itemWindowChanged);
        QQuickItemPrivate::get(item)->removeItemChangeListener(this, QQuickItemPrivate::Parent);
    }
}

void QQuickAttachedObjectPrivate::itemWindowChanged(QQuickWindow *window)
{
    Q_Q(QQuickAttachedObject);
    QQuickAttachedObject *attachedParent = nullptr;
    QQuickItem *item = qobject_cast<QQuickItem *>(q->sender());
    if (item)
        attachedParent = findAttachedParent(q->metaObject(), item);
    if (!attachedParent)
        attachedParent = attachedObject(q->metaObject(), window);
    q->setAttachedParent(attachedParent);
}

void QQuickAttachedObjectPrivate::itemParentChanged(QQuickItem *item, QQuickItem *parent)
{
    Q_Q(QQuickAttachedObject);
    Q_UNUSED(parent);
    q->setAttachedParent(findAttachedParent(q->metaObject(), item));
}

QQuickAttachedObject::QQuickAttachedObject(QObject *parent)
    : QObject(*(new QQuickAttachedObjectPrivate), parent)
{
    Q_D(QQuickAttachedObject);
    d->attachTo(parent);
}

QQuickAttachedObject::~QQuickAttachedObject()
{
    Q_D(QQuickAttachedObject);
    d->detachFrom(parent());
    setAttachedParent(nullptr);
}

QList<QQuickAttachedObject *> QQuickAttachedObject::attachedChildren() const
{
    Q_D(const QQuickAttachedObject);
    return d->attachedChildren;
}

QQuickAttachedObject *QQuickAttachedObject::attachedParent() const
{
    Q_D(const QQuickAttachedObject);
    return d->attachedParent;
}

void QQuickAttachedObject::setAttachedParent(QQuickAttachedObject *parent)
{
    Q_D(QQuickAttachedObject);
    if (d->attachedParent == parent)
        return;

    QQuickAttachedObject *oldParent = d->attachedParent;
    if (d->attachedParent)
        QQuickAttachedObjectPrivate::get(d->attachedParent)->attachedChildren.removeOne(this);
    d->attachedParent = parent;
    if (parent)
        QQuickAttachedObjectPrivate::get(parent)->attachedChildren.append(this);
    attachedParentChange(parent, oldParent);
}

void QQuickAttachedObject::init()
{
    QQuickAttachedObject *attachedParent = findAttachedParent(metaObject(), parent());
    if (attachedParent)
        setAttachedParent(attachedParent);

    const QList<QQuickAttachedObject *> attachedChildren = findAttachedChildren(metaObject(), parent());
    for (QQuickAttachedObject *child : attachedChildren)
        child->setAttachedParent(this);
}

void QQuickAttachedObject::attachedParentChange(QQuickAttachedObject *newParent, QQuickAttachedObject *oldParent)
{
    Q_UNUSED(newParent);
    Q_UNUSED(oldParent);
}

QT_END_NAMESPACE
