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

#include "src/core/SkBezierCurves.h"

#include "include/core/SkPoint.h"
#include "include/core/SkSpan.h"
#include "include/private/SkAssert.h"
#include "include/private/SkFloatingPoint.h"
#include "src/core/SkCubics.h"
#include "src/core/SkQuads.h"

#include <cstddef>

static inline double interpolate(double A, double B, double t) {
    return A + (B - A) * t;
}

std::array<double, 2> SkBezierCubic::EvalAt(const double curve[8], double t) {
    const auto in_X = [&curve](size_t n) { return curve[2*n]; };
    const auto in_Y = [&curve](size_t n) { return curve[2*n + 1]; };

    // Two semi-common fast paths
    if (t == 0) {
        return {in_X(0), in_Y(0)};
    }
    if (t == 1) {
        return {in_X(3), in_Y(3)};
    }
    // X(t) = X_0*(1-t)^3 + 3*X_1*t(1-t)^2 + 3*X_2*t^2(1-t) + X_3*t^3
    // Y(t) = Y_0*(1-t)^3 + 3*Y_1*t(1-t)^2 + 3*Y_2*t^2(1-t) + Y_3*t^3
    // Some compilers are smart enough and have sufficient registers/intrinsics to write optimal
    // code from
    //    double one_minus_t = 1 - t;
    //    double a = one_minus_t * one_minus_t * one_minus_t;
    //    double b = 3 * one_minus_t * one_minus_t * t;
    //    double c = 3 * one_minus_t * t * t;
    //    double d = t * t * t;
    // However, some (e.g. when compiling for ARM) fail to do so, so we use this form
    // to help more compilers generate smaller/faster ASM. https://godbolt.org/z/M6jG9x45c
    double one_minus_t = 1 - t;
    double one_minus_t_squared = one_minus_t * one_minus_t;
    double a = (one_minus_t_squared * one_minus_t);
    double b = 3 * one_minus_t_squared * t;
    double t_squared = t * t;
    double c = 3 * one_minus_t * t_squared;
    double d = t_squared * t;

    return {a * in_X(0) + b * in_X(1) + c * in_X(2) + d * in_X(3),
            a * in_Y(0) + b * in_Y(1) + c * in_Y(2) + d * in_Y(3)};
}

// Perform subdivision using De Casteljau's algorithm, that is, repeated linear
// interpolation between adjacent points.
void SkBezierCubic::Subdivide(const double curve[8], double t,
                              double twoCurves[14]) {
    SkASSERT(0.0 <= t && t <= 1.0);
    // We split the curve "in" into two curves "alpha" and "beta"
    const auto in_X = [&curve](size_t n) { return curve[2*n]; };
    const auto in_Y = [&curve](size_t n) { return curve[2*n + 1]; };
    const auto alpha_X = [&twoCurves](size_t n) -> double& { return twoCurves[2*n]; };
    const auto alpha_Y = [&twoCurves](size_t n) -> double& { return twoCurves[2*n + 1]; };
    const auto beta_X = [&twoCurves](size_t n) -> double& { return twoCurves[2*n + 6]; };
    const auto beta_Y = [&twoCurves](size_t n) -> double& { return twoCurves[2*n + 7]; };

    alpha_X(0) = in_X(0);
    alpha_Y(0) = in_Y(0);

    beta_X(3) = in_X(3);
    beta_Y(3) = in_Y(3);

    double x01 = interpolate(in_X(0), in_X(1), t);
    double y01 = interpolate(in_Y(0), in_Y(1), t);
    double x12 = interpolate(in_X(1), in_X(2), t);
    double y12 = interpolate(in_Y(1), in_Y(2), t);
    double x23 = interpolate(in_X(2), in_X(3), t);
    double y23 = interpolate(in_Y(2), in_Y(3), t);

    alpha_X(1) = x01;
    alpha_Y(1) = y01;

    beta_X(2) = x23;
    beta_Y(2) = y23;

    alpha_X(2) = interpolate(x01, x12, t);
    alpha_Y(2) = interpolate(y01, y12, t);

    beta_X(1) = interpolate(x12, x23, t);
    beta_Y(1) = interpolate(y12, y23, t);

    alpha_X(3) /*= beta_X(0) */ = interpolate(alpha_X(2), beta_X(1), t);
    alpha_Y(3) /*= beta_Y(0) */ = interpolate(alpha_Y(2), beta_Y(1), t);
}

std::array<double, 4> SkBezierCubic::ConvertToPolynomial(const double curve[8], bool yValues) {
    const double* offset_curve = yValues ? curve + 1 : curve;
    const auto P = [&offset_curve](size_t n) { return offset_curve[2*n]; };
    // A cubic Bézier curve is interpolated as follows:
    //  c(t) = (1 - t)^3 P_0 + 3t(1 - t)^2 P_1 + 3t^2 (1 - t) P_2 + t^3 P_3
    //       = (-P_0 + 3P_1 + -3P_2 + P_3) t^3 + (3P_0 - 6P_1 + 3P_2) t^2 +
    //         (-3P_0 + 3P_1) t + P_0
    // Where P_N is the Nth point. The second step expands the polynomial and groups
    // by powers of t. The desired output is a cubic formula, so we just need to
    // combine the appropriate points to make the coefficients.
    std::array<double, 4> results;
    results[0] = -P(0) + 3*P(1) - 3*P(2) + P(3);
    results[1] = 3*P(0) - 6*P(1) + 3*P(2);
    results[2] = -3*P(0) + 3*P(1);
    results[3] = P(0);
    return results;
}

namespace {
struct DPoint {
    DPoint(double x_, double y_) : x{x_}, y{y_} {}
    DPoint(SkPoint p) : x{p.fX}, y{p.fY} {}
    double x, y;
};

DPoint operator- (DPoint a) {
    return {-a.x, -a.y};
}

DPoint operator+ (DPoint a, DPoint b) {
    return {a.x + b.x, a.y + b.y};
}

DPoint operator- (DPoint a, DPoint b) {
    return {a.x - b.x, a.y - b.y};
}

DPoint operator* (double s, DPoint a) {
    return {s * a.x, s * a.y};
}

// Pin to 0 or 1 if within half a float ulp of 0 or 1.
double pinTRange(double t) {
    // The ULPs around 0 are tiny compared to the ULPs around 1. Shift to 1 to use the same
    // size ULPs.
    if (sk_double_to_float(t + 1.0) == 1.0f) {
        return 0.0;
    } else if (sk_double_to_float(t) == 1.0f) {
        return 1.0;
    }
    return t;
}
}  // namespace

SkSpan<const float>
SkBezierCubic::IntersectWithHorizontalLine(
        SkSpan<const SkPoint> controlPoints, float yIntercept, float* intersectionStorage) {
    SkASSERT(controlPoints.size() >= 4);
    const DPoint P0 = controlPoints[0],
                 P1 = controlPoints[1],
                 P2 = controlPoints[2],
                 P3 = controlPoints[3];

    const DPoint A =   -P0 + 3*P1 - 3*P2 + P3,
                 B =  3*P0 - 6*P1 + 3*P2,
                 C = -3*P0 + 3*P1,
                 D =    P0;

    return Intersect(A.x, B.x, C.x, D.x, A.y, B.y, C.y, D.y, yIntercept, intersectionStorage);
}

SkSpan<const float>
SkBezierCubic::Intersect(double AX, double BX, double CX, double DX,
                         double AY, double BY, double CY, double DY,
                         float toIntersect, float intersectionsStorage[3]) {
    double roots[3];
    SkSpan<double> ts = SkSpan(roots,
                               SkCubics::RootsReal(AY, BY, CY, DY - toIntersect, roots));

    size_t intersectionCount = 0;
    for (double t : ts) {
        const double pinnedT = pinTRange(t);
        if (0 <= pinnedT && pinnedT <= 1) {
            intersectionsStorage[intersectionCount++] = SkCubics::EvalAt(AX, BX, CX, DX, pinnedT);
        }
    }

    return {intersectionsStorage, intersectionCount};
}

SkSpan<const float>
SkBezierQuad::IntersectWithHorizontalLine(SkSpan<const SkPoint> controlPoints, float yIntercept,
                                          float intersectionStorage[2]) {
    SkASSERT(controlPoints.size() >= 3);
    const DPoint p0 = controlPoints[0],
                 p1 = controlPoints[1],
                 p2 = controlPoints[2];

    // Calculate A, B, C using doubles to reduce round-off error.
    const DPoint A = p0 - 2 * p1 + p2,
    // Remember we are generating the polynomial in the form A*t^2 -2*B*t + C, so the factor
    // of 2 is not needed and the term is negated. This term for a Bézier curve is usually
    // 2(p1-p0).
                 B = p0 - p1,
                 C = p0;

    return Intersect(A.x, B.x, C.x, A.y, B.y, C.y, yIntercept, intersectionStorage);
}

SkSpan<const float> SkBezierQuad::Intersect(
        double AX, double BX, double CX, double AY, double BY, double CY,
        double yIntercept, float intersectionStorage[2]) {
    auto [discriminant, r0, r1] = SkQuads::Roots(AY, BY, CY - yIntercept);

    size_t intersectionCount = 0;
    // Round the roots to the nearest float to generate the values t. Valid t's are on the
    // domain [0, 1].
    const double t0 = pinTRange(r0);
    if (0 <= t0 && t0 <= 1) {
        intersectionStorage[intersectionCount++] = SkQuads::EvalAt(AX, -2 * BX, CX, t0);
    }

    const double t1 = pinTRange(r1);
    if (0 <= t1 && t1 <= 1 && t1 != t0) {
        intersectionStorage[intersectionCount++] = SkQuads::EvalAt(AX, -2 * BX, CX, t1);
    }

    return {intersectionStorage, intersectionCount};
}

