
// Customer.java
// Andrew Davison, ad@coe.psu.ac.th, May 2023

/* The Sleeping barber problem:
  https://en.wikipedia.org/wiki/Sleeping_barber_problem

  A customer arrives at the barber's waiting room at a random 
  time and if there is space then they are assigned a 
  seat (and a ticket), and an ALERT is left for a barber. 

  If the room is full, the customer leaves, but will return
  after some random time.

  When a barber wants a customer, the waiting room assigns the 
  customer with the smallest ticket, and alerts the customer
  with the tuple: 
     ("HAIRCUT", custID, barberID)

  Usage:
    > compile.bat Customer.java

    Part of the application made up of:
       * BarberShop.java
       * Barber.java
       * WaitingRoom.java
       * Customer.java
*/

import java.util.*;

import org.jspace.*;


public class Customer implements Runnable
{
  private int id, pasID;
  private WaitingRoom room;
  private PrintAreas pas;
  private Space space;

  private Random rand = new Random();


  public Customer(int id, WaitingRoom wr, PrintAreas pas, Space s)
  {
    this.id = id;
    room = wr;
    this.pas = pas;
    space = s;
    pasID = id+2; // so offset from the two barbers' display panes
    pas.setTitle(pasID, "Cust-"+id);   
  }  // end of Customer()


  public void run()
  {
    try {
      while (true) {
        pas.println(pasID, "Visit barbershop");
        int seatIdx = room.addCustomer(id);
            // the Waiting room sends an alert, not the customer
        if (seatIdx != -1) {
          pas.println(pasID, "-- Sit in seat " + seatIdx);

          // wait for a pairing with a barber
          Object[] hairObj = space.get( 
                        new ActualField("HAIRCUT"), 
                        new ActualField(id),
                        new FormalField(Integer.class));
          int barberID = (int)hairObj[2];
          pas.println(pasID, "Has a haircut with barber " + barberID);
          SpaceUtils.pause(4000);  // haircut takes some time

          pas.println(pasID, "Leave barbershop");
          SpaceUtils.pause(rand.nextInt(7000));
              // wait a while before geting another cut
        }
        else {
          pas.println(pasID, "** No seat; departs barbershop");
          SpaceUtils.pause(rand.nextInt(5000));
              // wait a while before trying again
        }
      }
    }
    catch (InterruptedException e) 
    {  System.out.println("Customer " + id + " error: " + e);  }
  } /* run */

}  // end of Customer class
