/*******************************************************************************
 * 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>
  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) {
    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 ws;
    if (SplitAddress(address, out var wb, out ws, 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;

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

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