/*******************************************************************************
 * 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       		        2012-11-25
 *******************************************************************************/

using System;
using System.Collections;
using System.Collections.Generic;
using OfficeOpenXml;

internal class IndexBase : IComparable<IndexBase> {
  internal short Index;

  public int CompareTo(IndexBase other) {
    return Index < other.Index
        ? -1
        : Index > other.Index
            ? 1
            : 0;
  }
}

internal class IndexItem : IndexBase {
  internal int IndexPointer { get; set; }
}

internal class ColumnIndex : IndexBase {
  internal IndexBase _searchIx = new();

  public ColumnIndex() {
    _pages = new PageIndex[CellStore<int>._pagesPerColumnMin];
    PageCount = 0;
  }

  ~ColumnIndex() {
    _pages = null;
  }

  internal int GetPosition(int row) {
    var page = (short)(row >> CellStore<int>._pageBits);
    _searchIx.Index = page;
    var res =
        (_pages != null
                && page >= 0
                && page < PageCount
                && page < _pages.Length
                && _pages[page] != null
                && _pages[page].Index == page)
            ? page
            : Array.BinarySearch(_pages, 0, PageCount, _searchIx);
    if (res >= 0) {
      GetPage(row, ref res);
      return res;
    }
    var p = ~res;

    if (GetPage(row, ref p)) {
      return p;
    }
    return res;
  }

  private bool GetPage(int row, ref int res) {
    if (res < PageCount && _pages[res].MinIndex <= row && _pages[res].MaxIndex >= row) {
      return true;
    }
    if (res + 1 < PageCount && (_pages[res + 1].MinIndex <= row)) {
      do {
        res++;
      } while (res + 1 < PageCount && _pages[res + 1].MinIndex <= row);
      //if (res + 1 < PageCount && _pages[res + 1].MaxIndex >= Row)
      //{
      return true;
      //}
      //else
      //{
      //    return false;
      //}
    }
    if (res - 1 >= 0 && _pages[res - 1].MaxIndex >= row) {
      do {
        res--;
      } while (res - 1 > 0 && _pages[res - 1].MaxIndex >= row);
      //if (res > 0)
      //{
      return true;
      //}
      //else
      //{
      //    return false;
      //}
    }
    return false;
  }

  internal int GetNextRow(int row) {
    //var page = (int)((ulong)row >> CellStore<int>.pageBits);
    var p = GetPosition(row);
    if (p < 0) {
      p = ~p;
      if (p >= PageCount) {
        return -1;
      }
      if (_pages[p].IndexOffset + _pages[p].Rows[0].Index < row) {
        if (p + 1 >= PageCount) {
          return -1;
        }
        return _pages[p + 1].IndexOffset + _pages[p].Rows[0].Index;
      }
      return _pages[p].IndexOffset + _pages[p].Rows[0].Index;
    }
    if (p < PageCount) {
      var r = _pages[p].GetNextRow(row);
      if (r >= 0) {
        return _pages[p].IndexOffset + _pages[p].Rows[r].Index;
      } else {
        if (++p < PageCount) {
          return _pages[p].IndexOffset + _pages[p].Rows[0].Index;
        } else {
          return -1;
        }
      }
    }
    return -1;
  }

  internal int FindNext(int page) {
    var p = GetPosition(page);
    if (p < 0) {
      return ~p;
    }
    return p;
  }

  internal PageIndex[] _pages;
  internal int PageCount;
}

internal class PageIndex : IndexBase {
  internal IndexBase _searchIx = new();

  public PageIndex() {
    Rows = new IndexItem[CellStore<int>._pageSizeMin];
    RowCount = 0;
  }

  public PageIndex(IndexItem[] rows, int count) {
    Rows = rows;
    RowCount = count;
  }

  public PageIndex(PageIndex pageItem, int start, int size)
      : this(pageItem, start, size, pageItem.Index, pageItem.Offset) {}

  public PageIndex(PageIndex pageItem, int start, int size, short index, int offset) {
    Rows = new IndexItem[CellStore<int>.GetSize(size)];
    Array.Copy(pageItem.Rows, start, Rows, 0, size);
    RowCount = size;
    Index = index;
    Offset = offset;
  }

  ~PageIndex() {
    Rows = null;
  }

  internal int Offset;

  internal int IndexOffset => IndexExpanded + Offset;

  internal int IndexExpanded => (Index << CellStore<int>._pageBits);

  internal IndexItem[] Rows { get; set; }

  internal int RowCount;

  internal int GetPosition(int offset) {
    _searchIx.Index = (short)offset;
    return (Rows != null
            && offset > 0
            && offset - 1 < RowCount
            && offset - 1 < Rows.Length
            && Rows[offset - 1] != null
            && Rows[offset - 1].Index == offset)
        ? offset - 1
        : Array.BinarySearch(Rows, 0, RowCount, _searchIx);
  }

  internal int GetNextRow(int row) {
    int offset = row - IndexOffset;
    var o = GetPosition(offset);
    if (o < 0) {
      o = ~o;
      if (o < RowCount) {
        return o;
      }
      return -1;
    }
    return o;
  }

  public int MinIndex {
    get {
      if (Rows.Length > 0) {
        return IndexOffset + Rows[0].Index;
      }
      return -1;
    }
  }

  public int MaxIndex {
    get {
      if (RowCount > 0) {
        return IndexOffset + Rows[RowCount - 1].Index;
      }
      return -1;
    }
  }

  public int GetIndex(int pos) {
    return IndexOffset + Rows[pos].Index;
  }
}

/// <summary>
/// This is the store for all Rows, Columns and Cells.
/// It is a Dictionary implementation that allows you to change the Key (the RowID, ColumnID or CellID )
/// </summary>
internal class CellStore<T> {
  /**** Size constants ****/
  internal const int _pageBits = 10; //13bits=8192  Note: Maximum is 13 bits since short is used (PageMax=16K)
  internal const int _pageSize = 1 << _pageBits;
  internal const int _pageSizeMin = 1 << 10;
  internal const int _pageSizeMax = _pageSize << 1; //Double page size
  internal const int _colSizeMin = 32;
  internal const int _pagesPerColumnMin = 32;

  private List<T> _values = new();
  internal ColumnIndex[] _columnIndex;
  internal IndexBase _searchIx = new();
  internal int ColumnCount;

  public CellStore() {
    _columnIndex = new ColumnIndex[_colSizeMin];
  }

  ~CellStore() {
    if (_values != null) {
      _values.Clear();
      _values = null;
    }
    _columnIndex = null;
  }

  internal int GetPosition(int column) {
    _searchIx.Index = (short)column;
    return (_columnIndex != null
            && column > 0
            && column - 1 < ColumnCount
            && column - 1 < _columnIndex.Length
            && _columnIndex[column - 1] != null
            && _columnIndex[column - 1].Index == column)
        ? column - 1
        : Array.BinarySearch(_columnIndex, 0, ColumnCount, _searchIx);
  }

  internal CellStore<T> Clone() {
    int row,
        col;
    var ret = new CellStore<T>();
    for (int c = 0; c < ColumnCount; c++) {
      col = _columnIndex[c].Index;
      for (int p = 0; p < _columnIndex[c].PageCount; p++) {
        for (int r = 0; r < _columnIndex[c]._pages[p].RowCount; r++) {
          row = _columnIndex[c]._pages[p].IndexOffset + _columnIndex[c]._pages[p].Rows[r].Index;
          ret.SetValue(row, col, _values[_columnIndex[c]._pages[p].Rows[r].IndexPointer]);
        }
      }
    }
    return ret;
  }

  internal int Count {
    get {
      int count = 0;
      for (int c = 0; c < ColumnCount; c++) {
        for (int p = 0; p < _columnIndex[c].PageCount; p++) {
          count += _columnIndex[c]._pages[p].RowCount;
        }
      }
      return count;
    }
  }

  internal bool GetDimension(out int fromRow, out int fromCol, out int toRow, out int toCol) {
    if (ColumnCount == 0) {
      fromRow = fromCol = toRow = toCol = 0;
      return false;
    }
    fromCol = _columnIndex[0].Index;
    var fromIndex = 0;
    if (fromCol <= 0 && ColumnCount > 1) {
      fromCol = _columnIndex[1].Index;
      fromIndex = 1;
    } else if (ColumnCount == 1 && fromCol <= 0) {
      fromRow = fromCol = toRow = toCol = 0;
      return false;
    }
    var col = ColumnCount - 1;
    while (col > 0) {
      if (_columnIndex[col].PageCount == 0
          || _columnIndex[col]._pages[0].RowCount > 1
          || _columnIndex[col]._pages[0].Rows[0].Index > 0) {
        break;
      }
      col--;
    }
    toCol = _columnIndex[col].Index;
    if (toCol == 0) {
      fromRow = fromCol = toRow = toCol = 0;
      return false;
    }
    fromRow = toRow = 0;

    for (int c = fromIndex; c < ColumnCount; c++) {
      int first,
          last;
      if (_columnIndex[c].PageCount == 0) {
        continue;
      }
      if (_columnIndex[c]._pages[0].RowCount > 0 && _columnIndex[c]._pages[0].Rows[0].Index > 0) {
        first = _columnIndex[c]._pages[0].IndexOffset + _columnIndex[c]._pages[0].Rows[0].Index;
      } else {
        if (_columnIndex[c]._pages[0].RowCount > 1) {
          first = _columnIndex[c]._pages[0].IndexOffset + _columnIndex[c]._pages[0].Rows[1].Index;
        } else if (_columnIndex[c].PageCount > 1) {
          first = _columnIndex[c]._pages[0].IndexOffset + _columnIndex[c]._pages[1].Rows[0].Index;
        } else {
          first = 0;
        }
      }
      var lp = _columnIndex[c].PageCount - 1;
      while (_columnIndex[c]._pages[lp].RowCount == 0 && lp != 0) {
        lp--;
      }
      var p = _columnIndex[c]._pages[lp];
      if (p.RowCount > 0) {
        last = p.IndexOffset + p.Rows[p.RowCount - 1].Index;
      } else {
        last = first;
      }
      if (first > 0 && (first < fromRow || fromRow == 0)) {
        fromRow = first;
      }
      if (first > 0 && (last > toRow || toRow == 0)) {
        toRow = last;
      }
    }
    if (fromRow <= 0 || toRow <= 0) {
      fromRow = fromCol = toRow = toCol = 0;
      return false;
    }
    return true;
  }

  internal int FindNext(int column) {
    var c = GetPosition(column);
    if (c < 0) {
      return ~c;
    }
    return c;
  }

  internal T GetValue(int row, int column) {
    int i = GetPointer(row, column);
    if (i >= 0) {
      return _values[i];
    }
    return default(T);
    //var col = GetPosition(Column);
    //if (col >= 0)
    //{
    //    var pos = _columnIndex[col].GetPosition(Row);
    //    if (pos >= 0)
    //    {
    //        var pageItem = _columnIndex[col].Pages[pos];
    //        if (pageItem.MinIndex > Row)
    //        {
    //            pos--;
    //            if (pos < 0)
    //            {
    //                return default(T);
    //            }
    //            else
    //            {
    //                pageItem = _columnIndex[col].Pages[pos];
    //            }
    //        }
    //        short ix = (short)(Row - pageItem.IndexOffset);
    //        var cellPos = Array.BinarySearch(pageItem.Rows, 0, pageItem.RowCount, new IndexBase() { Index = ix });
    //        if (cellPos >= 0)
    //        {
    //            return _values[pageItem.Rows[cellPos].IndexPointer];
    //        }
    //        else //Cell does not exist
    //        {
    //            return default(T);
    //        }
    //    }
    //    else //Page does not exist
    //    {
    //        return default(T);
    //    }
    //}
    //else //Column does not exist
    //{
    //    return default(T);
    //}
  }

  private int GetPointer(int row, int column) {
    var col = GetPosition(column);
    if (col >= 0) {
      var pos = _columnIndex[col].GetPosition(row);
      if (pos >= 0 && pos < _columnIndex[col].PageCount) {
        var pageItem = _columnIndex[col]._pages[pos];
        if (pageItem.MinIndex > row) {
          pos--;
          if (pos < 0) {
            return -1;
          }
          pageItem = _columnIndex[col]._pages[pos];
        }
        short ix = (short)(row - pageItem.IndexOffset);
        _searchIx.Index = ix;
        var cellPos =
            (pageItem.Rows != null
                    && ix > 0
                    && ix - 1 < pageItem.RowCount
                    && ix - 1 < pageItem.Rows.Length
                    && pageItem.Rows[ix - 1] != null
                    && pageItem.Rows[ix - 1].Index == ix)
                ? ix - 1
                : Array.BinarySearch(pageItem.Rows, 0, pageItem.RowCount, _searchIx);
        if (cellPos >= 0) {
          return pageItem.Rows[cellPos].IndexPointer;
        } //Cell does not exist
        return -1;
      } //Page does not exist
      return -1;
    } //Column does not exist
    return -1;
  }

  internal bool Exists(int row, int column) {
    return GetPointer(row, column) >= 0;
  }

  internal bool Exists(int row, int column, ref T value) {
    var p = GetPointer(row, column);
    if (p >= 0) {
      value = _values[p];
      return true;
    }
    return false;
  }

  internal void SetValue(int row, int column, T value) {
    lock (_columnIndex) {
      var col =
          (_columnIndex != null
                  && column > 0
                  && column - 1 < ColumnCount
                  && column - 1 < _columnIndex.Length
                  && _columnIndex[column - 1] != null
                  && _columnIndex[column - 1].Index == column)
              ? column - 1
              : Array.BinarySearch(
                  _columnIndex,
                  0,
                  ColumnCount,
                  new IndexBase {
                    Index = (short)(column),
                  });
      var page = (short)(row >> _pageBits);
      if (col >= 0) {
        //var pos = Array.BinarySearch(_columnIndex[col].Pages, 0, _columnIndex[col].Count, new IndexBase() { Index = page });
        var pos = _columnIndex[col].GetPosition(row);
        if (pos < 0) {
          pos = ~pos;
          if (pos - 1 < 0 || _columnIndex[col]._pages[pos - 1].IndexOffset + _pageSize - 1 < row) {
            AddPage(_columnIndex[col], pos, page);
          } else {
            pos--;
          }
        }
        if (pos >= _columnIndex[col].PageCount) {
          AddPage(_columnIndex[col], pos, page);
        }
        var pageItem = _columnIndex[col]._pages[pos];
        if (pageItem.IndexOffset > row) {
          pos--;
          page--;
          if (pos < 0) {
            throw (new("Unexpected error when setting value"));
          }
          pageItem = _columnIndex[col]._pages[pos];
        }

        short ix = (short)(row - ((pageItem.Index << _pageBits) + pageItem.Offset));
        _searchIx.Index = ix;
        var cellPos =
            (pageItem.Rows != null
                    && ix >= 0
                    && ix < pageItem.RowCount
                    && ix < pageItem.Rows.Length
                    && pageItem.Rows[ix] != null
                    && pageItem.Rows[ix].Index == ix)
                ? ix
                : Array.BinarySearch(pageItem.Rows, 0, pageItem.RowCount, _searchIx);
        if (cellPos < 0) {
          cellPos = ~cellPos;
          AddCell(_columnIndex[col], pos, cellPos, ix, value);
        } else {
          _values[pageItem.Rows[cellPos].IndexPointer] = value;
        }
      } else //Column does not exist
      {
        col = ~col;
        AddColumn(col, column);
        AddPage(_columnIndex[col], 0, page);
        short ix = (short)(row - (page << _pageBits));
        AddCell(_columnIndex[col], 0, 0, ix, value);
      }
    }
  }

  internal void Insert(int fromRow, int fromCol, int rows, int columns) {
    lock (_columnIndex) {
      if (columns > 0) {
        var col = GetPosition(fromCol);
        if (col < 0) {
          col = ~col;
        }
        for (var c = col; c < ColumnCount; c++) {
          _columnIndex[c].Index += (short)columns;
        }
      } else {
        var page = fromRow >> _pageBits;
        for (int c = 0; c < ColumnCount; c++) {
          var column = _columnIndex[c];
          var pagePos = column.GetPosition(fromRow);
          if (pagePos >= 0) {
            if (fromRow >= column._pages[pagePos].MinIndex
                && fromRow
                    <= column._pages[pagePos].MaxIndex) //The row is inside the page
            {
              int offset = fromRow - column._pages[pagePos].IndexOffset;
              var rowPos = column._pages[pagePos].GetPosition(offset);
              if (rowPos < 0) {
                rowPos = ~rowPos;
              }
              UpdateIndexOffset(column, pagePos, rowPos, fromRow, rows);
            } else if (column._pages[pagePos].MinIndex > fromRow - 1
                && pagePos
                    > 0) //The row is on the page before.
            {
              int offset = fromRow - ((page - 1) << _pageBits);
              var rowPos = column._pages[pagePos - 1].GetPosition(offset);
              if (rowPos > 0 && pagePos > 0) {
                UpdateIndexOffset(column, pagePos - 1, rowPos, fromRow, rows);
              }
            } else if (column.PageCount >= pagePos + 1) {
              int offset = fromRow - column._pages[pagePos].IndexOffset;
              var rowPos = column._pages[pagePos].GetPosition(offset);
              if (rowPos < 0) {
                rowPos = ~rowPos;
              }
              if (column._pages[pagePos].RowCount > rowPos) {
                UpdateIndexOffset(column, pagePos, rowPos, fromRow, rows);
              } else {
                UpdateIndexOffset(column, pagePos + 1, 0, fromRow, rows);
              }
            }
          } else {
            UpdateIndexOffset(column, ~pagePos, 0, fromRow, rows);
          }
        }
      }
    }
  }

  internal void Clear(int fromRow, int fromCol, int rows, int columns) {
    Delete(fromRow, fromCol, rows, columns, false);
  }

  internal void Delete(int fromRow, int fromCol, int rows, int columns) {
    Delete(fromRow, fromCol, rows, columns, true);
  }

  internal void Delete(int fromRow, int fromCol, int rows, int columns, bool shift) {
    lock (_columnIndex) {
      if (columns > 0 && fromRow == 1 && rows >= ExcelPackage.MaxRows) {
        DeleteColumns(fromCol, columns, shift);
      } else {
        var toCol = fromCol + columns - 1;
        var pageFromRow = fromRow >> _pageBits;
        for (int c = 0; c < ColumnCount; c++) {
          var column = _columnIndex[c];
          if (column.Index >= fromCol) {
            if (column.Index > toCol) {
              break;
            }
            var pagePos = column.GetPosition(fromRow);
            if (pagePos < 0) {
              pagePos = ~pagePos;
            }
            if (pagePos < column.PageCount) {
              var page = column._pages[pagePos];
              if (shift
                  && page.RowCount > 0
                  && page.MinIndex > fromRow
                  && page.MaxIndex >= fromRow + rows) {
                var o = page.MinIndex - fromRow;
                if (o < rows) {
                  rows -= o;
                  page.Offset -= o;
                  UpdatePageOffset(column, pagePos, o);
                } else {
                  page.Offset -= rows;
                  UpdatePageOffset(column, pagePos, rows);
                  continue;
                }
              }
              if (page.RowCount > 0
                  && page.MinIndex <= fromRow + rows - 1
                  && page.MaxIndex
                      >= fromRow) //The row is inside the page
              {
                var endRow = fromRow + rows;
                var delEndRow = DeleteCells(column._pages[pagePos], fromRow, endRow, shift);
                if (shift && delEndRow != fromRow) {
                  UpdatePageOffset(column, pagePos, delEndRow - fromRow);
                }
                if (endRow > delEndRow
                    && pagePos < column.PageCount
                    && column._pages[pagePos].MinIndex < endRow) {
                  pagePos = (delEndRow == fromRow ? pagePos : pagePos + 1);
                  var rowsLeft = DeletePage(
                      shift ? fromRow : delEndRow,
                      endRow - delEndRow,
                      column,
                      pagePos,
                      shift);
                  //if (shift) UpdatePageOffset(column, pagePos, endRow - fromRow - rowsLeft);
                  if (rowsLeft > 0) {
                    var fr = shift ? fromRow : endRow - rowsLeft;
                    pagePos = column.GetPosition(fr);
                    delEndRow = DeleteCells(
                        column._pages[pagePos],
                        fr,
                        shift ? fr + rowsLeft : endRow,
                        shift);
                    if (shift) {
                      UpdatePageOffset(column, pagePos, rowsLeft);
                    }
                  }
                }
              } else if (pagePos > 0
                  && column._pages[pagePos].IndexOffset
                      > fromRow) //The row is on the page before.
              {
                int offset = fromRow + rows - 1 - ((pageFromRow - 1) << _pageBits);
                var rowPos = column._pages[pagePos - 1].GetPosition(offset);
                if (rowPos > 0 && pagePos > 0) {
                  if (shift) {
                    UpdateIndexOffset(column, pagePos - 1, rowPos, fromRow + rows - 1, -rows);
                  }
                }
              } else {
                if (shift && pagePos + 1 < column.PageCount) {
                  UpdateIndexOffset(
                      column,
                      pagePos + 1,
                      0,
                      column._pages[pagePos + 1].MinIndex,
                      -rows);
                }
              }
            }
          }
        }
      }
    }
  }

  private void UpdatePageOffset(ColumnIndex column, int pagePos, int rows) {
    //Update Pageoffset

    if (++pagePos < column.PageCount) {
      for (int p = pagePos; p < column.PageCount; p++) {
        if (column._pages[p].Offset - rows <= -_pageSize) {
          column._pages[p].Index--;
          column._pages[p].Offset -= rows - _pageSize;
        } else {
          column._pages[p].Offset -= rows;
        }
      }

      if (Math.Abs(column._pages[pagePos].Offset) > _pageSize
          || Math.Abs(column._pages[pagePos].Rows[column._pages[pagePos].RowCount - 1].Index)
              > _pageSizeMax) //Split or Merge???
      {
        rows = ResetPageOffset(column, pagePos, rows);
        ////MergePages
        //if (column.Pages[pagePos - 1].Index + 1 == column.Pages[pagePos].Index)
        //{
        //    if (column.Pages[pagePos].IndexOffset + column.Pages[pagePos].Rows[column.Pages[pagePos].RowCount - 1].Index + rows -
        //        column.Pages[pagePos - 1].IndexOffset + column.Pages[pagePos - 1].Rows[0].Index <= PageSize)
        //    {
        //        //Merge
        //        MergePage(column, pagePos - 1, -rows);
        //    }
        //    else
        //    {
        //        //Split
        //    }
        //}
        //rows -= PageSize;
        //for (int p = pagePos; p < column.PageCount; p++)
        //{
        //    column.Pages[p].Index -= 1;
        //}
      }
    }
  }

  private int ResetPageOffset(ColumnIndex column, int pagePos, int rows) {
    PageIndex fromPage = column._pages[pagePos];
    PageIndex toPage;
    short pageAdd = 0;
    if (fromPage.Offset < -_pageSize) {
      toPage = column._pages[pagePos - 1];
      pageAdd = -1;
      if (fromPage.Index - 1 == toPage.Index) {
        if (fromPage.IndexOffset
                + fromPage.Rows[fromPage.RowCount - 1].Index
                - toPage.IndexOffset
                + toPage.Rows[0].Index
            <= _pageSizeMax) {
          MergePage(column, pagePos - 1);
          //var newPage = new PageIndex(toPage, 0, GetSize(fromPage.RowCount + toPage.RowCount));
          //newPage.RowCount = fromPage.RowCount + fromPage.RowCount;
          //Array.Copy(toPage.Rows, 0, newPage.Rows, 0, toPage.RowCount);
          //Array.Copy(fromPage.Rows, 0, newPage.Rows, toPage.RowCount, fromPage.RowCount);
          //for (int r = toPage.RowCount; r < newPage.RowCount; r++)
          //{
          //    newPage.Rows[r].Index += (short)(fromPage.IndexOffset - toPage.IndexOffset);
          //}
        }
      } else //No page after
      {
        fromPage.Index -= pageAdd;
        fromPage.Offset += _pageSize;
      }
    } else if (fromPage.Offset > _pageSize) {
      toPage = column._pages[pagePos + 1];
      pageAdd = 1;
      if (fromPage.Index + 1 == toPage.Index) {} else {
        fromPage.Index += pageAdd;
        fromPage.Offset += _pageSize;
      }
    }
    return rows;
  }

  private int DeletePage(int fromRow, int rows, ColumnIndex column, int pagePos, bool shift) {
    PageIndex page = column._pages[pagePos];
    var startRows = rows;
    while (page != null
            && page.MinIndex >= fromRow
            && ((shift && page.MaxIndex < fromRow + rows)
                    || (!shift && page.MaxIndex < fromRow + startRows))) {
      //Delete entire page.
      var delSize = page.MaxIndex - page.MinIndex + 1;
      rows -= delSize;
      var prevOffset = page.Offset;
      Array.Copy(
          column._pages,
          pagePos + 1,
          column._pages,
          pagePos,
          column.PageCount - pagePos + 1);
      column.PageCount--;
      if (column.PageCount == 0) {
        return 0;
      }
      if (shift) {
        for (int i = pagePos; i < column.PageCount; i++) {
          column._pages[i].Offset -= delSize;
          if (column._pages[i].Offset <= -_pageSize) {
            column._pages[i].Index--;
            column._pages[i].Offset += _pageSize;
          }
        }
      }
      if (column.PageCount > pagePos) {
        page = column._pages[pagePos];
        //page.Offset = pagePos == 0 ? 1 : prevOffset;  //First page can only reference to rows starting from Index == 1
      } else {
        //No more pages, return 0
        return 0;
      }
    }
    return rows;
  }

  ///
  private int DeleteCells(PageIndex page, int fromRow, int toRow, bool shift) {
    var fromPos = page.GetPosition(fromRow - (page.IndexOffset));
    if (fromPos < 0) {
      fromPos = ~fromPos;
    }
    var maxRow = page.MaxIndex;
    var offset = toRow - page.IndexOffset;
    if (offset > _pageSizeMax) {
      offset = _pageSizeMax;
    }
    var toPos = page.GetPosition(offset);
    if (toPos < 0) {
      toPos = ~toPos;
    }

    if (fromPos <= toPos && fromPos < page.RowCount && page.GetIndex(fromPos) < toRow) {
      if (toRow > page.MaxIndex) {
        if (fromRow
            == page.MinIndex) //Delete entire page, late in the page delete method
        {
          return fromRow;
        }
        var r = page.MaxIndex;
        var deletedRow = page.RowCount - fromPos;
        page.RowCount -= deletedRow;
        return r + 1;
      }
      var rows = toRow - fromRow;
      if (shift) {
        UpdateRowIndex(page, toPos, rows);
      }
      Array.Copy(page.Rows, toPos, page.Rows, fromPos, page.RowCount - toPos);
      page.RowCount -= toPos - fromPos;

      return toRow;
    }
    if (shift) {
      UpdateRowIndex(page, toPos, toRow - fromRow);
    }
    return toRow < maxRow ? toRow : maxRow;
  }

  private static void UpdateRowIndex(PageIndex page, int toPos, int rows) {
    for (int r = toPos; r < page.RowCount; r++) {
      page.Rows[r].Index -= (short)rows;
    }
  }

  private void DeleteColumns(int fromCol, int columns, bool shift) {
    var fPos = GetPosition(fromCol);
    if (fPos < 0) {
      fPos = ~fPos;
    }
    int tPos = fPos;
    for (var c = fPos; c <= ColumnCount; c++) {
      tPos = c;
      if (tPos == ColumnCount || _columnIndex[c].Index >= fromCol + columns) {
        break;
      }
    }

    if (ColumnCount <= fPos) {
      return;
    }

    if (_columnIndex[fPos].Index >= fromCol && _columnIndex[fPos].Index <= fromCol + columns) {
      //if (_columnIndex[fPos].Index < ColumnCount)
      //{
      if (tPos < ColumnCount) {
        Array.Copy(_columnIndex, tPos, _columnIndex, fPos, ColumnCount - tPos);
      }
      ColumnCount -= (tPos - fPos);
      //}
    }
    if (shift) {
      for (var c = fPos; c < ColumnCount; c++) {
        _columnIndex[c].Index -= (short)columns;
      }
    }
  }

  private void UpdateIndexOffset(ColumnIndex column, int pagePos, int rowPos, int row, int rows) {
    if (pagePos >= column.PageCount) {
      return; //A page after last cell.
    }
    var page = column._pages[pagePos];
    if (rows > _pageSize) {
      short addPages = (short)(rows >> _pageBits);
      int offset = +(rows - (_pageSize * addPages));
      for (int p = pagePos + 1; p < column.PageCount; p++) {
        if (column._pages[p].Offset + offset > _pageSize) {
          column._pages[p].Index += (short)(addPages + 1);
          column._pages[p].Offset += offset - _pageSize;
        } else {
          column._pages[p].Index += addPages;
          column._pages[p].Offset += offset;
        }
      }

      var size = page.RowCount - rowPos;
      if (page.RowCount > rowPos) {
        if (column.PageCount - 1
            == pagePos) //No page after, create a new one.
        {
          //Copy rows to next page.
          var newPage = CopyNew(page, rowPos, size);
          newPage.Index = (short)((row + rows) >> _pageBits);
          newPage.Offset = row + rows - (newPage.Index * _pageSize) - newPage.Rows[0].Index;
          if (newPage.Offset > _pageSize) {
            newPage.Index++;
            newPage.Offset -= _pageSize;
          }
          AddPage(column, pagePos + 1, newPage);
          page.RowCount = rowPos;
        } else {
          if (column._pages[pagePos + 1].RowCount + size
              > _pageSizeMax) //Split Page
          {
            SplitPageInsert(column, pagePos, rowPos, rows, size, addPages);
          } else //Copy Page.
          {
            CopyMergePage(page, rowPos, rows, size, column._pages[pagePos + 1]);
          }
        }
      }
    } else {
      //Add to Pages.
      for (int r = rowPos; r < page.RowCount; r++) {
        page.Rows[r].Index += (short)rows;
      }
      if (page.Offset + page.Rows[page.RowCount - 1].Index
          >= _pageSizeMax) //Can not be larger than the max size of the page.
      {
        AdjustIndex(column, pagePos);
        if (page.Offset + page.Rows[page.RowCount - 1].Index >= _pageSizeMax) {
          pagePos = SplitPage(column, pagePos);
        }
        //IndexItem[] newRows = new IndexItem[GetSize(page.RowCount - page.Rows[r].Index)];
        //var newPage = new PageIndex(newRows, r);
        //newPage.Index = (short)(pagePos + 1);
        //TODO: MoveRows to next page.
      }

      for (int p = pagePos + 1; p < column.PageCount; p++) {
        if (column._pages[p].Offset + rows < _pageSize) {
          column._pages[p].Offset += rows;
        } else {
          column._pages[p].Index++;
          column._pages[p].Offset = (column._pages[p].Offset + rows) % _pageSize;
        }
      }
    }
  }

  private void SplitPageInsert(
      ColumnIndex column,
      int pagePos,
      int rowPos,
      int rows,
      int size,
      int addPages) {
    var newRows = new IndexItem[GetSize(size)];
    var page = column._pages[pagePos];

    var rStart = -1;
    for (int r = rowPos; r < page.RowCount; r++) {
      if (page.IndexExpanded - (page.Rows[r].Index + rows) > _pageSize) {
        rStart = r;
        break;
      }
      page.Rows[r].Index += (short)rows;
    }
    var rc = page.RowCount - rStart;
    page.RowCount = rStart;
    if (rc > 0) {
      //Copy to a new page
      var row = page.IndexOffset;
      var newPage = CopyNew(page, rStart, rc);
      var ix = (short)(page.Index + addPages);
      var offset = page.IndexOffset + rows - (ix * _pageSize);
      if (offset > _pageSize) {
        ix += (short)(offset / _pageSize);
        offset %= _pageSize;
      }
      newPage.Index = ix;
      newPage.Offset = offset;
      AddPage(column, pagePos + 1, newPage);
    }

    //Copy from next Row
  }

  private void CopyMergePage(PageIndex page, int rowPos, int rows, int size, PageIndex toPage) {
    var startRow = page.IndexOffset + page.Rows[rowPos].Index + rows;
    var newRows = new IndexItem[GetSize(toPage.RowCount + size)];
    page.RowCount -= size;
    Array.Copy(page.Rows, rowPos, newRows, 0, size);
    for (int r = 0; r < size; r++) {
      newRows[r].Index += (short)(page.IndexOffset + rows - toPage.IndexOffset);
    }

    Array.Copy(toPage.Rows, 0, newRows, size, toPage.RowCount);
    toPage.Rows = newRows;
    toPage.RowCount += size;
  }

  private void MergePage(ColumnIndex column, int pagePos) {
    PageIndex page1 = column._pages[pagePos];
    PageIndex page2 = column._pages[pagePos + 1];

    var newPage = new PageIndex(page1, 0, page1.RowCount + page2.RowCount);
    newPage.RowCount = page1.RowCount + page2.RowCount;
    Array.Copy(page1.Rows, 0, newPage.Rows, 0, page1.RowCount);
    Array.Copy(page2.Rows, 0, newPage.Rows, page1.RowCount, page2.RowCount);
    for (int r = page1.RowCount; r < newPage.RowCount; r++) {
      newPage.Rows[r].Index += (short)(page2.IndexOffset - page1.IndexOffset);
    }

    column._pages[pagePos] = newPage;
    column.PageCount--;

    if (column.PageCount > (pagePos + 1)) {
      Array.Copy(
          column._pages,
          pagePos + 2,
          column._pages,
          pagePos + 1,
          column.PageCount - (pagePos + 1));
      for (int p = pagePos + 1; p < column.PageCount; p++) {
        column._pages[p].Index--;
        column._pages[p].Offset += _pageSize;
      }
    }
  }

  private PageIndex CopyNew(PageIndex pageFrom, int rowPos, int size) {
    IndexItem[] newRows = new IndexItem[GetSize(size)];
    Array.Copy(pageFrom.Rows, rowPos, newRows, 0, size);
    return new(newRows, size);
  }

  internal static int GetSize(int size) {
    var newSize = 256;
    while (newSize < size) {
      newSize <<= 1;
    }
    return newSize;
  }

  private void AddCell(ColumnIndex columnIndex, int pagePos, int pos, short ix, T value) {
    PageIndex pageItem = columnIndex._pages[pagePos];
    if (pageItem.RowCount == pageItem.Rows.Length) {
      if (pageItem.RowCount
          == _pageSizeMax) //Max size-->Split
      {
        pagePos = SplitPage(columnIndex, pagePos);
        if (columnIndex._pages[pagePos - 1].RowCount > pos) {
          pagePos--;
        } else {
          pos -= columnIndex._pages[pagePos - 1].RowCount;
        }
        pageItem = columnIndex._pages[pagePos];
      } else //Expand to double size.
      {
        var rowsTmp = new IndexItem[pageItem.Rows.Length << 1];
        Array.Copy(pageItem.Rows, 0, rowsTmp, 0, pageItem.RowCount);
        pageItem.Rows = rowsTmp;
      }
    }
    if (pos < pageItem.RowCount) {
      Array.Copy(pageItem.Rows, pos, pageItem.Rows, pos + 1, pageItem.RowCount - pos);
    }
    pageItem.Rows[pos] = new() {
      Index = ix,
      IndexPointer = _values.Count,
    };
    _values.Add(value);
    pageItem.RowCount++;
  }

  private int SplitPage(ColumnIndex columnIndex, int pagePos) {
    var page = columnIndex._pages[pagePos];
    if (page.Offset != 0) {
      var offset = page.Offset;
      page.Offset = 0;
      for (int r = 0; r < page.RowCount; r++) {
        page.Rows[r].Index -= (short)offset;
      }
    }
    //Find Split pos
    int splitPos = 0;
    for (int r = 0; r < page.RowCount; r++) {
      if (page.Rows[r].Index > _pageSize) {
        splitPos = r;
        break;
      }
    }
    var newPage = new PageIndex(page, 0, splitPos);
    var nextPage = new PageIndex(
        page,
        splitPos,
        page.RowCount - splitPos,
        (short)(page.Index + 1),
        page.Offset);

    for (int r = 0; r < nextPage.RowCount; r++) {
      nextPage.Rows[r].Index = (short)(nextPage.Rows[r].Index - _pageSize);
    }

    columnIndex._pages[pagePos] = newPage;
    if (columnIndex.PageCount + 1 > columnIndex._pages.Length) {
      var pageTmp = new PageIndex[columnIndex._pages.Length << 1];
      Array.Copy(columnIndex._pages, 0, pageTmp, 0, columnIndex.PageCount);
      columnIndex._pages = pageTmp;
    }
    Array.Copy(
        columnIndex._pages,
        pagePos + 1,
        columnIndex._pages,
        pagePos + 2,
        columnIndex.PageCount - pagePos - 1);
    columnIndex._pages[pagePos + 1] = nextPage;
    page = nextPage;
    //pos -= PageSize;
    columnIndex.PageCount++;
    return pagePos + 1;
  }

  private PageIndex AdjustIndex(ColumnIndex columnIndex, int pagePos) {
    PageIndex page = columnIndex._pages[pagePos];
    //First Adjust indexes
    if (page.Offset + page.Rows[0].Index >= _pageSize
        || page.Offset >= _pageSize
        || page.Rows[0].Index >= _pageSize) {
      page.Index++;
      page.Offset -= _pageSize;
    } else if (page.Offset + page.Rows[0].Index <= -_pageSize
        || page.Offset <= -_pageSize
        || page.Rows[0].Index <= -_pageSize) {
      page.Index--;
      page.Offset += _pageSize;
    }
    return page;
  }

  private void AddPage(ColumnIndex column, int pos, short index) {
    AddPage(column, pos);
    column._pages[pos] = new() {
      Index = index,
    };
    if (pos > 0) {
      var pp = column._pages[pos - 1];
      if (pp.RowCount > 0 && pp.Rows[pp.RowCount - 1].Index > _pageSize) {
        column._pages[pos].Offset = pp.Rows[pp.RowCount - 1].Index - _pageSize;
      }
    }
  }

  /// <summary>
  /// Add a new page to the collection
  /// </summary>
  /// <param name="column">The column</param>
  /// <param name="pos">Position</param>
  /// <param name="page">The new page object to add</param>
  private void AddPage(ColumnIndex column, int pos, PageIndex page) {
    AddPage(column, pos);
    column._pages[pos] = page;
  }

  /// <summary>
  /// Add a new page to the collection
  /// </summary>
  /// <param name="column">The column</param>
  /// <param name="pos">Position</param>
  private void AddPage(ColumnIndex column, int pos) {
    if (column.PageCount == column._pages.Length) {
      var pageTmp = new PageIndex[column._pages.Length * 2];
      Array.Copy(column._pages, 0, pageTmp, 0, column.PageCount);
      column._pages = pageTmp;
    }
    if (pos < column.PageCount) {
      Array.Copy(column._pages, pos, column._pages, pos + 1, column.PageCount - pos);
    }
    column.PageCount++;
  }

  private void AddColumn(int pos, int column) {
    if (ColumnCount == _columnIndex.Length) {
      var colTmp = new ColumnIndex[_columnIndex.Length * 2];
      Array.Copy(_columnIndex, 0, colTmp, 0, ColumnCount);
      _columnIndex = colTmp;
    }
    if (pos < ColumnCount) {
      Array.Copy(_columnIndex, pos, _columnIndex, pos + 1, ColumnCount - pos);
    }
    _columnIndex[pos] = new() {
      Index = (short)(column),
    };
    ColumnCount++;
  }

  private int _colPos = -1,
      _row;

  public ulong Current => ((ulong)_row << 32) | (uint)(_columnIndex[_colPos].Index);

  //object IEnumerator.Current
  //{
  //    get
  //    {
  //        return GetValue(_row+1, _columnIndex[_colPos].Index);
  //    }
  //}
  public bool MoveNext() {
    return GetNextCell(ref _row, ref _colPos, 0, ExcelPackage.MaxRows, ExcelPackage.MaxColumns);
  }

  internal bool NextCell(ref int row, ref int col) {
    return NextCell(ref row, ref col, 0, 0, ExcelPackage.MaxRows, ExcelPackage.MaxColumns);
  }

  internal bool NextCell(
      ref int row,
      ref int col,
      int minRow,
      int minColPos,
      int maxRow,
      int maxColPos) {
    if (minColPos >= ColumnCount) {
      return false;
    }
    if (maxColPos >= ColumnCount) {
      maxColPos = ColumnCount - 1;
    }
    var c = GetPosition(col);
    if (c >= 0) {
      if (c > maxColPos) {
        if (col <= minColPos) {
          return false;
        }
        col = minColPos;
        return NextCell(ref row, ref col);
      }
      var r = GetNextCell(ref row, ref c, minColPos, maxRow, maxColPos);
      col = _columnIndex[c].Index;
      return r;
    }
    c = ~c;
    if (c > _columnIndex[c].Index) {
      if (col <= minColPos) {
        return false;
      }
      col = minColPos;
      return NextCell(ref row, ref col, minRow, minColPos, maxRow, maxColPos);
    }
    {
      var r = GetNextCell(ref c, ref row, minColPos, maxRow, maxColPos);
      col = _columnIndex[c].Index;
      return r;
    }
  }

  internal bool GetNextCell(
      ref int row,
      ref int colPos,
      int startColPos,
      int endRow,
      int endColPos) {
    if (ColumnCount == 0) {
      return false;
    }
    if (++colPos < ColumnCount && colPos <= endColPos) {
      var r = _columnIndex[colPos].GetNextRow(row);
      if (r
          == row) //Exists next Row
      {
        return true;
      }
      int minRow,
          minCol;
      if (r > row) {
        minRow = r;
        minCol = colPos;
      } else {
        minRow = int.MaxValue;
        minCol = 0;
      }

      var c = colPos + 1;
      while (c < ColumnCount && c <= endColPos) {
        r = _columnIndex[c].GetNextRow(row);
        if (r
            == row) //Exists next Row
        {
          colPos = c;
          return true;
        }
        if (r > row && r < minRow) {
          minRow = r;
          minCol = c;
        }
        c++;
      }
      c = startColPos;
      if (row < endRow) {
        row++;
        while (c < colPos) {
          r = _columnIndex[c].GetNextRow(row);
          if (r
              == row) //Exists next Row
          {
            colPos = c;
            return true;
          }
          if (r > row && (r < minRow || (r == minRow && c < minCol)) && r <= endRow) {
            minRow = r;
            minCol = c;
          }
          c++;
        }
      }

      if (minRow == int.MaxValue || minRow > endRow) {
        return false;
      }
      row = minRow;
      colPos = minCol;
      return true;
    }
    if (colPos <= startColPos || row >= endRow) {
      return false;
    }
    colPos = startColPos - 1;
    row++;
    return GetNextCell(ref row, ref colPos, startColPos, endRow, endColPos);
  }

  internal bool GetNextCell(
      ref int row,
      ref int colPos,
      int startColPos,
      int endRow,
      int endColPos,
      ref int[] pagePos,
      ref int[] cellPos) {
    if (colPos == endColPos) {
      colPos = startColPos;
      row++;
    } else {
      colPos++;
    }

    if (pagePos[colPos] < 0) {
      if (pagePos[colPos] == -1) {
        pagePos[colPos] = _columnIndex[colPos].GetPosition(row);
      }
    } else if (_columnIndex[colPos]._pages[pagePos[colPos]].RowCount <= row) {
      if (_columnIndex[colPos].PageCount > pagePos[colPos]) {
        pagePos[colPos]++;
      } else {
        pagePos[colPos] = -2;
      }
    }

    var r =
        _columnIndex[colPos]._pages[pagePos[colPos]].IndexOffset
            + _columnIndex[colPos]._pages[pagePos[colPos]].Rows[cellPos[colPos]].Index;
    if (r == row) {
      row = r;
    }
    return true;
  }

  internal bool PrevCell(ref int row, ref int col) {
    return PrevCell(ref row, ref col, 0, 0, ExcelPackage.MaxRows, ExcelPackage.MaxColumns);
  }

  internal bool PrevCell(
      ref int row,
      ref int col,
      int minRow,
      int minColPos,
      int maxRow,
      int maxColPos) {
    if (minColPos >= ColumnCount) {
      return false;
    }
    if (maxColPos >= ColumnCount) {
      maxColPos = ColumnCount - 1;
    }
    var c = GetPosition(col);
    if (c >= 0) {
      if (c == 0) {
        if (col >= maxColPos) {
          return false;
        }
        if (row == minRow) {
          return false;
        }
        row--;
        col = maxColPos;
        return PrevCell(ref row, ref col, minRow, minColPos, maxRow, maxColPos);
      }
      var ret = GetPrevCell(ref row, ref c, minRow, minColPos, maxColPos);
      if (ret) {
        col = _columnIndex[c].Index;
      }
      return ret;
    }
    c = ~c;
    if (c == 0) {
      if (col >= maxColPos || row <= 0) {
        return false;
      }
      col = maxColPos;
      row--;
      return PrevCell(ref row, ref col, minRow, minColPos, maxRow, maxColPos);
    }
    {
      var ret = GetPrevCell(ref row, ref c, minRow, minColPos, maxColPos);
      if (ret) {
        col = _columnIndex[c].Index;
      }
      return ret;
    }
  }

  internal bool GetPrevCell(
      ref int row,
      ref int colPos,
      int startRow,
      int startColPos,
      int endColPos) {
    if (ColumnCount == 0) {
      return false;
    }
    if (--colPos >= startColPos)
    //                if (++colPos < ColumnCount && colPos <= endColPos)
    {
      var r = _columnIndex[colPos].GetNextRow(row);
      if (r
          == row) //Exists next Row
      {
        return true;
      }
      int minRow,
          minCol;
      if (r > row && r >= startRow) {
        minRow = r;
        minCol = colPos;
      } else {
        minRow = int.MaxValue;
        minCol = 0;
      }

      var c = colPos - 1;
      if (c >= startColPos) {
        while (c >= startColPos) {
          r = _columnIndex[c].GetNextRow(row);
          if (r
              == row) //Exists next Row
          {
            colPos = c;
            return true;
          }
          if (r > row && r < minRow && r >= startRow) {
            minRow = r;
            minCol = c;
          }
          c--;
        }
      }
      if (row > startRow) {
        c = endColPos;
        row--;
        while (c > colPos) {
          r = _columnIndex[c].GetNextRow(row);
          if (r
              == row) //Exists next Row
          {
            colPos = c;
            return true;
          }
          if (r > row && r < minRow && r >= startRow) {
            minRow = r;
            minCol = c;
          }
          c--;
        }
      }
      if (minRow == int.MaxValue || startRow < minRow) {
        return false;
      }
      row = minRow;
      colPos = minCol;
      return true;
    }
    colPos = ColumnCount;
    row--;
    if (row < startRow) {
      Reset();
      return false;
    }
    return GetPrevCell(ref colPos, ref row, startRow, startColPos, endColPos);
  }

  public void Reset() {
    _colPos = -1;
    _row = 0;
  }

  //public IEnumerator<ulong> GetEnumerator()
  //{
  //    this.Reset();
  //    return this;
  //}

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

internal class CellsStoreEnumerator<T> : IEnumerable<T>, IEnumerator<T> {
  private readonly CellStore<T> _cellStore;
  private int row,
      colPos;
  private int[] pagePos,
      cellPos;
  private readonly int _startRow;
  private readonly int _startCol;
  private readonly int _endRow;
  private readonly int _endCol;
  private int minRow,
      minColPos,
      maxRow,
      maxColPos;

  public CellsStoreEnumerator(CellStore<T> cellStore)
      : this(cellStore, 0, 0, ExcelPackage.MaxRows, ExcelPackage.MaxColumns) {}

  public CellsStoreEnumerator(
      CellStore<T> cellStore,
      int startRow,
      int startCol,
      int endRow,
      int endCol) {
    _cellStore = cellStore;

    _startRow = startRow;
    _startCol = startCol;
    _endRow = endRow;
    _endCol = endCol;

    Init();
  }

  internal void Init() {
    minRow = _startRow;
    maxRow = _endRow;

    minColPos = _cellStore.GetPosition(_startCol);
    if (minColPos < 0) {
      minColPos = ~minColPos;
    }
    maxColPos = _cellStore.GetPosition(_endCol);
    if (maxColPos < 0) {
      maxColPos = ~maxColPos - 1;
    }
    row = minRow;
    colPos = minColPos - 1;

    var cols = maxColPos - minColPos + 1;
    pagePos = new int[cols];
    cellPos = new int[cols];
    for (int i = 0; i < cols; i++) {
      pagePos[i] = -1;
      cellPos[i] = -1;
    }
  }

  internal int Row => row;

  internal int Column {
    get {
      if (colPos == -1) {
        MoveNext();
      }
      if (colPos == -1) {
        return 0;
      }
      return _cellStore._columnIndex[colPos].Index;
    }
  }

  internal T Value {
    get {
      lock (_cellStore) {
        return _cellStore.GetValue(row, Column);
      }
    }
    set {
      lock (_cellStore) {
        _cellStore.SetValue(row, Column, value);
      }
    }
  }

  internal bool Next() {
    //return _cellStore.GetNextCell(ref row, ref colPos, minColPos, maxRow, maxColPos);
    return _cellStore.GetNextCell(ref row, ref colPos, minColPos, maxRow, maxColPos);
  }

  internal bool Previous() {
    lock (_cellStore) {
      return _cellStore.GetPrevCell(ref row, ref colPos, minRow, minColPos, maxColPos);
    }
  }

  public string CellAddress => ExcelCellBase.GetAddress(Row, Column);

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

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

  public T Current => Value;

  public void Dispose() {}

  object IEnumerator.Current {
    get {
      Reset();
      return this;
    }
  }

  public bool MoveNext() {
    return Next();
  }

  public void Reset() {
    Init();
  }
}

internal class FlagCellStore : CellStore<byte> {
  internal void SetFlagValue(int row, int col, bool value, CellFlags cellFlags) {
    CellFlags currentValue = (CellFlags)GetValue(row, col);
    if (value) {
      SetValue(row, col, (byte)(currentValue | cellFlags)); // add the CellFlag bit
    } else {
      SetValue(row, col, (byte)(currentValue & ~cellFlags)); // remove the CellFlag bit
    }
  }

  internal bool GetFlagValue(int row, int col, CellFlags cellFlags) {
    return !(((byte)cellFlags & GetValue(row, col)) == 0);
  }
}
