$( document ).ready ( function ()
	{
		$( window ).load ( _setTop );
		$( window ).resize ( _setTop );
	}
);

// Top matter -------------------------------------------------------------------------------------------------------------------------------------------------

function _setTop () {														// Center main box in window
	windowHeight = $( window ).height ();
	windowWidth = $( window ).width ();
	boxWidth = $( "#box" ).width ();
	boxHeight = $( "#box" ).height ();
	
	offset = Math.round( windowHeight - boxHeight ) / 2;
	offset = ( offset < 0 ) ? 0 : offset ;
	$( "#box" ).css ( "top", offset + "px" );

	offset = Math.round( windowWidth - boxWidth ) / 2;
	offset = ( offset < 0 ) ? 0 : offset ;
	$( "#box" ).css ( "left", offset + "px" );
}

var divNameList = new Array ( 'units', 'brine', 'nitrite', 'nutrients', 'brix', 'heat' );
var divNameCount = divNameList.length;

function _switch ( showDivName ) {				// Make active tool visible and disable its radio button
	for ( x = 0; x < divNameCount; x++ ) {
		if ( divNameList[x] !== showDivName ) {
			$( "#" + divNameList[x] ).css ( "display", "none" );
			$( "#radio_" + divNameList[x] ).attr ( "disabled", "" );
		}
	}
	$( "#" + showDivName ).css ( "display", "block" );
	$( "#radio_" + showDivName ).attr ( "disabled", "disabled" );
	$( "span#hideHead" ).css ( "display", "block");
	hideHeadStatus = true;

	_setTop ();
}

var hideHeadStatus;

function _toggleHeadButton () {
	if ( hideHeadStatus ) {
		hideHeadStatus = false;
		$( "span#hideHead" ).css ( "display", "none" );
		$( "span#showHead" ).css ( "display", "block" );
		$( "div#top" ).css ( "display", "none" );
	} else {
		hideHeadStatus = true;
		$( "span#showHead" ).css ( "display", "none" );
		$( "span#hideHead" ).css ( "display", "block" );
		$( "div#top" ).css ( "display", "block" );
	}
	_setTop ();
}

// Perform unit conversions -----------------------------------------------------------------------------------------------------------------------------------

function _setConv( type ) {													// Change the conversion routine based on which radio button is clicked
	var leftList = document.getElementById( 'leftUnits' );
	var rightList = document.getElementById( 'rightUnits' );
	var oForm = document.getElementById( 'unitsForm' );

	if ( type == 'w' ) {													// Units of measure for conversion by weight 
		var details = [ 1, "grams (g)", "",
						1000, "kilograms (kg)", "",
						28.349523, "ounces (oz)", "selected",
						453.59237, "pounds (lb)", "" ];
		document.getElementById( 'formType' ).value = 'w';					// Set hidden value for reference later by javascript
	} else if ( type == 'v' ) {												// Units of measure for conversion by volume
		var details = [ 1000, "liters (l)", "",
						100, "deciliters (dl)", "",
						10, "centiliters (cl)", "",
						1, "milliliters (ml)", "",
						3785.412, "gallons (gal)", "",
						946.353, "quarts (qt)", "selected",
						473.1765, "pints (pt)", "",
						236.58825, "cups (c)", "",
						29.573531, "fluid ounces (fl oz)", "",
						14.7867647, "tablespoons (tb)", "",
						4.928921593, "teaspoons (t)", "" ];
		document.getElementById( 'formType' ).value = 'v';					// Set hidden value for reference later by javascript
	} else if ( type == 'l' ) {												// Units of measure for conversion by length
		var details = [ 1, "millimeters (mm)", "",
						10, "centimeters (cm)", "",
						1000, "meters (m)", "",
						25.4, "inches (in)", "selected",
						304.8, "feet (ft)", "" ];
		document.getElementById( 'formType' ).value = 'l';					// Set hidden value for reference later by javascript
	} else if ( type == 't' ) {												// Units of measure for conversion by temperature
		var details = [ -1, "centigrade (C)", "",
						1, "Fahrenheit (F)", "selected",
						0, "thermostat", "" ];
		document.getElementById( 'formType' ).value = 't';					// Set hidden value for reference later by javascript
	} else if ( type == 'x' ) {												// Units of measure for approximation of weight to volume conversion
		var detailX = [ .005, "grams (g) of granulated sugar",
						.1417476150, "ounces (oz) of granulated sugar",
						.0083333333, "grams (g) of confectioner's sugar",
						.2362460250, "ounces (oz) of confectioner's sugar",
						.0071428571, "grams (g) of all-purpose flour",
						.2024965929, "ounces (oz) of all-purpose flour",
						.008, "grams (g) of cake flour",
						.226796184, "ounces (oz) of cake flour",
						.0074074074, "grams (g) of cornstarch",
						.2099964667, "ounces (oz) of cornstarch",
						.0076923077, "grams (g) of yellow cornmeal",
						.2180732538, "ounces (oz) of yellow cornmeal",
						.0095238095, "grams (g) of cocoa powder",
						.2699954571, "ounces (oz) of cocoa powder",
						.0052083333, "grams (g) of baking powder",
						.1476537656, "ounces (oz) of baking powder",
						.00390625, "grams (g) of baking soda",
						.1107403242, "ounces (oz) of baking soda",
						.0065789474, "grams (g) of salt (fine)",
						.1865100197, "ounces (oz) of salt (fine)",
						.0044247788, "grams (g) of butter",
						.1254403673, "ounces (oz) of butter",
						.00625, "grams (g) of honey",
						.1771845188, "ounces (oz) of honey",
						.0066666667, "grams (g) of almonds (whole)",
						.18899682, "ounces (oz) of almonds (whole)",
						.0071428571, "grams (g) of hazelnuts (whole)",
						.2024965929, "ounces (oz) of hazelnuts (whole)",
						.0071428571, "grams (g) of pistachios (whole)",
						.2024965929, "ounces (oz) of pistachios (whole)",
						.0090909091, "grams (g) of walnuts (halves)",
						.2577229364, "ounces (oz) of walnuts (halves)" ];
		var detailY = [ 1, "cups (c)",
						.0625, "tablespoons (tb)",
						.020833333, "teaspoons (t)" ];

		leftList.options.length = 0;										// Clear pull-down menus
		rightList.options.length = 0;
		for ( n = 0; n < detailX.length / 2; n++ ) {						// Populate pull-down menus based on type of conversion
			x = 2 * n;
			y = x + 1;
			leftList.options.length = n + 1;								// Increase pull-down size by 1
			leftList.options[n].text = detailX[y];							// Plug in text information in pull-down menu
			leftList.options[n].value = detailX[x];							// Plug in conversion information in pull-down menu
		}
		leftList.selectedIndex = 0;											// Indicate that the first item in this pull-down is selected
		document.getElementById( 'leftIn' ).value = '';						// Clear text input field on form

		rightList.options.length = 0;										// Clear pull-down menus
		for ( n = 0; n < detailY.length / 2; n++ ) {						// Populate pull-down menus based on type of conversion
			x = 2 * n;
			y = x + 1;
			rightList.options.length = n + 1;								// Increase pull-down size by 1
			rightList.options[n].text = detailY[y];							// Plug in text information in pull-down menu
			rightList.options[n].value = detailY[x];						// Plug in conversion information in pull-down menu
		}
		rightList.selectedIndex = 0;										// Indicate that the first item in this pull-down is selected

		document.getElementById( 'rightIn' ).value = '';					// Clear text input field on form
		document.getElementById( 'formType' ).value = 'x';					// Set hidden value for reference later by javascript

		_clearOut()															// Clear text input fields on form
		_setTop();															// Reset postion on screen

		alert( 'Caution: converting dry ingredients from weight to volume is not precise. Use the result as an estimate only.' ); // Warn about using this converter
		return;
	}

	leftList.options.length = 0;											// Clear pull-down menus
	rightList.options.length = 0;
	for ( n = 0; n < details.length / 3; n++ ) {							// Populate pull-down menus based on type of conversion
		x = 3 * n;
		y = x + 1;
		leftList.options.length = n + 1;									// Increase pull-down size by 1
		rightList.options.length = n + 1;
		leftList.options[n].text = details[y];								// Plug in text information in pull-down menu
		rightList.options[n].text = details[y];
		leftList.options[n].value = details[x];								// Plug in conversion information in pull-down menu
		rightList.options[n].value = details[x];
		if ( details[y+1] == "selected" ) rightList.selectedIndex = n;
	}
	leftList.selectedIndex = 0;												// Indicate that the first item in each pull-down is selected

	_clearOut()																// Clear text input fields on form
	_setTop();																// Reset postion on screen
}

function _calcUnits( direction ) {												// Perform actual unit conversion
	if ( direction == 'leftIn' ) {
		oInput =  document.getElementById( 'leftIn' );
		oOutput =  document.getElementById( 'rightIn' );
		oInList = document.getElementById( 'leftUnits' );
		oOutList = document.getElementById( 'rightUnits' );
	} else {
		oInput =  document.getElementById( 'rightIn' );
		oOutput =  document.getElementById( 'leftIn' );
		oInList = document.getElementById( 'rightUnits' );
		oOutList = document.getElementById( 'leftUnits' );
	}

	input = oInput.value;													// Substitute variable for input field property
	type = document.getElementById( 'formType' ).value;						// Substitute variable for conversion type: w, v, l, or t
	in_unit = oInList.options[oInList.selectedIndex].value;					// Determine "convert from" unit of measure conversion factor
	out_unit = oOutList.options[oOutList.selectedIndex].value;				// Determine "convert to" unit of measure conversion factor
	if ( input == ' ' || !isFinite( input ) ) {								// Exit if no valid number to convert
		alert( 'The input field is either empty or contains a space character or a non-numeric character. Please enter only numbers in the input field.' );
		return

	} else if ( input == '' ) {												// Ignore empty input field
		return;

	} else if ( type != 't' ) {												// Perform conversion if not for temperature
		x = input * in_unit / out_unit;										// Do conversion
		if ( x >= 100 ) {													// Reduce number of digits depending on size of number to the left of the decimal
			oOutput.value = Math.round( x );
		} else if ( x >= 10 ) {
			oOutput.value = Math.round( x * 10 ) / 10;
		} else if ( x >= 1 ) {
			oOutput.value = Math.round( x * 100 ) / 100;
		} else {
			x = Math.round( x * 1000 ) / 1000;
			if ( x <= 0 ) {													// Add a leading zero if result is less than 0
				x = '0' + x;
			}
			oOutput.value = x;
		}
		return

	} else if ( in_unit == 1 && out_unit == -1 ) {							// Perform conversion if Fahrenheit to centigrade and round to no more 1 digit right of the decimal
		var x = ( input - 32 ) / 1.8
		oOutput.value = Math.round( x * 10 ) / 10;
		return

	} else if ( in_unit == -1 && out_unit == 1 ) {							// Perform conversion if centigrade to Fahrenheit and round to no more 1 digit right of the decimal
		var x = ( input * 1.8 ) + 32
		oOutput.value = Math.round( x * 10 ) / 10;
		return

	} else if ( in_unit == out_unit ) {										// Perform "conversion" if "in" and "out" units are the same
		oOutput.value = input;
		return

	} else if ( in_unit == 0 ) {											// Test for valid entry for conversion from a thermostat setting
		if ( input != Math.round( input )) {								// Alert and exit if invalid
			alert('The value to be converted must be an integer from 1 to 10.'); // Non-integer entered
			return
		} else if ( input < 1 || input > 10 ) {
			alert('The value to be converted must be an integer from 1 to 10');	// Number outside of range
			return
		}
		var x = input * 30;													// Convert to centigrade degrees
		if ( out_unit == 1 ) {												// Convert to fahrenheit degrees if needed
			x = ( x * 1.8 ) + 32;
		}
		oOutput.value = Math.round( x * 10 ) / 10;							// Dipslay conversion
		return

	} else if ( in_unit == 1 ) {											// Assume conversion from Fahrenheit degrees to thermostat reading
		x = ( input - 32 ) / 1.8											// Convert to centigrade

	} else {																// Assume conversion from centigtade degrees to thermostat reading
		x = input;
	}
	if ( x < 15 ) {															// Test for range error, exit if error
		oOutput.value = "";
		return
	}
	if ( x > 315 ) {														// Test for range error, exit if error
		alert('The value to be converted is outside the range of thermostat settings. The input temperature must be between 30 and 300 degrees centigrade or 85 and 570 degrees Fahrenheit.');
		return
	}
	t_stat = [ "1", "1 - 2", "2", "2 - 3", "3", "3 - 4", "4", "4 - 5", "5", "5 - 6", "6", "6 - 7", "7", "7 - 8", "8", "8 - 9", "9", "9 - 10", "10"];

	oOutput.value = t_stat[ Math.round( x / 15 ) - 2 ];						// Output result from table of possible results (t_stat array)
	return
}

function _clearOut() {														// Clear results field. Called by onFocus event handler of input field
	document.getElementById( 'leftIn' ).value = '';
	document.getElementById( 'rightIn' ).value = '';
}

// Perform brining calculations -------------------------------------------------------------------------------------------------------------------------------

function _calcBrine () {													// Perform the brine calculations
	var oForm = document.getElementById( 'brineForm' );

	var resSalt = document.getElementById( 'resSalt' );						// Substitute variable for salt result output field object
	var resSugar = document.getElementById( 'resSugar' );					// Substitute variable for sugar result output field object
	var resNitrite = document.getElementById( 'resNitrite' );				// Substitute variable for nitrite result output field object

	var waterIn = oForm.waterIn.value;										// Substitute variable for water weight field property
	var waterUnit = getCheckedValue ( oForm.waterUnit );					// Substitute variable for water units correction factor field property
	var meatIn = oForm.meatIn.value;										// Substitute variable for meat weight field property
	var meatUnit = getCheckedValue ( oForm.meatUnit );						// Substitute variable for meat weight units correction factor field property

	var perWater = getCheckedValue ( oForm.perWater );						// Substitute variable for water percentage checked field property
	var perSalt = getCheckedValue ( oForm.perSalt );						// Substitute variable for salt percentage checked field property
	var perSugar = getCheckedValue ( oForm.perSugar );						// Substitute variable for sugar percentage checked field property
	var perNitrite = getCheckedValue ( oForm.perNitrite );					// Substitute variable for nitrite percentage checked field property

	if ( waterIn !== '.' && ( waterIn == ' ' || !isFinite( waterIn ) )) {	// Exit if no valid number for water quantity
		alert( 'The water quantity input field contains a non-numeric character. Please enter only numbers in this input field.' );
		oForm.waterIn.focus;
		oForm.waterIn.value = '';
		document.getElementById( 'resSalt' ).innerHTML = '';
		document.getElementById( 'resSugar' ).innerHTML = '';
		document.getElementById( 'resNitrite' ).innerHTML = '';
		return;

	} else if ( meatIn !== '.' && ( meatIn == ' ' || !isFinite( meatIn ) )) {	// Exit if no valid number for meat weight
		alert( 'The meat weight input field contains a non-numeric character. Please enter only numbers in this input field.' );
		oForm.meatIn.focus;
		oForm.meatIn.value = '';
		document.getElementById( 'resSalt' ).innerHTML = '';
		document.getElementById( 'resSugar' ).innerHTML = '';
		document.getElementById( 'resNitrite' ).innerHTML = '';
		return;

	} else if ( waterIn > 0 && meatIn > 0 && waterIn !== '.' && meatIn !== '.' ) {
		waterIn = 1000 * waterIn * waterUnit;								// Convert water to weight in grams
		meatIn = 1000 * meatIn * meatUnit;									// Convert meat to weight in grams

		var totalWaterWeight = waterIn + ( meatIn * perWater );				// Calculate total water weight in grams
		var totalSalt = totalWaterWeight * perSalt;							// Calculate initial salt weight in grams
		var totalSugar = totalWaterWeight * perSugar;						// Calculate total sugar weight in grams

		var totalBrineWeight = waterIn + totalSalt + totalSugar;			// Calculate total weight of brine in grams

		var totalPureNitrite = 0.0002 * ( waterIn + meatIn + totalSalt + totalSugar );
		var totalCurSalt = totalPureNitrite / perNitrite;					// Calculate total weight of curing salt in grams
		totalSalt = totalSalt - ( totalCurSalt * ( 1 - perNitrite ));		// Calculate final salt weight in grams

		totalSalt = ( totalSalt < 0 ) ? 0 : Math.round( totalSalt );		// Drop fractional values
		totalSugar = Math.round( totalSugar );								// Drop fractional values
		totalCurSalt = Math.round( totalCurSalt );							// Drop fractional values

		document.getElementById( 'resSalt' ).innerHTML = totalSalt + " grams";			// Output value
		document.getElementById( 'resSugar' ).innerHTML = totalSugar + " grams";		// Output value
		document.getElementById( 'resNitrite' ).innerHTML = totalCurSalt + " grams";	// Output value

	} else {							// Exit if a field is empty
		document.getElementById( 'resSalt' ).innerHTML = '';
		document.getElementById( 'resSugar' ).innerHTML = '';
		document.getElementById( 'resNitrite' ).innerHTML = '';
	}
}

function getCheckedValue ( radioObj ) {										// Determine the value of the radio button that is checked
	if ( !radioObj )
		return "";
	var radioLength = radioObj.length;
	if ( radioLength == undefined )
		if ( radioObj.checked )
			return radioObj.value;
		else
			return "";
	for ( var i = 0; i < radioLength; i++) {
		if ( radioObj[i].checked ) {
			return radioObj[i].value;
		}
	}
	return "";
}

// Perform nitrite calculations -------------------------------------------------------------------------------------------------------------------------------

function _calcNitrite () {

	var meatIn = $( "input#nitriteMeatIn" ).val ();							// Substitute variable for meat weight field property
	var meatUnit = $( "li#nitriteMeat input:checked" ).val ();				// Substitute variable for meat weight units correction factor field property
	var perNitrite = $( "li#nitritePercent input:checked" ).val ();			// Substitute variable for nitrite percentage checked field property
	var constant = 0.061;													// Grams nitrite per pound of meat
	
	if ( meatIn !== '.' && ( meatIn == ' ' || !isFinite( meatIn ) )) {		// Exit if no valid number for meat weight
		alert( 'The meat weight input field contains a non-numeric character. Please enter only numbers in this input field.' );
		$( "input#nitriteMeatIn" ).focus;
		$( "input#nitriteMeatIn" ).val ( "" );
		$( "span#resultNitrite" ).html ( "&#8212;" );
		return;
	} else if ( meatIn > 0 && meatIn !== '.' ) {
		totalCurSalt = constant * meatIn * meatUnit / perNitrite;			// Calculate total weight of curing salt in grams
		factor = ( totalCurSalt < 10 ) ? 10 : 1 ;							// Rounding factor
		totalCurSalt = Math.round( totalCurSalt * factor ) / factor;		// Drop fractional values
		$( "span#resultNitrite" ).text ( totalCurSalt + " grams" );			// Output value
	} else {
		$( "span#resultNitrite" ).html ( "&#8212;" );
	}
}

// Perform nutrient calculations -------------------------------------------------------------------------------------------------------------------------------

var quantity, units, base, description, servings;

function _checkSearch () {
	$( document ).keyup ( function ( event ) {
		if ( event.keyCode !== 13 ) {
			if ( $( "#search" ).attr ( "value" ).length > 2 ) {
				$( "#searchButton" ).attr ( "disabled", "" );
				$( "#searchButton" ).attr ( "value", "Search" );
			} else {
				$( "#searchButton" ).attr ( "disabled", "disabled" );
				$( "#noResult" ).css ( "display", "none" );
			}
		}
	});
	$( document ).select ( function () {
		if ( $( "input#search" ).attr ( "value" ).length > 2 ) {
			$( "input#searchButton" ).attr ( "disabled", "" );
			$( "input#searchButton" ).attr ( "value", "Search" );
		} else {
			$( "input#searchButton" ).attr ( "disabled", "disabled" );
			$( "div#noResult" ).css ( "display", "none" );
		}
	});
}

function _doSearch () {
	$( "input#searchButton" ).attr ( "disabled", "disabled" );
	$( "input#searchButton" ).attr ( "value", "Searching" );
	$( "input#customButton" ).attr ( "disabled", "disabled" );
	$status = $( "input#viewRecipe" ).attr ( "disabled" );
	$( "input#viewRecipe" ).attr ( "disabled", "disabled" );
	xajax_search ( $( "input#search" ).attr ( "value" ), $status );
}

function _showOne ( NDB_No ) {
	_switchOneToOther ();
	xajax_showOne ( NDB_No );
}

function _switchOneToOther () {
	$( 'div#nutrients_first' ).css ( 'display', 'none' );
	$( 'div#nutrients_first div' ).css ( 'display', 'none' );
	$( 'input#search' ).val ( '' );
	
	$( 'div#wait' ).html ( "<p>GATHERING THE DATA</p>" ).cyclicFade ({
		repeat: 0,
		params: [
			{ fadeout:600, stayout:300, opout:0.3, fadein:600, stayin:300, opin:1.0 }
		]
	});
	$( 'div#wait' ).css ( 'display', 'block' );
	_setTop ();
}

function _toggleDiv ( divName, shade ) {
	if ( $( "div#" + divName ).attr ( "status" ) == "true" ) {
		if ( $( "div#" + divName + "More" ).css ( "display" ) == "none" ) {
			$( "div#" + divName + "More" ).css ( "display", "block" );
			$( "div#" + divName ).css ( "background-image", "url('images/nutrient_arrow_" + shade + "_open.png')" );
		} else {
			$( "div#" + divName + "More" ).css ( "display", "none" );
			$( "div#" + divName ).css ( "background-image", "url('images/nutrient_arrow_" + shade + "_close.png')" );
		}
	}
}

function _startNewSearch () {
	$( "div#nutrients_second" ).css ( "display", "none" );
	$( "div#nutrients_third" ).css ( "display", "none" );
	$( "div#nutrients_custom" ).css ( "display", "none" );
	$( "div#longDesc" ).css ( "background-image", "url('images/nutrient_arrow_light_plain.png')" );
	$( "div#longDesc" ).css ( "cursor", "default" );
	$( "div#longDescMore" ).css ( "display", "none" );
	$( "div#nutrients_first" ).css ( "display", "block" );
	$( "input#search" ).val ( "" ).focus ();
	$( "input#searchButton" ).attr ( "value", "Search" );
	if ( recipeTotalsStatus ) $( "input#viewRecipe" ).attr ( "disabled", "" );
	_setTop ();
}

function _checkUnits () {
	unitsValue = $( "select#units :selected" ).val ().split ( "|" );
	newQuantity = unitsValue[0];
	newQuantity = ( newQuantity >= 1 ) ? Math.floor( newQuantity ) : newQuantity ;
	$( "input#quantity" ).val ( newQuantity );
	_checkQuantity ();
}

function _checkQuantity () {
	newValue = $( "input#quantity" ).val ();
	if ( newValue.match( /[^\d-./]/g ) != null ) {
		$( "input#quantity" ).val ( newValue.replace( /[^\d-./]/g, "" ));
		return;
	}
	if ( newValue.match( /[/]/g ) != null ) newValue = _checkFraction ( newValue );
	unitsValue = $( "select#units :selected" ).val ().split ( "|" );
	unitQuan = unitsValue[0];
	unitMass = unitsValue[1];
	multiplier =  ( newValue * unitMass ) / ( 100 * unitQuan );
	if ( isNaN ( multiplier ) || multiplier <= 0) {
		$( "span.nutQuan" ).html ( "&#8212;" );
	} else {
		nutrCount = $( "input#nutrientCount" ).val ();
		for ( x = 0; x < nutrCount; x++ ) {
			nutrData = $( "span#nutQuan_" + x ).attr ( "value" ).split ( "|" );
			nutrVal = nutrData[0];
			numDec = nutrData[1];
			roundFactor = Math.pow( 10, numDec );
			reportValue = Math.round( multiplier * nutrVal * roundFactor ) / roundFactor;
			reportValue = ( reportValue == 0 || isNaN( reportValue )) ? "&#8212;" : reportValue ;
			$( "span#nutQuan_" + x ).html ( _format ( reportValue ));
		}
	}
}

function _checkFraction ( value ) {
	if ( value.length < 3 ) return value;
	if ( value.match( /[.]/g ) != null ) return value;
	valueCount = value.length;
	var hypenPos, slashPos;
	var whole = 0;
	var newValue = value;
	for ( x = 0; x < valueCount; x++ ) {
		if ( value.charAt( x ) == "-" ) hypenPos = x;
		if ( value.charAt( x ) == "/" ) slashPos = x;
	}
	if ( slashPos == null || slashPos == valueCount - 1 ) return value;
	if ( hypenPos ) {
		if ( hypenPos == valueCount - 1 ) return value;
		bothParts = newValue.split ( "-" );
		whole = parseInt ( bothParts[0] );
		newValue = bothParts[1];
		if ( newValue.indexOf( "/" ) == -1 ) return value;
	}
	bothParts = newValue.split ( "/" );
	numerator = parseInt ( bothParts[0] );
	denominator = parseInt ( bothParts[1] );
	value = whole + ( numerator / denominator );
	return Math.round( value * 1000 ) / 1000;
}

function _format ( origNumber ) {
	if ( isNaN( origNumber )) return origNumber;
	if ( Math.floor( origNumber ) == origNumber ) {
		integer = String ( origNumber );
		decimal = "";
	} else {
		origNumber = String ( origNumber );
		splitNumber = origNumber.split ( "." );
		integer = splitNumber[0];
		decimal = "." + splitNumber[1];
	}
	if ( integer.length < 4 ) return origNumber;
	numDigits = integer.length;
	commaPos = numDigits - 3;
	return integer.slice( 0, commaPos ) + "," + integer.slice( commaPos, numDigits ) + decimal;
}

recipeTotalsStatus = false;

function _addToRecipe () {
	quantity = $( "input#quantity" ).val ();
	units = $( "select#units :selected" ).html ();
	if ( units !== "grams" ) {
		border = units.indexOf ( " [" );
		units = units.slice( 0, border );
	}
	var description = $( "div#longDesc" ).html ();
	ingredient = quantity + " " + units + " &#8230; " + description;
	
	recipeTotalsStatus = true;
	recipeTotals = "";
	nutrCount = $( "input#nutrientCount" ).val ();
	for ( x = 0; x < nutrCount; x++ ) {
		nutr_no = $( "span#nutQuan_" + x ).attr ( "Nutr_No" ) + "";
		value = $( "span#nutQuan_" + x ).html ();
		value =  parseFloat( value.replace( /[^\d.]/g, "" ));
		value = ( isNaN( value )) ? 0 : value ;
		recipeTotals += nutr_no + "=" + value;
		if ( x < nutrCount - 1 ) recipeTotals += "&";
	}
	xajax_addToRecipe ( recipeTotals, ingredient );
}

$( document ).ready ( function ()
	{
		$( "div#ingredients" ).attr ( "status", "false" );
	}	
);

function _viewRecipeTotals () {
	if ( $( "div#ingredients" ).attr ( "status" ) == "true" && $( "div#ingredients" + "More" ).css ( "display" ) == "block" ) {
		$( "div#ingredients" + "More" ).css ( "display", "none" );
		$( "div#ingredients" ).css ( "background-image", "url('images/nutrient_arrow_light_close.png')" );
	}

	_switchOneToOther ();
	xajax_viewRecipeTotals ();
}

function _clearRecipe () {
	if ( !confirm ( "Are you sure you want to delete all the recipe information? This action cannot be undone." )) {
		$( "input#clearRecipeButton" ).blur ();
		return false;
	}
	recipeTotalsStatus = false;
	$( "input#viewRecipe" ).attr ( "disabled", "disabled" );
	xajax_clearRecipeTotals ();
}

function _checkServings () {
	servings = $( "input#servingsInput" ).val ();
	if ( servings.match( /[^\d]/g ) != null ) {
		$( "input#servingsInput" ).val ( servings.replace( /[^\d]/g, "" ));
		return;
	}
	nutrCount = $( "input#nutrientCountTotal" ).val ();
	if ( isNaN ( servings ) || servings <= 0) {
		$( "span.nutServing" ).html ( "&#8212;" );
	} else {
		for ( x = 0; x < nutrCount; x++ ) {
			nutrData = $( "span#nutServing_" + x ).attr ( "value" ).split ( "|" );
			nutrVal = nutrData[0] / servings;
			numDec = nutrData[1];
			roundFactor = Math.pow( 10, numDec );
			reportValue = Math.round( nutrVal * roundFactor ) / roundFactor;
			reportValue = ( reportValue == 0 || isNaN( reportValue )) ? "&#8212;" : reportValue ;
			$( "span#nutServing_" + x ).html ( _format ( reportValue ));
		}
	}
}

var selectStatus, actualRadio, gramsRadio, servingRadio;

function _startCustom () {
	$( "div#nutrients_first" ).css ( "display", "none" );
	$( "div#nutrients_first div" ).css ( "display", "none" );
	$( "input#search" ).val ( "" );
	$( "div#customNutList" ).css ( "display", "none" );
	$( "div.details" ).css ( "display", "none" );
	$( "div.details input" ).val ( "" );
	$ ( "div#detailsSelection input" ).attr ({
		checked: false,
		disabled: ""
	});
	$ ( "div#detailsSelection span" ).css ( "color", "#000" );
	
	$( "div#wait" ).html ( "<p>Building Form</p>" ).cyclicFade ({
		repeat: 0,
		params: [
			{ fadeout:600, stayout:300, opout:0.3, fadein:600, stayin:300, opin:1.0 }
		]
	});
	$( "div#wait" ).css ( "display", "block" );
	$( "input#addCustomButton" ).attr ( "disabled", "disabled" );
	selectStatus = false;
	_setTop ();
	xajax_startCustom ();
}

function _select ( showDivName, hideDivName1, hideDivName2 ) {
	if ( selectStatus ) {
		if ( !confirm ( "Moving to a different nutrient selector with cause the general heading information to be cleared." )) {
			$( "input#radio_actual" ).attr ( "checked", actualRadio ).blur ();
			$( "input#radio_grams" ).attr ( "checked", gramsRadio ).blur ();
			$( "input#radio_serving" ).attr ( "checked", servingRadio ).blur ();
			return false;
		}
	}
	selectStatus = true;
	actualRadio = $( "input#radio_actual" ).attr ( "checked" );
	gramsRadio = $( "input#radio_grams" ).attr ( "checked" );
	servingRadio = $( "input#radio_serving" ).attr ( "checked" );
	$( "div#" + hideDivName1 ).css ( "display", "none" );
	$( "input#radio_" + hideDivName1 ).attr ( "disabled", "" );
	$( "span#" + hideDivName1 + "Text" ).css ( "color", "#999" );
	$( "div#" + hideDivName2 ).css ( "display", "none" );
	$( "input#radio_" + hideDivName2 ).attr ( "disabled", "" );
	$( "span#" + hideDivName2 + "Text" ).css ( "color", "#999" );
	$( "div#" + showDivName ).css ( "display", "block" );
	$( "input#radio_" + showDivName ).attr ( "disabled", "disabled" );
	$( "span#" + showDivName + "Text" ).css ( "color", "#000" );
	$( "div#customNutList" ).css ( "display", "block" );
	$( "input#addCustomButton" ).attr ( "disabled", "disabled" );
	$( "div.details input" ).val ( "" );

	_setTop ();
}

function _testCustomQuantity ( inputBox, divName ) {
	newValue = $( "input#" + inputBox ).val ();
	if ( newValue.match( /[^\d-./]/g ) != null ) {
		$( "input#" + inputBox ).val ( newValue.replace( /[^\d-./]/g, "" ));
		return;
	}
	_testCustomInput ( divName );
}

function _testCustomInput ( divName ) {
	customQuantity = $( "input#" + divName + "Quantity" ).val ();
	customQuantity = customQuantity.replace( /[\s]/g, "" )
	if ( divName == "grams" ) {
		customUnits = "-";
	} else {
		customUnits = $( "input#" + divName + "Units" ).val ();
		customUnits = customUnits.replace( /[\s]/g, "" )
	}
	if ( divName !== "serving" ) {
		customBase = "-";
	} else {
		customBase = $( "input#" + divName + "Base" ).val ();
		customBase = customBase.replace( /[\s]/g, "" )
	}
	customDescription = $( "input#" + divName + "Description" ).val ();
	customDescription = customDescription.replace( /[\s]/g, "" )
	if ( customQuantity.length > 0 && customUnits.length > 0 && customBase.length > 0 && customDescription.length > 0 ) {
		$( "input#addCustomButton" ).attr ( "disabled", "" );
	} else {
		$( "input#addCustomButton" ).attr ( "disabled", "disabled" );
	}
}

function _addCustomToRecipe () {
	if ( actualRadio ) {
		quantity = $( "input#actualQuantity" ).val ();
		if ( quantity.match( /[/]/g ) != null ) quantity = _fractionToDecimal ( quantity );
		if ( quantity == -1 ) {
			alert ( "Improperly formed fraction in the \"Quantity:\" box. Please fix it before preceeding." );
			$( "input#actualQuantity" ).focus ();
			return false;
		}
		units = $( "input#actualUnits" ).val ();
		description = $( "input#actualDescription" ).val ();
		ingredient = quantity + " " + units + " &#8230; " + description;
		multiplier = 1;
	} else if ( gramsRadio ) {
		quantity = $( "input#gramsQuantity" ).val ();
		if ( quantity.match( /[/]/g ) != null ) quantity = _fractionToDecimal ( quantity );
		if ( quantity == -1 ) {
			alert ( "Improperly formed fraction in the \"Number of grams used:\" box. Please fix it before preceeding." );
			$( "input#gramsQuantity" ).focus ();
			return false;
		}
		description = $( "input#gramsDescription" ).val ();
		ingredient = quantity + " grams &#8230; " + description;
		multiplier = quantity / 100;
	} else if (servingRadio  ) {
		quantity = $( "input#servingQuantity" ).val ();
		if ( quantity.match( /[/]/g ) != null ) quantity = _fractionToDecimal ( quantity );
		if ( quantity == -1 ) {
			alert ( "Improperly formed fraction in the \"Servings used:\" box. Please fix it before preceeding." );
			$( "input#servingQuantity" ).focus ();
			return false;
		}
		base = $( "input#servingBase" ).val ();
		if ( base.match( /[/]/g ) != null ) base = _fractionToDecimal ( base );
		if ( base == -1 ) {
			alert ( "Improperly formed fraction in the \"Base servings:\" box. Please fix it before preceeding." );
			$( "input#servingBase" ).focus ();
			return false;
		}
		units = $( "input#servingUnits" ).val ();
		description = $( "input#servingDescription" ).val ();
		ingredient = quantity + " " + units + " &#8230; " + description;
		multiplier = quantity / base;
	}

	$( "div.details input" ).val ( "" );
	
	recipeTotalsStatus = true;
	recipeTotals = "";
	nutrCount = $( "input#customNutrientCount" ).val ();
	ampStatus = false;
	for ( x = 0; x < nutrCount; x++ ) {
		nutr_no = $( "input#nutCustom_" + x ).attr ( "Nutr_No" ) + "";
		num_dec = $( "input#nutCustom_" + x ).attr ( "Num_Dec" ) + "";
		value = $( "input#nutCustom_" + x ).val ();
		value =  parseFloat( value.replace( /[^\d.]/g, "" ));
		value = ( isNaN( value )) ? 0 : value ;
		roundFactor = Math.pow( 10, num_dec );
		value = Math.round( multiplier * value * roundFactor ) / roundFactor;
		if ( value > 0 ) {
			if ( ampStatus ) recipeTotals += "&";
			recipeTotals += nutr_no + "=" + value;
			ampStatus = true;
		}
	}
	xajax_addToRecipe ( recipeTotals, ingredient );
}

function _fractionToDecimal ( value ) {
	if ( value.length < 3 ) return -1;
	if ( value.match( /[.]/g ) != null ) return -1;
	valueCount = value.length;
	var hypenPos, slashPos;
	var whole = 0;
	var newValue = value;
	for ( x = 0; x < valueCount; x++ ) {
		if ( value.charAt( x ) == "-" ) hypenPos = x;
		if ( value.charAt( x ) == "/" ) slashPos = x;
	}
	if ( slashPos == null || slashPos == valueCount - 1 ) return -1;
	if ( hypenPos ) {
		if ( hypenPos == valueCount - 1 ) return -1;
		bothParts = newValue.split ( "-" );
		whole = parseInt ( bothParts[0] );
		newValue = bothParts[1];
		if ( newValue.indexOf( "/" ) == -1 ) return -1;
	}
	bothParts = newValue.split ( "/" );
	numerator = parseInt ( bothParts[0] );
	denominator = parseInt ( bothParts[1] );
	value = whole + ( numerator / denominator );
	return Math.round( value * 1000 ) / 1000;
}

function _testNutCustom ( inputBox ) {
	newValue = $( inputBox ).val ();
	if ( newValue.match( /[^\d.]/g ) != null ) $( inputBox ).val ( newValue.replace( /[^\d.]/g, "" ));
}

function _getTitle () {
	$( "div#ingredients" ).css ( "display", "none" );
	$( "div#ingredientsMore" ).css ( "display", "none" );
	$( "div#servings" ).css ( "display", "none" );
	$( "div#totalNutList" ).css ( "display", "none" );
	$( "div#title" ).css ( "display", "block" );
	$( "input#recipeTitle" ).val ( "" ).focus ();
	$( "p#thirdButtons input" ).attr ( "disabled", "disabled" );
	_setTop ();
}

function _cancelPDF () {
	$( "div#title" ).css ( "display", "none" );
	$( "div#ingredients" ).css ( "display", "block" );
	$( "div#servings" ).css ( "display", "block" );
	$( "div#totalNutList" ).css ( "display", "block" );
	$( "p#thirdButtons input" ).attr ( "disabled", "" );
	_setTop ();
}

function _pdf () {
	_cancelPDF ();
	printIngredients = ( $( "input#ingredListYes" ).attr ( "checked" )) ? "yes" : "no" ;
	queryString = "title=" + $( "input#recipeTitle" ).val () + "&servings=" + $( "input#servingsInput" ).val () + "&printIngredients=" + printIngredients;
	window.open ( "tools-pdf.php?" + queryString );
}

// Pop-up picture

var popFrame, frameHeight, frameWidth, id, borders;
var pop_done = false;

function _viewInfo ( page ) {
	if ( popFrame ) _pop_hide( popFrame );
	popFrame = "div#" + page + "Info";
	frameWidth = $( popFrame ).width () + parseInt( $( "div.popInfo" ).css ( "padding-left" )) + parseInt( $( "div.popInfo" ).css ( "padding-right" ));
	frameHeight = $( popFrame ).height () + parseInt( $( "div.popInfo" ).css ( "padding-top" )) + parseInt( $( "div.popInfo" ).css ( "padding-bottom" ));
	_pop_show ();
	return false;
}

function _pop_show () {
	$( popFrame ).click ( function ()
		{
			_pop_hide ( popFrame );
		}
	);
	$( window ).resize ( _pop_position ).scroll ( _pop_position );
	thumbLoad = true;
	_pop_position ();
}

function _pop_hide ( frameName ) {
	$( frameName ).slideUp ( "medium" );
	thumbLoad = false;
	return false;
}

function _pop_position () {
	if ( thumbLoad ) {
		$( popFrame ).css (
			{
				left: (( $( window ).width() - frameWidth ) / 2 + 5 ) + "px",
				top: ((( $( window ).height() - frameHeight ) / 2 ) + $( window ).scrollTop() ) + "px",
				display: "none",
				opacity: 1
			}
		).slideDown ( "medium" );
	}
 }

// Perform Brix calculations --------------------------------------------------------------------------------------------------------------------

function _brix_switch ( show, hide ) {
	$( "form#" + hide ).css ( "display", "none" );
	$( "form#" + show ).css ( "display", "block" );
	$( "input#brix_" + show ).attr ( "disabled", "disabled" );
	$( "input#brix_" + hide ).attr ( "disabled", "" );
	if ( show == "sugar" ) {
		if ( $( "input#brix_concentration_liquid" ).val ()) $( "input#brix_sugar_liquid" ).val ( $( "input#brix_concentration_liquid" ).val ());
		if ( $( "input#brix_concentration_natural" ).val ()) $( "input#brix_sugar_natural" ).val ( $( "input#brix_concentration_natural" ).val ());
		brix_concentration = $( "span#brix_concentration_result" ).html () + "";
		if ( brix_concentration !== "&#8212;" ) $( "input#brix_sugar_final" ).attr ( "value", brix_concentration * 1 );
		_calcSugar ();
	} else if ( show == "concentration" ) {
		if ( $( "input#brix_sugar_liquid" ).val ()) $( "input#brix_concentration_liquid" ).val ( $( "input#brix_sugar_liquid" ).val ());
		if ( $( "input#brix_sugar_natural" ).val ()) $( "input#brix_concentration_natural" ).val ( $( "input#brix_sugar_natural" ).val ());
		brix_sugar = $( "span#brix_sugar_result" ).html () + "";
		if ( brix_sugar !== "&#8212;" ) $( "input#brix_concentration_sugar" ).attr ( "value", brix_sugar * 1 );
		_calcConcentration ();
	}
}

function _checkBrixNumber ( textBox ) {
	var text = textBox.value;
	textBox.value = text.replace( /[^.\d]/g, "" );
	if ( $( textBox ).attr ( "id" ).indexOf( '_sugar_' ) > 0 ) {
		_calcSugar ();
	} else {
		_calcConcentration ();
	}
}

function _calcSugar () {
	var j = $( "input#brix_sugar_liquid" ).val () * 1;
	var m = $( "input#brix_sugar_natural" ).val () / 100;
	var n = $( "input#brix_sugar_final" ).val () / 100;
	if ( j > 0 && m >= 0 && n > 0 ) {
		addedSugar = (( n * (( 1 - m ) * j )) / ( 1 - n )) - ( m * j );
		if ( addedSugar > 0 ) {
			$( "span#brix_sugar_result" ).html ( Math.round ( addedSugar ));
		} else {
			$( "span#brix_sugar_result" ).html ( "&#8212;" );
		}
	} else {
		$( "span#brix_sugar_result" ).html ( "&#8212;" );
	}
}

function _calcConcentration () {
	var j = $( "input#brix_concentration_liquid" ).val () * 1;
	var m = $( "input#brix_concentration_natural" ).val () / 100;
	var x = $( "input#brix_concentration_sugar" ).val () * 1;
	if ( j > 0 && m >= 0 && x > 10 ) {
		var k = ( x + ( m * j )) / (( 1 - m ) * j );
		finalBrix = ( k / ( 1 + k )) * 100;
		if ( finalBrix > 0 ) {
			$( "span#brix_concentration_result" ).html ( Math.round ( finalBrix ));
		} else {
			$( "span#brix_concentration_result" ).html ( "&#8212;" );
		}
	} else {
		$( "span#brix_concentration_result" ).html ( "&#8212;" );
	}
}

// Perform thermal equilibrium calculation --------------------------------------------------------------------------------------------------------------------

function _checkNumber ( textBox ) {
	var text = textBox.value;
	textBox.value = text.replace( /[^.\d]/g, "" );
	_calcHeat ();
}

var unitsHeatText = "&#176;F", unitsHeatType = "f";

function _setHeat () {
	unitsHeatType = $( "li#finalEqTemp input:checked" ).val ();				// Substitute variable for selected temperature units
	unitsHeatText = ( unitsHeatType == "c" ) ? "&#176;C" : "&#176;F" ;		// Substitute variable for formatted text representing temperature units
	$( "span.tempUnits" ).html ( unitsHeatText );							// Set proper units on page
	_calcHeat ();
}

function _setHeatCap () {
	specHeatCap = $( "select#ingredHeatCapacity :selected" ).val ();
	specHeatCap = ( specHeatCap > 0 ) ? specHeatCap : "&#8212;" ;
	$( "span#specHeatCap" ).html ( specHeatCap );
	_calcHeat ();
}

function _calcHeat () {

	var finalTemp = 1 * $( "input#finalTemp" ).val ();						// Substitute variable for final (equilibrium) temperature property
	if ( unitsHeatType == "f" ) finalTemp = tempConvert ( "f", finalTemp );	// Convert to Celsius, if necessary
	var ingredHeatCap = $( "select#ingredHeatCapacity :selected" ).val ();	// Substitute variable for ingredient heat capacity
	var ingredMass = $( "input#ingredientIn" ).val () * $( "li#ingredMassUnit input:checked" ).val (); // Substitute variable for ingredient mass and convert to kilograms
	var ingredStartTemp = $( "input#startIngredTemp" ).val ();				// Substitute variable for the starting ingredient temperature
	if ( unitsHeatType == "f" ) ingredStartTemp = tempConvert ( "f", ingredStartTemp );	// Convert to Celsius, if necessary
	var waterMass = $( "input#waterVol" ).val () * $( "li#waterMassUnit input:checked" ).val (); // Substitute variable for water mass and convert to kilograms

// alert ( finalTemp + ", " + ingredHeatCap + ", " + ingredMass + ", " + ingredStartTemp + ", " + waterMass );

	if ( finalTemp > 0 && ingredHeatCap > 0 && ingredMass > 0 && ingredStartTemp > 0 && waterMass > 0 ) {
		waterStartTemp = ( ingredMass * ingredHeatCap / waterMass * ( finalTemp - ingredStartTemp )) + finalTemp; // Determine starting water temperature in Celsius
		if ( unitsHeatType == "f" ) waterStartTemp = tempConvert ( "c", waterStartTemp ); //Convert to fahrenheit, if necessary
		$( "span#resultHeat" ).html ( Math.round ( waterStartTemp ) + " " + unitsHeatText );
	} else {
		$( "span#resultHeat" ).html ( "&#8212;" );
	}
}

function tempConvert ( direction, value ) {
	if ( direction == "c" ) {
		return ( value * 1.8 ) + 32;										// Convert from Celsius to Fahrenheit
	} else {
		return ( value - 32 ) / 1.8;										// Convert from Fahrenheit to Celsius
	}
}

