using System;
using Godot;

namespace Cirno.Scripts.Utils;

public static class RandomStuff
{
    public static double GaussianRandom(double mean = 0.0, double stdDev = 1.0)
    {
        // Box-Muller transform
        float u1 = GD.Randf();
        float u2 = GD.Randf();

        // Ensure u1 is strictly > 0
        while (u1 <= 0f)
            u1 = GD.Randf();

        float randStdNormal = Mathf.Sqrt(-2f * Mathf.Log(u1)) * Mathf.Sin(2f * Mathf.Pi * u2);
        return mean + stdDev * randStdNormal;
    }
    
    public static float GaussianClamped(float mean, float stdDev, float min, float max)
    {
        float value;
        do
        {
            float u1 = GD.Randf();
            float u2 = GD.Randf();

            // Ensure u1 > 0 to avoid log(0)
            while (u1 <= 0f) u1 = GD.Randf();

            float randStdNormal = Mathf.Sqrt(-2f * Mathf.Log(u1)) * Mathf.Sin(2f * Mathf.Pi * u2);
            value = mean + stdDev * randStdNormal;
        }
        while (value < min || value > max); // reject out-of-bounds values

        return value;
    }
}