/*
 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.
 */

#ifndef TextureMapperLayer_h
#define TextureMapperLayer_h

#include "FilterOperations.h"
#include "FloatRect.h"
#include "GraphicsLayerTransform.h"
#include "TextureMapper.h"
#include "TextureMapperAnimation.h"
#include "TextureMapperBackingStore.h"

namespace WebCore {

class GraphicsLayer;
class Region;
class TextureMapperPaintOptions;
class TextureMapperPlatformLayer;

class TextureMapperLayer {
    WTF_MAKE_NONCOPYABLE(TextureMapperLayer);
    WTF_MAKE_FAST_ALLOCATED;
public:
    WEBCORE_EXPORT TextureMapperLayer();
    virtual ~TextureMapperLayer();

    void setID(uint32_t id) { m_id = id; }
    uint32_t id() { return m_id; }

    const Vector<TextureMapperLayer*>& children() const { return m_children; }

    TextureMapper* textureMapper() const { return rootLayer().m_textureMapper; }
    void setTextureMapper(TextureMapper* texmap) { m_textureMapper = texmap; }

#if !USE(COORDINATED_GRAPHICS)
    void setChildren(const Vector<GraphicsLayer*>&);
#endif
    void setChildren(const Vector<TextureMapperLayer*>&);
    void setMaskLayer(TextureMapperLayer*);
    void setReplicaLayer(TextureMapperLayer*);
    void setPosition(const FloatPoint&);
    void setSize(const FloatSize&);
    void setAnchorPoint(const FloatPoint3D&);
    void setPreserves3D(bool);
    void setTransform(const TransformationMatrix&);
    void setChildrenTransform(const TransformationMatrix&);
    void setContentsRect(const FloatRect&);
    void setMasksToBounds(bool);
    void setDrawsContent(bool);
    bool drawsContent() const { return m_state.drawsContent; }
    bool contentsAreVisible() const { return m_state.contentsVisible; }
    FloatSize size() const { return m_state.size; }
    float opacity() const { return m_state.opacity; }
    TransformationMatrix transform() const { return m_state.transform; }
    void setContentsVisible(bool);
    void setContentsOpaque(bool);
    void setBackfaceVisibility(bool);
    void setOpacity(float);
    void setSolidColor(const Color&);
    void setContentsTileSize(const FloatSize&);
    void setContentsTilePhase(const FloatSize&);
    void setFilters(const FilterOperations&);

    bool hasFilters() const
    {
        return !m_currentFilters.isEmpty();
    }

    void setDebugVisuals(bool showDebugBorders, const Color& debugBorderColor, float debugBorderWidth, bool showRepaintCounter);
    bool isShowingRepaintCounter() const { return m_state.showRepaintCounter; }
    void setRepaintCount(int);
    void setContentsLayer(TextureMapperPlatformLayer*);
    void setAnimations(const TextureMapperAnimations&);
    void setFixedToViewport(bool);
    bool fixedToViewport() const { return m_fixedToViewport; }
    void setBackingStore(RefPtr<TextureMapperBackingStore>&&);

    bool applyAnimationsRecursively(MonotonicTime);
    bool syncAnimations(MonotonicTime);
    bool descendantsOrSelfHaveRunningAnimations() const;

    void paint();

    void setScrollPositionDeltaIfNeeded(const FloatSize&);

    void addChild(TextureMapperLayer*);

private:
    const TextureMapperLayer& rootLayer() const
    {
        if (m_effectTarget)
            return m_effectTarget->rootLayer();
        if (m_parent)
            return m_parent->rootLayer();
        return *this;
    }
    void computeTransformsRecursive();

    static void sortByZOrder(Vector<TextureMapperLayer* >& array);

    FloatPoint adjustedPosition() const { return m_state.pos + m_scrollPositionDelta; }
    bool isAncestorFixedToViewport() const;
    TransformationMatrix replicaTransform();
    void removeFromParent();
    void removeAllChildren();

    enum ResolveSelfOverlapMode {
        ResolveSelfOverlapAlways = 0,
        ResolveSelfOverlapIfNeeded
    };
    void computeOverlapRegions(Region& overlapRegion, Region& nonOverlapRegion, ResolveSelfOverlapMode);

    void paintRecursive(const TextureMapperPaintOptions&);
    void paintUsingOverlapRegions(const TextureMapperPaintOptions&);
    RefPtr<BitmapTexture> paintIntoSurface(const TextureMapperPaintOptions&, const IntSize&);
    void paintWithIntermediateSurface(const TextureMapperPaintOptions&, const IntRect&);
    void paintSelf(const TextureMapperPaintOptions&);
    void paintSelfAndChildren(const TextureMapperPaintOptions&);
    void paintSelfAndChildrenWithReplica(const TextureMapperPaintOptions&);
    void applyMask(const TextureMapperPaintOptions&);

    bool isVisible() const;

    bool shouldBlend() const;

    inline FloatRect layerRect() const
    {
        return FloatRect(FloatPoint::zero(), m_state.size);
    }

    Vector<TextureMapperLayer*> m_children;
    TextureMapperLayer* m_parent { nullptr };
    TextureMapperLayer* m_effectTarget { nullptr };
    RefPtr<TextureMapperBackingStore> m_backingStore;
    GraphicsLayerTransform m_currentTransform;
    TextureMapperPlatformLayer* m_contentsLayer { nullptr };
    float m_currentOpacity { 1.0 };
    FilterOperations m_currentFilters;
    float m_centerZ { 0 };

    struct State {
        FloatPoint pos;
        FloatPoint3D anchorPoint;
        FloatSize size;
        TransformationMatrix transform;
        TransformationMatrix childrenTransform;
        float opacity;
        FloatRect contentsRect;
        FloatSize contentsTileSize;
        FloatSize contentsTilePhase;
        TextureMapperLayer* maskLayer;
        TextureMapperLayer* replicaLayer;
        Color solidColor;
        FilterOperations filters;
        Color debugBorderColor;
        float debugBorderWidth;
        int repaintCount;

        bool preserves3D : 1;
        bool masksToBounds : 1;
        bool drawsContent : 1;
        bool contentsVisible : 1;
        bool contentsOpaque : 1;
        bool backfaceVisibility : 1;
        bool visible : 1;
        bool showDebugBorders : 1;
        bool showRepaintCounter : 1;

        State()
            : opacity(1)
            , maskLayer(0)
            , replicaLayer(0)
            , debugBorderWidth(0)
            , repaintCount(0)
            , preserves3D(false)
            , masksToBounds(false)
            , drawsContent(false)
            , contentsVisible(true)
            , contentsOpaque(false)
            , backfaceVisibility(true)
            , visible(true)
            , showDebugBorders(false)
            , showRepaintCounter(false)
        {
        }
    };

    State m_state;
    TextureMapper* m_textureMapper { nullptr };
    TextureMapperAnimations m_animations;
    FloatSize m_scrollPositionDelta;
    bool m_fixedToViewport { false };
    uint32_t m_id { 0 };
};

}

#endif // TextureMapperLayer_h
