#include "UserInterface.h"

// Author: Steve Talbot

UserInterface:: UserInterface() {

	// the default "configuration" for the application is set in
	// the constructors for "Account" and "OutputProcessor" ..
	_account = new Account();

	_showRootMenu = true;

	_showSubMenu1 = true;

	_endSession = false;

	_id = -1;

	_pn = -1;

	_a = -1;

	_notAnIntegerMessage = "must be a positive integer value.  Please try again.";
	
	_notGreaterThanMinBalanceMessage = "must be greater than min balance.  Please try again.";

	_incorrectMenuSelectionMessage = "Incorrect menu selection.  Please try again.";

	_inputNotReceivedMessage = "Error: user input was not retrieved.";

	_currentConfiguration = ConfigurationIds::firstConfiguration;

	_currentMixConfigurations = new vector<int>();

	_minSelection = 1;

	_maxSelection = 22;

	_startOPSelection = 10;

	// default is "Configuration #1" ..
	for(int i=0; i<_maxSelection; i++){

		_currentMixConfigurations->push_back( 0 );

	}

	// initialize "_currentMixConfigurations" index constants ..
	MAX_NUM_PIN_ATTEMPTS_INDEX = 0;
	MIN_ACCOUNT_BALANCE_INDEX = 1;
	OVERDRAW_PENALTY_INDEX = 2;
	LOGIN_INDEX = 3;
	PIN_INDEX = 4;
	OPEN_ACCOUNT_INDEX = 5;
	BALANCE_INDEX = 6;
	DEPOSIT_INDEX = 7;
	WITHDRAW_INDEX = 8;
	PIN_PROMPT_INDEX = 9;
	INCORRECT_ID_MSG_INDEX = 10;
	INCORRECT_PIN_MSG_INDEX = 11;
	TOO_MANY_ATTEMPTS_MSG_INDEX = 12;
	DISPLAY_MENU_INDEX = 13;
	DEACTIVATE_MSG_INDEX = 14;
	MAKE_WITHDRAW_INDEX = 15;
	PENALTY_MSG_INDEX = 16;
	MAKE_DEPOSIT_INDEX = 17;
	DISPLAY_BALANCE_INDEX = 18;
	BELOW_MIN_BALANCE_INDEX = 19;
	ACTIVATE_MSG_INDEX = 20;
	INACTIVE_ACCOUNT_MSG_INDEX = 21;

}


UserInterface:: ~UserInterface() {

	delete _account;

}

/**************************************************************************
 * Call Chain for this Component:
 *
 * 1) startProgram()
 *
 * 		(a) showApplicationTitle()
 *
 * 		(b) "Root Menu" - showRootMenu(), promptForInput(),
 * 						  parseRootMenuInput()
 *
 * 		(c) "Main Menu" - [ showMainMenu() ], promptForInput(),
 * 						  parseMainMenuInput()
 *
 *
 * 2) parseRootMenuInput()
 *
 * 		(a) "login" - promptForInput(), parseLoginInput(), promptForInput(),
 * 					  parsePinInput()
 *
 * 			(i) parseLoginInput(): _account->login()
 *
 * 			(ii) parsePinInput(): _account->pin(),
 * 								  loop[ promptForInput(), _account->pin() ]
 *
 *
 * 		(b) "open account" - promptForInput(), parseUserIdInput(),
 * 							 promptForInput(), parseUserPinInput(),
 * 							 promptForInput(), parseAccountBalanceInput()
 * 							 _account->open_account()
 *
 * 			(i) parseUserIdInput(): _id = strToInt( inputString_ )
 *
 * 			(ii) parseUserPinInput(): _pn = strToInt( inputString_ )
 *
 * 			(iii) parseAccountBalanceInput(): _a = strToInt( inputString_ )
 *
 *
 * 		(c) "change configuration" - showConfigurationSubMenu(),
 * 									 promptForInput(),
 * 									 parseConfigurationSubMenuInput()
 *
 * 			(i) parseConfigurationSubMenuInput():
 *
 *
 * 					(1) "Choice" 1 - loadConfiguration(),
 * 									 _account->setMaxAttempts(),
 * 									 _account->setMinBalance(),
 * 									 _account->setOverdrawPenalty(),
 * 									 showConfiguration1( true ),
 *
 * 					(2) "Choice" 2 - loadConfiguration(),
 * 									 _account->setMaxAttempts(),
 * 									 _account->setMinBalance(),
 * 									 _account->setOverdrawPenalty(),
 * 									 showConfiguration2( true ),
 *
 * 					(3) "Choice" 3 - showConfigurationSubMenu2(),
 * 									 promptForInput(),
 * 									 parseConfigurationSubMenu2Input(),
 *
 * 					(4) "Choice" 4 - showConfiguration1( true ),
 * 									 showConfiguration2( true ),
 * 									 showConfigurationMix( true ),
 *
 * 					(5) "Choice" 5 - showConfiguration1( true ),
 * 									 showConfiguration2( true ),
 * 									 showConfigurationSubMenu(),
 *
 * 			(ii) parseConfigurationSubMenu2Input(): loadMixConfiguration()
 *
 *
 *
 * 		(d) "end session" - _endSession = true
 *
 *
 * 3) parseMainMenuInput()
 *
 * 		(a) "balance" - _account->balance()
 *
 * 		(b) "deposit"
 *
 * 			(i) _account->getIsActive(), _account->deposit()
 *
 * 			(ii) parseForInput(), parseDepositAmountInput()
 *
 * 		(c) "Withdraw"
 *
 * 			(i) _account->getIsActive(), _account->getIsOverdrawn(),
 * 				_account->withdraw()
 *
 * 			(ii) parseForInput(), parseWithdrawAmountInput()
 *
 * 		(d) "Activate / Deactivate"
 *
 * 			(i) _account->getIsActive(), _account->deactivate()
 *
 * 			(ii) _account->getIsActive(), _account->activate()
 *
 * 		(e) "Current State"
 *
 * 			(i) _account->getState()
 *
 * 			(ii) showMainMenu()
 *
 * 		(f) "Logout"
 *
 * 			(i) _account->logout()
 *
 * 			(ii) _showRootMenu = true
 *
 **************************************************************************/


void UserInterface:: startProgram(){

	showApplicationTitle();

	while ( !_endSession ) {

		if ( _showRootMenu ) {

			// this should be in a loop, until:
			// (a) log-in successful, or
			// (b) session ended
			showRootMenu();

			string inputString = promptForInput( "", 1000 );
			parseRootMenuInput( inputString );

		} else {

			// this should be in a loop, until:
			// (a) log-out successful

			// this is performed by "OP->display_menu",
			// following each IP->Model->OP operation ..
			//showMainMenu();

			string inputString = promptForInput( ">", 1000 );
			parseMainMenuInput( inputString );

		}

	} // end "while()" ..

} // end "startProgram()" ..


void UserInterface:: showApplicationTitle(){

	cout << "      BANK ACCOUNT PROGRAM" << endl;
	cout << "CS586 Software System Architecture" << endl;
	cout << "         Steve Talbot" << endl << endl;

} // end "showApplicationTitle()" ..


void UserInterface:: showRootMenu(){

	// Display menu choices to user:
	// log in, open account, change configuration, end session ..

	cout << endl;
	cout << "==================================" << endl;
	cout << "        MENU SELECTIONS" << endl;
	cout << "==================================" << endl;
	cout << "1) Log In" << endl;
	cout << "2) Open Account" << endl;
	cout << "3) Manage Configuration" << endl;
	cout << "4) End Session" << endl;
	cout << endl;

} // end "showRootMenu()" ..


void UserInterface:: showConfigurationSubMenu(){

	// menu for selecting the style of setting configurations:
	// 1) Choose ALL "Configuration #1" settings
	// 2) Choose ALL "Configuration #2" settings
	// 3) Choose MIX of Configuration #1 & #2 settings

	cout << endl;
	cout << "==================================" << endl;
	cout << "     CONFIGURATION SELECTIONS" << endl;
	cout << "==================================" << endl;
	cout << endl;
	cout << "WARNING: if configuration is changed from 1 to 2," << endl;
	cout << "         and the user logs into an account" << endl;
	cout << "         with 0 < balance < 100, if the user" << endl;
	cout << "         performs \"deposit\" or \"withdraw\"" << endl;
	cout << "         such that the balance remains in this range," << endl;
	cout << "         the system will change the account to the" << endl;
	cout << "         \"overdrawn\" state and apply a penalty" << endl;
	cout << "         (i.e.: not overdrawn in #1, overdrawn in #2)." << endl;
	cout << endl;
	cout << "1) Set Configuration to ALL \"Configuration #1\"" << endl;
	cout << "2) Set Configuration to ALL \"Configuration #2\"" << endl;
	cout << "3) Pick a MIX of Configuration #1 & #2 settings" << endl;
	cout << "4) View Current Configuration" << endl;
	cout << "5) View Configuration Options" << endl;
	cout << "b) Back (previous menu)" << endl;
	cout << endl;


} // end "showConfigurationSubMenu()" ..

void UserInterface:: showConfigurationSubMenu2(){

	// Display configuration selection options,
	// each line can show either: configuration #1, configuration #2 ..

	cout << endl;
	cout << "=================================================" << endl;
	cout << "        CONFIGURATION SELECTIONS (MIX)" << endl;
	cout << "=================================================" << endl;
	cout << endl;
	cout << "1)     max # pin attempts: configuration #" << ( _currentMixConfigurations->at( MAX_NUM_PIN_ATTEMPTS_INDEX ) + 1 ) << endl;
	cout << "2)    min account balance: configuration #" << ( _currentMixConfigurations->at( MIN_ACCOUNT_BALANCE_INDEX ) + 1 ) << endl;
	cout << "3)       overdraw penalty: configuration #" << ( _currentMixConfigurations->at( OVERDRAW_PENALTY_INDEX ) + 1 ) << endl;
	cout << "4)                  login: configuration #" << ( _currentMixConfigurations->at( LOGIN_INDEX ) + 1 ) << endl;
	cout << "5)                    pin: configuration #" << ( _currentMixConfigurations->at( PIN_INDEX ) + 1 ) << endl;
	cout << "6)           open account: configuration #" << ( _currentMixConfigurations->at( OPEN_ACCOUNT_INDEX ) + 1 ) << endl;
	cout << "7)                balance: configuration #" << ( _currentMixConfigurations->at( BALANCE_INDEX ) + 1 ) << endl;
	cout << "8)                deposit: configuration #" << ( _currentMixConfigurations->at( DEPOSIT_INDEX ) + 1 ) << endl;
	cout << "9)               withdraw: configuration #" << ( _currentMixConfigurations->at( WITHDRAW_INDEX ) + 1 ) << endl;
	cout << "10)            pin prompt: configuration #" << ( _currentMixConfigurations->at( PIN_PROMPT_INDEX ) + 1 ) << endl;
	cout << "11)      incorrect id msg: configuration #" << ( _currentMixConfigurations->at( INCORRECT_ID_MSG_INDEX ) + 1 ) << endl;
	cout << "12)     incorrect pin msg: configuration #" << ( _currentMixConfigurations->at( INCORRECT_PIN_MSG_INDEX ) + 1 ) << endl;
	cout << "13) too many attempts msg: configuration #" << ( _currentMixConfigurations->at( TOO_MANY_ATTEMPTS_MSG_INDEX ) + 1 ) << endl;
	cout << "14)          display menu: configuration #" << ( _currentMixConfigurations->at( DISPLAY_MENU_INDEX ) + 1 ) << endl;
	cout << "15)        deactivate msg: configuration #" << ( _currentMixConfigurations->at( DEACTIVATE_MSG_INDEX ) + 1 ) << endl;
	cout << "16)         make withdraw: configuration #" << ( _currentMixConfigurations->at( MAKE_WITHDRAW_INDEX ) + 1 ) << endl;
	cout << "17)           penalty msg: configuration #" << ( _currentMixConfigurations->at( PENALTY_MSG_INDEX ) + 1 ) << endl;
	cout << "18)          make deposit: configuration #" << ( _currentMixConfigurations->at( MAKE_DEPOSIT_INDEX ) + 1 ) << endl;
	cout << "19)       display balance: configuration #" << ( _currentMixConfigurations->at( DISPLAY_BALANCE_INDEX ) + 1 ) << endl;
	cout << "20)     below min balance: configuration #" << ( _currentMixConfigurations->at( BELOW_MIN_BALANCE_INDEX ) + 1 ) << endl;
	cout << "21)          activate msg: configuration #" << ( _currentMixConfigurations->at( ACTIVATE_MSG_INDEX ) + 1 ) << endl;
	cout << "22)  inactive account msg: configuration #" << ( _currentMixConfigurations->at( INACTIVE_ACCOUNT_MSG_INDEX ) + 1 ) << endl;
	cout << "b) Back (previous menu)" << endl;
	cout << endl;

}

void UserInterface:: showMainMenu(){

	// Display menu choices to user:
	// balance, deposit, withdraw, activate / deactivate, logout ..

	if( ( _currentConfiguration == ConfigurationIds::firstConfiguration ) ||
	    ( _currentMixConfigurations->at( 13 ) == 0 ) ) {

		cout << endl;
		cout << "==================================" << endl;
		cout << "          MENU SELECTIONS" << endl;
		cout << "==================================" << endl;
		cout << "1) Balance" << endl;
		cout << "2) Deposit" << endl;
		cout << "3) Withdraw" << endl;

		if( _account->getIsActive() == false ){

			cout << "4) Activate Account" << endl;

		} else {

			cout << "4) Deactivate Account" << endl;

		}

		cout << "5) Current State" << endl;
		cout << "6) Logout" << endl;
		cout << endl;

	} else if( ( _currentConfiguration == ConfigurationIds::secondConfiguration ) ||
	   		   ( _currentMixConfigurations->at( 13 ) == 1 ) ) {

		cout << endl;
		cout << "==================================" << endl;
		cout << "          MENU SELECTIONS" << endl;
		cout << "==================================" << endl;
		cout << "1) Balance" << endl;
		cout << "2) Deposit" << endl;
		cout << "3) Withdraw" << endl;
		cout << "4) Activate / Deactivate Account" << endl;
		cout << "5) Current State" << endl;
		cout << "6) Logout" << endl;
		cout << endl;

	}

} // end "showMainMenu()" ..


void UserInterface:: showConfiguration1( bool showCurrent_ ){

	// Display "Configuration #1" settings ..

	cout << endl;
	cout << "   max # pin attempts: 3" << endl;
	cout << "  min account balance: 0" << endl;
	cout << "     overdraw penalty: 25 (lower min balance = bigger penalty)" << endl;
	cout << "                login: use local copy, else load file copy" << endl;
	cout << "                  pin: no extra output" << endl;
	cout << "         open account: default prompt" << endl;
	cout << "              balance: no extra output" << endl;
	cout << "              deposit: no extra output" << endl;
	cout << "             withdraw: no extra output" << endl;
	cout << "           pin prompt: default prompt " << endl;
	cout << "     incorrect id msg: default message" << endl;
	cout << "    incorrect pin msg: default message" << endl;
	cout << "too many attempts msg: default message" << endl;
	cout << "         display menu: either \"Activate\" or \"Deactivate\" shown, not both" << endl;
	cout << "       deactivate msg: default message" << endl;
	cout << "        make withdraw: no extra output" << endl;
	cout << "          penalty msg: no extra output" << endl;
	cout << "         make deposit: no extra output" << endl;
	cout << "      display balance: default balance message" << endl;
	cout << "    below min balance: default message" << endl;
	cout << "         activate msg: default message" << endl;
	cout << " inactive account msg: default message" << endl;
	cout << endl;
	if( showCurrent_ == true ) {
		cout << "CURRENT CONFIGURATION: #" << (_currentConfiguration + 1) << endl;
		cout << endl;
	}

}


void UserInterface:: showConfiguration2( bool showCurrent_ ){

	// Display "Configuration #2" settings ..

	cout << endl;
	cout << "   max # pin attempts: 5" << endl;
	cout << "  min account balance: 100" << endl;
	cout << "     overdraw penalty: 5 (bigger min balance = lower penalty)" << endl;
	cout << "                login: load file copy (never use local copy)" << endl;
	cout << "                  pin: output # pin \"attempts\" made" << endl;
	cout << "         open account: output alternate prompt" << endl;
	cout << "              balance: output \"invoked\" message" << endl;
	cout << "              deposit: output \"min balance\", \"deposit\", \"new balance\"" << endl;
	cout << "             withdraw: output \"min balance\", \"withdraw\", \"new balance\"" << endl;
	cout << "           pin prompt: output alternate prompt" << endl;
	cout << "     incorrect id msg: output alternate message" << endl;
	cout << "    incorrect pin msg: output alternate message" << endl;
	cout << "too many attempts msg: output alternate message" << endl;
	cout << "         display menu: Both \"Activate / Deactivate\" shown" << endl;
	cout << "       deactivate msg: output alternate message" << endl;
	cout << "        make withdraw: output \"overdrawn\" message when account is overdrawn" << endl;
	cout << "          penalty msg: output \"penalty\" message when account is overdrawn" << endl;
	cout << "         make deposit: output \"overdrawn\" message when account is overdrawn" << endl;
	cout << "      display balance: output alternate balance message" << endl;
	cout << "    below min balance: output alternate message" << endl;
	cout << "         activate msg: output alternate message" << endl;
	cout << " inactive account msg: output alternate message" << endl;
	cout << endl;
	if( showCurrent_ == true ) {
		cout << "CURRENT CONFIGURATION: #" << (_currentConfiguration + 1) << endl;
		cout << endl;
	}

}


void UserInterface:: showConfigurationMix( bool showCurrent_ ){

	// Display "Configuration" settings,
	// each line can be either: configuration #1, configuration #2 ..

	cout << endl;

	int size = _currentMixConfigurations->size();

	int currentConfig = -1;

	for(int i=0; i<size; i++) {

		currentConfig = _currentMixConfigurations->at(i);

		switch( (i+1) ){

			case 1:
				if( currentConfig == 0 )
					cout << "   max # pin attempts(config #" << (currentConfig+1) << "): 3" << endl;
				else if ( currentConfig == 1 )
					cout << "   max # pin attempts(config #" << (currentConfig+1) << "): 5" << endl;
			break;

			case 2:
				if( currentConfig == 0 )
					cout << "  min account balance(config #" << (currentConfig+1) << "): 0" << endl;
				else if ( currentConfig == 1 )
					cout << "  min account balance(config #" << (currentConfig+1) << "): 100" << endl;
			break;

			case 3:
				if( currentConfig == 0 )
					cout << "     overdraw penalty(config #" << (currentConfig+1) << "): 25 (lower min = bigger penalty)" << endl;
				else if ( currentConfig == 1 )
					cout << "     overdraw penalty(config #" << (currentConfig+1) << "): 5 (bigger min = lower penalty)" << endl;
			break;

			case 4:
				if( currentConfig == 0 )
					cout << "                login(config #" << (currentConfig+1) << "): use local copy, else load file copy" << endl;
				else if ( currentConfig == 1 )
					cout << "                login(config #" << (currentConfig+1) << "): load file copy (never use local copy)" << endl;
			break;

			case 5:
				if( currentConfig == 0 )
					cout << "                  pin(config #" << (currentConfig+1) << "): no extra output" << endl;
				else if ( currentConfig == 1 )
					cout << "                  pin(config #" << (currentConfig+1) << "): output # pin \"attempts\" made" << endl;
			break;

			case 6:
				if( currentConfig == 0 )
					cout << "         open account(config #" << (currentConfig+1) << "): default prompt" << endl;
				else if ( currentConfig == 1 )
					cout << "         open account(config #" << (currentConfig+1) << "): output alternate prompt" << endl;
			break;

			case 7:
				if( currentConfig == 0 )
					cout << "              balance(config #" << (currentConfig+1) << "): no extra output" << endl;
				else if ( currentConfig == 1 )
					cout << "              balance(config #" << (currentConfig+1) << "): output \"invoked\" message" << endl;
			break;

			case 8:
				if( currentConfig == 0 )
					cout << "              deposit(config #" << (currentConfig+1) << "): no extra output" << endl;
				else if ( currentConfig == 1 )
					cout << "              deposit(config #" << (currentConfig+1) << "): output \"min balance\", \"deposit\", \"new balance\"" << endl;
			break;

			case 9:
				if( currentConfig == 0 )
					cout << "             withdraw(config #" << (currentConfig+1) << "): no extra output" << endl;
				else if ( currentConfig == 1 )
					cout << "             withdraw(config #" << (currentConfig+1) << "): output \"min balance\", \"withdraw\", \"new balance\"" << endl;
			break;

			case 10:
				if( currentConfig == 0 )
					cout << "           pin prompt(config #" << (currentConfig+1) << "): default prompt " << endl;
				else if ( currentConfig == 1 )
					cout << "           pin prompt(config #" << (currentConfig+1) << "): output alternate prompt" << endl;
			break;

			case 11:
				if( currentConfig == 0 )
					cout << "     incorrect id msg(config #" << (currentConfig+1) << "): default message" << endl;
				else if ( currentConfig == 1 )
					cout << "     incorrect id msg(config #" << (currentConfig+1) << "): output alternate message" << endl;
			break;

			case 12:
				if( currentConfig == 0 )
					cout << "    incorrect pin msg(config #" << (currentConfig+1) << "): default message" << endl;
				else if ( currentConfig == 1 )
					cout << "    incorrect pin msg(config #" << (currentConfig+1) << "): output alternate message" << endl;
			break;

			case 13:
				if( currentConfig == 0 )
					cout << "too many attempts msg(config #" << (currentConfig+1) << "): default message" << endl;
				else if ( currentConfig == 1 )
					cout << "too many attempts msg(config #" << (currentConfig+1) << "): output alternate message" << endl;
			break;

			case 14:
				if( currentConfig == 0 )
					cout << "         display menu(config #" << (currentConfig+1) << "): either \"Activate\" or \"Deactivate\" shown, not both" << endl;
				else if ( currentConfig == 1 )
					cout << "         display menu(config #" << (currentConfig+1) << "): Both \"Activate / Deactivate\" shown" << endl;
			break;

			case 15:
				if( currentConfig == 0 )
					cout << "       deactivate msg(config #" << (currentConfig+1) << "): default message" << endl;
				else if ( currentConfig == 1 )
					cout << "       deactivate msg(config #" << (currentConfig+1) << "): output alternate message" << endl;
			break;

			case 16:
				if( currentConfig == 0 )
					cout << "        make withdraw(config #" << (currentConfig+1) << "): no extra output" << endl;
				else if ( currentConfig == 1 )
					cout << "        make withdraw(config #" << (currentConfig+1) << "): output \"overdrawn\" message when account is overdrawn" << endl;
			break;

			case 17:
				if( currentConfig == 0 )
					cout << "          penalty msg(config #" << (currentConfig+1) << "): no extra output" << endl;
				else if ( currentConfig == 1 )
					cout << "          penalty msg(config #" << (currentConfig+1) << "): output \"penalty\" message when account is overdrawn" << endl;
			break;

			case 18:
				if( currentConfig == 0 )
					cout << "         make deposit(config #" << (currentConfig+1) << "): no extra output" << endl;
				else if ( currentConfig == 1 )
					cout << "         make deposit(config #" << (currentConfig+1) << "): output \"overdrawn\" message when account is overdrawn" << endl;
			break;

			case 19:
				if( currentConfig == 0 )
					cout << "      display balance(config #" << (currentConfig+1) << "): default balance message" << endl;
				else if ( currentConfig == 1 )
					cout << "      display balance(config #" << (currentConfig+1) << "): output alternate balance message" << endl;
			break;

			case 20:
				if( currentConfig == 0 )
					cout << "    below min balance(config #" << (currentConfig+1) << "): default message" << endl;
				else if ( currentConfig == 1 )
					cout << "    below min balance(config #" << (currentConfig+1) << "): output alternate message" << endl;
			break;

			case 21:
				if( currentConfig == 0 )
					cout << "         activate msg(config #" << (currentConfig+1) << "): default message" << endl;
				else if ( currentConfig == 1 )
					cout << "         activate msg(config #" << (currentConfig+1) << "): output alternate message" << endl;
			break;

			case 22:
				if( currentConfig == 0 )
					cout << " inactive account msg(config #" << (currentConfig+1) << "): default message" << endl;
				else if ( currentConfig == 1 )
					cout << " inactive account msg(config #" << (currentConfig+1) << "): output alternate message" << endl;
			break;


			default:
			break;

		} // end "switch()" ..

	} // end "for()" ..

	cout << endl;

	if( showCurrent_ == true ) {
		cout << "CURRENT CONFIGURATION: #" << (_currentConfiguration + 1) << endl;
		cout << endl;
	}

} // end "showConfigurationMix()" ..


string UserInterface:: promptForInput( string prompt_, int numberOfCharacters_ ){

	// prompt for input ..
	if( prompt_.size() > 0 )
		cout << prompt_ << " ";
	else
		cout << "> ";

	char input[ numberOfCharacters_ ];
	cin.getline( input, numberOfCharacters_ );
	string inputString = input;

	string::iterator it;

	for(int i=0; i<inputString.size(); i++){

		it = inputString.begin() + i;

		// need to strip off the "\r" or "\n" anywhere in the string ..
		if( ( inputString[i] == '\n' ) ||
			( inputString[i] == '\r' ) )
			inputString.erase( it );

	}

	return inputString;

} // end "promptForInput()" ..


void UserInterface:: parseRootMenuInput( string inputString_ ){

	if ( inputString_.size() > 0 ) {

		int choice = strToInt( inputString_ );

		if( choice == 1 ){

			cout << endl;

			// "Log In" selected ..
			if ( ( _currentConfiguration == ConfigurationIds::firstConfiguration ) ||
				 ( _currentMixConfigurations->at( LOGIN_INDEX ) == 0 ) )
				cout << "Enter user id";
			else if ( ( _currentConfiguration == ConfigurationIds::secondConfiguration ) ||
				      ( _currentMixConfigurations->at( LOGIN_INDEX ) == 1 ) )
				cout << "Enter id";

			string inputString = promptForInput( ":", 1000 );
			bool isLoginSuccessful = parseLoginInput( inputString );

			if( !isLoginSuccessful ) return;
			else {

				// this is done in "OP->prompt_for_pin()" ..
				// cout << "Enter user pin";

				string inputString = promptForInput( ":", 1000 );

				parsePinInput( inputString );

				cout << endl;

			}

		} else if( choice == 2 ){

			cout << endl;

			// "Open Account" selected ..
			if ( ( _currentConfiguration == ConfigurationIds::firstConfiguration ) ||
				 ( _currentMixConfigurations->at( OPEN_ACCOUNT_INDEX ) == 0 ) )
				cout << "Enter account user id";
			else if ( ( _currentConfiguration == ConfigurationIds::secondConfiguration ) ||
				 ( _currentMixConfigurations->at( OPEN_ACCOUNT_INDEX ) == 1 ) )
				cout << "Enter id";
			string inputString = promptForInput( ":", 1000 );
			bool isIdValid = parseUserIdInput( inputString );
			if( !isIdValid ) return;

			if ( ( _currentConfiguration == ConfigurationIds::firstConfiguration ) ||
				 ( _currentMixConfigurations->at( OPEN_ACCOUNT_INDEX ) == 0 ) )
				cout << "Enter account user pin";
			else if ( ( _currentConfiguration == ConfigurationIds::firstConfiguration ) ||
				      ( _currentMixConfigurations->at( OPEN_ACCOUNT_INDEX ) == 1 ) )
				cout << "Enter pin";
			inputString = promptForInput( ":", 1000 );
			bool isPinValid = parseUserPinInput( inputString );
			if( !isPinValid ) return;

			if ( ( _currentConfiguration == ConfigurationIds::firstConfiguration ) ||
				 ( _currentMixConfigurations->at( OPEN_ACCOUNT_INDEX ) == 0 ) )
				cout << "Enter account initial balance";
			else if ( ( _currentConfiguration == ConfigurationIds::firstConfiguration ) ||
				      ( _currentMixConfigurations->at( OPEN_ACCOUNT_INDEX ) == 1 ) )
				cout << "Enter balance";
			inputString = promptForInput( ":", 1000 );
			bool isBalanceValid = parseAccountBalanceInput( inputString );
			if( !isBalanceValid ) return;
			cout << endl;

			// if the input was validated,
			// perform "open account" operation ..
			if( isIdValid && isPinValid && isBalanceValid ){

				bool isAccountOpened = _account->open_account( _pn, _id, _a );

				if( isAccountOpened ){

					if ( ( _currentConfiguration == ConfigurationIds::firstConfiguration ) ||
				 		 ( _currentMixConfigurations->at( OPEN_ACCOUNT_INDEX ) == 0 ) )
						cout << "User account was opened - id: " << _id << ", pin: " << _pn << ", balance: " << _a << endl << endl;
					else if ( ( _currentConfiguration == ConfigurationIds::firstConfiguration ) ||
				      		  ( _currentMixConfigurations->at( OPEN_ACCOUNT_INDEX ) == 1 ) )
						cout << "User account was opened (id: " << _id << ", pin: " << _pn << ", balance: " << _a << ")" << endl << endl;
					else
						cout << "User account was opened, id: " << _id << ", pin: " << _pn << ", balance: " << _a << endl << endl;

				} else {

					cout << "User account was NOT opened (id already exists, file error, or initial balance too small)." << endl << endl;

				}

			}

		} else if( choice == 3 ){

			// change the configuration of the system ..
			// display configuration sub-menu ..

			showConfigurationSubMenu();

			string inputString = promptForInput( ">", 1000 );

			if( inputString.size() > 0 ) {

				parseConfigurationSubMenuInput( inputString );

			} else {

				cout << _inputNotReceivedMessage << endl << endl;

			}

		} else if( choice == 4 ){

			// "End Session" selected ..
			_endSession = true;

		} else {

			// user did not enter an "integer" value (i.e.: choice < 0), or
			// user entered an "integer" value that is not supported ..
			cout << _incorrectMenuSelectionMessage << endl << endl;

		}

	} else {

		cout << _inputNotReceivedMessage << endl << endl;

	}



} // end "parseRootMenuInput()" ..


bool UserInterface:: parseLoginInput( string inputString_ ) {

	bool isLoginSuccessful = false;

	if( inputString_.size() > 0 ) {

		int login_y = strToInt( inputString_ );

		if( login_y < 0 ){

			// user did not enter an "integer" value ..
			cout << "\"Login\" ";
			cout << _notAnIntegerMessage << endl << endl;

			// need to transition state, so pass to model an invalid value ..
			isLoginSuccessful = _account->login( -1 );

		} else {

			// user entered an "integer" value,
			// check this login ..
			isLoginSuccessful = _account->login( login_y );

			if( isLoginSuccessful )
				_id = login_y;

		}

	} else {

		cout << _inputNotReceivedMessage << endl << endl;

		// need to transition state, so pass to model an invalid value ..
		isLoginSuccessful = _account->login( -1 );

	}


	return isLoginSuccessful;

} // end "parseLoginInput()" ..


void UserInterface:: parsePinInput( string inputString_ ){


	bool inputStringEmpty = false;

	// initialize "pin_p" with an invalid value ..
	int pin_p = -1;

	if( inputString_.size() <= 0 ) {

		inputStringEmpty = true;

		cout << _inputNotReceivedMessage << endl;

	}

	if( inputStringEmpty == false )
		pin_p = strToInt( inputString_ );

	if( ( pin_p < 0 ) && ( inputStringEmpty == false ) ) {

		// user did not enter a  "positive integer" value ..
		cout << "\"Pin\" ";
		cout << _notAnIntegerMessage << endl << endl;

		// need to update state, so pass to model an invalid value ..
		_account->pin( -1 );

	} else {

		bool attemptsRemain = true;

		// user entered an "integer" value,
		// check this pin ..
		bool isPinSuccessful = _account->pin( pin_p );


		if( isPinSuccessful ) {

			_showRootMenu = false;
			_pn = pin_p;

		} else {


			while ( attemptsRemain ) {


				if ( ( _currentConfiguration == ConfigurationIds::firstConfiguration ) ||
				     ( _currentMixConfigurations->at( PIN_INDEX ) == 0 ) )
					cout << "Enter user pin";
				else if ( ( _currentConfiguration == ConfigurationIds::firstConfiguration ) ||
				          ( _currentMixConfigurations->at( PIN_INDEX ) == 1 ) )
					cout << "Enter pin";

				inputStringEmpty = false;

				inputString_ = promptForInput( ":", 1000 );

				if( inputString_.size() <= 0 ) {

					inputStringEmpty = true;

					cout << _inputNotReceivedMessage << endl;

				}

				if( inputStringEmpty == false )
					pin_p = strToInt( inputString_ );

				if( ( pin_p < 0 ) && ( inputStringEmpty == false ) ){

					// user did not enter an "integer" value ..
					cout << "\"Pin\" ";
					cout << _notAnIntegerMessage << endl << endl;

					// need to transition state, so pass to model an invalid value ..
					_account->pin( -1 );

				} else {

					// user entered an "integer" value,
					// check this pin ..
					isPinSuccessful = _account->pin( pin_p );

					if( isPinSuccessful ) {

						_showRootMenu = false;
						attemptsRemain = false;
						_pn = pin_p;

					} else {

						// when number of pin "attempts" reaches max,
						// model returns to "IDLE" state ..
						if( _account->getStateID() == 0 ) {

							attemptsRemain = false;
							_showRootMenu = true;

						}

					}

				} // end "if()" ..

			} // end "while()" ..

		} // end "if()" ..


	} // end "if()" ..


} // end "parsePinInput()" ..


bool UserInterface:: parseUserIdInput( string inputString_ ){

	bool result = false;

	if( inputString_.size() > 0 ) {

		int login_y = strToInt( inputString_ );

		if( login_y < 0 ){

			// user did not enter an "integer" value ..
			cout << "\"Login\" ";
			cout << _notAnIntegerMessage << endl << endl;

		} else {

			// set the temp variable, user "_id" ..
			_id = login_y;

			result = true;

		}

	} else {

		cout << _inputNotReceivedMessage << endl << endl;

	}

	return result;

} // end "parseUserIdInput()" ..


bool UserInterface:: parseUserPinInput( string inputString_ ){

	bool result = false;

	if( inputString_.size() > 0 ) {

		int pin_p = strToInt( inputString_ );

		if( pin_p < 0 ){

			// user did not enter an "integer" value ..
			cout << "\"Pin\" ";
			cout << _notAnIntegerMessage << endl << endl;

		} else {

			// set the temp variable, user "_pn" ..
			_pn = pin_p;

			result = true;

		}

	} else {

		cout << _inputNotReceivedMessage << endl << endl;

	}

	return result;

} // end "parseUserPinInput()" ..


bool UserInterface:: parseAccountBalanceInput( string inputString_ ){

	bool result = false;

	if( inputString_.size() > 0 ) {

		int balance_b = strToInt( inputString_ );

		if( balance_b < 0 ){

			// user did not enter an "integer" value ..
			cout << "Initial \"balance\" amount ";
			cout << _notAnIntegerMessage << endl << endl;

		} else if( balance_b < _account->getMinBalance() ){
			
			// user entered an "initial balance" that was below
			// the min value for the currently chosen configuration ..
			cout << "Initial \"balance\" amount ";
			cout << _notGreaterThanMinBalanceMessage << endl << endl;
			
		}
		
		// neither "error" condition handled above applies,
		// so go ahead and assign the temp variable value to
		// the local variable "_a" ..
		if( ( balance_b >= 0 ) && 
			( balance_b >= _account->getMinBalance() ) ) {

			_a = balance_b;

			result = true;

		}

	} else {

		cout << _inputNotReceivedMessage << endl << endl;

	}

	return result;

} // end "parseAccountBalanceInput()" ..


void UserInterface:: parseConfigurationSubMenuInput( string inputString_ ){

/*
	=================================
	    CONFIGURATION SELECTIONS
	=================================
	1) ALL Configuration #1 (default)
	2) ALL Configuration #2
	3) MIX Configuration #1 & #2
*/

	// initialize these parameters ..
	_showSubMenu1 = true;
	bool isLoadConfiguration = false;
	bool isMixConfigurationLoaded = false;
	int choice = -1;


	while( _showSubMenu1 ) {

		choice = strToInt( inputString_ );

		if( choice == 1 ){

			// go with "Configuration #1 (default)" ..
			ConfigurationFactory1* cf1 = new ConfigurationFactory1();

			loadConfiguration( cf1 );

			// configure "Data" system parameters ..
			_account->setMaxAttempts( 3 );
			_account->setMinBalance( 0 );
			_account->setOverdrawPenalty( 25 );

			for(int i=0; i<_maxSelection; i++)
				_currentMixConfigurations->at(i) = 0;

			_currentConfiguration = ConfigurationIds::firstConfiguration;

			// show the "configuration selection" options that are currently chosen ..
			showConfiguration1( true );

			//_showSubMenu1 = true;

		} else if( choice == 2 ){

			// go with "Configuration #2" ..
			ConfigurationFactory* cf2 = new ConfigurationFactory2();

			loadConfiguration( cf2 );

			// configure "Data" system parameters ..
			_account->setMaxAttempts( 5 );
			_account->setMinBalance( 100 );
			_account->setOverdrawPenalty( 5 );

			for(int i=0; i<_maxSelection; i++)
				_currentMixConfigurations->at(i) = 1;

			_currentConfiguration = ConfigurationIds::secondConfiguration;

			// show the "configuration selection" options that are currently chosen ..
			showConfiguration2( true );

			//_showSubMenu1 = true;

		} else if( choice == 3 ){

			// "Configuration #1 (default)" ..
			ConfigurationFactory1* cf1 = new ConfigurationFactory1();

			// "Configuration #2" ..
			ConfigurationFactory2* cf2 = new ConfigurationFactory2();

			bool isDoneMakingSelections = false;

			while( isDoneMakingSelections == false ){

				// show the sub menu 2 selections ..
				showConfigurationSubMenu2();

				cout << "Enter selection to configure";
				string inputString = promptForInput( ":", 1000 );

				if ( inputString.size() > 0 ) {

					isDoneMakingSelections = parseConfigurationSubMenu2Input( inputString, cf1, cf2 );

				}  else {

					cout << _inputNotReceivedMessage << endl << endl;

				}

			}

			_currentConfiguration = ConfigurationIds::mixConfiguration;

			isMixConfigurationLoaded = true;

			//_showSubMenu1 = true;

		} else if( ( inputString_.compare("b") == 0 ) ||
			   	   ( inputString_.compare("B") == 0 ) ) {

			// return to previous "Root Menu" ..
			// do nothing special, just avoid other options ..

			_showSubMenu1 = false;

		} else if( choice == 4 ) {

			// "4) View Current Configuration" ..

			if( _currentConfiguration == ConfigurationIds::firstConfiguration ){

				showConfiguration1( true );

			} else if( _currentConfiguration == ConfigurationIds::secondConfiguration ){

				showConfiguration2( true );

			} else if( _currentConfiguration == ConfigurationIds::mixConfiguration ){

				showConfigurationMix( true );

			}

			cout << endl;

			//_showSubMenu1 = true;

		} else if( choice == 5 ) {

			// "5) View Configuration Options" ..

			cout << "CONFIGURATION #1:" << endl << endl;
			showConfiguration1( false );
			cout << endl;

			cout << "CONFIGURATION #2:" << endl << endl;
			showConfiguration2( false );
			cout << endl;

			//_showSubMenu1 = true;

		} else {

			// user did not enter an "integer" value (i.e.: choice < 0), or
			// user entered an "integer" value that is not supported ..
			cout << _incorrectMenuSelectionMessage << endl << endl;

			//_showSubMenu1 = true;

		} // end "if()" ..


		if( _showSubMenu1 == true ){

			// if the user has performed an operation that
			// remains in this sub-menu, prompt for new input selection ..

			bool isInputValid = false;

			while( isInputValid == false ) {

				// keep prompting until input is valid ..

				showConfigurationSubMenu();

				inputString_ = promptForInput( ">", 1000 );

				if( inputString_.size() > 0 ) {

					isInputValid = true;

				} else {

					cout << _inputNotReceivedMessage << endl << endl;

				}

			} // end "while()" ..

		} // end "if()" ..

		// re-set these parameters for the next iteration ..
		isLoadConfiguration = false;
		isMixConfigurationLoaded = false;

	} // end "while()" ..


	if ( isLoadConfiguration == true ) {

		if( isMixConfigurationLoaded == true ) {

			cout << "Mix of Configuration #1 & #2 was loaded." << endl << endl;

		} else {

			cout << "Configuration #" << choice << " was loaded." << endl << endl;

		} // end "if()" ..

	} // end "if()" ..

} // end "parseConfigurationSubMenuInput()" ..


void UserInterface:: loadConfiguration( ConfigurationFactory* cf_ ){

	// use the version of the "ConfigurationFactory"
	// to load the correct version of object method-wrappers ..

	// this isn't needed; each "set" method handles this now ..
	//_account->removeCurrentConfiguration();

	_account->setLoginA( cf_->makeLogin() );
	_account->setPinA( cf_->makePin() );
	_account->setDepositA( cf_->makeDeposit() );
	_account->setWithdrawA( cf_->makeWithdraw() );
	_account->setBalanceA( cf_->makeBalance() );

	OutputProcessor* OP = _account->getOutputProcessor();

	// this isn't needed; each "set" method handles this now ..
	//OP->removeCurrentConfiguration();

	OP->setPromptForPinA( cf_->makePromptForPin() );
	OP->setIncorrectIdMsgA( cf_->makeIncorrectIdMsg() );
	OP->setIncorrectPinMsgA( cf_->makeIncorrectPinMsg() );
	OP->setTooManyAttemptsMsgA( cf_->makeTooManyAttemptsMsg() );
	OP->setDisplayMenuA( cf_->makeDisplayMenu() );
	OP->setDeactivateMsgA( cf_->makeDeactivateMsg() );
	OP->setMakeWithdrawMsgA( cf_->makeMakeWithdraw() );
	OP->setPenaltyA( cf_->makePenalty() );
	OP->setMakeDepositA( cf_->makeMakeDeposit() );
	OP->setDisplayBalanceA( cf_->makeDisplayBalance() );
	OP->setBelowMinBalanceMsgA( cf_->makeBelowMinBalance() );
	OP->setActivateMsgA( cf_->makeActivateMsg() );
	OP->setInactiveAccountMsgA( cf_->makeInactiveAccountMsg() );

}

bool UserInterface:: parseConfigurationSubMenu2Input( string inputString_, ConfigurationFactory1* cf1_, ConfigurationFactory2* cf2_ ){

		bool isDoneMakingSelections = false;

		int selection = strToInt( inputString_ );

		if( ( selection >= _minSelection ) && ( selection <= _maxSelection ) ) {

			// valid selections ..

			cout << "1 or 2";
			inputString_ = promptForInput( ":", 1000 );


 			if( inputString_.size() > 0 ) {


				int configurationSelection = strToInt( inputString_ );

				// if( 1 <= configurationSelection <= 2 ) ..
				if( ( configurationSelection == 1 ) ||
					( configurationSelection == 2 ) ) {

					// valid selections ..

					ConfigurationFactory* cf_;

					if( configurationSelection == 1 ) {

						cf_ = cf1_;

					} else if( configurationSelection == 2 ) {

						cf_ = cf2_;

					}

					loadMixConfiguration( selection, configurationSelection, cf_ );

					_currentConfiguration = ConfigurationIds::mixConfiguration;


				} else {

					// user did not enter an "integer" value (i.e.: configurationSelection > 2), or
					// user entered an "integer" value that is not supported ..
					cout << _incorrectMenuSelectionMessage << endl << endl;

				}


			} else {

				cout << _inputNotReceivedMessage << endl << endl;

			}


		} else if( ( inputString_.compare("b") == 0 ) ||
			   	   ( inputString_.compare("B") == 0 ) ) {

			// return to previous "Root Menu" ..
			isDoneMakingSelections = true;


		} else {

			// user did not enter an "integer" value (i.e.: choice < 0), or
			// user entered an "integer" value that is not supported ..
			cout << _incorrectMenuSelectionMessage << endl << endl;

		}

		return isDoneMakingSelections;

}

void UserInterface:: loadMixConfiguration( int selection_, int configurationSelection_, ConfigurationFactory* cf_ ){

	// use the version of the "ConfigurationFactory"
	// to load the correct version of object method-wrappers ..

	// selections 10 - 21 only use the "OP" ..
	OutputProcessor* OP;

	// if( ( selection_ >= 10 ) && ( selection_ <= 21 ) )
	if( ( selection_ >= _startOPSelection ) && ( selection_ <= _maxSelection ) ) {

		OP = _account->getOutputProcessor();

	}

	switch( selection_ ){

		// configure "Data" system parameters ( selection_ == 1, 2, 3 ) ..
		case 1:
		if( configurationSelection_ == 1 ) {
			_account->setMaxAttempts( 3 );
		} else {
			_account->setMaxAttempts( 5 );
		}
		break;

		case 2:
		if( configurationSelection_ == 1 ) {
			_account->setMinBalance( 0 );
		} else {
			_account->setMinBalance( 100 );
		}
		break;

		case 3:
		if( configurationSelection_ == 1 ) {
			_account->setOverdrawPenalty( 25 );
		} else {
			_account->setOverdrawPenalty( 5 );
		}
		break;

		case 4:
		_account->setLoginA( cf_->makeLogin() );
		break;

		case 5:
		_account->setPinA( cf_->makePin() );
		break;

		case 6:
		// "open_account()" only 1 version (but w/ display message variations)
		break;

		case 7:
		_account->setBalanceA( cf_->makeBalance() );
		break;

		case 8:
		_account->setDepositA( cf_->makeDeposit() );
		break;

		case 9:
		_account->setWithdrawA( cf_->makeWithdraw() );
		break;

		case 10:
		OP->setPromptForPinA( cf_->makePromptForPin() );
		break;

		case 11:
		OP->setIncorrectIdMsgA( cf_->makeIncorrectIdMsg() );
		break;

		case 12:
		OP->setIncorrectPinMsgA( cf_->makeIncorrectPinMsg() );
		break;

		case 13:
		OP->setTooManyAttemptsMsgA( cf_->makeTooManyAttemptsMsg() );
		break;

		case 14:
		OP->setDisplayMenuA( cf_->makeDisplayMenu() );
		break;

		case 15:
		OP->setDeactivateMsgA( cf_->makeDeactivateMsg() );
		break;

		case 16:
		OP->setMakeWithdrawMsgA( cf_->makeMakeWithdraw() );
		break;

		case 17:
		OP->setPenaltyA( cf_->makePenalty() );
		break;

		case 18:
		OP->setMakeDepositA( cf_->makeMakeDeposit() );
		break;

		case 19:
		OP->setDisplayBalanceA( cf_->makeDisplayBalance() );
		break;

		case 20:
		OP->setBelowMinBalanceMsgA( cf_->makeBelowMinBalance() );
		break;

		case 21:
		OP->setActivateMsgA( cf_->makeActivateMsg() );
		break;

		case 22:
		OP->setInactiveAccountMsgA( cf_->makeInactiveAccountMsg() );
		break;

		default:
		break;

	}

	// designate the "Configuration Selection" as #1 or #2 ..
	if( configurationSelection_ == 1 )
		_currentMixConfigurations->at( ( selection_ - 1 ) ) = 0;
	else
		_currentMixConfigurations->at( ( selection_ - 1 ) ) = 1;

} // end "loadMixConfiguration()" ..


void UserInterface:: parseMainMenuInput( string inputString_ ){

/*
	cout << "MENU SELECTIONS" << endl;
	cout << "================" << endl;
	cout << "1) Balance" << endl;
	cout << "2) Deposit" << endl;
	cout << "3) Withdraw" << endl;
	if( data_->getCurrentAccountInfo()->getIsActive() == false ){
		cout << "4) Activate account" << endl;
	} else {
		cout << "4) Deactivate account" << endl;
	}
	cout << "5) Logout" << endl;
*/

	int choice = strToInt( inputString_ );

	if( choice == 1 ){

		// "Balance" selected ..
		_account->balance();

	} else if( choice == 2 ){

		// "Deposit" selected ..

		bool isDepositAmountValid = false;

		if( _account->getIsActive() == false ) {

			// "model" will indicate to "OP" to output a message
			// saying that the transaction cannot be performed,
			// b/c the account is "inactive" ..
			isDepositAmountValid = _account->deposit( 0 );

		} else {

			cout << "Enter \"deposit\" amount";
			string inputString = promptForInput( ":", 1000 );
			isDepositAmountValid = parseDepositAmountInput( inputString );

		}

	} else if( choice == 3 ){

		// "Withdraw" selected ..

		bool isWithdrawAmountValid = false;

		if( ( _account->getIsActive() == false ) ||
			( _account->getIsOverdrawn() == true ) ) {

			// "model" will indicate to "OP" to output a message
			// saying that the transaction cannot be performed,
			// b/c the account is "inactive" or "overdrawn" ..
			isWithdrawAmountValid = _account->withdraw( 0 );

		} else {

			cout << "Enter \"withdraw\" amount";
			string inputString = promptForInput( ":", 1000 );
			isWithdrawAmountValid = parseWithdrawAmountInput( inputString );

		}

	} else if( choice == 4 ){

		// "Activate" / "Deactivate" selected ..

		bool result = false;

		if( _account->getIsActive() == true )
			result = _account->deactivate();
		else
			result = _account->activate();

	} else if( choice == 5 ){

		// "Current State" selected ..

		cout << "Current state: " << _account->getState() << endl << endl;

		// this is needed here, because "show current state" operation
		// is not supported by the "IP->Model->OP" architecture ..
		showMainMenu();


	} else if( choice == 6 ){

		// "Logout" selected ..
		_account->logout();

		_showRootMenu = true;

		if ( _currentConfiguration == ConfigurationIds::firstConfiguration )
			cout << "The user was \"logged out\" - id: " << _id << endl << endl;
		else if ( _currentConfiguration == ConfigurationIds::secondConfiguration )
			cout << "The user was \"logged out\" (id: " << _id << ")" << endl << endl;
		else
			cout << "The user was \"logged out\" id: " << _id << endl << endl;

	} else {

		// user did not enter an "integer" value (i.e.: choice < 0), or
		// user entered an "integer" value that is not supported ..
		cout << _incorrectMenuSelectionMessage << endl << endl;

		showMainMenu();

	}

} // end "parseMainMenuInput()" ..


bool UserInterface:: parseDepositAmountInput( string inputString_ ){

	bool result = true;

	int deposit_d = strToInt( inputString_ );

	if( deposit_d < 0 ){

		// user did not enter an "integer" value ..
		cout << "\"Deposit\" amount ";
		cout << _notAnIntegerMessage << endl << endl;

		showMainMenu();

		result = false;

	} else {

		result = _account->deposit( deposit_d );

	}

	return result;

} // end "parseDepositAmountInput()" ..


bool UserInterface:: parseWithdrawAmountInput( string inputString_ ){

	bool result = true;

	int withdraw_w = strToInt( inputString_ );

	if( withdraw_w < 0 ){

		// user did not enter an "integer" value ..
		cout << "\"Withdraw\" amount ";
		cout << _notAnIntegerMessage << endl << endl;

		showMainMenu();

		result = false;

	} else {

		result = _account->withdraw( withdraw_w );

	}

	return result;

} // end "parseWithdrawAmountInput()" ..


