var rateConditionObjs = {} // hash used to store objs that get special rate treatments when necessary
var	rateLOBFormatting = { 1:2, 3:2, 4:{"Actual Rate":3, "Effective Yield":4}, 5:2 }
var months={
	"Jan" : "01",
	"Feb" : "02",
	"Mar" : "03",
	"Apr" : "04",
	"May" : "05",
	"Jun" : "06",
	"Jul" : "07",
	"Aug" : "08",
	"Sep" : "09",
	"Oct" : "10",
	"Nov" : "11",
	"Dec" : "12"
}

var rateTypeDefinitions={
	1 :		"Actual Rate",
	2 :		"APR", 
	3 :		"Cash Adv. Rate", 
	4 :		"Spread Over Base", 
	5 :		"Spread Over Prime", 
	6 :		"Purchase Rate",
	7 :		"Purchase Rate Low",
	8 :		"Purchase Rate Medium",
	9 :		"Purchase Rate High",
	10 :	"Spread over Rds. Mortgage Rate",
	11 :	"Effective Yield",
	12 :	"Current Yield",
	13 :	"Canadian Price",
	14 :	"US Price",
	15 :	"Ongoing",
	16 :	"Ongoing Reduction",
	17 :	"Promotional",
	18 :	"Promotional Reduction",
	19 :	"Rate Of Return",
	20 :	"Prime",
	21 :	"Posted",
	22 :	"Spread Over Prime Low",
	23 :	"Spread Over Prime Medium",
	24 :	"Spread Over Prime High",
	25 :	"Historical Canadian Price"
}

var customerType=[null,"individual","senior","youth","student","staff","nonPersonal","regular"];

/*
/* takes the rates and makes the original array accessible via objects
/* @param	product	the product variable returned by RDS
/* @param	params
/* 			- switch_unit_currency	define object based on currency instead of unit in the case
/* 			- multiRate	in the case that there is more than one rateType per unitType
/* NOTE:	object chains must be preceded with "x" because values often begin with numbers or are null, which is not allowed in javascript
/* 		  	RDS array order: [unit, currency, (rate)type, rate, status, date, customer]
*/
function makeRatesObj(product, params){
	if(product){ rates = product.rates }
	else{ return null; }

	// define defaults unless params override
	multiRate = false;
	unitIndex = 0;
	currencyIndex = 1;

	if(params){	// override defaults if necessary
		if(params.switch_unit_currency){
			unitIndex = params.switch_unit_currency ? 1 : unitIndex;
			currencyIndex = params.switch_unit_currency ? 0 : currencyIndex;
		}
		multiRate = params.multiRate ? true : false;
	}

	// go through all rates once and set up object chaining for direct access
	for(var i=0; i<rates.length; i++){
		yieldFlag = null;
		yieldDate = null;
		customerFlag = null;
		try{ unit = rates[i][unitIndex].toString().replace(/-_|_<|_>|_=|null_|_null|\.\d+|_.$/g, "").replace(/\s/g, "_"); }
		catch(e) { unit="null"; }

		try{ currency = rates[i][currencyIndex].match(/\d+/); }
		catch(e){ currency="null"; }

		var type = rates[i][2];
		var _rateLOBFormatting = rateLOBFormatting[product.lobId];
		var rate = _rateLOBFormatting && rates[i][3] != "-99.999999991" ?
			_rateLOBFormatting instanceof Object ?
				parseFloat(rates[i][3]).toFixed(_rateLOBFormatting[rateTypeDefinitions[type]]) :
				parseFloat(rates[i][3]).toFixed(_rateLOBFormatting)
			: rates[i][3];

		if(!product.lastUpdatedDate) product.lastUpdatedDate = rates[i][5];	// assume all rates entries have the same updated date

		customerFlag = customerType[rates[i][6] ? rates[i][6] : 0];

		// due to ambiguity of rates feed, we must determine chaining through type when necessary
		if(type == 11){ yieldFlag = "effectiveYield"; }
		else if(type == 12){ 
			yieldFlag = "currentYield"; 
			yieldDate = rates[i][5];
		}
		else if(unit=="null" && currency=="null"){ currency=rates[i][4]; }	// this will assign the value "Published" or "Historical"

		variable = "rates" + (unit == "null" ? "" : unit.match(/^\d/) ? ".x" + unit : "." + unit);

		eval("exists = " + variable + " ? true : false ");

		isDigit = currency.toString().match(/^\d/);

		// run the object chaining process
		if(!exists){ eval(variable + " = {}"); }	// create the main object for chaining
		if(multiRate){ // if the product has multiple rateTypes per unitType
			if(currency != "null"){
				eval("exists = " + variable + ".x" + currency + " ? true : false ");
				if(!exists) eval(variable + ".x" + currency + " = {}");
			}
			eval(variable + (currency == "null" ? "" : (isDigit ? ".x" : ".") + currency) + "[\"" + rateTypeDefinitions[type] + "\"]" + " = \"" + rate + "\"");
		}
		else{
			if(currency != "null"){
				eval(variable + (isDigit ? ".x" : ".") + currency + " = {}");
				eval(variable + (isDigit ? ".x" : ".") + currency + ".type" + " = " + type);
				eval(variable + (isDigit ? ".x" : ".") + currency + ".rate" + " = \"" + rate + "\"");
			}
			else{
				eval(variable + ".type" + " = " + type);
				eval(variable + ".rate" + " = \"" + rate + "\"");
			}
		}

		if(yieldFlag != null) { 
			eval(variable + (currency != "null" ? (isDigit ? ".x" : ".") + currency + "." : ".") + yieldFlag + " = " + "\"" + rate + "\""); 
			if(yieldDate != null){ 
				eval(variable + (currency != "null" ? (isDigit ? ".x" : ".") + currency + "." : ".") + yieldFlag + "LastUpdatedDate = \"" + yieldDate + "\""); 
			}
		}
		if(customerFlag != null){ eval(variable + (currency != "null" ? (isDigit ? ".x" : ".") + currency + "." : ".") + customerFlag + " = " + "\"" + rate + "\""); }
		if(currency.toString().match(/^(Historical|Published)/i)){ eval(variable + (isDigit ? ".x" : ".") + currency + ".lastUpdatedDate = \"" + rates[i][5] + "\""); }
	}
}

/* writes out the rate to the page
 * @param rate	the rate to be written, by default, eval() will be applied
 * @param asIs  do NOT eval() the rate if true (i.e. dates in this format 03/08)
 */
function writeRate(rate, params){
	try{ 
		var asIs = conditions = null;
		if(params){
			asIs = params["asIs"] ? true : false;
			conditions = params["conditions"] ? params["conditions"] : null;
		}

		rate = asIs ? rate : eval(rate);
		rate = rate == "-99.999999991" ? "-" : rate;
	}
	catch(e){ rate = "N/A"; }
	finally{
		document.write(rate);
		if(conditions){
			for(var i=0,l=conditions.length; i<l; i++){
				rateConditionObjs[conditions[i]] == undefined ? rateConditionObjs[conditions[i]] = new Array() : 0;
				conditions[i] == "hideRateOnZero" && rate <= 0 ?
					rateConditionObjs[conditions[i]].push(params["objs"]) : 0;
			}
		}
	}
}

/* ensures that javascript's subtraction on floating numbers are accurate */
function writeRateDiff(rate1, rate2){ 
	try{
		rate1 = eval(rate1);
		rate2 = eval(rate2);
		writeRate((rate1 - rate2).toFixed(10).replace(/0+$/, "")) 
	}
	catch(e){}
}

/* translates the date from this format "Thu Mar 13 00:00:00 EDT 2008" to either:
 * "03/08" 		- if fullDate is null/undefined
 * "Mar 3 2008" - if fullDate is set to true or some other non null/undefined value
 */
function translateDate(dateString, fullDate){
	try{
		dateString = eval(dateString);
		if(fullDate){
			formatDate(dateString);
		}
		else{
			dateString.match(/^[^\s]*\s([^\s]*).*(\d{2}$)/)
			writeRate(months[RegExp.$1] + "/" + RegExp.$2, {asIs:true})
		}
	}
	catch(e){ document.write("N/A"); }
}

// gets all objs related to the rates which need special treatment and applies the appropriate properties as required
function displayRateConditions(){
	for(rc in rateConditionObjs){
		for(c in rateConditionObjs[rc]){
			switch(rc){
				case "hideRateOnZero" :
					var relatedObjs = getElementsByClassName(rateConditionObjs[rc])
					for(ro in relatedObjs){ relatedObjs[ro].className += " hide"; }
					break;
			}
		}
	}
}
