using System;
#if UNITY_5_3_OR_NEWER
using Vector3Float = UnityEngine.Vector3;
#endif

namespace Passer.LinearAlgebra {
    public class Spherical {
        public float distance;
        public Direction direction;

        public static Spherical zero = new(0, 0, 0);
        public static Spherical forward = new(1, 0, 0);

        public Spherical(float distance, float horizontal, float vertical) {
            this.distance = distance;
            this.direction = new Direction(horizontal, vertical);
        }
        public Spherical(float distance, Direction direction) {
            this.distance = distance;
            this.direction = direction;
        }

        public static Spherical FromVector3(Vector3Float v) {
            float distance = v.magnitude;
            if (distance == 0.0f)
                return new Spherical(distance, 0, 0);
            else {
                float verticalAngle = (float)((Angle.pi / 2 - Math.Acos(v.y / distance)) * Angle.Rad2Deg);
                float horizontalAngle = (float) Math.Atan2(v.x, v.z) * Angle.Rad2Deg;
                return new Spherical(distance, horizontalAngle, verticalAngle);
            }
        }

        public Vector3Float ToVector3() {
            float verticalRad = (Angle.pi / 2) - this.direction.vertical * Angle.Deg2Rad;
            float horizontalRad = this.direction.horizontal * Angle.Deg2Rad;
            float cosVertical = (float)Math.Cos(verticalRad);
            float sinVertical = (float)Math.Sin(verticalRad);
            float cosHorizontal = (float)Math.Cos(horizontalRad);
            float sinHorizontal = (float)Math.Sin(horizontalRad);

            float x = this.distance * sinVertical * sinHorizontal;
            float y = this.distance * cosVertical;
            float z = this.distance * sinVertical * cosHorizontal;

            Vector3Float v = new Vector3Float(x, y, z);
            return v;
        }
    }
}