//-----------------------------------------------------------------------------
// Class Worker
// - the "objects" that do the extracting of Items from Trays
//-----------------------------------------------------------------------------

/* NOTES:
   We could have used the following hierarchy:
     abstract public class Person { }
     abstract class Customer extends Person {}
     abstract class Employee extends Person {}
     abstract class Pion extends Employee { }
     abstract class Boss extends Employee { }
     class Worker extends Pion {
   Instead, we assume just one type of Worker.
   This could be improved!
*/

import java.util.Vector;

public class Worker {    

    //-------------------------------------------------------------------------
    // Initialize Worker's position and effieciency in extracting Items:
    //-------------------------------------------------------------------------
       private int position;           // position of Worker along the Belt
       private double efficiency;      // factor that effects Worker's ability
       private final double HIGH_EFF = 1.0;  // upper limit of Worker's eff.
       private final double LOW_EFF  = 0.85; // lower limit of Worker's eff.
       private final double FACTOR   = 0.95; // modification factor for eff.

    //-------------------------------------------------------------------------
    // Initialize limits, which are set in terms of "points." A point is a 
    // measure of the retrievability of an Item, which is based on the 
    // attributes of that Item. Each Item contributes to the total points
    // extracted so far. 
    //-------------------------------------------------------------------------
       private final int HIGH_LIMIT  = 100;  // upper limit of Worker's points
       private final int LOW_LIMIT   = 75;   // lower limit of Worker's points

    //-------------------------------------------------------------------------
    // Constructor Worker(int position)
    // ================================
    // Construct a new Worker with a random efficiency:
    //-------------------------------------------------------------------------
       public Worker(int position) {
	   setEfficiency(); 
	   this.position = position;
       }

    //-------------------------------------------------------------------------
    // Method setEfficiency
    // ====================
    // Precondition: Worker has default efficiency (0).
    // Set a random efficiency using the lower and upper limits:
    //-------------------------------------------------------------------------
       private void setEfficiency() { 
	   efficiency = MyMath.random(LOW_EFF,HIGH_EFF);
       }
    
    //-------------------------------------------------------------------------
    // Method changeEfficiency
    // =======================
    // Reduce the Worker's efficiency:
    //-------------------------------------------------------------------------
       public void changeEfficiency() { 
	   efficiency *= FACTOR; 
       }

    //-------------------------------------------------------------------------
    // Method extractItems
    // ===================
    // Precondition: The input Vector trayItems contains a variety of Items.
    // Reminder: trayItems is a Vector of different Items that
    // are on a Tray: Spoon, Fork, Knife, Cup, Plate, etc.
    // Action: Extract items from input Tray and update Tray's amount of items.
    // When the Worker extracts enough Items to cause their total points to 
    // exceed the Worker's limit, the Worker stops extracting Items.
    // Postcondition: Tray has fewer, or no, Items left in the Vector
    //-------------------------------------------------------------------------
       public void extractItems(Vector trayItems) {

	   // Can extract only if Tray is not empty:
	      if (trayItems.size() > 0) { // Tray is not empty
	    
		  // Amount of items current Worker is *able* to take:
		     int itemPotential = 
		        (int) (efficiency*MyMath.random(LOW_LIMIT,HIGH_LIMIT));
	    
                  // Worker may choose to skip some boxes, so reduce items 
		  // depending on position and willingness to skip items:
		     double portion = MyMath.random(0,1)/(position+2.0);
		     // 2.0? because first Worker index starts at 0!
		     itemPotential = (int) (itemPotential*(1-portion));

		  // $items$ is Worker's potential at removing Items from Tray
		  // The Item Vector has a total number of "points" in terms of
	          // a retrievabilty measure. The Worker can extract items 
                  // from the Tray until the Worker's points are exhausted 
		  // or the Vector runs out of Items. So, scan through the
                  // Item Vector and extract Items from beginning to end:
		     int points = 0;  // accrued retrievability points so far

		     // Current Item so far:
		        Item currentItem = (Item) trayItems.firstElement();
                     // Points that current Item contributes so far:
			int currentPoints = currentItem.getRetrievability();

		     while (trayItems.size() > 0 && 
			    itemPotential >= (points+currentPoints)) {
			 
			 // Extract current Item and add its points:
			    trayItems.removeElement(currentItem);

                         // Increment points
			    points += currentPoints;

                         // Attempt to retrieve next Item:
			    if (trayItems.size() > 0) {
				currentItem = (Item) trayItems.firstElement();
				
				// New points to add:
				   currentPoints = 
				       currentItem.getRetrievability();
			    }

		     } // continue trying to remove Items from Tray
		     
	      } // current Tray finished
	      
       } // Method extractItems
   

} // Class Worker
