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

#include "include/core/SkPath.h"
#include "include/core/SkSpan.h"

#include <optional>
#include <vector>

namespace {

template <typename T> bool span_equal(SkSpan<T> a, SkSpan<T> b) {
    if (a.size() != b.size()) {
        return false;
    }
    if (a.empty()) {
        return true;
    }
    return (a.data() == b.data()) || std::equal(a.begin(), a.end(), b.begin());
}

SkPoint operator*(float s, SkPoint p) {
    return {
        p.fX * s,
        p.fY * s
    };
}

SkPoint lerp(SkPoint from, SkPoint to, float t) {
    return from + t * (to - from);
}

// These can be copy/pasted into Chrome / Android
// - CanInterpolate()
// - Interpolate()
//
// That would allow us to remove the associated SkPath methods.
//
// Note: they require no private access to SkPath internals, and are not used/called by
//       anthing in Skia.

/**
 *  Returns true if the two paths can be interpolated.
 *
 *  Returns true iff the paths have the same verbs and conicWeights,
 *  and the same number of points.
 */
bool CanInterpolate(const SkPath& from, const SkPath& to) {
    return from.points().size() == to.points().size() &&
           span_equal(from.verbs(), to.verbs()) &&
           span_equal(from.conicWeights(), to.conicWeights());
}

/**
 *  Return a path whose points are lineraly interpolated between from and to,
 *  using t (typically between 0 and 1).
 *
 *  (logically) newPoint = (1 - t) * fromPoint + t * toPoint
 *
 *  The result has the same fillType as the 'from' path.
 *
 *  If the two paths are not interpolatable, this returns {}.
 */
std::optional<SkPath> Interpolate(const SkPath& from, const SkPath& to, float t) {
    if (!CanInterpolate(from, to)) {
        return {};
    }

    // note, if from and to have different fill-types, that's up to the client to deal with.
    const SkPathFillType fillType = from.getFillType();

    const SkSpan<const SkPoint> fromPts = from.points(),
                                  toPts = to.points();

    std::vector<SkPoint> dst(fromPts.size());

    for (size_t i = 0; i < fromPts.size(); ++i) {
        dst[i] = lerp(fromPts[i], toPts[i], t);
    }
    return SkPath::Raw({dst.data(), dst.size()}, from.verbs(), from.conicWeights(), fillType);
}

} // namespace

///////////////////////////////////////////////////////////////////////////////////////////////

bool SkPath::isInterpolatable(const SkPath& compare) const {
    return CanInterpolate(*this, compare);
}

SkPath SkPath::makeInterpolate(const SkPath& ending, SkScalar weight) const {
    return Interpolate(*this, ending, 1 - weight).value_or(SkPath());
}

bool SkPath::interpolate(const SkPath& ending, SkScalar weight, SkPath* out) const {
    if (auto result = Interpolate(*this, ending, 1 - weight)) {
        *out = *result;
        return true;
    }
    return false;
}
