Vector
using Autodesk.DesignScript.Interfaces;
using Autodesk.DesignScript.Runtime;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
namespace Autodesk.DesignScript.Geometry
{
    public class Vector : DesignScriptEntity
    {
        internal IVectorEntity VectorEntity => HostImpl as IVectorEntity;
        [Scaling()]
        public double X {
            get {
                return VectorEntity.get_X() * DesignScriptEntity.scaleFactor;
            }
        }
        [Scaling()]
        public double Y {
            get {
                return VectorEntity.get_Y() * DesignScriptEntity.scaleFactor;
            }
        }
        [Scaling()]
        public double Z {
            get {
                return VectorEntity.get_Z() * DesignScriptEntity.scaleFactor;
            }
        }
        [Scaling()]
        public double Length {
            get {
                return VectorEntity.get_Length() * DesignScriptEntity.scaleFactor;
            }
        }
        internal Vector(IVectorEntity host, bool persist)
            : base(host, persist)
        {
        }
        public override string ToString()
        {
            string[] obj = new string[9] {
                "Vector(X = ",
                null,
                null,
                null,
                null,
                null,
                null,
                null,
                null
            };
            double num = X;
            obj[1] = num.ToString(GeometryExtension.DoublePrintFormat, CultureInfo.InvariantCulture);
            obj[2] = ", Y = ";
            num = Y;
            obj[3] = num.ToString(GeometryExtension.DoublePrintFormat, CultureInfo.InvariantCulture);
            obj[4] = ", Z = ";
            num = Z;
            obj[5] = num.ToString(GeometryExtension.DoublePrintFormat, CultureInfo.InvariantCulture);
            obj[6] = ", Length = ";
            num = Length;
            obj[7] = num.ToString(GeometryExtension.DoublePrintFormat, CultureInfo.InvariantCulture);
            obj[8] = ")";
            return string.Concat(obj);
        }
        protected override bool Equals(DesignScriptEntity other)
        {
            if (base.Equals(other))
                return true;
            Vector vector = other as Vector;
            if (vector == null)
                return false;
            double num = vector.X;
            if (num.Equals(X)) {
                num = vector.Y;
                if (num.Equals(Y)) {
                    num = vector.Z;
                    return num.Equals(Z);
                }
            }
            return false;
        }
        protected override int ComputeHashCode()
        {
            int num = 17;
            int num2 = num * 23;
            double num3 = X;
            num = num2 + num3.GetHashCode();
            int num4 = num * 23;
            num3 = Y;
            num = num4 + num3.GetHashCode();
            int num5 = num * 23;
            num3 = Z;
            return num5 + num3.GetHashCode();
        }
        internal static Vector Wrap(IVectorEntity host, bool persist = true)
        {
            if (host == null)
                return null;
            return new Vector(host, persist);
        }
        internal static Vector[] Wrap(IVectorEntity[] hosts, bool persist = true)
        {
            return (from x in hosts
            select Wrap(x, persist)).ToArray();
        }
        internal static Vector[][] Wrap(IVectorEntity[][] hosts, bool persist = true)
        {
            return (from x in hosts
            select Wrap(x, persist)).ToArray();
        }
        internal static IVectorEntity[][] Unwrap(Vector[][] o)
        {
            return (from x in o
            select Unwrap(x)).ToArray();
        }
        internal static IVectorEntity[] Unwrap(Vector[] o)
        {
            return (from x in o
            select Unwrap(x)).ToArray();
        }
        internal static IVectorEntity[] Unwrap(IEnumerable<Vector> o)
        {
            return (from x in o
            select Unwrap(x)).ToArray();
        }
        internal static IVectorEntity Unwrap(Vector o)
        {
            return o?.VectorEntity;
        }
        public static Vector ByCoordinates([Scaling()] double x = 0, [Scaling()] double y = 0, [Scaling()] double z = 0)
        {
            DesignScriptEntity.CheckArgsForAsmExtents(new List<double> {
                x,
                y,
                z
            });
            x /= DesignScriptEntity.scaleFactor;
            y /= DesignScriptEntity.scaleFactor;
            z /= DesignScriptEntity.scaleFactor;
            return Wrap(HostFactory.Factory.VectorByCoordinates(x, y, z), true);
        }
        public static Vector ByCoordinates([Scaling()] double x = 0, [Scaling()] double y = 0, [Scaling()] double z = 0, bool normalized = false)
        {
            DesignScriptEntity.CheckArgsForAsmExtents(new List<double> {
                x,
                y,
                z
            });
            if (normalized) {
                double num = Math.Sqrt(x * x + y * y + z * z);
                if (num > 1E-05) {
                    x /= num;
                    y /= num;
                    z /= num;
                }
            }
            x /= DesignScriptEntity.scaleFactor;
            y /= DesignScriptEntity.scaleFactor;
            z /= DesignScriptEntity.scaleFactor;
            return Wrap(HostFactory.Factory.VectorByCoordinates(x, y, z), true);
        }
        public static Vector ByTwoPoints(Point start, Point end)
        {
            return Wrap(HostFactory.Factory.VectorByTwoPoints(Point.Unwrap(start), Point.Unwrap(end)), true);
        }
        [Scaling()]
        public static Vector XAxis()
        {
            return Wrap(HostFactory.Factory.VectorXAxis(), true).Scale(1 / DesignScriptEntity.scaleFactor);
        }
        [Scaling()]
        public static Vector YAxis()
        {
            return Wrap(HostFactory.Factory.VectorYAxis(), true).Scale(1 / DesignScriptEntity.scaleFactor);
        }
        [Scaling()]
        public static Vector ZAxis()
        {
            return Wrap(HostFactory.Factory.VectorZAxis(), true).Scale(1 / DesignScriptEntity.scaleFactor);
        }
        public Point AsPoint()
        {
            return Point.Wrap(VectorEntity.AsPoint(), true);
        }
        public Vector Reverse()
        {
            return Wrap(VectorEntity.Reverse(), true);
        }
        public Vector Add(Vector vectorToAdd)
        {
            return Wrap(VectorEntity.Add(Unwrap(vectorToAdd)), true);
        }
        public Vector Subtract(Vector vectorToSubtract)
        {
            return Wrap(VectorEntity.Subtract(Unwrap(vectorToSubtract)), true);
        }
        [Scaling()]
        public Vector Cross(Vector cross)
        {
            return Wrap(VectorEntity.Cross(Unwrap(cross)).Scale(DesignScriptEntity.scaleFactor), true);
        }
        [Scaling()]
        public double Dot(Vector vec)
        {
            return VectorEntity.Dot(Unwrap(vec)) * DesignScriptEntity.scaleFactor * DesignScriptEntity.scaleFactor;
        }
        [Scaling()]
        public Vector Normalized()
        {
            return Wrap(VectorEntity.Normalized(), true).Scale(1 / DesignScriptEntity.scaleFactor);
        }
        public bool IsParallel(Vector otherVector)
        {
            return VectorEntity.IsParallel(Unwrap(otherVector));
        }
        public bool IsAlmostEqualTo(Vector otherVector)
        {
            return VectorEntity.IsAlmostEqualTo(Unwrap(otherVector));
        }
        public Vector Transform(CoordinateSystem coordinateSystem)
        {
            return Wrap(VectorEntity.Transform(CoordinateSystem.Unwrap(coordinateSystem)), true);
        }
        public Vector Rotate(Vector axis, double degrees = 0)
        {
            return Wrap(VectorEntity.Rotate(Unwrap(axis), degrees), true);
        }
        public Vector Rotate(Plane plane, double degrees = 0)
        {
            return Wrap(VectorEntity.Rotate(Plane.Unwrap(plane), degrees), true);
        }
        public Vector Scale(double scale_factor = 1)
        {
            return Wrap(VectorEntity.Scale(scale_factor), true);
        }
        public Vector Scale(double xScaleFactor = 1, double yScaleFactor = 1, double zScaleFactor = 1)
        {
            return Wrap(VectorEntity.Scale(xScaleFactor, yScaleFactor, zScaleFactor), true);
        }
        public double AngleWithVector(Vector otherVector)
        {
            return VectorEntity.AngleWithVector(Unwrap(otherVector));
        }
        [SupressImportIntoVM]
        [Obsolete("This method is deprecated and will be removed in a future version of Dynamo.Use AngleWithVector instead")]
        public double AngleBetween(Vector otherVector)
        {
            return VectorEntity.AngleBetween(Unwrap(otherVector));
        }
        public double AngleAboutAxis(Vector otherVector, Vector rotationAxis)
        {
            return VectorEntity.AngleAboutAxis(Unwrap(otherVector), Unwrap(rotationAxis));
        }
        [SupressImportIntoVM]
        [Obsolete("This method is deprecated and will be removed in a future version of Dynamo. Use AngleAboutAxis instead")]
        public double AngleBetween(Vector otherVector, Vector rotationAxis)
        {
            return VectorEntity.AngleBetween(Unwrap(otherVector), Unwrap(rotationAxis));
        }
        [SupressImportIntoVM]
        public static Vector FromJson(string json)
        {
            return Wrap(HostFactory.Factory.VectorFromJson(json, DesignScriptEntity.scaleFactor), true);
        }
        [SupressImportIntoVM]
        public string ToJson()
        {
            return HostImpl.ToJson(DesignScriptEntity.scaleFactor);
        }
    }
}
            