using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Common
{
    public static class Random
    {
        // http://stackoverflow.com/questions/5817490/implementing-box-mueller-random-number-generator-in-c-sharp
        public static float GaussianStandardDist()
        {
            float u, v, S;

            do
            {
                u = (float)(2.0 * UnityEngine.Random.value - 1.0);
                v = (float)(2.0 * UnityEngine.Random.value - 1.0);
                S = u * u + v * v;
            }
            while (S >= 1.0);

            var fac = (float)Math.Sqrt(-2.0 * Math.Log(S) / S);
            return u * fac;
        }

        public static float GaussianDist(float mean, float sigma)
        {
            return (GaussianStandardDist() * sigma + mean);
        }

        public static float BoundedGaussDist(float mean, float sigma)
        {
            return BoundedGaussDist(mean, sigma, mean - 3 * sigma, mean + 3 * sigma);
        }

        public static float BoundedGaussDist(float mean, float sigma, float minValue, float maxValue)
        {
            var result = GaussianDist(mean, sigma);
            if (result >= minValue && result <= maxValue)
                return result;
            else
                return BoundedGaussDist(mean, sigma, minValue, maxValue);
        }

        // http://answers.unity3d.com/questions/421968/normal-distribution-random.html
        public static float BoundedNormalDist(float minValue, float maxValue)
        {
            var mean = (minValue + maxValue) / 2;
            var sigma = (maxValue - mean) / 3;
            return BoundedGaussDist(mean, sigma);
        }

        public static bool RandomBool()
        {
            return UnityEngine.Random.Range(0.0f, 1.0f) > 0.5f;
        }
    }
}
