// FILE. . . . . d:/hak/hlt/src/hlt/math/matrix/sources/RowIterator.java
// EDIT BY . . . Hassan Ait-Kaci
// ON MACHINE. . Hak-Laptop
// STARTED ON. . Thu Nov 28 14:52:31 2019

/**
 * @version     Last modified on Thu Nov 28 23:48:54 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 rows of the matrix of a
 * <tt>BipartiteGraph</tt> for a given column.
 *
 * @see ColumnIterator
 */
public class RowIterator implements IntIterator
{
  /**
   * The <tt>BipartiteGraph</tt> concerned by this
   * <tt>RowIterator</tt>.
   */
  private BipartiteGraph graph;

  /**
   * The column index concerned by this <tt>RowIterator</tt>.
   */
  private int col;

  /**
   * The number of rows per column in the matrix of <tt>graph</tt>.
   */
  private int rows;

  /**
   * The index of the last non-zero row for <tt>column</tt> in
   * <tt>graph</tt>, or <tt>-1</tt> if there is none.
   */
  private int last;

  /**
   * Current row in this <tt>RowIterator</tt>.
   */
  private int row;

  /**
   * Construct a <tt>RowIterator</tt> for <tt>col</tt> in the given
   * <tt>graph</tt>.
   */
  public RowIterator (BipartiteGraph graph, int col)
  {
    this.graph = graph;
    this.col = col;
    rows = graph.data().length;
    last = graph.lastNonZeroRowInColumn(col); // -1 if only 0.0s in this column
    row = 0;
  }

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

      return row <= last; // NB: if all 0.0s in column, this returns false (since last = -1)
    }

  /**
   * Return the last non-zero row index in <tt>col</tt>, or <tt>-1</tt>
   * if none exists.
   */
  public final int last ()
  {
    return last;
  }

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

}
