// ATM Simulation Implementation - the ATM itself

ATM Simulation Implementation - the ATM itself


/*
 * Example ATM simulation - file atm.cc
 *
 * This file implements the class that manages the ATM itself
 * - as declared in atm.h
 *
 * Copyright (c) 1996 - Russell C. Bjork
 *
 */

#include "sysdep.h"
#include "bank.h"
#include "session.h"
#include "transaction.h"
#include "atmparts.h"
#include "atm.h"


//


ATM::ATM(int number, const char * location)
  : _cardReader(* new CardReader()),
    _display(* new Display()),
    _keyboard(* new Keyboard()),
    _cashDispenser(* new CashDispenser()),
    _envelopeAcceptor(* new EnvelopeAcceptor),
    _receiptPrinter(* new ReceiptPrinter()),
    _operatorPanel(* new OperatorPanel()),
    _number(number), _location(location)
  { }


//


Money ATM::startupOperation()
  { 
    // Wait for switch to be turned on
    while (! _operatorPanel.switchOn()) 
	;
    _state = RUNNING;
    return _operatorPanel.getInitialCash(); 
  }

//


void ATM::serviceCustomers(Money initialCash)
  {
    _cashDispenser.setCash(initialCash);

    while (_state == RUNNING)
      { 
	CardReader::ReaderStatus readerStatus;

	_display.displayScreen(Display::INSERT_CARD);
	do
	  { 
	    if (! _operatorPanel.switchOn())
		_state = STOPPED;
	    else
		readerStatus = _cardReader.checkForCardInserted();
	  }
	while (_state == RUNNING && readerStatus == CardReader::NO_CARD);

	if (_state == RUNNING)
	  switch (readerStatus)
	    {
	      case CardReader::CARD_HAS_BEEN_READ:	
	        {
		  Session * session = new Session(_cardReader.cardNumber());
		  session -> doSessionUseCase();
		  delete session;

		  break;
	        }

	      case CardReader::UNREADABLE_CARD:

		_display.displayScreen(Display::CARD_UNREADABLE);
		_cardReader.ejectCard();
	    }
      }
  }


//


int ATM::getPIN() const
  { _display.displayScreen(Display::ENTER_PIN);
    int PIN = _keyboard.readPIN();
    _display.clearDisplay();
    return PIN;
  }


//


Transaction::TransactionType ATM::getTransactionChoice() const
  { _display.displayScreen(Display::CHOOSE_TRANSACTION);
    Transaction::TransactionType choice = _keyboard.readTransactionChoice();
    _display.clearDisplay();
    return choice;
  }


//


bool ATM::getDoAnotherTransactionChoice() const
  { _display.displayScreen(Display::WANT_ANOTHER_TRANSACTION);
    bool choice = _keyboard.readDoAnotherTransactionChoice();
    _display.clearDisplay();
    return choice;
  }


//


Bank::AccountType ATM::getAccountChoice(const char * purpose) const
  { _display.displayScreen(Display::CHOOSE_ACCOUNT, purpose);
    Bank::AccountType choice = _keyboard.readAccountChoice();
    _display.clearDisplay();
    return choice;
  }


//


Money ATM::getWithdrawlAmountChoice() const
  { _display.displayScreen(Display::CHOOSE_AMOUNT);
    Money amount = _keyboard.readWithdrawlAmountChoice();
    _display.clearDisplay();
    return amount;
  }


//


Money ATM::getAmountEntry() const
  { _display.displayScreen(Display::ENTER_AMOUNT);
    Money amount = _keyboard.readAmountEntry();
    _display.clearDisplay();
    return amount;
  }


//


bool ATM::checkIfCashAvailable(Money amount) const
  { if (amount <= _cashDispenser.currentCash())
	return true;
    else
      { _display.displayScreen(Display::NOT_ENOUGH_CASH);
	_keyboard.pressEnterToContinue();
	return false;
      }
  }


//


void ATM::dispenseCash(Money amount) const
  { _cashDispenser.dispenseCash(amount);
  }


//


bool ATM::acceptEnvelope() const
  { return _envelopeAcceptor.acceptEnvelope(); 
  }


//


void ATM::issueReceipt(int cardNumber,
		       int serialNumber,
		       const char * description,
		       Money amount,
		       Money balance,
		       Money availableBalance) const
  { 
    _receiptPrinter.printReceipt(_number, _location, cardNumber, serialNumber,
				 description, amount,
				 balance, availableBalance);;
  }


//


int ATM::reEnterPIN() const
  { _display.displayScreen(Display::INVALID_PIN);
    int PIN = _keyboard.readPIN();
    _display.clearDisplay();
    return PIN;
  }


//


void ATM::reportRejection(const char * reason) const
  {
    _display.displayScreen(Display::TRANSACTION_REJECTED, reason);
    _keyboard.pressEnterToContinue();
    _display.clearDisplay();
  }


//


void ATM::ejectCard() const
  { _cardReader.ejectCard(); }


//


void ATM::retainCard() const
  { _cardReader.retainCard(); 
    _display.displayScreen(Display::CARD_RETAINED);
    _keyboard.pressEnterToContinue();
    _display.clearDisplay();
  }

//


int ATM::number() const
  { return _number; }

//