/**
 * Determines whether or not a device deemed by us has limited support for what 
 * needs to be accomplished dynamically. eg. calls to updateNutrients from 
 * events onkeyup and onchange, requires full support by the device OS's
 * javascript implementation, which currently for 3 out of 5 support devices,
 * is not the case.
 *
 * Reasons for device blacklisting:
 * --------------------------------
 * Blackberry: Version 4.3 and certain versions of 4.6 of the Blackberry OS 
 * don't support the javascript onkeyup event.
 *
 * Windows Mobile: Versions 5 to 6.1 don't support the javascript onkeyup event. 
 * Version 6.5 not properply tested at this stage, although both the javascript
 * onkeyup and onchange events work, the nutrient data for a food doesn't
 * update when the events are triggered, however innerHTML is supported by this
 * particular version of the OS.
 *
 * Palm: Version 5.2.1 doesn't support the javascript onkeyup event. 
 */
function deviceWithLimitedSupport() {
	// Blacklisted devices.
	var deviceBlackberry = 'blackberry';
	var devicePalm = 'palm';
	var deviceWindowsMobile = 'windows ce';
		
	// Initialise our user agent string and set to lower case.
	var uagent = navigator.userAgent.toLowerCase();
	
	// Detect platform.
	if (uagent.search(deviceBlackberry) > -1
	 || uagent.search(devicePalm) > -1
	 || uagent.search(deviceWindowsMobile) > -1)
	{
		return true;
	} else {
		return false;
	}
}

/*
 * A helper function that rounds to a certain number of decimal places
 */
function myRound(val, dps) {
	return Math.round(val * Math.pow(10, dps)) / Math.pow(10, dps);
}

function updateNutrients() {
	// Since a device with limited support will make use of form submissions to
	// update nutrient data, we need to ensure that updateNutrients doesn't
	// fully execute when called. This will prevent confusion whereby an event
	// such as onchange is supported by a limited support device, but onkeyup is
	// not. Put simply, data should not update dynamically in any circumstance on
	// a limited support device, it should only update upon form submission.
	if (deviceWithLimitedSupport()) {
		return false;
	}
	
	qty = parseFloat(document.getElementById('amount').value);
	units = document.getElementById('units').value;
	data = {};
	data.point = new Array();
	// if the amount is blank, don't bother doing anything
	if(qty && qty >= 0 && !isNaN(qty)) {
		xml = '<anychart><charts><chart plot_type="Pie"><chart_settings><chart_background enabled="false"><border enabled="true" type="solid" thickness="2" color="#d7d7d7"/><fill enabled="true" type="solid" color="white"/><corners type="square"/></chart_background><title enabled="false"><text>Calorie Breakdown</text></title></chart_settings><data_plot_settings><pie_series><tooltip_settings enabled="true"> <format>{%YPercentOfSeries}{numDecimals:0}% of calories from {%Name}</format></tooltip_settings></pie_series></data_plot_settings><data><series name="Calorie Breakdown">';
		if(type != 'S') {
			scale = (qty * units) / base;
		}
		else {
			scale = qty;
		}
		// update nutrient
		for(i = 0; i < nutrient_arr.length; i++) {
			n = nutrient_arr[i];
			nutrient = document.getElementById(n[0]);
			// Allow the alcohol nutrient to be used for the calorie break down
			// pie chart.
			if(nutrient || n[0] == 'alcohol') {
				amount = myRound(n[1] * scale, n[2]);
				// Since there is no line item to update for alcohol in the 
				// nutrition facts table, it will be excluded.
				if (n[0] != 'alcohol') {
					// if it is exactly zero, or rounded to larger than 0, just
					// display the number
					if(n[1] == 0 || amount != 0) {
						nutrient.innerHTML = amount;
					}
					// if it is rounded to 0, show that it is less than 0.1
					else {
						nutrient.innerHTML = "< 0.1";
					}
				}
				if(n[3] != 0) {
					if(n[5] != 0) {
						name = n[5];
					}
					else {
						name = n[4];
					}
					xml += "<point exploded='false' name='" + name + "' y='" + (n[1] * n[3]) + "' color='" + n[4] + "'/>";
				}
				if (n[0] == 'calories' && document.getElementById('burn-' + n[0])) {
					document.getElementById('burn-' + n[0]).innerHTML = amount;
				}
			}
		}
		// update daily percentage
		for(i = 0; i < nutrient_pc_arr.length; i++) {
			n = nutrient_pc_arr[i];
			nutrient_pc = document.getElementById(n[0]);
			if(nutrient_pc) {
				pc_amount = Math.round((n[1] * scale / n[2]) * 100);
				// if it is exactly zero, or rounded to larger than 0, just
				// display the number
				if(n[1] == 0 || pc_amount != 0) {
					nutrient_pc.innerHTML = pc_amount;
				}
				// if it is rounded to 0, show that it is less than 0.1
				else {
					nutrient_pc.innerHTML = "< 0.1";
				}
			}
		}
		// update the exercises
		for(i = 0; i < exercise_arr.length; i++) {
			e = exercise_arr[i];
			exercise = document.getElementById(e[0]);
			if(exercise) {
				exercise.innerHTML = Math.round((scale * e[2]) / e[1] * 60);
			}
		}
		xml += '</series></data></chart></charts><margin all="0" /></anychart>';

		// The chart object doesn't exist in the mobile food view and calls to
		// object functions shouldn't occur if there is no need or intention.
		if (typeof(chart) == 'object') {
			chart.setData(xml.toString());
		}
	}
}
