/*******************************************************************************
 * 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;
using System.Text.RegularExpressions;

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>
  public ExcelAddressBase(string address, ExcelPackage pck, ExcelAddressBase referenceAddress) {
    SetAddress(address);
    SetRcFromTable(pck, referenceAddress);
  }

  internal void SetRcFromTable(ExcelPackage pck, ExcelAddressBase referenceAddress) {
    if (string.IsNullOrEmpty(_wb) && Table != null) {
      foreach (var ws in pck.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 {
    get { return _address; }
  }

  /// <summary>
  /// If the address is a defined name
  /// </summary>
  public bool IsName {
    get { return _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 {
    get {
      return _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 {
    get { return _ws; }
  }

  protected internal List<ExcelAddress> _addresses;

  internal virtual List<ExcelAddress> Addresses {
    get { return _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) {
    double d;
    if (address == "#REF!") {
      return AddressType.Invalid;
    }
    if (double.TryParse(
        address,
        NumberStyles.Any,
        CultureInfo.InvariantCulture,
        out d)) //A double, no valid address
    {
      return AddressType.Invalid;
    }
    if (IsFormula(address)) {
      return AddressType.Formula;
    }
    string wb,
        ws,
        intAddress;
    if (SplitAddress(address, out wb, out ws, out 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;

    //if(string.IsNullOrEmpty(wb));
    //ExcelAddress a = new ExcelAddress(Address);
    //if (Address.IndexOf('!') > 0)
    //{
    //    string[] split = Address.Split('!');
    //    if (split.Length == 2)
    //    {
    //        ws = split[0];
    //        Address = split[1];
    //    }
    //    else if (split.Length == 3 && split[1] == "#REF" && split[2] == "")
    //    {
    //        ws = split[0];
    //        Address = "#REF!";
    //        if (ws.StartsWith("[") && ws.IndexOf("]") > 1)
    //        {
    //            return AddressType.ExternalAddress;
    //        }
    //        else
    //        {
    //            return AddressType.InternalAddress;
    //        }
    //    }
    //    else
    //    {
    //        return AddressType.Invalid;
    //    }
    //}
    //int _fromRow, column, _toRow, _toCol;
    //if (ExcelAddressBase.GetRowColFromAddress(Address, out _fromRow, out column, out _toRow, out _toCol))
    //{
    //    if (_fromRow > 0 && column > 0 && _toRow <= ExcelPackage.MaxRows && _toCol <= ExcelPackage.MaxColumns)
    //    {
    //        if (ws.StartsWith("[") && ws.IndexOf("]") > 1)
    //        {
    //            return AddressType.ExternalAddress;
    //        }
    //        else
    //        {
    //            return AddressType.InternalAddress;
    //        }
    //    }
    //    else
    //    {
    //        return AddressType.Invalid;
    //    }
    //}
    //else
    //{
    //    if(IsValidName(Address))
    //    {
    //        if (ws.StartsWith("[") && ws.IndexOf("]") > 1)
    //        {
    //            return AddressType.ExternalName;
    //        }
    //        else
    //        {
    //            return AddressType.InternalName;
    //        }
    //    }
    //    else
    //    {
    //        return AddressType.Invalid;
    //    }
    //}
  }

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

    if (!GetRowCol(cells[0], out fromRow, out 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;
  }

  private static bool IsValidName(string address) {
    if (Regex.IsMatch(
        address,
        "[^0-9./*-+,½!\"@#£%&/{}()\\[\\]=?`^~':;<>|][^/*-+,½!\"@#£%&/{}()\\[\\]=?`^~':;<>|]*")) {
      return true;
    }
    return false;
  }

  public int Rows {
    get { return _toRow - _fromRow + 1; }
  }

  public int Columns {
    get { return _toCol - _fromCol + 1; }
  }

  internal bool IsMultiCell() {
    return (_fromRow < _fromCol || _fromCol < _toCol);
  }

  internal static String GetWorkbookPart(string address) {
    var ix = 0;
    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) {
    int ix = 0;
    return GetWorksheetPart(address, defaultWorkSheet, ref ix);
  }

  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 string GetAddressPart(string address) {
    var ix = 0;
    GetWorksheetPart(address, "", ref ix);
    if (ix < address.Length) {
      if (address[ix] == '!') {
        return address.Substring(ix + 1);
      }
      return "";
    }
    return "";
  }

  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("''");
    var prevStrIx = ix;
    while (strIx > -1) {
      prevStrIx = strIx;
      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, ExcelPackage package, ExcelAddressBase referenceAddress)
      : base(address, package, 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;

  internal ExcelFormulaAddress() {}

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

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

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

  internal ExcelFormulaAddress(string ws, string address, bool isName)
      : base(address, isName) {
    if (string.IsNullOrEmpty(_ws)) {
      _ws = ws;
    }
    if (!isName) {
      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;
  }
}
