/*******************************************************************************
 * 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       		        2010-02-04
 * Jan Källman		    License changed GPL-->LGPL  2011-12-27
 *******************************************************************************/

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

namespace OfficeOpenXml;

/// <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 RangeCollection : IEnumerator<IRangeId>, IEnumerable, IDisposable {
  private class IndexItem {
    internal IndexItem(ulong cellId) {
      RangeID = cellId;
    }

    internal IndexItem(ulong cellId, int listPointer) {
      RangeID = cellId;
      ListPointer = listPointer;
    }

    internal ulong RangeID;
    internal int ListPointer;
  }

  /// <summary>
  /// Compares an IndexItem
  /// </summary>
  internal class Compare : IComparer<IndexItem> {
    int IComparer<IndexItem>.Compare(IndexItem x, IndexItem y) {
      return x.RangeID < y.RangeID
          ? -1
          : x.RangeID > y.RangeID
              ? 1
              : 0;
    }
  }

  private IndexItem[] _cellIndex;
  private List<IRangeId> _cells;
  private static readonly Compare _comparer = new();

  /// <summary>
  /// Creates a new collection
  /// </summary>
  /// <param name="cells">The Cells. This list must be sorted</param>
  internal RangeCollection(List<IRangeId> cells) {
    _cells = cells;
    InitSize(_cells);
    for (int i = 0; i < _cells.Count; i++) {
      _cellIndex[i] = new(cells[i].RangeID, i);
    }
  }

  ~RangeCollection() {
    _cells = null;
    _cellIndex = null;
  }

  /// <summary>
  /// Return the item with the RangeID
  /// </summary>
  /// <param name="rangeId"></param>
  /// <returns></returns>
  internal IRangeId this[ulong rangeId] => _cells[_cellIndex[IndexOf(rangeId)].ListPointer];

  /// <summary>
  /// Return specified index from the sorted list
  /// </summary>
  /// <param name="index"></param>
  /// <returns></returns>
  internal IRangeId this[int index] => _cells[_cellIndex[index].ListPointer];

  internal int Count => _cells.Count;

  internal void Add(IRangeId cell) {
    var ix = IndexOf(cell.RangeID);
    if (ix >= 0) {
      throw (new("Item already exists"));
    }
    Insert(~ix, cell);
  }

  internal void Delete(ulong key) {
    var ix = IndexOf(key);
    if (ix < 0) {
      throw (new("Key does not exists"));
    }
    int listPointer = _cellIndex[ix].ListPointer;
    Array.Copy(_cellIndex, ix + 1, _cellIndex, ix, _cells.Count - ix - 1);
    _cells.RemoveAt(listPointer);

    //Item is removed subtract one from all items with greater ListPointer
    for (int i = 0; i < _cells.Count; i++) {
      if (_cellIndex[i].ListPointer >= listPointer) {
        _cellIndex[i].ListPointer--;
      }
    }
  }

  internal int IndexOf(ulong key) {
    return Array.BinarySearch(_cellIndex, 0, _cells.Count, new(key), _comparer);
  }

  internal bool ContainsKey(ulong key) {
    return IndexOf(key) < 0 ? false : true;
  }

  private int _size { get; set; }

  /// <summary>
  /// Insert a number of rows in the collecion but dont update the cell only the index
  /// </summary>
  /// <param name="rowId"></param>
  /// <param name="rows"></param>
  /// <returns>Index of first rangeItem</returns>
  internal int InsertRowsUpdateIndex(ulong rowId, int rows) {
    int index = IndexOf(rowId);
    if (index < 0) {
      index = ~index; //No match found invert to get start cell
    }
    ulong rowAdd = (((ulong)rows) << 29);
    for (int i = index; i < _cells.Count; i++) {
      _cellIndex[i].RangeID += rowAdd;
    }
    return index;
  }

  /// <summary>
  /// Insert a number of rows in the collecion
  /// </summary>
  /// <param name="rowId"></param>
  /// <param name="rows"></param>
  /// <returns>Index of first rangeItem</returns>
  internal int InsertRows(ulong rowId, int rows) {
    int index = IndexOf(rowId);
    if (index < 0) {
      index = ~index; //No match found invert to get start cell
    }
    ulong rowAdd = (((ulong)rows) << 29);
    for (int i = index; i < _cells.Count; i++) {
      _cellIndex[i].RangeID += rowAdd;
      _cells[_cellIndex[i].ListPointer].RangeID += rowAdd;
    }
    return index;
  }

  /// <summary>
  /// Delete rows from the collecion
  /// </summary>
  /// <param name="rowId"></param>
  /// <param name="rows"></param>
  /// <param name="updateCells">Update range id's on cells</param>
  internal int DeleteRows(ulong rowId, int rows, bool updateCells) {
    ulong rowAdd = (((ulong)rows) << 29);
    var index = IndexOf(rowId);
    if (index < 0) {
      index = ~index; //No match found invert to get start cell
    }

    if (index >= _cells.Count || _cellIndex[index] == null) {
      return -1; //No row above this row
    }
    while (index < _cells.Count && _cellIndex[index].RangeID < rowId + rowAdd) {
      Delete(_cellIndex[index].RangeID);
    }

    int updIndex = IndexOf(rowId + rowAdd);
    if (updIndex < 0) {
      updIndex = ~updIndex; //No match found invert to get start cell
    }

    for (int i = updIndex; i < _cells.Count; i++) {
      _cellIndex[i].RangeID -= rowAdd; //Change the index
      if (updateCells) {
        _cells[_cellIndex[i].ListPointer].RangeID -= rowAdd; //Change the cell/row or column object
      }
    }
    return index;
  }

  internal void InsertColumn(ulong columnId, int columns) {
    throw (new("Working on it..."));
  }

  internal void DeleteColumn(ulong columnId, int columns) {
    throw (new("Working on it..."));
  }

  /// <summary>
  /// Init the size starting from 128 items. Double the size until the list fits.
  /// </summary>
  /// <param name="_cells"></param>
  private void InitSize(List<IRangeId> cells) {
    _size = 128;
    while (cells.Count > _size) {
      _size <<= 1;
    }
    _cellIndex = new IndexItem[_size];
  }

  /// <summary>
  /// Check the size and double the size if out of bound
  /// </summary>
  private void CheckSize() {
    if (_cells.Count >= _size) {
      _size <<= 1;
      Array.Resize(ref _cellIndex, _size);
    }
  }

  private void Insert(int ix, IRangeId cell) {
    CheckSize();
    Array.Copy(_cellIndex, ix, _cellIndex, ix + 1, _cells.Count - ix);
    _cellIndex[ix] = new(cell.RangeID, _cells.Count);
    _cells.Add(cell);
  }

  IRangeId IEnumerator<IRangeId>.Current {
    get { throw new NotImplementedException(); }
  }

  void IDisposable.Dispose() {
    _ix = -1;
  }

  private int _ix = -1;

  object IEnumerator.Current {
    get { return _cells[_cellIndex[_ix].ListPointer]; }
  }

  bool IEnumerator.MoveNext() {
    _ix++;
    return _ix < _cells.Count;
  }

  void IEnumerator.Reset() {
    _ix = -1;
  }

  IEnumerator IEnumerable.GetEnumerator() {
    return MemberwiseClone() as IEnumerator;
  }
}
