GeometryExtension
using Autodesk.DesignScript.Interfaces;
using Autodesk.DesignScript.Runtime;
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
namespace Autodesk.DesignScript.Geometry
{
    [SupressImportIntoVM]
    public static class GeometryExtension
    {
        internal static string DoublePrintFormat = "F3";
        public static readonly double PI = 3.141592653589793;
        public static bool LessThanOrEquals(double x, double y, double tolerance = 1E-06)
        {
            if (Equals(x, y, tolerance))
                return true;
            if (x < y)
                return true;
            return false;
        }
        public static bool Equals(double x, double y, double tolerance = 1E-06)
        {
            return Math.Abs(x - y) < tolerance;
        }
        public static bool EqualsTo(this double thisValue, double value)
        {
            return Equals(thisValue, value, 1E-06);
        }
        public static bool LessThanOrEqualTo(this double thisValue, double value)
        {
            if (!(thisValue < value))
                return Equals(thisValue, value, 1E-06);
            return true;
        }
        [SupressImportIntoVM]
        internal static bool EqualsTo(this IPointEntity thisValue, IPointEntity value)
        {
            if (thisValue == value)
                return true;
            if (thisValue == null || value == null)
                return false;
            if (Equals(thisValue.get_X(), value.get_X(), 1E-06) && Equals(thisValue.get_Y(), value.get_Y(), 1E-06))
                return Equals(thisValue.get_Z(), value.get_Z(), 1E-06);
            return false;
        }
        [SupressImportIntoVM]
        public static bool AreCoincident(this IPointEntity[] pts)
        {
            if (pts == null)
                return true;
            int num = pts.Length;
            for (int i = 0; i < num - 1; i++) {
                if (!pts[i].EqualsTo(pts[i + 1]))
                    return false;
            }
            return true;
        }
        public static double DegreesToRadians(double deg)
        {
            return deg * PI / 180;
        }
        public static double RadiansToDegrees(double rad)
        {
            return rad * 180 / PI;
        }
        [SupressImportIntoVM]
        public static IPointEntity[][] ToPointEntityArray(this Point[][] points, bool checkRectangular = true)
        {
            if (points == null)
                return null;
            List<IPointEntity[]> list = new List<IPointEntity[]>();
            int num = -1;
            foreach (Point[] array in points) {
                IPointEntity[] array2 = array.ConvertAll(GeometryExtension.ToEntity<Point, IPointEntity>);
                if (array2 != null && array2.Length != 0) {
                    if (checkRectangular) {
                        if (num == -1)
                            num = array2.Length;
                        if (num != array2.Length)
                            return null;
                    }
                    list.Add(array2);
                }
            }
            if (list.Count == 0)
                return null;
            return list.ToArray();
        }
        [SupressImportIntoVM]
        public static Point[][] ToPointArray(this IPointEntity[][] points, bool checkRectangular = true)
        {
            List<Point[]> list = new List<Point[]>();
            int num = -1;
            foreach (IPointEntity[] array in points) {
                Point[] array2 = array.ConvertAll((IPointEntity p) => p.ToPoint(false, null));
                if (array2 != null) {
                    if (checkRectangular) {
                        if (num == -1)
                            num = array2.Length;
                        if (num != array2.Length)
                            return null;
                    }
                    list.Add(array2);
                }
            }
            return list.ToArray();
        }
        private static GeomClass ToGeometry<GeomClass, GeomEntity>(this GeomEntity host, bool persist = false, Geometry context = null) where GeomClass : Geometry where GeomEntity : IGeometryEntity
        {
            return Geometry.Wrap((object)host, persist, context) as GeomClass;
        }
        [SupressImportIntoVM]
        internal static GEOM[] ToArray<GEOM, ENTITY>(this ENTITY[] hosts, bool persist = true, Geometry context = null) where GEOM : Geometry where ENTITY : IGeometryEntity
        {
            if (hosts == null)
                return null;
            List<GEOM> list = new List<GEOM>();
            foreach (ENTITY val in hosts) {
                if (val != null) {
                    GEOM val2 = Geometry.Wrap((object)val, persist, context) as GEOM;
                    if (val2 != null)
                        list.Add(val2);
                }
            }
            return list.ToArray();
        }
        [SupressImportIntoVM]
        public static IDesignScriptEntity ToEntity(this DesignScriptEntity data)
        {
            return data.ToEntity<DesignScriptEntity, IDesignScriptEntity>();
        }
        [SupressImportIntoVM]
        internal static ENTITY ToEntity<GEOMETRY, ENTITY>(this GEOMETRY data) where GEOMETRY : DesignScriptEntity where ENTITY : IDesignScriptEntity
        {
            if (data == null)
                return default(ENTITY);
            return (ENTITY)(object)data.HostImpl;
        }
        [SupressImportIntoVM]
        public static ICurveEntity GetCurveEntity(Curve curve, bool checkClosed)
        {
            bool isClosed = curve.IsClosed;
            if ((checkClosed & isClosed) || (!checkClosed && !isClosed))
                return curve.CurveEntity;
            return null;
        }
        internal static bool IsDisposed<T>(this T obj) where T : DesignScriptEntity
        {
            return obj?.IsDisposed ?? true;
        }
        internal static bool IsDisposed<T>(this T[] obj) where T : DesignScriptEntity
        {
            if (obj == null)
                return true;
            foreach (T obj2 in obj) {
                if (obj2.IsDisposed())
                    return true;
            }
            return false;
        }
        internal static bool IsDisposed<T>(this T[][] obj) where T : DesignScriptEntity
        {
            if (obj == null)
                return true;
            foreach (T[] obj2 in obj) {
                if (obj2.IsDisposed())
                    return true;
            }
            return false;
        }
        internal static void DisposeObject(this IDisposable obj)
        {
            obj?.Dispose();
        }
        internal static void DisposeObject<T>(ref T obj) where T : DesignScriptEntity
        {
            if (obj != null) {
                obj.Dispose();
                if (obj.IsDisposed)
                    obj = null;
            }
        }
        internal static void DisposeObject<T>(ref T[] obj) where T : DesignScriptEntity
        {
            obj.ForEach(delegate(T item) {
                GeometryExtension.DisposeObject<T>(ref item);
            });
            if (obj.IsDisposed())
                obj = null;
        }
        internal static void DisposeObject<T>(ref T[][] obj) where T : DesignScriptEntity
        {
            obj.ForEach(delegate(T[] item) {
                GeometryExtension.DisposeObject<T>(ref item);
            });
            if (obj.IsDisposed())
                obj = null;
        }
        internal static void DisposeObject(this IDisposable[] obj)
        {
            obj.ForEach(DisposeObject);
        }
        internal static void DisposeObject(this IDisposable[][] obj)
        {
            obj.ForEach((Action<IDisposable>)DisposeObject);
        }
        public static void ForEach<T>(this T[] array, Action<T> action)
        {
            if (array != null) {
                foreach (T obj in array) {
                    action(obj);
                }
            }
        }
        public static void ForEach<T>(this T[][] array, Action<T> action)
        {
            if (array != null) {
                foreach (T[] array2 in array) {
                    array2.ForEach(action);
                }
            }
        }
        public static TOutput[] ConvertAll<TInput, TOutput>(this TInput[] array, Converter<TInput, TOutput> converter)
        {
            if (array == null)
                return null;
            List<TOutput> list = new List<TOutput>();
            foreach (TInput val in array) {
                if (val != null) {
                    TOutput val2 = converter(val);
                    if (val2 != null)
                        list.Add(val2);
                }
            }
            if (list.Count == 0)
                return null;
            return list.ToArray();
        }
        internal static Point[] CreatePoints(this IPointEntity[] points)
        {
            return points.ToArray<Point, IPointEntity>(false, (Geometry)null);
        }
        internal static Point ToPoint(this IPointEntity host, bool persist, Geometry context)
        {
            return host.ToGeometry<Point, IPointEntity>(persist, context);
        }
        internal static Curve ToCurve(this ICurveEntity host, bool persist, Geometry context)
        {
            return host.ToGeometry<Curve, ICurveEntity>(persist, context);
        }
        internal static Line ToLine(this ILineEntity host, bool persist, Geometry context)
        {
            return host.ToGeometry<Line, ILineEntity>(persist, context);
        }
        internal static Surface ToSurf(this ISurfaceEntity host, bool persist, Geometry context)
        {
            return host.ToGeometry<Surface, ISurfaceEntity>(persist, context);
        }
        internal static NurbsSurface ToNurbsSurf(this INurbsSurfaceEntity host, bool persist, Geometry context)
        {
            return host.ToGeometry<NurbsSurface, INurbsSurfaceEntity>(persist, context);
        }
        internal static Plane ToPlane(this IPlaneEntity host, bool persist, Geometry context)
        {
            return host.ToGeometry<Plane, IPlaneEntity>(persist, context);
        }
        internal static Solid ToSolid(this ISolidEntity host, bool persist, Geometry context)
        {
            return host.ToGeometry<Solid, ISolidEntity>(persist, context);
        }
        internal static bool ClipParamRange(ref double param)
        {
            if (param < 0) {
                param = 0;
                return true;
            }
            if (param > 1) {
                param = 1;
                return true;
            }
            return false;
        }
        public static string LocateFile(string fileName)
        {
            if (fileName == null)
                return null;
            IExecutionSession session = Application.Instance.Session;
            if (session != null) {
                string text = session.SearchFile(fileName);
                if (text != null)
                    return text;
            } else {
                Assembly executingAssembly = Assembly.GetExecutingAssembly();
                Uri uri = new Uri(executingAssembly.CodeBase);
                string text2 = Path.Combine(Path.GetDirectoryName(uri.LocalPath), fileName);
                if (text2 != null && File.Exists(text2))
                    return text2;
            }
            string[] array = (Environment.GetEnvironmentVariable("PATH") ?? "").Split(new char[1] {
                ';'
            });
            char[] trimChars = new char[1] {
                '"'
            };
            string[] array2 = array;
            foreach (string text3 in array2) {
                string text4 = text3.Trim();
                if (!string.IsNullOrEmpty(text4)) {
                    text4 = text4.Trim(trimChars);
                    if (!string.IsNullOrEmpty(text4) && File.Exists(text4 = Path.Combine(text4, fileName)))
                        return Path.GetFullPath(text4);
                }
            }
            return fileName;
        }
    }
}
            