//----------------------------------------------------------------------------
// Client-side script for handling loading of transport rates dynamically from
// the client instead of requiring a page refresh. 
//----------------------------------------------------------------------------

var RATES_SERVICE_URL = "/getrates.asp";

function UpdateTransportRates (strProductId, strService, strSupplierCode, blnWAorNT, strDate, strPickupLocation, strDropoffLocation) {

	// If we can't create an xmlhttp object, return immediately.
    var xmlHttp = XmlHttp.create();
	if (!xmlHttp) {
		return (false);
	}	

	// Clear the options list and replace it temporarily with a "loading rates..." value
	// to indicate to the user that something is happening.
	var country = document.getElementById('country').value;
    var duration = document.getElementById('duration');
    var selectedIndex = duration.selectedIndex;
    duration.options.length = 0;
    duration.options[duration.options.length] = new Option('loading rates...', '');

	// Do an XMLHTTP call to retrieve the new rates.
	var url = RATES_SERVICE_URL + "?productid=" + strProductId +
		"&country=" + country +
		"&date=" + escape(strDate) +
		"&service=" + strService +
		"&suppliercode=" + strSupplierCode +
		"&pickup=" + strPickupLocation +
		"&dropoff=" + strDropoffLocation +
		"&blnWAorNT=" + (blnWAorNT ? 'true' : 'false');

    var text;
    if (xmlHttp) {
            xmlHttp.open('GET', url, true);

            xmlHttp.onreadystatechange = function () {
        		if (xmlHttp.readyState == 4) {
				    // Populate the rates select with the new options.
				    var duration = document.getElementById('duration');
					var options = getChildNodes(getNamedChildNode(xmlHttp.responseXML.documentElement, "options"));
					duration.options.length = 0;
					for (var i=0; i<options.length; i++) {
						option = options[i];
						duration.options[duration.options.length] = new Option(GetNodeText(option), option.getAttribute('value'));					
					}
					duration.selectedIndex = selectedIndex;

			        // Update the charges area.
			        UpdateCharges (xmlHttp.responseXML.documentElement);
		        
			        // Update the specials area.
			        UpdateSpecials (xmlHttp.responseXML.documentElement);
		        
					// Update the total to reflect the change in rates 
					UpdateTotal();
					
					return (true);
		        }
				return (false);
	        };

            // call in new thread to allow ui to update
			window.setTimeout(function () {
				xmlHttp.send(null);
	        }, 10);
    }
    else {
		return (false);
    }
    
    return (true);
}    

//----------------------------------------------------------------------------
// For all non-transport services, update rates when the start date changes by
// retrieving the rates for the season containing the new date. Once retrieved,
// we'll update all the relevant rate values.
//----------------------------------------------------------------------------

function UpdateNonTransportRates (strService, strSupplierCode, strDate) {

	// If we can't create an xmlhttp object, return immediately.
    var xmlHttp = XmlHttp.create();
	if (!xmlHttp) {
		return (false);
	}	

	// Get the currency symbol.
	var currency_symbol = document.getElementById('currency_symbol').value;

	// Notification the user that rates are going to be changing.
	NotifyRefresh(true); 

	// Do an XMLHTTP call to retrieve the new rates.
	var url = RATES_SERVICE_URL + "?date=" + escape(strDate) +
		"&service=" + strService +
		"&suppliercode=" + strSupplierCode;

    var text;
    if (xmlHttp) {
            xmlHttp.open('GET', url, true);

            xmlHttp.onreadystatechange = function () {
			    var result;
        		if (xmlHttp.readyState == 4) {
				    // Iterate through the product rates and update the
				    // relevant page elements.
					var currency;
					var id;
					var product;
					var singlerate;
					var doublerate;
					var triplerate;
					var quadrate;
					var rate;
					var rate_prefix = 'rate_';
					
					// Get the product nodes
					var products = getChildNodes(getNamedChildNode(xmlHttp.responseXML.documentElement, "products"));
					
					// For each product ...
					for (var i=0; i<products.length; i++) {
						product = products[i];
						currency = product.getAttribute("currency");
						id = product.getAttribute("id");
							
						// Get the rate values
						singlerate = product.getAttribute("singlerate");
						doublerate = product.getAttribute("doublerate");
						triplerate = product.getAttribute("triplerate");
						quadrate = product.getAttribute("quadrate");
						
						// Update the corresponding page elements.
						if (singlerate != '') {
							// For accommodation products
							try {
								el = document.getElementById(rate_prefix + id + '_singlerooms');
								el.value = singlerate;
								el = document.getElementById(rate_prefix + id + '_singlerooms_text');
								el.innerHTML = currency + currency_symbol + singlerate;
							}
							catch (e) {}
							// For non-accommodation products (GT and TR)
							try {
								el = document.getElementById(rate_prefix + id + '_quantity');
								el.value = singlerate;
								el = document.getElementById(rate_prefix + id + '_text');
								el.innerHTML = currency + currency_symbol + singlerate;
							}
							catch (e) {}
						}
						
						if (doublerate != '') {
							try {
								el = document.getElementById(rate_prefix + id + '_doublerooms');
								el.value = doublerate;
								el = document.getElementById(rate_prefix + id + '_doublerooms_text');
								el.innerHTML = currency + currency_symbol + doublerate;
							}
							catch (e) {}
						}
						
						if (triplerate != '') {
							try {
								el = document.getElementById(rate_prefix + id + '_triplerooms');
								el.value = triplerate;
								el = document.getElementById(rate_prefix + id + '_triplerooms_text');
								el.innerHTML = currency + currency_symbol + triplerate;
							}
							catch (e) {}
						}
						
						if (quadrate != '') {
							try {
								el = document.getElementById(rate_prefix + id + '_quadrooms');
								el.value = quadrate;
								el = document.getElementById(rate_prefix + id + '_quadrooms_text');
								el.innerHTML = currency + currency_symbol + quadrate;
							}
							catch (e) {}
						}
							
					} 
					result = true;

					// Update the charges area.
					UpdateCharges (xmlHttp.responseXML.documentElement);
			        
					// Update the total to reflect the change in rates 
					UpdateTotal();
		        }
		        else {
					result = false;
		        }
		        
				// Turn off the notification
				NotifyRefresh(false);
				return (result);
	        };

            // call in new thread to allow ui to update
			window.setTimeout(function () {
				xmlHttp.send(null);
	        }, 10);
    }
    else {
		return (false);
    }
	
    return (true);
}

//----------------------------------------------------------------------------
// Update the extra charges.
//----------------------------------------------------------------------------
function UpdateCharges (doc) {

	// Get the charges content
	var chargesContent = getNamedChildNode(doc, "charges");

	// Update the charges area.
	var chargesRow = document.getElementById('chargesrow');
	var chargesContentArea = document.getElementById('chargescontent');
	chargesRow.style.display = 'none'; // Turn it off while we do some calcs
	
	if (chargesContent && chargesContent.innerHTML != '') {
		// Render the charges area.
		chargesContentArea.innerHTML = GetNodeText(chargesContent);
		
		// Enable the charges row.
		chargesRow.style.display = '';
	}
	else {
		// Turn off the charges row.
		chargesContentArea.innerHTML = '';
	}
}

//----------------------------------------------------------------------------
// Update the specials
//----------------------------------------------------------------------------
function UpdateSpecials (doc) {

	// Get the specials content
	var specialsContent = getNamedChildNode(doc, "specials");

	// Update the charges area.
	var specialsRow = document.getElementById('specialsrow');
	var specialsContentArea = document.getElementById('specialscontent');
	specialsRow.style.display = 'none'; // Turn it off while we do some calcs
	
	if (specialsContent && specialsContent.innerHTML != '') {
		// Render the specials area.
		specialsContentArea.innerHTML = GetNodeText(specialsContent);
		
		// Enable the charges row.
		specialsRow.style.display = '';
	}
	else {
		// Turn off the charges row.
		specialsContentArea.innerHTML = '';
	}
}

//----------------------------------------------------------------------------
// Calculate the charges based on the duration and subtotal, display them and
// return the total charge.
//----------------------------------------------------------------------------
function CalculateCharges (intDuration, intTotal) {

	// Get the currency details
	var strCurrency = document.getElementById('currency').value;	
	var strCurrencySymbol = document.getElementById('currency_symbol').value;
	var fCurrencyConversionRate = parseFloat(document.getElementById('currencyconversionrate').value);
	
	// Find all the charges elements and total their amounts, taking into
	// account the duration and subtotal where necesary.
	var iTotalCharge = 0;
	var fCharge = 0;
	var arrVals;
	var iNum;
	var addToTotal = true;
	var arrIDs = new Array();
	var fDisplayCharge = 0;
	var displayEl;
	
	if (intTotal > 0) {
		var elInputs = document.getElementsByTagName("input");
		for (var i=0; i<elInputs.length; i++) {
			el = elInputs[i];
			if (el.id.indexOf('charge_') == 0) {
				iNum = parseInt(el.id.split('_')[1]);
				displayEl = document.getElementById('display_charge_' + iNum);
				arrVals = el.value.split(',');
				fCharge = parseFloat(arrVals[0]);
				addToTotal = (arrVals[2] == 'True');

				// Don't display anything if the amount is zero.
				if (!fCharge) continue;

				switch (arrVals[1]) {
					case 'fixed':
						fDisplayCharge = strCurrency + strCurrencySymbol + (fCurrencyConversionRate * fCharge).toDecimals(2);
						break;
					case 'perday':
						fDisplayCharge = strCurrency + strCurrencySymbol + (fCurrencyConversionRate * fCharge).toDecimals(2) + ' per day';
						fCharge = fCharge * intDuration;
						break;
					case 'percent':					
						fDisplayCharge = (fCurrencyConversionRate * fCharge).toDecimals(2) + '%';
						fCharge = (fCharge * 0.01) * intTotal;
						break;
				}

				// Update the hidden value for this charge.
				try {
					var chargeEl = document.getElementById('actual_charge_' + iNum);
					chargeEl.value = fCharge.toDecimals(2);
				}
				catch (e) {}

				// Add the charge to the total if necessary.
				if (addToTotal) {
					iTotalCharge += fCharge;					
				}

				// Update the displayed charge.
				displayEl.innerHTML = strCurrency + strCurrencySymbol + (fCurrencyConversionRate * fCharge).toDecimals(2);
			}			
		}	
	}
	
	// Record the total charge in a hidden field (for form submission) and return it.
	try {
		var totalEl = document.getElementById('totalcharge');
		totalEl.value = iTotalCharge.toDecimals(2);
	}
	catch (e) {}
	return (iTotalCharge); 
}

//----------------------------------------------------------------------------
// Return node text.
//----------------------------------------------------------------------------
function GetNodeText(node) {
	var text;
	if (node.textContent) {
		text = node.textContent;
	}
	else if (node.innerText) {
		text = node.innerText;
	}
	else if (node.firstChild && node.firstChild.nodeValue) {
		text = node.firstChild.nodeValue;
	}
	else if (node.text) {
		text = node.text;
	}
	return (text);
}

//----------------------------------------------------------------------------
// Set node text.
//----------------------------------------------------------------------------
function SetNodeText(node, text) {
	if (node.textContent) {
		node.textContent = text;
	}
	else if (node.innerText) {
		node.innerText = text;
	}
	else if (node.firstChild && node.firstChild.nodeValue) {
		node.firstChild.nodeValue = text;
	}
	else if (node.text) {
		node.text = text;
	}
}

//----------------------------------------------------------------------------
// Display a notification that new rates are loading in the background.
//----------------------------------------------------------------------------
function NotifyRefresh(blnOn) {
	var notifyEl = document.getElementById("refresh_notification");
	if (blnOn) {
		notifyEl.style.display = "";
	}
	else {
		notifyEl.style.display = "none";
	}
}

//----------------------------------------------------------------------------
// Truncate a number to a specified number of decimal places with zero padding
// to the right.
//----------------------------------------------------------------------------
Number.prototype.toDecimals = function(n) {
    n = (isNaN(n)) ? 2 : n;
    var nT = Math.pow(10, n);
    
    function pad(s) {
        s = s||'.';
        return (s.length > n) ? s : pad(s + '0');
    }
    
    return (isNaN(this)) ? this : (new String(Math.round(this * nT)/nT)).replace(/(\.\d*)?$/, pad());
}
