import java.io.*;
import java.util.*;

/**
 * An abstract dispatch handler.
 *
 * Note: This version starts a new thread of execution
 * to process the daily dispatches.
 *
 * @author  Prof. David Bernstein, James Madison University
 * @version 2.0
 */
public abstract class AbstractDispatchHandler implements Runnable
{
    protected BufferedReader   in;    
    protected Dispatcher       dispatcher;
    protected Thread           controlThread;    

    /**
     * Construct a new DailyDispatchHandler
     *
     * @param d   The Dispatcher to use
     * @param f   The name of the dispatch file
     */
    public AbstractDispatchHandler(Dispatcher d, BufferedReader in) 
    {
       dispatcher = d;
       this.in    = in;
    }

    /**
     * Process an individual dispatch.
     *
     * @param line  The dispatch
     */
    protected abstract void processDispatch(String line);
    

    /**
     * Process the daily dispatches.
     *
     * Note: This method will continue to execute until 
     * all vehicles have been dispatched.  This could take
     * all day.  The application will not be able to
     * do anything else while this method is executing.
     */
    public void processDispatches()
    {
       String            line;

       do
       {
           try
           {
               line = in.readLine();               
               if (line != null) processDispatch(line);
           }
           catch (IOException ioe)
           {
               line = "";               
               System.err.println("Unable to read a dispatch");
           }
       } while (line != null);       
    }

    /**
     * Start this AbstractDispatchHandler.
     *
     * Specifically, start a new thread of execution and process
     * the dispatches in this thread.
     */
    public void start()
    {
       if (controlThread == null)
       {
          controlThread = new Thread(this);
          controlThread.start();        
       }
    }

    /**
     * The code that runs in this AbstractDispatchHandler
     * objects thread of execution (required by Runnable).
     */
    public void run()
    {
        processDispatches();

        try 
        {
            in.close();
        }
        catch (IOException ioeClose)
        {
            System.err.println("Unable to close dispatches");
        }
    }
}
