@Override
  public void cardSwiped(int memberID) {
    System.out.println("cardSwiped: got " + memberID);
    if (!state.equals(EBorrowState.INITIALIZED)) {
      throw new RuntimeException(
          String.format("BorrowUC_CTL : cardSwiped : illegal operation in state: %s", state));
    }
    borrower = memberDAO.getMemberByID(memberID);
    if (borrower == null) {
      ui.displayErrorMessage(String.format("Member ID %d not found", memberID));
      return;
    }
    boolean overdue = borrower.hasOverDueLoans();
    boolean atLoanLimit = borrower.hasReachedLoanLimit();
    boolean hasFines = borrower.hasFinesPayable();
    boolean overFineLimit = borrower.hasReachedFineLimit();
    boolean borrowing_restricted = (overdue || atLoanLimit || overFineLimit);

    if (borrowing_restricted) {
      setState(EBorrowState.BORROWING_RESTRICTED);
    } else {
      setState(EBorrowState.SCANNING_BOOKS);
    }

    // display member details
    int mID = borrower.getID();
    String mName = borrower.getFirstName() + " " + borrower.getLastName();
    String mContact = borrower.getContactPhone();
    ui.displayMemberDetails(mID, mName, mContact);

    if (hasFines) {
      float amountOwing = borrower.getFineAmount();
      ui.displayOutstandingFineMessage(amountOwing);
    }

    if (overdue) {
      ui.displayOverDueMessage();
    }

    if (atLoanLimit) {
      ui.displayAtLoanLimitMessage();
    }

    if (overFineLimit) {
      System.out.println("State: " + state);
      float amountOwing = borrower.getFineAmount();
      ui.displayOverFineLimitMessage(amountOwing);
    }

    // display existing loans
    String loanString = buildLoanListDisplay(borrower.getLoans());
    ui.displayExistingLoan(loanString);
  }
  @Override
  public void bookScanned(int barcode) {
    System.out.println("bookScanned: got " + barcode);
    if (state != EBorrowState.SCANNING_BOOKS) {
      throw new RuntimeException(
          String.format("BorrowUC_CTL : bookScanned : illegal operation in state: %s", state));
    }
    ui.displayErrorMessage("");

    IBook book = bookDAO.getBookByID(barcode);
    if (book == null) {
      ui.displayErrorMessage(String.format("Book %d not found", barcode));
      return;
    }

    if (book.getState() != EBookState.AVAILABLE) {
      ui.displayErrorMessage(
          String.format("Book %d is not available: %s", book.getID(), book.getState()));
      return;
    }

    if (bookList.contains(book)) {
      ui.displayErrorMessage(String.format("Book %d already scanned: ", book.getID()));
      return;
    }

    scanCount++;
    bookList.add(book);
    ILoan loan = loanDAO.createLoan(borrower, book);
    loanList.add(loan);

    // display current book
    ui.displayScannedBookDetails(book.toString());

    // display pending loans
    ui.displayPendingLoan(buildLoanListDisplay(loanList));

    if (scanCount >= IMember.LOAN_LIMIT) {
      setState(EBorrowState.CONFIRMING_LOANS);
    }
  }
 public void initialise() {
   previous = display.getDisplay();
   display.setDisplay((JPanel) ui, "Borrow UI");
   setState(EBorrowState.INITIALIZED);
 }
 @Override
 public void loansRejected() {
   System.out.println("Loans Rejected");
   setState(EBorrowState.SCANNING_BOOKS);
 }
 @Override
 public void loansConfirmed() {
   setState(EBorrowState.COMPLETED);
 }
 @Override
 public void scansCompleted() {
   setState(EBorrowState.CONFIRMING_LOANS);
 }
 @Override
 public void cancelled() {
   setState(EBorrowState.CANCELLED);
 }