#region Namespaces
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.Metrics;
using System.Windows.Input;
using Autodesk.Revit.ApplicationServices;
using Autodesk.Revit.Attributes;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Architecture;
using Autodesk.Revit.UI;
using Autodesk.Revit.UI.Selection;

#endregion

namespace RevitAddinAllWalls
{
    [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;

            Dictionary<string, double> walls = new Dictionary<string, double>();

            //フィルタードエレメントコレクターでモデルの中の全ての壁を抽出
            FilteredElementCollector col = new FilteredElementCollector(doc).OfClass(typeof(Wall));

            //情報の取得
            string info = "壁の総数: " + col.GetElementCount() + "\n";
            foreach (Wall wall in col)
            {
                //ファミリ名、タイプ名を取得
                string fam = wall.WallType.FamilyName;
                string typ = wall.WallType.Name;
                // wallsディクショナリのキーのために文字列を作成。"@"はファミリ名とタイプ名を分離するため区切子
                string wallFamilyAndType = fam + "@" + typ;

                //壁の面積を取得
                double area = wall.get_Parameter(BuiltInParameter.HOST_AREA_COMPUTED).AsDouble();
                //内部単位を平方メートルに変換
                double areaSQM = Math.Round(UnitUtils.ConvertFromInternalUnits(area, UnitTypeId.SquareMeters), 2);

                // ディクショナリwallsの中にキーwallFamilyAndTypeが存在するか確認
                if (walls.TryGetValue(wallFamilyAndType, out double areaCount))
                {
                    // 存在する場合は面積を加算する
                    walls[wallFamilyAndType] = areaCount + areaSQM;
                }
                else
                {
                    walls.Add(wallFamilyAndType, areaSQM);
                }
            }
            // Dictionaryの中身を表示する            
            foreach (KeyValuePair<string, double> keyValue in walls)
            {
                //キー
                string key = keyValue.Key;
                //バリュー
                double v = keyValue.Value;

                //keyをファミリ名とタイプ名に分ける
                string[] k = key.Split("@");

                //infoに情報を追加
                info += $"{k[0]} \t {k[1]} \t {v.ToString("F2")}\n";
            }
            // 結果を表示
            TaskDialog.Show("壁の一覧", $"{info}");

            return Result.Succeeded;
        }
    }
}
