/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtWebEngine 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 "render_widget_host_view_qt_delegate_quick.h"

#include "qquickwebengineview_p.h"
#include "qquickwebengineview_p_p.h"
#include <QGuiApplication>
#include <QQuickPaintedItem>
#include <QQuickWindow>
#include <QSurfaceFormat>
#include <QVariant>
#include <QWindow>
#include <QtQuick/private/qquickwindow_p.h>

namespace QtWebEngineCore {

RenderWidgetHostViewQtDelegateQuick::RenderWidgetHostViewQtDelegateQuick(RenderWidgetHostViewQtDelegateClient *client, bool isPopup)
    : m_client(client)
    , m_isPopup(isPopup)
{
    setFlag(ItemHasContents);
    setAcceptedMouseButtons(Qt::AllButtons);
    setAcceptHoverEvents(true);
    if (isPopup)
        return;
    setFocus(true);
    setActiveFocusOnTab(true);

#if defined(Q_OS_MACOS) && QT_CONFIG(opengl)
    // Check that the default QSurfaceFormat OpenGL profile is compatible with the global OpenGL
    // shared context profile, otherwise this could lead to a nasty crash.
    QOpenGLContext *globalSharedContext = QOpenGLContext::globalShareContext();
    if (globalSharedContext) {
        QSurfaceFormat sharedFormat = globalSharedContext->format();
        QSurfaceFormat defaultFormat = QSurfaceFormat::defaultFormat();

        if (defaultFormat.profile() != sharedFormat.profile()
            && defaultFormat.profile() == QSurfaceFormat::CoreProfile
            && defaultFormat.version() >= qMakePair(3, 2)) {
            qFatal("QWebEngine: Default QSurfaceFormat OpenGL profile is not compatible with the "
                   "global shared context OpenGL profile. Please make sure you set a compatible "
                   "QSurfaceFormat before the QtGui application instance is created.");
        }
    }
#endif

}

RenderWidgetHostViewQtDelegateQuick::~RenderWidgetHostViewQtDelegateQuick()
{
    QQuickWebEngineViewPrivate::bindViewAndWidget(nullptr, this);
}

void RenderWidgetHostViewQtDelegateQuick::initAsPopup(const QRect &r)
{
    Q_ASSERT(m_isPopup && parentItem());
    QRectF rect(parentItem()->mapRectFromScene(r));
    setX(rect.x());
    setY(rect.y());
    setWidth(rect.width());
    setHeight(rect.height());
    setVisible(true);
}

QRectF RenderWidgetHostViewQtDelegateQuick::viewGeometry() const
{
    // Transform the entire rect to find the correct top left corner.
    const QPointF p1 = mapToGlobal(mapFromScene(QPointF(0, 0)));
    const QPointF p2 = mapToGlobal(mapFromScene(QPointF(width(), height())));
    QRectF geometry = QRectF(p1, p2).normalized();
    // But keep the size untransformed to behave like other QQuickItems.
#if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)
    geometry.setSize(size());
#else
    geometry.setSize(QSizeF(width(), height()));
#endif
    return geometry;
}

QRect RenderWidgetHostViewQtDelegateQuick::windowGeometry() const
{
    if (!window())
        return QRect();
    return window()->frameGeometry();
}

void RenderWidgetHostViewQtDelegateQuick::setKeyboardFocus()
{
    setFocus(true);
}

bool RenderWidgetHostViewQtDelegateQuick::hasKeyboardFocus()
{
    return hasActiveFocus();
}

void RenderWidgetHostViewQtDelegateQuick::lockMouse()
{
    grabMouse();
}

void RenderWidgetHostViewQtDelegateQuick::unlockMouse()
{
    ungrabMouse();
}

void RenderWidgetHostViewQtDelegateQuick::show()
{
    setVisible(true);
    m_client->notifyShown();
}

void RenderWidgetHostViewQtDelegateQuick::hide()
{
    setVisible(false);
    m_client->notifyHidden();
}

bool RenderWidgetHostViewQtDelegateQuick::isVisible() const
{
    return QQuickItem::isVisible();
}

QWindow* RenderWidgetHostViewQtDelegateQuick::window() const
{
    return QQuickItem::window();
}

QSGTexture *RenderWidgetHostViewQtDelegateQuick::createTextureFromImage(const QImage &image)
{
    return QQuickItem::window()->createTextureFromImage(image, QQuickWindow::TextureCanUseAtlas);
}

QSGLayer *RenderWidgetHostViewQtDelegateQuick::createLayer()
{
    QSGRenderContext *renderContext = QQuickWindowPrivate::get(QQuickItem::window())->context;
    return renderContext->sceneGraphContext()->createLayer(renderContext);
}

QSGImageNode *RenderWidgetHostViewQtDelegateQuick::createImageNode()
{
    return QQuickItem::window()->createImageNode();
}

QSGRectangleNode *RenderWidgetHostViewQtDelegateQuick::createRectangleNode()
{
    return QQuickItem::window()->createRectangleNode();
}

void RenderWidgetHostViewQtDelegateQuick::update()
{
    QQuickItem::update();
}

void RenderWidgetHostViewQtDelegateQuick::updateCursor(const QCursor &cursor)
{
    setCursor(cursor);
}

void RenderWidgetHostViewQtDelegateQuick::resize(int width, int height)
{
    setSize(QSizeF(width, height));
}

void RenderWidgetHostViewQtDelegateQuick::inputMethodStateChanged(bool editorVisible, bool passwordInput)
{
    setFlag(QQuickItem::ItemAcceptsInputMethod, editorVisible && !passwordInput);

    if (parentItem())
        parentItem()->setFlag(QQuickItem::ItemAcceptsInputMethod, editorVisible && !passwordInput);

    qApp->inputMethod()->update(Qt::ImQueryInput | Qt::ImEnabled | Qt::ImHints);
    if (qApp->inputMethod()->isVisible() != editorVisible)
        qApp->inputMethod()->setVisible(editorVisible);
}

bool RenderWidgetHostViewQtDelegateQuick::event(QEvent *event)
{
    if (event->type() == QEvent::ShortcutOverride)
        return m_client->forwardEvent(event);

#ifndef QT_NO_GESTURES
    if (event->type() == QEvent::NativeGesture)
        return m_client->forwardEvent(event);
#endif

    return QQuickItem::event(event);
}

void RenderWidgetHostViewQtDelegateQuick::focusInEvent(QFocusEvent *event)
{
#if QT_CONFIG(accessibility)
    if (QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(this)->focusChild()) {
        QAccessibleEvent focusEvent(iface, QAccessible::Focus);
        QAccessible::updateAccessibility(&focusEvent);
    }
#endif // QT_CONFIG(accessibility)

    m_client->forwardEvent(event);
}

void RenderWidgetHostViewQtDelegateQuick::focusOutEvent(QFocusEvent *event)
{
    m_client->forwardEvent(event);
}

void RenderWidgetHostViewQtDelegateQuick::mousePressEvent(QMouseEvent *event)
{
    QQuickItem *parent = parentItem();
    if (!m_isPopup && (parent && parent->property("activeFocusOnPress").toBool()))
        forceActiveFocus();
    if (!m_isPopup && parent && !parent->property("activeFocusOnPress").toBool() && !parent->hasActiveFocus()) {
        event->ignore();
        return;
    }
    m_client->forwardEvent(event);
}

void RenderWidgetHostViewQtDelegateQuick::mouseMoveEvent(QMouseEvent *event)
{
    QQuickItem *parent = parentItem();
    if (parent && !parent->property("activeFocusOnPress").toBool() && !parent->hasActiveFocus()) {
        event->ignore();
        return;
    }
    m_client->forwardEvent(event);
}

void RenderWidgetHostViewQtDelegateQuick::mouseReleaseEvent(QMouseEvent *event)
{
    QQuickItem *parent = parentItem();
    if (!m_isPopup && parent && !parent->property("activeFocusOnPress").toBool() && !parent->hasActiveFocus()) {
        event->ignore();
        return;
    }
    m_client->forwardEvent(event);
}

void RenderWidgetHostViewQtDelegateQuick::keyPressEvent(QKeyEvent *event)
{
    m_client->forwardEvent(event);
}

void RenderWidgetHostViewQtDelegateQuick::keyReleaseEvent(QKeyEvent *event)
{
    m_client->forwardEvent(event);
}

void RenderWidgetHostViewQtDelegateQuick::wheelEvent(QWheelEvent *event)
{
    m_client->forwardEvent(event);
}

void RenderWidgetHostViewQtDelegateQuick::touchEvent(QTouchEvent *event)
{
    QQuickItem *parent = parentItem();
    if (event->type() == QEvent::TouchBegin && !m_isPopup
            && (parent && parent->property("activeFocusOnPress").toBool()))
        forceActiveFocus();
    if (parent && !parent->property("activeFocusOnPress").toBool() && !parent->hasActiveFocus()) {
        event->ignore();
        return;
    }
    m_client->forwardEvent(event);
}

void RenderWidgetHostViewQtDelegateQuick::hoverMoveEvent(QHoverEvent *event)
{
    QQuickItem *parent = parentItem();
    if ((!m_isPopup && parent && !parent->property("activeFocusOnPress").toBool()
         && !parent->hasActiveFocus()) || event->posF() == event->oldPosF()) {
        event->ignore();
        return;
    }
    m_client->forwardEvent(event);
}

void RenderWidgetHostViewQtDelegateQuick::hoverLeaveEvent(QHoverEvent *event)
{
    m_client->forwardEvent(event);
}

QVariant RenderWidgetHostViewQtDelegateQuick::inputMethodQuery(Qt::InputMethodQuery query) const
{
    return m_client->inputMethodQuery(query);
}

void RenderWidgetHostViewQtDelegateQuick::inputMethodEvent(QInputMethodEvent *event)
{
    m_client->forwardEvent(event);
}

void RenderWidgetHostViewQtDelegateQuick::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
{
    QQuickItem::geometryChanged(newGeometry, oldGeometry);
    m_client->visualPropertiesChanged();
}

void RenderWidgetHostViewQtDelegateQuick::itemChange(ItemChange change, const ItemChangeData &value)
{
    QQuickItem::itemChange(change, value);
    if (change == QQuickItem::ItemSceneChange) {
        for (const QMetaObject::Connection &c : qAsConst(m_windowConnections))
            disconnect(c);
        m_windowConnections.clear();
        if (value.window) {
            m_windowConnections.append(connect(value.window, SIGNAL(xChanged(int)), SLOT(onWindowPosChanged())));
            m_windowConnections.append(connect(value.window, SIGNAL(yChanged(int)), SLOT(onWindowPosChanged())));
            if (!m_isPopup)
                m_windowConnections.append(connect(value.window, SIGNAL(closing(QQuickCloseEvent *)), SLOT(onHide())));
        }
        m_client->visualPropertiesChanged();
    } else if (change == QQuickItem::ItemVisibleHasChanged) {
        if (!m_isPopup && !value.boolValue)
            onHide();
    }
}

QSGNode *RenderWidgetHostViewQtDelegateQuick::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
{
    return m_client->updatePaintNode(oldNode);
}

void RenderWidgetHostViewQtDelegateQuick::onWindowPosChanged()
{
    m_client->visualPropertiesChanged();
}

void RenderWidgetHostViewQtDelegateQuick::onHide()
{
    QFocusEvent event(QEvent::FocusOut, Qt::OtherFocusReason);
    m_client->forwardEvent(&event);
}

bool RenderWidgetHostViewQtDelegateQuick::copySurface(const QRect &rect, const QSize &size, QImage &image)
{
    image = QQuickItem::window()->grabWindow();
    if (image.isNull())
        return false;
    QRect subrect = !rect.isEmpty() ? rect : image.rect();
    image = image.copy(subrect);
    image = image.scaled(size, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
    return true;
}

#if QT_CONFIG(accessibility)
RenderWidgetHostViewQtDelegateQuickAccessible::RenderWidgetHostViewQtDelegateQuickAccessible(RenderWidgetHostViewQtDelegateQuick *o, QQuickWebEngineView *view)
    : QAccessibleObject(o)
    , m_view(view)
{
}

bool RenderWidgetHostViewQtDelegateQuickAccessible::isValid() const
{
    if (!viewAccessible() || !viewAccessible()->isValid())
        return false;

    return QAccessibleObject::isValid();
}

QAccessibleInterface *RenderWidgetHostViewQtDelegateQuickAccessible::parent() const
{
    return viewAccessible()->parent();
}

QString RenderWidgetHostViewQtDelegateQuickAccessible::text(QAccessible::Text) const
{
    return QString();
}

QAccessible::Role RenderWidgetHostViewQtDelegateQuickAccessible::role() const
{
    return QAccessible::Client;
}

QAccessible::State RenderWidgetHostViewQtDelegateQuickAccessible::state() const
{
    return viewAccessible()->state();
}

QAccessibleInterface *RenderWidgetHostViewQtDelegateQuickAccessible::focusChild() const
{
    return viewAccessible()->focusChild();
}

int RenderWidgetHostViewQtDelegateQuickAccessible::childCount() const
{
    return viewAccessible()->childCount();
}

QAccessibleInterface *RenderWidgetHostViewQtDelegateQuickAccessible::child(int index) const
{
    return viewAccessible()->child(index);
}

int RenderWidgetHostViewQtDelegateQuickAccessible::indexOfChild(const QAccessibleInterface *c) const
{
    return viewAccessible()->indexOfChild(c);
}

QQuickWebEngineViewAccessible *RenderWidgetHostViewQtDelegateQuickAccessible::viewAccessible() const
{
    return static_cast<QQuickWebEngineViewAccessible *>(QAccessible::queryAccessibleInterface(m_view));
}
#endif // QT_CONFIG(accessibility)

} // namespace QtWebEngineCore
