/*
 * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public License
 * along with this library; see the file COPYING.LIB.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 *
 */

#include "config.h"

#include "PageClientQt.h"
#include "TextureMapperQt.h"
#include "texmap/TextureMapperPlatformLayer.h"
#include <QGraphicsScene>
#include <QGraphicsView>
#if defined(Q_WS_X11)
#include <QX11Info>
#endif

#ifdef QT_OPENGL_LIB
#include "opengl/TextureMapperGL.h"
#include <QGLWidget>
#endif

namespace WebCore {

#if USE(ACCELERATED_COMPOSITING) && USE(TEXTURE_MAPPER)    
class PlatformLayerProxyQt : public QObject, public virtual TextureMapperLayerClient {
public:
    PlatformLayerProxyQt(QWebFrame* frame, TextureMapperContentLayer* layer, QObject* object)
        : QObject(object)
        , m_frame(frame)
        , m_layer(layer)
    {
        if (m_layer)
            m_layer->setPlatformLayerClient(this);
        m_frame->d->rootGraphicsLayer = m_layer;
    }

    void setTextureMapper(PassOwnPtr<TextureMapper> textureMapper)
    {
        m_frame->d->textureMapper = textureMapper;
    }

    virtual ~PlatformLayerProxyQt()
    {
        if (m_layer)
            m_layer->setPlatformLayerClient(0);
        if (m_frame->d)
            m_frame->d->rootGraphicsLayer = 0;
    }

    virtual TextureMapper* textureMapper()
    {
        return m_frame->d->textureMapper.get();
    }

    // Since we just paint the composited tree and never create a special item for it, we don't have to handle its size changes.
    void setSizeChanged(const IntSize&) { }

private:
    QWebFrame* m_frame;
    TextureMapperContentLayer* m_layer;
};

class PlatformLayerProxyQWidget : public PlatformLayerProxyQt {
public:
    PlatformLayerProxyQWidget(QWebFrame* frame, TextureMapperContentLayer* layer, QWidget* widget)
        : PlatformLayerProxyQt(frame, layer, widget)
        , m_widget(widget)
    {
        if (m_widget)
            m_widget->installEventFilter(this);

        if (textureMapper())
            return;

        setTextureMapper(TextureMapperQt::create());
    }

    // We don't want a huge region-clip on the compositing layers; instead we unite the rectangles together
    // and clear them when the paint actually occurs.
    bool eventFilter(QObject* object, QEvent* event)
    {
        if (object == m_widget && event->type() == QEvent::Paint)
            m_dirtyRect = QRect();
        return QObject::eventFilter(object, event);
    }

    void setNeedsDisplay()
    {
        if (m_widget)
            m_widget->update();
    }

    void setNeedsDisplayInRect(const IntRect& rect)
    {
        m_dirtyRect |= rect;
        m_widget->update(m_dirtyRect);
    }

private:
    QRect m_dirtyRect;
    QWidget* m_widget;
};

#if !defined(QT_NO_GRAPHICSVIEW)
class PlatformLayerProxyQGraphicsObject : public PlatformLayerProxyQt {
public:
    PlatformLayerProxyQGraphicsObject(QWebFrame* frame, TextureMapperContentLayer* layer, QGraphicsObject* object)
        : PlatformLayerProxyQt(frame, layer, object)
        , m_graphicsItem(object)
    {
        if (textureMapper())
            return;

#ifdef QT_OPENGL_LIB
        QGraphicsView* view = object->scene()->views()[0];
        if (view && view->viewport() && view->viewport()->inherits("QGLWidget")) {
            setTextureMapper(TextureMapperGL::create());
            return;
        }
#endif
        setTextureMapper(TextureMapperQt::create());
    }

    void setNeedsDisplay()
    {
        if (m_graphicsItem)
            m_graphicsItem->update();
    }

    void setNeedsDisplayInRect(const IntRect& rect)
    {
        if (m_graphicsItem)
            m_graphicsItem->update(QRectF(rect));
    }

private:
    QGraphicsItem* m_graphicsItem;
};
#endif // QT_NO_GRAPHICSVIEW

void PageClientQWidget::setRootGraphicsLayer(TextureMapperPlatformLayer* layer)
{
    if (layer) {
        platformLayerProxy = new PlatformLayerProxyQWidget(page->mainFrame(), static_cast<TextureMapperContentLayer*>(layer), view);
        return;
    }
    delete platformLayerProxy;
    platformLayerProxy = 0;
}

void PageClientQWidget::markForSync(bool scheduleSync)
{
    syncTimer.startOneShot(0);
}

void PageClientQWidget::syncLayers(Timer<PageClientQWidget>*)
{
    QWebFramePrivate::core(page->mainFrame())->view()->syncCompositingStateIncludingSubframes();
}
#endif

void PageClientQWidget::scroll(int dx, int dy, const QRect& rectToScroll)
{
    view->scroll(qreal(dx), qreal(dy), rectToScroll);
}

void PageClientQWidget::update(const QRect & dirtyRect)
{
    view->update(dirtyRect);
}

void PageClientQWidget::setInputMethodEnabled(bool enable)
{
    view->setAttribute(Qt::WA_InputMethodEnabled, enable);
}

bool PageClientQWidget::inputMethodEnabled() const
{
    return view->testAttribute(Qt::WA_InputMethodEnabled);
}

void PageClientQWidget::setInputMethodHints(Qt::InputMethodHints hints)
{
    view->setInputMethodHints(hints);
}

PageClientQWidget::~PageClientQWidget()
{
#if USE(ACCELERATED_COMPOSITING) && USE(TEXTURE_MAPPER)
    delete platformLayerProxy;
#endif
}

#ifndef QT_NO_CURSOR
QCursor PageClientQWidget::cursor() const
{
    return view->cursor();
}

void PageClientQWidget::updateCursor(const QCursor& cursor)
{
    view->setCursor(cursor);
}
#endif

QPalette PageClientQWidget::palette() const
{
    return view->palette();
}

int PageClientQWidget::screenNumber() const
{
#if defined(Q_WS_X11)
    return view->x11Info().screen();
#endif
    return 0;
}

QWidget* PageClientQWidget::ownerWidget() const
{
    return view;
}

QRect PageClientQWidget::geometryRelativeToOwnerWidget() const
{
    return view->geometry();
}

QObject* PageClientQWidget::pluginParent() const
{
    return view;
}

QStyle* PageClientQWidget::style() const
{
    return view->style();
}

QRectF PageClientQWidget::windowRect() const
{
    return QRectF(view->window()->geometry());
}

#if !defined(QT_NO_GRAPHICSVIEW)
PageClientQGraphicsWidget::~PageClientQGraphicsWidget()
{
    delete overlay;
#if USE(ACCELERATED_COMPOSITING)
#if USE(TEXTURE_MAPPER)
    delete platformLayerProxy;
#else
    if (!rootGraphicsLayer)
        return;
    // we don't need to delete the root graphics layer. The lifecycle is managed in GraphicsLayerQt.cpp.
    rootGraphicsLayer.data()->setParentItem(0);
    view->scene()->removeItem(rootGraphicsLayer.data());
#endif
#endif
}

void PageClientQGraphicsWidget::scroll(int dx, int dy, const QRect& rectToScroll)
{
    view->scroll(qreal(dx), qreal(dy), rectToScroll);
}

void PageClientQGraphicsWidget::update(const QRect& dirtyRect)
{
    view->update(dirtyRect);

    createOrDeleteOverlay();
    if (overlay)
        overlay->update(QRectF(dirtyRect));
#if USE(ACCELERATED_COMPOSITING)
    syncLayers();
#endif
}

void PageClientQGraphicsWidget::createOrDeleteOverlay()
{
    // We don't use an overlay with TextureMapper. Instead, the overlay is drawn inside QWebFrame.
#if !USE(TEXTURE_MAPPER)
    bool useOverlay = false;
    if (!viewResizesToContents) {
#if USE(ACCELERATED_COMPOSITING)
        useOverlay = useOverlay || rootGraphicsLayer;
#endif
#if ENABLE(TILED_BACKING_STORE)
        useOverlay = useOverlay || QWebFramePrivate::core(page->mainFrame())->tiledBackingStore();
#endif
    }
    if (useOverlay == !!overlay)
        return;

    if (useOverlay) {
        overlay = new QGraphicsItemOverlay(view, page);
        overlay->setZValue(OverlayZValue);
    } else {
        // Changing the overlay might be done inside paint events.
        overlay->deleteLater();
        overlay = 0;
    }
#endif // !USE(TEXTURE_MAPPER)
}

#if USE(ACCELERATED_COMPOSITING)
void PageClientQGraphicsWidget::syncLayers()
{
    if (shouldSync) {
        QWebFramePrivate::core(page->mainFrame())->view()->syncCompositingStateIncludingSubframes();
        shouldSync = false;
    }
}

#if USE(TEXTURE_MAPPER)
void PageClientQGraphicsWidget::setRootGraphicsLayer(TextureMapperPlatformLayer* layer)
{
    if (layer) {
        platformLayerProxy = new PlatformLayerProxyQGraphicsObject(page->mainFrame(), static_cast<TextureMapperContentLayer*>(layer), view);
        return;
    }
    delete platformLayerProxy;
    platformLayerProxy = 0;
}
#else
void PageClientQGraphicsWidget::setRootGraphicsLayer(QGraphicsObject* layer)
{
    if (rootGraphicsLayer) {
        rootGraphicsLayer.data()->setParentItem(0);
        view->scene()->removeItem(rootGraphicsLayer.data());
        QWebFramePrivate::core(page->mainFrame())->view()->syncCompositingStateIncludingSubframes();
    }

    rootGraphicsLayer = layer;

    if (layer) {
        layer->setFlag(QGraphicsItem::ItemClipsChildrenToShape, true);
        layer->setParentItem(view);
        layer->setZValue(RootGraphicsLayerZValue);
    }
    createOrDeleteOverlay();
}
#endif

void PageClientQGraphicsWidget::markForSync(bool scheduleSync)
{
    shouldSync = true;
    if (scheduleSync)
        syncMetaMethod.invoke(view, Qt::QueuedConnection);
}

#endif

#if ENABLE(TILED_BACKING_STORE)
void PageClientQGraphicsWidget::updateTiledBackingStoreScale()
{
    WebCore::TiledBackingStore* backingStore = QWebFramePrivate::core(page->mainFrame())->tiledBackingStore();
    if (!backingStore)
        return;
    backingStore->setContentsScale(view->scale());
}
#endif

void PageClientQGraphicsWidget::setInputMethodEnabled(bool enable)
{
    view->setFlag(QGraphicsItem::ItemAcceptsInputMethod, enable);
}

bool PageClientQGraphicsWidget::inputMethodEnabled() const
{
    return view->flags() & QGraphicsItem::ItemAcceptsInputMethod;
}

void PageClientQGraphicsWidget::setInputMethodHints(Qt::InputMethodHints hints)
{
    view->setInputMethodHints(hints);
}

#ifndef QT_NO_CURSOR
QCursor PageClientQGraphicsWidget::cursor() const
{
    return view->cursor();
}

void PageClientQGraphicsWidget::updateCursor(const QCursor& cursor)
{
    view->setCursor(cursor);
}
#endif

QPalette PageClientQGraphicsWidget::palette() const
{
    return view->palette();
}

int PageClientQGraphicsWidget::screenNumber() const
{
#if defined(Q_WS_X11)
    if (QGraphicsScene* scene = view->scene()) {
        const QList<QGraphicsView*> views = scene->views();

        if (!views.isEmpty())
            return views.at(0)->x11Info().screen();
    }
#endif

    return 0;
}

QWidget* PageClientQGraphicsWidget::ownerWidget() const
{
    if (QGraphicsScene* scene = view->scene()) {
        const QList<QGraphicsView*> views = scene->views();
        return views.value(0);
    }
    return 0;
}

QRect PageClientQGraphicsWidget::geometryRelativeToOwnerWidget() const
{
    if (!view->scene())
        return QRect();

    QList<QGraphicsView*> views = view->scene()->views();
    if (views.isEmpty())
        return QRect();

    QGraphicsView* graphicsView = views.at(0);
    return graphicsView->mapFromScene(view->boundingRect()).boundingRect();
}

#if ENABLE(TILED_BACKING_STORE)
QRectF PageClientQGraphicsWidget::graphicsItemVisibleRect() const
{
    if (!view->scene())
        return QRectF();

    QList<QGraphicsView*> views = view->scene()->views();
    if (views.isEmpty())
        return QRectF();

    QGraphicsView* graphicsView = views.at(0);
    int xOffset = graphicsView->horizontalScrollBar()->value();
    int yOffset = graphicsView->verticalScrollBar()->value();
    return view->mapRectFromScene(QRectF(QPointF(xOffset, yOffset), graphicsView->viewport()->size()));
}
#endif

QObject* PageClientQGraphicsWidget::pluginParent() const
{
    return view;
}

QStyle* PageClientQGraphicsWidget::style() const
{
    return view->style();
}

QRectF PageClientQGraphicsWidget::windowRect() const
{
    if (!view->scene())
        return QRectF();

    // The sceneRect is a good approximation of the size of the application, independent of the view.
    return view->scene()->sceneRect();
}
#endif // QT_NO_GRAPHICSVIEW

} // namespace WebCore
