// FILE. . . . . d:/hak/hlt/src/hlt/math/matrix/sources/SuccsIterator.java
// EDIT BY . . . Hassan Ait-Kaci
// ON MACHINE. . Hak-Laptop
// STARTED ON. . Fri Nov 29 00:07:28 2019

/**
 * @version     Last modified on Fri Nov 29 11:22:22 2019 by hak
 * @author      <a href="mailto:hak@acm.org">Hassan A&iuml;t-Kaci</a>
 * @copyright   &copy; <a href="http://www.hassan-ait-kaci.net/">by the author</a>
 */

package hlt.math.matrix;

import hlt.language.util.IntIterator;

/**
 * This is a class implementing the <a
 * href="https://www.hassan-ait-kaci.net/hlt/doc/hlt/code/language/util/IntIterator.html"><tt>hlt.language.util.IntIterator</tt></a>
 * interface for iterating through the right nodes that are the
 * successors of a given left node in a <tt>BipartiteGraph</tt>.
 *
 * @see BipartiteGraph
 * @see PredsIterator
 */
public class SuccsIterator implements IntIterator
{
  /**
   * The <tt>BipartiteGraph</tt> concerned by this
   * <tt>SuccsIterator</tt>.
   */
  private BipartiteGraph graph;

  /**
   * The left node index concerned by this <tt>SuccsIterator</tt>.
   */
  private int left;

  /**
   * The number of right nodes
   */
  private int rights;

  /**
   * The index of the first right node successor of <tt>left</tt> in
   * <tt>graph</tt>, or <tt>-1</tt> if there is none.
   */
  private int first;

  /**
   * The index of the last right node successor of <tt>left</tt> in
   * <tt>graph</tt>, or <tt>-1</tt> if there is none.
   */
  private int last;

  /**
   * Current right node index in this <tt>SuccsIterator</tt>.
   */
  private int index;

  /**
   * Construct a <tt>SuccsIterator</tt> for <tt>left</tt> in the given
   * <tt>graph</tt>.
   */
  public SuccsIterator (BipartiteGraph graph, int left)
  {
    this.graph = graph;
    this.left = left;
    rights = graph.order();
    first = graph.firstSuccessor(left); // -1 if no successors
    last = graph.lastSuccessor(left);   // -1 if no successors
    index = first;
  }

  /**
   * Return <tt>true</tt> iff this <tt>SuccsIterator</tt> has more
   * indices remaining.
   */
  public final boolean hasNext ()
    {
      if (index > last)
	return false;
      
      while (index <= last && !graph.isEdge(left,index))
	index++;

      return index <= last; // NB: if left has no successors, this returns false (since last = -1)
    }

  /**
   * Return the index of the first successor of <tt>left</tt>, or
   * <tt>-1</tt> if none exists.
   */
  public final int first ()
  {
    return first;
  }

  /**
   * Return the index of the last successor of <tt>left</tt>, or
   * <tt>-1</tt> if none exists.
   */
  public final int last ()
  {
    return last;
  }

  /**
   * Return the next successor node index in this
   * <tt>SuccsIterator</tt>, or <tt>-1</tt> if there is none
   * remaining.
   */
  public final int next ()
  {        
    return index == rights ? -1 : index++;
  }

}
