/*
 * 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 "modules/skottie/src/SkottieAdapter.h"
#include "modules/skottie/src/SkottieValue.h"
#include "modules/sksg/include/SkSGRenderEffect.h"
#include "src/utils/SkJSON.h"

namespace skottie {
namespace internal {

namespace  {

class DropShadowAdapter final : public SkNVRefCnt<DropShadowAdapter> {
public:
    explicit DropShadowAdapter(sk_sp<sksg::DropShadowImageFilter> dropShadow)
        : fDropShadow(std::move(dropShadow)) {
        SkASSERT(fDropShadow);
    }

    ADAPTER_PROPERTY(Color     , SkColor , SK_ColorBLACK)
    ADAPTER_PROPERTY(Opacity   , SkScalar,           255)
    ADAPTER_PROPERTY(Direction , SkScalar,             0)
    ADAPTER_PROPERTY(Distance  , SkScalar,             0)
    ADAPTER_PROPERTY(Softness  , SkScalar,             0)
    ADAPTER_PROPERTY(ShadowOnly, bool    ,         false)

private:
    void apply() {
        // fColor -> RGB, fOpacity -> A
        fDropShadow->setColor(SkColorSetA(fColor, SkTPin(SkScalarRoundToInt(fOpacity), 0, 255)));

        // The offset is specified in terms of a bearing angle + distance.
        SkScalar rad = SkDegreesToRadians(90 - fDirection);
        fDropShadow->setOffset(SkVector::Make( fDistance * SkScalarCos(rad),
                                              -fDistance * SkScalarSin(rad)));

        // Close enough to AE.
        static constexpr SkScalar kSoftnessToSigmaFactor = 0.3f;
        const auto sigma = fSoftness * kSoftnessToSigmaFactor;
        fDropShadow->setSigma(SkVector::Make(sigma, sigma));

        fDropShadow->setMode(fShadowOnly ? sksg::DropShadowImageFilter::Mode::kShadowOnly
                                         : sksg::DropShadowImageFilter::Mode::kShadowAndForeground);
    }

    const sk_sp<sksg::DropShadowImageFilter> fDropShadow;
};

} // anonymous ns

sk_sp<sksg::RenderNode> EffectBuilder::attachDropShadowEffect(const skjson::ArrayValue& jprops,
                                                              sk_sp<sksg::RenderNode> layer) const {
    enum : size_t {
        kShadowColor_Index = 0,
        kOpacity_Index     = 1,
        kDirection_Index   = 2,
        kDistance_Index    = 3,
        kSoftness_Index    = 4,
        kShadowOnly_Index  = 5,
    };

    auto shadow_effect  = sksg::DropShadowImageFilter::Make();
    auto shadow_adapter = sk_make_sp<DropShadowAdapter>(shadow_effect);

    fBuilder->bindProperty<VectorValue>(GetPropValue(jprops, kShadowColor_Index),
        [shadow_adapter](const VectorValue& c) {
            shadow_adapter->setColor(ValueTraits<VectorValue>::As<SkColor>(c));
        });
    fBuilder->bindProperty<ScalarValue>(GetPropValue(jprops, kOpacity_Index),
        [shadow_adapter](const ScalarValue& o) {
            shadow_adapter->setOpacity(o);
        });
    fBuilder->bindProperty<ScalarValue>(GetPropValue(jprops, kDirection_Index),
        [shadow_adapter](const ScalarValue& d) {
            shadow_adapter->setDirection(d);
        });
    fBuilder->bindProperty<ScalarValue>(GetPropValue(jprops, kDistance_Index),
        [shadow_adapter](const ScalarValue& d) {
            shadow_adapter->setDistance(d);
        });
    fBuilder->bindProperty<ScalarValue>(GetPropValue(jprops, kSoftness_Index),
        [shadow_adapter](const ScalarValue& s) {
            shadow_adapter->setSoftness(s);
        });
    fBuilder->bindProperty<ScalarValue>(GetPropValue(jprops, kShadowOnly_Index),
        [shadow_adapter](const ScalarValue& s) {
            shadow_adapter->setShadowOnly(SkToBool(s));
        });

    return sksg::ImageFilterEffect::Make(std::move(layer), std::move(shadow_effect));
}

} // namespace internal
} // namespace skottie
