package race;

import java.util.Random;

class Car implements Comparable<Car> {
	String make_and_model;
	int id_number;
	String team;
	double max_speed;
	double reliability;
	double tire_wear;
	double fuel_capacity;
	double fuel;
	int lap;
	double end_lap_time;
	boolean boost;
	Driver driver;
	Random random_generator;
	int num_crashes;

	public Car(String make_and_model,int id_number, double max_speed,double reliability) {
		this.make_and_model=make_and_model;
		this.id_number=id_number;
		this.max_speed = max_speed;
		this.reliability = reliability;
		this.fuel_capacity = 160.0; // Set by regulation
		random_generator = new Random();
	}

	public void driven_by(Driver driver) {
		this.driver = driver;
	}

	public void start_race(double start_time) {
		this.tire_wear = 0; // 0 - tires are new, 1 - tires are worn and will blow-out next lap
		this.fuel= fuel_capacity; // Assume we start out filled up
		this.lap=0;
		this.end_lap_time = start_time;
		this.boost=false;
		this.num_crashes=0;
	}

	public int do_lap(double lap_distance) {
		double avg_speed = 0.8 * max_speed;
		reliability -= 0.008; // Every lap, reliability gets worse
		tire_wear += 0.02; // Every lap, tires wear
		avg_speed *= driver.speed_factor();
		if (boost) {
			avg_speed *=1.15;
			reliability -= 0.01;
		}
		fuel -= (avg_speed/max_speed) * 1.5;
		if (fuel<0.0) {
			crash("Out of gas");
		}

		if (tire_wear > 0.4 || fuel < 5.0) pit_stop();

		double chance_of_wreck = random_generator.nextFloat() * 0.1;
		if (tire_wear > reliability) {
			crash("Tire failure");
		} else {
			chance_of_wreck += 0.1 * tire_wear;
			if (chance_of_wreck > reliability) {
				crash("Equipment Failure");
			}
		}
		if (chance_of_wreck > (1.0 -driver.recklessness()) ) {
				crash("Driver Error");
		}
		lap++;
		end_lap_time += 3600.0 * lap_distance/avg_speed;
// System.out.println("DEBUG: Car " + this + " finished lap " + lap + " at " + end_lap_time + " avg speed: " + avg_speed);
		return lap;
	}

	public void pit_stop() {
		System.out.println("Car " + this + " made a pit stop on lap " + lap);
		end_lap_time += 18.75;
		tire_wear = 0; // 0 - tires are new, 1 - tires are worn and will blow-out next lap
		fuel= fuel_capacity; // Assume we start out filled up
	}

	public double get_end_lap_time() {
		return end_lap_time;
	}

	public int get_lap() {
		return lap;
	}

	public void crash(String cause) {
		System.out.println("Crash! " + this + " on lap " + lap + " caused by: " + cause);
		end_lap_time +=30.0 * random_generator.nextFloat();
		reliability *=0.8;
		max_speed *=0.8;
		pit_stop();
		num_crashes++;
	}

	public int get_num_crashes() {
		return num_crashes;
	}

	public int compareTo(Car c2) {
		if (this.end_lap_time <= c2.end_lap_time) return -1;
		else return 1;
	}

	public String toString() {
		return "#" + id_number + " " + make_and_model + " driven by " + driver.name();
	}

}
