import java.util.*;


/**
 * Used to dispatch vehicles in a fleet (e.g., emergency
 * response vehicles).
 *
 * This version uses a synchronized LinkedList.
 *
 * @author  Prof. David Bernstein, James Madison University
 * @version 5.0b
 */
public class Dispatcher
{
    protected int                    numberOfVehicles;
    protected List<Integer>          availableVehicles;
    

    /**
     * Construct a new Dispatcher
     *
     * @param n   The number of vehicles in the fleet
     */
    public Dispatcher(int n)
    {
       int     i;

       numberOfVehicles = n;
       availableVehicles = Collections.synchronizedList(new LinkedList<Integer>());

       for (i=0; i < n; i++)
       {
          makeVehicleAvailable(i);
       }
    }

    /**
     * Dispatch an available vehicle
     *
     * @param  task  The task to be handled
     * @return       true if a vehicle was dispatched
     */
    public boolean dispatch(String task)
    {
       boolean  ok;
       int      vehicle;
       Integer  v;

       try
       {
          v = availableVehicles.remove(0);
          vehicle = v.intValue();
          sendMessage(vehicle, task);
          ok = true;
       }
       catch (IndexOutOfBoundsException ioobe)
       {
           ok = false;           
       }
       return ok;
    }

    /**
     * Makes a vehicle available for future dispatching
     *
     * @param vehicle  The number of the vehicle
     */
    public void makeVehicleAvailable(int vehicle)
    {
       availableVehicles.add(new Integer(vehicle));
    }

    /**
     * Sends a message to a vehicle
     *
     * @param vehicle  The number of the vehicle
     * @param message  The message to send
     */
    private void sendMessage(int vehicle, String message)
    {

       // This method would normally transmit the message 
       // to the vehicle.  For simplicity, it now writes it 
       // to the screen instead.

       System.out.println(vehicle+"\t"+message+"\n");
       System.out.flush();       
    }
}
