/****************************************************************************
**
** Copyright (C) 2017 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the Qt3D 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 "qscene2d.h"
#include "qscene2d_p.h"
#include <private/qrenderaspect_p.h>
#include "scene2d_p.h"
#include "scene2dmanager_p.h"
#include "scene2devent_p.h"

#include <Qt3DCore/qentity.h>

QT_BEGIN_NAMESPACE

using namespace Qt3DCore;

namespace Qt3DRender {

namespace Quick {

/*!
    \namespace Qt3DRender::Quick
    \inmodule Qt3DScene2D
    \brief Internal namespace to import QML types.
*/

/*!
    \class Qt3DRender::Quick::QScene2D
    \inheaderfile Qt3DQuickScene2D/QScene2D
    \inmodule Qt3DScene2D

    \brief This class enables rendering qml into a texture, which then can be
    used as a part of 3D scene.

    This class uses QQuickRenderControl to render the given QQuickItem into an
    offscreen surface, which is attached to a texture provided by the user. This allows the
    component to directly render into the texture without intermediate copy and the user to
    freely specify how the texture is used in the 3D scene.

    The entities using the QScene2D can be associated with the class to enable interaction
    with the item; if an entity has a QObjectPicker component, the pick events from that picker
    are sent to the QScene2D and converted to mouse events and finally sent to the item.

    \note Only mouse events are supported. The item does not support keyboard input.

    \since 5.9
*/

/*!
    \qmltype Scene2D
    \inqmlmodule QtQuick.Scene2D
    \since 5.9
    \instantiates Qt3DRender::Quick::QScene2D

    \brief This type enables rendering qml into a texture, which then can be
    used as a part of 3D scene.

    This object uses RenderControl to render the given Item into an
    offscreen surface, which is attached to a texture provided by the user. This allows the
    component to directly render into the texture without intermediate copy and the user to
    freely specify how the texture is used in the 3D scene.

    The entities using the Scene2D can be associated with the type to enable interaction
    with the item; if an entity has an ObjectPicker component, the pick events from that picker
    are sent to the Scene2D and converted to mouse events and finally sent to the item.

    \note Only mouse events are supported. The item does not support keyboard input.

    Usage:
    \qml
        Entity {
            id: sceneRoot

            // specify Scene2D inside the entity hierarchy
            Scene2D {
                // specify output
                output: RenderTargetOutput {
                    attachmentPoint: RenderTargetOutput.Color0
                    texture: Texture2D {
                        id: textureId
                        width: 1024
                        height: 1024
                        format: Texture.RGBA8_UNorm
                    }
                }
                // specify entities
                entities: [entityId]

                // specify rendered content
                Rectangle {
                    color: "red"
                }
            }

            Entity {
                id: entityId

                property Material material: TextureMaterial {
                    texture: textureId
                }
                property ObjectPicker picker: ObjectPicker {
                    hoverEnabled: true
                    dragEnabled: true
                }
                ...

    \endqml
 */

/*!
    \enum QScene2D::RenderPolicy

    This enum type describes types of render policies available.
    \value Continuous The Scene2D is rendering continuously. This is the default render policy.
    \value SingleShot The Scene2D renders to the texture only once after which the resources
                      allocated for rendering are released.
*/

/*!
    \qmlproperty RenderTargetOutput Qt3D.Render::Scene2D::output
    Holds the RenderTargetOutput, which specifies where the Scene2D is rendering to.
 */

/*!
    \qmlproperty enumeration Qt3D.Render::Scene2D::renderPolicy
    Holds the render policy of this Scene2D.

    \list
    \li Continuous The Scene2D is rendering continuously. This is the default render policy.
    \li SingleShot The Scene2D renders to the texture only once after which the resources
                      allocated for rendering are released.
    \endlist
 */
/*!
    \qmlproperty Item Qt3D.Render::Scene2D::item
    Holds the Item, which is rendered by Scene2D to the texture.
 */

/*!
    \qmlproperty bool Qt3D.Render::Scene2D::mouseEnabled
    Holds whether mouse events are enabled for the rendered item. The mouse events are
    generated from object picking events of the entities added to the Scene2D.
    Mouse is enabled by default.

    \note Events sent to items are delayed by one frame due to object picking
          happening in the backend.
 */
/*!
    \qmlproperty list<Entity> Qt3D.Render::Scene2D::entities
    Holds the list of entities which are associated with the Scene2D object. If the
    entities have ObjectPicker, the pick events from that entity are sent to Scene2D
    and converted to mouse events.
 */

QScene2DPrivate::QScene2DPrivate()
    : Qt3DCore::QNodePrivate()
    , m_renderManager(new Scene2DManager(this))
    , m_output(nullptr)
{
}

QScene2DPrivate::~QScene2DPrivate()
{
    m_renderManager->cleanup();
    delete m_renderManager;
}


/*!
    The constructor creates a new QScene2D instance with the specified \a parent.
 */
QScene2D::QScene2D(Qt3DCore::QNode *parent)
    : Qt3DCore::QNode(*new QScene2DPrivate, parent)
{
#ifdef QT_STATIC
    static bool isInitialized = false;
    if (!isInitialized) {
        Qt3DRender::QRenderAspectPrivate::configurePlugin(QLatin1String("scene2d"));
    }
#endif
}

/*!
    \property QScene2D::item
    Holds the QQuickItem, which is rendered by QScene2D to the texture.
 */
QQuickItem* QScene2D::item() const
{
    Q_D(const QScene2D);
    return d->m_renderManager->m_item;
}

void QScene2D::setItem(QQuickItem *item)
{
    Q_D(QScene2D);
    if (d->m_renderManager->m_initialized) {
        qWarning() << "Unable to set item after initialization.";
        return;
    }
    if (d->m_renderManager->m_item != item) {
        d->m_renderManager->setItem(item);
        emit itemChanged(item);
    }
}

/*!
    \property QScene2D::renderPolicy

    Holds the render policy of this Scene2D.
 */
QScene2D::RenderPolicy QScene2D::renderPolicy() const
{
    Q_D(const QScene2D);
    return d->m_renderManager->m_renderPolicy;
}

void QScene2D::setRenderPolicy(QScene2D::RenderPolicy renderPolicy)
{
    Q_D(const QScene2D);
    if (d->m_renderManager->m_renderPolicy != renderPolicy) {
        d->m_renderManager->m_renderPolicy = renderPolicy;
        emit renderPolicyChanged(renderPolicy);
    }
}

/*!
    \property QScene2D::output
    Holds the QRenderTargetOutput, which specifies where the QScene2D is
    rendering to.
 */
Qt3DRender::QRenderTargetOutput *QScene2D::output() const
{
    Q_D(const QScene2D);
    return d->m_output;
}

void QScene2D::setOutput(Qt3DRender::QRenderTargetOutput *output)
{
    Q_D(QScene2D);
    if (d->m_output != output) {
        if (d->m_output)
            d->unregisterDestructionHelper(d->m_output);
        d->m_output = output;
        if (output)
            d->registerDestructionHelper(output, &QScene2D::setOutput, d->m_output);
        emit outputChanged(output);
    }
}

Qt3DCore::QNodeCreatedChangeBasePtr QScene2D::createNodeCreationChange() const
{
    auto creationChange = Qt3DCore::QNodeCreatedChangePtr<QScene2DData>::create(this);
    auto &data = creationChange->data;
    Q_D(const QScene2D);
    data.renderPolicy = d->m_renderManager->m_renderPolicy;
    data.sharedObject = d->m_renderManager->m_sharedObject;
    data.output = d->m_output ? d->m_output->id() : Qt3DCore::QNodeId();
    for (Qt3DCore::QEntity *e : d->m_entities)
        data.entityIds.append(e->id());
    data.mouseEnabled = d->m_renderManager->m_mouseEnabled;
    return creationChange;
}

bool QScene2D::isMouseEnabled() const
{
    Q_D(const QScene2D);
    return d->m_renderManager->m_mouseEnabled;
}

/*!
    Retrieve entities associated with the QScene2D.
 */
QVector<Qt3DCore::QEntity*> QScene2D::entities()
{
    Q_D(const QScene2D);
    return d->m_entities;
}

/*!
    Adds an \a entity to the the QScene2D object. If the entities have QObjectPicker,
    the pick events from that entity are sent to QScene2D and converted to mouse events.
*/
void QScene2D::addEntity(Qt3DCore::QEntity *entity)
{
    Q_D(QScene2D);
    if (!d->m_entities.contains(entity)) {
        d->m_entities.append(entity);

        d->registerDestructionHelper(entity, &QScene2D::removeEntity, d->m_entities);
        d->updateNode(entity, "entities", PropertyValueAdded);
    }
}

/*!
    Removes an \a entity from the the QScene2D object.
*/
void QScene2D::removeEntity(Qt3DCore::QEntity *entity)
{
    Q_D(QScene2D);
    if (d->m_entities.contains(entity)) {
        d->m_entities.removeAll(entity);

        d->unregisterDestructionHelper(entity);
        d->updateNode(entity, "entities", PropertyValueRemoved);
    }
}

/*!
    \property QScene2D::mouseEnabled
    Holds whether mouse events are enabled for the rendered item. The mouse events are
    generated from object picking events of the entities added to the QScene2D.
    Mouse is enabled by default.

    \note Events are delayed by one frame due to object picking happening in the backend.
 */
void QScene2D::setMouseEnabled(bool enabled)
{
    Q_D(QScene2D);
    if (d->m_renderManager->m_mouseEnabled != enabled) {
        d->m_renderManager->m_mouseEnabled = enabled;
        emit mouseEnabledChanged(enabled);
    }
}


} // namespace Quick
} // namespace Qt3DRender

QT_END_NAMESPACE
