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

#include "include/core/SkContourMeasure.h"
#include "include/core/SkPathBuilder.h"
#include "modules/skottie/src/SkottieJson.h"
#include "modules/skottie/src/SkottieValue.h"
#include "modules/skottie/src/animator/Animator.h"
#include "modules/skottie/src/animator/KeyframeAnimator.h"

#include <cmath>

namespace skottie::internal {

namespace  {

// Spatial 2D specialization: stores SkV2s and optional contour interpolators externally.
class Vec2KeyframeAnimator final : public KeyframeAnimator {
public:
    struct SpatialValue {
        Vec2Value               v2;
        sk_sp<SkContourMeasure> cmeasure;
    };

    Vec2KeyframeAnimator(std::vector<Keyframe> kfs, std::vector<SkCubicMap> cms,
                         std::vector<SpatialValue> vs, Vec2Value* vec_target, float* rot_target)
        : INHERITED(std::move(kfs), std::move(cms))
        , fValues(std::move(vs))
        , fVecTarget(vec_target)
        , fRotTarget(rot_target) {}

private:
    StateChanged update(const Vec2Value& new_vec_value, const Vec2Value& new_tan_value) {
        auto changed = (new_vec_value != *fVecTarget);
        *fVecTarget = new_vec_value;

        if (fRotTarget) {
            const auto new_rot_value = SkRadiansToDegrees(std::atan2(new_tan_value.y,
                                                                     new_tan_value.x));
            changed |= new_rot_value != *fRotTarget;
            *fRotTarget = new_rot_value;
        }

        return changed;
    }

    StateChanged onSeek(float t) override {
        auto get_lerp_info = [this](float t) {
            auto lerp_info = this->getLERPInfo(t);

            // When tracking rotation/orientation, the last keyframe requires special handling:
            // it doesn't store any spatial information but it is expected to maintain the
            // previous orientation (per AE semantics).
            //
            // The easiest way to achieve this is to actually swap with the previous keyframe,
            // with an adjusted weight of 1.
            const auto vidx = lerp_info.vrec0.idx;
            if (fRotTarget && vidx == fValues.size() - 1 && vidx > 0) {
                SkASSERT(!fValues[vidx].cmeasure);
                SkASSERT(lerp_info.vrec1.idx == vidx);

                // Change LERPInfo{0, SIZE - 1, SIZE - 1}
                // to     LERPInfo{1, SIZE - 2, SIZE - 1}
                lerp_info.weight = 1;
                lerp_info.vrec0  = {vidx - 1};

                // This yields equivalent lerp results because keyframed values are contiguous
                // i.e frame[n-1].end_val == frame[n].start_val.
            }

            return lerp_info;
        };

        const auto lerp_info = get_lerp_info(t);

        const auto& v0 = fValues[lerp_info.vrec0.idx];
        if (v0.cmeasure) {
            // Spatial keyframe: the computed weight is relative to the interpolation path
            // arc length.
            SkPoint  pos;
            SkVector tan;
            if (v0.cmeasure->getPosTan(lerp_info.weight * v0.cmeasure->length(), &pos, &tan)) {
                return this->update({ pos.fX, pos.fY }, {tan.fX, tan.fY});
            }
        }

        const auto& v1 = fValues[lerp_info.vrec1.idx];
        const auto tan = v1.v2 - v0.v2;

        return this->update(Lerp(v0.v2, v1.v2, lerp_info.weight), tan);
    }

    const std::vector<Vec2KeyframeAnimator::SpatialValue> fValues;
    Vec2Value*                      fVecTarget;
    float*                          fRotTarget;

    using INHERITED = KeyframeAnimator;
};

class Vec2ExpressionAnimator final : public Animator {
public:
    Vec2ExpressionAnimator(sk_sp<ExpressionEvaluator<std::vector<float>>> expression_evaluator,
        Vec2Value* target_value)
        : fExpressionEvaluator(std::move(expression_evaluator))
        , fTarget(target_value) {}

private:

    StateChanged onSeek(float t) override {
        auto old_value = *fTarget;

        std::vector<float> result = fExpressionEvaluator->evaluate(t);
        fTarget->x = result.size() > 0 ? result[0] : 0;
        fTarget->y = result.size() > 1 ? result[1] : 0;

        return *fTarget != old_value;
    }

    sk_sp<ExpressionEvaluator<std::vector<float>>> fExpressionEvaluator;
    Vec2Value* fTarget;
};

class Vec2AnimatorBuilder final : public AnimatorBuilder {
    public:
        Vec2AnimatorBuilder(Vec2Value* vec_target, float* rot_target)
            : INHERITED(Keyframe::Value::Type::kIndex)
            , fVecTarget(vec_target)
            , fRotTarget(rot_target) {}

        sk_sp<KeyframeAnimator> makeFromKeyframes(const AnimationBuilder& abuilder,
                                     const skjson::ArrayValue& jkfs) override {
            SkASSERT(jkfs.size() > 0);

            fValues.reserve(jkfs.size());
            if (!this->parseKeyframes(abuilder, jkfs)) {
                return nullptr;
            }
            fValues.shrink_to_fit();

            return sk_sp<Vec2KeyframeAnimator>(
                        new Vec2KeyframeAnimator(std::move(fKFs),
                                                 std::move(fCMs),
                                                 std::move(fValues),
                                                 fVecTarget,
                                                 fRotTarget));
        }

        sk_sp<Animator> makeFromExpression(ExpressionManager& em, const char* expr) override {
            sk_sp<ExpressionEvaluator<std::vector<SkScalar>>> expression_evaluator =
                em.createArrayExpressionEvaluator(expr);
            return sk_make_sp<Vec2ExpressionAnimator>(expression_evaluator, fVecTarget);
        }

        bool parseValue(const AnimationBuilder&, const skjson::Value& jv) const override {
            return Parse(jv, fVecTarget);
        }

    private:
        void backfill_spatial(const Vec2KeyframeAnimator::SpatialValue& val) {
            SkASSERT(!fValues.empty());
            auto& prev_val = fValues.back();
            SkASSERT(!prev_val.cmeasure);

            if (val.v2 == prev_val.v2) {
                // spatial interpolation only make sense for noncoincident values
                return;
            }

            // Check whether v0 and v1 have the same direction AND ||v0||>=||v1||
            auto check_vecs = [](const SkV2& v0, const SkV2& v1) {
                const auto v0_len2 = v0.lengthSquared(),
                           v1_len2 = v1.lengthSquared();

                // check magnitude
                if (v0_len2 < v1_len2) {
                    return false;
                }

                // v0, v1 have the same direction iff dot(v0,v1) = ||v0||*||v1||
                // <=>    dot(v0,v1)^2 = ||v0||^2 * ||v1||^2
                const auto dot = v0.dot(v1);
                return SkScalarNearlyEqual(dot * dot, v0_len2 * v1_len2);
            };

            if (check_vecs(val.v2 - prev_val.v2, fTo) &&
                check_vecs(prev_val.v2 - val.v2, fTi)) {
                // Both control points lie on the [prev_val..val] segment
                //   => we can power-reduce the Bezier "curve" to a straight line.
                return;
            }

            // Finally, this looks like a legitimate spatial keyframe.
            SkPathBuilder p;
            p.moveTo (prev_val.v2.x        , prev_val.v2.y);
            p.cubicTo(prev_val.v2.x + fTo.x, prev_val.v2.y + fTo.y,
                           val.v2.x + fTi.x,      val.v2.y + fTi.y,
                           val.v2.x,              val.v2.y);
            prev_val.cmeasure = SkContourMeasureIter(p.detach(), false).next();
        }

        bool parseKFValue(const AnimationBuilder&,
                          const skjson::ObjectValue& jkf,
                          const skjson::Value& jv,
                          Keyframe::Value* v) override {
            Vec2KeyframeAnimator::SpatialValue val;
            if (!Parse(jv, &val.v2)) {
                return false;
            }

            if (fPendingSpatial) {
                this->backfill_spatial(val);
            }

            // Track the last keyframe spatial tangents (checked on next parseValue).
            fTi             = ParseDefault<SkV2>(jkf["ti"], {0,0});
            fTo             = ParseDefault<SkV2>(jkf["to"], {0,0});
            fPendingSpatial = fTi != SkV2{0,0} || fTo != SkV2{0,0};

            if (fValues.empty() || val.v2 != fValues.back().v2 || fPendingSpatial) {
                fValues.push_back(std::move(val));
            }

            v->idx = SkToU32(fValues.size() - 1);

            return true;
        }

        std::vector<Vec2KeyframeAnimator::SpatialValue> fValues;
        Vec2Value*                fVecTarget; // required
        float*                    fRotTarget; // optional
        SkV2                      fTi{0,0},
                                  fTo{0,0};
        bool                      fPendingSpatial = false;

        using INHERITED = AnimatorBuilder;
    };

} // namespace

bool AnimatablePropertyContainer::bindAutoOrientable(const AnimationBuilder& abuilder,
                                                     const skjson::ObjectValue* jprop,
                                                     Vec2Value* v, float* orientation) {
    if (!jprop) {
        return false;
    }

    if (!ParseDefault<bool>((*jprop)["s"], false)) {
        // Regular (static or keyframed) 2D value.
        Vec2AnimatorBuilder builder(v, orientation);
        return this->bindImpl(abuilder, jprop, builder);
    }

    // Separate-dimensions vector value: each component is animated independently.
    bool boundX = this->bind(abuilder, (*jprop)["x"], &v->x);
    bool boundY = this->bind(abuilder, (*jprop)["y"], &v->y);
    return boundX || boundY;
}

template <>
bool AnimatablePropertyContainer::bind<Vec2Value>(const AnimationBuilder& abuilder,
                                                  const skjson::ObjectValue* jprop,
                                                  Vec2Value* v) {
    return this->bindAutoOrientable(abuilder, jprop, v, nullptr);
}

} // namespace skottie::internal
