/*******************************************************************************
 * You may amend and distribute as you like, but don't remove this header!
 *
 * EPPlus provides server-side generation of Excel 2007/2010 spreadsheets.
 * See http://www.codeplex.com/EPPlus for details.
 *
 * Copyright (C) 2011  Jan Källman
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.

 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU Lesser General Public License for more details.
 *
 * The GNU Lesser General Public License can be viewed at http://www.opensource.org/licenses/lgpl-license.php
 * If you unfamiliar with this license or have questions about it, here is an http://www.gnu.org/licenses/gpl-faq.html
 *
 * All code and executables are provided "as is" with no warranty either express or implied.
 * The author accepts no liability for any damage or loss of business that this product may cause.
 *
 * Code change notes:
 *
 * Author							Change						Date
 * ******************************************************************************
 * Jan Källman		    Initial Release		       2011-01-01
 * Jan Källman		    License changed GPL-->LGPL 2011-12-27
 * Richard Tallent		Fix escaping of quotes					2012-10-31
 *******************************************************************************/

using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Globalization;
using System.IO;
using System.Text;
using System.Xml;
using OfficeOpenXml.FormulaParsing;
using OfficeOpenXml.FormulaParsing.LexicalAnalysis;
using OfficeOpenXml.Packaging;
using OfficeOpenXml.Utils;

namespace OfficeOpenXml;

/// <summary>
/// How the application should calculate formulas in the workbook
/// </summary>
public enum ExcelCalcMode {
  /// <summary>
  /// Indicates that calculations in the workbook are performed automatically when cell values change.
  /// The application recalculates those cells that are dependent on other cells that contain changed values.
  /// This mode of calculation helps to avoid unnecessary calculations.
  /// </summary>
  Automatic,

  /// <summary>
  /// Indicates tables be excluded during automatic calculation
  /// </summary>
  AutomaticNoTable,

  /// <summary>
  /// Indicates that calculations in the workbook be triggered manually by the user.
  /// </summary>
  Manual,
}

/// <summary>
/// Represents the Excel workbook and provides access to all the
/// document properties and worksheets within the workbook.
/// </summary>
public sealed class ExcelWorkbook : XmlHelper {
  internal class SharedStringItem {
    internal int pos;
    internal string Text;
    internal bool isRichText;
  }

  private readonly ExcelPackage _package;
  private ExcelWorksheets _worksheets;
  private OfficeProperties _properties;

  private ExcelStyles _styles;

  internal static ImmutableArray<string> WorkbookSchemaNodeOrder = [
    "fileVersion",
    "fileSharing",
    "workbookPr",
    "workbookProtection",
    "bookViews",
    "sheets",
    "functionGroups",
    "functionPrototypes",
    "externalReferences",
    "definedNames",
    "calcPr",
    "oleSize",
    "customWorkbookViews",
    "pivotCaches",
    "smartTagPr",
    "smartTagTypes",
    "webPublishing",
    "fileRecoveryPr",
  ];

  protected override ImmutableArray<string> SchemaNodeOrder => WorkbookSchemaNodeOrder;

  internal ExcelWorkbook(ExcelPackage package, XmlNamespaceManager namespaceManager)
      : base(namespaceManager) {
    _package = package;
    _names = new(this);
    _namespaceManager = namespaceManager;

    WorkbookXml = package.GetOrCreateXmlDocument(
        WorkbookUri,
        "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml",
        ExcelPackage._schemaRelationships + "/officeDocument",
        () => CreateEmptyWorkbookXml(namespaceManager));
    _stylesXml = package.GetOrCreateXmlDocument(
        StylesUri,
        "application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml",
        ExcelPackage._schemaRelationships + "/styles",
        CreateEmptyStylesXml);

    TopNode = WorkbookXml.DocumentElement;
    FullCalcOnLoad = true; //Full calculation on load by default, for both new workbooks and templates.

    GetSharedStrings();
    GetExternalReferences();
    GetDefinedNames();
  }

  private static XmlDocument CreateEmptyWorkbookXml(XmlNamespaceManager namespaceManager) {
    var result = new XmlDocument(namespaceManager.NameTable);
    var wbElem = result.CreateElement("workbook", ExcelPackage._schemaMain);

    // Add the relationships namespace
    wbElem.SetAttribute("xmlns:r", ExcelPackage._schemaRelationships);
    result.AppendChild(wbElem);

    // Create the bookViews and workbooks element
    var bookViews = result.CreateElement("bookViews", ExcelPackage._schemaMain);
    wbElem.AppendChild(bookViews);
    var workbookView = result.CreateElement("workbookView", ExcelPackage._schemaMain);
    bookViews.AppendChild(workbookView);

    return result;
  }

  private static XmlDocument CreateEmptyStylesXml() {
    StringBuilder xml = new StringBuilder(
        "<styleSheet xmlns=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\">");
    xml.Append("<numFmts />");
    xml.Append("<fonts count=\"1\"><font><sz val=\"11\" /><name val=\"Calibri\" /></font></fonts>");
    xml.Append(
        "<fills><fill><patternFill patternType=\"none\" /></fill><fill><patternFill patternType=\"gray125\" /></fill></fills>");
    xml.Append(
        "<borders><border><left /><right /><top /><bottom /><diagonal /></border></borders>");
    xml.Append("<cellStyleXfs count=\"1\"><xf numFmtId=\"0\" fontId=\"0\" /></cellStyleXfs>");
    xml.Append("<cellXfs count=\"1\"><xf numFmtId=\"0\" fontId=\"0\" xfId=\"0\" /></cellXfs>");
    xml.Append("<cellStyles><cellStyle name=\"Normal\" xfId=\"0\" builtinId=\"0\" /></cellStyles>");
    xml.Append("<dxfs count=\"0\" />");
    xml.Append("</styleSheet>");

    var result = new XmlDocument();
    result.LoadXml(xml.ToString());
    return result;
  }

  internal readonly Dictionary<string, SharedStringItem> _sharedStrings = new(); //Used when reading cells.
  internal List<SharedStringItem> _sharedStringsList = new(); //Used when reading cells.
  internal ExcelNamedRangeCollection _names;
  internal int _nextTableID = int.MinValue;
  internal int _nextPivotTableID = int.MinValue;
  private readonly XmlNamespaceManager _namespaceManager;
  private FormulaParser _formulaParser;
  private FormulaParserManager _parserManager;
  internal CellStore<List<Token>> _formulaTokens;

  /// <summary>
  /// Read shared strings to list
  /// </summary>
  private void GetSharedStrings() {
    if (_package.Package.PartExists(SharedStringsUri)) {
      var xml = _package.GetXmlDocument(SharedStringsUri);
      XmlNodeList nl = xml.SelectNodes("//d:sst/d:si", NameSpaceManager);
      _sharedStringsList = new();
      if (nl != null) {
        foreach (XmlNode node in nl) {
          XmlNode n = node.SelectSingleNode("d:t", NameSpaceManager);
          if (n != null) {
            _sharedStringsList.Add(
                new() {
                  Text = ConvertUtil.ExcelDecodeString(n.InnerText),
                });
          } else {
            _sharedStringsList.Add(
                new() {
                  Text = node.InnerXml,
                  isRichText = true,
                });
          }
        }
      }
      //Delete the shared string part, it will be recreated when the package is saved.
      foreach (var rel in Part.GetRelationships()) {
        if (rel.TargetUri.OriginalString.EndsWith(
            "sharedstrings.xml",
            StringComparison.InvariantCultureIgnoreCase)) {
          Part.DeleteRelationship(rel.Id);
          break;
        }
      }
      _package.Package.DeletePart(SharedStringsUri); //Remove the part, it is recreated when saved.
    }
  }

  internal void GetDefinedNames() {
    XmlNodeList nl = WorkbookXml.SelectNodes("//d:definedNames/d:definedName", NameSpaceManager);
    if (nl != null) {
      foreach (XmlElement elem in nl) {
        string fullAddress = elem.InnerText;

        ExcelWorksheet nameWorksheet;
        if (!int.TryParse(elem.GetAttribute("localSheetId"), out var localSheetId)) {
          localSheetId = -1;
          nameWorksheet = null;
        } else {
          nameWorksheet = Worksheets[localSheetId + 1];
        }
        var addressType = ExcelAddressBase.IsValid(fullAddress);
        ExcelRangeBase range;
        ExcelNamedRange namedRange;

        if (fullAddress.IndexOf("[") == 0) {
          int start = fullAddress.IndexOf("[");
          int end = fullAddress.IndexOf("]", start);
          if (start >= 0 && end >= 0) {
            string externalIndex = fullAddress.Substring(start + 1, end - start - 1);
            if (int.TryParse(externalIndex, out var index)) {
              if (index > 0 && index <= _externalReferences.Count) {
                fullAddress =
                    fullAddress.Substring(0, start)
                        + "["
                        + _externalReferences[index - 1]
                        + "]"
                        + fullAddress.Substring(end + 1);
              }
            }
          }
        }

        if (addressType == ExcelAddressBase.AddressType.Invalid
            || addressType == ExcelAddressBase.AddressType.InternalName
            || addressType == ExcelAddressBase.AddressType.ExternalName
            || addressType == ExcelAddressBase.AddressType.Formula
            || addressType
                == ExcelAddressBase
                    .AddressType
                    .ExternalAddress) //A value or a formula
        {
          range = new(this, nameWorksheet, elem.GetAttribute("name"), true);
          if (nameWorksheet == null) {
            namedRange = _names.Add(elem.GetAttribute("name"), range);
          } else {
            namedRange = nameWorksheet.Names.Add(elem.GetAttribute("name"), range);
          }

          if (fullAddress.StartsWith(
              "\"")) //String value
          {
            namedRange.NameValue = fullAddress.Substring(1, fullAddress.Length - 2);
          } else if (double.TryParse(
              fullAddress,
              NumberStyles.Any,
              CultureInfo.InvariantCulture,
              out var value)) {
            namedRange.NameValue = value;
          } else {
            //if (addressType == ExcelAddressBase.AddressType.ExternalAddress || addressType == ExcelAddressBase.AddressType.ExternalName)
            //{
            //    var r = new ExcelAddress(fullAddress);
            //    namedRange.NameFormula = '\'[' + r._wb
            //}
            //else
            //{
            namedRange.NameFormula = fullAddress;
            //}
          }
        } else {
          ExcelAddress addr = new ExcelAddress(fullAddress, this, null);
          if (localSheetId > -1) {
            if (string.IsNullOrEmpty(addr._ws)) {
              namedRange = Worksheets[localSheetId + 1].Names.Add(
                  elem.GetAttribute("name"),
                  new(this, Worksheets[localSheetId + 1], fullAddress, false));
            } else {
              namedRange = Worksheets[localSheetId + 1].Names.Add(
                  elem.GetAttribute("name"),
                  new(this, Worksheets[addr._ws], fullAddress, false));
            }
          } else {
            var ws = Worksheets[addr._ws];
            namedRange = _names.Add(elem.GetAttribute("name"), new(this, ws, fullAddress, false));
          }
        }
        if (elem.GetAttribute("hidden") == "1" && namedRange != null) {
          namedRange.IsNameHidden = true;
        }
        if (!string.IsNullOrEmpty(elem.GetAttribute("comment"))) {
          namedRange.NameComment = elem.GetAttribute("comment");
        }
      }
    }
  }

  /// <summary>
  /// Provides access to all the worksheets in the workbook.
  /// </summary>
  public ExcelWorksheets Worksheets {
    get {
      if (_worksheets == null) {
        var sheetsNode = WorkbookXml.DocumentElement.SelectSingleNode(
            "d:sheets",
            _namespaceManager);
        if (sheetsNode == null) {
          sheetsNode = CreateNode("d:sheets");
        }

        _worksheets = new(_package, this, _namespaceManager, sheetsNode);
      }
      return (_worksheets);
    }
  }

  /// <summary>
  /// Provides access to named ranges
  /// </summary>
  public ExcelNamedRangeCollection Names => _names;

  internal FormulaParser FormulaParser {
    get {
      if (_formulaParser == null) {
        _formulaParser = new(new EpplusExcelDataProvider(this));
      }
      return _formulaParser;
    }
  }

  public FormulaParserManager FormulaParserManager {
    get {
      if (_parserManager == null) {
        _parserManager = new(FormulaParser);
      }
      return _parserManager;
    }
  }

  private ExcelProtection _protection;

  /// <summary>
  /// Access properties to protect or unprotect a workbook
  /// </summary>
  public ExcelProtection Protection => _protection ??= new(NameSpaceManager, TopNode);

  private ExcelWorkbookView _view;

  /// <summary>
  /// Access to workbook view properties
  /// </summary>
  public ExcelWorkbookView View {
    get {
      if (_view == null) {
        _view = new(NameSpaceManager, TopNode, this);
      }
      return _view;
    }
  }

  /// <summary>
  /// URI to the workbook inside the package
  /// </summary>
  internal static Uri WorkbookUri { get; } = new("/xl/workbook.xml", UriKind.Relative);

  /// <summary>
  /// URI to the styles inside the package
  /// </summary>
  private static Uri StylesUri { get; } = new("/xl/styles.xml", UriKind.Relative);

  /// <summary>
  /// URI to the shared strings inside the package
  /// </summary>
  private static Uri SharedStringsUri { get; } = new("/xl/sharedStrings.xml", UriKind.Relative);

  /// <summary>
  /// Returns a reference to the workbook's part within the package
  /// </summary>
  internal ZipPackagePart Part => (_package.Package.GetPart(WorkbookUri));

  /// <summary>
  /// Provides access to the XML data representing the workbook in the package.
  /// </summary>
  internal XmlDocument WorkbookXml { get; }

  private const string _codeModuleNamePath = "d:workbookPr/@codeName";

  internal string CodeModuleName {
    get => GetXmlNodeString(_codeModuleNamePath);
    set => SetXmlNodeString(_codeModuleNamePath, value);
  }

  internal void CodeNameChange(string value) {
    CodeModuleName = value;
  }

  private const string _date1904Path = "d:workbookPr/@date1904";
  internal const double _date1904Offset = 365.5 * 4; // offset to fix 1900 and 1904 differences, 4 OLE years

  /// <summary>
  /// The date systems used by Microsoft Excel can be based on one of two different dates. By default, a serial number of 1 in Microsoft Excel represents January 1, 1900.
  /// The default for the serial number 1 can be changed to represent January 2, 1904.
  /// This option was included in Microsoft Excel for Windows to make it compatible with Excel for the Macintosh, which defaults to January 2, 1904.
  /// </summary>
  public bool Date1904 {
    get => GetXmlNodeBool(_date1904Path, false);
    set {
      if (Date1904 != value) {
        // Like Excel when the option it's changed update it all cells with Date format
        foreach (var item in Worksheets) {
          item.UpdateCellsWithDate1904Setting();
        }
      }

      SetXmlNodeBool(_date1904Path, value, false);
    }
  }

  private readonly XmlDocument _stylesXml;

  /// <summary>
  /// Package styles collection. Used internally to access style data.
  /// </summary>
  public ExcelStyles Styles {
    get {
      if (_styles == null) {
        _styles = new(NameSpaceManager, _stylesXml, this);
      }
      return _styles;
    }
  }

  /// <summary>
  /// The office document properties
  /// </summary>
  public OfficeProperties Properties {
    get {
      if (_properties == null) {
        //  Create a NamespaceManager to handle the default namespace,
        //  and create a prefix for the default namespace:
        _properties = new(_package, NameSpaceManager);
      }
      return _properties;
    }
  }

  private readonly string _calcModePath = "d:calcPr/@calcMode";

  /// <summary>
  /// Calculation mode for the workbook.
  /// </summary>
  public ExcelCalcMode CalcMode {
    get {
      string calcMode = GetXmlNodeString(_calcModePath);
      switch (calcMode) {
        case "autoNoTable":
          return ExcelCalcMode.AutomaticNoTable;
        case "manual":
          return ExcelCalcMode.Manual;
        default:
          return ExcelCalcMode.Automatic;
      }
    }
    set {
      switch (value) {
        case ExcelCalcMode.AutomaticNoTable:
          SetXmlNodeString(_calcModePath, "autoNoTable");
          break;
        case ExcelCalcMode.Manual:
          SetXmlNodeString(_calcModePath, "manual");
          break;
        default:
          SetXmlNodeString(_calcModePath, "auto");
          break;
      }
    }
  }

  private const string _fullCalcOnLoadPath = "d:calcPr/@fullCalcOnLoad";

  /// <summary>
  /// Should Excel do a full calculation after the workbook has been loaded?
  /// <remarks>This property is always true for both new workbooks and loaded templates(on load). If this is not the wanted behavior set this property to false.</remarks>
  /// </summary>
  public bool FullCalcOnLoad {
    get => GetXmlNodeBool(_fullCalcOnLoadPath);
    set => SetXmlNodeBool(_fullCalcOnLoadPath, value);
  }

  internal void Save() {
    if (Worksheets.Count == 0) {
      throw new InvalidOperationException("The workbook must contain at least one worksheet");
    }

    DeleteCalcChain();
    UpdateDefinedNamesXml();

    // save the style sheet
    Styles.UpdateXml();

    // save all the open worksheets
    var isProtected = Protection.LockWindows || Protection.LockStructure;
    foreach (ExcelWorksheet worksheet in Worksheets) {
      if (isProtected && Protection.LockWindows) {
        worksheet.View.WindowProtection = true;
      }
      worksheet.Save();
    }

    _package.Package.CreatePart(
        SharedStringsUri,
        ExcelPackage._contentTypeSharedString,
        SaveSharedStringHandler);
    Part.CreateRelationship(
        UriHelper.GetRelativeUri(WorkbookUri, SharedStringsUri),
        TargetMode.Internal,
        ExcelPackage._schemaRelationships + "/sharedStrings");

    // Data validation
    ValidateDataValidations();
  }

  private void DeleteCalcChain() {
    //Remove the calc chain if it exists.
    Uri uriCalcChain = new Uri("/xl/calcChain.xml", UriKind.Relative);
    if (_package.Package.PartExists(uriCalcChain)) {
      Uri calcChain = new Uri("calcChain.xml", UriKind.Relative);
      foreach (var relationship in Part.GetRelationships()) {
        if (relationship.TargetUri == calcChain) {
          Part.DeleteRelationship(relationship.Id);
          break;
        }
      }
      // delete the calcChain part
      _package.Package.DeletePart(uriCalcChain);
    }
  }

  private void ValidateDataValidations() {
    foreach (var sheet in Worksheets) {
      if (!(sheet is ExcelChartsheet)) {
        sheet.DataValidations.ValidateAll();
      }
    }
  }

  private void SaveSharedStringHandler(StreamWriter sw) {
    var cache = new StringBuilder();
    cache.AppendFormat(
        "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\" ?><sst xmlns=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\" count=\"{0}\" uniqueCount=\"{0}\">",
        _sharedStrings.Count);
    foreach (string t in _sharedStrings.Keys) {
      SharedStringItem ssi = _sharedStrings[t];
      if (ssi.isRichText) {
        cache.Append("<si>");
        ConvertUtil.ExcelEncodeString(cache, t);
        cache.Append("</si>");
      } else {
        if (t.Length > 0
            && (t[0] == ' '
                    || t[t.Length - 1] == ' '
                    || t.Contains("  ")
                    || t.Contains("\t")
                    || t.Contains("\n")
                    || t.Contains(
                        "\n"))) //Fixes issue 14849
        {
          cache.Append("<si><t xml:space=\"preserve\">");
        } else {
          cache.Append("<si><t>");
        }
        ConvertUtil.ExcelEncodeString(cache, ConvertUtil.ExcelEscapeString(t));
        cache.Append("</t></si>");
      }
      if (cache.Length > 0x600000) {
        sw.Write(cache.ToString());
        cache = new();
      }
    }
    cache.Append("</sst>");
    sw.Write(cache.ToString());
    sw.Flush();
    Part.CreateRelationship(
        UriHelper.GetRelativeUri(WorkbookUri, SharedStringsUri),
        TargetMode.Internal,
        ExcelPackage._schemaRelationships + "/sharedStrings");
  }

  private void UpdateDefinedNamesXml() {
    try {
      XmlNode top = WorkbookXml.SelectSingleNode("//d:definedNames", NameSpaceManager);
      if (!ExistsNames()) {
        if (top != null) {
          TopNode.RemoveChild(top);
        }
        return;
      }
      if (top == null) {
        CreateNode("d:definedNames");
        top = WorkbookXml.SelectSingleNode("//d:definedNames", NameSpaceManager);
      } else {
        top.RemoveAll();
      }
      foreach (ExcelNamedRange name in _names) {
        XmlElement elem = WorkbookXml.CreateElement("definedName", ExcelPackage._schemaMain);
        top.AppendChild(elem);
        elem.SetAttribute("name", name.Name);
        if (name.IsNameHidden) {
          elem.SetAttribute("hidden", "1");
        }
        if (!string.IsNullOrEmpty(name.NameComment)) {
          elem.SetAttribute("comment", name.NameComment);
        }
        SetNameElement(name, elem);
      }
      foreach (ExcelWorksheet ws in _worksheets) {
        if (!(ws is ExcelChartsheet)) {
          foreach (ExcelNamedRange name in ws.Names) {
            XmlElement elem = WorkbookXml.CreateElement("definedName", ExcelPackage._schemaMain);
            top.AppendChild(elem);
            elem.SetAttribute("name", name.Name);
            elem.SetAttribute("localSheetId", name.LocalSheetId.ToString());
            if (name.IsNameHidden) {
              elem.SetAttribute("hidden", "1");
            }
            if (!string.IsNullOrEmpty(name.NameComment)) {
              elem.SetAttribute("comment", name.NameComment);
            }
            SetNameElement(name, elem);
          }
        }
      }
    } catch (Exception ex) {
      throw new("Internal error updating named ranges ", ex);
    }
  }

  private void SetNameElement(ExcelNamedRange name, XmlElement elem) {
    if (name.IsName) {
      if (string.IsNullOrEmpty(name.NameFormula)) {
        if ((name.NameValue.GetType().IsPrimitive
                    || name.NameValue is double
                    || name.NameValue is decimal)) {
          elem.InnerText = Convert
              .ToDouble(name.NameValue, CultureInfo.InvariantCulture)
              .ToString("R15", CultureInfo.InvariantCulture);
        } else if (name.NameValue is DateTime time) {
          elem.InnerText = time.ToOADate().ToString(CultureInfo.InvariantCulture);
        } else {
          elem.InnerText = "\"" + name.NameValue + "\"";
        }
      } else {
        elem.InnerText = name.NameFormula;
      }
    } else {
      elem.InnerText = name.FullAddressAbsolute;
    }
  }

  /// <summary>
  /// Is their any names in the workbook or in the sheets.
  /// </summary>
  /// <returns>?</returns>
  private bool ExistsNames() {
    if (_names.Count == 0) {
      foreach (ExcelWorksheet ws in Worksheets) {
        if (ws is ExcelChartsheet) {
          continue;
        }
        if (ws.Names.Count > 0) {
          return true;
        }
      }
    } else {
      return true;
    }
    return false;
  }

  internal bool ExistsTableName(string name) {
    foreach (var ws in Worksheets) {
      if (ws.Tables._tableNames.ContainsKey(name)) {
        return true;
      }
    }
    return false;
  }

  internal bool ExistsPivotTableName(string name) {
    foreach (var ws in Worksheets) {
      if (ws.PivotTables._pivotTableNames.ContainsKey(name)) {
        return true;
      }
    }
    return false;
  }

  internal void AddPivotTable(string cacheId, Uri defUri) {
    CreateNode("d:pivotCaches");

    XmlElement item = WorkbookXml.CreateElement("pivotCache", ExcelPackage._schemaMain);
    item.SetAttribute("cacheId", cacheId);
    var rel = Part.CreateRelationship(
        UriHelper.ResolvePartUri(WorkbookUri, defUri),
        TargetMode.Internal,
        ExcelPackage._schemaRelationships + "/pivotCacheDefinition");
    item.SetAttribute("id", ExcelPackage._schemaRelationships, rel.Id);

    var pivotCaches = WorkbookXml.SelectSingleNode("//d:pivotCaches", NameSpaceManager);
    pivotCaches.AppendChild(item);
  }

  internal List<string> _externalReferences = new();

  //internal bool _isCalculated=false;
  internal void GetExternalReferences() {
    XmlNodeList nl = WorkbookXml.SelectNodes(
        "//d:externalReferences/d:externalReference",
        NameSpaceManager);
    if (nl != null) {
      foreach (XmlElement elem in nl) {
        string rId = elem.GetAttribute("r:id");
        var rel = Part.GetRelationship(rId);
        var part = _package.Package.GetPart(UriHelper.ResolvePartUri(rel.SourceUri, rel.TargetUri));
        XmlDocument xmlExtRef = new XmlDocument();
        LoadXmlSafe(xmlExtRef, part.GetStream());

        XmlElement book =
            xmlExtRef.SelectSingleNode("//d:externalBook", NameSpaceManager) as XmlElement;
        if (book != null) {
          string rIdExtRef = book.GetAttribute("r:id");
          var relExtRef = part.GetRelationship(rIdExtRef);
          if (relExtRef != null) {
            _externalReferences.Add(relExtRef.TargetUri.OriginalString);
          }
        }
      }
    }
  }

  internal void ReadAllTables() {
    if (_nextTableID > 0) {
      return;
    }
    _nextTableID = 1;
    _nextPivotTableID = 1;
    foreach (var ws in Worksheets) {
      if (!(ws
                  is ExcelChartsheet)) //Fixes 15273. Chartsheets should be ignored.
      {
        foreach (var tbl in ws.Tables) {
          if (tbl.Id >= _nextTableID) {
            _nextTableID = tbl.Id + 1;
          }
        }
        foreach (var pt in ws.PivotTables) {
          if (pt.CacheID >= _nextPivotTableID) {
            _nextPivotTableID = pt.CacheID + 1;
          }
        }
      }
    }
  }
}
