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

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

using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.Security;
using System.Text;
using System.Xml;
using OfficeOpenXml.ConditionalFormatting;
using OfficeOpenXml.DataValidation;
using OfficeOpenXml.FormulaParsing.LexicalAnalysis;
using OfficeOpenXml.Style;
using OfficeOpenXml.Style.XmlAccess;

namespace OfficeOpenXml;

/// <summary>
/// A range of cells
/// </summary>
public class ExcelRangeBase
    : ExcelAddress,
      IExcelCell,
      IDisposable,
      IEnumerable<ExcelRangeBase>,
      IEnumerator<ExcelRangeBase> {
  /// <summary>
  /// Reference to the worksheet
  /// </summary>
  protected ExcelWorksheet _worksheet;
  internal ExcelWorkbook _workbook;

  private delegate void ChangePropHandler(SetValueHandler method, object value);

  private delegate void SetValueHandler(object value, int row, int col);

  private ChangePropHandler _changePropMethod;
  private int _styleID;

  private class CopiedCell {
    internal int Row { get; set; }

    internal int Column { get; set; }

    internal object Value { get; set; }

    internal string Type { get; set; }

    internal object Formula { get; set; }

    internal int? StyleID { get; set; }

    internal Uri HyperLink { get; set; }

    internal ExcelComment Comment { get; set; }

    internal Byte Flag { get; set; }
  }

  //private class CopiedFlag
  //{
  //    internal int Row { get; set; }
  //    internal int Column { get; set; }
  //    internal Byte Flag { get; set; }
  //}


  internal ExcelRangeBase(ExcelWorksheet worksheet) {
    _worksheet = worksheet;
    _ws = _worksheet.Name;
    _workbook = _worksheet.Workbook;
    AddressChange += ExcelRangeBase_AddressChange;
    SetDelegate();
  }

  private void ExcelRangeBase_AddressChange(object sender, EventArgs e) {
    if (Table != null) {
      SetRcFromTable(_workbook, null);
    }
    SetDelegate();
  }

  internal ExcelRangeBase(ExcelWorksheet worksheet, string address)
      : base(worksheet == null ? "" : worksheet.Name, address) {
    _worksheet = worksheet;
    _workbook = worksheet.Workbook;
    SetRcFromTable(_workbook, null);
    if (string.IsNullOrEmpty(_ws)) {
      _ws = _worksheet == null ? "" : _worksheet.Name;
    }
    AddressChange += ExcelRangeBase_AddressChange;
    SetDelegate();
  }

  internal ExcelRangeBase(ExcelWorkbook wb, ExcelWorksheet xlWorksheet, string address, bool isName)
      : base(xlWorksheet == null ? "" : xlWorksheet.Name, address, isName) {
    SetRcFromTable(wb, null);
    _worksheet = xlWorksheet;
    _workbook = wb;
    if (string.IsNullOrEmpty(_ws)) {
      _ws = xlWorksheet?.Name;
    }
    AddressChange += ExcelRangeBase_AddressChange;
    SetDelegate();
  }

  ~ExcelRangeBase() {
    //this.AddressChange -= new EventHandler(ExcelRangeBase_AddressChange);
  }

  private void SetDelegate() {
    if (_fromRow == -1) {
      _changePropMethod = SetUnknown;
    }
    //Single cell
    else if (_fromRow == _toRow && _fromCol == _toCol && Addresses == null) {
      _changePropMethod = SetSingle;
    }
    //Range (ex A1:A2)
    else if (Addresses == null) {
      _changePropMethod = SetRange;
    }
    //Multi Range (ex A1:A2,C1:C2)
    else {
      _changePropMethod = SetMultiRange;
    }
  }

  /// <summary>
  /// We dont know the address yet. Set the delegate first time a property is set.
  /// </summary>
  /// <param name="valueMethod"></param>
  /// <param name="value"></param>
  private void SetUnknown(SetValueHandler valueMethod, object value) {
    //Address is not set use, selected range
    if (_fromRow == -1) {
      SetToSelectedRange();
    }
    SetDelegate();
    _changePropMethod(valueMethod, value);
  }

  /// <summary>
  /// Set a single cell
  /// </summary>
  /// <param name="valueMethod"></param>
  /// <param name="value"></param>
  private void SetSingle(SetValueHandler valueMethod, object value) {
    valueMethod(value, _fromRow, _fromCol);
  }

  /// <summary>
  /// Set a range
  /// </summary>
  /// <param name="valueMethod"></param>
  /// <param name="value"></param>
  private void SetRange(SetValueHandler valueMethod, object value) {
    SetValueAddress(this, valueMethod, value);
  }

  /// <summary>
  /// Set a multirange (A1:A2,C1:C2)
  /// </summary>
  /// <param name="valueMethod"></param>
  /// <param name="value"></param>
  private void SetMultiRange(SetValueHandler valueMethod, object value) {
    SetValueAddress(this, valueMethod, value);
    foreach (var address in Addresses) {
      SetValueAddress(address, valueMethod, value);
    }
  }

  /// <summary>
  /// Set the property for an address
  /// </summary>
  /// <param name="address"></param>
  /// <param name="valueMethod"></param>
  /// <param name="value"></param>
  private void SetValueAddress(ExcelAddress address, SetValueHandler valueMethod, object value) {
    IsRangeValid("");
    if (_fromRow == 1
        && _fromCol == 1
        && _toRow == ExcelPackage.MaxRows
        && _toCol
            == ExcelPackage.MaxColumns) //Full sheet (ex ws.Cells.Value=0). Set value for A1 only to avoid hanging
    {
      throw (new ArgumentException(
              "Can't reference all cells. Please use the indexer to set the range"));
    }
    for (int col = address.Start.Column; col <= address.End.Column; col++) {
      for (int row = address.Start.Row; row <= address.End.Row; row++) {
        valueMethod(value, row, col);
      }
    }
  }

  private void Set_StyleID(object value, int row, int col) {
    _worksheet._styles.SetValue(row, col, (int)value);
  }

  private void Set_Value(object value, int row, int col) {
    //ExcelCell c = _worksheet.Cell(row, col);
    var sfi = _worksheet._formulas.GetValue(row, col);
    if (sfi is int) {
      SplitFormulas(_worksheet.Cells[row, col]);
    }
    if (sfi != null) {
      _worksheet._formulas.SetValue(row, col, string.Empty);
    }
    _worksheet._values.SetValue(row, col, value);
  }

  private void Set_Formula(object value, int row, int col) {
    //ExcelCell c = _worksheet.Cell(row, col);
    var f = _worksheet._formulas.GetValue(row, col);
    if (f is int i && i >= 0) {
      SplitFormulas(_worksheet.Cells[row, col]);
    }

    string formula = (value == null ? string.Empty : value.ToString());
    if (formula == string.Empty) {
      _worksheet._formulas.SetValue(row, col, string.Empty);
    } else {
      if (formula[0] == '=') {
        value = formula.Substring(1, formula.Length - 1); // remove any starting equalsign.
      }
      _worksheet._formulas.SetValue(row, col, formula);
      _worksheet._values.SetValue(row, col, null);
    }
  }

  /// <summary>
  /// Handles shared formulas
  /// </summary>
  /// <param name="value">The  formula</param>
  /// <param name="address">The address of the formula</param>
  /// <param name="isArray">If the forumla is an array formula.</param>
  private void Set_SharedFormula(string value, ExcelAddress address, bool isArray) {
    if (_fromRow == 1
        && _fromCol == 1
        && _toRow == ExcelPackage.MaxRows
        && _toCol
            == ExcelPackage.MaxColumns) //Full sheet (ex ws.Cells.Value=0). Set value for A1 only to avoid hanging
    {
      throw (new InvalidOperationException("Can't set a formula for the entire worksheet"));
    }
    if (address.Start.Row == address.End.Row
        && address.Start.Column == address.End.Column
        && !isArray) //is it really a shared formula? Arrayformulas can be one cell only
    {
      //Nope, single cell. Set the formula
      Set_Formula(value, address.Start.Row, address.Start.Column);
      return;
    }
    //RemoveFormuls(address);
    CheckAndSplitSharedFormula(address);
    ExcelWorksheet.Formulas f = new ExcelWorksheet.Formulas(SourceCodeTokenizer.Default);
    f.Formula = value;
    f.Index = _worksheet.GetMaxShareFunctionIndex(isArray);
    f.Address = address.FirstAddress;
    f.StartCol = address.Start.Column;
    f.StartRow = address.Start.Row;
    f.IsArray = isArray;

    _worksheet._sharedFormulas.Add(f.Index, f);
    //_worksheet.Cell(address.Start.Row, address.Start.Column).SharedFormulaID = f.Index;
    //_worksheet.Cell(address.Start.Row, address.Start.Column).Formula = value;

    for (int col = address.Start.Column; col <= address.End.Column; col++) {
      for (int row = address.Start.Row; row <= address.End.Row; row++) {
        //_worksheet.Cell(row, col).SharedFormulaID = f.Index;
        _worksheet._formulas.SetValue(row, col, f.Index);
        _worksheet._values.SetValue(row, col, null);
      }
    }
  }

  private void Set_HyperLink(object value, int row, int col) {
    //_worksheet.Cell(row, col).Hyperlink = value as Uri;
    if (value is Uri uri) {
      _worksheet._hyperLinks.SetValue(row, col, uri);

      if (uri is ExcelHyperLink link) {
        _worksheet._values.SetValue(row, col, link.Display);
      } else {
        _worksheet._values.SetValue(row, col, uri.OriginalString);
      }
    } else {
      _worksheet._hyperLinks.SetValue(row, col, null);
      _worksheet._values.SetValue(row, col, null);
    }
  }

  private void Set_IsArrayFormula(object value, int row, int col) {
    _worksheet._flags.SetFlagValue(row, col, (bool)value, CellFlags.ArrayFormula);
  }

  private void Set_IsRichText(object value, int row, int col) {
    //_worksheet.Cell(row, col).IsRichText = (bool)value;
    _worksheet._flags.SetFlagValue(row, col, (bool)value, CellFlags.RichText);
  }

  private void Exists_Comment(object value, int row, int col) {
    ulong cellId = GetCellId(_worksheet.SheetID, row, col);
    if (_worksheet.Comments._comments.ContainsKey(cellId)) {
      throw (new InvalidOperationException(
              string.Format(
                  "Cell {0} already contain a comment.",
                  new ExcelCellAddress(row, col).Address)));
    }
  }

  private void SetToSelectedRange() {
    if (_worksheet.View.SelectedRange == "") {
      Address = "A1";
    } else {
      Address = _worksheet.View.SelectedRange;
    }
  }

  private void IsRangeValid(string type) {
    if (_fromRow <= 0) {
      if (_address == "") {
        SetToSelectedRange();
      } else {
        if (type == "") {
          throw (new InvalidOperationException(
                  string.Format("Range is not valid for this operation: {0}", _address)));
        }
        throw (new InvalidOperationException(
                string.Format("Range is not valid for {0} : {1}", type, _address)));
      }
    }
  }

  /// <summary>
  /// The styleobject for the range.
  /// </summary>
  public ExcelStyle Style {
    get {
      IsRangeValid("styling");
      int s = 0;
      if (!_worksheet._styles.Exists(
          _fromRow,
          _fromCol,
          ref s)) //Cell exists
      {
        if (!_worksheet._styles.Exists(
            _fromRow,
            0,
            ref s)) //No, check Row style
        {
          var c = Worksheet.GetColumn(_fromCol);
          if (c == null) {
            s = 0;
          } else {
            s = c.StyleID;
          }
        }
      }
      return _worksheet.Workbook.Styles.GetStyleObject(s, _worksheet.PositionID, Address);
    }
  }

  /// <summary>
  /// The named style
  /// </summary>
  public string StyleName {
    get {
      IsRangeValid("styling");
      int xfId;
      if (_fromRow == 1 && _toRow == ExcelPackage.MaxRows) {
        xfId = GetColumnStyle(_fromCol);
      } else if (_fromCol == 1 && _toCol == ExcelPackage.MaxColumns) {
        xfId = 0;
        if (!_worksheet._styles.Exists(_fromRow, 0, ref xfId)) {
          xfId = GetColumnStyle(_fromCol);
        }
      } else {
        xfId = 0;
        if (!_worksheet._styles.Exists(_fromRow, _fromCol, ref xfId)) {
          if (!_worksheet._styles.Exists(_fromRow, 0, ref xfId)) {
            xfId = GetColumnStyle(_fromCol);
          }
        }
      }
      int nsId;
      if (xfId <= 0) {
        nsId = Style.Styles.CellXfs[0].XfId;
      } else {
        nsId = Style.Styles.CellXfs[xfId].XfId;
      }
      foreach (var ns in Style.Styles.NamedStyles) {
        if (ns.StyleXfId == nsId) {
          return ns.Name;
        }
      }

      return "";
    }
    set {
      _styleID = _worksheet.Workbook.Styles.GetStyleIdFromName(value);
      int col = _fromCol;
      if (_fromRow == 1
          && _toRow
              == ExcelPackage.MaxRows) //Full column
      {
        ExcelColumn column;
        //Get the startcolumn
        //ulong colID = ExcelColumn.GetColumnID(_worksheet.SheetID, column);
        var c = _worksheet.GetValue(0, _fromCol);
        if (c == null) {
          column = _worksheet.Column(_fromCol);
          //if (_worksheet._values.PrevCell(ref row, ref col))
          //{
          //    var prevCol = (ExcelColumn)_worksheet._values.GetValue(row, col);
          //    column = prevCol.Clone(_worksheet, column);
          //    prevCol.ColumnMax = column - 1;
          //}
        } else {
          column = (ExcelColumn)c;
        }

        column.StyleName = value;
        column.StyleID = _styleID;

        //var index = _worksheet._columns.IndexOf(colID);
        var cols = new CellsStoreEnumerator<object>(_worksheet._values, 0, _fromCol + 1, 0, _toCol);
        if (cols.Next()) {
          col = _fromCol;
          while (column.ColumnMin <= _toCol) {
            if (column.ColumnMax > _toCol) {
              var newCol = _worksheet.CopyColumn(column, _toCol + 1, column.ColumnMax);
              column.ColumnMax = _toCol;
            }

            column._styleName = value;
            column.StyleID = _styleID;

            if (cols.Value == null) {
              break;
            }
            var nextCol = (ExcelColumn)cols.Value;
            if (column.ColumnMax < nextCol.ColumnMax - 1) {
              column.ColumnMax = nextCol.ColumnMax - 1;
            }
            column = nextCol;
            cols.Next();
          }
        }
        if (column.ColumnMax < _toCol) {
          column.ColumnMax = _toCol;
        }
        //if (column.ColumnMin == column)
        //{
        //    column.ColumnMax = _toCol;
        //}
        //else if (column._columnMax < _toCol)
        //{
        //    var newCol = _worksheet.Column(column._columnMax + 1) as ExcelColumn;
        //    newCol._columnMax = _toCol;

        //    newCol._styleID = _styleID;
        //    newCol._styleName = value;
        //}
        if (_fromCol == 1
            && _toCol
                == ExcelPackage.MaxColumns) //FullRow
        {
          var rows = new CellsStoreEnumerator<object>(
              _worksheet._values,
              1,
              0,
              ExcelPackage.MaxRows,
              0);
          rows.Next();
          while (rows.Value != null) {
            _worksheet._styles.SetValue(rows.Row, 0, _styleID);
            if (!rows.Next()) {
              break;
            }
          }
        }
      } else if (_fromCol == 1
          && _toCol
              == ExcelPackage.MaxColumns) //FullRow
      {
        for (int r = _fromRow; r <= _toRow; r++) {
          _worksheet.Row(r)._styleName = value;
          _worksheet.Row(r).StyleID = _styleID;
        }
      }

      if (!((_fromRow == 1 && _toRow == ExcelPackage.MaxRows)
                  || (_fromCol == 1
                          && _toCol
                              == ExcelPackage.MaxColumns))) //Cell specific
      {
        for (int c = _fromCol; c <= _toCol; c++) {
          for (int r = _fromRow; r <= _toRow; r++) {
            _worksheet._styles.SetValue(r, c, _styleID);
          }
        }
      } else //Only set name on created cells. (uncreated cells is set on full row or full column).
      {
        var cells = new CellsStoreEnumerator<object>(
            _worksheet._values,
            _fromRow,
            _fromCol,
            _toRow,
            _toCol);
        while (cells.Next()) {
          _worksheet._styles.SetValue(cells.Row, cells.Column, _styleID);
        }
      }
      //_changePropMethod(Set_StyleName, value);
    }
  }

  private int GetColumnStyle(int col) {
    object c = null;
    if (_worksheet._values.Exists(0, col, ref c)) {
      return (c as ExcelColumn).StyleID;
    }
    int row = 0;
    if (_worksheet._values.PrevCell(ref row, ref col)) {
      var column = _worksheet._values.GetValue(row, col) as ExcelColumn;
      if (column.ColumnMax >= col) {
        return _worksheet._styles.GetValue(row, col);
      }
    }
    return 0;
  }

  /// <summary>
  /// The style ID.
  /// It is not recomended to use this one. Use Named styles as an alternative.
  /// If you do, make sure that you use the Style.UpdateXml() method to update any new styles added to the workbook.
  /// </summary>
  public int StyleID {
    get {
      int s = 0;
      if (!_worksheet._styles.Exists(_fromRow, _fromCol, ref s)) {
        if (!_worksheet._styles.Exists(_fromRow, 0, ref s)) {
          s = _worksheet._styles.GetValue(0, _fromCol);
        }
      }
      return s;
    }
    set => _changePropMethod(Set_StyleID, value);
  }

  /// <summary>
  /// Set the range to a specific value
  /// </summary>
  public object Value {
    get {
      if (IsName) {
        if (_worksheet == null) {
          return _workbook._names[_address].NameValue;
        }
        return _worksheet.Names[_address].NameValue;
      }
      if (_fromRow == _toRow && _fromCol == _toCol) {
        return _worksheet.GetValue(_fromRow, _fromCol);
      }
      return GetValueArray();
    }
    set {
      if (IsName) {
        if (_worksheet == null) {
          _workbook._names[_address].NameValue = value;
        } else {
          _worksheet.Names[_address].NameValue = value;
        }
      } else {
        _changePropMethod(Set_Value, value);
      }
    }
  }

  private object GetValueArray() {
    ExcelAddressBase addr;
    if (_fromRow == 1
        && _fromCol == 1
        && _toRow == ExcelPackage.MaxRows
        && _toCol == ExcelPackage.MaxColumns) {
      addr = _worksheet.Dimension;
      if (addr == null) {
        return null;
      }
    } else {
      addr = this;
    }
    object[,] v = new object[addr._toRow - addr._fromRow + 1, addr._toCol - addr._fromCol + 1];

    for (int col = addr._fromCol; col <= addr._toCol; col++) {
      for (int row = addr._fromRow; row <= addr._toRow; row++) {
        if (_worksheet._values.Exists(row, col)) {
          if (_worksheet._flags.GetFlagValue(row, col, CellFlags.RichText)) {
            v[row - addr._fromRow, col - addr._fromCol] = GetRichText(row, col).Text;
          } else {
            v[row - addr._fromRow, col - addr._fromCol] = _worksheet._values.GetValue(row, col);
          }
        }
      }
    }
    return v;
  }

  /// <summary>
  /// Returns the formatted value.
  /// </summary>
  public string Text => GetFormattedText(false);

  private string GetFormattedText(bool forWidthCalc) {
    object v = Value;
    if (v == null) {
      return "";
    }
    var styles = Worksheet.Workbook.Styles;
    var nfId = styles.CellXfs[StyleID].NumberFormatId;
    ExcelNumberFormatXml.ExcelFormatTranslator nf = null;
    for (int i = 0; i < styles.NumberFormats.Count; i++) {
      if (nfId == styles.NumberFormats[i].NumFmtId) {
        nf = styles.NumberFormats[i].FormatTranslator;
        break;
      }
    }

    string format,
        textFormat;
    if (forWidthCalc) {
      format = nf.NetFormatForWidth;
      textFormat = nf.NetTextFormatForWidth;
    } else {
      format = nf.NetFormat;
      textFormat = nf.NetTextFormat;
    }

    return FormatValue(v, nf, format, textFormat);
  }

  internal static string FormatValue(
      object v,
      ExcelNumberFormatXml.ExcelFormatTranslator nf,
      string format,
      string textFormat) {
    if (v is decimal || v.GetType().IsPrimitive) {
      double d;
      try {
        d = Convert.ToDouble(v);
      } catch {
        return "";
      }

      if (nf.DataType == ExcelNumberFormatXml.eFormatType.Number) {
        if (string.IsNullOrEmpty(nf.FractionFormat)) {
          return d.ToString(format, nf.Culture);
        }
        return nf.FormatFraction(d);
      }
      if (nf.DataType == ExcelNumberFormatXml.eFormatType.DateTime) {
        var date = DateTime.FromOADate(d);
        return date.ToString(format, nf.Culture);
      }
    } else if (v is DateTime time) {
      if (nf.DataType == ExcelNumberFormatXml.eFormatType.DateTime) {
        return time.ToString(format, nf.Culture);
      }
      double d = time.ToOADate();
      if (string.IsNullOrEmpty(nf.FractionFormat)) {
        return d.ToString(format, nf.Culture);
      }
      return nf.FormatFraction(d);
    } else if (v is TimeSpan span) {
      if (nf.DataType == ExcelNumberFormatXml.eFormatType.DateTime) {
        return new DateTime(span.Ticks).ToString(format, nf.Culture);
      }
      double d = (new DateTime(span.Ticks)).ToOADate();
      if (string.IsNullOrEmpty(nf.FractionFormat)) {
        return d.ToString(format, nf.Culture);
      }
      return nf.FormatFraction(d);
    } else {
      if (textFormat == "") {
        return v.ToString();
      }
      return string.Format(textFormat, v);
    }
    return v.ToString();
  }

  /// <summary>
  /// Gets or sets a formula for a range.
  /// </summary>
  public string Formula {
    get {
      if (IsName) {
        if (_worksheet == null) {
          return _workbook._names[_address].NameFormula;
        }
        return _worksheet.Names[_address].NameFormula;
      }
      return _worksheet.GetFormula(_fromRow, _fromCol);
    }
    set {
      if (IsName) {
        if (_worksheet == null) {
          _workbook._names[_address].NameFormula = value;
        } else {
          _worksheet.Names[_address].NameFormula = value;
        }
      } else {
        if (value == null || value.Trim() == "") {
          //Set the cells to null
          Value = null;
        } else if (_fromRow == _toRow && _fromCol == _toCol) {
          Set_Formula(value, _fromRow, _fromCol);
        } else {
          Set_SharedFormula(value, this, false);
          if (Addresses != null) {
            foreach (var address in Addresses) {
              Set_SharedFormula(value, address, false);
            }
          }
        }
      }
    }
  }

  /// <summary>
  /// Gets or Set a formula in R1C1 format.
  /// </summary>
  public string FormulaR1C1 {
    get {
      IsRangeValid("FormulaR1C1");
      return _worksheet.GetFormulaR1C1(_fromRow, _fromCol);
    }
    set {
      IsRangeValid("FormulaR1C1");
      if (value.Length > 0 && value[0] == '=') {
        value = value.Substring(1, value.Length - 1); // remove any starting equalsign.
      }

      if (value == null || value.Trim() == "") {
        //Set the cells to null
        _worksheet.Cells[TranslateFromR1C1(value, _fromRow, _fromCol)].Value = null;
      } else if (Addresses == null) {
        Set_SharedFormula(TranslateFromR1C1(value, _fromRow, _fromCol), this, false);
      } else {
        Set_SharedFormula(
            TranslateFromR1C1(value, _fromRow, _fromCol),
            new(WorkSheet, FirstAddress),
            false);
        foreach (var address in Addresses) {
          Set_SharedFormula(
              TranslateFromR1C1(value, address.Start.Row, address.Start.Column),
              address,
              false);
        }
      }
    }
  }

  /// <summary>
  /// Gets or Set a formula in R1C1 format.
  ///
  public string FormulaR1C1_V1 {
    get {
      IsRangeValid("FormulaR1C1");
      return _worksheet.GetFormulaR1C1_V1(_fromRow, _fromCol);
    }
  }

  public string ArrayFormulaAddress {
    get {
      IsRangeValid("FormulaR1C1");
      return _worksheet.GetArrayFormulaAddress(_fromRow, _fromCol);
    }
  }

  /// <summary>
  /// Set the hyperlink property for a range of cells
  /// </summary>
  public Uri Hyperlink {
    get {
      IsRangeValid("formulaR1C1");
      return _worksheet._hyperLinks.GetValue(_fromRow, _fromCol);
    }
    set => _changePropMethod(Set_HyperLink, value);
  }

  /// <summary>
  /// If the cells in the range are merged.
  /// </summary>
  public bool Merge {
    get {
      IsRangeValid("merging");
      for (int col = _fromCol; col <= _toCol; col++) {
        for (int row = _fromRow; row <= _toRow; row++) {
          if (_worksheet.MergedCells[row, col] == null) {
            return false;
          }
          //if (!_worksheet._flags.GetFlagValue(row, col, CellFlags.Merged))
          //{
          //    return false;
          //}
        }
      }
      return true;
    }
    set {
      IsRangeValid("merging");
      //SetMerge(value, FirstAddress);
      if (value) {
        _worksheet.MergedCells.Add(new(FirstAddress), true);
        if (Addresses != null) {
          foreach (var address in Addresses) {
            _worksheet.MergedCells.Add(address, true);
            //SetMerge(value, address._address);
          }
        }
      } else {
        _worksheet.MergedCells.Clear(this);
        if (Addresses != null) {
          foreach (var address in Addresses) {
            _worksheet.MergedCells.Clear(address);
            ;
          }
        }
      }
    }
  }

  //private void SetMerge(bool value, string address)
  //{
  //    if (!value)
  //    {
  //        if (_worksheet.MergedCells.List.Contains(address))
  //        {
  //            SetCellMerge(false, address);
  //            _worksheet.MergedCells.List.Remove(address);
  //        }
  //        else if (!CheckMergeDiff(false, address))
  //        {
  //            throw (new Exception("Range is not fully merged.Specify the exact range"));
  //        }
  //    }
  //    else
  //    {
  //        if (CheckMergeDiff(false, address))
  //        {
  //            SetCellMerge(true, address);
  //            _worksheet.MergedCells.List.Add(address);
  //        }
  //        else
  //        {
  //            if (!_worksheet.MergedCells.List.Contains(address))
  //            {
  //                throw (new Exception("Cells are already merged"));
  //            }
  //        }
  //    }
  //}
  /// <summary>
  /// Set an autofilter for the range
  /// </summary>
  public bool AutoFilter {
    get {
      IsRangeValid("autofilter");
      ExcelAddressBase address = _worksheet.AutoFilterAddress;
      if (address == null) {
        return false;
      }
      if (_fromRow >= address.Start.Row
          && _toRow <= address.End.Row
          && _fromCol >= address.Start.Column
          && _toCol <= address.End.Column) {
        return true;
      }
      return false;
    }
    set {
      IsRangeValid("autofilter");
      _worksheet.AutoFilterAddress = this;
      if (_worksheet.Names.ContainsKey("_xlnm._FilterDatabase")) {
        _worksheet.Names.Remove("_xlnm._FilterDatabase");
      }
      var result = _worksheet.Names.Add("_xlnm._FilterDatabase", this);
      result.IsNameHidden = true;
    }
  }

  /// <summary>
  /// If the value is in richtext format.
  /// </summary>
  public bool IsRichText {
    get {
      IsRangeValid("richtext");
      return _worksheet._flags.GetFlagValue(_fromRow, _fromCol, CellFlags.RichText);
    }
    set => _changePropMethod(Set_IsRichText, value);
  }

  /// <summary>
  /// Is the range a part of an Arrayformula
  /// </summary>
  public bool IsArrayFormula {
    get {
      IsRangeValid("arrayformulas");
      return _worksheet._flags.GetFlagValue(_fromRow, _fromCol, CellFlags.ArrayFormula);
    }
    set => _changePropMethod(Set_IsArrayFormula, value);
  }

  private ExcelRichTextCollection _rtc;

  /// <summary>
  /// Cell value is richtext formatted.
  /// Richtext-property only apply to the left-top cell of the range.
  /// </summary>
  public ExcelRichTextCollection RichText {
    get {
      IsRangeValid("richtext");
      if (_rtc == null) {
        _rtc = GetRichText(_fromRow, _fromCol);
      }
      return _rtc;
    }
  }

  private ExcelRichTextCollection GetRichText(int row, int col) {
    XmlDocument xml = new XmlDocument();
    var v = _worksheet._values.GetValue(row, col);
    var isRt = _worksheet._flags.GetFlagValue(row, col, CellFlags.RichText);
    if (v != null) {
      if (isRt) {
        XmlHelper.LoadXmlSafe(
            xml,
            "<d:si xmlns:d=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\" >"
                + v
                + "</d:si>",
            Encoding.UTF8);
      } else {
        xml.LoadXml(
            "<d:si xmlns:d=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\" ><d:r><d:t>"
                + SecurityElement.Escape(v.ToString())
                + "</d:t></d:r></d:si>");
      }
    } else {
      xml.LoadXml("<d:si xmlns:d=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\" />");
    }
    var rtc = new ExcelRichTextCollection(
        _worksheet.NameSpaceManager,
        xml.SelectSingleNode("d:si", _worksheet.NameSpaceManager),
        this);
    return rtc;
  }

  /// <summary>
  /// returns the comment object of the first cell in the range
  /// </summary>
  public ExcelComment Comment {
    get {
      IsRangeValid("comments");
      ulong cellId = GetCellId(_worksheet.SheetID, _fromRow, _fromCol);
      if (_worksheet.Comments._comments.ContainsKey(cellId)) {
        return _worksheet._comments._comments[cellId] as ExcelComment;
      }
      return null;
    }
  }

  /// <summary>
  /// WorkSheet object
  /// </summary>
  public ExcelWorksheet Worksheet => _worksheet;

  /// <summary>
  /// Address including sheetname
  /// </summary>
  public string FullAddress {
    get {
      string fullAddress = GetFullAddress(_worksheet.Name, _address);
      if (Addresses != null) {
        foreach (var a in Addresses) {
          fullAddress += "," + GetFullAddress(_worksheet.Name, a.Address);
          ;
        }
      }
      return fullAddress;
    }
  }

  /// <summary>
  /// Address including sheetname
  /// </summary>
  public string FullAddressAbsolute {
    get {
      string wbwsRef = string.IsNullOrEmpty(_wb) ? _ws : "[" + _wb.Replace("'", "''") + "]" + _ws;
      string fullAddress = GetFullAddress(
          wbwsRef,
          GetAddress(_fromRow, _fromCol, _toRow, _toCol, true));
      if (Addresses != null) {
        foreach (var a in Addresses) {
          fullAddress +=
              ","
                  + GetFullAddress(
                      wbwsRef,
                      GetAddress(a.Start.Row, a.Start.Column, a.End.Row, a.End.Column, true));
          ;
        }
      }
      return fullAddress;
    }
  }

  /// <summary>
  /// Address including sheetname
  /// </summary>
  internal string FullAddressAbsoluteNoFullRowCol {
    get {
      string wbwsRef = string.IsNullOrEmpty(_wb) ? _ws : "[" + _wb.Replace("'", "''") + "]" + _ws;
      string fullAddress = GetFullAddress(
          wbwsRef,
          GetAddress(_fromRow, _fromCol, _toRow, _toCol, true),
          false);
      if (Addresses != null) {
        foreach (var a in Addresses) {
          fullAddress +=
              ","
                  + GetFullAddress(
                      wbwsRef,
                      GetAddress(a.Start.Row, a.Start.Column, a.End.Row, a.End.Column, true),
                      false);
          ;
        }
      }
      return fullAddress;
    }
  }

  /// <summary>
  /// Set the value without altering the richtext property
  /// </summary>
  /// <param name="value">the value</param>
  internal void SetValueRichText(object value) {
    if (_fromRow == 1
        && _fromCol == 1
        && _toRow == ExcelPackage.MaxRows
        && _toCol
            == ExcelPackage.MaxColumns) //Full sheet (ex ws.Cells.Value=0). Set value for A1 only to avoid hanging
    {
      //_worksheet.Cell(1, 1).SetValueRichText(value);
      SetValue(value, 1, 1);
    } else {
      //for (int col = _fromCol; col <= _toCol; col++)
      //{
      //    for (int row = _fromRow; row <= _toRow; row++)
      //    {
      //_worksheet.Cell(row, col).SetValueRichText(value);
      SetValue(value, _fromRow, _fromCol);
      //}
      //}
    }
  }

  private void SetValue(object value, int row, int col) {
    _worksheet.SetValue(row, col, value);
    // if (value is string) _worksheet._types.SetValue(row, col, "S"); else _worksheet._types.SetValue(row, col, "");
    _worksheet._formulas.SetValue(row, col, "");
  }

  internal void SetSharedFormulaId(int id) {
    for (int col = _fromCol; col <= _toCol; col++) {
      for (int row = _fromRow; row <= _toRow; row++) {
        _worksheet._formulas.SetValue(row, col, id);
      }
    }
  }

  private void CheckAndSplitSharedFormula(ExcelAddressBase address) {
    for (int col = address._fromCol; col <= address._toCol; col++) {
      for (int row = address._fromRow; row <= address._toRow; row++) {
        var f = _worksheet._formulas.GetValue(row, col);
        if (f is int i && i >= 0) {
          SplitFormulas(address);
          return;
        }
      }
    }
  }

  private void SplitFormulas(ExcelAddressBase address) {
    List<int> formulas = new List<int>();
    for (int col = address._fromCol; col <= address._toCol; col++) {
      for (int row = address._fromRow; row <= address._toRow; row++) {
        var f = _worksheet._formulas.GetValue(row, col);
        if (f is int id) {
          if (id >= 0 && !formulas.Contains(id)) {
            if (_worksheet._sharedFormulas[id].IsArray
                && Collide(_worksheet.Cells[_worksheet._sharedFormulas[id].Address])
                    == eAddressCollition.Partly) // If the formula is an array formula and its on the inside the overwriting range throw an exception
            {
              throw (new InvalidOperationException("Can not overwrite a part of an array-formula"));
            }
            formulas.Add(id);
          }
        }
      }
    }

    foreach (int ix in formulas) {
      SplitFormula(address, ix);
    }

    ////Clear any formula references inside the refered range
    //_worksheet._formulas.Clear(address._fromRow, address._toRow, address._toRow - address._fromRow + 1, address._toCol - address.column + 1);
  }

  private void SplitFormula(ExcelAddressBase address, int ix) {
    var f = _worksheet._sharedFormulas[ix];
    var fRange = _worksheet.Cells[f.Address];
    var collide = address.Collide(fRange);

    //The formula is inside the currenct range, remove it
    if (collide == eAddressCollition.Equal || collide == eAddressCollition.Inside) {
      _worksheet._sharedFormulas.Remove(ix);
      return;
      //fRange.SetSharedFormulaID(int.MinValue);
    }
    var firstCellCollide = address.Collide(
        new(fRange._fromRow, fRange._fromCol, fRange._fromRow, fRange._fromCol));
    if (collide == eAddressCollition.Partly
        && (firstCellCollide == eAddressCollition.Inside
                || firstCellCollide
                    == eAddressCollition.Equal)) //Do we need to split? Only if the functions first row is inside the new range.
    {
      //The formula partly collides with the current range
      bool fIsSet = false;
      string formulaR1C1 = fRange.FormulaR1C1;
      //Top Range
      if (fRange._fromRow < _fromRow) {
        f.Address = GetAddress(fRange._fromRow, fRange._fromCol, _fromRow - 1, fRange._toCol);
        fIsSet = true;
      }
      //Left Range
      if (fRange._fromCol < address._fromCol) {
        if (fIsSet) {
          f = new(SourceCodeTokenizer.Default);
          f.Index = _worksheet.GetMaxShareFunctionIndex(false);
          f.StartCol = fRange._fromCol;
          f.IsArray = false;
          _worksheet._sharedFormulas.Add(f.Index, f);
        } else {
          fIsSet = true;
        }
        if (fRange._fromRow < address._fromRow) {
          f.StartRow = address._fromRow;
        } else {
          f.StartRow = fRange._fromRow;
        }
        if (fRange._toRow < address._toRow) {
          f.Address = GetAddress(f.StartRow, f.StartCol, fRange._toRow, address._fromCol - 1);
        } else {
          f.Address = GetAddress(f.StartRow, f.StartCol, address._toRow, address._fromCol - 1);
        }
        f.Formula = TranslateFromR1C1(formulaR1C1, f.StartRow, f.StartCol);
        _worksheet.Cells[f.Address].SetSharedFormulaId(f.Index);
      }
      //Right Range
      if (fRange._toCol > address._toCol) {
        if (fIsSet) {
          f = new(SourceCodeTokenizer.Default);
          f.Index = _worksheet.GetMaxShareFunctionIndex(false);
          f.IsArray = false;
          _worksheet._sharedFormulas.Add(f.Index, f);
        } else {
          fIsSet = true;
        }
        f.StartCol = address._toCol + 1;
        if (address._fromRow < fRange._fromRow) {
          f.StartRow = fRange._fromRow;
        } else {
          f.StartRow = address._fromRow;
        }

        if (fRange._toRow < address._toRow) {
          f.Address = GetAddress(f.StartRow, f.StartCol, fRange._toRow, fRange._toCol);
        } else {
          f.Address = GetAddress(f.StartRow, f.StartCol, address._toRow, fRange._toCol);
        }
        f.Formula = TranslateFromR1C1(formulaR1C1, f.StartRow, f.StartCol);
        _worksheet.Cells[f.Address].SetSharedFormulaId(f.Index);
      }
      //Bottom Range
      if (fRange._toRow > address._toRow) {
        if (fIsSet) {
          f = new(SourceCodeTokenizer.Default);
          f.Index = _worksheet.GetMaxShareFunctionIndex(false);
          f.IsArray = false;
          _worksheet._sharedFormulas.Add(f.Index, f);
        }

        f.StartCol = fRange._fromCol;
        f.StartRow = _toRow + 1;

        f.Formula = TranslateFromR1C1(formulaR1C1, f.StartRow, f.StartCol);

        f.Address = GetAddress(f.StartRow, f.StartCol, fRange._toRow, fRange._toCol);
        _worksheet.Cells[f.Address].SetSharedFormulaId(f.Index);
      }
    }
  }

  private object ConvertData(ExcelTextFormat format, string v, int col, bool isText) {
    if (isText && (format.DataTypes == null || format.DataTypes.Length < col)) {
      return v;
    }

    double d;
    DateTime dt;
    if (format.DataTypes == null
        || format.DataTypes.Length <= col
        || format.DataTypes[col] == eDataTypes.Unknown) {
      string v2 = v.EndsWith("%") ? v.Substring(0, v.Length - 1) : v;
      if (double.TryParse(v2, NumberStyles.Any, format.Culture, out d)) {
        if (v2 == v) {
          return d;
        }
        return d / 100;
      }
      if (DateTime.TryParse(v, format.Culture, DateTimeStyles.None, out dt)) {
        return dt;
      }
      return v;
    }
    switch (format.DataTypes[col]) {
      case eDataTypes.Number:
        if (double.TryParse(v, NumberStyles.Any, format.Culture, out d)) {
          return d;
        }
        return v;
      case eDataTypes.DateTime:
        if (DateTime.TryParse(v, format.Culture, DateTimeStyles.None, out dt)) {
          return dt;
        }
        return v;
      case eDataTypes.Percent:
        string v2 = v.EndsWith("%") ? v.Substring(0, v.Length - 1) : v;
        if (double.TryParse(v2, NumberStyles.Any, format.Culture, out d)) {
          return d / 100;
        }
        return v;

      default:
        return v;
    }
  }

  /// <summary>
  /// Conditional Formatting for this range.
  /// </summary>
  public IRangeConditionalFormatting ConditionalFormatting =>
    new RangeConditionalFormatting(_worksheet, new(Address));

  /// <summary>
  /// Data validation for this range.
  /// </summary>
  public IRangeDataValidation DataValidation => new RangeDataValidation(_worksheet, Address);

  /// <summary>
  /// Get the strongly typed value of the cell.
  /// </summary>
  /// <typeparam name="T">The type</typeparam>
  /// <returns>The value. If the value can't be converted to the specified type, the default value will be returned</returns>
  public T GetValue<T>() {
    return _worksheet.GetTypedValue<T>(Value);
  }

  /// <summary>
  /// Get a range with an offset from the top left cell.
  /// The new range has the same dimensions as the current range
  /// </summary>
  /// <param name="rowOffset">Row Offset</param>
  /// <param name="columnOffset">Column Offset</param>
  /// <returns></returns>
  public ExcelRangeBase Offset(int rowOffset, int columnOffset) {
    if (_fromRow + rowOffset < 1
        || _fromCol + columnOffset < 1
        || _fromRow + rowOffset > ExcelPackage.MaxRows
        || _fromCol + columnOffset > ExcelPackage.MaxColumns) {
      throw (new ArgumentOutOfRangeException("Offset value out of range"));
    }
    string address = GetAddress(
        _fromRow + rowOffset,
        _fromCol + columnOffset,
        _toRow + rowOffset,
        _toCol + columnOffset);
    return new(_worksheet, address);
  }

  /// <summary>
  /// Get a range with an offset from the top left cell.
  /// </summary>
  /// <param name="rowOffset">Row Offset</param>
  /// <param name="columnOffset">Column Offset</param>
  /// <param name="numberOfRows">Number of rows. Minimum 1</param>
  /// <param name="numberOfColumns">Number of colums. Minimum 1</param>
  /// <returns></returns>
  public ExcelRangeBase Offset(
      int rowOffset,
      int columnOffset,
      int numberOfRows,
      int numberOfColumns) {
    if (numberOfRows < 1 || numberOfColumns < 1) {
      throw (new("Number of rows/columns must be greater than 0"));
    }
    numberOfRows--;
    numberOfColumns--;
    if (_fromRow + rowOffset < 1
        || _fromCol + columnOffset < 1
        || _fromRow + rowOffset > ExcelPackage.MaxRows
        || _fromCol + columnOffset > ExcelPackage.MaxColumns
        || _fromRow + rowOffset + numberOfRows < 1
        || _fromCol + columnOffset + numberOfColumns < 1
        || _fromRow + rowOffset + numberOfRows > ExcelPackage.MaxRows
        || _fromCol + columnOffset + numberOfColumns > ExcelPackage.MaxColumns) {
      throw (new ArgumentOutOfRangeException("Offset value out of range"));
    }
    string address = GetAddress(
        _fromRow + rowOffset,
        _fromCol + columnOffset,
        _fromRow + rowOffset + numberOfRows,
        _fromCol + columnOffset + numberOfColumns);
    return new(_worksheet, address);
  }

  /// <summary>
  /// Clear all cells
  /// </summary>
  public void Clear() {
    Delete(this, false);
  }

  /// <summary>
  /// Creates an array-formula.
  /// </summary>
  /// <param name="arrayFormula">The formula</param>
  public void CreateArrayFormula(string arrayFormula) {
    if (Addresses != null) {
      throw (new("An Arrayformula can not have more than one address"));
    }
    Set_SharedFormula(arrayFormula, this, true);
  }

  //private void Clear(ExcelAddressBase Range)
  //{
  //    Clear(Range, true);
  //}
  internal void Delete(ExcelAddressBase range, bool shift) {
    //DeleteCheckMergedCells(Range);
    _worksheet.MergedCells.Clear(range);
    //First find the start cell
    int fromRow,
        fromCol;
    var d = Worksheet.Dimension;
    if (d != null
        && range._fromRow <= d._fromRow
        && range._toRow
            >= d._toRow) //EntireRow?
    {
      fromRow = 0;
    } else {
      fromRow = range._fromRow;
    }
    if (d != null
        && range._fromCol <= d._fromCol
        && range._toCol
            >= d._toCol) //EntireRow?
    {
      fromCol = 0;
    } else {
      fromCol = range._fromCol;
    }

    var rows = range._toRow - fromRow + 1;
    var cols = range._toCol - fromCol + 1;

    _worksheet._values.Delete(fromRow, fromCol, rows, cols, shift);
    _worksheet._types.Delete(fromRow, fromCol, rows, cols, shift);
    _worksheet._styles.Delete(fromRow, fromCol, rows, cols, shift);
    _worksheet._formulas.Delete(fromRow, fromCol, rows, cols, shift);
    _worksheet._hyperLinks.Delete(fromRow, fromCol, rows, cols, shift);
    _worksheet._flags.Delete(fromRow, fromCol, rows, cols, shift);
    _worksheet._commentsStore.Delete(fromRow, fromCol, rows, cols, shift);

    //if(shift)
    //{
    //    _worksheet.AdjustFormulasRow(fromRow, rows);
    //}

    //Clear multi addresses as well
    if (Addresses != null) {
      foreach (var sub in Addresses) {
        Delete(sub, shift);
      }
    }
  }

  public void Dispose() {}

  //int _index;
  //ulong _toCellId;
  //int _enumAddressIx;
  private CellsStoreEnumerator<object> cellEnum;

  public IEnumerator<ExcelRangeBase> GetEnumerator() {
    Reset();
    return this;
  }

  IEnumerator IEnumerable.GetEnumerator() {
    Reset();
    return this;
  }

  /// <summary>
  /// The current range when enumerating
  /// </summary>
  public ExcelRangeBase Current => new(_worksheet, GetAddress(cellEnum.Row, cellEnum.Column));

  /// <summary>
  /// The current range when enumerating
  /// </summary>
  object IEnumerator.Current =>
    new ExcelRangeBase(_worksheet, GetAddress(cellEnum.Row, cellEnum.Column));

  private int _enumAddressIx = -1;

  public bool MoveNext() {
    if (cellEnum.Next()) {
      return true;
    }
    if (_addresses != null) {
      _enumAddressIx++;
      if (_enumAddressIx < _addresses.Count) {
        cellEnum = new(
            _worksheet._values,
            _addresses[_enumAddressIx]._fromRow,
            _addresses[_enumAddressIx]._fromCol,
            _addresses[_enumAddressIx]._toRow,
            _addresses[_enumAddressIx]._toCol);
        return MoveNext();
      }
      return false;
    }
    return false;
  }

  public void Reset() {
    _enumAddressIx = -1;
    cellEnum = new(_worksheet._values, _fromRow, _fromCol, _toRow, _toCol);
  }

  //private void GetNextIndexEnum(int fromRow, int fromCol, int toRow, int toCol)
  //{
  //    if (_index >= _worksheet._cells.Count) return;
  //    ExcelCell cell = _worksheet._cells[_index] as ExcelCell;
  //    while (cell.Column > toCol || cell.Column < fromCol)
  //    {
  //        if (cell.Column < fromCol)
  //        {
  //            _index = _worksheet._cells.IndexOf(ExcelAddress.GetCellID(_worksheet.SheetID, cell.Row, fromCol));
  //        }
  //        else
  //        {
  //            _index = _worksheet._cells.IndexOf(ExcelAddress.GetCellID(_worksheet.SheetID, cell.Row + 1, fromCol));
  //        }

  //        if (_index < 0)
  //        {
  //            _index = ~_index;
  //        }
  //        if (_index >= _worksheet._cells.Count || _worksheet._cells[_index].RangeID > _toCellId)
  //        {
  //            break;
  //        }
  //        cell = _worksheet._cells[_index] as ExcelCell;
  //    }
  //}

  //private void GetStartIndexEnum(int fromRow, int fromCol, int toRow, int toCol)
  //{
  //    _index = _worksheet._cells.IndexOf(ExcelCellBase.GetCellID(_worksheet.SheetID, fromRow, fromCol));
  //    _toCellId = ExcelCellBase.GetCellID(_worksheet.SheetID, toRow, toCol);
  //    if (_index < 0)
  //    {
  //        _index = ~_index;
  //    }
  //    _index--;
  //}
}
