
/**
 * An illustration of a shallow copy and a deep copy
 */
import java.util.Random;

public class Car {
	// A car has a make (e.g. "Ford"), a weight (e.g. 2000), and a
	// license plate (e.g. "ABC-123")
	private String make;
	private double weight;
	private StringBuffer licensePlate;

	// to randomly generate the licensePlate
	private static Random rand = new Random();

	/**
	 * Creates a car given its make and weight. The license plate is randomly
	 * generated
	 * 
	 * @param theMake   the make of the car
	 * @param theWeight the weight of the car
	 */
	public Car(String theMake, double theWeight) {
		make = theMake;
		weight = theWeight;
		createLicensePlate();
	}

	/**
	 * Randomly creates a license plate number
	 */
	private void createLicensePlate() {
		licensePlate = new StringBuffer("");
		for (int i = 1; i <= 6; i++) {
			if (i == 4) {
				// place a - between the first 3 characters and the
				// last 3 characters
				licensePlate.append('-');
			}
			// randomly select a letter or a digit
			if (rand.nextBoolean()) {
				// Select a random character among 'A' to 'Z'
				licensePlate.append((char) ('A' + rand.nextInt(26)));
			} else {
				// Select a random character among '0' to '9'
				licensePlate.append((char) ('0' + rand.nextInt(10)));
			}
		}
	}

	/**
	 * Modifies the license plate number
	 */
	public void changeLicensePlate() {
		for (int i = 0; i < licensePlate.length(); i++) {
			if (i != 3) {
				if (rand.nextBoolean()) {
					licensePlate.setCharAt(i, (char) ('A' + rand.nextInt(26)));
				} else {
					licensePlate.setCharAt(i, (char) ('0' + rand.nextInt(10)));
				}
			}
		}
	}

	/**
	 * Make a shallow copy of this Car
	 * 
	 * @return the shallow copy
	 */
	public Car shallowCopy() {
		// The copy and the original share the same String and StringBuffer
		// objects
		Car copy = new Car(make, weight);
		copy.licensePlate = licensePlate;
		return copy;
	}

	/**
	 * Make a deep copy of this Car
	 * 
	 * @return the deep copy
	 */
	public Car deepCopy() {
		// Makes a deep copy of this Car (not truly a deep copy since
		// the String objects are shared between the original and the copy.
		// However, since a String is immutable, the copy behaves like
		// a deep copy
		Car copy = new Car(make, weight);
		copy.licensePlate = new StringBuffer(licensePlate);
		return copy;
	}

	/**
	 * Returns a String representation of this Car
	 */
	@Override
	public String toString() {
		return "make = " + make + ", weight = " + weight + ", license plate = " + licensePlate;
	}
}
