#ifndef STATE_H_
#define STATE_H_

// Author: Steve Talbot

#pragma once

using namespace std;

#include "OutputProcessor.h"
#include "StateIds.h"

class State {

public:
	State();
	virtual ~State();

	int getID();
	void setID( int id_ );

	string getDescription();
	void setDescription( string desciption_ );

	OutputProcessor* getOutputProcessor();
	void setOutputProcessor( OutputProcessor* OP_ );

	StateIds* getStateIds();
	void setStateIds( StateIds* OP_ );

	// All of the methods that are invoked in any of the sub-classes of this parent class are found here.
	// The methods in this parent class are all concrete, not "abstract" (i.e.: pure virtual) methods,
	// so they have "empty implementations", since they are never invoked directly from the parent class "State",
	// and since the sub-classes override only the methods which apply to each sub-class.

	// An alternate approach would be to make all of the methods in this parent class "abstract" (i.e. pure virtual).
	// Each sub-class would be forced to implement every method in found here this abstract parent class.
	// However, this approach places the "empty implementations" in the sub-classes instead of in the parent class,
	// and requires much more code duplication than the approach used here.  Therefore, this alternate approach
	// was not actualized (but the code is included for reference).

	// The state sub-classes associated with each method are shown to the right of the method.

	virtual bool correct_login( int& nextStateId_ ); //= 0;									// Idle();
	virtual bool incorrect_login(); //= 0;													// Idle();
	virtual bool logout( int& nextStateId_ ); //= 0;										// Inactive(); Overdrawn(); Ready();

	virtual bool correct_pin( int& nextStateId_ ); //= 0;									// Overdrawn(); Ready();
	virtual bool correct_pin( bool isAboveMinBalance_, int& nextStateId_ ); //= 0;			// Inactive();
	virtual bool correct_pin( bool isAboveMinBalance_, bool isActive_, int& nextStateId_ ); //= 0;	// CheckPin();

	virtual bool incorrect_pin(); //= 0;													// Inactive(); Overdrawn(); Ready();
	virtual bool incorrect_pin( bool attemptsRemain_, int& nextStateId_ ); //= 0;			// CheckPin();

	virtual bool attempts_remain(); //= 0;													// CheckPin();
	virtual bool too_many_attempts(int& nextStateId_); //= 0;								// CheckPin();

	virtual bool active(bool isAboveMinBalance_, int& nextStateId_); //= 0;					// CheckPin();
	virtual bool inactive(int& nextStateId_); //= 0;										// CheckPin();

	virtual bool above_min_balance(int& nextStateId_); //= 0;								// CheckPin(); Inactive();
	virtual bool below_min_balance(int& nextStateId_); //= 0;								// CheckPin(); Inactive();

	virtual bool activate( bool isPinCorrect_, bool isAboveMinBalance_, int& nextStateId ); //= 0;	// Inactive();
	virtual bool deactivate( bool isPinCorrect_, int& nextStateId_ ); //= 0;						// Overdrawn(); Ready();

	virtual bool balance(); //= 0;															// Inactive(); Overdrawn(); Ready();
	virtual bool withdraw( bool isLessThanMinBalance_, int& nextStateId_ ); //= 0;			// Inactive(); Overdrawn(); Ready();
	virtual bool deposit( bool isLessThanMinBalance_, int& nextStateId_ ); //= 0;			// Inactive(); Overdrawn(); Ready();

	virtual bool diff_more_or_equal_to_min_balance(); //= 0;								// Ready();
	virtual bool diff_less_than_min_balance( int& nextStateId_ ); //= 0;					// Ready();

	virtual bool sum_more_or_equal_to_min_balance( int& nextStateId_ ); //= 0;				// Overdrawn();
	virtual bool sum_less_than_min_balance(); //= 0;										// Overdrawn();

	StateIds* _stateIds;

private:

	int _id;

	string _description;

	OutputProcessor* _OP;

};

#endif /*STATE_H_*/
