using UnityEngine;

public static class VectorExtensions
{
    public static Vector3 ClampTop(this Vector3 v, float maxLength)
    {
        return Vector3.ClampMagnitude(v, maxLength);
    }

    public static Vector3 ClampBottom(this Vector3 v, float minLength)
    {
        var tempMagnitude = v.magnitude;
        return v.normalized * tempMagnitude.ClampBottom(minLength);
    }

    public static float DistTo(this Vector3 v, Vector3 targetVector)
    {
        return Vector3.Distance(v, targetVector);
    }

    public static float GetAngleTo(this Vector3 v1, Vector3 v2)
    {
        var v = v2 - v1;
        return Mathf.Atan2(v.y, v.x) * Mathf.Rad2Deg;
    }

    public static Quaternion GetQAngleTo(this Vector3 v1, Vector3 v2)
    {
        var v = v2 - v1;
        var angle = Mathf.Atan2(v.y, v.x) * Mathf.Rad2Deg;
        return Quaternion.Euler(0, 0, angle);
    }

    public static float GetAngle(this Vector3 v)
    {
        return Vector3.zero.GetAngleTo(v);
    }

    public static Vector3 GetAngularOffset(this Vector3 v, float dist, float angle)
    {
        angle *= Mathf.Deg2Rad;
        return v + new Vector3(dist * Mathf.Cos(angle), dist * Mathf.Sin(angle));
    }

    public static Vector2 Rotate(this Vector2 v, float degrees)
    {
        var sin = Mathf.Sin(degrees * Mathf.Deg2Rad);
        var cos = Mathf.Cos(degrees * Mathf.Deg2Rad);

        var tx = v.x;
        var ty = v.y;
        v.x = cos * tx - sin * ty;
        v.y = sin * tx + cos * ty;
        return v;
    }

    public static Vector3 Rotate2D(this Vector3 v, float degrees)
    {
        var sin = Mathf.Sin(degrees * Mathf.Deg2Rad);
        var cos = Mathf.Cos(degrees * Mathf.Deg2Rad);

        var tx = v.x;
        var ty = v.y;
        v.x = cos * tx - sin * ty;
        v.y = sin * tx + cos * ty;
        return v;
    }

    public static Vector3 Randomize(this Vector3 v)
    {
        return new Vector3(
            Random.Range(-v.x, v.x),
            Random.Range(-v.y, v.y),
            Random.Range(-v.z, v.z));
    }

    public static Vector3 SetZ(this Vector3 v, float z)
    {
        v.z = z;
        return v;
    }

    public static Vector3 AddZ(this Vector3 v, float addZ)
    {
        v.z += addZ;
        return v;
    }

    public static Quaternion DirToRotation(this Vector3 v)
    {
        var angle = Mathf.Atan2(v.y, v.x) * Mathf.Rad2Deg;
        return Quaternion.AngleAxis(angle, Vector3.forward);
    }
}