// Michael Tartaglia
// 12 July 2002
// LaGuardia Air Traffic Control:
//		THIS PROGRAM SORTS ARRIVAL TIMES OF X AIRCRAFTS FOR STRUCTURED LANDING
//		TIMES, DIVERTING IF NECESSARY. RESULTING SCHEDULE IS DISPLAYED.

import java.applet.Applet;
import java.awt.*;
import java.awt.event.*;

public class LGA extends Applet implements MouseListener
{
 public int planes = 25,	// NUMBER OF PLANES TO LAND
 				planeIndex,		// CURRENT PLANE
				forNextHour,	// INDEX FOR NEXT HOUR LANDING
				hour,				// CURRENT HOUR
			   top = 15, Left = 20;	// COORDINATES FOR GRAPHING ARRIVALS
 public int[] timesArrived = new int[planes];		// ARRIVAL TIMES
 public int[] timesForLanding = new int[planes];	// SCHEDULED LANDING TIMES

 public void init() {
	setBackground(Color.white);
	hour = 0;	// CURRENT HOUR INITIALIZED
	newHour();	// DRAW DATA FOR NEW HOUR

	this.addMouseListener(this);
	requestFocus();
 }

 // IF USER WANTS TO SEE NEXT HOUR, HE/SHE NEEDS TO CLICK THE "NEXT HOUR"
 //    GRAPHICAL ICON IN THE APPLET, WHICH TRIGGERS "mousePressed"
 public void mouseEntered(MouseEvent m) {}
 public void mouseExited(MouseEvent m) {}
 public void mousePressed(MouseEvent m) {
	int x = m.getX(), y = m.getY();
	if (x < 215 && x > 165 && y < 40 && y > 30) newHour();
	repaint();
}
 public void mouseReleased(MouseEvent m) {}
 public void mouseClicked(MouseEvent m) {}


 public void newHour() {
	planeIndex = planes - 1;	// RESET INDEX TO LAST PLANE IN QUEUE
	hour++;							// INCREASE HOUR
	forNextHour = 0;				// RESET NUMBER OF NEXT-HOUR LANDINGS
	timesArrived = sort(getTimes(timesArrived));	// GET QUEUE TIMES AND SORT 'EM
	for (int i = 0; i < planes; ++i) {
		timesForLanding[i] = timesArrived[i];		// PLACE ARRIVALS QUEUE INTO LANDING QUEUE
	}
	timesForLanding = setTimesForLanding(timesForLanding);	// SET TIMES
 }


 public int[] getTimes(int[] t)
 // FUNCTION: places random minute values (0-59 inclusive) into array and returns array
 {
	for (int i = 0; i < planes; ++i)
	 t[i] = (int)Math.round(Math.random()*100)%60;
	return t;
 }


 public int[] sort(int[] t)
 // FUNCTION: recieves array and uses bubble sort to sort array values into ascending order
  {
	int temp;
	for (int i = 0; i <= planeIndex; ++i) {
		for (int j = i+1; j <= planeIndex; ++j) {
			if (t[j] == t[i]) {
				temp = t[planeIndex];
				t[planeIndex] = t[j];
				t[j] = temp;
				planeIndex--;
			}
			if (t[j] < t[i]) {
				temp = t[j];
				t[j] = t[i];
				t[i] = temp;
	}	}	}
	return t;
 }

 // SPACE PLANES 3 MINUTES APART IF NOT ALREADY, AND SEND THOSE WITH ARRIVAL 
 //	MINUTE TIMES OVER 60 TO ARRIVE IN THE NEXT HOUR
 public int[] setTimesForLanding(int[] t) {
	for (int i = 1; i <= planeIndex; ++i) {
		if (t[i-1]+3 > t[i]) t[i] = t[i-1]+3;
		if (t[i] >= 60) {forNextHour++;}
	}
	return t;
 }


 public void paint(Graphics g) {
	if (hour > 0) {
		// DRAW TABLE HEADER ROW
		g.setColor(Color.green);
		g.fill3DRect(165,30,51,10,true);
		g.setColor(Color.black);
		g.setFont(new Font("Arial",Font.BOLD,14));
		g.drawString("LGA Landing Sequence",14,29);
		g.setFont(new Font("Courier",Font.BOLD,11));
		g.drawString("Hour "+hour,15,39);
		g.drawString("Arrived",17,51);
		g.drawString("Will Land",97,51);
		g.setFont(new Font("Arial",Font.PLAIN,8));
		g.drawString("See Next Hour",166,39);
		g.drawRect(15,40,80,13);
		g.drawRect(95,40,120,13);

		g.setFont(new Font("Courier",Font.BOLD,11));
		int x = 15, y = 53;	// INITIAL VALUE FOR LANDING TABLE DATA
		for (int i = 0; i < planes; i++) {
			g.setColor(Color.black);
			g.drawRect(x,y,80,13);			// DRAW CELLS
			g.drawRect(x+80,y,120,13);
			g.drawString(""+timesArrived[i],x+2,y+11);	// DRAW ARRIVAL TIME
			if (i <= planeIndex-forNextHour) {				// IF CLEARED TO LAND
				g.setColor(Color.blue);
				g.drawString(""+timesForLanding[i],x+82,y+11);
			} else if (i <= planeIndex) {						// IF NEEDS TO WAIT UNTIL NEXT HOUR
				g.setColor(Color.red);
				g.drawString("Lands next hour.",x+82,y+11);
			} else {													// << IF ARRIVES AT THE SAME TIME AS
				g.setColor(new Color(180,0,0));				//    SOMEONE ELSE
				g.drawString("Diverted to JFK.",x+82,y+11);
			}
			y += 13;	// INCREASE FOR NEXT ROW
 }	}	}

}