import java.io.*;
import java.util.*;

/**
 * Reads a line-oriented file
 *
 * @author  Prof. David Bernstein, James Madison University
 * @version 3.0
 */
public class LineReader implements LineSubject
{
    private BufferedReader            in;
//[Hashtable.

    private Collection<LineObserver>  observers;
//]Hashtable.
    private int                       maxLines;
    private String                    line;


    /**
     * Explicit Value Constructor
     *
     * @param is          The InputStream to read from
     * @param maxLines    The number of lines to read
     */
    public LineReader(InputStream is, int maxLines) throws IOException
    {
       this.maxLines = maxLines;

       in        = new BufferedReader(new InputStreamReader(is));
       observers = new HashSet<LineObserver>(); 
    }


//[addObserver.

    /**
     * Add an observer
     *
     * @param observer   The LineObserver to add
     */
    public void addObserver(LineObserver observer)
    {
       observers.add(observer);
    }
//]addObserver.



    /**
     * Get the last line
     *
     * @return   The line
     */
    public String getLine()
    {
       return line;
    }


//[notifyObservers.

    /**
     * Notify observers of a line
     */
    public void notifyObservers()
    {
       for (LineObserver o: observers)
       {
          o.handleLine(this);
       }
    }
//]notifyObservers.


    /**
     * Remove an observer
     *
     * @param observer   The LineObserver to remove
     */
    public void removeObserver(LineObserver observer)
    {
       observers.remove(observer);
    }


//[start.

    /**
     * Start the LineReader
     */
    public void start() throws IOException
    {
       // Read from the console and alert listeners
       while ((line = in.readLine()) != null) 
       {
          notifyObservers();
       }
    }
//]start.
}
