using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Runtime;
using System.Collections.Generic;
 
#pragma warning disable 0618
 
// This line is not mandatory, but improves loading performances
[assembly: CommandClass(typeof(Rivilis.ScanXrefs))]
 
namespace Rivilis
{
  public class ScanXrefs
  {
    [CommandMethod("RemoveAllXrefs")]
    public void RemoveAllXrefs()
    {
      Document doc = Application.DocumentManager.MdiActiveDocument;
      if (doc == null) return;
      Editor ed = doc.Editor;
      Database db = doc.Database;
      List<ObjectId> idsXref = new List<ObjectId>(); // Внешние ссылки
      List<ObjectId> idsLocked = new List<ObjectId>(); // Блокированные слои
      // Отбираем блокированные слои и сразу их разблокируем
      using (LayerTable lt = db.LayerTableId.Open(OpenMode.ForRead) as LayerTable)
      {
        foreach (ObjectId idLay in lt)
        {
          using (LayerTableRecord ltr = idLay.Open(OpenMode.ForRead) as LayerTableRecord)
          {
            if (ltr.IsLocked)
            {
              ltr.UpgradeOpen();
              ltr.IsLocked = false;
              idsLocked.Add(idLay);
            }
          }
        }
      }
      // Отбираем внешние ссылки
      using (BlockTable bt = db.BlockTableId.Open(OpenMode.ForRead) as BlockTable)
      {
        foreach (ObjectId idBtr in bt)
        {
          using (BlockTableRecord btr = idBtr.Open(OpenMode.ForRead) as BlockTableRecord)
          {
            if (btr.IsFromExternalReference)
              idsXref.Add(idBtr);
          }
        }
      }
      // Удаляем внешние ссылки
      foreach (ObjectId idBtr in idsXref)
      {
        using (BlockTableRecord btr = idBtr.Open(OpenMode.ForRead) as BlockTableRecord)
        {
          // Находим все вставки внешних ссылок и удаляем их
          ObjectIdCollection idsBrefs = btr.GetBlockReferenceIds(false, true);
          foreach (ObjectId idBref in idsBrefs)
            using (DBObject bref = idBref.Open(OpenMode.ForWrite))
              bref.Erase();
        }
        // Удаляем саму внешнюю ссылку
        db.DetachXref(idBtr);
      }
      // Блокируем слои, которые были заблокированы до запуска команды
      // но небыли удалены при удалении внешних ссылок
      foreach (ObjectId idLay in idsLocked)
          if (!idLay.IsErased)
          using (LayerTableRecord ltr = idLay.Open(OpenMode.ForWrite) as LayerTableRecord)
            ltr.IsLocked = true;
    }
  }
}