
var Convertor = {};
var Formatter = {};
var BreadTool = {};

Convertor.poundsToKilograms = function(n){
	return .455 * n;
}

Convertor.kilogramsToPounds = function(n){
	return 2.2 * n;
}

Convertor.kilogramsToOunces = function(n){
	return Convertor.poundsToOunces(Convertor.kilogramsToPounds(n));
}

Convertor.loavesToPounds = function(n){
	return Loaves[n];
}

Convertor.ouncesToKilograms = function(n){
	return .02835 * n;
}

Convertor.ouncesToPounds = function(n){
	return .0625 * n;
}

Convertor.poundsToOunces = function(n){
	return 16 * n;
}

Convertor.ouncesToCups = function (n,density){
	return (n / density) / 8;
}

Convertor.tablespoonsToCups = function(n){
	return .0625 * n;
}

Convertor.cupsToTablespoons = function(n){
	return 16 * n;
}

Convertor.cupsToTeaspoons = function(n){
	return this.tablespoonsToTeaspoons(this.cupsToTablespoons(n));
}

Convertor.tablespoonsToTeaspoons = function(n){
	return 3 * n;
}

Convertor.teaspoonsToTablespoons = function(n){
	return .33 * n;
}

Convertor.percentTotalWeightFlour = function(recipe){
	var activeRecipe = Recipes[recipe];
	var flourWeight = 0;
	var totalWeight = 0;
	for (ingredient in activeRecipe){
		if (ingredient.match(/flour/))
			flourWeight += activeRecipe[ingredient];
		totalWeight += activeRecipe[ingredient];
	}	
	return flourWeight / totalWeight;
}

Convertor.isQtyNumeric = function (sQty) {
	var validChars = ".0123456789";
	var isNumber=true;
	var sChar;
	if (sQty.length == 0) return false;
	for (i = 0; i < sQty.length && isNumber == true; i++) { 
		sChar = sQty.charAt(i); 
		if (validChars.indexOf(sChar) == -1) {
	      isNumber = false;
		}
	}
	return isNumber;
}

Formatter.formatAsDecimal = function (n, places){
	if (places == 0)
		return Math.round(n);
	else
		return (Math.round(n * 100 * places)) / (100 * places);
}

Formatter.formatAsFraction = function (n){
	var whole = Math.floor(n);
	var partial = n - whole;
	var eighths = Math.floor(partial / .125);
	
	if (whole == 0) whole = '';
	
	if (eighths == 0 && whole == '')
		return "less than 1/8";
	else if (eighths == 0)
		return whole;
	else if (eighths % 4 == 0)
		return whole + " " + eighths / 4 + "/2";
	else if (eighths % 2 == 0)
		return whole + " " + eighths / 2 + "/4";		
	else
		return whole + " " + eighths + "/8";
}

Formatter.returnTableHeader = function (title){
	var head = "<table class=\"recipeTable\">";
	head     += "<tr><th colspan=\"5\">" + title + "</th></tr>";
	head     += "<tr><th>Ingredient</th><th>Metric</th><th>Imperial</th<th>&nbsp;</th><th>Baker's Percentage</th></tr>";
	return head;
}

Formatter.returnTableFooter = function (title){
	var output = '';
	if (document.getElementById('loaves').checked){
		var loafType = document.getElementById('loafType').value;
		var qty = document.getElementById('scale').value;
		output += Formatter.startRow();
		output += '<td colspan="5"><center><i>Makes ' + qty;
		if (qty == 1)
			output += ' ' + loafType.replace(/ves$/,'f').replace(/s$/,'');
		else
			output += ' ' + loafType;
		output += ' (' + Formatter.formatOuncesAsPoundsAndOunces(Convertor.poundsToOunces(Loaves[loafType]));
		output += ' / ' + Formatter.formatAsKilosOrGrams(Convertor.poundsToKilograms(Loaves[loafType])) + ' each)';
		output += '</i></center></td>';
		output += Formatter.endRow();		
	}
	output += "</table>";
	return output;
}


Formatter.returnIngredientName = function (title){
	return "<td width=\"200\">" + title + "</td>";
}

Formatter.returnBakersPercentages = function (value){
	return "<td>" + Formatter.formatAsDecimal((value * 100), 1) + "%</td>";
}

Formatter.formatAsKilosOrGrams = function(v){
	if (v < 1){
		v = Formatter.formatAsDecimal(v * 1000, 0);
		unit = 'g';
		
	} else {
		v = Formatter.formatAsDecimal(v,1);
		unit = 'kg';
	}
	return v + unit;
}

Formatter.formatOuncesAsPoundsAndOunces = function(v){
	if(Convertor.ouncesToPounds(v) >= 1){	
		var output = '';	
		output += Math.floor(v / 16) + " lb. ";
		if (Formatter.formatAsDecimal((v % 16),0) > 0)
		 	output +=  Formatter.formatAsDecimal((v % 16),0) + " oz.";
		return output;
	} else 
		return Formatter.formatAsFraction(v) + " oz.";
}

Formatter.formatAsCupsAndSpoons = function(v){
	if(v >= 1)		
		return Formatter.formatAsFraction(v) + " cups";
	else if (Convertor.cupsToTablespoons(v) > 4)
			return Formatter.formatAsFraction(v) + " cups";
    else if (Convertor.cupsToTablespoons(v) > 2)
		return Formatter.formatAsFraction(Convertor.cupsToTablespoons(v)) + " T";
	else if (Formatter.formatAsFraction(Convertor.cupsToTeaspoons(v)) == 3)
		return Formatter.formatAsFraction(Convertor.cupsToTablespoons(v)) + " T";	
	else
		return Formatter.formatAsFraction(Convertor.cupsToTeaspoons(v)) + " t";
}


Formatter.returnMetricWeight = function (v, scale){
	var value = v * scale;
	return "<td width=\"150\"	>" + Formatter.formatAsKilosOrGrams(value) + "</td>";
}

Formatter.returnImperialWeight = function (v, scale){
	var value = v * scale;
	value = Formatter.formatOuncesAsPoundsAndOunces(Formatter.formatAsDecimal(Convertor.kilogramsToOunces(value), 1));
	return "<td width=\"150\"	>" + value + "</td>";
}

Formatter.returnImperialMeasure = function (ingredient, v, scale){
	var value = v * scale;
	value = Convertor.ouncesToCups(Convertor.kilogramsToOunces(value), Ingredients[ingredient]);
	value = Formatter.formatAsCupsAndSpoons(value);
	return "<td width=\"150\"	>" + value + "</td>";
}

Formatter.startRow = function(){
	return "<tr>";
}

Formatter.endRow = function(){
	return "</tr>";
}

BreadTool.update = function(){
	var scale  = document.getElementById('scale').value;
	var recipe = document.getElementById('breadtype').value;

	if (document.getElementById('loaves').checked){
		document.getElementById('loafSpan').style.display = 'inline';	
		scale = Convertor.percentTotalWeightFlour(recipe) * scale * Convertor.poundsToKilograms(Convertor.loavesToPounds(document.getElementById('loafType').value));
	} else
		document.getElementById('loafSpan').style.display = 'none';
		
	if (document.getElementById('lbs').checked)
		scale = Convertor.poundsToKilograms(scale);
		
	BreadTool.scaleRecipe(recipe,scale);
}

BreadTool.scaleRecipe = function (recipe, scale){
	if (!Convertor.isQtyNumeric(scale)){
		alert('Scale Factor must be numeric value.  Decimal values are OK.');
		return false;
	}
	var output = '';
	var activeRecipe = Recipes[recipe];
	output += Formatter.returnTableHeader(recipe);
	for (attr in activeRecipe){
		var x = activeRecipe[attr];
		output +=  Formatter.startRow();
		output +=  Formatter.returnIngredientName(attr);
		output +=  Formatter.returnMetricWeight(x, scale);
		output +=  Formatter.returnImperialWeight(x, scale);	
		output +=  Formatter.returnImperialMeasure(attr, x, scale);	
		output +=  Formatter.returnBakersPercentages(x);
		output +=  Formatter.endRow();
	}	
	output += Formatter.returnTableFooter(recipe);
	
	
	document.getElementById('recipe').innerHTML = output;
}

// value is the multiplier (relative to the density of water)
var Ingredients = {
	"flour" 			: .5,
	"all-purpose flour" 		: .5,
	"all-purpose unbleached flour" 	: .5,
	"whole-wheat flour" 		: .6,
	"rye flour" 			: .6,	
	"bread flour" 			: .5,
	"salt"        			: .75,
	"milk"		  		: 1,
	"buttermilk"	  		: 1,
	"honey"		  		: 1,
	"oil"		  		: .9,
	"water"		  		: 1,
	"yeast"		  		: .66
	
};
 
var Loaves = {
	"Small loaves"				: 1,
	"Normal loaves"				: 1.5,
	"Large loaves"				: 2,
	"Small rolls"				: .1875,
	"Large rolls"				: .25
}


var Recipes = {
 	"Ciabatta" : {
		flour :  1,
		water : .73,
		salt  :	 .02,
		yeast : .011
	},
 	"Baguette" : {
		flour :  1,
		water : .66,
		salt  :	 .02,
		yeast : .011
	},
 	"French Bread" : {
		flour :  1,
		water : .60,
		salt  :	 .02,
		yeast : .02
	},
 	"Focaccia" : {
		flour :  1,
		water : .71,
		oil   : .13,
		salt  :	 .02,
		yeast : .01
	},	
 	"Honey Buttermilk Bread" : {
		"all-purpose unbleached flour"  : .85,
		"whole-wheat flour"		: .15,
		buttermilk 			: .615,
		honey  				: .09,
		salt  				: .0145,
		yeast 				: .0173
	},	

	
 	"Rustic Bread" : {
		"bread flour" :  .8,
		"rye flour" : .1,
		"whole-wheat flour" : .1,
		water : .69,
		salt  :	 .018,
		yeast : .006
	}	
};	

BreadTool.render = function(params){
	document.write('	Recipe: <select name="breadtype" id="breadtype" onChange="BreadTool.update();"><option value="">Choose one...</option>');
	for (var recipe in Recipes){
		document.write('<option value="' + recipe +'">' + recipe + '</option>');
	}
	document.write('</select> \
	&nbsp;&nbsp; \
		Scale/Quantity: <input name="scale" id="scale" value="1" size="3" onChange="BreadTool.update();"> \
	&nbsp;&nbsp; \
		Units: \
			<input type="radio" name="units" id="kgs" value="kg" onChange="BreadTool.update();" checked /> kgs \
			<input type="radio" name="units" id="lbs" value="lb" onChange="BreadTool.update();" /> lbs \
			<input type="radio" name="units" id="loaves" value="loaves" onChange="BreadTool.update();" /> loaves \
\
	<span id="loafSpan" style="display: none;"><select name="loafType" id="loafType" onChange="BreadTool.update();">');
	for (var loaf in Loaves){
		document.write('<option value="' + loaf +'">' + loaf + '</option>');
	}	
	document.write('</select></span> \
		<div id="recipe"> \
			<br /> \
			<br /> \
			<i>Please select a recipe from the menu above.</i> \
		</div>');

		
}

							

