<!--
// 'validated' is old code...
/*
 * We could differentiate between the French & English styles of numbers...
 *
 * ... We've used 2 ways of indicating the language:
 * 1. A hidden form INPUT object (IE <input type=hidden name=language value="F">)
 *    Then the JS code uses (passes around) form.language.value
 * 2. Set a JS variable with the language setting (var language = "F";)
 *
 * Combining the 2 ways lets us not need different JS for each language
 * and lets the FORM call the shots; just need to be sure that the JS code
 * doesn't try to use the INPUT object's value before the object is created.
 * 
 * Try: 
 * <form ...>
 * <input type=hidden name=language value="F">
 * ...
 * </form> <!-- The form's "language" object should be available now. -->
 * <script type="text/javascript" language="JavaScript">var language = form.language.value;</script>
 */
var language = new String();
var defautLanguage = new String();
 
function validated(string) {

	/*
    * If there is a '.' in the number, regardless of the language setting,
    * use it as the fraction separator.
    */
   var save_str = new String(string);
   var re = /\./;
   //alert("re.test(string) = " + re.test(string) );
	if ( ! re.test(string) && language == "F") {
    
		//alert("language = " + language); 
   	// We allow zero/one comma (as a decimal separator)
      // Replace the last comma with a decimal point.
      string = string.replace(/,([^,]*)$/, ".$1");
      //alert("String = " + string);
      // other commas and any spaces (thousands separators) will be ignored.
   }
   
/*
     for (var i=0, output='', valid="1234567890."; i<string.length; i++)
        if (valid.indexOf(string.charAt(i)) != -1)
           output += string.charAt(i)
 */
           
	// The above can be replaced with this...
   //alert("string = " + string);
   string = string.replace(/[^.0-9]/g, "");
   //alert("string = " + string);
   if ( isNaN(parseFloat(string)) ) {
   	alert("validated: You entered '"+save_str+"' which is not a number. Please enter a number."+"\n\n"+
            "Le montant que vous avez indiqu\351 ("+save_str+") n'est pas un chiffre. Veuillez entrer un chiffre.");
      string = "100";
   }
   var valNumb = new Datum(parseFloat(string));
//alert("valNumb as a 'Datum' = " + valNumb);
   return formatNumber(valNumb);
}

/*
var cpi  = new Array();
cpi["y1972"]= new Array();
cpi["y1972"]["aug"] = 12.5;
alert(cpi["y1972"]["aug"]);
alert(cpi[0][0]); // Same thing?
alert(cpi.length);
*/

/*
	A function to add commas to numbers for display
*/
function formatNumber(numString) {

	var myNumbStr = new String(numString);
	var np = myNumbStr.split(/\./); // The decimal point might not be there
   
   
   if        ( language == "E" ) {
   	var decimalSeperator   = ".";
      var thousandsSeparator = ",";
   } else if ( language == "F" ) {
   	var decimalSeperator   = ",";
      var thousandsSeparator = " ";
   } // There could be potentially more language settings.
	
	// Add the commas...
	var regex = /(-?\d+)(\d{3})/;
	while (regex.test(np[0])) {
		np[0] = np[0].replace(regex,"$1"+thousandsSeparator+"$2");
	}
	
	if ( np.length == 1 ) {
		return np[0];
	} else { // There is a decimal point
		return np[0]+decimalSeperator+np[1];
	}

}

/*
	In the code above, I was thinking the ["aug"] notation was populating an element
	of the array -- WRONG!
	
	That notation creates a property of the Array object instance
	IE.
	var cpi  = new Array()		creates an Array object
	cpi["y1972"]= new Array()	creates a property of the cpi Array object, "y1972",
										that references a new Array object. We could have written:
										cpi.y1972 = new Array()
	Since we never do anything but use properties (ie. cpi.y1972.aug), we need not use Array
	objects at all -- or we should drop the pretense of using 'meaningful' names ('y1972', 'aug')
	and use numeric coordinates, cpi[1972][8] for example.

	Create a month 'map' object, to turn the string representation of a month
	into a numeric rep. (IE. "aug" = 8)
	var mthMap = { 
	var cpi  = new Array();
	cpi[1972] = [ "", 7.2, 7.2, 7.2, 7.1, 7.0, 7.1, 7.0, 7.2, 7.2, 7.3, 7.3, 7.3 ];
	
	If want to keep up with the meaningful names, we should go to objects...
	- a 'cpi' class...
		var cpi				= new Object;	// No particular class here is there (yet)?
		cpi["1972"]			= new Object;	// the "1972" property of 'cpi' references another Object.
		alert(cpi.toSource());				// gives... {1972:{}}
		cpi["1972"].jan	= new Object;	// Each data point property("jan") is another object (so we can
													// override the toString() method with something that uses the
													// Number.toExponential() method to give the correct #
													// of signifigant digits.
*/
		// might look something like this...
		
		// prototype for the "cpiData" class.
		// cpi["1972"] = new cpiData( [7.2, 7.2, 7.2, 7.1, 7.0, 7.1, 7.0, 7.2, 7.2, 7.3, 7.3, 7.3] );
		function cpiData(datalist) {
			// datalist = an Array of numeric values
			var mthPropMap =	[	"jan", "feb", "mar", "apr",
										"may", "jun", "jul", "aug",
										"sep", "oct", "nov", "dec"
									];
			
			for ( var m = 0 ; m < datalist.length; m++ ) {
				this[mthPropMap[m]] = new Datum( datalist[m] );
			}
		
		}
		
		// prototype for the "Datum" class.
		// cpi["1972"].jan	= new Datum(66.3)
		function Datum(datum) {
			this.value=datum;
			// CPI data has 4 signifigant digits.
			this.sigDig=4; // 3 decimal places in the exponential notation.
		}
		//The function we want to override the default toString() method with...
		function datumToString() {
			// Old code...
			var ret = new Number(this.value);
//alert("datumToString Number object = " + ret);
			//>return ret.toExponential(this.sigDig-1) + "";	// Convert to a string.
			
			/*	In production, clients will not enjoy seeing something like 1.234e5
				We want to show them 123,400, So...
				1.234e5	...	123,400
				1.234e-3	...	0.00 (max of 2 decimal places? To conform to the old code?)
				
				A rule... (SD = # of significant digits = 4)
				- if x>=10**(sd-1 = 1000) use... 0 decimal places...
					var y = new Number(parseFloat(x.toExponential(SD-1)));
					return y.toFixed(0); // (need to add commas. ie 1,234)
				- else if x>=10**(sd-2 = 100) use ... 1 decimal place...
					var y = new Number(parseFloat(x.toExponential(SD-1)));
					return y.toFixed(1); // (ie 123.4)	- Brent may veto 1 decimal place because 2 looks better
																	- For money values, that makes cents!
				- else if x>=10**(sd-3 = 10) use ... 2 decimal places...
					var y = new Number(parseFloat(x.toExponential(SD-1)));
					return y.toFixed(2); // (ie 12.34)
				- else if x>=10**(sd-4 = 1) use ... 3 decimal places...
					var y = new Number(parseFloat(x.toExponential(SD-1)));
					return y.toFixed(3); // (ie 1.234)	- doesn't make sense for money values. use 2 decimal places.
				- else if x>=10**(sd-5 = .1) use ... 4 decimal places...
					var y = new Number(parseFloat(x.toExponential(SD-1)));
					return y.toFixed(4); // (ie .1234)	- doesn't make sense for money values. use 2 decimal places.
				- else if x>=10**(sd-6 = .01) use ... 5 decimal places...
					var y = new Number(parseFloat(x.toExponential(SD-1)));
					return y.toFixed(5); // (ie .01234 = still 4 signigicant digits)	- doesn't make sense for money values. use 2 decimal places.
				- etc. (infinitely)
				
				Because of the last item above, we should try splitting the string, 1.023e-06 (=0.000001023)
				into "1.023" and "-06".
			*/
         /* 15 June 2006 - KEK
          * Here's the original code, that preserves the # of signigicant digits.
				var edp = this.sigDig - 1;
				var xString = ret.toExponential(edp);
				var x = new Number(parseFloat(xString));
				var numbParts = xString.split(/e[+]?/); // get 2 string elements.
				//var r = parseFloat(numbParts[0]);
				var e =   parseInt(numbParts[1]);
				var dp = ( e-edp < 0 ) ? Math.abs(e-edp) : 0;
				return x.toFixed(dp);
          */
          // For now, just return the number rounded to 2 decimal places
          return ret.toFixed(2);
		}
		// Tell Javascript we're overriding toString()
		Datum.prototype.toString = datumToString;
		
		
		// use the whole thing...
var cpi		= new Object;
		
/*=======================================================================================*/
/* Some testing code (23 Feb 2006):

		// Show data with the exponential notation
		document.write(
			"<h4>Exponential Notation</h4><p>" +
			"CPI 1972 " + currentMonth + " = " + cpi["1972"][currentMonth] + "<p>"
		);
		// Show in decimal notation.
		document.write(
			"<h4>Decimal Notation</h4><p>" +
			"CPI 1972 " + currentMonth + "  = " + cpi["1972"][currentMonth].value + "<p>"
		);
*/
/* showData is now deprecated...

	- The year range validation will take place in validation functions
	 (creating year1 & year2)
	- cpi2=resultTo will be calculated like this:
			var cpi2 = cpi[year2][currentMonth];	// IE. cpi["1945"].apr
	- cpi1=resultFrom will be calculated like this:
			var cpi1 = cpi[year1][currentMonth];	// IE. cpi["1936"].apr
			
function showData(form) {
    i = ""
    yearTo = parseInt(form.enterto.value)
        if (yearTo <= 1913) {alert('Year must be 1914 or later'); i = "0"}
        else if (yearTo >= 2006) {alert('Please enter a date in the range 1914-2005.'); i = "0"}
        else if (form.enterto.value == "1914")
    {i = "1"}
        else if (form.enterto.value == "1915")
...
	    else if (form.enterto.value == "2005")
    {i = "92"};

resultTo = year[i].dec
// NEW on November 4 1999
// Routine to show month and CPI numbers
	displayMonth = " "
	if (resultTo == year[i].dec) 
{displayMonth = "Dec"}
// End new section

yearFrom = parseInt(form.enterfrom.value)
if (yearFrom <= 1913) {alert('Year must be 1914 or later'); i = "0"}
else if (yearFrom >= 2006) {alert('Please enter a date in the range 1914-2005.'); i = "0"}
        else if (form.enterfrom.value == "1914")
    {i = "1"}
        else if (form.enterfrom.value == "1915")
...
	    else if (form.enterfrom.value == "2005")
    {i = "92"};
	
resultFrom = year[i].dec
}
... End of deprecated showData
*/

// Validate the start & end years.
var year1 = "";	// Init year1
function year1_validate (y1Str) {

/*
 * y1Str is now an object ref instead of a string.
 */
 
	// check that the supplied string converts to an integer
	// and firstYear <= y1Str <= lastYear
	
	var test = parseInt(y1Str.value);	// local
	if ( isNaN(test) || !( firstYear <= test && test <= lastYear) ) {
		alert("You entered '"+y1Str.value+
		      "'\nPlease enter a year in the range "+
				firstYear+"-"+lastYear + "\n\n" + 
            "L'ann\351e que vous avez indiqu\351e est : "+y1Str.value+
            "\nVeuillez indiquer une ann\351e comprise entre "+firstYear+" et "+lastYear);
		
		return false;
	} else {
 		// Change the passed object's value
      y1Str.value = test.toString();
		year1 = new String(test.toString());
		year1.asAnumber = test; // A property containing the numeric value
		return true;
	}

}
var year2 = new String();	// Init year2
function year2_validate (y2Str) {

/*
 * y2Str is now an object ref instead of a string.
 */
 
	// check that the supplied string converts to an integer
	// and firstYear <= y2Str <= lastYear
	
	var test = parseInt(y2Str.value);	// local
	if ( isNaN(test) || !( firstYear <= test && test <= lastYear) ) {
		alert("You entered '"+y2Str.value+
		      "'\nPlease enter a year in the range "+
				firstYear+"-"+lastYear + "\n\n" + 
            "L'ann\351e que vous avez indiqu\351e est : "+y2Str.value+
            "\nVeuillez indiquer une ann\351e comprise entre "+firstYear+" et "+lastYear);
		
		return false;
	} else {
//alert("test = " + test );
//alert("test as a string = " + test.toString );
//		year2 = y2Str; //alert("year2 as a string = " + year2);	// year2 = y2Str turns year2 from a String object into a String value!
/*
 * Q: What if y2Str is entered as "2002.01.01"? (A Maureen test value)
 * 
 * A: In our existing code, we have, "year2 = new String(y2Str);"
 * so we'd get year2 = "2002.01.01" & year2.asAnumber = 2000
 *
 * We don't get an alert from here when the "calculate" button is pushed
 * but the calculation is not done (?!)... trace this through.
 *
 * Aha... year2 is used as a property of our CPI object, like this:
 * var cpi2 = cpi[year2][currentMonth].value;
 * If year2 = "2002.01.01" this would look like:
 * var cpi2 = cpi["2002.01.01"][currentMonth].value;
 * and there is no "2002.01.01" property of 'cpi'.
 *
 * If 'test' is a number then year2 (and the 'enterto' form field?)
 * shold be set to the string value of 'test'.
 */
 		// Change the passed object's value
      y2Str.value = test.toString();
		//year2 = new String(y2Str); //alert("year2 as a string = " + year2);
		year2 = new String(test.toString()); //alert("year2 as a string = " + year2);
		year2.asAnumber = test; // A property containing the numeric value
//		alert("year2 as a number = " + year2.asAnumber);
		return true;
	}

}
var dollarsThen = "";

function setDollarAmount(dtStr) {
	
	// Strip out extraneous commas and spaces
	// Assume (because of field validation) that the supplied string converts to an float.
 	if ( language == "F" ) {
   	// We allow zero/one comma (as a decimal separator)
      // Replace the last comma with a decimal point.
      dtStr = dtStr.replace(/,([^,]*)$/, ".$1");
      //alert("dtStr = " + dtStr);
      // other commas and any spaces (thousands separators) will be ignored below
   }
	
	var test = parseFloat(dtStr.replace(/[, ]/g,""));	// local
//alert("dollarAmount_validate: test = "+test);
/*
	if ( isNaN(test) ) {
		alert("dollarAmount_validate: You entered '"+dtStr+"' which is not a number. Please enter a number."+"\n\n"+
            "Le montant que vous avez indiqu\351 ("+dtStr+") n'est pas un chiffre. Veuillez entrer un chiffre.");
		return false;
	} else {
*/
		dollarsThen = test;
		dollarsThen.asAstring = dtStr; // A property containing the original string
//alert("dollarAmount_validate:  dollarsThen = "+dollarsThen);
//		return true;
//	}

}

function calcInflation(form) {

	// Set the dollarsThen variable from the form object...
	setDollarAmount(document.inflation.dollarAmount.value);
   
	var cpi1 = cpi[year1][currentMonth].value;	// Start CPI = yearValueFrom = resultFrom
	var cpi2 = cpi[year2][currentMonth].value;	// End   CPI = yearValueTo = resultTo

	var dollarsNow = new Datum(dollarsThen * (cpi2/cpi1));
	var perCentage = new Datum((dollarsNow.value - dollarsThen) / dollarsThen * 100);
	
	form.result2.value =  formatNumber(dollarsNow);	// Automagically converted to a string?
	form.result3.value =  formatNumber(perCentage);	// Automagically converted to a string?
	var yearSpan = year2.asAnumber - year1.asAnumber;
	form.result4.value =  parseInt(yearSpan);

	// set variables for APC calculation

//	logB = 	resultFrom		= cpi1
//	logA = 	resultTo			= cpi2
//	C = yearTo					= year2.asAnumber |(C-D) = yearTo-yearFrom = yearSpan.value
//	D = yearFrom				= year1.asAnumber |
//
//calcAPC = 100 * Math.exp(((Math.log(logA) - (Math.log(logB))) / (Math.abs(C - D)))) - 100
var calcAPC =
	new Datum(
	         100 * Math.exp( (Math.log(cpi2) - Math.log(cpi1)) / Math.abs(yearSpan) ) - 100
	);

	
	form.result5.value = formatNumber(calcAPC);
	/**
     * The "currentMonth" needs to be language-specific
     *
     * 22 Sep 2006
     * The toString() method for the CPI numbers returns 2 decimal palces...
     * but we want to display CPI values with a single decimal place.
     *
     * So, we turn the number into a String and throw away the last character
     * (since CPI numbers _are_ to one decimal place in the first place,
     * we are always just throwing away a '0' chatacter).
     */
	var result6_2Decimals = new String(cpi[year2][currentMonth]);
	form.result6.value = "\(" + mthByLang(currentMonth) + " " + year2 + "\) " + " " + formatNumber(result6_2Decimals.slice(0,-1));
//	form.result6.value = "\(" + mthByLang(currentMonth) + " " + year2 + "\) " + " " + formatNumber(cpi[year2][currentMonth].slice(0,-1));
	
	var result7_2Decimals = new String(cpi[year1][currentMonth]);
	form.result7.value = "\(" + mthByLang(currentMonth) + " " + year1 + "\) " + " " + formatNumber(result7_2Decimals.slice(0,-1));
//	form.result7.value = "\(" + mthByLang(currentMonth) + " " + year1 + "\) " + " " + formatNumber(cpi[year1][currentMonth].slice(0,-1));
//alert("dollarsThen = " + dollarsThen);
	var da = new Datum(dollarsThen);
	form.dollarAmount.value = formatNumber(da);

}

/*
 * Use a simple function to return the value of the selected language radio button
 * Usage: languageSelection(document.inflation.language)
 */

function languageSelectionByRadio(radioButtonArrayRef) {

	/*
    * this function is passed a reference to a radio button array.
    */
    
	var rbar = radioButtonArrayRef;	// Copy the array ref into a shorter name!
   for ( var i = 0; i < rbar.length; i++ ) {
//alert("rbar[i] = "+rbar[i].value);
   	if ( rbar[i].checked ) {
      	break;	// Use i to index the checked button.
      }
   }
   
   language = rbar[i].value;
   return true;
}
function languageSelectionByText(textRef) {

	/*
    * this function is passed a reference to a form's hidden input object.
    */
       
   language = textRef.value;
   return true;
}

function defaultLanguageByRadio(radioButtonArrayRef) {

/*
 * This function sets the default language setting to whatever the checked value of
 * the passed radio buttons is at the time of the call; if English is currently
 * checked then we set the default to "E" (if French then "F")
 * -- Call this carefully... perhaps when the page is loaded (and we'll save the
 * initial state of the radio buttons).
 */
 
	var rbar = radioButtonArrayRef;	// Copy the array ref into a shorter name!
   for ( var i = 0; i < rbar.length; i++ ) {
//alert("rbar[i] = "+rbar[i].value);
   	if ( rbar[i].checked ) {
      	break;	// Use i to index the checked button.
      }
   }
   
   defaultLanguage = rbar[i].value;
   return true;
}
function defaultLanguageByText(textRef) {

/*
 * This function sets the default language setting to whatever the value of
 * the passed form input object is at the time of the call; if English is the value
 * then we set the default to "E" (if French then "F")
 * -- Call this carefully... perhaps when the page is loaded (and we'll save the
 * initial state of the radio buttons).
 */
 
   defaultLanguage = textRef.value;
   return true;
}

function setLanguageToDefault() {

	language=defaultLanguage;
   
   return true;
}

/*
 * We need to get the month in a language-specific style...
 *
 * Here are some maps for English & French...
 *
 * The fame-generated JS code uses lower case English 3-letter forms for the months (IE "aug");
 * We can make them nicer.
 */
var CPImonth = new Object;
//cpiDisplayMonths = new mthHTMLCalendar();
//alert("cpiDisplayMonths['apr'] = "+cpiDisplayMonths["apr"]);
// prototype for the "cpiDisplayMonths" class.
function mthHTMLCalendar() {

	var mthLang = new Object;
   
	var mthFame =	   [	"jan", "feb", "mar", "apr",
								"may", "jun", "jul", "aug",
								"sep", "oct", "nov", "dec"
							];
	if       ( language == "F" ) {
   	mthLang = 		[	"jan",	"f\351v",		"mar",
      						"avr",	"mai",			"jun",
                        "jul",	"ao\373",		"sep",
                        "oct",	"nov",			"d\351c"
                     ];
	} else if ( language == "E" ) {
   	mthLang = 		[	"Jan",	"Feb",			"Mar",
      						"Apr",	"May",			"Jun",
                        "Jul",	"Aug",			"Sep",
                        "Oct",	"Nov",			"Dec"
                     ];
	}
//alert("mthLang"+mthLang);
	for ( var m = 0 ; m < mthFame.length; m++ ) {
		this[mthFame[m]] = mthLang[m];
//alert("mthHTMLCalendar:mthFame[m] = " + mthFame[m] + " / " + mthLang[m]);
	}

}

function mthByLang(mth) {

	/*
    * We plug 'language' and 'mth' into the CPImonth object as properties
    * and return the string value.
    */
//alert("mthByLang:mth = "+mth);
	return cpiDisplayMonths[mth];

}
//-->
