Plane
using Autodesk.DesignScript.Interfaces;
using Autodesk.DesignScript.Runtime;
using System.Collections.Generic;
using System.Linq;
namespace Autodesk.DesignScript.Geometry
{
    public class Plane : Geometry
    {
        internal IPlaneEntity PlaneEntity => HostImpl as IPlaneEntity;
        public Point Origin => Point.Wrap(PlaneEntity.get_Origin(), true);
        [Scaling()]
        public Vector Normal {
            get {
                return Vector.Wrap(PlaneEntity.get_Normal().Scale(1 / DesignScriptEntity.scaleFactor), true);
            }
        }
        [Scaling()]
        public Vector XAxis {
            get {
                return Vector.Wrap(PlaneEntity.get_XAxis().Scale(1 / DesignScriptEntity.scaleFactor), true);
            }
        }
        [Scaling()]
        public Vector YAxis {
            get {
                return Vector.Wrap(PlaneEntity.get_YAxis().Scale(1 / DesignScriptEntity.scaleFactor), true);
            }
        }
        internal Plane(IPlaneEntity host, bool persist)
            : base(host, persist)
        {
        }
        public override string ToString()
        {
            return "Plane(Origin = " + Origin?.ToString() + ", Normal = " + Normal?.ToString() + ", XAxis = " + XAxis?.ToString() + ", YAxis = " + YAxis?.ToString() + ")";
        }
        internal static void InitType()
        {
            Geometry.RegisterHostType(typeof(IPlaneEntity), (IGeometryEntity host, bool persist) => new Plane(host as IPlaneEntity, persist));
        }
        internal static Plane Wrap(IPlaneEntity host, bool persist = true)
        {
            if (host == null)
                return null;
            return new Plane(host, persist);
        }
        internal static Plane[] Wrap(IPlaneEntity[] hosts, bool persist = true)
        {
            return (from x in hosts
            select Wrap(x, persist)).ToArray();
        }
        internal static Plane[][] Wrap(IPlaneEntity[][] hosts, bool persist = true)
        {
            return (from x in hosts
            select Wrap(x, persist)).ToArray();
        }
        internal static IPlaneEntity[][] Unwrap(Plane[][] o)
        {
            return (from x in o
            select Unwrap(x)).ToArray();
        }
        internal static IPlaneEntity[] Unwrap(Plane[] o)
        {
            return (from x in o
            select Unwrap(x)).ToArray();
        }
        internal static IPlaneEntity[] Unwrap(IEnumerable<Plane> o)
        {
            return (from x in o
            select Unwrap(x)).ToArray();
        }
        internal static IPlaneEntity Unwrap(Plane o)
        {
            return o.PlaneEntity;
        }
        public static Plane ByOriginNormal([DefaultArgument("Autodesk.DesignScript.Geometry.Point.ByCoordinates(0, 0, 0)")] Point origin, [DefaultArgument("Autodesk.DesignScript.Geometry.Vector.ByCoordinates(0, 0, 1)")] Vector normal)
        {
            return Wrap(HostFactory.Factory.PlaneByOriginNormal(Point.Unwrap(origin), Vector.Unwrap(normal)), true);
        }
        public static Plane ByOriginNormalXAxis([DefaultArgument("Autodesk.DesignScript.Geometry.Point.ByCoordinates(0, 0, 0)")] Point origin, [DefaultArgument("Autodesk.DesignScript.Geometry.Vector.ByCoordinates(0, 0, 1)")] Vector normal, [DefaultArgument("Autodesk.DesignScript.Geometry.Vector.ByCoordinates(1, 0, 0)")] Vector xAxis)
        {
            return Wrap(HostFactory.Factory.PlaneByOriginNormalXAxis(Point.Unwrap(origin), Vector.Unwrap(normal), Vector.Unwrap(xAxis)), true);
        }
        public static Plane ByOriginXAxisYAxis([DefaultArgument("Autodesk.DesignScript.Geometry.Point.ByCoordinates(0, 0, 0)")] Point origin, [DefaultArgument("Autodesk.DesignScript.Geometry.Vector.ByCoordinates(1, 0, 0)")] Vector xAxis, [DefaultArgument("Autodesk.DesignScript.Geometry.Vector.ByCoordinates(0, 1, 0)")] Vector yAxis)
        {
            return Wrap(HostFactory.Factory.PlaneByOriginXAxisYAxis(Point.Unwrap(origin), Vector.Unwrap(xAxis), Vector.Unwrap(yAxis)), true);
        }
        public static Plane ByBestFitThroughPoints(IEnumerable<Point> points)
        {
            return Wrap(HostFactory.Factory.PlaneByBestFitThroughPoints(Point.Unwrap(points)), true);
        }
        public static Plane ByLineAndPoint(Line line, Point point)
        {
            return Wrap(HostFactory.Factory.PlaneByLineAndPoint(Line.Unwrap(line), Point.Unwrap(point)), true);
        }
        public static Plane ByThreePoints(Point origin, Point planePoint, Point xAxisPoint)
        {
            return Wrap(HostFactory.Factory.PlaneByThreePoints(Point.Unwrap(origin), Point.Unwrap(planePoint), Point.Unwrap(xAxisPoint)), true);
        }
        public static Plane XY()
        {
            return Wrap(HostFactory.Factory.PlaneXY(), true);
        }
        public static Plane XZ()
        {
            return Wrap(HostFactory.Factory.PlaneXZ(), true);
        }
        public static Plane YZ()
        {
            return Wrap(HostFactory.Factory.PlaneYZ(), true);
        }
        public CoordinateSystem ToCoordinateSystem()
        {
            return CoordinateSystem.Wrap(PlaneEntity.ToCoordinateSystem(), true);
        }
        public Plane Offset([Scaling()] double dist = 1)
        {
            DesignScriptEntity.CheckArgsForAsmExtents(new List<double> {
                dist
            });
            dist /= DesignScriptEntity.scaleFactor;
            return Wrap(PlaneEntity.Offset(dist), true);
        }
    }
}
            