package race;

import java.util.PriorityQueue;

public class Race {
	double lap_distance;
	int laps;
	Car entries[];
	PriorityQueue<Car> position;
	double time;

	public Race(double lap_distance,Car ... entries) {
		this.lap_distance = lap_distance;
		this.laps = 1 + (int)(305.0/lap_distance);
		this.entries = entries;
		position = new PriorityQueue<Car>(entries.length);
		time = 0.0;
	}

	public void race() {
		System.out.println("Gentlemen, start your engines!");
		int max_laps=0;
		int finish=0;
		for(Car entry : entries) {
			entry.start_race(time);
			position.add(entry);
			time += 0.025; // Time from one car to the next at the start
		}
		while(position.size()>0) {
			if (0==max_laps%10) {
							top_five(max_laps,finish);
							max_laps++;
			}
			Car next = position.poll();
			time = next.get_end_lap_time();
			int nlap=next.do_lap(lap_distance);
			if (nlap < laps && next.get_num_crashes() < 5) position.add(next);
			else {
				entries[finish++]=next;
			}
			if (nlap > max_laps) max_laps=nlap;
// System.out.print("T=" + time + " : ");
		}
		System.out.println("Checker flag!... Final finishes...");
		int pos=1;
		for(finish=0;finish<entries.length;finish++) {
			if (entries[finish].get_lap() < max_laps) {
				System.out.println("  DNF " + entries[finish] + " exited race in lap " + entries[finish].get_lap());
			} else {
				System.out.println("  " + (pos++) + " " + entries[finish] + " @ " + entries[finish].get_end_lap_time());
			}
		}
	}

	public void top_five(int lap,int finished) {
		System.out.println("Top five at lap " + lap);
		int pos=1;
		if (finished>0) {
			for(int fin=0;fin<finished && pos<6;fin++) {
				if (entries[fin].get_lap() < laps) {
					System.out.println("  DNF " + entries[fin] + " exited race in lap " + entries[fin].get_lap());
				} else {
					System.out.println("  " + pos + entries[fin] + " Finished @ " + entries[fin].get_end_lap_time());
					pos++;
				}
			}
		}
		Car[] lapFinishes = getLapFinishes();
		boolean found=true;
		while(pos<6 && found) {
			found=false;
			for(Car entry : lapFinishes) {
				if (entry.get_lap()==lap) {
					System.out.println("   " + pos + "  " + entry + " finished lap " + lap + " at " + entry.get_end_lap_time());
					pos++;
					found=true;
					if (pos>=6) break;
				} else if (entry.get_lap() < lap) found=true;
			}
			lap--;
		}
	}

	Car[] getLapFinishes() {
		int s=position.size();
		Car[] parray = new Car[s];
		int p=0;
		for(Car next=position.poll();next!=null;next=position.poll()) {
			parray[p++]=next;
		}
		for(Car next : parray) position.add(next);
		return parray;
	}
}
