/*******************************************************************************
 * 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		Added		18-MAR-2010
 * Jan Källman		License changed GPL-->LGPL 2011-12-16
 *******************************************************************************/

using System;
using System.Collections.Generic;
using System.Globalization;

namespace OfficeOpenXml;

public class ExcelTableAddress {
  public string Name { get; set; }

  public string ColumnSpan { get; set; }

  public bool IsAll { get; set; }

  public bool IsHeader { get; set; }

  public bool IsData { get; set; }

  public bool IsTotals { get; set; }

  public bool IsThisRow { get; set; }
}

/// <summary>
/// A range address
/// </summary>
/// <remarks>Examples of addresses are "A1" "B1:C2" "A:A" "1:1" "A1:E2,G3:G5" </remarks>
public class ExcelAddressBase : ExcelCellBase {
  protected internal int _fromRow = -1,
      _toRow,
      _fromCol,
      _toCol;
  protected internal bool _fromRowFixed,
      _fromColFixed,
      _toRowFixed,
      _toColFixed;
  protected internal string _wb;
  protected internal string _ws;
  protected internal string _address;

  protected internal event EventHandler AddressChange;

  internal enum eAddressCollition {
    No,
    Partly,
    Inside,
    Equal,
  }

  internal enum eShiftType {
    Right,
    Down,
    EntireRow,
    EntireColumn,
  }

  internal ExcelAddressBase() {}

  /// <summary>
  /// Creates an Address object
  /// </summary>
  /// <param name="fromRow">start row</param>
  /// <param name="fromCol">start column</param>
  /// <param name="toRow">End row</param>
  /// <param name="toColumn">End column</param>
  public ExcelAddressBase(int fromRow, int fromCol, int toRow, int toColumn) {
    _fromRow = fromRow;
    _toRow = toRow;
    _fromCol = fromCol;
    _toCol = toColumn;
    Validate();

    _address = GetAddress(_fromRow, _fromCol, _toRow, _toCol);
  }

  /// <summary>
  /// Creates an Address object
  /// </summary>
  /// <param name="fromRow">start row</param>
  /// <param name="fromCol">start column</param>
  /// <param name="toRow">End row</param>
  /// <param name="toColumn">End column</param>
  /// <param name="fromRowFixed">start row fixed</param>
  /// <param name="fromColFixed">start column fixed</param>
  /// <param name="toRowFixed">End row fixed</param>
  /// <param name="toColFixed">End column fixed</param>
  public ExcelAddressBase(
      int fromRow,
      int fromCol,
      int toRow,
      int toColumn,
      bool fromRowFixed,
      bool fromColFixed,
      bool toRowFixed,
      bool toColFixed) {
    _fromRow = fromRow;
    _toRow = toRow;
    _fromCol = fromCol;
    _toCol = toColumn;
    _fromRowFixed = fromRowFixed;
    _fromColFixed = fromColFixed;
    _toRowFixed = toRowFixed;
    _toColFixed = toColFixed;
    Validate();

    _address = GetAddress(
        _fromRow,
        _fromCol,
        _toRow,
        _toCol,
        _fromRowFixed,
        fromColFixed,
        _toRowFixed,
        _toColFixed);
  }

  /// <summary>
  /// Creates an Address object
  /// </summary>
  /// <remarks>Examples of addresses are "A1" "B1:C2" "A:A" "1:1" "A1:E2,G3:G5" </remarks>
  /// <param name="address">The Excel Address</param>
  public ExcelAddressBase(string address) {
    SetAddress(address);
  }

  /// <summary>
  /// Creates an Address object
  /// </summary>
  /// <remarks>Examples of addresses are "A1" "B1:C2" "A:A" "1:1" "A1:E2,G3:G5" </remarks>
  /// <param name="address">The Excel Address</param>
  /// <param name="pck">Reference to the package to find information about tables and names</param>
  /// <param name="referenceAddress">The address</param>
  protected ExcelAddressBase(
      string address,
      ExcelWorkbook workbook,
      ExcelAddressBase referenceAddress) {
    SetAddress(address);
    SetRcFromTable(workbook, referenceAddress);
  }

  internal void SetRcFromTable(ExcelWorkbook workbook, ExcelAddressBase referenceAddress) {
    if (string.IsNullOrEmpty(_wb) && Table != null) {
      foreach (var ws in workbook.Worksheets) {
        foreach (var t in ws.Tables) {
          if (t.Name.Equals(Table.Name, StringComparison.InvariantCultureIgnoreCase)) {
            _ws = ws.Name;
            if (Table.IsAll) {
              _fromRow = t.Address._fromRow;
              _toRow = t.Address._toRow;
            } else {
              if (Table.IsThisRow) {
                if (referenceAddress == null) {
                  _fromRow = -1;
                  _toRow = -1;
                } else {
                  _fromRow = referenceAddress._fromRow;
                  _toRow = _fromRow;
                }
              } else if (Table.IsHeader && Table.IsData) {
                _fromRow = t.Address._fromRow;
                _toRow = t.ShowTotal ? t.Address._toRow - 1 : t.Address._toRow;
              } else if (Table.IsData && Table.IsTotals) {
                _fromRow = t.ShowHeader ? t.Address._fromRow + 1 : t.Address._fromRow;
                _toRow = t.Address._toRow;
              } else if (Table.IsHeader) {
                _fromRow = t.ShowHeader ? t.Address._fromRow : -1;
                _toRow = t.ShowHeader ? t.Address._fromRow : -1;
              } else if (Table.IsTotals) {
                _fromRow = t.ShowTotal ? t.Address._toRow : -1;
                _toRow = t.ShowTotal ? t.Address._toRow : -1;
              } else {
                _fromRow = t.ShowHeader ? t.Address._fromRow + 1 : t.Address._fromRow;
                _toRow = t.ShowTotal ? t.Address._toRow - 1 : t.Address._toRow;
              }
            }

            if (string.IsNullOrEmpty(Table.ColumnSpan)) {
              _fromCol = t.Address._fromCol;
              _toCol = t.Address._toCol;
              return;
            }
            var col = t.Address._fromCol;
            var cols = Table.ColumnSpan.Split(':');
            foreach (var c in t.Columns) {
              if (_fromCol <= 0
                  && cols[0]
                      .Equals(
                          c.Name,
                          StringComparison.InvariantCultureIgnoreCase)) //Issue15063 Add invariant igore case
              {
                _fromCol = col;
                if (cols.Length == 1) {
                  _toCol = _fromCol;
                  return;
                }
              } else if (cols.Length > 1
                  && _fromCol > 0
                  && cols[1]
                      .Equals(
                          c.Name,
                          StringComparison.InvariantCultureIgnoreCase)) //Issue15063 Add invariant igore case
              {
                _toCol = col;
                return;
              }

              col++;
            }
          }
        }
      }
    }
  }

  /// <summary>
  /// Address is an defined name
  /// </summary>
  /// <param name="address">the name</param>
  /// <param name="isName">Should always be true</param>
  internal ExcelAddressBase(string address, bool isName) {
    if (isName) {
      _address = address;
      _fromRow = -1;
      _fromCol = -1;
      _toRow = -1;
      _toCol = -1;
      _start = null;
      _end = null;
    } else {
      SetAddress(address);
    }
  }

  protected internal void SetAddress(string address) {
    address = address.Trim();
    if (address.StartsWith("'")) {
      SetWbWs(address);
    } else if (address.StartsWith(
        "[")) //Remove any external reference
    {
      SetWbWs(address);
    } else {
      _address = address;
    }
    if (_address.IndexOfAny(new[] { ',', '!', '[' }) > -1) {
      //Advanced address. Including Sheet or multi or table.
      ExtractAddress(_address);
    } else {
      //Simple address
      GetRowColFromAddress(
          _address,
          out _fromRow,
          out _fromCol,
          out _toRow,
          out _toCol,
          out _fromRowFixed,
          out _fromColFixed,
          out _toRowFixed,
          out _toColFixed);
      _addresses = null;
      _start = null;
      _end = null;
    }
    _address = address;
    Validate();
  }

  internal void ChangeAddress() {
    if (AddressChange != null) {
      AddressChange(this, new());
    }
  }

  private void SetWbWs(string address) {
    int pos = 0;

    // Get Workbook, if any
    if (address[pos] == '[') {
      pos = address.IndexOf("]");
      _wb = address.Substring(1, pos - 1);
      pos++;
    } else {
      _wb = "";
    }

    // Get Worksheet
    if (address[pos] == '\'') {
      int startPos = pos;
      pos = address.IndexOf("'", pos + 1);
      while (pos < address.Length && address[pos + 1] == '\'') {
        pos = address.IndexOf("'", pos + 2);
      }
      _ws = address.Substring(startPos + 1, pos - startPos - 1).Replace("''", "'");
      pos++;
    } else {
      int startPos = pos;
      pos = address.IndexOf("!", pos);
      if (pos > -1) {
        _ws = address.Substring(startPos, pos - startPos);
      }
    }

    // Get Address
    pos = address.IndexOf("!", pos);
    if (pos > -1) {
      _address = address.Substring(pos + 1);
    } else {
      _address = "";
    }
  }

  internal void ChangeWorksheet(string wsName, string newWs) {
    if (_ws == wsName) {
      _ws = newWs;
    }
    var fullAddress = GetAddress();

    if (Addresses != null) {
      foreach (var a in Addresses) {
        if (a._ws == wsName) {
          a._ws = newWs;
          fullAddress += "," + a.GetAddress();
        } else {
          fullAddress += "," + a._address;
        }
      }
    }
    _address = fullAddress;
  }

  private string GetAddress() {
    var adr = "";
    if (string.IsNullOrEmpty(_wb)) {
      adr = "[" + _wb + "]";
    }

    if (string.IsNullOrEmpty(_ws)) {
      adr += string.Format("'{0}'!", _ws);
    }
    adr += GetAddress(_fromRow, _fromCol, _toRow, _toCol);
    return adr;
  }

  private ExcelCellAddress _start;

  /// <summary>
  /// Gets the row and column of the top left cell.
  /// </summary>
  /// <value>The start row column.</value>
  public ExcelCellAddress Start {
    get {
      if (_start == null) {
        _start = new(_fromRow, _fromCol);
      }
      return _start;
    }
  }

  private ExcelCellAddress _end;

  /// <summary>
  /// Gets the row and column of the bottom right cell.
  /// </summary>
  /// <value>The end row column.</value>
  public ExcelCellAddress End {
    get {
      if (_end == null) {
        _end = new(_toRow, _toCol);
      }
      return _end;
    }
  }

  private ExcelTableAddress _table;

  public ExcelTableAddress Table => _table;

  /// <summary>
  /// The address for the range
  /// </summary>
  public virtual string Address => _address;

  /// <summary>
  /// If the address is a defined name
  /// </summary>
  public bool IsName => _fromRow < 0;

  /// <summary>
  /// Returns the address text
  /// </summary>
  /// <returns></returns>
  public override string ToString() {
    return _address;
  }

  private string _firstAddress;

  /// <summary>
  /// returns the first address if the address is a multi address.
  /// A1:A2,B1:B2 returns A1:A2
  /// </summary>
  internal string FirstAddress {
    get {
      if (string.IsNullOrEmpty(_firstAddress)) {
        return _address;
      }
      return _firstAddress;
    }
  }

  internal string AddressSpaceSeparated => _address.Replace(',', ' '); //Conditional formatting and a few other places use space as separator for mulit addresses.

  /// <summary>
  /// Validate the address
  /// </summary>
  protected void Validate() {
    if (_fromRow > _toRow || _fromCol > _toCol) {
      throw new ArgumentOutOfRangeException(
          "Start cell Address must be less or equal to End cell address");
    }
  }

  internal string WorkSheet => _ws;

  protected internal List<ExcelAddress> _addresses;

  internal virtual List<ExcelAddress> Addresses => _addresses;

  private bool ExtractAddress(string fullAddress) {
    var brackPos = new Stack<int>();
    var bracketParts = new List<string>();
    string first = "",
        second = "";
    bool isText = false,
        hasSheet = false;
    try {
      if (fullAddress == "#REF!") {
        SetAddress(ref fullAddress, ref second, ref hasSheet);
        return true;
      }
      if (fullAddress.StartsWith("!")) {
        // invalid address!
        return false;
      }
      for (int i = 0; i < fullAddress.Length; i++) {
        var c = fullAddress[i];
        if (c == '\'') {
          if (isText && i + 1 < fullAddress.Length && fullAddress[i] == '\'') {
            if (hasSheet) {
              second += c;
            } else {
              first += c;
            }
          }
          isText = !isText;
        } else {
          if (brackPos.Count > 0) {
            if (c == '[' && !isText) {
              brackPos.Push(i);
            } else if (c == ']' && !isText) {
              if (brackPos.Count > 0) {
                var from = brackPos.Pop();
                bracketParts.Add(fullAddress.Substring(from + 1, i - from - 1));

                if (brackPos.Count == 0) {
                  HandleBrackets(first, second, bracketParts);
                }
              } else {
                //Invalid address!
                return false;
              }
            }
          } else if (c == '[' && !isText) {
            brackPos.Push(i);
          } else if (c == '!' && !isText && !first.EndsWith("#REF") && !second.EndsWith("#REF")) {
            hasSheet = true;
          } else if (c == ',' && !isText) {
            SetAddress(ref first, ref second, ref hasSheet);
          } else {
            if (hasSheet) {
              second += c;
            } else {
              first += c;
            }
          }
        }
      }
      if (Table == null) {
        SetAddress(ref first, ref second, ref hasSheet);
      }
      return true;
    } catch {
      return false;
    }
  }

  private void HandleBrackets(string first, string second, List<string> bracketParts) {
    if (!string.IsNullOrEmpty(first)) {
      _table = new();
      Table.Name = first;
      foreach (var s in bracketParts) {
        if (s.IndexOf("[") < 0) {
          switch (s.ToLower(CultureInfo.InvariantCulture)) {
            case "#all":
              _table.IsAll = true;
              break;
            case "#headers":
              _table.IsHeader = true;
              break;
            case "#data":
              _table.IsData = true;
              break;
            case "#totals":
              _table.IsTotals = true;
              break;
            case "#this row":
              _table.IsThisRow = true;
              break;
            default:
              if (string.IsNullOrEmpty(_table.ColumnSpan)) {
                _table.ColumnSpan = s;
              } else {
                _table.ColumnSpan += ":" + s;
              }
              break;
          }
        }
      }
    }
  }

  internal eAddressCollition Collide(ExcelAddressBase address) {
    if (address.WorkSheet != WorkSheet && address.WorkSheet != null) {
      return eAddressCollition.No;
    }

    if (address._fromRow > _toRow
        || address._fromCol > _toCol
        || _fromRow > address._toRow
        || _fromCol > address._toCol) {
      return eAddressCollition.No;
    }
    if (address._fromRow == _fromRow
        && address._fromCol == _fromCol
        && address._toRow == _toRow
        && address._toCol == _toCol) {
      return eAddressCollition.Equal;
    }
    if (address._fromRow >= _fromRow
        && address._toRow <= _toRow
        && address._fromCol >= _fromCol
        && address._toCol <= _toCol) {
      return eAddressCollition.Inside;
    }
    return eAddressCollition.Partly;
  }

  internal ExcelAddressBase AddRow(int row, int rows, bool setFixed = false) {
    if (row > _toRow) {
      return this;
    }
    if (row <= _fromRow) {
      return new(
          (setFixed && _fromRowFixed ? _fromRow : _fromRow + rows),
          _fromCol,
          (setFixed && _toRowFixed ? _toRow : _toRow + rows),
          _toCol,
          _fromRowFixed,
          _fromColFixed,
          _toRowFixed,
          _toColFixed);
    }
    return new(
        _fromRow,
        _fromCol,
        (setFixed && _toRowFixed ? _toRow : _toRow + rows),
        _toCol,
        _fromRowFixed,
        _fromColFixed,
        _toRowFixed,
        _toColFixed);
  }

  internal ExcelAddressBase DeleteRow(int row, int rows, bool setFixed = false) {
    if (row
        > _toRow) //After
    {
      return this;
    }
    if (row + rows
        <= _fromRow) //Before
    {
      return new(
          (setFixed && _fromRowFixed ? _fromRow : _fromRow - rows),
          _fromCol,
          (setFixed && _toRowFixed ? _toRow : _toRow - rows),
          _toCol,
          _fromRowFixed,
          _fromColFixed,
          _toRowFixed,
          _toColFixed);
    }
    if (row <= _fromRow
        && row + rows
            > _toRow) //Inside
    {
      return null;
    } //Partly
    if (row <= _fromRow) {
      return new(
          row,
          _fromCol,
          (setFixed && _toRowFixed ? _toRow : _toRow - rows),
          _toCol,
          _fromRowFixed,
          _fromColFixed,
          _toRowFixed,
          _toColFixed);
    }
    return new(
        _fromRow,
        _fromCol,
        (setFixed && _toRowFixed
                ? _toRow
                : _toRow - rows < row
                    ? row - 1
                    : _toRow - rows),
        _toCol,
        _fromRowFixed,
        _fromColFixed,
        _toRowFixed,
        _toColFixed);
  }

  internal ExcelAddressBase AddColumn(int col, int cols, bool setFixed = false) {
    if (col > _toCol) {
      return this;
    }
    if (col <= _fromCol) {
      return new(
          _fromRow,
          (setFixed && _fromColFixed ? _fromCol : _fromCol + cols),
          _toRow,
          (setFixed && _toColFixed ? _toCol : _toCol + cols),
          _fromRowFixed,
          _fromColFixed,
          _toRowFixed,
          _toColFixed);
    }
    return new(
        _fromRow,
        _fromCol,
        _toRow,
        (setFixed && _toColFixed ? _toCol : _toCol + cols),
        _fromRowFixed,
        _fromColFixed,
        _toRowFixed,
        _toColFixed);
  }

  internal ExcelAddressBase DeleteColumn(int col, int cols, bool setFixed = false) {
    if (col
        > _toCol) //After
    {
      return this;
    }
    if (col + cols
        <= _fromCol) //Before
    {
      return new(
          _fromRow,
          (setFixed && _fromColFixed ? _fromCol : _fromCol - cols),
          _toRow,
          (setFixed && _toColFixed ? _toCol : _toCol - cols),
          _fromRowFixed,
          _fromColFixed,
          _toRowFixed,
          _toColFixed);
    }
    if (col <= _fromCol
        && col + cols
            > _toCol) //Inside
    {
      return null;
    } //Partly
    if (col <= _fromCol) {
      return new(
          _fromRow,
          col,
          _toRow,
          (setFixed && _toColFixed ? _toCol : _toCol - cols),
          _fromRowFixed,
          _fromColFixed,
          _toRowFixed,
          _toColFixed);
    }
    return new(
        _fromRow,
        _fromCol,
        _toRow,
        (setFixed && _toColFixed
                ? _toCol
                : _toCol - cols < col
                    ? col - 1
                    : _toCol - cols),
        _fromRowFixed,
        _fromColFixed,
        _toRowFixed,
        _toColFixed);
  }

  internal ExcelAddressBase Insert(
      ExcelAddressBase address,
      eShiftType shift /*, out ExcelAddressBase topAddress, out ExcelAddressBase leftAddress, out ExcelAddressBase rightAddress, out ExcelAddressBase bottomAddress*/) {
    //Before or after, no change
    //if ((_toRow > address._fromRow && _toCol > address.column) ||
    //    (_fromRow > address._toRow && column > address._toCol))
    if (_toRow < address._fromRow
        || _toCol < address._fromCol
        || (_fromRow > address._toRow && _fromCol > address._toCol)) {
      //topAddress = null;
      //leftAddress = null;
      //rightAddress = null;
      //bottomAddress = null;
      return this;
    }

    int rows = address.Rows;
    int cols = address.Columns;
    string retAddress = "";
    if (shift == eShiftType.Right) {
      if (address._fromRow > _fromRow) {
        retAddress = GetAddress(
            _fromRow,
            _fromCol,
            address._fromRow,
            _toCol,
            _fromRowFixed,
            _fromColFixed,
            _toRowFixed,
            _toColFixed);
      }
      if (address._fromCol > _fromCol) {
        retAddress = GetAddress(
            _fromRow < address._fromRow ? _fromRow : address._fromRow,
            _fromCol,
            address._fromRow,
            _toCol,
            _fromRowFixed,
            _fromColFixed,
            _toRowFixed,
            _toColFixed);
      }
    }
    if (_toRow < address._fromRow) {
      if (_fromRow < address._fromRow) {}
    }
    return null;
  }

  private void SetAddress(ref string first, ref string second, ref bool hasSheet) {
    string ws,
        address;
    if (hasSheet) {
      ws = first;
      address = second;
      first = "";
      second = "";
    } else {
      address = first;
      ws = "";
      first = "";
    }
    hasSheet = false;
    if (string.IsNullOrEmpty(_firstAddress)) {
      if (string.IsNullOrEmpty(_ws) || !string.IsNullOrEmpty(ws)) {
        _ws = ws;
      }
      _firstAddress = address;
      GetRowColFromAddress(
          address,
          out _fromRow,
          out _fromCol,
          out _toRow,
          out _toCol,
          out _fromRowFixed,
          out _fromColFixed,
          out _toRowFixed,
          out _toColFixed);
    } else {
      if (_addresses == null) {
        _addresses = new();
      }
      _addresses.Add(new(_ws, address));
    }
  }

  internal enum AddressType {
    Invalid,
    InternalAddress,
    ExternalAddress,
    InternalName,
    ExternalName,
    Formula,
  }

  internal static AddressType IsValid(string address) {
    if (address == "#REF!") {
      return AddressType.Invalid;
    }
    if (double.TryParse(
        address,
        NumberStyles.Any,
        CultureInfo.InvariantCulture,
        out _)) //A double, no valid address
    {
      return AddressType.Invalid;
    }
    if (IsFormula(address)) {
      return AddressType.Formula;
    }
    if (SplitAddress(address, out var wb, out _, out var intAddress)) {
      if (intAddress.Contains(
          "[")) //Table reference
      {
        return string.IsNullOrEmpty(wb) ? AddressType.InternalAddress : AddressType.ExternalAddress;
      }
      if (intAddress.Contains(",")) {
        intAddress = intAddress.Substring(0, intAddress.IndexOf(','));
      }
      if (IsAddress(intAddress)) {
        return string.IsNullOrEmpty(wb) ? AddressType.InternalAddress : AddressType.ExternalAddress;
      }
      return string.IsNullOrEmpty(wb) ? AddressType.InternalName : AddressType.ExternalName;
    }
    return AddressType.Invalid;
  }

  private static bool IsAddress(string intAddress) {
    if (string.IsNullOrEmpty(intAddress)) {
      return false;
    }
    var cells = intAddress.Split(':');
    int toRow,
        toCol;

    if (!GetRowCol(cells[0], out var fromRow, out var fromCol, false)) {
      return false;
    }
    if (cells.Length > 1) {
      if (!GetRowCol(cells[1], out toRow, out toCol, false)) {
        return false;
      }
    } else {
      toRow = fromRow;
      toCol = fromCol;
    }
    if (fromRow <= toRow
        && fromCol <= toCol
        && fromCol > -1
        && toCol <= ExcelPackage.MaxColumns
        && fromRow > -1
        && toRow <= ExcelPackage.MaxRows) {
      return true;
    }
    return false;
  }

  private static bool SplitAddress(
      string address,
      out string wb,
      out string ws,
      out string intAddress) {
    wb = "";
    ws = "";
    intAddress = "";
    var text = "";
    bool isText = false;
    var brackPos = -1;
    for (int i = 0; i < address.Length; i++) {
      if (address[i] == '\'') {
        isText = !isText;
        if (i > 0 && address[i - 1] == '\'') {
          text += "'";
        }
      } else {
        if (address[i] == '!' && !isText) {
          if (text.Length > 0 && text[0] == '[') {
            wb = text.Substring(1, text.IndexOf("]") - 1);
            ws = text.Substring(text.IndexOf("]") + 1);
          } else {
            ws = text;
          }
          intAddress = address.Substring(i + 1);
          return true;
        }
        if (address[i] == '[' && !isText) {
          if (i
              > 0) //Table reference return full address;
          {
            intAddress = address;
            return true;
          }
          brackPos = i;
        } else if (address[i] == ']' && !isText) {
          if (brackPos > -1) {
            wb = text;
            text = "";
          } else {
            return false;
          }
        } else {
          text += address[i];
        }
      }
    }
    intAddress = text;
    return true;
  }

  private static bool IsFormula(string address) {
    var isText = false;
    for (int i = 0; i < address.Length; i++) {
      if (address[i] == '\'') {
        isText = !isText;
      } else {
        if (isText == false
            && address
                .Substring(i, 1)
                .IndexOfAny(new[] { '(', ')', '+', '-', '*', '/', '.', '=', '^', '&', '%', '\"' })
                > -1) {
          return true;
        }
      }
    }
    return false;
  }

  public int Rows => _toRow - _fromRow + 1;

  public int Columns => _toCol - _fromCol + 1;

  internal static String GetWorkbookPart(string address) {
    int ix;
    if (address[0] == '[') {
      ix = address.IndexOf(']') + 1;
      if (ix > 0) {
        return address.Substring(1, ix - 2);
      }
    }
    return "";
  }

  internal static string GetWorksheetPart(string address, string defaultWorkSheet, ref int endIx) {
    if (address == "") {
      return defaultWorkSheet;
    }
    var ix = 0;
    if (address[0] == '[') {
      ix = address.IndexOf(']') + 1;
    }
    if (ix > 0 && ix < address.Length) {
      if (address[ix] == '\'') {
        return GetString(address, ix, out endIx);
      }
      var ixEnd = address.IndexOf('!', ix);
      if (ixEnd > ix) {
        return address.Substring(ix, ixEnd - ix);
      }
      return defaultWorkSheet;
    }
    return defaultWorkSheet;
  }

  internal static void SplitAddress(
      string fullAddress,
      out string wb,
      out string ws,
      out string address,
      string defaultWorksheet = "") {
    wb = GetWorkbookPart(fullAddress);
    int ix = 0;
    ws = GetWorksheetPart(fullAddress, defaultWorksheet, ref ix);
    if (ix < fullAddress.Length) {
      if (fullAddress[ix] == '!') {
        address = fullAddress.Substring(ix + 1);
      } else {
        address = fullAddress.Substring(ix);
      }
    } else {
      address = "";
    }
  }

  private static string GetString(string address, int ix, out int endIx) {
    var strIx = address.IndexOf("''");
    while (strIx > -1) {
      strIx = address.IndexOf("''");
    }
    endIx = address.IndexOf("'");
    return address.Substring(ix, endIx - ix).Replace("''", "'");
  }

  internal bool IsValidRowCol() {
    return !(_fromRow > _toRow
            || _fromCol > _toCol
            || _fromRow < 1
            || _fromCol < 1
            || _toRow > ExcelPackage.MaxRows
            || _toCol > ExcelPackage.MaxColumns);
  }
}

/// <summary>
/// Range address with the address property readonly
/// </summary>
public class ExcelAddress : ExcelAddressBase {
  internal ExcelAddress() {}

  public ExcelAddress(int fromRow, int fromCol, int toRow, int toColumn)
      : base(fromRow, fromCol, toRow, toColumn) {
    _ws = "";
  }

  public ExcelAddress(string address)
      : base(address) {}

  internal ExcelAddress(string ws, string address)
      : base(address) {
    if (string.IsNullOrEmpty(_ws)) {
      _ws = ws;
    }
  }

  internal ExcelAddress(string ws, string address, bool isName)
      : base(address, isName) {
    if (string.IsNullOrEmpty(_ws)) {
      _ws = ws;
    }
  }

  public ExcelAddress(string address, ExcelWorkbook workbook, ExcelAddressBase referenceAddress)
      : base(address, workbook, referenceAddress) {}

  /// <summary>
  /// The address for the range
  /// </summary>
  /// <remarks>Examples of addresses are "A1" "B1:C2" "A:A" "1:1" "A1:E2,G3:G5" </remarks>
  public new string Address {
    get {
      if (string.IsNullOrEmpty(_address) && _fromRow > 0) {
        _address = GetAddress(_fromRow, _fromCol, _toRow, _toCol);
      }
      return _address;
    }
    set {
      SetAddress(value);
      ChangeAddress();
    }
  }
}

public class ExcelFormulaAddress : ExcelAddressBase {
  private bool _fromRowFixed,
      _toRowFixed,
      _fromColFixed,
      _toColFixed;

  public ExcelFormulaAddress(int fromRow, int fromCol, int toRow, int toColumn)
      : base(fromRow, fromCol, toRow, toColumn) {
    _ws = "";
  }

  public ExcelFormulaAddress(string address)
      : base(address) {
    SetFixed();
  }

  private void SetFixed() {
    if (Address.IndexOf("[") >= 0) {
      return;
    }
    var address = FirstAddress;
    if (_fromRow == _toRow && _fromCol == _toCol) {
      GetFixed(address, out _fromRowFixed, out _fromColFixed);
    } else {
      var cells = address.Split(':');
      GetFixed(cells[0], out _fromRowFixed, out _fromColFixed);
      GetFixed(cells[1], out _toRowFixed, out _toColFixed);
    }
  }

  private void GetFixed(string address, out bool rowFixed, out bool colFixed) {
    rowFixed = colFixed = false;
    var ix = address.IndexOf('$');
    while (ix > -1) {
      ix++;
      if (ix < address.Length) {
        if (address[ix] >= '0' && address[ix] <= '9') {
          rowFixed = true;
          break;
        }
        colFixed = true;
      }
      ix = address.IndexOf('$', ix);
    }
  }

  /// <summary>
  /// The address for the range
  /// </summary>
  /// <remarks>Examples of addresses are "A1" "B1:C2" "A:A" "1:1" "A1:E2,G3:G5" </remarks>
  public new string Address {
    get {
      if (string.IsNullOrEmpty(_address) && _fromRow > 0) {
        _address = GetAddress(
            _fromRow,
            _fromCol,
            _toRow,
            _toCol,
            _fromRowFixed,
            _toRowFixed,
            _fromColFixed,
            _toColFixed);
      }
      return _address;
    }
    set {
      SetAddress(value);
      ChangeAddress();
      SetFixed();
    }
  }

  internal new List<ExcelFormulaAddress> _addresses;

  public new List<ExcelFormulaAddress> Addresses {
    get {
      if (_addresses == null) {
        _addresses = new();
      }
      return _addresses;
    }
  }

  internal string GetOffset(int row, int column) {
    int fromRow = _fromRow,
        fromCol = _fromCol,
        toRow = _toRow,
        tocol = _toCol;
    var isMulti = (fromRow != toRow || fromCol != tocol);
    if (!_fromRowFixed) {
      fromRow += row;
    }
    if (!_fromColFixed) {
      fromCol += column;
    }
    if (isMulti) {
      if (!_toRowFixed) {
        toRow += row;
      }
      if (!_toColFixed) {
        tocol += column;
      }
    } else {
      toRow = fromRow;
      tocol = fromCol;
    }
    string a = GetAddress(
        fromRow,
        fromCol,
        toRow,
        tocol,
        _fromRowFixed,
        _fromColFixed,
        _toRowFixed,
        _toColFixed);
    if (Addresses != null) {
      foreach (var sa in Addresses) {
        a += "," + sa.GetOffset(row, column);
      }
    }
    return a;
  }
}
