#include <GeneratorNode/GeneratorNode.hpp>
#include <Perlin1D/Perlin1D.hpp>
#include <Utilities/Utilities.hpp>
#include <cmath>

float Perlin1D::fade(float t)
{
    return t * t * t * (t * (t * 6 - 15) + 10);
}

float Perlin1D::lerp(float a, float b, float t)
{
    return a + t * (b - a);
}

float Perlin1D::getControlPoint(uint64_t t)
{
    return unormFromBits(genNode[t]) * 2.0f - 1.0f;
}

Perlin1D::Perlin1D(GeneratorNode node) : genNode(node) {}

float Perlin1D::sample(uint64_t x, float offset)
{
    float g0 = getControlPoint(x);
    float g1 = getControlPoint(x + 1);

    float d0 = offset;
    float d1 = 1.0f - offset;

    float influence0 = g0 * d0;
    float influence1 = g1 * d1;

    float t = fade(d0);

    return lerp(influence0, influence1, t);
}