// Sean Szumlanski
// 7/15/02
// This program, like the previous program, allows the user to choose one
// of several mathematical functions to calculate and produces the result
// of the desired computation. A menu is used so that the user can attempt
// as many calculations as they want before terminating the program.
#include <iostream.h>

// Function prototypes.
int	display_menu(void); 
float	add(float lhs, float rhs); 
float	multiply(float lhs, float rhs); 
float	subtract(float lhs, float rhs); 
float	divide(float lhs, float rhs);
int	factorial(int n);
float	power(float n, int exp);


int main() {

	int   option, exit = 0, nArg;
	float lhs, rhs, answer;

	// Continue until the user wants to quit.
	while (!exit) {

		option = display_menu();  // This calls the display_menu() function and assigns
		                          // whatever value it returns to the "option" variable

		if (option == 1) {
			// Prompt and read in the input values.
			cout << "\nEnter the two numbers to be added, separated by a space: ";
			cin >> lhs >> rhs;

			// Make the appropriate function call to do the 
			// calculation.
			cout << "\n" << lhs << " + " << rhs << " = " << add(lhs, rhs) << "\n\n";
		}

		else if (option == 2) {
			cout << "\nEnter the two numbers to be subtracted, separated by a space: ";
			cin >> lhs >> rhs;
			cout << "\n" << lhs << " - " << rhs << " = " << subtract(lhs, rhs) << "\n\n";
		}

		else if (option == 3) {
			cout << "\nEnter the two numbers to be multiplied, separated by a space: ";
			cin >> lhs >> rhs;
			cout << "\n" << lhs << " * " << rhs << " = " << multiply(lhs, rhs) << "\n\n";
		}

		else if (option == 4) {
			cout << "\nEnter the quotient, followed by the divisor, separated by a space: ";
			cin >> lhs >> rhs;
	
			// Check for invalid input.
			if (rhs == 0)
				cout << "Division by zero is not allowed.\n\n";
			else 
				cout << "\n" << lhs << " / " << rhs << " = " << divide(lhs,rhs) << "\n\n";
			
		}

		else if (option == 5) {
			cout << "\nEnter the number to be raised to some power: ";
			cin >> lhs;
			cout << "Enter the power to which you want to raise " << lhs << ": ";
			cin >> nArg;
			cout << "\n" << lhs << " ^ " << nArg << " = " << power(lhs, nArg) << "\n\n";
		}

		else if (option == 6) {
			cout << "\nEnter an integer to calculate its factorial: ";
			cin >> nArg;
			cout << "\nThe factorial of " << lhs << " is " << factorial(nArg) << "\n\n";
		}

		else if (option == 7) {
			cout << "\nGoodbye!\n";
			exit = 1;
		}

		else
			cout << "\nThat is not a valid option. Please try again.\n\n";

	}

	return 0;
}

// Prompts the user with the menu, reads their selection, and returns this
// value.
int display_menu(void) {

	int option;
	// Print menu
	cout << "1. Add Two Numbers" << endl;
	cout << "2. Subtract Two Numbers" << endl;
	cout << "3. Multiply Two Numbers" << endl;
	cout << "4. Divide Two Numbers" << endl;
	cout << "5. Raise a Number to a Power" << endl;
	cout << "6. Calculate a Factorial" << endl;
	cout << "7. Exit Program" << endl;
	cout << "\nSelect an option: ";

	// Read and return the response.
	cin >> option;
	return option;
}

// Returns the sum of the two parameters.
float add(float lhs, float rhs) {
	return lhs + rhs;
}

// Returns the product of the two parameters.
float multiply(float lhs, float rhs) {
	return lhs * rhs;
}

// Returns the difference between the two parameters.
float subtract(float lhs, float rhs) {
	return lhs - rhs;
}

// Returns the quotient of the first parameter divided by the second.
float divide(float lhs, float rhs) {
	return lhs / rhs;
}

// Computes the value of n!, if n is a non-negative integer.
int factorial(int n) {
	int answer = 1;
	
	// Multiplies each integer from n downto 2 together.
	while (n > 1) {
		answer *= n;
		n--;
	}
	return answer;
}

// Returns the value of n^exp.
float power(float n, int exp) {

	float answer = 1;

	// Check for a negative exponent.
	bool flag = false;
	if (exp < 0) {
		flag = true;
		exp = -exp;
	}

	// Multiplies n by itself |exp| times.
	for (int i=0; i < exp; i++) {
		answer *= n;
	}

	// Reciprocate the answer for a negative exponent.
	if (flag)
		answer = 1/answer;
	return answer;
}
