// Digits To Text Representation
// Created By Nic Raboy

/*
 * This code will take in a positive integer and convert it to its textual alpha representation.
 * For example if you enter 1,234 the textual representation will be one thousand two
 * hundred thirty-four
 */

#include <iostream>
#include <string>

using namespace std;

/*
 * This function will handle the wierd case of the teens like sixteen and so forth.
 * The variable to be passed is the digit that follows the one in the teen.
 */
string calcTeen(char numstr)
{
	string wordstr = "";
	switch(numstr)
	{
		case '0': wordstr += "ten "; break;
		case '1': wordstr += "eleven "; break;
		case '2': wordstr += "twelve "; break;
		case '3': wordstr += "thirteen "; break;
		case '4': wordstr += "fourteen "; break;
		case '5': wordstr += "fifteen "; break;
		case '6': wordstr += "sixteen "; break;
		case '7': wordstr += "seventeen "; break;
		case '8': wordstr += "eighteen "; break;
		case '9': wordstr += "nineteen "; break;
		default: wordstr = "FAIL"; break;
	}
	return wordstr;
}

/*
 * This function will handle all numbers that are in the hundreds.  It will take a three digit number and figure out the
 * name of each digit.
 */
string calcThree(string numstr)
{
	string wordstr = "";
	switch(numstr[0])
	{
		case '0': wordstr += ""; break;
		case '1': wordstr += "one hundred "; break;
		case '2': wordstr += "two hundred "; break;
		case '3': wordstr += "three hundred "; break;
		case '4': wordstr += "four hundred "; break;
		case '5': wordstr += "five hundred "; break;
		case '6': wordstr += "six hundred "; break;
		case '7': wordstr += "seven hundred "; break;
		case '8': wordstr += "eight hundred "; break;
		case '9': wordstr += "nine hundred "; break;
		default: wordstr = "FAIL"; break;
	}
	switch(numstr[1])
	{
		case '0': wordstr += ""; break;
		case '1': wordstr += calcTeen(numstr[2]); return wordstr;	// The number is going to be a teen.  Figure out which one
		case '2': wordstr += "twenty-"; break;
		case '3': wordstr += "thirty-"; break;
		case '4': wordstr += "forty-"; break;
		case '5': wordstr += "fifty-"; break;
		case '6': wordstr += "sixy-"; break;
		case '7': wordstr += "seventy-"; break;
		case '8': wordstr += "eighty-"; break;
		case '9': wordstr += "ninety-"; break;
		default: wordstr += "FAIL"; break;
	}
	switch(numstr[2])
	{
		case '0': wordstr += ""; break;
		case '1': wordstr += "one "; break;
		case '2': wordstr += "two "; break;
		case '3': wordstr += "three "; break;
		case '4': wordstr += "four "; break;
		case '5': wordstr += "five "; break;
		case '6': wordstr += "six "; break;
		case '7': wordstr += "seven "; break;
		case '8': wordstr += "eight "; break;
		case '9': wordstr += "nine "; break;
		default: wordstr += "FAIL "; break;
	}
	return wordstr;
}

/*
 * This function will take in a two digit number and figure out the name of each of the two digits
 */
string calcTwo(string numstr)
{
	string wordstr = "";
	switch(numstr[0])
	{
		case '0': wordstr += ""; break;
		case '1': wordstr += calcTeen(numstr[1]); return wordstr;	// The number is going to be a teen.  Figure out which one
		case '2': wordstr += "twenty-"; break;
		case '3': wordstr += "thirty-"; break;
		case '4': wordstr += "forty-"; break;
		case '5': wordstr += "fifty-"; break;
		case '6': wordstr += "sixy-"; break;
		case '7': wordstr += "seventy-"; break;
		case '8': wordstr += "eighty-"; break;
		case '9': wordstr += "ninety-"; break;
		default: wordstr += "FAIL"; break;
	}
	switch(numstr[1])
	{
		case '0': wordstr += ""; break;
		case '1': wordstr += "one "; break;
		case '2': wordstr += "two "; break;
		case '3': wordstr += "three "; break;
		case '4': wordstr += "four "; break;
		case '5': wordstr += "five "; break;
		case '6': wordstr += "six "; break;
		case '7': wordstr += "seven "; break;
		case '8': wordstr += "eight "; break;
		case '9': wordstr += "nine "; break;
		default: wordstr += "FAIL"; break;
	}
	return wordstr;
}

/*
 * This function will calculate one digit numbers.  So if you have 1,234 it will calculate the digit on the far left or if you only
 * have one digit period
 */
string calcOne(string numstr)
{
	string wordstr = "";
	switch(numstr[0])
	{
		case '0': wordstr += "zero "; break;
		case '1': wordstr += "one "; break;
		case '2': wordstr += "two "; break;
		case '3': wordstr += "three "; break;
		case '4': wordstr += "four "; break;
		case '5': wordstr += "five "; break;
		case '6': wordstr += "six "; break;
		case '7': wordstr += "seven "; break;
		case '8': wordstr += "eight "; break;
		case '9': wordstr += "nine "; break;
		default: wordstr += "FAIL"; break;
	}
	return wordstr;
}

/*
 * Figure out the size of the number
 */
string checkCount(int len)
{
	string wordstr = "";
	switch(len)
	{
		case 4: wordstr = "thousand "; break;
		case 5: wordstr = "thousand "; break;
		case 6: wordstr = "thousand "; break;
		case 7: wordstr = "million "; break;
		case 8: wordstr = "million "; break;
		case 9: wordstr = "million "; break;
		case 10: wordstr = "billion "; break;
		case 11: wordstr = "billion "; break;
		case 12: wordstr = "billion "; break;
		case 13: wordstr = "trillion "; break;
		case 14: wordstr = "trillion "; break;
		case 15: wordstr = "trillion "; break;
		case 16: wordstr = "quadrillion "; break;
		case 17: wordstr = "quadrillion "; break;
		case 18: wordstr = "quadrillion "; break;
		case 19: wordstr = "quintillion "; break;
		case 20: wordstr = "quintillion "; break;
		case 21: wordstr = "quintillion "; break;
		case 22: wordstr = "sextillion "; break;
		case 23: wordstr = "sextillion "; break;
		case 24: wordstr = "sextillion "; break;
		case 25: wordstr = "septillion "; break;
		case 26: wordstr = "septillion "; break;
		case 27: wordstr = "septillion "; break;
		case 28: wordstr = "octillion "; break;
		case 29: wordstr = "octillion "; break;
		case 30: wordstr = "octillion "; break;
		default: wordstr = ""; break;
	}
	return wordstr;
}

/*
 * This is where the magic happens.  We will take our integer and convert it into a string.  Then we will use the modulus to determine
 * how many digits the number has.  We need to know if we will be calculating hundreds or so forth.  When the count is determined
 * we will execute the proper function passing in the proper digits.  We will then calculate the current count and append it to the digits
 * we just calculated.  Finally we will delete the digits from the front of the string and continue the loop until no digits are left
 */
string num2str(int num)
{
	string numstr;
	string tempstr = "";
	string wordstr = "";
	int i = 0;
	char buffer[100];
	sprintf(buffer, "%d", num);
	numstr.assign(buffer);
	while(i < numstr.length())
	{
		// The number is evenly divisible by three.  For example 123,456.
		if(numstr.length() % 3 == 0)
		{
			tempstr = numstr[i];
			tempstr += numstr[i+1];
			tempstr += numstr[i+2];
			wordstr += calcThree(tempstr);
			if(tempstr != "000") { wordstr += checkCount(numstr.length()); }
			numstr.erase(0, 3);	// Erase three characters from the beginning of the string
		}
		// The number has two digits total or has two digits before the comma.  For example 12,364
		if(numstr.length() % 3 == 2)
		{
			tempstr = numstr[i];
			tempstr += numstr[i+1];
			wordstr += calcTwo(tempstr);
			if(tempstr != "00") { wordstr += checkCount(numstr.length()); }
			numstr.erase(0, 2);	// Erase two characters from the beginning of the string
		}
		// The number has one digit total or has one digit before the comma.  For example 1,456
		if(numstr.length() % 3 == 1)
		{
			tempstr = numstr[i];
			wordstr += calcOne(tempstr);
			wordstr += checkCount(numstr.length());
			numstr.erase(0, 1);	// Erase one character from the beginning of the string
		}
	}
	return wordstr;
}

int main()
{
	int nums = 0;
	while(nums != -1)
	{
		cout << "Enter A Number (-1 To Stop)> ";
		cin >> nums;
		if (nums == -1) { break; }
		cout << num2str(nums) << endl;
	}
	return 0;
}