// FILE. . . . . d:/hak/hlt/src/hlt/math/matrix/sources/PredsIterator.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:23:08 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 left nodes that are the
 * predecessors of a given right node in a <tt>BipartiteGraph</tt>.
 *
 * @see BipartiteGraph
 * @see SuccsIterator
 */
public class PredsIterator implements IntIterator
{
  /**
   * The <tt>BipartiteGraph</tt> concerned by this
   * <tt>PredsIterator</tt>.
   */
  private BipartiteGraph graph;

  /**
   * The right node index concerned by this <tt>PredsIterator</tt>.
   */
  private int right;

  /**
   * The number of left nodes
   */
  private int lefts;

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

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

  /**
   * Current left node index in this <tt>PredsIterator</tt>.
   */
  private int index;

  /**
   * Construct a <tt>PredsIterator</tt> for <tt>right</tt> in the given
   * <tt>graph</tt>.
   */
  public PredsIterator (BipartiteGraph graph, int right)
  {
    this.graph = graph;
    this.right = right;
    lefts = graph.order();
    first = graph.firstPredecessor(right); // -1 if no predecessors
    last = graph.lastPredecessor(right);   // -1 if no predecessors
    index = first;
  }

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

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

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

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

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

}
