/*-------------------------------------------------------------------------
 * 功能描述：CurveExtension
 * 作者：xulisong
 * 创建时间： 2019/6/26 14:14:27
 * 版本号：v1.0
 *  -------------------------------------------------------------------------*/

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

namespace RevitToJBim.Extension
{
    public static class CurveExtension
    {
        /// <summary>
        /// 获取curve偏移后的Polygon信息
        /// </summary>
        /// <param name="curve"></param>
        /// <param name="normal"></param>
        /// <param name="offset"></param>
        /// <returns></returns>
        public static List<XYZ> GetCurvePolygon(this Curve curve, XYZ normal, double offset)
        {
            List<XYZ> xyzs = new List<XYZ>();
            XYZ referenceDirection = normal;
            if (curve.IsLine())
            {
                referenceDirection = normal.CrossProduct((curve as Line).Direction);
            }

            #region 构建围护线
            //从curve1.StartPoint()开始的可以顺序连接的线结构
            var curve1 = curve.CreateOffset(offset, referenceDirection);
            var curve2 = curve.CreateOffset(-offset, referenceDirection);
            var line1 = Line.CreateBound(curve1.EndPoint(), curve2.EndPoint());
            var line2 = Line.CreateBound(curve2.StartPoint(), curve1.StartPoint());
            //curve2调转方向
            curve2 = curve2.CreateReversed();
            List<Curve> curves = new List<Curve>();
            curves.Add(curve1);
            curves.Add(line1);
            curves.Add(curve2);
            curves.Add(line2);
            foreach (Curve useCurve in curves)
            {
                var points = useCurve.Tessellate();
                points.RemoveAt(points.Count - 1);
                xyzs.AddRange(points);
            }
            #endregion
            #region 逆时针顺序转化
            /*
                *  //将线结构整理成逆时针形式;
                * 如果curve是弧线则使用开始，中间，结束三个点判断
                * 如果curve是直线，则使用开始，结束，curve2的开始三个点判断;
                *
                * 也可以直接使用上面的的点集合取出三个点进行判断
                */
            List<XYZ> decisionXyzs = new List<XYZ>();
            if (curve1.IsLine())
            {
                decisionXyzs.Add(curve1.StartPoint());
                decisionXyzs.Add(curve1.EndPoint());
                decisionXyzs.Add(curve2.StartPoint());
            }
            else if(curve1.IsArc())
            {
                //找半径大的弧
                var useCurve = (curve1 as Arc).Radius > (curve2 as Arc).Radius ? curve1 : curve2;
                decisionXyzs.Add(useCurve.StartPoint());
                decisionXyzs.Add(useCurve.MiddlePoint());
                decisionXyzs.Add(useCurve.EndPoint());

            }
            if (decisionXyzs.Any())
            {
                var useDirection = (decisionXyzs[1] - decisionXyzs[0]).CrossProduct(decisionXyzs[2] - decisionXyzs[0]);
                var isAnticlockwise = useDirection.IsSameDirection(normal);
                if (!isAnticlockwise)
                {
                    xyzs.Reverse();
                }
            }         
            #endregion
            return xyzs;
        }
    }
}
