/***************************************************************************************************
 * This collection of functions provide a function to update a group of price labels based on an
 * array of quantities and static attributes plus the control values of attributes in the form.
 **************************************************************************************************/

/***************************************************************************************************
 * Global variables used to manage the price update.
 **************************************************************************************************/
var priceListReq;
var priceListDom;
var finishedUpdatingPrices = true;
var reloadPrices = false;
var price_spinner_image = new Image();
var price_spacer_image = new Image();
price_spinner_image.src = '/images/spinner-clear.gif';
price_spacer_image.src = '/images/spacer.gif';

/***************************************************************************************************
 * This function creates an XML PriceListRequest string from the controls in the form.
 **************************************************************************************************/
function getPriceListRequestXML(table_specs,form,callback)
{
	var xml = '';

// Start the request
	xml += '<'+"?xml version=\"1.0\" xml:lang=\"UTF-8\"?>\n";
	xml += "<maverick>\n";

// Get the base form specs
	var base_job_attribute = getAttributesFromForm(form);

// Iterate over the table_specs
	for (var name in table_specs)
	{
	// Start the request
		xml += "<PriceListRequest name=\""+name+"\"";
		if (form.currency && form.currency.value)
			xml += ' currency="'+form.currency.value+'"';
		if (callback)
			xml += ' callback="'+callback+'"';
		xml += ">\n";

	// Add the quantity
		xml += "<Quantity>"+table_specs[name]['qty']+"</Quantity>\n";

	// Get the specs
		var job_attribute = base_job_attribute;
		var override = table_specs[name]['job_attribute'];
		for (var i in override)
		{
			if (override[i])
				job_attribute[i] = override[i];
		}

	// Add the product
		xml += "<Product>"+job_attribute['product'][0]+"</Product>\n";

	// Add the specs
		xml += getAttributeList(job_attribute);

	// End request
		xml += "</PriceListRequest>\n";
	}
	xml += "</maverick>\n";

	return xml;
}

/***************************************************************************************************
 * This function initializes the spinner image (if any) for the price update.
 **************************************************************************************************/
function startPriceListUpdate()
{
	finishedUpdatingPrices = false;
	var price_spinner = document.getElementById('price_chart_spinner');
	if (price_spinner)
		price_spinner.src = price_spinner_image.src;
}

/***************************************************************************************************
 * This function cleans up the spinner image (if any) after the price update.
 **************************************************************************************************/
function endPriceListUpdate()
{
	finishedUpdatingPrices = true;
	var price_spinner = document.getElementById('price_chart_spinner');
	if (price_spinner)
		price_spinner.src = price_spacer_image.src;
}

/***************************************************************************************************
 * This function provides an interface to updatePrice without a callback.
 **************************************************************************************************/
function updatePriceList(table_specs,form)
{
	updatePriceListWithCallback(table_specs,form,null);
}

/***************************************************************************************************
 * This function uses AJAX to get prices for the table using the form with a callback.
 **************************************************************************************************/
function updatePriceListWithCallback(table_specs,form,callback)
{
	if (!finishedUpdatingPrices)
	{
		reloadPrices = true;
		return;
	}
	startPriceListUpdate();
	var xml_request = getPriceListRequestXML(table_specs,form,callback);
//alert(xml_request);
	var url = get_base_url()+'/xml/priceList.php';
	if (window.XMLHttpRequest)
	{
	// Non-IE browsers
		priceListReq = new XMLHttpRequest();
		priceListReq.onreadystatechange = processStateChangePriceList;
		try {
			priceListReq.open("POST", url, true);
		} catch (e) {
			alert(e);
		}
		priceListReq.setRequestHeader('Content-Type', 'text/xml');
		priceListReq.send(xml_request);
	}
	else if (window.ActiveXObject)
	{
	// IE
		priceListReq = new ActiveXObject("Microsoft.XMLHTTP");
		if (priceListReq)
		{
			priceListReq.onreadystatechange = processStateChangePriceList;
			priceListReq.open("POST", url, true);
			priceListReq.setRequestHeader('Content-Type', 'text/xml');
			priceListReq.send(xml_request);
		}
	}
}

/***************************************************************************************************
 * This function indicates whether the most recent price update has finished.
 **************************************************************************************************/
function isFinishedUpdatingPrices()
{
	return 	(finishedUpdatingPrices && !reloadPrices);
}

/***************************************************************************************************
 * This function receives the UpdatePrice response and updates the price labels. If an error was 
 * returned and there is an error label, set it. If a callback was requested, call it after the 
 * update.
 **************************************************************************************************/
function processStateChangePriceList()
{
	if (!priceListReq)
		return;
	if (priceListReq.readyState == 4)
	{
	// Complete
		if (priceListReq.status == 200)
		{
		// OK response
			if (typeof priceListReq.responseXML != 'undefined')
				priceListDom = priceListReq.responseXML;
			else
				parseXMLIntoDOM(priceListReq.responseText);
//alert(priceListReq.responseText);
			if (!priceListDom)
			{
				endPriceListUpdate();
				return;
			}

		// Iterate over the price array, plugging in the answers into labels
			var maverick = priceListDom.getElementsByTagName('maverick')[0];
			if (!maverick)
			{
//				alert(priceListReq.responseText);
				blankPriceList(table_specs,new Array());
				endPriceListUpdate();
				return;
			}
			var price_response = maverick.getElementsByTagName('PriceListResponse')[0];
			if (!price_response)
			{
//				alert(priceListReq.responseText);
				blankPriceList(table_specs,new Array());
				endPriceListUpdate();
				return;
			}
//alert(priceListReq.responseText);
			var callback = price_response.getAttribute('callback');
			if (callback != null && callback != '' && callback.value) callback = callback.value;
			var prices = price_response.getElementsByTagName('Price');
			var updated = new Array();
			var len = prices.length;
			for (var i=0;i<len;i++)
			{
				var price = prices[i];
				var element_id = price.getAttribute('name');
				if (!element_id)
					continue;
				var label = getElement(element_id);
				if (!label)
					continue;
				var currency = price.getAttribute('currency');
				if (currency == '')
					currency = 'USD';
				var qty = table_specs[element_id]['qty'];
				var per = table_specs[element_id]['per'];
				var per_price = Math.round(price.firstChild.data.replace(',','')*per*100/qty)/100;
				label.innerHTML = label.innerText = formatCurrency(per_price,currency);
				updated[element_id] = 1;
				var label = getElement(element_id+'_error');
				if (!label)
					continue;
				label.innerHTML = label.innerText = '';
			}
			var errors = price_response.getElementsByTagName('Error');
			var len = errors.length;
			for (var i=0;i<len;i++)
			{
				var error = errors[i];
				var element_id = error.getAttribute('name');
				if (!element_id)
					continue;
				var label = getElement(element_id+'_error');
				if (!label)
					continue;
				label.innerHTML = label.innerText = (error != null && error.firstChild != null) ? error.firstChild.data : '';
			}
/*
		// Plug in any errors
			var errors = price_response.getElementsByTagName('Error');
			var len = errors.length;
			for (var i=0;i<len;i++)
			{
				var error = errors[i];
				var element_id = error.getAttribute('name');
				if (!element_id)
					continue;
				var label = getElement(element_id);
				if (!label)
					continue;
				label.innerHTML = label.innerText = error.firstChild.data;
				updated[element_id] = 1;
			}
*/
			blankPriceList(table_specs,updated);
			endPriceListUpdate();

		// Check to see if it should queue another request
			var qty = (document.getElementById('quantity')) ? document.getElementById('quantity') : document.getElementById('qty');
			if (reloadPrices && qty)
			{
				reloadPrices = false;
				if (callback)
					updatePriceListWithCallback(table_specs,qty.form,callback);
				else
					updatePriceList(table_specs,qty.form);
				return;
			}

		// If there's a callback specified, look for it and run it
			if (callback)
			{
			// Look for the function (defined outside of this file, of course)
				var callback_function = self[callback];
				if (callback_function)
					callback_function();
			}
		}
	}
}

/***************************************************************************************************
 * This function blanks out the price list.
 **************************************************************************************************/
function blankPriceList(table_specs,updated)
{
// Blank out the rest
	if (typeof table_specs != 'undefined')
	{
		for (var element_id in table_specs)
		{
			if (updated[element_id] == 1)
				continue;
			var label = getElement(element_id);
			if (!label)
				continue;
			label.innerHTML = label.innerText = '';
		}
	}
}
