/*-------------------------------------------------------------------------
 * 功能描述：RevitUtil
 * 作者：xulisong
 * 创建时间： 2019/6/24 9:55:09
 * 版本号：v1.0
 *  -------------------------------------------------------------------------*/

using Autodesk.Revit.DB;
using SAGA.RevitUtils;
using SAGA.RevitUtils.Extends;
using SAGA.RevitUtils.Extends.Graphic;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace RevitToJBim.Common
{
    public class RevitUtil
    {
        /// <summary>
        /// 获取FamilyInstance顶面轮廓
        /// </summary>
        /// <param name="fi"></param>
        /// <returns></returns>
        public static List<XYZ> GetTopPolygon(FamilyInstance fi)
        {
            List<XYZ> path = new List<XYZ>();
            var faces = fi.GetOriginalFaces(XYZ.BasisZ);
            var topface = faces.FirstOrDefault();
            //传递的path中没有重复点
            if (topface != null)
            {
                var curves = topface.GetCurves();
                for (int i = 0; i < curves.Count; i++)
                {
                    var current = curves[i];
                    var points = current.GetPoints();
                    points.RemoveAt(points.Count - 1);
                    path.AddRange(points);
                }
            }

            return path;
        }

        /// <summary>
        /// 获取门窗到墙线上的投影线
        /// </summary>
        /// <param name="fi"></param>
        /// <returns></returns>
        public static List<XYZ> GetWindowDoorLocation(FamilyInstance fi)
        {
            //取几何实体顶点信息，将点到指定方向做投影
            List<XYZ> xyzs = GetVertexPoints(fi);
            XYZ handDirection = (fi.Host as Wall)?.Orientation;
            if (handDirection != null)
            {
                handDirection = handDirection.CrossProduct(XYZ.BasisZ);
            }
            else if (handDirection == null)
            {
                handDirection = fi.HandOrientation;
            }
            var location = fi.GetLocationPoint();
            if (location == null)
            {
                location = xyzs.FirstOrDefault();
            }

            double min=0, max=0;
            XYZ minXYZ=XYZ.Zero, maxXYZ = XYZ.Zero;
            for (int i = 0; i < xyzs.Count; i++)
            {
                var usePoint = xyzs[i];
                var refDirection = usePoint - location;
                var offset= refDirection.DotProduct(handDirection);
                #region 初始化逻辑
                if (i == 0)
                {
                    minXYZ = maxXYZ = usePoint;
                    min = max = offset;
                }
                #endregion
                #region 判定逻辑
                else
                {
                    if (offset < min)
                    {
                        minXYZ =  usePoint;
                        min =  offset;
                        continue;
                    }
                    if (max < offset)
                    {
                        maxXYZ = usePoint;
                        max = offset;
                        continue;
                    }
                } 
                #endregion
            }
            return new List<XYZ>(){minXYZ,maxXYZ};
        }

        /// <summary>
        /// 获取元素顶点集合
        /// </summary>
        /// <returns></returns>
        public static List<XYZ> GetVertexPoints(Element element)
        {
            List<XYZ> xyzs = new List<XYZ>();
            var solids=element.GetSolids();
            foreach (var solid in solids)
            {
                foreach (Edge edge in solid.Edges)
                {
                    xyzs.AddRange(edge.Tessellate());
                }
            }
            return xyzs.Distinct(new XyzEqualComparer()).ToList();
        }

        /// <summary>
        /// 获取墙的轮廓线
        /// </summary>
        /// <param name="wall"></param>
        /// <returns></returns>
        public static List<List<XYZ>> GetWallPolygon(Wall wall)
        {
            /*
             * 1找到墙的定位线，
             * 2将定位线拆分成多段
             * 3按照宽度，将多段定位线生成闭合区域
             */
            var curve = wall.GetLocationCurve();

            
            List<List<XYZ>> polygons = new List<List<XYZ>>();
            var refs = HostObjectUtils.GetSideFaces(wall,ShellLayerType.Exterior).OfType<Face>();
            foreach (Face face in refs)
            {
                List<XYZ> polygon = new List<XYZ>();
                //foreach (Curve curve in face.ed)
                //{

                //}
            }

            //偏移位位置信息
            return polygons;
        }

      
    }
}
