/****************************************
*  Seg 2501, hiver 2002 Devoir # 4
*
*  file : FileClient.java
*  simulates the lineups (queues) for clients
*  at a bank as well as the operations on these lines
*
*  @author  Anne Bertrand
*  @author  Robin Tropper
*  @refactoredBy Robin Tropper  B.Sc.A.
*
*****************************************/

import java.util.*;

public class ClientQueue{
	private Vector<Client> lineup = new Vector<Client>();
	private String name;
	private long arrivalTime=0, duration=0, waitingTime=0;
	private long totalTime=0, clientsServed=0;
	private long timeInQueue=0, execution=0;
	private int delta=0, average=0, i=0;
	private Timer bankHours;
	
	public ClientQueue(int moy, int del, long dur, String qName) {
		average = moy;
		delta = del;
		bankHours = new Timer();
		name = qName;
		duration = dur;
		try {
			addClient();
		}
			catch (Exception ex) {
   			System.out.println("Problem adding at /e: "+name+"\n\t"+ ex);
		}//fin du try-catch pour ajouter
	}//fin constructeur

	
	private void addClient(){
		//bank is closing!
		if( Bank.isClosed() ){
			return;
		}
   		try {
	   		i++;
	   		System.out.println("Added client to " + name +" " + i); 	
	   			arrivalTime = System.currentTimeMillis();
	   			lineup.addElement(new Client(arrivalTime,name+i));   		
	   		} catch (Exception ex) {
	   			System.out.println("Problem adding an individual: "+"\n\t"+ ex);
			}//fin du try-catch pour ajouter
		timeInQueue = GenerateurR.generer(average, delta);
		execution += timeInQueue;
		bankHours.schedule(new ClientAddition(), execution);
	}//fin ajouteClient
	
	/**
	 * Serving a client implies taking one out of the queue.
	 * @return : the next client waiting in the queue OR
	 * null if queue is empty. 
	 */
	public synchronized Client serve(){
		Client bonhomme = null;
		if(lineup.size()!=0) {
				clientsServed++;
				bonhomme = (Client)(lineup.remove(0));
				waitingTime += bonhomme.getWaitingTime();
				totalTime += waitingTime+bonhomme.getRequiredServiceTime();
		}//fin du if size
		return bonhomme;
 	}//fin de la méthode Servir
 	
 	public String getName() { return name; }

 	public int queueSize() { return lineup.size(); }
 	
	public long getNumClientsServed() { return clientsServed; }

 	public long getTime() { return totalTime; }
 	
 	public long getMeanWaitingTime() {
 		long retour=0;
 		if (clientsServed!=0) {
 			retour = (waitingTime/10)/clientsServed;
 		}
 		return retour;
 	}//fin de getMoyAttente

	 class ClientAddition extends TimerTask {
		public void run() {	
			addClient();
		}//fin du run
	}//fin de classe ajouterClient
	
}//fin de classe FileClient