// Origin: 06-01-04 Tobias Eger
// 06-01-05 Khu Slight modifications.

// Argument 1: Anzahl der Autos
// Argument 2: Anzahl der Parkplätze im Parkhaus
// Argument 3: Anzahl der Wiederholungen, die ein Auto parken gehen soll
// Argument 4: Fahr- und Parkzeit [s] eines Autos

public class CarThread extends Thread
{
    private static int numberOfCarThreads = 100;
    private static int capacity = 20;
    private static int numberOfIterations = 10; // Wie oft ein Auto parken geht
    private static int millis = 1;         // Werte zwischen 1-300 sinnvoll
    
    private static CarPark carPark;   
//    private static CarParkISem carPark;
	
    public CarThread (String name)
    {
    	super(name);
    }

    private Thread newCarThread (int number)
    {
        CarThread thread = new CarThread ("Car " + number);
        System.out.println("Car " + number + ": created");
	return thread;
    }

    private CarThread (String[] args)
    {
        super("Root Thread");
	try
	{
            if (args.length > 0)
            {
                numberOfCarThreads = Integer.parseInt(args[0]);
		if (args.length > 1)
		{
                    capacity = Integer.parseInt(args[1]);
                    if (args.length > 2)
                    {
                        numberOfIterations = Integer.parseInt(args[2]);
			if (args.length > 3)
			{
                            millis = Integer.parseInt(args[3]);
			}
                    }
		}
            }
	}
	catch(NumberFormatException e)
	{
            System.out.println
                ("If 1 or 2 arguments, then posivtive integer expected! --- " +
                 e.toString());
	}
	carPark = new CarPark(capacity);
//	carPark = new CarParkISem(capacity);
	System.out.println
            ("Cars: " + numberOfCarThreads + "; Capacity: " + capacity + 
             "; Iterations: " + numberOfIterations +
             "; Driving and Parking Time [ms]: " + millis);
	for (int i = 0; i < numberOfCarThreads; ++i)
	{
            Thread CarThread = newCarThread(i+1);
            CarThread.start();
	}
    }
	
    public void run ()
    {
	for (int i = 0; i < numberOfIterations; ++i)
	{
            doIt();
	}
    }

    private void driveAround (int millis)
    {
        try
	{
            System.out.println(getName() + ": driving");
            sleep(millis);
	}
	catch(InterruptedException e)
	{
            System.out.println
                ("InterruptedException caught! --- " + e.toString());
	}
    }
       
    private void standStill (int millis)
    {
        try
	{
            System.out.println(getName() + ": parking");
            sleep(millis);
	}
	catch(InterruptedException e)
	{
            System.out.println
                ("InterruptedException caught! --- " + e.toString());
	}
    }
   
    private void doIt ()
    {
	try
	{
            java.util.Random random = new java.util.Random();
            driveAround(random.nextInt(millis));
            System.out.println(getName() + ": requesting carpark");
            carPark.request();
            standStill(random.nextInt(millis));
            System.out.println(getName() + ": leaving carpark");     		
            carPark.release();
   	}
	catch(InterruptedException e)
	{
            System.out.println 
                ("InterruptedException caught! --- " + e.toString());
	}
    }

    public static void main (String[] args)
    {
        CarThread thread = new CarThread(args);
    }
}