/*******************************************************************************
 * 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.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;
  }

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

  private ExcelStyles _styles;

  /// <summary>
  /// Creates a new instance of the ExcelWorkbook class.
  /// </summary>
  /// <param name="package">The parent package</param>
  /// <param name="namespaceManager">NamespaceManager</param>
  internal ExcelWorkbook(ExcelPackage package, XmlNamespaceManager namespaceManager)
      : base(namespaceManager) {
    _package = package;

    _names = new(this);
    _namespaceManager = namespaceManager;
    TopNode = WorkbookXml.DocumentElement;
    SchemaNodeOrder = new[] {
      "fileVersion",
      "fileSharing",
      "workbookPr",
      "workbookProtection",
      "bookViews",
      "sheets",
      "functionGroups",
      "functionPrototypes",
      "externalReferences",
      "definedNames",
      "calcPr",
      "oleSize",
      "customWorkbookViews",
      "pivotCaches",
      "smartTagPr",
      "smartTagTypes",
      "webPublishing",
      "fileRecoveryPr",
    };
    FullCalcOnLoad = true; //Full calculation on load by default, for both new workbooks and templates.
    GetSharedStrings();
  }

  internal Dictionary<string, SharedStringItem> _sharedStrings = new(); //Used when reading cells.
  internal List<SharedStringItem> _sharedStringsList = new(); //Used when reading cells.
  internal ExcelNamedRangeCollection _names;
  internal int _nextDrawingID = 0;
  internal int _nextTableID = int.MinValue;
  internal int _nextPivotTableID = int.MinValue;
  internal XmlNamespaceManager _namespaceManager;
  internal FormulaParser _formulaParser;
  internal 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.GetXmlFromUri(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 {
    get {
      if (_protection == null) {
        _protection = new(NameSpaceManager, TopNode, this);
        _protection.SchemaNodeOrder = SchemaNodeOrder;
      }
      return _protection;
    }
  }

  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>
  internal static Uri StylesUri { get; } = new("/xl/styles.xml", UriKind.Relative);

  /// <summary>
  /// URI to the shared strings inside the package
  /// </summary>
  internal 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));

  private XmlDocument _workbookXml;

  /// <summary>
  /// Provides access to the XML data representing the workbook in the package.
  /// </summary>
  public XmlDocument WorkbookXml {
    get {
      if (_workbookXml == null) {
        CreateWorkbookXml(_namespaceManager);
      }
      return (_workbookXml);
    }
  }

  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);
    }
  }

  /// <summary>
  /// Create or read the XML for the workbook.
  /// </summary>
  private void CreateWorkbookXml(XmlNamespaceManager namespaceManager) {
    if (_package.Package.PartExists(WorkbookUri)) {
      _workbookXml = _package.GetXmlFromUri(WorkbookUri);
    } else {
      // create a new workbook part and add to the package
      ZipPackagePart partWorkbook = _package.Package.CreatePart(
          WorkbookUri,
          "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml",
          _package.Compression);

      // create the workbook
      _workbookXml = new(namespaceManager.NameTable);

      _workbookXml.PreserveWhitespace = ExcelPackage._preserveWhitespace;
      // create the workbook element
      XmlElement wbElem = _workbookXml.CreateElement("workbook", ExcelPackage._schemaMain);

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

      _workbookXml.AppendChild(wbElem);

      // create the bookViews and workbooks element
      XmlElement bookViews = _workbookXml.CreateElement("bookViews", ExcelPackage._schemaMain);
      wbElem.AppendChild(bookViews);
      XmlElement workbookView = _workbookXml.CreateElement(
          "workbookView",
          ExcelPackage._schemaMain);
      bookViews.AppendChild(workbookView);

      // save it to the package
      StreamWriter stream = new StreamWriter(
          partWorkbook.GetStream(FileMode.Create, FileAccess.Write));
      _workbookXml.Save(stream);
    }
  }

  private XmlDocument _stylesXml;

  /// <summary>
  /// Provides access to the XML data representing the styles in the package.
  /// </summary>
  public XmlDocument StylesXml {
    get {
      if (_stylesXml == null) {
        if (_package.Package.PartExists(StylesUri)) {
          _stylesXml = _package.GetXmlFromUri(StylesUri);
        } else {
          // create a new styles part and add to the package
          ZipPackagePart part = _package.Package.CreatePart(
              StylesUri,
              "application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml",
              _package.Compression);
          // create the style sheet

          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>");

          _stylesXml = new();
          _stylesXml.LoadXml(xml.ToString());

          //Save it to the package
          StreamWriter stream = new StreamWriter(part.GetStream(FileMode.Create, FileAccess.Write));

          _stylesXml.Save(stream);
          //stream.Close();

          // create the relationship between the workbook and the new shared strings part
          Part.CreateRelationship(
              UriHelper.GetRelativeUri(WorkbookUri, StylesUri),
              TargetMode.Internal,
              ExcelPackage._schemaRelationships + "/styles");
        }
      }
      return (_stylesXml);
    }
    set => _stylesXml = value;
  }

  /// <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 CALC_MODE_PATH = "d:calcPr/@calcMode";

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

  /// <summary>
  /// Saves the workbook and all its components to the package.
  /// For internal use only!
  /// </summary>
  internal void Save() // Workbook Save
  {
    if (Worksheets.Count == 0) {
      throw new InvalidOperationException("The workbook must contain at least one worksheet");
    }

    DeleteCalcChain();

    const string vbaPartUri = "/xl/vbaProject.bin";
    if (!_package.Package.PartExists(new(vbaPartUri, UriKind.Relative))) {
      if (Part.ContentType != ExcelPackage._contentTypeWorkbookDefault) {
        Part.ContentType = ExcelPackage._contentTypeWorkbookDefault;
      }
    } else {
      if (Part.ContentType != ExcelPackage._contentTypeWorkbookMacroEnabled) {
        Part.ContentType = ExcelPackage._contentTypeWorkbookMacroEnabled;
      }
    }

    UpdateDefinedNamesXml();

    // save the workbook
    if (_workbookXml != null) {
      _package.SavePart(WorkbookUri, _workbookXml);
    }

    // save the properties of the workbook
    if (_properties != null) {
      _properties.Save();
    }

    // save the style sheet
    Styles.UpdateXml();
    _package.SavePart(StylesUri, _stylesXml);

    // 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();
      worksheet.Part.SaveHandler = worksheet.SaveHandler;
    }

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

    // 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;
          }
        }
      }
    }
  }
}
