text: //Copyright (c) 2018 Yardi Technology Limited. Http://www.kooboo.com 
  //All rights reserved.
  using System;
  using System.Collections.Generic;
  using System.Linq;
  using System.Text;
  using System.Threading.Tasks;
  
  namespace Kooboo.IndexedDB.Sequence
  {
    public  class SequenceCollection<TValue> : IEnumerable<TValue>
      {
          private Sequence<TValue> sequence;
          private bool ascending;
          private Int64 start;
          private Int64 end;
  
              public SequenceCollection(Sequence<TValue> sequence, bool Ascending, Int64 start, Int64 end)
              {
                  this.sequence = sequence;
                  this.ascending = Ascending;
  
                 ///make sure start smaller than end. 
  
                  if (start > end)
                  {
                      this.start = end;
                      this.end = start;
                  }
                  else
                  {
                      this.start = start;
                      this.end = end;
                  }
                  
              }
  
              IEnumerator<TValue> GetEnumerator()
              {
                  return new Enumerator<TValue>(sequence, ascending, start, end);
              }
  
              System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
              {
                  return this.GetEnumerator();
              }
  
              IEnumerator<TValue> IEnumerable<TValue>.GetEnumerator()
              {
                  return this.GetEnumerator();
              }
  
              public class Enumerator<EValue> : IEnumerator<EValue>
              {
                  private Sequence<EValue> sequence;
                  private bool ascending;
                  private Int64 start;
                  private Int64 end;
  
                  private long currentindex = 0;
                  private int currentcount = 0;
  
                  public Enumerator(Sequence<EValue> sequence, bool Ascending, Int64 start, Int64 end)
                  {
                      this.sequence = sequence;
                      this.ascending = Ascending;
                      this.start = start;
                      this.end = end;
                  }
  
                  public EValue Current
                  {
                      get
                      {
                          long startindex = 0;
  
                          if (this.ascending)
                          {
                              startindex = this.currentindex;
                          }
                          else
                          {
                              startindex = this.currentindex - 12 - this.currentcount;
                          }
  
                          return this.sequence.Get(startindex, this.currentcount);
  
                      }
                  }
  
                  public void Dispose()
                  {
                      this.sequence = null;
                  }
  
                  public bool MoveNext()
                  {
                      if (this.start == this.end)
                      {
                          return false; 
                      }
  
                      if (this.ascending)
                      {
                          if (currentindex == 0)
                          {
                              currentindex = this.start;
                              currentcount = this.sequence.GetValueBytesCount(currentindex, this.ascending);
                              return true;
                          }
                          else
                          {
                              if ((currentindex + currentcount + 12 + 6) >= this.end)
                              {
                                  return false;
                              }
                              else
                              {
                                  currentindex = currentindex + 12 + currentcount;
                                  currentcount = this.sequence.GetValueBytesCount(currentindex, this.ascending);
                                  return true;
                              }
                          }
                      }
                      else
                      {
                          ///DESC
                          if (currentindex == 0)
                          {
                              currentindex = this.end;
                              currentcount = this.sequence.GetValueBytesCount(currentindex, this.ascending);
                              return true;
                          }
                          else
                          {
                              if ((currentindex - currentcount - 12 - 6) <=  this.start)
                              {
                                  return false;
                              }
                              else
                              {
                                  currentindex = currentindex - 12 - currentcount;
                                  
                                  /// get the next current count. 
                                  currentcount = this.sequence.GetValueBytesCount(currentindex, this.ascending);
  
                                  if ((currentindex - currentcount - 12) < this.start)
                                  {
                                      return false;
                                  }
                                  else
                                  {
                                      return true;
                                  }
                              }
                          }
  
                      }
  
                  }
  
  
                  /// <summary>
                  /// Sorry,not reset available or needed here. 
                  /// </summary>
                  public void Reset()
                  {
                      this.currentindex = 0;
                      this.currentcount = 0;
                  }
  
                  object System.Collections.IEnumerator.Current
                  {
                      get { return Current; }
                  }
              }
  
     
      }
  }
  