#region Namespaces
using Autodesk.Revit.ApplicationServices;
using Autodesk.Revit.Attributes;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using Autodesk.Revit.UI.Selection;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Windows.Controls;
using System.Windows.Shapes;

#endregion

namespace RevitAddinCreateGrids
{
    [Transaction(TransactionMode.Manual)]
    public class Command : IExternalCommand
    {
        public Result Execute(
          ExternalCommandData commandData,
          ref string message,
          ElementSet elements)
        {
            UIApplication uiapp = commandData.Application;
            UIDocument uidoc = uiapp.ActiveUIDocument;
            Application app = uiapp.Application;
            Document doc = uidoc.Document;
            View activeView = uidoc.ActiveView;

            //通芯の情報を用意する
            //X通芯の開始点と終了点のY座標
            double y1 = -3600;
            double y2 = 25200;
            //X通芯の座標値と名称
            double[] x = { 0, 7200, 14400, 21600, 28800, 36000 };
            string[] symbolX = { "1", "2", "3", "4", "5", "6"};
            //Y通芯の開始点と終了点のX座標
            double x1 = -3600;
            double x2 = 39600;
            //Y通芯の座標値と名称
            double[] y = { 0, 7200, 14400, 21600 };
            string[] symbolY = { "A", "B", "C", "D" };

            //作成したグリッドを格納するリスト
            List<Autodesk.Revit.DB.Grid> gridX = new List<Autodesk.Revit.DB.Grid>();
            List<Autodesk.Revit.DB.Grid> gridY = new List<Autodesk.Revit.DB.Grid>();

            using (Transaction tx = new Transaction(doc))
            {
                tx.Start("Transaction Create Grids");
                for (int i = 0; i < x.Length; i++)
                {
                    //X方向　通芯開始点と終了点のXYZ座標を作成
                    XYZ start = new XYZ(CVmmToInt(x[i]), CVmmToInt(y1), 0);
                    XYZ end = new XYZ(CVmmToInt(x[i]), CVmmToInt(y2), 0);
                    //線分を作成
                    Autodesk.Revit.DB.Line line = Autodesk.Revit.DB.Line.CreateBound(start, end);
                    //グリッド（通芯）を作成
                    Autodesk.Revit.DB.Grid grid = Autodesk.Revit.DB.Grid.Create(doc, line);
                    //グリッド（通芯）に名称を設定
                    grid.Name = symbolX[i];
                    //リストに追加
                    gridX.Add(grid);
                }

                for (int i = 0; i < y.Length; i++)
                {
                    //Y方向　通芯開始点と終了点のXYZ座標を作成
                    XYZ start = new XYZ(CVmmToInt(x1), CVmmToInt(y[i]), 0);
                    XYZ end = new XYZ(CVmmToInt(x2), CVmmToInt(y[i]), 0);
                    //線分を作成
                    Autodesk.Revit.DB.Line line = Autodesk.Revit.DB.Line.CreateBound(start, end);
                    //グリッド（通芯）を作成
                    Autodesk.Revit.DB.Grid grid = Autodesk.Revit.DB.Grid.Create(doc, line);
                    //グリッド（通芯）に名称を設定
                    grid.Name = symbolY[i];
                    //リストに追加
                    gridY.Add(grid);
                }
                tx.Commit();
                //寸法線の作成
                tx.Start("Transaction Create Dimensions");
                // X方向グリッド寸法線の作成
                for (int i = 1; i < x.Length; i++)
                {
                    //寸法線作成にはReferenceArrayが必要。どことどこのグリッドを寸法線で結ぶかを指定する
                    ReferenceArray references = new ReferenceArray();
                    references.Append(new Reference(gridX[i - 1]));
                    references.Append(new Reference(gridX[i]));
                    //寸法線の位置を決めるためのオフセット値。今回はX方向に500mm移動した点に設定
                    double offset = CVmmToInt(500);
                    //寸法線の開始点と終了点のXYZ座標を作成
                    XYZ dimLineStart = new XYZ(gridX[i - 1].Curve.GetEndPoint(0).X, gridX[i - 1].Curve.GetEndPoint(0).Y + offset, 0);
                    XYZ dimLineEnd = new XYZ(gridX[i].Curve.GetEndPoint(0).X, gridX[i].Curve.GetEndPoint(0).Y + offset, 0);
                    //寸法線になる線分を作成
                    Autodesk.Revit.DB.Line dimLine = Autodesk.Revit.DB.Line.CreateBound(dimLineStart, dimLineEnd);
                    //寸法線を作成
                    doc.Create.NewDimension(activeView, dimLine, references);
                }
                // Y方向グリッド寸法線の作成
                for (int i = 1; i < y.Length; i++)
                {
                    ReferenceArray references = new ReferenceArray();
                    references.Append(new Reference(gridY[i - 1]));
                    references.Append(new Reference(gridY[i]));
                    double offset = CVmmToInt(500);
                    XYZ dimLineStart = new XYZ(gridY[i - 1].Curve.GetEndPoint(0).X + offset, gridY[i - 1].Curve.GetEndPoint(0).Y, 0);
                    XYZ dimLineEnd = new XYZ(gridY[i].Curve.GetEndPoint(0).X + offset, gridY[i].Curve.GetEndPoint(0).Y, 0);
                    Autodesk.Revit.DB.Line dimLine = Autodesk.Revit.DB.Line.CreateBound(dimLineStart, dimLineEnd);
                    doc.Create.NewDimension(activeView, dimLine, references);
                }
                tx.Commit();
            }
            return Result.Succeeded;
        }
        //ミリメーターを内部単位に変換する
        public static double CVmmToInt(double x)
        {
            return UnitUtils.ConvertToInternalUnits(x, UnitTypeId.Millimeters);
        }
    }
}
