/*

		    Car Wash Example of Mitrani pp. 12-15

		      Coded in C++ with process package
				 G. Lindstrom
				 January 1994

*/

import sim.*;
import random.*;

class global {
static int T;				// simulation shut down time
static int N;				// capacity of car park
static int car_park_contents = 0;	// cars currently in car park
static car_wash benz;
static car_arrivals gen;

static public void main(String av[])
{
  N = 1;
  T = 150;

  benz = new car_wash("Mr. Benz", 25, 35);
  gen = new car_arrivals("Car generator", 10, 25);
  
  scheduler.activate(benz);
  scheduler.activate(gen);

  scheduler.run_simulation();
}

} // end global

class car_wash extends process {
  urand gen_period;
  int fast_wash, slow_wash;
  boolean busy;

car_wash(String n, int fast_wash_, int slow_wash_)
 {
     super(n);
     fast_wash = fast_wash_;
     slow_wash = slow_wash_;
 }

void body()
{ 
  System.out.println("Time " + scheduler.clock + 
	": car wash " + name + " created");
  gen_period = new urand(fast_wash, slow_wash);
  while (scheduler.clock < global.T)
    { if (global.car_park_contents == 0)
	{ busy = false;
	  System.out.println("Time " + scheduler.clock + 
		": car wash goes idle");
	  scheduler.passivate();
	}

      /* have car waiting */
      global.car_park_contents -= 1;
      busy = true;
      System.out.println("Time " + scheduler.clock + 
	": car wash begins service on car (" + global.car_park_contents + 
		" now waiting)");

      scheduler.hold(gen_period.draw());
      System.out.println("Time " + scheduler.clock + 
	": car wash finishes service on car (" + global.car_park_contents +
		" now waiting)");
    }

  System.out.println("Time " + scheduler.clock + ": car wash " + 
	name + " terminates\n");
  terminate();
}

}	// end car_wash

class car_arrivals extends process {
  urand gen_period;
  int low_period;
  int high_period;

 car_arrivals(String n, int low_period_, int high_period_)
 {
     super(n);
     low_period = low_period_;
     high_period = high_period_;
 }

void body()
{ gen_period = new urand(low_period, high_period);
  while (true)
    { scheduler.hold(gen_period.draw());

      System.out.print("Time " + scheduler.clock + ": car arrives; ");
      if (scheduler.clock >= global.T)
        terminate();
      if (global.car_park_contents < global.N)
	{ global.car_park_contents += 1;
	  System.out.println(" enters car park (" + global.car_park_contents 
		+ " now waiting)");
	  if (!global.benz.busy)
	    scheduler.activate(global.benz);
	}
      else
	System.out.println(" turned away from car park");
    }
}

};	// car_arrival

