/*
 * Copyright 2019 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "modules/skottie/src/effects/Effects.h"

#include "include/core/SkCanvas.h"
#include "include/core/SkPictureRecorder.h"
#include "include/core/SkShader.h"
#include "include/effects/SkGradientShader.h"
#include "include/private/base/SkTPin.h"
#include "modules/skottie/src/Adapter.h"
#include "modules/skottie/src/SkottieValue.h"
#include "modules/sksg/include/SkSGRenderNode.h"
#include "src/utils/SkJSON.h"

#include <cmath>

namespace skottie {
namespace internal {

namespace  {

// AE motion tile effect semantics
// (https://helpx.adobe.com/after-effects/using/stylize-effects.html#motion_tile_effect):
//
//   - the full content of the layer is mapped to a tile: tile_center, tile_width, tile_height
//
//   - tiles are repeated in both dimensions to fill the output area: output_width, output_height
//
//   - tiling mode is either kRepeat (default) or kMirror (when mirror_edges == true)
//
//   - for a non-zero phase, alternating vertical columns (every other column) are offset by
//     the specified amount
//
//   - when horizontal_phase is true, the phase is applied to horizontal rows instead of columns
//
class TileRenderNode final : public sksg::CustomRenderNode {
public:
    TileRenderNode(const SkSize& size, sk_sp<sksg::RenderNode> layer)
        : INHERITED({std::move(layer)})
        , fLayerSize(size) {}

    SG_ATTRIBUTE(TileCenter     , SkPoint , fTileCenter     )
    SG_ATTRIBUTE(TileWidth      , SkScalar, fTileW          )
    SG_ATTRIBUTE(TileHeight     , SkScalar, fTileH          )
    SG_ATTRIBUTE(OutputWidth    , SkScalar, fOutputW        )
    SG_ATTRIBUTE(OutputHeight   , SkScalar, fOutputH        )
    SG_ATTRIBUTE(Phase          , SkScalar, fPhase          )
    SG_ATTRIBUTE(MirrorEdges    , bool    , fMirrorEdges    )
    SG_ATTRIBUTE(HorizontalPhase, bool    , fHorizontalPhase)

protected:
    const RenderNode* onNodeAt(const SkPoint&) const override { return nullptr; } // no hit-testing

    SkRect onRevalidate(sksg::InvalidationController* ic, const SkMatrix& ctm) override {
        // Re-record the layer picture if needed.
        if (!fLayerPicture || this->hasChildrenInval()) {
            SkASSERT(this->children().size() == 1ul);
            const auto& layer = this->children()[0];

            layer->revalidate(ic, ctm);

            SkPictureRecorder recorder;
            layer->render(recorder.beginRecording(fLayerSize.width(), fLayerSize.height()));
            fLayerPicture = recorder.finishRecordingAsPicture();
        }

        // tileW and tileH use layer size percentage units.
        const auto tileW = SkTPin(fTileW, 0.0f, 100.0f) * 0.01f * fLayerSize.width(),
                   tileH = SkTPin(fTileH, 0.0f, 100.0f) * 0.01f * fLayerSize.height();
        const auto tile_size = SkSize::Make(std::max(tileW, 1.0f),
                                            std::max(tileH, 1.0f));
        const auto tile  = SkRect::MakeXYWH(fTileCenter.fX - 0.5f * tile_size.width(),
                                            fTileCenter.fY - 0.5f * tile_size.height(),
                                            tile_size.width(),
                                            tile_size.height());

        const auto layerShaderMatrix = SkMatrix::RectToRect(
                    SkRect::MakeWH(fLayerSize.width(), fLayerSize.height()), tile);

        const auto tm = fMirrorEdges ? SkTileMode::kMirror : SkTileMode::kRepeat;
        auto layer_shader = fLayerPicture->makeShader(tm, tm, SkFilterMode::kLinear,
                                                      &layerShaderMatrix, nullptr);

        if (fPhase && layer_shader && tile.isFinite()) {
            // To implement AE phase semantics, we construct a mask shader for the pass-through
            // rows/columns.  We then draw the layer content through this mask, and then again
            // through the inverse mask with a phase shift.
            const auto phase_vec = fHorizontalPhase
                    ? SkVector::Make(tile.width(), 0)
                    : SkVector::Make(0, tile.height());
            const auto phase_shift = SkVector::Make(phase_vec.fX, phase_vec.fY)
                                     * std::fmod(fPhase * (1/360.0f), 1);
            const auto phase_shader_matrix = SkMatrix::Translate(phase_shift.x(), phase_shift.y());

            // The mask is generated using a step gradient shader, spanning 2 x tile width/height,
            // and perpendicular to the phase vector.
            static constexpr SkColor colors[] = { 0xffffffff, 0x00000000 };
            static constexpr SkScalar   pos[] = {       0.5f,       0.5f };

            const SkPoint pts[] = {{ tile.x(), tile.y() },
                                   { tile.x() + 2 * (tile.width()  - phase_vec.fX),
                                     tile.y() + 2 * (tile.height() - phase_vec.fY) }};

            auto mask_shader = SkGradientShader::MakeLinear(pts, colors, pos,
                                                            std::size(colors),
                                                            SkTileMode::kRepeat);

            // First drawing pass: in-place masked layer content.
            fMainPassShader  = SkShaders::Blend(SkBlendMode::kSrcIn , mask_shader, layer_shader);
            // Second pass: phased-shifted layer content, with an inverse mask.
            fPhasePassShader = SkShaders::Blend(SkBlendMode::kSrcOut, mask_shader, layer_shader)
                               ->makeWithLocalMatrix(phase_shader_matrix);
        } else {
            fMainPassShader  = std::move(layer_shader);
            fPhasePassShader = nullptr;
        }

        // outputW and outputH also use layer size percentage units.
        const auto outputW = fOutputW * 0.01f * fLayerSize.width(),
                   outputH = fOutputH * 0.01f * fLayerSize.height();

        return SkRect::MakeXYWH((fLayerSize.width()  - outputW) * 0.5f,
                                (fLayerSize.height() - outputH) * 0.5f,
                                outputW, outputH);
    }

    void onRender(SkCanvas* canvas, const RenderContext* ctx) const override {
        // AE allow one of the tile dimensions to collapse, but not both.
        if (this->bounds().isEmpty() || (fTileW <= 0 && fTileH <= 0)) {
            return;
        }

        SkPaint paint;
        paint.setAntiAlias(true);

        if (ctx) {
            // apply any pending paint effects via the shader paint
            ctx->modulatePaint(canvas->getLocalToDeviceAs3x3(), &paint);
        }

        paint.setShader(fMainPassShader);
        canvas->drawRect(this->bounds(), paint);

        if (fPhasePassShader) {
            paint.setShader(fPhasePassShader);
            canvas->drawRect(this->bounds(), paint);
        }
    }

private:
    const SkSize fLayerSize;

    SkPoint  fTileCenter      = { 0, 0 };
    SkScalar fTileW           = 1,
             fTileH           = 1,
             fOutputW         = 1,
             fOutputH         = 1,
             fPhase           = 0;
    bool     fMirrorEdges     = false;
    bool     fHorizontalPhase = false;

    // These are computed/cached on revalidation.
    sk_sp<SkPicture> fLayerPicture;      // cached picture for layer content
    sk_sp<SkShader>  fMainPassShader,    // shader for the main tile(s)
                     fPhasePassShader;   // shader for the phased tile(s)

    using INHERITED = sksg::CustomRenderNode;
};

class MotionTileAdapter final : public DiscardableAdapterBase<MotionTileAdapter, TileRenderNode> {
public:
    MotionTileAdapter(const skjson::ArrayValue& jprops,
                      sk_sp<sksg::RenderNode> layer,
                      const AnimationBuilder& abuilder,
                      const SkSize& layer_size)
        : INHERITED(sk_make_sp<TileRenderNode>(layer_size, std::move(layer))) {

        enum : size_t {
                      kTileCenter_Index = 0,
                       kTileWidth_Index = 1,
                      kTileHeight_Index = 2,
                     kOutputWidth_Index = 3,
                    kOutputHeight_Index = 4,
                     kMirrorEdges_Index = 5,
                           kPhase_Index = 6,
            kHorizontalPhaseShift_Index = 7,
        };

        EffectBinder(jprops, abuilder, this)
            .bind(          kTileCenter_Index, fTileCenter     )
            .bind(           kTileWidth_Index, fTileW          )
            .bind(          kTileHeight_Index, fTileH          )
            .bind(         kOutputWidth_Index, fOutputW        )
            .bind(        kOutputHeight_Index, fOutputH        )
            .bind(         kMirrorEdges_Index, fMirrorEdges    )
            .bind(               kPhase_Index, fPhase          )
            .bind(kHorizontalPhaseShift_Index, fHorizontalPhase);
    }

private:
    void onSync() override {
        const auto& tiler = this->node();

        tiler->setTileCenter({fTileCenter.x, fTileCenter.y});
        tiler->setTileWidth (fTileW);
        tiler->setTileHeight(fTileH);
        tiler->setOutputWidth (fOutputW);
        tiler->setOutputHeight(fOutputH);
        tiler->setPhase(fPhase);
        tiler->setMirrorEdges(SkToBool(fMirrorEdges));
        tiler->setHorizontalPhase(SkToBool(fHorizontalPhase));
    }

    Vec2Value   fTileCenter      = {0,0};
    ScalarValue fTileW           = 1,
                fTileH           = 1,
                fOutputW         = 1,
                fOutputH         = 1,
                fMirrorEdges     = 0,
                fPhase           = 0,
                fHorizontalPhase = 0;

    using INHERITED = DiscardableAdapterBase<MotionTileAdapter, TileRenderNode>;
};

}  // namespace

sk_sp<sksg::RenderNode> EffectBuilder::attachMotionTileEffect(const skjson::ArrayValue& jprops,
                                                              sk_sp<sksg::RenderNode> layer) const {
    return fBuilder->attachDiscardableAdapter<MotionTileAdapter>(jprops,
                                                                 std::move(layer),
                                                                 *fBuilder,
                                                                 fLayerSize);
}

} // namespace internal
} // namespace skottie
