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

#ifndef SkSGGeometryEffect_DEFINED
#define SkSGGeometryEffect_DEFINED

#include "modules/sksg/include/SkSGGeometryNode.h"

#include "include/core/SkPaint.h"
#include "include/core/SkPath.h"
#include "include/effects/SkTrimPathEffect.h"
#include "modules/sksg/include/SkSGTransform.h"

namespace sksg {

/**
 * Base class for geometry effects.
 */
class GeometryEffect : public GeometryNode {
protected:
    explicit GeometryEffect(sk_sp<GeometryNode>);
    ~GeometryEffect() override;

    void onClip(SkCanvas*, bool antiAlias) const final;
    void onDraw(SkCanvas*, const SkPaint&) const final;
    bool onContains(const SkPoint&)        const final;

    SkRect onRevalidate(InvalidationController*, const SkMatrix&) final;
    SkPath onAsPath() const final;

    virtual SkPath onRevalidateEffect(const sk_sp<GeometryNode>&) = 0;

private:
    const sk_sp<GeometryNode> fChild;
    SkPath                    fPath; // transformed child cache.

    using INHERITED = GeometryNode;
};

/**
 * Apply a trim effect to the child geometry.
 */
class TrimEffect final : public GeometryEffect {
public:
    static sk_sp<TrimEffect> Make(sk_sp<GeometryNode> child) {
        return child ? sk_sp<TrimEffect>(new TrimEffect(std::move(child))) : nullptr;
    }

    SG_ATTRIBUTE(Start , SkScalar              , fStart )
    SG_ATTRIBUTE(Stop  , SkScalar              , fStop  )
    SG_ATTRIBUTE(Mode  , SkTrimPathEffect::Mode, fMode  )

private:
    explicit TrimEffect(sk_sp<GeometryNode> child) : INHERITED(std::move(child)) {}

    SkPath onRevalidateEffect(const sk_sp<GeometryNode>&) override;

    SkScalar               fStart = 0,
                           fStop  = 1;
    SkTrimPathEffect::Mode fMode  = SkTrimPathEffect::Mode::kNormal;

    using INHERITED = GeometryEffect;
};

/**
 * Apply a transform to a GeometryNode.
 */
class GeometryTransform final : public GeometryEffect {
public:
    static sk_sp<GeometryTransform> Make(sk_sp<GeometryNode> child, sk_sp<Transform> transform) {
        return child && transform
            ? sk_sp<GeometryTransform>(new GeometryTransform(std::move(child),
                                                             std::move(transform)))
            : nullptr;
    }

    ~GeometryTransform() override;

    const sk_sp<Transform>& getTransform() const { return fTransform; }

private:
    GeometryTransform(sk_sp<GeometryNode>, sk_sp<Transform>);

    SkPath onRevalidateEffect(const sk_sp<GeometryNode>&) override;

    const sk_sp<Transform> fTransform;

    using INHERITED = GeometryEffect;
};

/**
 * Apply a dash effect to the child geometry.
 *
 * Follows the same semantics as SkDashPathEffect, with one minor tweak: when the number of
 * intervals is odd, they are repeated once more to attain an even sequence (same as SVG
 * stroke-dasharray: https://www.w3.org/TR/SVG11/painting.html#StrokeDasharrayProperty).
 */
class DashEffect final : public GeometryEffect {
public:
    static sk_sp<DashEffect> Make(sk_sp<GeometryNode> child) {
        return child ? sk_sp<DashEffect>(new DashEffect(std::move(child))) : nullptr;
    }

    SG_ATTRIBUTE(Intervals, std::vector<float>, fIntervals)
    SG_ATTRIBUTE(Phase,                 float , fPhase    )

private:
    explicit DashEffect(sk_sp<GeometryNode> child) : INHERITED(std::move(child)) {}

    SkPath onRevalidateEffect(const sk_sp<GeometryNode>&) override;

    std::vector<float> fIntervals;
    float              fPhase = 0;

    using INHERITED = GeometryEffect;
};

/**
 * Apply a rounded-corner effect to the child geometry.
 */
class RoundEffect final : public GeometryEffect {
public:
    static sk_sp<RoundEffect> Make(sk_sp<GeometryNode> child) {
        return child ? sk_sp<RoundEffect>(new RoundEffect(std::move(child))) : nullptr;
    }

    SG_ATTRIBUTE(Radius, SkScalar, fRadius)

private:
    explicit RoundEffect(sk_sp<GeometryNode> child) : INHERITED(std::move(child)) {}

    SkPath onRevalidateEffect(const sk_sp<GeometryNode>&) override;

    SkScalar fRadius = 0;

    using INHERITED = GeometryEffect;
};

/**
 * Apply an offset effect to the child geometry.
 */
class OffsetEffect final : public GeometryEffect {
public:
    static sk_sp<OffsetEffect> Make(sk_sp<GeometryNode> child) {
        return child ? sk_sp<OffsetEffect>(new OffsetEffect(std::move(child))) : nullptr;
    }

    SG_ATTRIBUTE(Offset     , SkScalar     , fOffset    )
    SG_ATTRIBUTE(MiterLimit , SkScalar     , fMiterLimit)
    SG_ATTRIBUTE(Join       , SkPaint::Join, fJoin      )

private:
    explicit OffsetEffect(sk_sp<GeometryNode> child) : INHERITED(std::move(child)) {}

    SkPath onRevalidateEffect(const sk_sp<GeometryNode>&) override;

    SkScalar fOffset     = 0,
             fMiterLimit = 4;
    SkPaint::Join  fJoin = SkPaint::kMiter_Join;

    using INHERITED = GeometryEffect;
};

} // namespace sksg

#endif // SkSGGeometryEffect_DEFINED
