//This file contains functions required to retrieve interest rate data from the productdata
//json and insert it into productdata page elements.

//These variables store details of the loaded json document(s) and are used for client side caching
var arrJSONCached = new Array();
var arrCountryCached = new Array();
var arrSectionCached = new Array();
var arrSubSectionCached = new Array();

// Flag to check for successful response from json data feed requests
var blnCallbackSuccess = false;

//This function retrieves all of the interest rate data required for the page
function retrieveRates() {

	try {
		var rateElements;
		var i;
		var intCountArray;
		var xpath;
		var suffix;
		var countryCode;
		var sectionCode;
		var subSectionCode;
		var position;
		var insertionElement;
		var populateScript;
		
		//Retrieving all span elements in the page
		rateElements = document.getElementsByTagName("span");
		
		//Looping through span elements
		for (i=0;i<rateElements.length;i++) {
			//productdata span element has been found
			if (rateElements[i].className=="productdata") {
				//Retrieving title value
				xpath = rateElements[i].getAttribute("title");
				
				//title attribute contains an xpath
				if (xpath != null && xpath != "") {
					//suffix exists in xpath
					suffix = (xpath.indexOf(";suffix") >= 0);
					if (suffix) {
						xpath = xpath.replace(/\;suffix$/, "");
					} else {
						xpath = xpath.replace(/\;$/, "");
					}
					
					//Extracting country code from xpath
					position = xpath.indexOf("country[@code=");
					if (position >= 0) {
						countryCode = xpath.substr(position + 14, xpath.length);
						countryCode = countryCode.substr(0, countryCode.indexOf("]"));
						countryCode = countryCode.replace(/'/g, "");
						countryCode = countryCode.replace(/"/g, "");
						
						//Extracting section code from xpath
						position = xpath.indexOf("section[@code=");
						if (position >= 0) {
							sectionCode = xpath.substr(position + 14, xpath.length);
							sectionCode = sectionCode.substr(0, sectionCode.indexOf("]"));
							sectionCode = sectionCode.replace(/'/g, "");
							sectionCode = sectionCode.replace(/"/g, "");
						} else {
							sectionCode = null;
						}
						//Extracting sub-section code from xpath
						position = xpath.indexOf("subsection[@code=");
						if (position >= 0) {
							subSectionCode = xpath.substr(position + 17, xpath.length);
							subSectionCode = subSectionCode.substr(0, subSectionCode.indexOf("]"));
							subSectionCode = subSectionCode.replace(/'/g, "");
							subSectionCode = subSectionCode.replace(/"/g, "");
						} else {
							subSectionCode = null;
						}
					
						//Looping through cached array
						blnFound = false;
						for (intCountArray=0;intCountArray<arrJSONCached.length;intCountArray++) {
							//json for this country, section and sub-section has already been cached
							blnFound = (arrCountryCached[intCountArray] == countryCode && (sectionCode == null || arrSectionCached[intCountArray] == sectionCode) && (subSectionCode == null || arrSubSectionCached[intCountArray] == subSectionCode));
							if (blnFound) {
								break;
							}
						}
					
						//json for this country, section and sub-section has not already been cached
						if (blnFound != true) {
							//Increasing length of cache arrays
							arrJSONCached.length+=1;
							arrCountryCached.length+=1;
							arrSectionCached.length+=1;
							arrSubSectionCached.length+=1;
							
							//Caching json country
							arrCountryCached[arrCountryCached.length-1] = countryCode;
							//Caching json section
							arrSectionCached[arrSectionCached.length-1] = sectionCode;
							//Caching json sub-section
							arrSubSectionCached[arrSubSectionCached.length-1] = subSectionCode;
						}
					} else {
						countryCode = null;
						// xpath must contain country code
						singleRateErrorHandler(rateElements[i]);
					}
					
				} else {
					singleRateErrorHandler(rateElements[i]);
				}
			}
		}
		
		//At least one json is required
		if (arrCountryCached.length > 0 ) {
			//Retrieving the first json doc
			retrieveDoc(arrCountryCached[0], arrSectionCached[0], arrSubSectionCached[0]);
		}
	}
	catch(err) {
		globalRateErrorHandler();
	}
}

//This function populates all interest rate elements in the page
function populateRates() {

	try {
		var rateElements;
		var i;
		var xpath;
		var suffix;
		var countryCode;
		var sectionCode;
		var subSectionCode;
		var position;
		var value;
		var suffixvalue;
		var suffixpath;
		var tempstring;
		
		//Retrieving all span elements in the page
		rateElements = document.getElementsByTagName("span");
		
		//Looping through span elements
		for (i=0;i<rateElements.length;i++) {
			//productdata span element has been found
			if (rateElements[i].className=="productdata") {
				try {
					//Retrieving title value
					xpath = rateElements[i].getAttribute("title");
					
					//title attribute contains an xpath
					if (xpath != null && xpath != "") {
						//suffix exists in xpath
						suffix = (xpath.indexOf(";suffix") >= 0);
						if (suffix) {
							xpath = xpath.replace(/\;suffix$/, "");
						} else {
							xpath = xpath.replace(/\;$/, "");
						}
						
						//Extracting country code from xpath
						position = xpath.indexOf("country[@code=");
						if (position >= 0) {
							countryCode = xpath.substr(position + 14, xpath.length);
							countryCode = countryCode.substr(0, countryCode.indexOf("]"));
							countryCode = countryCode.replace(/'/g, "");
							countryCode = countryCode.replace(/"/g, "");
							
							//Extracting section code from xpath
							position = xpath.indexOf("section[@code=");
							if (position >= 0) {
								sectionCode = xpath.substr(position + 14, xpath.length);
								sectionCode = sectionCode.substr(0, sectionCode.indexOf("]"));
								sectionCode = sectionCode.replace(/'/g, "");
								sectionCode = sectionCode.replace(/"/g, "");
							} else {
								sectionCode = null;
							}
							//Extracting sub-section code from xpath
							position = xpath.indexOf("subsection[@code=");
							if (position >= 0) {
								subSectionCode = xpath.substr(position + 17, xpath.length);
								subSectionCode = subSectionCode.substr(0, subSectionCode.indexOf("]"));
								subSectionCode = subSectionCode.replace(/'/g, "");
								subSectionCode = subSectionCode.replace(/"/g, "");
							} else {
								subSectionCode = null;
							}
						
							//Retrieving rate value
							value = retrieveSingleRate(xpath, countryCode, sectionCode, subSectionCode);
						
							//value is not undefined or null (empty values are accepted as they are possible in some cases)
							if (value != undefined && value != null) {
								//suffix attribute is set to true and value is not empty
								if (suffix && value != "") {
									//Determining suffix node name
									tempstring = xpath.substring(xpath.lastIndexOf("/") + 1, xpath.length);
									//Building suffix path
									suffixpath = "";
									if (tempstring == "ratevalue") {
										suffixpath = xpath.replace("/ratevalue", "/ratesuffix");
									}
									
									//Suffix path exists
									if (suffixpath != "") {
										//Retrieving suffix value
										suffixvalue = retrieveSingleRate(suffixpath, countryCode, sectionCode, subSectionCode);
										//Suffix is not undefined or null
										if (suffixvalue != null && suffixvalue != undefined) {
											//Appending suffix to value
											value += suffixvalue;
										}
									}
								}
								//Populating productdata span element with value (replacing loading image)
								rateElements[i].innerHTML = value;
							}
							//value is undefined or null
							else {
								singleRateErrorHandler(rateElements[i]);
							}
							//Clearing xpath from title
							rateElements[i].setAttribute("title", "");
						} else {
							countryCode = null;
							// xpath must contain country code
							singleRateErrorHandler(rateElements[i]);
						}
					}
				}
				catch(err_inner) {
					singleRateErrorHandler(rateElements[i]);
				}
			}
		}
	}
	catch(err) {
		globalRateErrorHandler();
	}
}

//This function inserts script for the retrieval of appropriate json documents into the page.
//It can be called directly prior to the retrieval a single rate or via the
//populateRates function when populating all productdata elements in the page.
function retrieveDoc(country, section, subsection) {

	try {
		var strJSONPath = '';
		var insertionElement;
		var retrieveScript;
		
		//We are currently in a cms environment
		if(location.href.toLowerCase().indexOf('/cp/wcm/') > 0) {
			//Use the CMS domain determination method
			strJSONPath = getEnvironmentProperty("IntRateFeedDomain");
		//We are currently in a QA environment
		} else if (location.hostname.toLowerCase().indexOf('qa.anz') >= 0) {
			strJSONPath = location.protocol+'//qa.anz.com';
		//We are currently in a dev environment
		} else if (location.hostname.toLowerCase().indexOf('dev.anz') > 0 || location.hostname.toLowerCase().indexOf('ecom.anz') > 0) {
			strJSONPath = location.protocol+'//anzcom.dev.anz';
		//We are currently in a test environment
		} else if (location.hostname.toLowerCase().indexOf('test.anz') > 0) {
			strJSONPath = location.protocol+'//anz.test.anz';
		//We are in a production or unknown domain
		} else {
			//Default to production domain
			strJSONPath = location.protocol+'//www.anz.com';
		}
		strJSONPath += '/productdata/productdata.asp?output=json&callback=callbackFunction';
		
		//Adding country, section and sub-section parameters to json URL querystring
		if (country == null || country == undefined) {
			country = '';
		}
		strJSONPath += '&country=' + country;
		if (section == null || section == undefined) {
			section = '';
		}
		strJSONPath += '&section=' + section;
		if (subsection == null || subsection == undefined) {
			subsection = '';
		}
		strJSONPath += '&subsection=' + subsection;
		
		//Retrieving insertion element
		insertionElement = document.getElementById("retrieveRates");
		
		//Building script
		retrieveScript = document.createElement("script");
		retrieveScript.type = "text/javascript";
		retrieveScript.src = strJSONPath;
		
		//Trigger the global error handler if script response doesn't call the callback function
		//e.g. in the event of activation of the database outage page
		retrieveScript.onload = retrieveScript.onreadystatechange = function(){
			if(!this.readyState || this.readyState == "loaded" || this.readyState == "complete")
				if(!blnCallbackSuccess) globalRateErrorHandler();
		}
		
		//Placing script in page
		insertionElement.appendChild(retrieveScript);
	}
	catch(err) {
		globalRateErrorHandler();
	}
}

//This function retrieves and returns the specified rate.
//It can be called directly to retrieve a single rate (preceeded by a call to retrieveDoc)
//or via the populateRates function when populating all productdata elements in the page.
function retrieveSingleRate(xpath, country, section, subsection) {

	try {
		var i;
		var j;
		var k;
		var objJSON;
		var objNode;
		var value;
		var arrSplit;
		var arrConditionNode;
		var arrConditionValue;
		var strNode;
		var blnMet;
		
		//Initialise json object
		objJSON = null;
		
		//Looping through cached elements
		for (i=0;i<arrCountryCached.length;i++) {
			if (arrCountryCached[i] == country && (section == null || arrSectionCached[i] == section) && (subsection == null || arrSubSectionCached[i] == subsection)) {
				objJSON = arrJSONCached[i];
				break;
			}
		}
		
		//Cached json could not be found
		if (objJSON == null || objJSON == undefined || objJSON == '') {
			return null;
		}
		
		//Looping through xpath query
		arrSplit = xpath.split("/");
		for (i=0;i<arrSplit.length;i++) {
			//Element is not empty
			if (arrSplit[i] != "") {
				//Initialising condition arrays
				arrConditionNode = null;
				arrConditionValue = null;
			
				//Contains conditions
				if (arrSplit[i].indexOf("[") >= 0) {
					//Extracting node name
					strNode = arrSplit[i].substr(0, arrSplit[i].indexOf("[")).replace(/@/g, "");
					
					//Extracting if conditions
					arrConditionNode = arrSplit[i].substr(arrSplit[i].indexOf("["), arrSplit[i].length);
					arrConditionNode = arrConditionNode.split(" and ");
					arrConditionValue = arrConditionNode.slice(0);
					
					//Stripping characters from if conditions
					for (j=0;j<arrConditionNode.length;j++) {
						arrConditionNode[j] = arrConditionNode[j].replace(/\[/g, "");
						arrConditionNode[j] = arrConditionNode[j].replace(/\]/g, "");
						arrConditionNode[j] = arrConditionNode[j].replace(/@/g, "");
						arrConditionNode[j] = arrConditionNode[j].substr(0, arrConditionNode[j].indexOf("="));
						
						arrConditionValue[j] = arrConditionValue[j].replace(/\[/g, "");
						arrConditionValue[j] = arrConditionValue[j].replace(/\]/g, "");
						arrConditionValue[j] = arrConditionValue[j].replace(/@/g, "");
						arrConditionValue[j] = arrConditionValue[j].substr(arrConditionValue[j].indexOf("="), arrConditionValue[j].length);
						arrConditionValue[j] = arrConditionValue[j].replace(/=/g, "");
						arrConditionValue[j] = arrConditionValue[j].replace(/'/g, "");
					}
				}
				//Does not contain conditions
				else {
					//Extracting node name
					strNode = arrSplit[i].replace(/@/g, "");
				}
			
				//Node has not yet been set
				if (objNode == undefined) {
					objNode = objJSON;
				}
				
				//No conditions exist for this node
				if (arrConditionNode == null) {
					//This is the last element in the selection array
					if (i == arrSplit.length - 1) {
						//Set the value to this node
						value = objNode[strNode];
					}
					else {
						//Select the first node of this type
						objNode = objNode[strNode][0];
					}
				}
				//Conditions exist for this node
				else {
					//Initialising conditions met value
					blnMet = false;
					
					//Looping through array of nodes
					for (j=0;j<objNode[strNode].length;j++) {
						//Looping through conditions
						for (k=0;k<arrConditionNode.length;k++) {
							//Condition is met and either this is the first condition or the previous conditions were also met
							blnMet = ((k == 0 || blnMet == true) && (objNode[strNode][j][arrConditionNode[k]] == arrConditionValue[k]));
						}
						
						//All conditions were met
						if (blnMet == true) {
							//Select this node
							objNode = objNode[strNode][j];
							break;
						}
					}
					
					//None of the nodes met the conditions
					if (blnMet != true) {
						return null;
					}
				}
			}
		}
		
		return value;
	}
	catch(err) {
		return null;
	}
}

//This function handles and caches json responses.
function callbackFunction(objJSON) {

	try {
		var i;
		
		blnCallbackSuccess = true;
		
		//Looping through cache array
		for (i=0;i<arrJSONCached.length;i++) {
			//Cached item does not exist at this location
			if (arrJSONCached[i] == undefined || arrJSONCached[i] == null) {
				if(objJSON == null) 
					// There's no json object, set empty cache value at this location which can be used for error detection 
					arrJSONCached[i] = '';
				else
					//Caching json object at this location
					arrJSONCached[i] = objJSON;
				
				//This is the last json object to be cached
				if (i == arrJSONCached.length - 1) {
					//Populate all of the rates in the page
					populateRates();
				}
				//This is not the last json object
				else {
					//Insert script for retrieval of next json object
					retrieveDoc(arrCountryCached[i + 1], arrSectionCached[i + 1], arrSubSectionCached[i + 1]);
				}
				break;
			}
		}
	}
	catch(err) {
		globalRateErrorHandler();
	}
}

// Function to handle errors with single rate data retrieval
function singleRateErrorHandler(objRateElement){
	//Hiding loading image and displaying rate link
	if(objRateElement.getElementsByTagName("img")[0]) objRateElement.getElementsByTagName("img")[0].style.display = "none";
	if(objRateElement.getElementsByTagName("a")[0]) objRateElement.getElementsByTagName("a")[0].style.display = "inline";
}

// Function to handle global errors with rate data retrieval
function globalRateErrorHandler(){
	//Hiding loading image and displaying rate links globally
	var rateElements = document.getElementsByTagName("span");
		
	//Looping through span elements
	for (var i=0;i<rateElements.length;i++) {
		//productdata span element has been found
		if (rateElements[i].className=="productdata") {
				if(rateElements[i].getElementsByTagName("img")[0]) rateElements[i].getElementsByTagName("img")[0].style.display = "none";
				if(rateElements[i].getElementsByTagName("a")[0]) rateElements[i].getElementsByTagName("a")[0].style.display = "inline";
		}
	}
}
