/*****************************************************************************
 * Conveyor Belt Simulation                                                  *
 * ========================                                                  *
 * David I. Schwartz                                                         *
 *****************************************************************************
 * Revision record:                                                          *
 * 4/15/2001  draft from non-inheritance version                             *
 * 4/21/2001  working version                                                *
 * 4/23/2001  cleaned up comments                                            *
 *****************************************************************************/

//-----------------------------------------------------------------------------
// Class p6sp01 (Project 6, Spring 2001):
// - performs the dining hall simulation
// - handles program's I/O
//-----------------------------------------------------------------------------

import java.io.*;

public class p6sp01 {
    
    //-------------------------------------------------------------------------
    // Initialize data:
    //-------------------------------------------------------------------------
       private static int runsPerSim;        // # of runs for each simulation
       private static int initialSize;       // initial # of Workers to test
       private static int finalSize;         // final # of Workers to test
       private static BufferedReader in;     // read user input
       private static String inFileName;     // input filename
       private static String outFileName;    // output filename
       private static BufferedReader inFile; // input file
       private static PrintWriter outFile;   // output file

    //-------------------------------------------------------------------------
    // Method main
    // ===========
    // Precondition: User has entered input and output filenames for $args$.
    // Start and run all the simulations:
    //-------------------------------------------------------------------------
       public static void main(String[] args) {
	   welcomeUser();
	   setParameters(args);
	   runSimulation();
	   cleanup();
       } // Method main

    //-------------------------------------------------------------------------
    // Method welcomeUser
    // ==================
    // Welcome the user:
    //-------------------------------------------------------------------------
       private static void welcomeUser() {
	   System.out.println("Welcome to BELT!");
       } // Method welcomeUser


    //-------------------------------------------------------------------------
    // Method setParameters
    // ====================
    // Precondition: $args$ stores the input and output file names.
    // Read in data and set up output file for storing results:
    //-------------------------------------------------------------------------
       private static void setParameters(String[] args) {
	      
	   // Read in data file and create outfile with initial parameters:
	      try {
		  
		  // Check if $args$ contains 2 Strings and that one
		  // corresponds to the input file. Open both the 
		  // input and output files:
		     checkParameters(args);
			     
	          // Read input-options as strings from input file:
		     initialSize = Integer.parseInt(inFile.readLine());
		     System.out.println("initial size: "+initialSize);
		     finalSize = Integer.parseInt(inFile.readLine());
		     System.out.println("final size: "+finalSize);
		     if (finalSize < initialSize)
			 quitProgram("Final size not <= initial size!");
		     runsPerSim = Integer.parseInt(inFile.readLine());
		     System.out.println("runs per sim: "+runsPerSim);
		     
	          // Close input file because finished reading from it:
		     inFile.close();
		     in.close();
	       
	      } 

	      catch(IOException e) {
		  quitProgram("Unable to obtain user input!");
	      }

       } // Method setParameters
    
    //-------------------------------------------------------------------------
    // Method checkParameters
    // ======================
    // Precondition: $args$ hopefully contains 2 Strings.
    // Postcondition: The first String corresponds to an existing text file
    // and the second String becomes the output file for the simulation:
    //-------------------------------------------------------------------------
       private static void checkParameters(String[] args) throws IOException {
	   
	   // Check if user enters names for input file and output file:
	      if (args.length != 2)
		  quitProgram("You entered an incorrect amount of" +
			      " command-line arguments!" +
			      "\nEnter \"javac infile outfile\".");
	      else {
		  inFileName = args[0];
		  outFileName = args[1];
	      }
      
	   // Ensure that input file exists:
	      in = new BufferedReader(new 
		  InputStreamReader(System.in)); 
	      while (!new File(inFileName).exists()) {
		  System.out.println("No such file !");
		  System.out.print("Enter file name to read: ");
		  inFileName  = in.readLine();
	      }

	   // Generate an input stream to read from the input file:
	      inFile = new BufferedReader(new FileReader(inFileName));

           // Generate an output stream to write to the output file:
	      outFile = new PrintWriter(new 
		  FileWriter(new File(outFileName)));

       } // Method checkParameters
    
    //-------------------------------------------------------------------------
    // Method runSimulation
    // ====================
    // Precondition: Input file has been read and output file is ready.
    // Run each simulation: for each size to test, do $runsPerSim$ amount of
    // of simulations. For each simulation, report the current simulation,
    // the number of Trays extracted, and the number of Items extracted:
    //-------------------------------------------------------------------------
    // Perform all runs of the simulation:
       private static void runSimulation() {
	   // Alert the User to the current status:
	      System.out.println("working...");
	   
	   // Output total number sizes to test:
              outFile.print("Total number of tests: ");
	      outFile.print(finalSize-initialSize+1);
	      outFile.println();
	      
	   // Output number of runs per size:
	      outFile.print("Number of runs per test: ");
	      outFile.print(runsPerSim);
	      outFile.println();
	      
	   // Need Dishroom to perform simulation:
	      Dishroom dr;
	
	   // Pick a new $size$:
	      for (int size=initialSize ; size <= finalSize ; size++) {
		  outFile.print("Current size: ");
		  outFile.print(size);
		  outFile.println();
		  
		  // Report $run$, trays removed, and items removed:
		     for (int run=1 ; run<=runsPerSim ; run++) {
			 dr = new Dishroom(size);
			 dr.activate();
			 outFile.print(" "+run);
			 outFile.print(" "+dr.getTrays() );
			 outFile.print(" "+dr.getItems() );
			 outFile.println();
			 dr.reset();
		     } // end for
		     
	      } // end for

       } // Method runSimulation

    //-------------------------------------------------------------------------
    // Method cleanup
    // ====================
    // Precondition: output file is open.
    // Close the output file.
    //-------------------------------------------------------------------------
       private static void cleanup() {
	   System.out.println("Congratulations! We're done.");
	   outFile.close();
       } // Method cleanup

    //-------------------------------------------------------------------------
    // Method quitProgram
    // ====================
    // Precondition: Something went horribly wrong in the program.
    // Kill the program's execution. Actually, there ought to be better 
    // error handling!
    //-------------------------------------------------------------------------
       public static void quitProgram(String s) {
	   System.err.println(s);
	   System.err.println("sorry...quitting program....");
	   System.exit(0);
       } // Method quitProgram

    //-------------------------------------------------------------------------
    // Method pause (not used)
    // ============
    // Pause the execution of the program:
    //-------------------------------------------------------------------------
       public void checkPause() {
	   BufferedReader inPause = 
	       new BufferedReader(new InputStreamReader(System.in));
	   System.out.print("Hit RETURN to continue...");
	   try { 
	       inPause.readLine();
	   } 
	   catch(IOException e) {}

       } // Method checkPause

    
} // Class Simulation

