using System;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Collections.Generic;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using Autodesk.Revit.UI.Selection;

namespace EarthLayerModel
{
    [Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]
    public class uBIM_EarthTools : IExternalCommand
    {
        public Result Execute(Autodesk.Revit.UI.ExternalCommandData CommandData, ref string Message, ElementSet elementset)
        {
            Autodesk.Revit.ApplicationServices.Application Revit = CommandData.Application.Application;
            Autodesk.Revit.UI.UIDocument uidoc = CommandData.Application.ActiveUIDocument;
            Autodesk.Revit.DB.Document doc = CommandData.Application.ActiveUIDocument.Document;
            ICollection<ElementId> currentselectid = uidoc.Selection.GetElementIds();
            Autodesk.Revit.DB.View curview = doc.ActiveView;
            string path = Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + "\\data.csv";

            //MessageBox.Show("注意要在±0平面视图运行。", "向日葵", MessageBoxButtons.OK);

            //所有文字
            List<TextNote> textnoteList = new List<TextNote>();
            ICollection<ElementId> textnoteid_list = (new FilteredElementCollector(doc, curview.Id)).
                WherePasses(new ElementClassFilter(typeof(TextNote))).ToElementIds();
            foreach (ElementId eid in textnoteid_list)
                textnoteList.Add(doc.GetElement(eid) as TextNote);

            //所有线条
            //List<DetailCurve> detaillineList = new List<DetailCurve>();
            //ICollection<ElementId> detaillineidList = (new FilteredElementCollector(doc, curview.Id)).
            //    WherePasses(new CurveElementFilter(CurveElementType.DetailCurve)).ToElementIds();
            //foreach (ElementId eid in detaillineidList)
            //    detaillineList.Add(doc.GetElement(eid) as DetailCurve);

            //所有1000的水平分格线
            //List<DetailLine> dl_fg_list = new List<DetailLine>();
            //foreach (DetailCurve dltmp in detailline_list)
            //{
            //    if (dltmp.GetType().Name != "DetailLine")
            //        continue;
            //    DetailLine dl = dltmp as DetailLine;
            //    if (dltmp.GeometryCurve.Length < 900 / 304.8 || dltmp.GeometryCurve.Length > 1100 / 304.8)
            //        continue;
            //    XYZ pp1 = dl.GeometryCurve.GetEndPoint(0);
            //    XYZ pp2 = dl.GeometryCurve.GetEndPoint(1);
            //    if (Math.Abs(pp1.Y - pp2.Y) < 0.1)
            //        dl_fg_list.Add(dl);
            //}

            XYZ origin = new XYZ();
            XYZ origin2 = new XYZ();
            try
            {
                origin = uidoc.Selection.PickPoint(ObjectSnapTypes.Endpoints, "点击图框左上角……");
                origin2 = uidoc.Selection.PickPoint(ObjectSnapTypes.Endpoints, "点击第二个图框左上角……");
            }
            catch
            {
                return Result.Cancelled;
            }

            string allstr = "";  //总记录
            List<int> maybe_error_list = new List<int>();   //可能出错的行

            //——————————————以下为深国际商业及写字楼的dwg定位数据——————————————
            //double column1_x1 = 2390 / 304.8;  //第一列地层编号左侧x坐标
            //double column1_x2 = 3390 / 304.8;  //第一列地层编号右侧x坐标 
            //double column3_x1 = 4390 / 304.8;  //第三列层底高程左侧x坐标
            //double column3_x2 = 5390 / 304.8;  //第三列层底高程右侧x坐标
            //double column_y = -9000 / 304.8;  //此Y坐标以下为地层数据

            //——————————————以下为dwg定位数据——————————————
            double column1_x1 = 43.2 / 304.8;  //地层编号左侧x坐标
            double column1_x2 = 52.9896 / 304.8;  //地层编号右侧x坐标 
            double column3_x1 = 13.8312 / 304.8;  //层底高程左侧x坐标
            double column3_x2 = 23.6208 / 304.8;  //层底高程右侧x坐标
            double column_y = -62.3 / 304.8;  //此Y坐标以下为地层数据

            TransactionStatus status = TransactionStatus.Uninitialized;
            TransactionGroup transGroup = new TransactionGroup(doc, "地质建模");
            if (transGroup.Start() == TransactionStatus.Started)
            {
                List<TextNote> del_textnote_list = new List<TextNote>();  //被归并的textnote，后面被排除 
                //int k = 0;
                //do
                for (int k = 0; k <= 7; k++)    //钻点数量
                {
                    //求第i格的数字，表示地层编号                
                    //try
                    //{
                    XYZ origin_k = origin + new XYZ(k * (origin2.X - origin.X), 0, 0);

                    List<TextNote> textnote_k_list = new List<TextNote>();  //当前图框里的textnote                
                    foreach (TextNote tntmp in textnoteList)
                    {

                        //tntmp.Coord.Y > origin_k.Y - 29106 / 304.8 && tntmp.Coord.Y < origin_k.Y)

                        if (tntmp.Coord.X > origin_k.X && tntmp.Coord.X < origin_k.X + 178 / 304.8 &&
                        tntmp.Coord.Y > origin_k.Y - 267 / 304.8 && tntmp.Coord.Y < origin_k.Y)
                        {
                            //消重
                            Boolean dub = false;
                            for (int i = 0; i <= textnote_k_list.Count - 1; i++)
                            {
                                TextNote tntmp1 = textnote_k_list[i];
                                if (tntmp.Coord.DistanceTo(tntmp1.Coord) < 10 / 304.8 && tntmp.Text == tntmp1.Text)
                                {
                                    dub = true;
                                    break;
                                }
                            }
                            if (dub == false)
                                textnote_k_list.Add(tntmp);
                        }
                    }

                    if (textnote_k_list.Count == 0)   //结束
                        break;

                    //——————————————以下为深国际商业及写字楼的dwg定位数据——————————————
                    //TextNote zkbh_tn = Textnote_At_Point(origin_k + new XYZ(12890 / 304.8, -4350 / 304.8, 0), textnote_k_list);  //钻孔编号
                    //TextNote kkbg_tn = Textnote_At_Point(origin_k + new XYZ(5200 / 304.8, -5220 / 304.8, 0), textnote_k_list);  //孔口标高
                    //TextNote x_tn = Textnote_At_Point(origin_k + new XYZ(8490 / 304.8, -5220 / 304.8, 0), textnote_k_list);  //孔口X
                    //TextNote y_tn = Textnote_At_Point(origin_k + new XYZ(8490 / 304.8, -6100 / 304.8, 0), textnote_k_list);  //孔口Y

                    //——————————————以下为深国际住宅旋挖桩的dwg定位数据——————————————
                    TextNote zkbh_tn = Textnote_At_Point(origin_k + new XYZ(24.73 / 304.8, -21.46 / 304.8, 0), textnote_k_list);  //钻孔编号
                    TextNote kkbg_tn = Textnote_At_Point(origin_k + new XYZ(24.73 / 304.8, -30.4 / 304.8, 0), textnote_k_list);  //孔口标高
                    TextNote x_tn = Textnote_At_Point(origin_k + new XYZ(61.75 / 304.8, -21.46 / 304.8, 0), textnote_k_list);  //孔口X
                    TextNote y_tn = Textnote_At_Point(origin_k + new XYZ(61.75 / 304.8, -30.4 / 304.8, 0), textnote_k_list);  //孔口Y

                    if (zkbh_tn == null || kkbg_tn == null)    //钻孔编号跟孔口标高不对应
                        continue;

                    //归并类似3-1的文字                      
                    foreach (TextNote tntmp1 in textnote_k_list)
                    {
                        if (tntmp1.Coord.X > origin_k.X + column1_x2)
                            continue;
                        if (del_textnote_list.Contains(tntmp1))
                            continue;

                        foreach (TextNote tntmp2 in textnote_k_list)
                        {

                            if (del_textnote_list.Contains(tntmp2))
                                continue;
                            if (tntmp2.Coord.X > origin_k.X + column1_x2)
                                continue;
                            if (tntmp1.Id == tntmp2.Id)
                                continue;

                            //三重过滤：X相近、Y相近、字高不一
                            if (Math.Abs(tntmp1.Coord.X - tntmp2.Coord.X) < 6 / 304.8 &&
                                Math.Abs(tntmp1.Coord.Y - tntmp2.Coord.Y) < 4 / 304.8 &&
                                 Math.Abs(tntmp1.Height - tntmp2.Height) > 0.00001 / 304.8)
                            {
                                //TaskDialog.Show("Show", (Math.Abs(tntmp1.Coord.X - tntmp2.Coord.X) * 304.8).ToString());

                                Transaction transaction = new Transaction(doc, "yy"); transaction.Start();
                                if (tntmp1.Height > tntmp2.Height)
                                {
                                    tntmp1.Text = "=\"" + tntmp1.Text + "-" + tntmp2.Text + "\"";
                                    del_textnote_list.Add(tntmp2);
                                }
                                else
                                {
                                    tntmp2.Text = "=\"" + tntmp2.Text + "-" + tntmp1.Text + "\"";
                                    del_textnote_list.Add(tntmp1);
                                }
                                transaction.Commit();
                            }
                        }
                    }
                    textnote_k_list = textnote_k_list.Except(del_textnote_list).ToList<TextNote>();

                    List<TextNote> dcbh_list = new List<TextNote>();   //地层编号
                    List<double> dcbh_Y_list = new List<double>();   //地层编号Y坐标
                    List<TextNote> dcmc_list = new List<TextNote>();   //地层名称
                    List<double> dcmc_Y_list = new List<double>();   //地层名称Y坐标

                    string record1 = zkbh_tn.Text + "," + kkbg_tn.Text + ",";
                    string record2 = zkbh_tn.Text + "," + kkbg_tn.Text + ",";

                    for (int i = 0; i <= textnote_k_list.Count - 1; i++)
                    {
                        TextNote tntmp = textnote_k_list[i];
                        if (tntmp.Coord.Y > origin_k.Y + column_y)
                            continue;
                        if (tntmp.Coord.X > origin_k.X + column1_x1 && tntmp.Coord.X < origin_k.X + column1_x2)
                        {
                            dcbh_list.Add(tntmp);
                            dcbh_Y_list.Add(tntmp.Coord.Y);
                        }
                        if (tntmp.Coord.X > origin_k.X + column3_x1 && tntmp.Coord.X < origin_k.X + column3_x2)
                        {
                            dcmc_list.Add(tntmp);
                            dcmc_Y_list.Add(tntmp.Coord.Y);
                        }
                    }

                    dcbh_Y_list.Sort();
                    dcbh_Y_list.Reverse(); //从高到低

                    dcmc_Y_list.Sort();
                    dcmc_Y_list.Reverse(); //从高到低

                    for (int i = 0; i < dcbh_list.Count; i++)
                    {
                        if (i > dcmc_list.Count - 1)
                            break;
                        string dcbh_i = "";
                        string dcmc_i = "";
                        foreach (TextNote tn in dcbh_list)
                        {
                            if (tn.Coord.Y == dcbh_Y_list[i])
                                dcbh_i = tn.Text;
                        }
                        foreach (TextNote tn in dcmc_list)
                        {
                            if (tn.Coord.Y == dcmc_Y_list[i])
                                dcmc_i = tn.Text;
                        }
                        record1 += dcbh_i + ",";
                        record2 += dcmc_i + ",";
                    }

                    //补齐空格
                    for (int i = 1; i <= 16 - dcbh_list.Count; i++)
                    {
                        record1 += " ,";
                        record2 += " ,";
                    }

                    record1 += x_tn.Text + "," + y_tn.Text;
                    record2 += x_tn.Text + "," + y_tn.Text;


                    allstr += record1 + "\r\n" + record2 + "\r\n";

                    //k++;
                    //}
                    //catch
                    //{
                    //    MessageBox.Show(k + "\n" + "OK", "向日葵", MessageBoxButtons.OK);
                    //    break;
                    //}
                }
                //while (k > 0);

                Transaction transaction10 = new Transaction(doc, "yy"); transaction10.Start();
                foreach (TextNote tn in del_textnote_list)
                    doc.Delete(tn.Id);
                transaction10.Commit();

                File.WriteAllText(path, allstr, Encoding.Default);
            }
            status = transGroup.RollBack();


        
            string tips = "已导出到" + path + "。数据请查对。";
            //foreach (int t in maybe_error_list)
            //    tips += t.ToString() + " , ";
            //MessageBox.Show(tips, "向日葵", MessageBoxButtons.OK);
            return Result.Succeeded;
        }

        //求某点处的textnote，在textnote_list范围内
        public TextNote Textnote_At_Point(XYZ p, List<TextNote> textnote_list)
        {
            TextNote tn = null;
            foreach (TextNote tntmp in textnote_list)
            {
                if (tntmp.Coord.DistanceTo(new XYZ(p.X, p.Y, tntmp.Coord.Z)) < 5 / 304.8)
                {
                    tn = tntmp;
                }
            }
            return tn;
        }
    }
}
