package sleepingbarber;

import java.util.concurrent.Semaphore;

/**
 * Kunde, der die Haare geschnitten haben moechte.
 * 
 * @author  Ralf Kunze (rkunze@uos.de), Institut fuer Informatik, Universitaet Osnabrueck
 * @date 14.05.2007
 */
public class Customer extends Thread {
	Semaphore plaetze;

	Semaphore barberAvailable;

	SleepingBarber barber;

	int cntHairCut = 0;

	/**
	 * Konstruktor, der dem Kunden die benoetigten Informationen mitgibt.
	 * @param plaetze Semaphore fuer die Anzahl der Warteplaetze
	 * @param barberAvailable Semaphore, ob der Barber verfuegbar ist.
	 * @param barber Der Barber selbst.
	 * @param name Name des Kunden.
	 */
	public Customer(Semaphore plaetze, Semaphore barberAvailable,
			SleepingBarber barber, String name) {
		this.plaetze = plaetze;
		this.barberAvailable = barberAvailable;
		this.barber = barber;
		setName(name);

	}

	/**
	 * Ausfuehrungen des Kunden
	 */
	public void run() {
		while (true) {
			try {
				int zeit = (int) (Math.random() * 4000);
				System.out.printf("%s wartet %04dms (vor der Tuer).%n",
						getName(), zeit);
				sleep(zeit);
				System.out.printf("%s versucht einen Platz zu bekommen.%n",
						getName());

				// Warteplatz ergattern
				if (plaetze.tryAcquire()) {
					// Warteplatz bekommen
					int zeit2 = 800 + (int) Math.random() * 700;
					System.out.printf("%s hat einen Platz. Wartet %04dms.%n",
							getName(), zeit);
					sleep(zeit2);
					System.out.printf("%s wartet auf Barber.%n", getName());
					// Barber ergattern
					barberAvailable.acquire();
					// Barber bekommen und Wartestuhl freigeben
					plaetze.release();
					System.out.printf("%s hat Barber, macht Platz frei.%n",
							getName());
					// Barber wecken und sich die Haare schneiden lassen
					barber.wakeUp(this);
					barberAvailable.release();
					// Barber wieder freigeben
					System.out
							.printf(
									"%s hat Haare geschnitten bekommen. Platz ist frei.%n",
									getName());
				} else {	// Falls kein Wartestuhl frei einfach gehen und spaeter wieder reinschauen
					System.out
							.printf(
									"%s hat keinen Wartestuhl bekommen und geht demnaechst wieder hin.%n",
									getName());
				}
				sleep(1000);
			} catch (InterruptedException e) {
			}
		}
	}

	/**
	 * Anzahl der Haarschnitte raufsetzen.
	 */
	public void hairCutted() {
		cntHairCut++;
	}

	public String toString() {
		return getName() + " hatte " + cntHairCut + " HaarSchnitte.";
	}
}