using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;


public static class Vector2Extensions
{
    public static float AngleOffAroundAxis(this Vector3 v, Vector3 forward, Vector3 axis)
    {
        Vector3 right = Vector3.Cross(axis, forward).normalized;
        forward = Vector3.Cross(right, axis).normalized;
        return Mathf.Atan2(Vector3.Dot(v, right), Vector3.Dot(v, forward)) * Mathf.Rad2Deg;
    }
    public static float AngleBetweenVector2(this Vector2 vec1, Vector2 vec2)
    {
        Vector2 diference = vec2 - vec1;
        float sign = (vec2.y < vec1.y) ? -1.0f : 1.0f;
        return Vector2.Angle(Vector2.right, diference) * sign;
    }
    public static float AngleSingle(this Vector2 from, Vector2 to)
    {
        return Mathf.Acos(Mathf.Clamp(Vector2.Dot(from.normalized, to.normalized), -1f, 1f)) * 57.29578f;
    }
    public static Vector2 ToVector2(this Vector3 vector) => new Vector2(vector.x, vector.y);
    public static Vector3 ToVector3(this Vector2 vector) => new Vector3(vector.x, vector.y);


    public static Vector3 DirectionFromAngle(this float angleInDegree)
    => new Vector3(Mathf.Sin(angleInDegree * Mathf.Deg2Rad), -Mathf.Cos(angleInDegree * Mathf.Deg2Rad));
    public static Vector2 AngleVector2(float angle)
    {
        return new Vector2(Mathf.Cos(angle * Mathf.Deg2Rad), Mathf.Sin(angle * Mathf.Deg2Rad));
    }

    public static void OrthoNormalize(ref Vector2 vec1, ref Vector2 vec2)
    {
        var u1 = vec1;
        var e1 = new Vector2((u1.x) / Mathf.Sqrt(u1.x * u1.x), (u1.y) / Mathf.Sqrt(u1.y * u1.y));
        var u2 = vec2 - ((u1 * vec2) / u1 * u1) * u1;
        var e2 = new Vector2(u2.x / (Mathf.Sqrt(u2.x * u2.x)), (u2.y / (Mathf.Sqrt(u2.y * u2.y))));
        vec1 = e1;
        vec2 = e2;
    }
    public static Vector2 ClampTo(this Vector2 vector2, float xMin, float xMax, float yMin, float yMax)
    {
        if (vector2.x < xMin)
            vector2.x = xMin;
        else if (vector2.x > xMax)
            vector2.x = xMax;
        if (vector2.y < yMin)
            vector2.y = yMin;
        else if (vector2.y > yMax)
            vector2.y = yMax;
        return vector2;
    }
    public static Vector2 ClampTo(this Vector2 vector2, Vector2 Min, Vector2 Max)
    {
        return ClampTo(vector2, Min.x, Max.x, Min.y, Max.y);
    }
}
