/*
 * Copyright (C) 2018 Metrological Group B.V.
 * Copyright (C) 2018 Igalia S.L.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above
 *    copyright notice, this list of conditions and the following
 *    disclaimer in the documentation and/or other materials provided
 *    with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#pragma once

#include "Color.h"
#include "FilterOperations.h"
#include "FloatPoint.h"
#include "FloatPoint3D.h"
#include "FloatRect.h"
#include "FloatSize.h"
#include "NicosiaAnimatedBackingStoreClient.h"
#include "NicosiaAnimation.h"
#include "NicosiaSceneIntegration.h"
#include "ScrollTypes.h"
#include "TransformationMatrix.h"
#include <wtf/Function.h>
#include <wtf/Lock.h>
#include <wtf/ThreadSafeRefCounted.h>
#include <wtf/TypeCasts.h>

namespace Nicosia {

class PlatformLayer : public ThreadSafeRefCounted<PlatformLayer> {
public:
    virtual ~PlatformLayer();

    virtual bool isCompositionLayer() const { return false; }
    virtual bool isContentLayer() const { return false; }

    using LayerID = uint64_t;
    LayerID id() const { return m_id; }

    void setSceneIntegration(RefPtr<SceneIntegration>&& sceneIntegration)
    {
        Locker locker { m_state.lock };
        m_state.sceneIntegration = WTFMove(sceneIntegration);
    }

    std::unique_ptr<SceneIntegration::UpdateScope> createUpdateScope()
    {
        Locker locker { m_state.lock };
        if (m_state.sceneIntegration)
            return m_state.sceneIntegration->createUpdateScope();
        return nullptr;
    }

protected:
    explicit PlatformLayer(uint64_t);

    uint64_t m_id;

    struct {
        Lock lock;
        RefPtr<SceneIntegration> sceneIntegration;
    } m_state;
};

class ContentLayer;
class BackingStore;
class ImageBacking;

class CompositionLayer : public PlatformLayer {
public:
    class Impl {
    public:
        using Factory = Function<std::unique_ptr<Impl>(uint64_t, CompositionLayer&)>;

        virtual ~Impl();
        virtual bool isTextureMapperImpl() const { return false; }
    };

    static Ref<CompositionLayer> create(uint64_t id, const Impl::Factory& factory)
    {
        return adoptRef(*new CompositionLayer(id, factory));
    }
    virtual ~CompositionLayer();
    bool isCompositionLayer() const override { return true; }

    Impl& impl() const { return *m_impl; }

    struct LayerState {
        struct Delta {
            Delta() = default;

            union {
                struct {
                    bool positionChanged : 1;
                    bool anchorPointChanged : 1;
                    bool sizeChanged : 1;
                    bool boundsOriginChanged : 1;
                    bool transformChanged : 1;
                    bool childrenTransformChanged : 1;
                    bool contentsRectChanged : 1;
                    bool contentsTilingChanged : 1;
                    bool contentsClippingRectChanged : 1;
                    bool opacityChanged : 1;
                    bool solidColorChanged : 1;
                    bool filtersChanged : 1;
                    bool backdropFiltersChanged : 1;
                    bool backdropFiltersRectChanged : 1;
                    bool animationsChanged : 1;
                    bool childrenChanged : 1;
                    bool maskChanged : 1;
                    bool replicaChanged : 1;
                    bool flagsChanged : 1;
                    bool contentLayerChanged : 1;
                    bool backingStoreChanged : 1;
                    bool imageBackingChanged : 1;
                    bool animatedBackingStoreClientChanged : 1;
                    bool repaintCounterChanged : 1;
                    bool debugBorderChanged : 1;
                    bool scrollingNodeChanged : 1;
                };
                uint32_t value { 0 };
            };
        } delta;

        struct Flags {
            Flags()
                : contentsVisible(true)
                , backfaceVisible(true)
            { }

            union {
                struct {
                    bool contentsOpaque : 1;
                    bool drawsContent : 1;
                    bool contentsVisible : 1;
                    bool backfaceVisible : 1;
                    bool masksToBounds : 1;
                    bool preserves3D : 1;
                };
                uint32_t value { 0 };
            };
        } flags;

        WebCore::FloatPoint position;
        WebCore::FloatPoint3D anchorPoint;
        WebCore::FloatSize size;
        WebCore::FloatPoint boundsOrigin;

        WebCore::TransformationMatrix transform;
        WebCore::TransformationMatrix childrenTransform;

        WebCore::FloatRect contentsRect;
        WebCore::FloatSize contentsTilePhase;
        WebCore::FloatSize contentsTileSize;
        WebCore::FloatRoundedRect contentsClippingRect;

        float opacity { 0 };
        WebCore::Color solidColor;

        WebCore::FilterOperations filters;
        // FIXME: Despite the name, this implementation is not
        // TextureMapper-specific. Should be renamed when necessary.
        Animations animations;

        Vector<RefPtr<CompositionLayer>> children;
        RefPtr<CompositionLayer> replica;
        RefPtr<CompositionLayer> mask;
        RefPtr<CompositionLayer> backdropLayer;
        WebCore::FloatRoundedRect backdropFiltersRect;

        RefPtr<ContentLayer> contentLayer;
        RefPtr<BackingStore> backingStore;
        RefPtr<ImageBacking> imageBacking;
        RefPtr<AnimatedBackingStoreClient> animatedBackingStoreClient;

        struct RepaintCounter {
            unsigned count { 0 };
            bool visible { false };
        } repaintCounter;
        struct DebugBorder {
            WebCore::Color color;
            float width { 0 };
            bool visible { false };
        } debugBorder;

        WebCore::ScrollingNodeID scrollingNodeID { 0 };
    };

    template<typename T>
    void updateState(const T& functor)
    {
        Locker locker { PlatformLayer::m_state.lock };
        functor(m_state.pending);
    }

    template<typename T>
    void flushState(const T& functor)
    {
        Locker locker { PlatformLayer::m_state.lock };
        auto& pending = m_state.pending;
        auto& staging = m_state.staging;

        staging.delta.value |= pending.delta.value;

        if (pending.delta.positionChanged)
            staging.position = pending.position;
        if (pending.delta.anchorPointChanged)
            staging.anchorPoint = pending.anchorPoint;
        if (pending.delta.sizeChanged)
            staging.size = pending.size;
        if (pending.delta.boundsOriginChanged)
            staging.boundsOrigin = pending.boundsOrigin;

        if (pending.delta.transformChanged)
            staging.transform = pending.transform;
        if (pending.delta.childrenTransformChanged)
            staging.childrenTransform = pending.childrenTransform;

        if (pending.delta.contentsRectChanged)
            staging.contentsRect = pending.contentsRect;
        if (pending.delta.contentsTilingChanged) {
            staging.contentsTilePhase = pending.contentsTilePhase;
            staging.contentsTileSize = pending.contentsTileSize;
        }
        if (pending.delta.contentsClippingRectChanged)
            staging.contentsClippingRect = pending.contentsClippingRect;

        if (pending.delta.opacityChanged)
            staging.opacity = pending.opacity;
        if (pending.delta.solidColorChanged)
            staging.solidColor = pending.solidColor;

        if (pending.delta.filtersChanged)
            staging.filters = pending.filters;
        if (pending.delta.backdropFiltersChanged)
            staging.backdropLayer = pending.backdropLayer;
        if (pending.delta.backdropFiltersRectChanged)
            staging.backdropFiltersRect = pending.backdropFiltersRect;
        if (pending.delta.animationsChanged)
            staging.animations = pending.animations;

        if (pending.delta.childrenChanged)
            staging.children = pending.children;
        if (pending.delta.maskChanged)
            staging.mask = pending.mask;
        if (pending.delta.replicaChanged)
            staging.replica = pending.replica;

        if (pending.delta.flagsChanged)
            staging.flags.value = pending.flags.value;

        if (pending.delta.repaintCounterChanged)
            staging.repaintCounter = pending.repaintCounter;
        if (pending.delta.debugBorderChanged)
            staging.debugBorder = pending.debugBorder;

        if (pending.delta.scrollingNodeChanged)
            staging.scrollingNodeID = pending.scrollingNodeID;

        if (pending.delta.backingStoreChanged)
            staging.backingStore = pending.backingStore;
        if (pending.delta.contentLayerChanged)
            staging.contentLayer = pending.contentLayer;
        if (pending.delta.imageBackingChanged)
            staging.imageBacking = pending.imageBacking;
        if (pending.delta.animatedBackingStoreClientChanged)
            staging.animatedBackingStoreClient = pending.animatedBackingStoreClient;

        pending.delta = { };

        functor(staging);
    }

    template<typename T>
    void commitState(const T& functor)
    {
        Locker locker { PlatformLayer::m_state.lock };
        m_state.committed = m_state.staging;
        m_state.staging.delta = { };

        functor(m_state.committed);
    }

    template<typename T>
    void accessPending(const T& functor)
    {
        Locker locker { PlatformLayer::m_state.lock };
        functor(m_state.pending);
    }

    template<typename T>
    void accessCommitted(const T& functor)
    {
        Locker locker { PlatformLayer::m_state.lock };
        functor(m_state.committed);
    }

private:
    CompositionLayer(uint64_t, const Impl::Factory&);

    std::unique_ptr<Impl> m_impl;

    struct {
        LayerState pending;
        LayerState staging;
        LayerState committed;
    } m_state;
};

class ContentLayer : public PlatformLayer {
public:
    class Impl {
    public:
        using Factory = Function<std::unique_ptr<Impl>(ContentLayer&)>;

        virtual ~Impl();
        virtual bool isTextureMapperImpl() const { return false; }
    };

    static Ref<ContentLayer> create(const Impl::Factory& factory)
    {
        return adoptRef(*new ContentLayer(factory));
    }
    virtual ~ContentLayer();
    bool isContentLayer() const override { return true; }

    Impl& impl() const { return *m_impl; }

private:
    ContentLayer(const Impl::Factory&);

    std::unique_ptr<Impl> m_impl;
};

class BackingStore : public ThreadSafeRefCounted<BackingStore> {
public:
    class Impl {
    public:
        using Factory = Function<std::unique_ptr<Impl>(BackingStore&)>;

        virtual ~Impl();
        virtual bool isTextureMapperImpl() const { return false; }
    };

    static Ref<BackingStore> create(const Impl::Factory& factory)
    {
        return adoptRef(*new BackingStore(factory));
    }
    virtual ~BackingStore();

    Impl& impl() const { return *m_impl; }

private:
    BackingStore(const Impl::Factory&);

    std::unique_ptr<Impl> m_impl;
};

class ImageBacking : public ThreadSafeRefCounted<ImageBacking> {
public:
    class Impl {
    public:
        using Factory = Function<std::unique_ptr<Impl>(ImageBacking&)>;

        virtual ~Impl();
        virtual bool isTextureMapperImpl() const { return false; }
    };

    static Ref<ImageBacking> create(const Impl::Factory& factory)
    {
        return adoptRef(*new ImageBacking(factory));
    }
    virtual ~ImageBacking();

    Impl& impl() const { return *m_impl; }

private:
    ImageBacking(const Impl::Factory&);

    std::unique_ptr<Impl> m_impl;
};

} // namespace Nicosia

#define SPECIALIZE_TYPE_TRAITS_NICOSIA_PLATFORMLAYER(ToClassName, predicate) \
    SPECIALIZE_TYPE_TRAITS_BEGIN(Nicosia::ToClassName) \
    static bool isType(const Nicosia::PlatformLayer& layer) { return layer.predicate; } \
    SPECIALIZE_TYPE_TRAITS_END()

SPECIALIZE_TYPE_TRAITS_NICOSIA_PLATFORMLAYER(CompositionLayer, isCompositionLayer());
SPECIALIZE_TYPE_TRAITS_NICOSIA_PLATFORMLAYER(ContentLayer, isContentLayer());

#define SPECIALIZE_TYPE_TRAITS_NICOSIA_COMPOSITIONLAYER_IMPL(ToClassName, predicate) \
    SPECIALIZE_TYPE_TRAITS_BEGIN(Nicosia::ToClassName) \
    static bool isType(const Nicosia::CompositionLayer::Impl& impl) { return impl.predicate; } \
    SPECIALIZE_TYPE_TRAITS_END()

#define SPECIALIZE_TYPE_TRAITS_NICOSIA_CONTENTLAYER_IMPL(ToClassName, predicate) \
    SPECIALIZE_TYPE_TRAITS_BEGIN(Nicosia::ToClassName) \
    static bool isType(const Nicosia::ContentLayer::Impl& impl) { return impl.predicate; } \
    SPECIALIZE_TYPE_TRAITS_END()

#define SPECIALIZE_TYPE_TRAITS_NICOSIA_BACKINGSTORE_IMPL(ToClassName, predicate) \
    SPECIALIZE_TYPE_TRAITS_BEGIN(Nicosia::ToClassName) \
    static bool isType(const Nicosia::BackingStore::Impl& impl) { return impl.predicate; } \
    SPECIALIZE_TYPE_TRAITS_END()

#define SPECIALIZE_TYPE_TRAITS_NICOSIA_IMAGEBACKING_IMPL(ToClassName, predicate) \
    SPECIALIZE_TYPE_TRAITS_BEGIN(Nicosia::ToClassName) \
    static bool isType(const Nicosia::ImageBacking::Impl& impl) { return impl.predicate; } \
    SPECIALIZE_TYPE_TRAITS_END()
