/*
    Copyright (C) 2009 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 "GraphicsLayerQt.h"

#include "CurrentTime.h"
#include "FloatRect.h"
#include "GraphicsContext.h"
#include "Image.h"
#include "RefCounted.h"
#include "TranslateTransformOperation.h"
#include "UnitBezier.h"
#include <QtCore/qabstractanimation.h>
#include <QtCore/qdebug.h>
#include <QtCore/qmetaobject.h>
#include <QtCore/qset.h>
#include <QtCore/qtimer.h>
#include <QtGui/qcolor.h>
#include <QtGui/qgraphicseffect.h>
#include <QtGui/qgraphicsitem.h>
#include <QtGui/qgraphicsscene.h>
#include <QtGui/qpainter.h>
#include <QtGui/qpixmap.h>
#include <QtGui/qpixmapcache.h>
#include <QtGui/qstyleoption.h>


#define QT_DEBUG_RECACHE 0
#define QT_DEBUG_CACHEDUMP 0

namespace WebCore {

#ifndef QT_NO_GRAPHICSEFFECT
class MaskEffectQt : public QGraphicsEffect {
public:
    MaskEffectQt(QObject* parent, QGraphicsItem* maskLayer)
            : QGraphicsEffect(parent)
            , m_maskLayer(maskLayer)
    {
    }

    void draw(QPainter* painter)
    {
        // this is a modified clone of QGraphicsOpacityEffect.
        // It's more efficient to do it this way because
        // (a) we don't need the QBrush abstraction - we always end up using QGraphicsItem::paint from the mask layer
        // (b) QGraphicsOpacityEffect detaches the pixmap, which is inefficient on OpenGL.
        const QSize maskSize = sourceBoundingRect().toAlignedRect().size();
        if (!maskSize.isValid() || maskSize.isEmpty()) {
            drawSource(painter);
            return;
        }
        QPixmap maskPixmap(maskSize);

        // we need to do this so the pixmap would have hasAlpha()
        maskPixmap.fill(Qt::transparent);
        QPainter maskPainter(&maskPixmap);
        QStyleOptionGraphicsItem option;
        option.exposedRect = option.rect = maskPixmap.rect();
        maskPainter.setRenderHints(painter->renderHints(), true);
        m_maskLayer->paint(&maskPainter, &option, 0);
        maskPainter.end();
        QPoint offset;
        QPixmap srcPixmap = sourcePixmap(Qt::LogicalCoordinates, &offset, QGraphicsEffect::NoPad);

        // we have to use another intermediate pixmap, to make sure the mask applies only to this item
        // and doesn't modify pixels already painted into this paint-device
        QPixmap pixmap(srcPixmap.size());
        pixmap.fill(Qt::transparent);

        if (pixmap.isNull())
            return;

        QPainter pixmapPainter(&pixmap);
        pixmapPainter.setRenderHints(painter->renderHints());
        pixmapPainter.setCompositionMode(QPainter::CompositionMode_Source);
        // We use drawPixmap rather than detaching, because it's more efficient on OpenGL
        pixmapPainter.drawPixmap(0, 0, srcPixmap);
        pixmapPainter.setCompositionMode(QPainter::CompositionMode_DestinationIn);
        pixmapPainter.drawPixmap(0, 0, maskPixmap);
        pixmapPainter.end();
        painter->drawPixmap(offset, pixmap);
    }

    QGraphicsItem* m_maskLayer;
};
#endif // QT_NO_GRAPHICSEFFECT

class GraphicsLayerQtImpl : public QGraphicsObject {
    Q_OBJECT

public:
    // this set of flags help us defer which properties of the layer have been
    // modified by the compositor, so we can know what to look for in the next flush
    enum ChangeMask {
        NoChanges =                 0,

        ParentChange =              (1L << 0),
        ChildrenChange =            (1L << 1),
        MaskLayerChange =           (1L << 2),
        PositionChange =            (1L << 3),

        AnchorPointChange =         (1L << 4),
        SizeChange  =               (1L << 5),
        TransformChange =           (1L << 6),
        ContentChange =             (1L << 7),

        GeometryOrientationChange = (1L << 8),
        ContentsOrientationChange = (1L << 9),
        OpacityChange =             (1L << 10),
        ContentsRectChange =        (1L << 11),

        Preserves3DChange =         (1L << 12),
        MasksToBoundsChange =       (1L << 13),
        DrawsContentChange =        (1L << 14),
        ContentsOpaqueChange =      (1L << 15),

        BackfaceVisibilityChange =  (1L << 16),
        ChildrenTransformChange =   (1L << 17),
        DisplayChange =             (1L << 18),
        BackgroundColorChange =     (1L << 19),

        DistributesOpacityChange =  (1L << 20)
    };

    // the compositor lets us special-case images and colors, so we try to do so
    enum StaticContentType { HTMLContentType, PixmapContentType, ColorContentType, MediaContentType};

    const GraphicsLayerQtImpl* rootLayer() const;

    GraphicsLayerQtImpl(GraphicsLayerQt* newLayer);
    virtual ~GraphicsLayerQtImpl();

    // reimps from QGraphicsItem
    virtual QPainterPath opaqueArea() const;
    virtual QRectF boundingRect() const;
    virtual void paint(QPainter*, const QStyleOptionGraphicsItem*, QWidget*);

    // We manage transforms ourselves because transform-origin acts differently in webkit and in Qt, and we need it as a fallback in case we encounter an un-invertible matrix
    void setBaseTransform(const TransformationMatrix&);
    void updateTransform();

    // let the compositor-API tell us which properties were changed
    void notifyChange(ChangeMask);

    // actual rendering of the web-content into a QPixmap
    // We prefer to use our own caching because it gives us a higher level of granularity than QGraphicsItem cache modes -
    // sometimes we need to cache the contents even `though the item needs to be updated, e.g. when the background-color is changed.
    // TODO: investigate if QGraphicsItem caching can be improved to support that out of the box.
    QPixmap recache(const QRegion&);

    // called when the compositor is ready for us to show the changes on screen
    // this is called indirectly from ChromeClientQt::setNeedsOneShotDrawingSynchronization
    // (meaning the sync would happen together with the next draw)
    // or ChromeClientQt::scheduleCompositingLayerSync (meaning the sync will happen ASAP)
    void flushChanges(bool recursive = true, bool forceTransformUpdate = false);

public slots:
    // we need to notify the client (aka the layer compositor) when the animation actually starts
    void notifyAnimationStarted();

    // we notify WebCore of a layer changed asynchronously; otherwise we end up calling flushChanges too often.
    void notifySyncRequired();

signals:
    // optimization: we don't want to use QTimer::singleShot
    void notifyAnimationStartedAsync();

public:
    GraphicsLayerQt* m_layer;

    TransformationMatrix m_baseTransform;
    TransformationMatrix m_transformRelativeToRootLayer;
    bool m_transformAnimationRunning;
    bool m_opacityAnimationRunning;
#ifndef QT_NO_GRAPHICSEFFECT
    QWeakPointer<MaskEffectQt> m_maskEffect;
#endif

    struct ContentData {
        QPixmap pixmap;
        QRegion regionToUpdate;
        bool updateAll;
        QColor contentsBackgroundColor;
        QColor backgroundColor;
        QWeakPointer<QGraphicsObject> mediaLayer;
        StaticContentType contentType;
        float opacity;
        ContentData()
                : updateAll(false)
                , contentType(HTMLContentType)
                , opacity(1.f)
        {
        }

    };

    ContentData m_pendingContent;
    ContentData m_currentContent;

    int m_changeMask;

    QSizeF m_size;
    struct {
        QPixmapCache::Key key;
        QSizeF size;
    } m_backingStore;
#ifndef QT_NO_ANIMATION
    QList<QWeakPointer<QAbstractAnimation> > m_animations;
#endif
    QTimer m_suspendTimer;

    struct State {
        GraphicsLayer* maskLayer;
        FloatPoint pos;
        FloatPoint3D anchorPoint;
        FloatSize size;
        TransformationMatrix transform;
        TransformationMatrix childrenTransform;
        Color backgroundColor;
        Color currentColor;
        GraphicsLayer::CompositingCoordinatesOrientation geoOrientation;
        GraphicsLayer::CompositingCoordinatesOrientation contentsOrientation;
        float opacity;
        QRect contentsRect;

        bool preserves3D: 1;
        bool masksToBounds: 1;
        bool drawsContent: 1;
        bool contentsOpaque: 1;
        bool backfaceVisibility: 1;
        bool distributeOpacity: 1;
        bool align: 2;
        State(): maskLayer(0), opacity(1.f), preserves3D(false), masksToBounds(false),
                  drawsContent(false), contentsOpaque(false), backfaceVisibility(false),
                  distributeOpacity(false)
        {
        }
    } m_state;

#ifndef QT_NO_ANIMATION
    friend class AnimationQtBase;
#endif
};

GraphicsLayerQtImpl::GraphicsLayerQtImpl(GraphicsLayerQt* newLayer)
    : QGraphicsObject(0)
    , m_layer(newLayer)
    , m_transformAnimationRunning(false)
    , m_opacityAnimationRunning(false)
    , m_changeMask(NoChanges)
{
    // we use graphics-view for compositing, not for interactivity
    setAcceptedMouseButtons(Qt::NoButton);
    // we need to have the item enabled, or else wheel events are not
    // passed to the parent class implementation of wheelEvent, where
    // they are ignored and passed to the item below.
    setEnabled(true);

    connect(this, SIGNAL(notifyAnimationStartedAsync()), this, SLOT(notifyAnimationStarted()), Qt::QueuedConnection);
}

GraphicsLayerQtImpl::~GraphicsLayerQtImpl()
{
    // the compositor manages item lifecycle - we don't want the graphics-view
    // system to automatically delete our items

    const QList<QGraphicsItem*> children = childItems();
    for (QList<QGraphicsItem*>::const_iterator it = children.begin(); it != children.end(); ++it) {
        if (QGraphicsItem* item = *it) {
            if (scene())
                scene()->removeItem(item);
            item->setParentItem(0);
        }
    }

#ifndef QT_NO_ANIMATION
    // we do, however, own the animations...
    for (QList<QWeakPointer<QAbstractAnimation> >::iterator it = m_animations.begin(); it != m_animations.end(); ++it)
        if (QAbstractAnimation* anim = it->data())
            delete anim;
#endif
}

const GraphicsLayerQtImpl* GraphicsLayerQtImpl::rootLayer() const
{
    if (const GraphicsLayerQtImpl* parent = qobject_cast<const GraphicsLayerQtImpl*>(parentObject()))
        return parent->rootLayer();
    return this;
}



QPixmap GraphicsLayerQtImpl::recache(const QRegion& regionToUpdate)
{
    if (!m_layer->drawsContent() || m_size.isEmpty() || !m_size.isValid())
        return QPixmap();

    QPixmap pixmap;
    QRegion region = regionToUpdate;
    if (QPixmapCache::find(m_backingStore.key, &pixmap)) {
        if (region.isEmpty())
            return pixmap;
        QPixmapCache::remove(m_backingStore.key); // Remove the reference to the pixmap in the cache to avoid a detach.
    }

    {
        bool erased = false;

        // If the pixmap is not in the cache or the view has grown since last cached.
        if (pixmap.isNull() || m_size != m_backingStore.size) {
#if QT_DEBUG_RECACHE
            if (pixmap.isNull())
                qDebug() << "CacheMiss" << this << m_size;
#endif
            bool fill = true;
            QRegion newRegion;
            QPixmap oldPixmap = pixmap;

            // If the pixmap is two small to hold the view contents we enlarge, otherwise just use the old (large) pixmap.
            if (pixmap.width() < m_size.width() || pixmap.height() < m_size.height()) {
#if QT_DEBUG_RECACHE
                qDebug() << "CacheGrow" << this << m_size;
#endif
                pixmap = QPixmap(m_size.toSize());
                pixmap.fill(Qt::transparent);
                newRegion = QRegion(0, 0, m_size.width(), m_size.height());
            }

#if 1
            // Blit the contents of oldPixmap back into the cached pixmap as we are just adding new pixels.
            if (!oldPixmap.isNull()) {
                const QRegion cleanRegion = (QRegion(0, 0, m_size.width(), m_size.height())
                                             & QRegion(0, 0, m_backingStore.size.width(), m_backingStore.size.height())) - regionToUpdate;
                if (!cleanRegion.isEmpty()) {
#if QT_DEBUG_RECACHE
                    qDebug() << "CacheBlit" << this << cleanRegion;
#endif
                    const QRect cleanBounds(cleanRegion.boundingRect());
                    QPainter painter(&pixmap);
                    painter.setCompositionMode(QPainter::CompositionMode_Source);
                    painter.drawPixmap(cleanBounds.topLeft(), oldPixmap, cleanBounds);
                    newRegion -= cleanRegion;
                    fill = false; // We cannot just fill the pixmap.
                }
                oldPixmap = QPixmap();
            }
#endif
            region += newRegion;
            if (fill && !region.isEmpty()) { // Clear the entire pixmap with the background.
#if QT_DEBUG_RECACHE
                qDebug() << "CacheErase" << this << m_size << background;
#endif
                erased = true;
                pixmap.fill(Qt::transparent);
            }
        }
        region &= QRegion(0, 0, m_size.width(), m_size.height());

        // If we have something to draw its time to erase it and render the contents.
        if (!region.isEmpty()) {
#if QT_DEBUG_CACHEDUMP
            static int recacheCount = 0;
            ++recacheCount;
            qDebug() << "**** CACHEDUMP" << recacheCount << this << m_layer << region << m_size;
            pixmap.save(QString().sprintf("/tmp/%05d_A.png", recacheCount), "PNG");
#endif

            QPainter painter(&pixmap);
            GraphicsContext gc(&painter);

            painter.setClipRegion(region);

            if (!erased) { // Erase the area in cache that we're drawing into.
                painter.setCompositionMode(QPainter::CompositionMode_Clear);
                painter.fillRect(region.boundingRect(), Qt::transparent);

#if QT_DEBUG_CACHEDUMP
                qDebug() << "**** CACHEDUMP" << recacheCount << this << m_layer << region << m_size;
                pixmap.save(QString().sprintf("/tmp/%05d_B.png", recacheCount), "PNG");
#endif
            }

            // Render the actual contents into the cache.
            painter.setCompositionMode(QPainter::CompositionMode_SourceOver);
            m_layer->paintGraphicsLayerContents(gc, region.boundingRect());
            painter.end();

#if QT_DEBUG_CACHEDUMP
            qDebug() << "**** CACHEDUMP" << recacheCount << this << m_layer << region << m_size;
            pixmap.save(QString().sprintf("/tmp/%05d_C.png", recacheCount), "PNG");
#endif
        }
        m_backingStore.size = m_size; // Store the used size of the pixmap.
    }

    // Finally insert into the cache and allow a reference there.
    m_backingStore.key = QPixmapCache::insert(pixmap);
    return pixmap;
}

void GraphicsLayerQtImpl::updateTransform()
{
    if (!m_transformAnimationRunning)
        m_baseTransform = m_layer->transform();

    TransformationMatrix localTransform;

    GraphicsLayerQtImpl* parent = qobject_cast<GraphicsLayerQtImpl*>(parentObject());

    // webkit has relative-to-size originPoint, graphics-view has a pixel originPoint, here we convert
    // we have to manage this ourselves because QGraphicsView's transformOrigin is incompatible
    const qreal originX = m_state.anchorPoint.x() * m_size.width();
    const qreal originY = m_state.anchorPoint.y() * m_size.height();

    // We ignore QGraphicsItem::pos completely, and use only transforms - because we have to maintain that ourselves for 3D.
    localTransform
            .translate3d(originX + m_state.pos.x(), originY + m_state.pos.y(), m_state.anchorPoint.z())
            .multLeft(m_baseTransform)
            .translate3d(-originX, -originY, -m_state.anchorPoint.z());

    // This is the actual 3D transform of this item, with the ancestors' transform baked in.
    m_transformRelativeToRootLayer = TransformationMatrix(parent ? parent->m_transformRelativeToRootLayer : TransformationMatrix())
                                         .multLeft(localTransform);

    // Now we have enough information to determine if the layer is facing backwards.
    if (!m_state.backfaceVisibility && m_transformRelativeToRootLayer.inverse().m33() < 0) {
        setVisible(false);
        // No point in making extra calculations for invisible elements.
        return;
    }

    // The item is front-facing or backface-visibility is on.
    setVisible(true);

    // Flatten to 2D-space of this item if it doesn't preserve 3D.
    if (!m_state.preserves3D) {
        m_transformRelativeToRootLayer.setM13(0);
        m_transformRelativeToRootLayer.setM23(0);
        m_transformRelativeToRootLayer.setM31(0);
        m_transformRelativeToRootLayer.setM32(0);
        m_transformRelativeToRootLayer.setM33(1);
        m_transformRelativeToRootLayer.setM34(0);
        m_transformRelativeToRootLayer.setM43(0);
    }

    // Apply perspective for the use of this item's children. Perspective is always applied from the item's center.
    if (!m_state.childrenTransform.isIdentity())
        m_transformRelativeToRootLayer
            .translate(m_size.width() / 2, m_size.height() /2)
            .multLeft(m_state.childrenTransform)
            .translate(-m_size.width() / 2, -m_size.height() /2);

    bool inverseOk = true;
    // Use QTransform::inverse to extrapolate the relative transform of this item, based on the parent's transform relative to
    // the root layer and the desired transform for this item relative to the root layer.
    const QTransform parentTransform = parent ? parent->itemTransform(rootLayer()) : QTransform();
    const QTransform transform2D = QTransform(m_transformRelativeToRootLayer) * parentTransform.inverted(&inverseOk);

    // In rare cases the transformation cannot be inversed - in that case we don't apply the transformation at all, otherwise we'd flicker.
    // FIXME: This should be amended when Qt moves to a real 3D scene-graph.
    if (!inverseOk)
        return;

    setTransform(transform2D);

    const QList<QGraphicsItem*> children = childItems();
    for (QList<QGraphicsItem*>::const_iterator it = children.begin(); it != children.end(); ++it)
        if (GraphicsLayerQtImpl* layer= qobject_cast<GraphicsLayerQtImpl*>((*it)->toGraphicsObject()))
            layer->updateTransform();
}

void GraphicsLayerQtImpl::setBaseTransform(const TransformationMatrix& baseTransform)
{
    m_baseTransform = baseTransform;
    updateTransform();
}

QPainterPath GraphicsLayerQtImpl::opaqueArea() const
{
    QPainterPath painterPath;

    // we try out best to return the opaque area, maybe it will help graphics-view render less items
    if (m_currentContent.backgroundColor.isValid() && m_currentContent.backgroundColor.alpha() == 0xff)
        painterPath.addRect(boundingRect());
    else {
        if (m_state.contentsOpaque
            || (m_currentContent.contentType == ColorContentType && m_currentContent.contentsBackgroundColor.alpha() == 0xff)
            || (m_currentContent.contentType == MediaContentType)
            || (m_currentContent.contentType == PixmapContentType && !m_currentContent.pixmap.hasAlpha())) {

            painterPath.addRect(m_state.contentsRect);
        }
    }
    return painterPath;
}

QRectF GraphicsLayerQtImpl::boundingRect() const
{
    return QRectF(QPointF(0, 0), QSizeF(m_size));
}

void GraphicsLayerQtImpl::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget)
{
    if (m_currentContent.backgroundColor.isValid())
        painter->fillRect(option->rect, QColor(m_currentContent.backgroundColor));

    switch (m_currentContent.contentType) {
    case HTMLContentType:
        if (m_state.drawsContent) {
            QPixmap backingStore;
            // We might need to recache, in case we try to paint and the cache was purged (e.g. if it was full).
            if (!QPixmapCache::find(m_backingStore.key, &backingStore) || backingStore.size() != m_size.toSize())
                backingStore = recache(QRegion(m_state.contentsRect));
            const QRectF bounds(0, 0, m_backingStore.size.width(), m_backingStore.size.height());
            painter->drawPixmap(0, 0, backingStore);
        }
        break;
    case PixmapContentType:
        painter->drawPixmap(m_state.contentsRect, m_currentContent.pixmap);
        break;
    case ColorContentType:
        painter->fillRect(m_state.contentsRect, m_currentContent.contentsBackgroundColor);
        break;
    case MediaContentType:
        // we don't need to paint anything: we have a QGraphicsItem from the media element
        break;
    }
}

void GraphicsLayerQtImpl::notifySyncRequired()
{
    if (m_layer->client())
        m_layer->client()->notifySyncRequired(m_layer);
}

void GraphicsLayerQtImpl::notifyChange(ChangeMask changeMask)
{
    m_changeMask |= changeMask;
    static QMetaMethod syncMethod = staticMetaObject.method(staticMetaObject.indexOfMethod("notifySyncRequired()"));
    syncMethod.invoke(this, Qt::QueuedConnection);
}

void GraphicsLayerQtImpl::flushChanges(bool recursive, bool forceUpdateTransform)
{
    // this is the bulk of the work. understanding what the compositor is trying to achieve,
    // what graphics-view can do, and trying to find a sane common-grounds
    if (!m_layer || m_changeMask == NoChanges)
        goto afterLayerChanges;

    if (m_currentContent.contentType == HTMLContentType && (m_changeMask & ParentChange)) {
        // the WebCore compositor manages item ownership. We have to make sure
        // graphics-view doesn't try to snatch that ownership...
        if (!m_layer->parent() && !parentItem())
            setParentItem(0);
        else if (m_layer && m_layer->parent() && m_layer->parent()->nativeLayer() != parentItem())
            setParentItem(m_layer->parent()->nativeLayer());
    }

    if (m_changeMask & ChildrenChange) {
        // we basically do an XOR operation on the list of current children
        // and the list of wanted children, and remove/add
        QSet<QGraphicsItem*> newChildren;
        const Vector<GraphicsLayer*> newChildrenVector = (m_layer->children());
        newChildren.reserve(newChildrenVector.size());

        for (size_t i = 0; i < newChildrenVector.size(); ++i)
            newChildren.insert(newChildrenVector[i]->platformLayer());

        const QSet<QGraphicsItem*> currentChildren = childItems().toSet();
        const QSet<QGraphicsItem*> childrenToAdd = newChildren - currentChildren;
        const QSet<QGraphicsItem*> childrenToRemove = currentChildren - newChildren;

        for (QSet<QGraphicsItem*>::const_iterator it = childrenToAdd.begin(); it != childrenToAdd.end(); ++it)
             if (QGraphicsItem* w = *it)
                w->setParentItem(this);

        for (QSet<QGraphicsItem*>::const_iterator it = childrenToRemove.begin(); it != childrenToRemove.end(); ++it)
             if (GraphicsLayerQtImpl* w = qobject_cast<GraphicsLayerQtImpl*>((*it)->toGraphicsObject()))
                w->setParentItem(0);

        // children are ordered by z-value, let graphics-view know.
        for (size_t i = 0; i < newChildrenVector.size(); ++i)
            if (newChildrenVector[i]->platformLayer())
                newChildrenVector[i]->platformLayer()->setZValue(i);
    }

    if (m_changeMask & MaskLayerChange) {
        // we can't paint here, because we don't know if the mask layer
        // itself is ready... we'll have to wait till this layer tries to paint
        setFlag(ItemClipsChildrenToShape, m_layer->maskLayer() || m_layer->masksToBounds());
#ifndef QT_NO_GRAPHICSEFFECT
        setGraphicsEffect(0);
        if (m_layer->maskLayer()) {
            if (GraphicsLayerQtImpl* mask = qobject_cast<GraphicsLayerQtImpl*>(m_layer->maskLayer()->platformLayer()->toGraphicsObject())) {
                mask->m_maskEffect = new MaskEffectQt(this, mask);
                setGraphicsEffect(mask->m_maskEffect.data());
            }
        }
#endif
    }

    if (m_changeMask & SizeChange) {
        if (m_layer->size() != m_state.size) {
            prepareGeometryChange();
            m_size = QSizeF(m_layer->size().width(), m_layer->size().height());
        }
    }
    // FIXME: this is a hack, due to a probable QGraphicsScene bug when rapidly modifying the perspective
    // but without this line we get graphic artifacts
    if ((m_changeMask & ChildrenTransformChange) && m_state.childrenTransform != m_layer->childrenTransform())
        if (scene())
            scene()->update();

    if (m_changeMask & (ChildrenTransformChange | Preserves3DChange | TransformChange | AnchorPointChange | SizeChange | BackfaceVisibilityChange | PositionChange)) {
        // due to the differences between the way WebCore handles transforms and the way Qt handles transforms,
        // all these elements affect the transforms of all the descendants.
        forceUpdateTransform = true;
    }

    if (m_changeMask & (ContentChange | DrawsContentChange | MaskLayerChange)) {
        switch (m_pendingContent.contentType) {
        case PixmapContentType:
            update();
            setFlag(ItemHasNoContents, false);

            break;
        case MediaContentType:
            setFlag(ItemHasNoContents, true);
            m_pendingContent.mediaLayer.data()->setParentItem(this);
            break;

        case ColorContentType:
            if (m_pendingContent.contentType != m_currentContent.contentType || m_pendingContent.contentsBackgroundColor != m_currentContent.contentsBackgroundColor)
                update();
            m_state.drawsContent = false;
            setFlag(ItemHasNoContents, false);

            // we only use ItemUsesExtendedStyleOption for HTML content - colors don't gain much from that anyway
            setFlag(QGraphicsItem::ItemUsesExtendedStyleOption, false);
            break;

        case HTMLContentType:
            if (m_pendingContent.contentType != m_currentContent.contentType)
                update();
            if (!m_state.drawsContent && m_layer->drawsContent())
                update();

            setFlag(ItemHasNoContents, !m_layer->drawsContent());
            break;
        }
    }

    if ((m_changeMask & OpacityChange) && m_state.opacity != m_layer->opacity() && !m_opacityAnimationRunning)
        setOpacity(m_layer->opacity());

    if (m_changeMask & ContentsRectChange) {
        const QRect rect(m_layer->contentsRect());
        if (m_state.contentsRect != rect) {
            m_state.contentsRect = rect;
            update();
        }
    }

    if ((m_changeMask & MasksToBoundsChange)
        && m_state.masksToBounds != m_layer->masksToBounds()) {

        setFlag(QGraphicsItem::ItemClipsToShape, m_layer->masksToBounds());
        setFlag(QGraphicsItem::ItemClipsChildrenToShape, m_layer->masksToBounds());
    }

    if ((m_changeMask & ContentsOpaqueChange) && m_state.contentsOpaque != m_layer->contentsOpaque())
        prepareGeometryChange();

#ifndef QT_NO_GRAPHICSEFFECT
    if (m_maskEffect)
        m_maskEffect.data()->update();
    else
#endif
    if (m_changeMask & DisplayChange) {
#ifndef QT_GRAPHICS_LAYER_NO_RECACHE_ON_DISPLAY_CHANGE
        // Recache now: all the content is ready and we don't want to wait until the paint event.
        // We only need to do this for HTML content, there's no point in caching directly composited
        // content like images or solid rectangles.
        if (m_pendingContent.contentType == HTMLContentType)
            recache(m_pendingContent.regionToUpdate);
#endif
        update(m_pendingContent.regionToUpdate.boundingRect());
        m_pendingContent.regionToUpdate = QRegion();
    }

    if ((m_changeMask & BackgroundColorChange) && (m_pendingContent.backgroundColor != m_currentContent.backgroundColor))
        update();

    m_state.maskLayer = m_layer->maskLayer();
    m_state.pos = m_layer->position();
    m_state.anchorPoint = m_layer->anchorPoint();
    m_state.size = m_layer->size();
    m_state.transform = m_layer->transform();
    m_state.geoOrientation = m_layer->geometryOrientation();
    m_state.contentsOrientation =m_layer->contentsOrientation();
    m_state.opacity = m_layer->opacity();
    m_state.contentsRect = m_layer->contentsRect();
    m_state.preserves3D = m_layer->preserves3D();
    m_state.masksToBounds = m_layer->masksToBounds();
    m_state.drawsContent = m_layer->drawsContent();
    m_state.contentsOpaque = m_layer->contentsOpaque();
    m_state.backfaceVisibility = m_layer->backfaceVisibility();
    m_state.childrenTransform = m_layer->childrenTransform();
    m_currentContent.pixmap = m_pendingContent.pixmap;
    m_currentContent.contentType = m_pendingContent.contentType;
    m_currentContent.mediaLayer = m_pendingContent.mediaLayer;
    m_currentContent.backgroundColor = m_pendingContent.backgroundColor;
    m_currentContent.contentsBackgroundColor = m_pendingContent.contentsBackgroundColor;
    m_pendingContent.regionToUpdate = QRegion();
    m_changeMask = NoChanges;


afterLayerChanges:
    if (forceUpdateTransform)
        updateTransform();

    if (!recursive)
        return;    

    QList<QGraphicsItem*> children = childItems();
    if (m_state.maskLayer)
        children.append(m_state.maskLayer->platformLayer());

    for (QList<QGraphicsItem*>::const_iterator it = children.begin(); it != children.end(); ++it) {
        if (QGraphicsItem* item = *it)
            if (GraphicsLayerQtImpl* layer = qobject_cast<GraphicsLayerQtImpl*>(item->toGraphicsObject()))
                layer->flushChanges(true, forceUpdateTransform);
    }
}

void GraphicsLayerQtImpl::notifyAnimationStarted()
{
    // WebCore notifies javascript when the animation starts
    // here we're letting it know
    m_layer->client()->notifyAnimationStarted(m_layer, WTF::currentTime());
}

GraphicsLayerQt::GraphicsLayerQt(GraphicsLayerClient* client)
    : GraphicsLayer(client)
    , m_impl(PassOwnPtr<GraphicsLayerQtImpl>(new GraphicsLayerQtImpl(this)))
{
}

GraphicsLayerQt::~GraphicsLayerQt()
{
}

// this is the hook for WebCore compositor to know that Qt implements compositing with GraphicsLayerQt
PassOwnPtr<GraphicsLayer> GraphicsLayer::create(GraphicsLayerClient* client)
{
    return new GraphicsLayerQt(client);
}

// reimp from GraphicsLayer.h: Qt is top-down
GraphicsLayer::CompositingCoordinatesOrientation GraphicsLayer::compositingCoordinatesOrientation()
{
    return CompositingCoordinatesTopDown;
}

// reimp from GraphicsLayer.h: we'll need to update the whole display, and we can't count on the current size because it might change
void GraphicsLayerQt::setNeedsDisplay()
{
    m_impl->m_pendingContent.regionToUpdate = QRegion(QRect(QPoint(0, 0), QSize(size().width(), size().height())));
    m_impl->notifyChange(GraphicsLayerQtImpl::DisplayChange);
}

// reimp from GraphicsLayer.h
void GraphicsLayerQt::setNeedsDisplayInRect(const FloatRect& rect)
{
    m_impl->m_pendingContent.regionToUpdate|= QRectF(rect).toAlignedRect();
    m_impl->notifyChange(GraphicsLayerQtImpl::DisplayChange);
}

// reimp from GraphicsLayer.h
void GraphicsLayerQt::setName(const String& name)
{
    m_impl->setObjectName(name);
    GraphicsLayer::setName(name);
}

// reimp from GraphicsLayer.h
void GraphicsLayerQt::setParent(GraphicsLayer* layer)
{
    m_impl->notifyChange(GraphicsLayerQtImpl::ParentChange);
    GraphicsLayer::setParent(layer);
}

// reimp from GraphicsLayer.h
bool GraphicsLayerQt::setChildren(const Vector<GraphicsLayer*>& children)
{
    m_impl->notifyChange(GraphicsLayerQtImpl::ChildrenChange);
    return GraphicsLayer::setChildren(children);
}

// reimp from GraphicsLayer.h
void GraphicsLayerQt::addChild(GraphicsLayer* layer)
{
    m_impl->notifyChange(GraphicsLayerQtImpl::ChildrenChange);
    GraphicsLayer::addChild(layer);
}

// reimp from GraphicsLayer.h
void GraphicsLayerQt::addChildAtIndex(GraphicsLayer* layer, int index)
{
    GraphicsLayer::addChildAtIndex(layer, index);
    m_impl->notifyChange(GraphicsLayerQtImpl::ChildrenChange);
}

// reimp from GraphicsLayer.h
void GraphicsLayerQt::addChildAbove(GraphicsLayer* layer, GraphicsLayer* sibling)
{
     GraphicsLayer::addChildAbove(layer, sibling);
     m_impl->notifyChange(GraphicsLayerQtImpl::ChildrenChange);
}

// reimp from GraphicsLayer.h
void GraphicsLayerQt::addChildBelow(GraphicsLayer* layer, GraphicsLayer* sibling)
{

    GraphicsLayer::addChildBelow(layer, sibling);
    m_impl->notifyChange(GraphicsLayerQtImpl::ChildrenChange);
}

// reimp from GraphicsLayer.h
bool GraphicsLayerQt::replaceChild(GraphicsLayer* oldChild, GraphicsLayer* newChild)
{
    if (GraphicsLayer::replaceChild(oldChild, newChild)) {
        m_impl->notifyChange(GraphicsLayerQtImpl::ChildrenChange);
        return true;
    }

    return false;
}

// reimp from GraphicsLayer.h
void GraphicsLayerQt::removeFromParent()
{
    if (parent())
        m_impl->notifyChange(GraphicsLayerQtImpl::ParentChange);
    GraphicsLayer::removeFromParent();
}

// reimp from GraphicsLayer.h
void GraphicsLayerQt::setMaskLayer(GraphicsLayer* value)
{
    if (value == maskLayer())
        return;
    GraphicsLayer::setMaskLayer(value);
    m_impl->notifyChange(GraphicsLayerQtImpl::MaskLayerChange);
}

// reimp from GraphicsLayer.h
void GraphicsLayerQt::setPosition(const FloatPoint& value)
{
    if (value == position())
        return;
    GraphicsLayer::setPosition(value);
    m_impl->notifyChange(GraphicsLayerQtImpl::PositionChange);
}

// reimp from GraphicsLayer.h
void GraphicsLayerQt::setAnchorPoint(const FloatPoint3D& value)
{
    if (value == anchorPoint())
        return;
    GraphicsLayer::setAnchorPoint(value);
    m_impl->notifyChange(GraphicsLayerQtImpl::AnchorPointChange);
}

// reimp from GraphicsLayer.h
void GraphicsLayerQt::setSize(const FloatSize& value)
{
    if (value == size())
        return;
    GraphicsLayer::setSize(value);
    m_impl->notifyChange(GraphicsLayerQtImpl::SizeChange);
}

// reimp from GraphicsLayer.h
void GraphicsLayerQt::setTransform(const TransformationMatrix& value)
{
    if (value == transform())
        return;
    GraphicsLayer::setTransform(value);
    m_impl->notifyChange(GraphicsLayerQtImpl::TransformChange);
}

// reimp from GraphicsLayer.h
void GraphicsLayerQt::setChildrenTransform(const TransformationMatrix& value)
{
    if (value == childrenTransform())
        return;
    GraphicsLayer::setChildrenTransform(value);
    m_impl->notifyChange(GraphicsLayerQtImpl::ChildrenTransformChange);
}

// reimp from GraphicsLayer.h
void GraphicsLayerQt::setPreserves3D(bool value)
{
    if (value == preserves3D())
        return;
    GraphicsLayer::setPreserves3D(value);
    m_impl->notifyChange(GraphicsLayerQtImpl::Preserves3DChange);
}

// reimp from GraphicsLayer.h
void GraphicsLayerQt::setMasksToBounds(bool value)
{
    if (value == masksToBounds())
        return;
    GraphicsLayer::setMasksToBounds(value);
    m_impl->notifyChange(GraphicsLayerQtImpl::MasksToBoundsChange);
}

// reimp from GraphicsLayer.h
void GraphicsLayerQt::setDrawsContent(bool value)
{
    if (value == drawsContent())
        return;
    m_impl->notifyChange(GraphicsLayerQtImpl::DrawsContentChange);
    GraphicsLayer::setDrawsContent(value);
}

// reimp from GraphicsLayer.h
void GraphicsLayerQt::setBackgroundColor(const Color& value)
{
    if (value == m_impl->m_pendingContent.backgroundColor)
        return;
    m_impl->m_pendingContent.backgroundColor = value;
    GraphicsLayer::setBackgroundColor(value);
    m_impl->notifyChange(GraphicsLayerQtImpl::BackgroundColorChange);
}

// reimp from GraphicsLayer.h
void GraphicsLayerQt::clearBackgroundColor()
{
    if (!m_impl->m_pendingContent.backgroundColor.isValid())
        return;
    m_impl->m_pendingContent.backgroundColor = QColor();
    GraphicsLayer::clearBackgroundColor();
    m_impl->notifyChange(GraphicsLayerQtImpl::BackgroundColorChange);
}

// reimp from GraphicsLayer.h
void GraphicsLayerQt::setContentsOpaque(bool value)
{
    if (value == contentsOpaque())
        return;
    m_impl->notifyChange(GraphicsLayerQtImpl::ContentsOpaqueChange);
    GraphicsLayer::setContentsOpaque(value);
}

// reimp from GraphicsLayer.h
void GraphicsLayerQt::setBackfaceVisibility(bool value)
{
    if (value == backfaceVisibility())
        return;
    GraphicsLayer::setBackfaceVisibility(value);
    m_impl->notifyChange(GraphicsLayerQtImpl::BackfaceVisibilityChange);
}

// reimp from GraphicsLayer.h
void GraphicsLayerQt::setOpacity(float value)
{
    if (value == opacity())
        return;
    GraphicsLayer::setOpacity(value);
    m_impl->notifyChange(GraphicsLayerQtImpl::OpacityChange);
}

// reimp from GraphicsLayer.h
void GraphicsLayerQt::setContentsRect(const IntRect& value)
{
    if (value == contentsRect())
        return;
    GraphicsLayer::setContentsRect(value);
    m_impl->notifyChange(GraphicsLayerQtImpl::ContentsRectChange);
}

// reimp from GraphicsLayer.h
void GraphicsLayerQt::setContentsToImage(Image* image)
{
    m_impl->notifyChange(GraphicsLayerQtImpl::ContentChange);
    m_impl->m_pendingContent.contentType = GraphicsLayerQtImpl::HTMLContentType;
    GraphicsLayer::setContentsToImage(image);
    if (image) {
        QPixmap* pxm = image->nativeImageForCurrentFrame();
        if (pxm) {
            m_impl->m_pendingContent.pixmap = *pxm;
            m_impl->m_pendingContent.contentType = GraphicsLayerQtImpl::PixmapContentType;
            return;
        }        
    }
    m_impl->m_pendingContent.pixmap = QPixmap();
}

// reimp from GraphicsLayer.h
void GraphicsLayerQt::setContentsBackgroundColor(const Color& color)
{
    m_impl->notifyChange(GraphicsLayerQtImpl::ContentChange);
    m_impl->m_pendingContent.contentType = GraphicsLayerQtImpl::ColorContentType;
    m_impl->m_pendingContent.contentsBackgroundColor = QColor(color);
    GraphicsLayer::setContentsBackgroundColor(color);
}

void GraphicsLayerQt::setContentsToMedia(PlatformLayer* media)
{
    if (media) {
        m_impl->m_pendingContent.contentType = GraphicsLayerQtImpl::MediaContentType;
        m_impl->m_pendingContent.mediaLayer = media->toGraphicsObject();
    } else
        m_impl->m_pendingContent.contentType = GraphicsLayerQtImpl::HTMLContentType;

    m_impl->notifyChange(GraphicsLayerQtImpl::ContentChange);
    GraphicsLayer::setContentsToMedia(media);
}


// reimp from GraphicsLayer.h
void GraphicsLayerQt::setGeometryOrientation(CompositingCoordinatesOrientation orientation)
{
    m_impl->notifyChange(GraphicsLayerQtImpl::GeometryOrientationChange);
    GraphicsLayer::setGeometryOrientation(orientation);
}

// reimp from GraphicsLayer.h
void GraphicsLayerQt::setContentsOrientation(CompositingCoordinatesOrientation orientation)
{
    m_impl->notifyChange(GraphicsLayerQtImpl::ContentsOrientationChange);
    GraphicsLayer::setContentsOrientation(orientation);
}

// reimp from GraphicsLayer.h
void GraphicsLayerQt::distributeOpacity(float o)
{
    m_impl->notifyChange(GraphicsLayerQtImpl::OpacityChange);
    m_impl->m_state.distributeOpacity = true;
}

// reimp from GraphicsLayer.h
float GraphicsLayerQt::accumulatedOpacity() const
{
    return m_impl->effectiveOpacity();
}

// reimp from GraphicsLayer.h
void GraphicsLayerQt::syncCompositingState()
{
    m_impl->flushChanges();
    GraphicsLayer::syncCompositingState();
}

// reimp from GraphicsLayer.h
NativeLayer GraphicsLayerQt::nativeLayer() const
{
    return m_impl.get();
}

// reimp from GraphicsLayer.h
PlatformLayer* GraphicsLayerQt::platformLayer() const
{
    return m_impl.get();
}

// now we start dealing with WebCore animations translated to Qt animations

template <typename T>
struct KeyframeValueQt {
    TimingFunction timingFunction;
    T value;
};

// we copy this from the AnimationBase.cpp
static inline double solveEpsilon(double duration)
{
    return 1.0 / (200.0 * duration);
}

static inline double solveCubicBezierFunction(qreal p1x, qreal p1y, qreal p2x, qreal p2y, double t, double duration)
{
    UnitBezier bezier(p1x, p1y, p2x, p2y);
    return bezier.solve(t, solveEpsilon(duration));
}

// we want the timing function to be as close as possible to what the web-developer intended, so we're using the same function used by WebCore when compositing is disabled
// Using easing-curves would probably work for some of the cases, but wouldn't really buy us anything as we'd have to convert the bezier function back to an easing curve
static inline qreal applyTimingFunction(const TimingFunction& timingFunction, qreal progress, double duration)
{
    if (timingFunction.type() == LinearTimingFunction)
        return progress;
    if (timingFunction.type() == CubicBezierTimingFunction) {
        return solveCubicBezierFunction(timingFunction.x1(),
                                        timingFunction.y1(),
                                        timingFunction.x2(),
                                        timingFunction.y2(),
                                        double(progress), double(duration) / 1000);
    }
    return progress;
}

// helper functions to safely get a value out of WebCore's AnimationValue*
static void webkitAnimationToQtAnimationValue(const AnimationValue* animationValue, TransformOperations& transformOperations)
{
    transformOperations = TransformOperations();
    if (!animationValue)
        return;

    if (const TransformOperations* ops = static_cast<const TransformAnimationValue*>(animationValue)->value())
        transformOperations = *ops;
}

static void webkitAnimationToQtAnimationValue(const AnimationValue* animationValue, qreal& realValue)
{
    realValue = animationValue ? static_cast<const FloatAnimationValue*>(animationValue)->value() : 0;
}

#ifndef QT_NO_ANIMATION
// we put a bit of the functionality in a base class to allow casting and to save some code size
class AnimationQtBase : public QAbstractAnimation {
public:
    AnimationQtBase(GraphicsLayerQtImpl* layer, const KeyframeValueList& values, const IntSize& boxSize, const Animation* anim, const QString & name)
        : QAbstractAnimation(0)
        , m_layer(layer)
        , m_boxSize(boxSize)
        , m_duration(anim->duration() * 1000)
        , m_isAlternate(anim->direction() == Animation::AnimationDirectionAlternate)
        , m_webkitPropertyID(values.property())
        , m_webkitAnimation(anim)
        , m_keyframesName(name)
        , m_fillsForwards(false)
    {
    }

    virtual void updateState(QAbstractAnimation::State newState, QAbstractAnimation::State oldState)
    {
        QAbstractAnimation::updateState(newState, oldState);

        // for some reason I have do this asynchronously - or the animation won't work
        if (newState == Running && oldState == Stopped && m_layer.data())
            m_layer.data()->notifyAnimationStartedAsync();
    }

    virtual int duration() const { return m_duration; }

    QWeakPointer<GraphicsLayerQtImpl> m_layer;
    IntSize m_boxSize;
    int m_duration;
    bool m_isAlternate;
    AnimatedPropertyID m_webkitPropertyID;

    // we might need this in case the same animation is added again (i.e. resumed by WebCore)
    const Animation* m_webkitAnimation;
    QString m_keyframesName;
    bool m_fillsForwards;
};

// we'd rather have a templatized QAbstractAnimation than QPropertyAnimation / QVariantAnimation;
// Since we know the types that we're dealing with, the QObject/QProperty/QVariant abstraction
// buys us very little in this case, for too much overhead
template <typename T>
class AnimationQt : public AnimationQtBase {

public:
    AnimationQt(GraphicsLayerQtImpl* layer, const KeyframeValueList& values, const IntSize& boxSize, const Animation* anim, const QString & name)
        :AnimationQtBase(layer, values, boxSize, anim, name)
    {
        // copying those WebCore structures is not trivial, we have to do it like this
        for (size_t i = 0; i < values.size(); ++i) {
            const AnimationValue* animationValue = values.at(i);
            KeyframeValueQt<T> keyframeValue;
            if (animationValue->timingFunction())
                keyframeValue.timingFunction = *animationValue->timingFunction();
            else
                keyframeValue.timingFunction = anim->timingFunction();
            webkitAnimationToQtAnimationValue(animationValue, keyframeValue.value);
            m_keyframeValues[animationValue->keyTime()] = keyframeValue;
        }
    }

protected:

    // this is the part that differs between animated properties
    virtual void applyFrame(const T& fromValue, const T& toValue, qreal progress) = 0;

    virtual void updateCurrentTime(int currentTime)
    {
        if (!m_layer)
            return;

        qreal progress = qreal(currentLoopTime()) / duration();

        if (m_isAlternate && currentLoop()%2)
            progress = 1-progress;

        if (m_keyframeValues.isEmpty())
            return;

        // we find the current from-to keyframes in our little map
        typename QMap<qreal, KeyframeValueQt<T> >::iterator it = m_keyframeValues.find(progress);

        // we didn't find an exact match, we try the closest match (lower bound)
        if (it == m_keyframeValues.end())
            it = m_keyframeValues.lowerBound(progress)-1;

        // we didn't find any match - we use the first keyframe
        if (it == m_keyframeValues.end())
            it = m_keyframeValues.begin();

        typename QMap<qreal, KeyframeValueQt<T> >::iterator it2 = it+1;
        if (it2 == m_keyframeValues.end())
            it2 = it;
        const KeyframeValueQt<T>& fromKeyframe = it.value();
        const KeyframeValueQt<T>& toKeyframe = it2.value();

        const TimingFunction& timingFunc = fromKeyframe.timingFunction;
        const T& fromValue = fromKeyframe.value;
        const T& toValue = toKeyframe.value;

        // now we have a source keyframe, origin keyframe and a timing function
        // we can now process the progress and apply the frame
        progress = (!progress || progress == 1 || it.key() == it2.key())
                                         ? progress
                                         : applyTimingFunction(timingFunc, (progress - it.key()) / (it2.key() - it.key()), duration());
        applyFrame(fromValue, toValue, progress);
    }

    QMap<qreal, KeyframeValueQt<T> > m_keyframeValues;
};

class TransformAnimationQt : public AnimationQt<TransformOperations> {
public:
    TransformAnimationQt(GraphicsLayerQtImpl* layer, const KeyframeValueList& values, const IntSize& boxSize, const Animation* anim, const QString & name)
        : AnimationQt<TransformOperations>(layer, values, boxSize, anim, name)
    {
    }

    ~TransformAnimationQt()
    {
        if (m_fillsForwards)
            setCurrentTime(1);
    }

    // the idea is that we let WebCore manage the transform-operations
    // and Qt just manages the animation heartbeat and the bottom-line QTransform
    // we get the performance not by using QTransform instead of TransformationMatrix, but by proper caching of
    // items that are expensive for WebCore to render. We want the rest to be as close to WebCore's idea as possible.
    virtual void applyFrame(const TransformOperations& sourceOperations, const TransformOperations& targetOperations, qreal progress)
    {
        TransformationMatrix transformMatrix;

        bool validTransformLists = true;
        const int sourceOperationCount = sourceOperations.size();
        if (sourceOperationCount) {
            if (targetOperations.size() != sourceOperationCount)
                validTransformLists = false;
            else
                for (size_t j = 0; j < sourceOperationCount && validTransformLists; ++j)
                    if (!sourceOperations.operations()[j]->isSameType(*targetOperations.operations()[j]))
                        validTransformLists = false;
        }

        if (validTransformLists) {
            for (size_t i = 0; i < targetOperations.size(); ++i)
                targetOperations.operations()[i]->blend(sourceOperations.at(i), progress)->apply(transformMatrix, m_boxSize);
        } else {
            targetOperations.apply(m_boxSize, transformMatrix);
            transformMatrix.blend(m_sourceMatrix, progress);
        }

        m_layer.data()->m_layer->setTransform(transformMatrix);
        // We force the actual opacity change, otherwise it would be ignored because of the animation.
        m_layer.data()->setBaseTransform(transformMatrix);
    }

    virtual void updateState(QAbstractAnimation::State newState, QAbstractAnimation::State oldState)
    {
        AnimationQtBase::updateState(newState, oldState);
        if (!m_layer)
            return;
        m_layer.data()->flushChanges(true);

        // to increase FPS, we use a less accurate caching mechanism while animation is going on
        // this is a UX choice that should probably be customizable
        if (newState == QAbstractAnimation::Running) {
            m_sourceMatrix = m_layer.data()->m_layer->transform();
            m_layer.data()->m_transformAnimationRunning = true;
        } else if (newState == QAbstractAnimation::Stopped) {
            // We update the transform back to the default. This already takes fill-modes into account.
            m_layer.data()->m_transformAnimationRunning = false;
            if (m_layer && m_layer.data()->m_layer)
                m_layer.data()->setBaseTransform(m_layer.data()->m_layer->transform());
        }
    }

    TransformationMatrix m_sourceMatrix;
};

class OpacityAnimationQt : public AnimationQt<qreal> {
public:
    OpacityAnimationQt(GraphicsLayerQtImpl* layer, const KeyframeValueList& values, const IntSize& boxSize, const Animation* anim, const QString & name)
         : AnimationQt<qreal>(layer, values, boxSize, anim, name)
    {
    }

    ~OpacityAnimationQt()
    {
        if (m_fillsForwards)
            setCurrentTime(1);
    }

    virtual void applyFrame(const qreal& fromValue, const qreal& toValue, qreal progress)
    {
        qreal opacity = qBound(qreal(0), fromValue + (toValue-fromValue)*progress, qreal(1));

        // FIXME: this is a hack, due to a probable QGraphicsScene bug.
        // Without this the opacity change doesn't always have immediate effect.
        if (m_layer.data()->scene() && !m_layer.data()->opacity() && opacity)
            m_layer.data()->scene()->update();

        m_layer.data()->m_layer->setOpacity(opacity);
        // We force the actual opacity change, otherwise it would be ignored because of the animation.
        m_layer.data()->setOpacity(opacity);
    }

    virtual void updateState(QAbstractAnimation::State newState, QAbstractAnimation::State oldState)
    {
        QAbstractAnimation::updateState(newState, oldState);

        if (m_layer)
            m_layer.data()->m_opacityAnimationRunning = (newState == QAbstractAnimation::Running);

        // If stopped, we update the opacity back to the default. This already takes fill-modes into account.
        if (newState == Stopped)
            if (m_layer && m_layer.data()->m_layer)
                m_layer.data()->setOpacity(m_layer.data()->m_layer->opacity());

    }
};

bool GraphicsLayerQt::addAnimation(const KeyframeValueList& values, const IntSize& boxSize, const Animation* anim, const String& keyframesName, double timeOffset)
{
    if (!anim->duration() || !anim->iterationCount())
        return false;

    AnimationQtBase* newAnim = 0;

    // fixed: we might already have the Qt animation object associated with this WebCore::Animation object
    for (QList<QWeakPointer<QAbstractAnimation> >::iterator it = m_impl->m_animations.begin(); it != m_impl->m_animations.end(); ++it) {
        if (*it) {
            AnimationQtBase* curAnimation = static_cast<AnimationQtBase*>(it->data());
            if (curAnimation && curAnimation->m_webkitAnimation == anim)
                newAnim = curAnimation;
        }
    }

    if (!newAnim) {
        switch (values.property()) {
        case AnimatedPropertyOpacity:
            newAnim = new OpacityAnimationQt(m_impl.get(), values, boxSize, anim, keyframesName);
            break;
        case AnimatedPropertyWebkitTransform:
            newAnim = new TransformAnimationQt(m_impl.get(), values, boxSize, anim, keyframesName);
            break;
        default:
            return false;
        }

        // we make sure WebCore::Animation and QAnimation are on the same terms
        newAnim->setLoopCount(anim->iterationCount());
        newAnim->m_fillsForwards = anim->fillsForwards();
        m_impl->m_animations.append(QWeakPointer<QAbstractAnimation>(newAnim));
        QObject::connect(&m_impl->m_suspendTimer, SIGNAL(timeout()), newAnim, SLOT(resume()));
    }

    // flush now or flicker...
    m_impl->flushChanges(false);

    // when fill-mode is backwards/both, we set the value to 0 before the delay takes place
    if (anim->fillsBackwards())
        newAnim->setCurrentTime(0);

    newAnim->start();

    // we synchronize the animation's clock to WebCore's timeOffset
    newAnim->setCurrentTime(timeOffset * 1000);

    // we don't need to manage the animation object's lifecycle:
    // WebCore would call removeAnimations when it's time to delete.

    return true;
}

void GraphicsLayerQt::removeAnimationsForProperty(AnimatedPropertyID id)
{
    for (QList<QWeakPointer<QAbstractAnimation> >::iterator it = m_impl->m_animations.begin(); it != m_impl->m_animations.end(); ++it) {
        if (*it) {
            AnimationQtBase* anim = static_cast<AnimationQtBase*>(it->data());
            if (anim && anim->m_webkitPropertyID == id) {
                // We need to stop the animation right away, or it might flicker before it's deleted.
                anim->stop();
                anim->deleteLater();
                it = m_impl->m_animations.erase(it);
                --it;
            }
        }
    }
}

void GraphicsLayerQt::removeAnimationsForKeyframes(const String& name)
{
    for (QList<QWeakPointer<QAbstractAnimation> >::iterator it = m_impl->m_animations.begin(); it != m_impl->m_animations.end(); ++it) {
        if (*it) {
            AnimationQtBase* anim = static_cast<AnimationQtBase*>((*it).data());
            if (anim && anim->m_keyframesName == QString(name)) {
                // We need to stop the animation right away, or it might flicker before it's deleted.
                anim->stop();
                anim->deleteLater();
                it = m_impl->m_animations.erase(it);
                --it;
            }
        }
    }
}

void GraphicsLayerQt::pauseAnimation(const String& name, double timeOffset)
{
    for (QList<QWeakPointer<QAbstractAnimation> >::iterator it = m_impl->m_animations.begin(); it != m_impl->m_animations.end(); ++it) {
        if (!(*it))
            continue;

        AnimationQtBase* anim = static_cast<AnimationQtBase*>((*it).data());
        if (anim && anim->m_keyframesName == QString(name)) {
            // we synchronize the animation's clock to WebCore's timeOffset
            anim->setCurrentTime(timeOffset * 1000);
            anim->pause();
        }
    }
}

void GraphicsLayerQt::suspendAnimations(double time)
{
    if (m_impl->m_suspendTimer.isActive()) {
        m_impl->m_suspendTimer.stop();
        m_impl->m_suspendTimer.start(time * 1000);
    } else {
        for (QList<QWeakPointer<QAbstractAnimation> >::iterator it = m_impl->m_animations.begin(); it != m_impl->m_animations.end(); ++it) {
            QAbstractAnimation* anim = it->data();
            if (anim)
                anim->pause();
        }
    }
}

void GraphicsLayerQt::resumeAnimations()
{
    if (m_impl->m_suspendTimer.isActive()) {
        m_impl->m_suspendTimer.stop();
        for (QList<QWeakPointer<QAbstractAnimation> >::iterator it = m_impl->m_animations.begin(); it != m_impl->m_animations.end(); ++it) {
            QAbstractAnimation* anim = (*it).data();
            if (anim)
                anim->resume();
        }
    }
}

#endif // QT_NO_ANIMATION
}

#include <GraphicsLayerQt.moc>
