#include "MDA_EFSM.h"

// Author: Steve Talbot

MDA_EFSM:: MDA_EFSM( OutputProcessor* OP_ ){

	_stateIds = new StateIds();

	// initialize "states" ..
	_states = new vector<State*>();

	Idle* idle = new Idle();
	idle->setID( 0 );
	idle->setDescription("IDLE");
	idle->setOutputProcessor( OP_ );
	_states->push_back( idle );

	CheckPin* checkPin = new CheckPin();
	checkPin->setID( 1 );
	checkPin->setDescription("CHECKPIN");
	checkPin->setOutputProcessor( OP_ );
	_states->push_back( checkPin );

	Ready* ready = new Ready();
	ready->setID( 2 );
	ready->setDescription("READY");
	ready->setOutputProcessor( OP_ );
	_states->push_back( ready );

	Overdrawn* overdrawn = new Overdrawn();
	overdrawn->setID( 3 );
	overdrawn->setDescription("OVERDRAWN");
	overdrawn->setOutputProcessor( OP_ );
	_states->push_back( overdrawn );

	Inactive* inactive = new Inactive();
	inactive->setID( 4 );
	inactive->setDescription("INACTIVE");
	inactive->setOutputProcessor( OP_ );
	_states->push_back( inactive );

	// initialize the "currentState" ..
	_currentState = _states->at( 0 );


}

MDA_EFSM:: ~MDA_EFSM(){

	if( _states != NULL ) {
		for(int i=0; i<_states->size(); i++)
			if( _states->at(i) != NULL ) delete _states->at(i);
	}

	if( _states != NULL ) delete _states;

	// don't do this, b/c it just points to an entry in "_states",
	// which gets "deleted" in the line above!
	//if( _currentState != NULL ) delete _currentState;

	if( _stateIds != NULL ) delete _stateIds;

}


vector<State*>* MDA_EFSM:: getStates(){

	return _states;

}

void MDA_EFSM:: setStates( vector<State*>* states_ ){

	_states = states_;

	// starts at the IDLE state ..
	_currentState = _states->at( 0 );

}


State* MDA_EFSM:: getCurrentState(){

	return _currentState;

}


void MDA_EFSM:: changeState( int stateId_ ) {

	_currentState = _states->at( stateId_ );

}

bool MDA_EFSM:: open_account(){

	changeState( _stateIds->IDLE );

	return true;

}

bool MDA_EFSM:: correct_login(){

	int nextStateId = -1;

	bool result = _currentState->correct_login( nextStateId );

	if( nextStateId >= 0 ) changeState( nextStateId );

	return result;

}

bool MDA_EFSM:: incorrect_login(){

	return _currentState->incorrect_login();

}

bool MDA_EFSM:: logout(){

	int nextStateId = -1;

	bool result = _currentState->logout( nextStateId );

	if( nextStateId >= 0 ) changeState( nextStateId );

	return result;

}

bool MDA_EFSM:: correct_pin( bool isAboveMinBalance_, bool isActive_ ){

	// “isAboveMinBalance_”and “isActive_” passed in from the Account..

	int nextStateId = -1;

	bool result = _currentState->correct_pin( isAboveMinBalance_, isActive_, nextStateId );

	if( nextStateId >= 0 ) changeState( nextStateId );

	return result;

}

bool MDA_EFSM:: incorrect_pin( bool attemptsRemain_ ){

	// “attemptsRemain_ passed in from the Account ..

	int nextStateId = -1;

	bool result = _currentState->incorrect_pin( attemptsRemain_, nextStateId );

	if( nextStateId >= 0 ) changeState( nextStateId );

	return result;

}
/*
bool MDA_EFSM:: attempts_remain(){

	// remove ..

}

bool MDA_EFSM:: too_many_attempts(){

	// remove ..

}

bool MDA_EFSM:: active(){

	// remove ..

}

bool MDA_EFSM:: inactive(){

	// remove ..

}

bool MDA_EFSM:: above_min_balance(){

	// remove ..

}

bool MDA_EFSM:: below_min_balance(){

	// remove ..

}
*/

bool MDA_EFSM:: activate( bool isPinCorrect_, bool isAboveMinBalance_ ){

	// “isPinCorrect_” passed in from the Account..

	int nextStateId = -1;

	bool result = _currentState->activate( isPinCorrect_, isAboveMinBalance_, nextStateId );

	if( nextStateId >= 0 ) changeState( nextStateId );

	return result;

}

bool MDA_EFSM:: deactivate( bool isPinCorrect_ ){

	// “isPinCorrect_” passed in from the Account..

	int nextStateId = -1;

	bool result = _currentState->deactivate( isPinCorrect_, nextStateId );

	if( nextStateId >= 0 ) changeState( nextStateId );

	return result;

}

bool MDA_EFSM:: balance(){

	return _currentState->balance();

}

bool MDA_EFSM:: withdraw( bool isLessThanMinBalance_ ){

	// “isLessThanMinBalance_” passed in from the Account..

	int nextStateId = -1;

	bool result = _currentState->withdraw( isLessThanMinBalance_, nextStateId );

	if( nextStateId >= 0 ) changeState( nextStateId );

	return result;

}

bool MDA_EFSM:: deposit( bool isLessThanMinBalance_ ){

	int nextStateId = -1;

	bool result = _currentState->deposit( isLessThanMinBalance_, nextStateId );

	if( nextStateId >= 0 ) changeState( nextStateId );

	return result;

}
/*
bool MDA_EFSM:: diff_more_or_equal_to_min_balance(){

	// remove ..

}

bool MDA_EFSM:: diff_less_than_min_balance(){

	// remove ..

}

bool MDA_EFSM:: sum_more_or_equal_to_min_balance(){

	// remove ..

}

bool MDA_EFSM:: sum_less_than_min_balance(){

	// remove ..

}
*/
