import { Noise } from "noisejs";
import { clampNumber } from "./Math.utils";

function _normalizeNoiseValue(value)
{
    return (value+1)*0.5;
}

/**
 * Fractal Brownian Motion
 * @param {Noise} noiseRef 
 * @param {Number} octaves 
 * @param {Number} x 
 * @param {Number} y 
 */
export function FBMSimplex2(noiseRef, octaves = 8, x, y)
{
    let value = 0;
    let freq = 1.0;
    let amplitude = 1.0;
    for (let i = 0; i < octaves; i++) {
        value += _normalizeNoiseValue(noiseRef.simplex2(x * freq, y * freq)) * amplitude;
        amplitude *= 0.35;
        freq *= 2.0;
    }
    return clampNumber(value, 0.0, 1.0);
}

/**
 * Domain Warping for FBM
 * @param {Noise} noiseRef 
 * @param {Number} x 
 * @param {Number} y 
 * @param {Number} strength 
 * @param {Number} octaves 
 */
export function DWFBMSimplex2(noiseRef, x, y, strength, octaves = 8)
{
    let q = [FBMSimplex2(noiseRef, octaves, x, y), FBMSimplex2(noiseRef, octaves, x + 5.2, y + 1.3)];
    return FBMSimplex2(noiseRef, octaves, x + q[0]*strength, y + q[1]*strength);
}