using System.Collections.Generic;
using System.Linq;
using Autodesk.Revit.DB;
using uBIMEarthTools.Utils;

namespace uBIMEarthTools.Model
{
    /// <summary>
    /// 地质块
    /// <image url="$(SolutionDir)/Comments/常规模型族.png" />
    /// </summary>
    class GeologyBlock
    {
        /// <summary>
        /// F面左端上坐标
        /// </summary>
        public XYZ FLeftUp { get; set; }

        /// <summary>
        /// F面左端下坐标
        /// </summary>
        public XYZ FLeftBottom { get; set; }

        /// <summary>
        /// F面右端上坐标
        /// </summary>
        public XYZ FRightUp { get; set; }

        /// <summary>
        /// F面右端下坐标
        /// </summary>
        public XYZ FRightBottom { get; set; }

        /// <summary>
        /// 棱面左端上坐标
        /// </summary>
        public XYZ ELeftUp { get; set; }

        /// <summary>
        /// 棱面左端下坐标
        /// </summary>
        public XYZ ELeftBottom { get; set; }

        /// <summary>
        /// 棱面右端上坐标
        /// </summary>
        public XYZ ERightUp { get; set; }

        /// <summary>
        /// 棱面右端下坐标
        /// </summary>
        public XYZ ERightBottom { get; set; }

        /// <summary>
        /// 地质块地质层
        /// </summary>
        public string Type { get; set; }

        /// <summary>
        /// 钻孔一编号
        /// </summary>
        public string Num1 { get; }

        /// <summary>
        /// 钻孔二编号
        /// </summary>
        public string Num2 { get; }

        /// <summary>
        /// 钻孔三编号
        /// </summary>
        public string Num3 { get; }

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="borehole1">钻孔一</param>
        /// <param name="borehole2">钻孔二</param>
        /// <param name="borehole3">钻孔三</param>
        public GeologyBlock(Borehole borehole1, Borehole borehole2, Borehole borehole3)
        {
            Num1 = borehole1.Name;
            Num2 = borehole2.Name;
            Num3 = borehole3.Name;
        }

        public GeologyParams GetGeologyParams(double Elevation)
        {
            GeologyParams geologyParams = new GeologyParams();



            XYZ tmpPoint0 = new XYZ(FLeftUp.X, FLeftUp.Y, 0);
            XYZ tmpPoint1 = new XYZ(FRightUp.X, FRightUp.Y, 0);
            XYZ tmpPoint2 = new XYZ(ELeftUp.X, ELeftUp.Y, 0);
            XYZ tmpPoint3 = new XYZ(ERightUp.X, ERightUp.Y, 0);

            if ((tmpPoint1 - tmpPoint0).CrossProduct(tmpPoint3 - tmpPoint1).Z < 0)
            {
                Flip();
            }

            List<double> bottoms = new List<double>() { FLeftBottom.Z, FRightBottom.Z, ELeftBottom.Z, ERightBottom.Z };
            geologyParams.FLeftBottom = FLeftBottom.Z - bottoms.Min();
            geologyParams.FRightBottom = FRightBottom.Z - bottoms.Min();
            geologyParams.ELeftBottom = ELeftBottom.Z - bottoms.Min();
            geologyParams.ERightBottom = ERightBottom.Z - bottoms.Min();
            geologyParams.ElevationOffset = bottoms.Min() - Elevation;
            tmpPoint0 = new XYZ(FLeftUp.X, FLeftUp.Y, bottoms.Min());
            tmpPoint1 = new XYZ(FRightUp.X, FRightUp.Y, bottoms.Min());
            tmpPoint2 = new XYZ(ELeftUp.X, ELeftUp.Y, bottoms.Min());
            tmpPoint3 = new XYZ(ERightUp.X, ERightUp.Y, bottoms.Min());

            geologyParams.FLeftHeight = FLeftUp.DistanceTo(FLeftBottom);
            geologyParams.FRightHeight = FRightUp.DistanceTo(FRightBottom);
            geologyParams.FWidth = FLeftUp.DistanceTo(new XYZ(FRightUp.X, FRightUp.Y, FLeftUp.Z));
            geologyParams.ELeftHeight = ELeftUp.DistanceTo(ELeftBottom);
            geologyParams.ERightHeight = ERightUp.DistanceTo(ERightBottom);
            geologyParams.EWidth = ELeftUp.DistanceTo(new XYZ(ERightUp.X, ERightUp.Y, ELeftUp.Z));




            Line fLine = Line.CreateBound(tmpPoint0, tmpPoint1);
            double start = fLine.GetEndParameter(0);
            double end = fLine.GetEndParameter(1);
            fLine.MakeUnbound();
            IntersectionResult intersectionResult = fLine.Project(tmpPoint2);
            geologyParams.FEOffset = intersectionResult.Distance;
            fLine.MakeBound(start, end);
            //bool inside = fLine.IsInside(intersectionResult.Parameter);
            bool near = intersectionResult.Parameter > fLine.GetEndParameter(0);
            geologyParams.Location = near ? tmpPoint0 : intersectionResult.XYZPoint;
            geologyParams.FDistance = near ? 0 : intersectionResult.XYZPoint.DistanceTo(tmpPoint0);
            geologyParams.EDistance = near ? intersectionResult.XYZPoint.DistanceTo(tmpPoint0) : 0;

            geologyParams.Angle = Common.AngleOfThreePoint(FRightUp, FLeftUp, FLeftUp + new XYZ(1, 0, 0));

            return geologyParams;
        }

        private void Flip()
        {
            XYZ temp;

            temp = FRightUp;
            FRightUp = FLeftUp;
            FLeftUp = temp;

            temp = FRightBottom;
            FRightBottom = FLeftBottom;
            FLeftBottom = temp;

            temp = ERightUp;
            ERightUp = ELeftUp;
            ELeftUp = temp;

            temp = ERightBottom;
            ERightBottom = ELeftBottom;
            ELeftBottom = temp;
        }
    }

    //class GeologyBlocks
    //{
    //    /// <summary>
    //    /// 钻孔一上坐标
    //    /// </summary>
    //    public XYZ P1 { get; set; }

    //    /// <summary>
    //    /// 钻孔二上坐标
    //    /// </summary>
    //    public XYZ P2 { get; set; }

    //    /// <summary>
    //    /// 钻孔三上坐标
    //    /// </summary>
    //    public XYZ P3 { get; set; }

    //    /// <summary>
    //    /// 钻孔一下坐标
    //    /// </summary>
    //    public XYZ P4 { get; set; }

    //    /// <summary>
    //    /// 钻孔二下坐标
    //    /// </summary>
    //    public XYZ P5 { get; set; }

    //    /// <summary>
    //    /// 钻孔三下坐标
    //    /// </summary>
    //    public XYZ P6 { get; set; }

    //    /// <summary>
    //    /// 地质块地质层
    //    /// </summary>
    //    public string Type { get; set; }

    //    /// <summary>
    //    /// 钻孔一编号
    //    /// </summary>
    //    public string Num1 { get; }

    //    /// <summary>
    //    /// 钻孔二编号
    //    /// </summary>
    //    public string Num2 { get; }

    //    /// <summary>
    //    /// 钻孔三编号
    //    /// </summary>
    //    public string Num3 { get; }

    //    /// <summary>
    //    /// 构造函数
    //    /// </summary>
    //    /// <param name="borehole1">钻孔一</param>
    //    /// <param name="borehole2">钻孔二</param>
    //    /// <param name="borehole3">钻孔三</param>
    //    public GeologyBlocks(Borehole borehole1, Borehole borehole2, Borehole borehole3)
    //    {
    //        Num1 = borehole1.Name;
    //        Num2 = borehole2.Name;
    //        Num3 = borehole3.Name;
    //    }
    //}
}
