#include "rive/animation/cubic_interpolator.hpp"
#include "rive/artboard.hpp"
#include "rive/importers/artboard_importer.hpp"
#include "rive/importers/import_stack.hpp"
#include <cmath>

using namespace rive;

const int NewtonIterations = 4;
const float NewtonMinSlope = 0.001f;
const float SubdivisionPrecision = 0.0000001f;
const int SubdivisionMaxIterations = 10;

// Returns x(t) given t, x1, and x2, or y(t) given t, y1, and y2.
static float calcBezier(float aT, float aA1, float aA2)
{
    return (((1.0f - 3.0f * aA2 + 3.0f * aA1) * aT +
             (3.0f * aA2 - 6.0f * aA1)) *
                aT +
            (3.0f * aA1)) *
           aT;
}

// Returns dx/dt given t, x1, and x2, or dy/dt given t, y1, and y2.
static float getSlope(float aT, float aA1, float aA2)
{
    return 3.0f * (1.0f - 3.0f * aA2 + 3.0f * aA1) * aT * aT +
           2.0f * (3.0f * aA2 - 6.0f * aA1) * aT + (3.0f * aA1);
}

StatusCode CubicInterpolator::onAddedDirty(CoreContext* context)
{
    for (int i = 0; i < SplineTableSize; ++i)
    {
        m_Values[i] = calcBezier(i * SampleStepSize, x1(), x2());
    }
    return StatusCode::Ok;
}

float CubicInterpolator::getT(float x) const
{
    float intervalStart = 0.0f;
    int currentSample = 1;
    int lastSample = SplineTableSize - 1;

    for (; currentSample != lastSample && m_Values[currentSample] <= x;
         ++currentSample)
    {
        intervalStart += SampleStepSize;
    }
    --currentSample;

    // Interpolate to provide an initial guess for t
    float dist = (x - m_Values[currentSample]) /
                 (m_Values[currentSample + 1] - m_Values[currentSample]);
    float guessForT = intervalStart + dist * SampleStepSize;

    float _x1 = x1(), _x2 = x2();

    float initialSlope = getSlope(guessForT, _x1, _x2);
    if (initialSlope >= NewtonMinSlope)
    {
        for (int i = 0; i < NewtonIterations; ++i)
        {
            float currentSlope = getSlope(guessForT, _x1, _x2);
            if (currentSlope == 0.0f)
            {
                return guessForT;
            }
            float currentX = calcBezier(guessForT, _x1, _x2) - x;
            guessForT -= currentX / currentSlope;
        }
        return guessForT;
    }
    else if (initialSlope == 0.0f)
    {
        return guessForT;
    }
    else
    {
        float aB = intervalStart + SampleStepSize;
        float currentX, currentT;
        int i = 0;
        do
        {
            currentT = intervalStart + (aB - intervalStart) / 2.0f;
            currentX = calcBezier(currentT, _x1, _x2) - x;
            if (currentX > 0.0f)
            {
                aB = currentT;
            }
            else
            {
                intervalStart = currentT;
            }
        } while (std::abs(currentX) > SubdivisionPrecision &&
                 ++i < SubdivisionMaxIterations);
        return currentT;
    }
}

float CubicInterpolator::transform(float mix) const
{
    return calcBezier(getT(mix), y1(), y2());
}

StatusCode CubicInterpolator::import(ImportStack& importStack)
{
    auto artboardImporter =
        importStack.latest<ArtboardImporter>(ArtboardBase::typeKey);
    if (artboardImporter == nullptr)
    {
        return StatusCode::MissingObject;
    }
    artboardImporter->addComponent(this);
    return Super::import(importStack);
}