using UnityEngine;

namespace pdinklag
{
    public static class Vector2Extensions
    {
        /// <summary>
        /// Tests whether the vector lies inside the given polygon.
        /// </summary>
        /// <param name="v">the vector in question</param>
        /// <param name="poly">the polygon points</param>
        /// <returns>true iff the vector lies inside the polygon</returns>
        public static bool InsidePolygon(this Vector2 v, params Vector2[] poly)
        {
            var j = poly.Length - 1;
            var inside = false;
            for (int i = 0; i < poly.Length; j = i++)
            {
                var pi = poly[i];
                var pj = poly[j];
                if (
                    ((pi.y <= v.y && v.y < pj.y) || (pj.y <= v.y && v.y < pi.y)) &&
                    (v.x < (pj.x - pi.x) * (v.y - pi.y) / (pj.y - pi.y) + pi.x)
                )
                {
                    inside = !inside;
                }
            }
            return inside;
        }

        /// <summary>
        /// Creates a 3D vector with this vector's components as X and Z.
        /// </summary>
        /// <param name="v">the input vector</param>
        /// <param name="y">the vector's Y value</param>
        /// <returns>the 3D XZ vector</returns>
        public static Vector3 AsXZ(this Vector2 v, float y = 0)
        {
            return new Vector3(v.x, y, v.y);
        }

        /// <summary>
        /// Tests if any of the vector's components is not zero.
        /// </summary>
        /// <param name="v">the input vector</param>
        /// <returns>true if non-zero</returns>
        public static bool IsZero(this Vector2 v)
        {
            return v.x == 0.0f && v.y == 0.0f;
        }

        /// <summary>
        /// Tests if any of the vector's components is not zero.
        /// </summary>
        /// <param name="v">the input vector</param>
        /// <returns>true if non-zero</returns>
        public static bool IsNonZero(this Vector2 v)
        {
            return v.x != 0.0f || v.y != 0.0f;
        }

        public static Quaternion AsLookYawRotation(this Vector2 v)
        {
            return MathExt.YawRotation(Mathf.Atan2(v.x, v.y));
        }

        public static Vector2 InvertComponents(this Vector2 v) => new(1.0f / v.x, 1.0f / v.y);
    }
}
