import Semaphore;
import BaseThread;

public class SemRestaurant
{
	public static final int CAPACITY = 10;
	public static final int MAX_WAIT = 3;

	public static Semaphore mutex = new Semaphore(1);

	private static int iCustomerCount = 0;

	public static void main(String argv[])
	{
		int NumSpawnedCustomers = Integer.parseInt(argv[0]);
	
		Customer[] customers = new Customer[NumSpawnedCustomers];

		for(int i = 0; i < NumSpawnedCustomers; i++)
		{
			customers[i] = new Customer();
		}

		for(int i = 0; i < NumSpawnedCustomers; i++)
		{
			customers[i].start();
		}
	}

	public static boolean eat(int tid)
	{
		boolean bLeave = false;

		SemRestaurant.mutex.Wait();

		if(iCustomerCount >= CAPACITY + MAX_WAIT)
		{
			bLeave = true;
			SemRestaurant.mutex.Signal();
		}
		else
		{
			iCustomerCount++;
			SemRestaurant.mutex.Signal();

			while(true)
			{
				SemRestaurant.mutex.Wait();

				if(iCustomerCount > CAPACITY)
				{
					System.out.println("Customer " + tid + " is in the waiting area ...");
					try{Thread.currentThread().sleep(1200);} catch(InterruptedException e){}
				}
				else
					break;

				SemRestaurant.mutex.Signal();
				Thread.currentThread().yield();
			}

			SemRestaurant.mutex.Signal();

			System.out.println("Customer " + tid + " is eating ...");
			try{Thread.currentThread().sleep(300);} catch(InterruptedException e){}
			Thread.currentThread().yield();
		}

		return bLeave;
	}

	public static void leave(int tid)
	{
		SemRestaurant.mutex.Wait();
		
		System.out.println("Customer " + tid + " is leaving ...");
		
		if(iCustomerCount > 0)
			iCustomerCount--;

		SemRestaurant.mutex.Signal();
	}
}

class Customer extends BaseThread
{
	public void run()
	{
		if(SemRestaurant.eat(iTID))
			System.out.println("Eh... I ("+ iTID+") have to leave hungry :(");
		else
			SemRestaurant.leave(iTID);
	}
}

