<!--
/***************************************************************************
Copyright © 2003-2007 John L. Whiteman. All rights reserved. 

Name:         Number2English.js
Version:      12/27/2006 - 01/27/2007
Author(s):    John L. Whiteman
Dependencies: N/A
Description:  Translates numbers into English words

Private:
	isWhiteSpace()
	num()
	trim()

Public:
	format()
	n1()
	n2()
	n3()
	n4()
	n5()
	n6()
	n7()
	n8()
	n9()
	n10()
	n11()
	n12()
	n13()
	n14()
	n15()
	translate()
	translatec()
***************************************************************************/
var Number2English = function() {

	/***********************************************************************
	 PRIVATE API
	***********************************************************************/

	var numbers1 = new Array();
	var numbers2 = new Array();
	var numbersc = new Array();
	var numberscw = new Array();

	numbers1['1'] = 'one';
	numbers1['2'] = 'two';
	numbers1['3'] = 'three';
	numbers1['4'] = 'four';
	numbers1['5'] = 'five';
	numbers1['6'] = 'six';
	numbers1['7'] = 'seven';
	numbers1['8'] = 'eight';
	numbers1['9'] = 'nine';
	numbers1['10'] = 'ten';
	numbers1['11'] = 'eleven';
	numbers1['12'] = 'twelve';
	numbers1['13'] = 'thirteen';
	numbers1['14'] = 'fourteen';
	numbers1['15'] = 'fifteen';
	numbers1['16'] = 'sixteen';
	numbers1['17'] = 'seventeen';
	numbers1['18'] = 'eighteen';
	numbers1['19'] = 'nineteen';
	numbers2['2'] = 'twenty';
	numbers2['3'] = 'thirty';
	numbers2['4'] = 'forty';
	numbers2['5'] = 'fifty';
	numbers2['6'] = 'sixty';
	numbers2['7'] = 'seventy';
	numbers2['8'] = 'eighty';
	numbers2['9'] = 'ninety';

	numbersc['0'] = 'zeroth';
	numbersc['1'] = 'first';
	numbersc['2'] = 'second';
	numbersc['3'] = 'third';
	numbersc['4'] = 'fourth';
	numbersc['5'] = 'fifth';
	numbersc['6'] = 'sixth';
	numbersc['7'] = 'seventh';
	numbersc['8'] = 'eighth';
	numbersc['9'] = 'nineth';
	numbersc['10'] = 'tenth';
	numbersc['11'] = 'eleventh';
	numbersc['12'] = 'twelfth';
	numbersc['13'] = 'thirteenth';
	numbersc['14'] = 'fourteenth';
	numbersc['15'] = 'fifteenth';
	numbersc['16'] = 'sixteenth';
	numbersc['17'] = 'seventeenth';
	numbersc['18'] = 'eighteenth';
	numbersc['19'] = 'nineteenth';

	numberscw['hundred'] = 'hundredth';
	numberscw['thousand'] = 'thousandth';
	numberscw['million'] = 'millionth';
	numberscw['billion'] = 'billionth';
	numberscw['trillion'] = 'trillionth';

	/***********************************************************************
	 Returns true if white space or null
	***********************************************************************/
	function isWhiteSpace(token) {

		if ((token != null) && (token != '')) {

			return(false);
		}

		return(true);
	}
	/***********************************************************************
	 Extracts numbers based upon substring coordinates
	***********************************************************************/
	function num(token, 
		         start, 
		         stop) {

		return(trim(token.substring(start, (start + stop))));
	}
	/***********************************************************************
	 Trims leading and trailing whitespace
	***********************************************************************/
	function trim(token) {

		token = token.replace(/^\s*/, "");

		token = token.replace(/\s*$/, "");

		return(token);

	}  return {
	
	/***********************************************************************
	 PUBLIC API
	***********************************************************************/
	
	/***********************************************************************
	 Formats a number with commas
	***********************************************************************/
	format : function(token) {

		if (!token.match(/^[0-9]+$/)) {

			return('');
		}

		token = trim(token);

		if (token.length < 4) return(token);

		token =
			this.format(num(token, 0, token.length - 3)) + 
			"," + num(token, token.length - 3, token.length);

		return(trim(token));
	},
	/***********************************************************************
	 Translates 0-9 to English words
	***********************************************************************/
	n1 : function(token) {

		if (numbers1[token]) 
			return(numbers1[token]);

		return('');
	},
	/***********************************************************************
	 Translates 0-99 to English words
	***********************************************************************/
	n2 : function(token) {

		var translation = '';

		if (token.length == 2) {

			if (parseInt(token) > 19) {

				if (num(token, 1, 1) != '0') {

					translation = 
						numbers2[num(token, 0, 1)] + " " +
						this.translate(num(token, 1, 1), false);

				} else {

					translation = 
						numbers2[num(token, 0, 1)];
				}

			} else {

				translation = numbers1[token];
			}

		} else {

			translation = 
				this.translate(token, false);
		}

		return(trim(translation));
	},
	/***********************************************************************
	 Translates 0-999 to English words
	***********************************************************************/
	n3 : function(token) {

		var translation = '';

		if (token.length == 3) {

			translation =
				this.translate(num(token, 0, 1), false) + 
				' hundred ' + 
				this.translate(num(token, 1, 2), false);

		} else {

			translation = 
				this.translate(token, false);
		}

		return(trim(translation));
	},
	/***********************************************************************
	 Translates 0-9,999 to English words
	***********************************************************************/
	n4 : function(token) {

		var translation = '';

		if (token.length == 4) {

			translation =
				this.translate(num(token, 0, 1), false) +
				' thousand ' + 
				this.translate(num(token, 1, 3), false);

		} else {

			translation = 
				this.translate(token, false);
		}

		return(trim(translation));
	},
	/***********************************************************************
	 Translates 0-99,999 to English words
	***********************************************************************/
	n5 : function(token) {

		var translation = '';

		if (token.length == 5) {

			translation =
				this.translate(num(token, 0, 2), false) +
				' thousand ' + 
				this.translate(num(token, 2, 3), false);

		} else {

			translation = 
				this.translate(token, false);
		}

		return(trim(translation));
	},
	/***********************************************************************
	 Translates 0-999,999 to English words
	***********************************************************************/
	n6 : function(token) {

		var translation = '';

		if (token.length == 6) {

			translation =
				this.translate(num(token, 0, 3), false) +
				' thousand ' + 
				this.translate(num(token, 3, 3), false);

		} else {

			translation = 
				this.translate(token, false);
		}

		return(trim(translation));
	},
	/***********************************************************************
	 Translates 0-9,999,999 to English words
	***********************************************************************/
	n7 : function(token) {

		var translation = '';

		if (token.length == 7) {

			translation =
				this.translate(num(token, 0, 1), false) +
				' million ' + 
				this.translate(num(token, 1, 6), false);

		} else {

			translation = 
				this.translate(token, false);
		}

		return(trim(translation));
	},
	/***********************************************************************
	 Translates 0-99,999,999 to English words
	***********************************************************************/
	n8 : function(token) {

		var translation = '';

		if (token.length == 8) {

			translation =
				this.translate(num(token, 0, 2), false) +
				' million ' + 
				this.translate(num(token, 2, 6), false);

		} else {

			translation = 
				this.translate(token, false);
		}

		return(trim(translation));
	},
	/***********************************************************************
	 Translates 0-999,999,999 to English words
	***********************************************************************/
	n9 : function(token) {

		var translation = '';

		if (token.length == 9) {

			translation =
				this.translate(num(token, 0, 3), false) +
				' million ' + 
				this.translate(num(token, 3, 6), false);

		} else {

			translation = 
				this.translate(token, false);
		}

		return(trim(translation));
	},
	/***********************************************************************
	 Translates 0-9,999,999,999 to English words
	***********************************************************************/
	n10 : function(token) {

		var translation = '';

		if (token.length == 10) {

			translation =
				this.translate(num(token, 0, 1), false) +
				' billion ' + 
				this.translate(num(token, 1, 9), false);

		} else {

			translation = 
				this.translate(token, false);
		}

		return(trim(translation));
	},
	/***********************************************************************
	 Translates 0-99,999,999,999 to English words
	***********************************************************************/
	n11 : function(token) {

		var translation = '';

		if (token.length == 11) {

			translation =
				this.translate(num(token, 0, 2), false) +
				' billion ' + 
				this.translate(num(token, 2, 9), false);

		} else {

			translation = 
				this.translate(token, false);
		}

		return(trim(translation));
	},
	/***********************************************************************
	 Translates 0-999,999,999,999 to English words
	***********************************************************************/
	n12 : function(token) {

		var translation = '';

		if (token.length == 12) {

			translation =
				this.translate(num(token, 0, 3), false) +
				' billion ' + 
				this.translate(num(token, 3, 9), false);

		} else {

			translation = 
				this.translate(token, false);
		}

		return(trim(translation));
	},
	/***********************************************************************
	 Translates 0-9,999,999,999,999 to English words
	***********************************************************************/
	n13 : function(token) {

		var translation = '';

		if (token.length == 13) {

			translation =
				this.translate(num(token, 0, 1), false) +
				' trillion ' + 
				this.translate(num(token, 1, 12), false);

		} else {

			translation = 
				this.translate(token, false);
		}

		return(trim(translation));
	},
	/***********************************************************************
	 Translates 0-99,999,999,999,999 to English words
	***********************************************************************/
	n14 : function(token) {

		var translation = '';

		if (token.length == 14) {

			translation =
				this.translate(num(token, 0, 2), false) +
				' trillion ' + 
				this.translate(num(token, 2, 12), false);

		} else {

			translation = 
				this.translate(token, false);
		}

		return(trim(translation));
	},
	/***********************************************************************
	 Translates 0-999,999,999,999,999 to English words
	***********************************************************************/
	n15 : function(token) {

		var translation = '';

		if (token.length == 15) {

			translation =
				this.translate(num(token, 0, 3), false) +
				' trillion ' + 
				this.translate(num(token, 3, 12), false);

		} else {

			translation = 
				this.translate(token, false);
		}

		return(trim(translation));
	},
	/***********************************************************************
	 Translates 0-999,999,999,999,999 to English words with error checking
	 and proper conversion before sending to the n# functions
	***********************************************************************/
	translate : function(token, 
		                 checkZeroFlag) {

		var translation = '';
		var tokenSize;

		token = trim(token.toString());

		if (!token.match(/^[0-9]+$/)) {

			return(translation);
		}

		if (token.length > 1) {

			token = token.replace(/^0+/, '');
		}

		if (isWhiteSpace(token)) {

			return(translation);
		}

		switch(token.length) {

			case 1:

				if (token != '0') {

					translation = this.n1(token);

				} else {

					if (checkZeroFlag) {

						translation = 'zero';
					}
				}

				break;

			case 2:

				translation = this.n2(token);

				break;

			case 3:

				translation = this.n3(token);

				break;

			case 4:

				translation = this.n4(token);

				break;

			case 5:

				translation = this.n5(token);
	
				break;

			case 6:

				translation = this.n6(token);

				break;

			case 7:

				translation = this.n7(token);

				break;

			case 8:

				translation = this.n8(token);

				break;

			case 9:

				translation = this.n9(token);

				break;

			case 10:

				translation = this.n10(token);

				break;

			case 11:

				translation = this.n11(token);

				break;

			case 12:

				translation = this.n12(token);

				break;

			case 13:

				translation = this.n13(token);

				break;

			case 14:

				translation = this.n14(token);

				break;

			case 15:

				translation = this.n15(token);

				break;

			default:

				translation = '';
		}

		return(trim(translation));
	},
	/***********************************************************************
	***********************************************************************/
	translatec : function(token) {

		var translation = this.translate(token);

		if (isWhiteSpace(translation)) {

			return(translation);
		}

		if (numbersc[token]) 
			return(numbersc[token]);

		var numLast = token.charAt(token.length - 1);

		var numSecondLast = token.charAt(token.length - 2);

		var numBoth = numSecondLast.toString() + numLast.toString();

		translation = translation.split(" ");

		if ((numLast != '0') && (numSecondLast != '0')) {

			var numWordSecondLast = translation[translation.length - 2];

			if (numBoth > 19) {

				translation = translation.slice(0, translation.length - 2);
			
			} else {

				translation = translation.slice(0, translation.length - 1);
			}

			if (numbersc[numBoth]) {

				translation[translation.length] = numbersc[numBoth];
			
			} else {

				translation.push(numWordSecondLast);

				translation.push(numbersc[numLast]);
			}

		} else if ((numLast == '0') && (numSecondLast == '0')) {

			var numWordLast = translation[translation.length - 1];

			if (numberscw[numWordLast]) {

				translation[translation.length - 1] = numberscw[numWordLast];
			}

		} else if (numSecondLast == '0' ) {

			translation = translation.slice(0, translation.length - 1);

			translation.push(numbersc[numLast]);

		} else {

			if (numbersc[numBoth]) {

				translation[translation.length - 1] = numbersc[numBoth];

			} else {

				var numWordLast = translation[translation.length - 1];

				numWordLast = numWordLast.replace(/y+/, 'ieth');

				translation[translation.length - 1] = numWordLast;
			}
		} 

		return(translation.join(" "));
	}
	/***********************************************************************
	***********************************************************************/
	};
}();

// -->