﻿/*******************************************************************************
 * 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.Generic;
using System.Linq;
using System.Text;
using System.Collections;
using OfficeOpenXml;
using OfficeOpenXml.FormulaParsing.Excel.Functions.RefAndLookup;

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, IDisposable
    {
        internal IndexBase _searchIx=new IndexBase();
        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;
            }
            else
            {
                var p = ~res;
                
                if (GetPage(Row, ref p))
                {
                    return p;
                }
                else
                {
                    return res;
                }
            }
        }

        private bool GetPage(int Row, ref int res)
        {
            if (res < PageCount && _pages[res].MinIndex <= Row && _pages[res].MaxIndex >= Row)
            {
                return true;
            }
            else
            {
                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;
                    //}
                }
                else 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;
                }
                else
                {

                    if (_pages[p].IndexOffset + _pages[p].Rows[0].Index < row)
                    {
                        if (p + 1 >= PageCount)
                        {
                            return -1;
                        }
                        else
                        {
                            return _pages[p + 1].IndexOffset + _pages[p].Rows[0].Index;
                        }
                    }
                    else
                    {
                        return _pages[p].IndexOffset + _pages[p].Rows[0].Index;
                    }
                }
            }
            else
            {
                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;
                        }
                    }
                }
                else
                {
                    return -1;
                }
            }
        }
        internal int FindNext(int Page)
        {
            var p = GetPosition(Page);
            if (p < 0)
            {
                return ~p;
            }
            return p;
        }
        internal PageIndex[] _pages;
        internal int PageCount;

    public void Dispose()
    {
        if (_pages != null)
        {
            for (int p = 0; p < PageCount; p++)
            {
                ((IDisposable)_pages[p]).Dispose();
            }
            _pages = null;
        }
    }

    }
    internal class PageIndex : IndexBase, IDisposable
    {
        internal IndexBase _searchIx = new IndexBase();
        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 = 0;
        internal int IndexOffset
        {
            get
            {
                return IndexExpanded + (int)Offset;
            }
        }
        internal int IndexExpanded
        {
            get
            {
                return (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;
                }
                else
                {
                    return -1;
                }
            }
            return o;
        }

        public int MinIndex
        {
            get
            {
                if (Rows.Length > 0)
                {
                    return IndexOffset + Rows[0].Index;
                }
                else
                {
                    return -1;
                }
            }
        }
        public int MaxIndex
        {
            get
            {
                if (RowCount > 0)
                {
                    return IndexOffset + Rows[RowCount-1].Index;
                }
                else
                {
                    return -1;
                }
            }
        }
        public int GetIndex(int pos)
        {
            return IndexOffset + Rows[pos].Index;
        }
        public void Dispose()
        {
            Rows = null;
        }
    }
    /// <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> : IDisposable// : IEnumerable<ulong>, IEnumerator<ulong>
    {
        /**** 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;

        List<T> _values = new List<T>();
        internal ColumnIndex[] _columnIndex;
        internal IndexBase _searchIx = new IndexBase();
        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;
            }
            else
            {
                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;
                }
                else
                {
                    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];
            }
            else
            {
                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);
            //}
        }
        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;
                        }
                        else
                        {
                            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;
                    }
                    else //Cell does not exist
                    {
                        return -1;
                    }
                }
                else //Page does not exist
                {
                    return -1;
                }
            }
            else //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;
            }
            else
            {                
                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 Exception("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;
                    //}
                    return;
                }
            }
        }

        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;
                }
                else
                {
                    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;
                }
            }
            else 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 = +(int)(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;
                }
                else
                {
                    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 PageIndex(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 IndexItem() { 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;
            }
            //else if (page.Rows[0].Index >= PageSize) //Delete
            //{
            //    page.Index++;
            //    AddPageRowOffset(page, -PageSize);
            //}
            //else if (page.Rows[0].Index <= -PageSize)   //Delete
            //{
            //    page.Index--;
            //    AddPageRowOffset(page, PageSize);
            //}
            return page;
        }

        private void AddPageRowOffset(PageIndex page, short offset)
        {
            for (int r = 0; r < page.RowCount; r++)
            {
                page.Rows[r].Index += offset;
            }
        }
        private void AddPage(ColumnIndex column, int pos, short index)
        {
            AddPage(column, pos);
            column._pages[pos] = new PageIndex() { 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 ColumnIndex() { Index = (short)(Column) };
            ColumnCount++;
        }        
        int _colPos = -1, _row;
        public ulong Current
        {
            get
            {
                return ((ulong)_row << 32) | (uint)(_columnIndex[_colPos].Index);
            }
        }

        public void Dispose()
        {
            if(_values!=null) _values.Clear();
            if (_columnIndex != null)
            {
                for (var c = 0; c < ColumnCount; c++)
                {
                    if (_columnIndex[c] != null)
                    {
                        ((IDisposable)_columnIndex[c]).Dispose();
                    }
                }
            }
            _values = null;
            _columnIndex = null;
        }

        //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);
                }
                else
                {
                    var r=GetNextCell(ref row, ref c, minColPos, maxRow, maxColPos);
                    col = _columnIndex[c].Index;
                    return r;
                }
            }
            else
            {
                c=~c;
                if (c > _columnIndex[c].Index)
                {
                    if (col <= minColPos)
                    {
                        return false;
                    }
                    col = minColPos;
                    return NextCell(ref row, ref col, minRow, minColPos, maxRow, maxColPos);
                }
                else
                {                    
                    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;
            }
            else
            {
                if (++colPos < ColumnCount && colPos <=endColPos)
                {
                    var r = _columnIndex[colPos].GetNextRow(row);
                    if (r == row) //Exists next Row
                    {
                        return true;
                    }
                    else
                    {
                        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;
                        }
                        else
                        {
                            row = minRow;
                            colPos = minCol;
                            return true;
                        }
                    }
                }
                else
                {
                    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;
            }
            else
            {
            }
            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);
                }
                else
                {
                    var ret=GetPrevCell(ref row, ref c, minRow, minColPos, maxColPos);
                    if (ret)
                    {
                        col = _columnIndex[c].Index;
                    }
                    return ret;
                }
            }
            else
            {
                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);
                }
                else
                {
                    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;
            }
            else
            {
                if (--colPos >= startColPos)
//                if (++colPos < ColumnCount && colPos <= endColPos)
                {
                    var r = _columnIndex[colPos].GetNextRow(row);
                    if (r == row) //Exists next Row
                    {
                        return true;
                    }
                    else
                    {
                        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;
                        }
                        else
                        {
                            row = minRow;
                            colPos = minCol;
                            return true;
                        }
                    }
                }
                else
                {
                    colPos = ColumnCount;
                    row--;
                    if (row < startRow)
                    {
                        Reset();
                        return false;
                    }
                    else
                    {
                        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>
    {
        CellStore<T> _cellStore;
        int row, colPos;
        int[] pagePos, cellPos;
        int _startRow, _startCol, _endRow, _endCol;
        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 
        {
            get
            {
                return 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 
        {
            get
            {
                return ExcelAddressBase.GetAddress(Row, Column);
            }
        }

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

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

        public T Current
        {
            get
            {
                return Value;
            }
        }

        public void Dispose()
        {
            //_cellStore=null;
        }

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