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

#endregion

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

            // 選択フィルターを設定
            WallSelectionFilter filter = new WallSelectionFilter(doc);

            try
            {
                // フィルター付きでユーザーに壁インスタンスを選択してもらう
                Reference myRef = uidoc.Selection.PickObject(ObjectType.Element, filter, "壁を選択してください。キャンセルするにはESCを押します");

                // 選択された要素を取得
                Element selectElement = doc.GetElement(myRef);
                // ファミリ名、タイプ名、カテゴリを取得
                Wall wall = selectElement as Wall;

                //壁タイプを検索する
                string newWallTypeName = "(L#)EB1/EB1";
                WallType newWallType = new FilteredElementCollector(doc)
                    .OfClass(typeof(WallType))
                    .Where(typ => typ.Name == newWallTypeName).First() as WallType;

                if (newWallType != null)
                {
                    using (Transaction tx = new Transaction(doc, "Change Wall Type"))
                    {
                        tx.Start();
                        // 壁のタイプを変更する
                        wall.ChangeTypeId(newWallType.Id);
                        tx.Commit();
                    }
                }
                else
                {
                    // 壁タイプが見つからない場合のエラーメッセージ
                    TaskDialog.Show("エラー", $"指定された壁タイプ '{newWallTypeName}' が見つかりません。");
                    return Result.Cancelled;
                }
            }
            catch (Autodesk.Revit.Exceptions.OperationCanceledException)
            {
                // ユーザーがキャンセルした場合
                return Result.Cancelled;
            }
            catch (Exception ex)
            {
                // その他のエラーが発生した場合
                message = $"エラーが発生しました: {ex.Message}";
                return Result.Failed;
            }
            return Result.Succeeded;

        }
    }
    public class WallSelectionFilter : ISelectionFilter
    {
        private readonly Document doc;
        //コンストラクタ
        public WallSelectionFilter(Document doc)
        {
            this.doc = doc;
        }
        //要素の選択を許可するかどうかのメソッド
        public bool AllowElement(Element elem)
        {
            if (elem is Autodesk.Revit.DB.Wall)
            {
                return true;
            }
            return false;
        }
        //要素の面やエッジなどジオメトリへの参照を選択できるかどうかのメソッド
        public bool AllowReference(Reference reference, XYZ position)
        {
            return false;
        }
    }

}
