// cstand.C: the CashierStand class (modified from pstand.cc).

#include <stdlib.h>
#include <iostream.h>
#include "cashierstand.h"
#include "supermarket.h"

CashierStand::CashierStand (int nExpress, int nRegular) {

   if ((nRegular <= 0 )||(nExpress <=0)) {
      cerr << "Error! "
	"Number of regular and express cashiers must be positive!\n";
      exit(1);
   }
     
   numExpressCashiers = nExpress;
   numRegularCashiers = nRegular;

   if (numExpressCashiers > 0)
      expressCashiers = new Cashier[numExpressCashiers];
   for (int i = 0; i < numExpressCashiers; i++) {
      expressCashiers[ i ].setType( express );
   }

   regularCashiers = new Cashier[numRegularCashiers];
   for (int i = 0; i < numRegularCashiers; i++) {
      regularCashiers[ i ].setType( regular );
   }
}

Cashier* CashierStand::getBestCashier(typeCashier ctype) {
   // select cashier of given type that has shorter line-up

   Cashier* cashierList;
   int numCashiers;

   if (ctype == express) {
      cashierList = expressCashiers;
      numCashiers = numExpressCashiers;
   }
   else {
      cashierList = regularCashiers;
      numCashiers = numRegularCashiers;

   }

   // Assume first cashier has the smallest queue, and search for a
   // smaller one
   Cashier *returnCashier = &( cashierList[0] );
   int minQueueSize = returnCashier->getCustQueue()->getQueueSize();

   for (int i = 1; i < numCashiers; i++)
      if (minQueueSize > cashierList[i].getCustQueue()->getQueueSize()) {
          minQueueSize = cashierList[i].getCustQueue()->getQueueSize();
          returnCashier = &( cashierList[i] );
      }
      
   return returnCashier;
}


void CashierStand::sendCustomerToCashier (Cust *arrivingCust) {
   
   int numItems = arrivingCust->getItemsBought ();

   Cashier * cashierToGo;

   if (numItems <= sim->getMaxExpressItems()) // goes to express cashier
      cashierToGo = getBestCashier(express);
   else  // goes to regular cashier
      cashierToGo = getBestCashier(regular);

   if ((cashierToGo->getCustQueue()->getQueueSize() ==0) 
      &&(cashierToGo->freeCashier()) ) // queue empty and cashier free
       cashierToGo->startService(arrivingCust);
   else
       cashierToGo->getCustQueue()->insert(arrivingCust);
      

}
