// An application for program Cruise Control, CS100 Assignment 9

import java.awt.*;

public class CruiseControl {
	static boolean outputToggle= false; // Set to true in Accelerator.java if
							// user clicks button. If true, then
							// output should be printed
							// at each tick of the clock.

	static public int period= 1000; 	// Time to wait between events

	static SystemClock c;			// The system clock
	static Thread cThread;			// (and its thread)

	static RoadGrade roadGrade;	      // Simulation of road grade
	static Thread roadGradeThread;	// (and its thread)

	static Accelerator a;	         	// Simulation of the accelerator
	static Thread aThread;			// (and its thread)

	static DesiredSpeed desSpeed;	    	// Simulation of desired speed setting
	static Thread desSpeedThread;		// (and its thread)
   	
	static CurrentSpeed currSpeed;	// Simulation of the current speed of the
	static Thread currSpeedThread;	// car (and its thread)

	static String s= "";			// The output String

	static SystemOutput sysout; 		// Simulate the system output window


	// The method called by the system to start the program
 	// Each iteration of the main loop of the simulation, 
  	// 	(0) Wait for a clock tick (by calling sleep).
  	// 	(1) Do what is necessary to update cruise control system
	//	(2) Print data to output window 

	public static void main(String[] args) {
		initializeProcesses(); 
		
		// YOUR CODE GOES HERE
   	}


	// Create all the processes --clock, accelerator, road grade,
	// desired speed, and current speed -- and start their threads going.
	static public void initializeProcesses() {
  		c= new SystemClock(period);
		roadGrade= new RoadGrade(c, 3);
		a= new Accelerator(c);
 		desSpeed= new DesiredSpeed(c, 65);
   		currSpeed= new CurrentSpeed(c, 50);
   	
   		cThread= new Thread(c);
   		roadGradeThread= new Thread(roadGrade);
   		aThread= new Thread(a);
   		desSpeedThread= new Thread(desSpeed);
   		currSpeedThread= new Thread(currSpeed);
   	
   		cThread.setDaemon(true);
   		roadGradeThread.setDaemon(true);
   		aThread.setDaemon(true);
   		desSpeedThread.setDaemon(true);
   		currSpeedThread.setDaemon(true);
   	
   		cThread.start();
   		roadGradeThread.start();
   		aThread.start();
   		desSpeedThread.start();
   		currSpeedThread.start();
   	
   		sysout= new SystemOutput();
	}
   		
    
  	// Wait for the next tick of clock c
  	static public void sleep() {
  		synchronized(c) {
   			try {c.wait();}
   				catch(InterruptedException ie) {
   					System.out.println(
   				  	"Interrupt exception in CruiseControl.sleep");
   				}
    		}
  	}
  	
    	
  	// Change the current speed based on the state of the accelerator.
  	// If the accelerator is off, there is a slight decrease in speed, say 0.3 mph. 
  	// If the accelerator is on, increase the speed by 1 mph and some additional
  	// amount that depends on the difference between the desired speed and the 
  	// current speed.
  	// Return the change in speed.	 
  	static public double ChangeDueToAccel() {

		// YOUR CODE GOES HERE. Be sure to change the RETURN statement.
		return 0; 
  	}
  	
  	// Update the current speed depending on the road grade.
  	// If the road grade is positive (uphill), decrease the current speed.
	// If the road grade is negative (downhill), increase the current speed.
	// Return the change in speed.
 	static public double ChangeDueToGrade() {

		// YOUR CODE GOES HERE. Be sure to change the RETURN statement.
		return 0;	
   	}

  	// The accelerator is on. Turn it off if it should be off. This
 	// has to be done keeping method checkTurnOn in mind as well.
	// Provide in both methods some way to ensure that quick 
	// switching on and off of the accelerator does not occur.
  	static public void checkTurnOff() {

		// YOUR CODE GOES HERE. 
  	}
  	
  	// The accelerator is off. Turn it on if it should be on.
  	// See the comment for method checkTurnOff.
  	static public void checkTurnOn() {

		// YOUR CODE GOES HERE. 
  	}


  	public void paint(Graphics g) {
		g.drawString("Cruise Control!", 30, 30);
	}

}
