/*
 * 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 "modules/skottie/src/animator/VectorKeyframeAnimator.h"

#include "include/core/SkTypes.h"
#include "include/private/SkTPin.h"
#include "include/private/SkVx.h"
#include "modules/skottie/src/SkottieJson.h"
#include "modules/skottie/src/SkottieValue.h"
#include "modules/skottie/src/animator/Animator.h"
#include "src/core/SkSafeMath.h"

#include <algorithm>
#include <cstring>

namespace skottie {

// Parses an array of exact size.
static bool parse_array(const skjson::ArrayValue* ja, float* a, size_t count) {
    if (!ja || ja->size() != count) {
        return false;
    }

    for (size_t i = 0; i < count; ++i) {
        if (!Parse((*ja)[i], a + i)) {
            return false;
        }
    }

    return true;
}

VectorValue::operator SkV3() const {
    // best effort to turn this into a 3D point
    return SkV3 {
        this->size() > 0 ? (*this)[0] : 0,
        this->size() > 1 ? (*this)[1] : 0,
        this->size() > 2 ? (*this)[2] : 0,
    };
}

VectorValue::operator SkColor() const {
    return static_cast<SkColor4f>(*this).toSkColor();
}

VectorValue::operator SkColor4f() const {
    // best effort to turn a vector into a color
    const auto r = this->size() > 0 ? SkTPin((*this)[0], 0.0f, 1.0f) : 0,
               g = this->size() > 1 ? SkTPin((*this)[1], 0.0f, 1.0f) : 0,
               b = this->size() > 2 ? SkTPin((*this)[2], 0.0f, 1.0f) : 0,
               a = this->size() > 3 ? SkTPin((*this)[3], 0.0f, 1.0f) : 1;

    return { r, g, b, a };
}

namespace internal {
namespace {

// Vector specialization - stores float vector values (of same length) in consolidated/contiguous
// storage.  Keyframe records hold the storage offset for each value:
//
// fStorage: [     vec0     ][     vec1     ] ... [     vecN     ]
//            <-  vec_len ->  <-  vec_len ->       <-  vec_len ->
//
//           ^               ^                    ^
// fKFs[]: .idx            .idx       ...       .idx
//
class VectorKeyframeAnimator final : public KeyframeAnimator {
public:
    VectorKeyframeAnimator(std::vector<Keyframe> kfs,
                           std::vector<SkCubicMap> cms,
                           std::vector<float> storage,
                           size_t vec_len,
                           std::vector<float>* target_value)
        : INHERITED(std::move(kfs), std::move(cms))
        , fStorage(std::move(storage))
        , fVecLen(vec_len)
        , fTarget(target_value) {

        // Resize the target value appropriately.
        fTarget->resize(fVecLen);
    }

private:
    StateChanged onSeek(float t) override {
        const auto& lerp_info = this->getLERPInfo(t);

        SkASSERT(lerp_info.vrec0.idx + fVecLen <= fStorage.size());
        SkASSERT(lerp_info.vrec1.idx + fVecLen <= fStorage.size());
        SkASSERT(fTarget->size() == fVecLen);

        const auto* v0  = fStorage.data() + lerp_info.vrec0.idx;
        const auto* v1  = fStorage.data() + lerp_info.vrec1.idx;
              auto* dst = fTarget->data();

        const auto is_constant = lerp_info.vrec0.equals(lerp_info.vrec1,
                                                        Keyframe::Value::Type::kIndex);
        if (is_constant) {
            if (0 != std::memcmp(dst, v0, fVecLen * sizeof(float))) {
                std::copy(v0, v0 + fVecLen, dst);
                return true;
            }
            return false;
        }

        size_t count = fVecLen;
        bool changed = false;

        while (count >= 4) {
            const auto old_val = skvx::float4::Load(dst),
                       new_val = Lerp(skvx::float4::Load(v0),
                                      skvx::float4::Load(v1),
                                      lerp_info.weight);

            changed |= any(new_val != old_val);
            new_val.store(dst);

            v0    += 4;
            v1    += 4;
            dst   += 4;
            count -= 4;
        }

        while (count-- > 0) {
            const auto new_val = Lerp(*v0++, *v1++, lerp_info.weight);

            changed |= (new_val != *dst);
            *dst++ = new_val;
        }

        return changed;
    }

    const std::vector<float> fStorage;
    const size_t             fVecLen;

    std::vector<float>*      fTarget;

    using INHERITED = KeyframeAnimator;
};

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

private:

    StateChanged onSeek(float t) override {
        std::vector<float> result = fExpressionEvaluator->evaluate(t);
        bool changed = false;
        for (size_t i = 0; i < fTarget->size(); i++) {
            // Use 0 as a default if the result is too small.
            float val = i >= result.size() ? 0 : result[i];
            if (!SkScalarNearlyEqual(val, (*fTarget)[i])) {
                changed = true;
            }
            (*fTarget)[i] = val;
        }

        return changed;
    }

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

VectorAnimatorBuilder::VectorAnimatorBuilder(std::vector<float>* target,
                                                             VectorLenParser  parse_len,
                                                             VectorDataParser parse_data)
    : INHERITED(Keyframe::Value::Type::kIndex)
    , fParseLen(parse_len)
    , fParseData(parse_data)
    , fTarget(target) {}

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

    // peek at the first keyframe value to find our vector length
    const skjson::ObjectValue* jkf0 = jkfs[0];
    if (!jkf0 || !fParseLen((*jkf0)["s"], &fVecLen)) {
        return nullptr;
    }

    SkSafeMath safe;
    // total elements: vector length x number vectors
    const auto total_size = safe.mul(fVecLen, jkfs.size());

    // we must be able to store all offsets in Keyframe::Value::idx (uint32_t)
    if (!safe || !SkTFitsIn<uint32_t>(total_size)) {
        return nullptr;
    }
    fStorage.resize(total_size);

    if (!this->parseKeyframes(abuilder, jkfs)) {
        return nullptr;
    }

    // parseKFValue() might have stored fewer vectors thanks to tail-deduping.
    SkASSERT(fCurrentVec <= jkfs.size());
    fStorage.resize(fCurrentVec * fVecLen);
    fStorage.shrink_to_fit();

    return sk_sp<VectorKeyframeAnimator>(
                new VectorKeyframeAnimator(std::move(fKFs),
                                           std::move(fCMs),
                                           std::move(fStorage),
                                           fVecLen,
                                           fTarget));
}

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

bool VectorAnimatorBuilder::parseValue(const AnimationBuilder&,
                                               const skjson::Value& jv) const {
    size_t vec_len;
    if (!this->fParseLen(jv, &vec_len)) {
        return false;
    }

    fTarget->resize(vec_len);
    return fParseData(jv, vec_len, fTarget->data());
}

bool VectorAnimatorBuilder::parseKFValue(const AnimationBuilder&,
                                                 const skjson::ObjectValue&,
                                                 const skjson::Value& jv,
                                                 Keyframe::Value* kfv) {
    auto offset = fCurrentVec * fVecLen;
    SkASSERT(offset + fVecLen <= fStorage.size());

    if (!fParseData(jv, fVecLen, fStorage.data() + offset)) {
        return false;
    }

    SkASSERT(!fCurrentVec || offset >= fVecLen);
    // compare with previous vector value
    if (fCurrentVec > 0 && !memcmp(fStorage.data() + offset,
                                   fStorage.data() + offset - fVecLen,
                                   fVecLen * sizeof(float))) {
        // repeating value -> use prev offset (dedupe)
        offset -= fVecLen;
    } else {
        // new value -> advance the current index
        fCurrentVec += 1;
    }

    // Keyframes record the storage-offset for a given vector value.
    kfv->idx = SkToU32(offset);

    return true;
}

template <>
bool AnimatablePropertyContainer::bind<VectorValue>(const AnimationBuilder& abuilder,
                                                    const skjson::ObjectValue* jprop,
                                                    VectorValue* v) {
    if (!jprop) {
        return false;
    }

    if (!ParseDefault<bool>((*jprop)["s"], false)) {
        // Regular (static or keyframed) vector value.
        VectorAnimatorBuilder builder(
                    v,
                    // Len parser.
                    [](const skjson::Value& jv, size_t* len) -> bool {
                        if (const skjson::ArrayValue* ja = jv) {
                            *len = ja->size();
                            return true;
                        }
                        return false;
                    },
                    // Data parser.
                    [](const skjson::Value& jv, size_t len, float* data) {
                        return parse_array(jv, data, len);
                    });

        return this->bindImpl(abuilder, jprop, builder);
    }

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

} // namespace internal
} // namespace skottie
