/*
 * Copyright 2022 Rive
 */

#include "rive/math/math_types.hpp"
#include "rive/math/raw_path_utils.hpp"
#include <cmath>

// just putting a sane limit, the particular value not important.
constexpr int MAX_LINE_SEGMENTS = 100;

// (a+c)/2 - (a+2b+c)/4)
//  a/4 - b/2 + c/4
// d = |a - 2b + c|/4
// count = sqrt(d / tol)
//
int rive::computeApproximatingQuadLineSegments(const rive::Vec2D pts[3], float invTolerance) {
    auto diff = pts[0] - rive::two(pts[1]) + pts[2];
    float d = diff.length();
    float count = sqrtf(d * invTolerance * 0.25f);
    return std::max(1, std::min((int)std::ceil(count), MAX_LINE_SEGMENTS));
}

int rive::computeApproximatingCubicLineSegments(const rive::Vec2D pts[4], float invTolerance) {
    auto abc = pts[0] - pts[1] - pts[1] + pts[2];
    auto bcd = pts[1] - pts[2] - pts[2] + pts[3];
    float dx = std::max(std::abs(abc.x), std::abs(bcd.x));
    float dy = std::max(std::abs(abc.y), std::abs(bcd.y));
    float d = Vec2D{dx, dy}.length();
    // count = sqrt(3*d / 4*tol)
    float count = sqrtf(d * invTolerance * 0.75f);
    return std::max(1, std::min((int)std::ceil(count), MAX_LINE_SEGMENTS));
}

// Extract subsets

void rive::quad_subdivide(const rive::Vec2D src[3], float t, rive::Vec2D dst[5]) {
    assert(t >= 0 && t <= 1);
    auto ab = lerp(src[0], src[1], t);
    auto bc = lerp(src[1], src[2], t);
    dst[0] = src[0];
    dst[1] = ab;
    dst[2] = lerp(ab, bc, t);
    dst[3] = bc;
    dst[4] = src[2];
}

void rive::cubic_subdivide(const rive::Vec2D src[4], float t, rive::Vec2D dst[7]) {
    assert(t >= 0 && t <= 1);
    auto ab = lerp(src[0], src[1], t);
    auto bc = lerp(src[1], src[2], t);
    auto cd = lerp(src[2], src[3], t);
    auto abc = lerp(ab, bc, t);
    auto bcd = lerp(bc, cd, t);
    dst[0] = src[0];
    dst[1] = ab;
    dst[2] = abc;
    dst[3] = lerp(abc, bcd, t);
    dst[4] = bcd;
    dst[5] = cd;
    dst[6] = src[3];
}

void rive::line_extract(const rive::Vec2D src[2], float startT, float endT, rive::Vec2D dst[2]) {
    assert(startT <= endT);
    assert(startT >= 0 && endT <= 1);

    dst[0] = lerp(src[0], src[1], startT);
    dst[1] = lerp(src[0], src[1], endT);
}

void rive::quad_extract(const rive::Vec2D src[3], float startT, float endT, rive::Vec2D dst[3]) {
    assert(startT <= endT);
    assert(startT >= 0 && endT <= 1);

    rive::Vec2D tmp[5];
    if (startT == 0 && endT == 1) {
        std::copy(src, src + 3, dst);
    } else if (startT == 0) {
        rive::quad_subdivide(src, endT, tmp);
        std::copy(tmp, tmp + 3, dst);
    } else if (endT == 1) {
        rive::quad_subdivide(src, startT, tmp);
        std::copy(tmp + 2, tmp + 5, dst);
    } else {
        assert(endT > 0);
        rive::quad_subdivide(src, endT, tmp);
        rive::Vec2D tmp2[5];
        rive::quad_subdivide(tmp, startT / endT, tmp2);
        std::copy(tmp2 + 2, tmp2 + 5, dst);
    }
}

void rive::cubic_extract(const rive::Vec2D src[4], float startT, float endT, rive::Vec2D dst[4]) {
    assert(startT <= endT);
    assert(startT >= 0 && endT <= 1);

    rive::Vec2D tmp[7];
    if (startT == 0 && endT == 1) {
        std::copy(src, src + 4, dst);
    } else if (startT == 0) {
        rive::cubic_subdivide(src, endT, tmp);
        std::copy(tmp, tmp + 4, dst);
    } else if (endT == 1) {
        rive::cubic_subdivide(src, startT, tmp);
        std::copy(tmp + 3, tmp + 7, dst);
    } else {
        assert(endT > 0);
        rive::cubic_subdivide(src, endT, tmp);
        rive::Vec2D tmp2[7];
        rive::cubic_subdivide(tmp, startT / endT, tmp2);
        std::copy(tmp2 + 3, tmp2 + 7, dst);
    }
}
