using UnityEngine;

namespace pdinklag
{
    public static class MathExt
    {
        private static readonly float FWD_ANGLE = Mathf.Atan2(0, 1);

        public const float GoldenRatio = 1.61803398874989484820458683436f;
        public const float GoldenRatioInv = 0.61803398874989484820458683436779f;

        public const float SphereVolumeCoeff = (4.0f / 3.0f) * Mathf.PI;

        public static float FromToYaw(Vector3 from, Vector3 to)
        {
            return Mathf.Atan2(to.x - from.x, to.z - from.z) - FWD_ANGLE;
        }

        public static Quaternion FromToRotationXZ(Vector3 from, Vector3 to)
        {
            return YawRotation(FromToYaw(from, to));
        }

        public static Quaternion YawRotation(float yawRad)
        {
            yawRad *= 0.5f;
            var sin = Mathf.Sin(yawRad);
            var cos = Mathf.Cos(yawRad);
            return new Quaternion(0, sin, 0, cos);
        }

        /// <summary>
        /// Computes the logistic function value for the specified parameters.
        /// </summary>
        /// <param name="x">the function parameter</param>
        /// /// <param name="k">the sigmoid's steepness</param>
        /// <param name="center">the x value of the sigmoid's center</param>
        /// <param name="max">the maximum value of the sigmoid</param>
        /// <returns>the logistic function value for the specified parameters</returns>
        public static float Logistic(float x, float k, float center, float max)
        {
            return max / (1.0f + Mathf.Exp(-k * (x - center)));
        }

        /// <summary>
        /// Computes the flipped logistic function (falling instead of rising) value for the specified parameters.
        /// </summary>
        /// <param name="x">the function parameter</param>
        /// /// <param name="k">the sigmoid's steepness</param>
        /// <param name="center">the x value of the sigmoid's center</param>
        /// <param name="max">the maximum value of the sigmoid</param>
        /// <returns>the flipped logistic function value for the specified parameters</returns>
        public static float LogisticFlipped(float x, float k, float center, float max)
        {
            return max - Logistic(x, k, center, max);
        }
    }
}
