/* Lecture Code 4.0
 *
 * strutils.h Implementations.  Some of this is based on older lecture code.
 *
 */
 
#include <string>
#include <sstream>
#include <cctype> // for toupper, tolower
#include <cstdlib> // for exit
#include <iostream>
#include <algorithm> // for transform
using namespace std;
 
string ConvertToUpperCase(string input)
{
	/* Apply toupper to each element and store it back in itself.  Note that the icky
	 * (int (*)(int)) typecast is not needed in Visual Studio. */
	transform(input.begin(), input.end(), input.begin(), (int (*)(int))toupper);
	return input;
}
 
string ConvertToLowerCase(string input)
{
	/* Apply tolower to each element and store it back in itself. */
	transform(input.begin(), input.end(), input.begin(), (int (*)(int))tolower);
	return input;
}
 
string IntegerToString(int input)
{
	/* Use a stringstream! */
	stringstream converter;
	converter << input;
	return converter.str();
}
 
string RealToString(double input)
{
	/* Use a stringstream! */
	stringstream converter;
	converter << input;
	return converter.str();
}

/* A modified version of GetInteger that calls the C function 'exit' to halt
 * execution if input is invalid.
 */
int StringToInteger(string input)
{
	stringstream converter(input);
	int result;
	
	/* Try reading an integer, fail if the operation fails. */
	converter >> result;
	if(converter.fail())
	{
		/* Write an error to cerr (Character ERRor strream) and quit. */
		cerr << "Error: StringToInteger called on invalid input " << input << endl;
		exit(-1);
	}
	
	/* Try reading anything else, fail if we're able to. */
	char remaining;
	converter >> remaining;
	
	if(!converter.fail())
	{
		/* Write an error to cerr (Character ERRor strream) and quit. */
		cerr << "Error: StringToInteger called on invalid input " << input << endl;
		exit(-1);
	}
	
	return result;
}

/* A modified version of GetReal that calls the C function 'exit' to halt
 * execution if input is invalid.
 */
int StringToReal(string input)
{
	stringstream converter(input);
	double result;
	
	/* Try reading an integer, fail if the operation fails. */
	converter >> result;
	if(converter.fail())
	{
		/* Write an error to cerr (Character ERRor strream) and quit. */
		cerr << "Error: StringToReal called on invalid input " << input << endl;
		exit(-1);
	}
	
	/* Try reading anything else, fail if we're able to. */
	char remaining;
	converter >> remaining;
	
	if(!converter.fail())
	{
		/* Write an error to cerr (Character ERRor strream) and quit. */
		cerr << "Error: StringToReal called on invalid input " << input << endl;
		exit(-1);
	}
	
	return result;
}