// very simplified fsm to illustrate the inner workings of an elevator
#include <iostream>

enum StateType { ST_REST, ST_GOING_UP, ST_GOING_DOWN };
enum { DOWN_BUTTON_PRESS, UP_BUTTON_PRESS } eEvent;

StateType Transition(StateType CurrentState);
void PrintState(StateType CurrentState);

void GoUp() {}; // action
void GoDown() {};
void Stop() {};


int main()
{
	std::cout << "Original State" << std::endl;
	PrintState(ST_REST);

	eEvent = UP_BUTTON_PRESS;
	std::cout << "\n->Event: Up button pressed" << std::endl;
	StateType state1 = Transition(ST_REST);

	std::cout << "\nState After" << std::endl;
	PrintState(state1);

	eEvent = DOWN_BUTTON_PRESS;
	std::cout << "\n->Event: Down button pressed" << std::endl;
	StateType state2 = Transition(state1);

	std::cout << "\nState After" << std::endl;
	PrintState(state2);

	eEvent = DOWN_BUTTON_PRESS;
	std::cout << "\n->Event: Down button pressed" << std::endl;
	StateType state3 = Transition(state2);

	std::cout << "\nState After" << std::endl;
	PrintState(state3);

	return 0;
}

StateType Transition(StateType CurrentState)
{
	StateType NextState = CurrentState;

	switch(CurrentState)
	{
	case ST_REST:
		switch(eEvent)
		{
		case UP_BUTTON_PRESS:
			NextState = ST_GOING_UP;
			break;
		case DOWN_BUTTON_PRESS:
			NextState = ST_GOING_DOWN;
			break;
		}
		break;
	case ST_GOING_UP:
		switch(eEvent)
		{
		case DOWN_BUTTON_PRESS:
			Stop();
			NextState = ST_GOING_DOWN;
			break;
		}
		break;
	case ST_GOING_DOWN:
		switch(eEvent)
		{
		case UP_BUTTON_PRESS:
			Stop();
			NextState = ST_GOING_UP;
			break;
		}
		break;
	}
	return NextState;
}
			
void PrintState(StateType CurrentState)
{
	switch(CurrentState)
	{
	case ST_REST:
		std::cout << "The elevator is at rest." << std::endl;
		break;
	case ST_GOING_UP:
		std::cout << "The elevator is going up." << std::endl;
		break;
	case ST_GOING_DOWN:
		std::cout << "The elevator is going down." << std::endl;
		break;
	}
}