/*
Issues:
	none known
*/

function jsTitleCalc()
{
	var _county;
	var _loanAmount;
	var _priorPolicyAmount;
	var _salesPrice;
	var _type;
	var _types;
	
	var _addCommas = function(nStr) {
		// From http://www.mredkj.com/javascript/numberFormat.html
		nStr += '';
		x = nStr.split('.');
		x1 = x[0];
		x2 = x.length > 1 ? '.' + x[1] : '';
		var rgx = /(\d+)(\d{3})/;
		while (rgx.test(x1)) {
			x1 = x1.replace(rgx, '$1' + ',' + '$2');
		}
		return x1 + x2;
	}
	
	var _displayAsMoney = function(number) {
		return _addCommas(number.toFixed(2));
	}
	
	var _policyChargeFromTable = function(chargeTable, amount) {
		var ret = 0;
		var chargable;
		
		for (var i = 0, il = chargeTable.length; i < il; i++) {
			// Ignore an amount less than the first min
			if (amount > chargeTable[i].min) {
				if (i + 1 < il) {
					// There is another entry in the table
					chargable = (amount > chargeTable[i+1].min) ? (chargeTable[i+1].min - chargeTable[i].min) : (amount - chargeTable[i].min);
				} else {
					// This is the last entry
					chargable = amount - chargeTable[i].min;
				}
				
				ret += chargeTable[i].rate * Math.ceil(chargable/1000);
			}
		}
		
		return ret;
	}
	
	var _policyChargeFromTableWithOffset = function(chargeTable, amount, offset) {
		var ret = 0;
		var chargable;
		
		// Round offset up to the nearest thousand
		offset = 1000 * Math.ceil(offset / 1000);
		
		if (amount <= offset) {
			alert("_policyChargeFromTableWithOffset: amount must be greater than offset");
			return;
		}
		
		// In-bracket charge
		//amount = 99000, offset = 97000
		//	chargable = 2000 @ >1k rate
		
		// Cross-bracket charge
		//amount = 105000, offset = 97000
		//	chargable = 3000 @ >1k rate
		//	chargable = 5000 @ >100k rate
		
		// Cross-multi-bracket charge
		//amount = 501000, offset = 97000
		//	chargable = 3000 @ >1k rate
		//	chargable = 400000 @ >100k rate
		//	chargable = 1000 @ >500k rate
		
		// Last-bracket
		//amount = 15100000, offset = 15040000
		//	chargable = 60000 @ >15000k rate
		
		// Skips early brackets, crosses into last bracket
		//amount = 15100000, offset = 14700000
		//	chargable = 300000 @ >10000k rate
		//	chargable = 100000 @ >15000k rate
		
		// Find the bracket the amount applies to
		for (var i = 0, il = chargeTable.length; i < il; i++) {
			chargable = 0;
			
			// Ignore amounts less than the first min
			if (amount > chargeTable[i].min) {
				if (i + 1 < il) {
					// There is another entry in the table
					
					// Skip entries with upper bounds smaller than offset
					if (chargeTable[i+1].min >= offset) {
						// See if amount passes into the next bracket
						if (amount > chargeTable[i+1].min) {
							// Amount goes into the next bracket, chargable is the upper bound - offset
							chargable = chargeTable[i+1].min - offset;
							
							// For the next bracket, the offset is the lower bound
							offset = chargeTable[i+1].min;
						} else {
							// Amount is within the upper bounds of this bracket, chargable is the amount - offset
							chargable = amount - offset;
						}
					}
				} else {
					// This is the last entry
					
					chargable = amount - (offset > chargeTable[i].min ? offset : chargeTable[i].min);
				}
			}
			
			// Avoid needless math
			if (chargable > 0) {
				ret += chargeTable[i].rate * Math.ceil(chargable/1000);
			}
		}
		
		return ret;
	}
	
	var _roundToMoney = function(number) {
		return Math.round(100 * number) / 100;
	}
	
	var _calcDavidson = function(result) {
		var policyCharge = 0;
		var priorPolicyDiscount = 0;
		var total;
		var chargable;
		
		// Charge table used in Davidson county
		var chargeTable = [
			{min:     1000, rate: 6},
			{min:   100000, rate: 4.5},
			{min:   500000, rate: 3},
			{min:  1000000, rate: 2},
			{min:  5000000, rate: 1.5},
			{min: 10000000, rate: 1.25},
			{min: 15000000, rate: 1}
		];
		
		// Eagle scale factor
		var eagleScaleFactor = 1;
		switch (_type) {
			case "eagle_loan_policy":
			case "eagle_owners_policy":
			case "eagle_simultaneous_issue":
				eagleScaleFactor = 1.1;
				break;
		}
		
		// Prior policy scale factor
		var priorPolicyScaleFactor = 0.3;
		
		// Base policy charge
		var basePolicyCharge = 125;
		
		switch (_type) {
			case "eagle_loan_policy":
			case "alta_loan_policy":
				policyCharge = eagleScaleFactor * (basePolicyCharge + _policyChargeFromTable(chargeTable, _loanAmount));
				policyCharge = _roundToMoney(policyCharge);
				
				if (_priorPolicyAmount) {
					var effectivePriorPolicyAmount = (_priorPolicyAmount > _loanAmount) ? _loanAmount : _priorPolicyAmount;
					priorPolicyDiscount = priorPolicyScaleFactor * eagleScaleFactor * (basePolicyCharge + _policyChargeFromTable(chargeTable, effectivePriorPolicyAmount));
					priorPolicyDiscount = _roundToMoney(priorPolicyDiscount);
				}
				
				total = policyCharge - priorPolicyDiscount;
				
				result.error = false;
				result.mode = "loan";
				result.policyCharge = _displayAsMoney(policyCharge);
				result.priorPolicyDiscount = _displayAsMoney(priorPolicyDiscount);
				result.total = _displayAsMoney(total);
				result.message = "Policy: " + _displayAsMoney(policyCharge);
				result.message += "\nPrior Policy Discount: " + _displayAsMoney(priorPolicyDiscount);
				result.message += "\nTotal: " + _displayAsMoney(total);
				break;
			
			case "alta_owners_policy":
			case "eagle_owners_policy":
				policyCharge = eagleScaleFactor * (basePolicyCharge + _policyChargeFromTable(chargeTable, _salesPrice));
				policyCharge = _roundToMoney(policyCharge);
				
				if (_priorPolicyAmount) {
					var effectivePriorPolicyAmount = (_priorPolicyAmount > _salesPrice) ? _salesPrice : _priorPolicyAmount;
					priorPolicyDiscount = priorPolicyScaleFactor * eagleScaleFactor * (basePolicyCharge + _policyChargeFromTable(chargeTable, effectivePriorPolicyAmount));
					priorPolicyDiscount = _roundToMoney(priorPolicyDiscount);
				}
				
				total = policyCharge - priorPolicyDiscount;
				
				result.error = false;
				result.mode = "owners";
				result.policyCharge = _displayAsMoney(policyCharge);
				result.priorPolicyDiscount = _displayAsMoney(priorPolicyDiscount);
				result.total = _displayAsMoney(total);
				result.message = "Policy: " + _displayAsMoney(policyCharge);
				result.message += "\nPrior Policy Discount: " + _displayAsMoney(priorPolicyDiscount);
				result.message += "\nTotal: " + _displayAsMoney(total);
				break;
				
			case "alta_simultaneous_issue":
			case "eagle_simultaneous_issue":
				// Get the largest of the two
				var amount = (_salesPrice > _loanAmount) ? _salesPrice : _loanAmount;
				
				// Geneate the simultaneous issue fee (35 for normal, 50 for eagle)
				var simultaneousFee = (eagleScaleFactor == 1) ? 35 : 50;
				
				policyCharge = simultaneousFee + eagleScaleFactor * (basePolicyCharge + _policyChargeFromTable(chargeTable, amount));
				policyCharge = _roundToMoney(policyCharge);
				
				if (_priorPolicyAmount) {
					var effectivePriorPolicyAmount = (_priorPolicyAmount > _salesPrice) ? _salesPrice : _priorPolicyAmount;
					priorPolicyDiscount = priorPolicyScaleFactor * eagleScaleFactor * (basePolicyCharge + _policyChargeFromTable(chargeTable, effectivePriorPolicyAmount));
					priorPolicyDiscount = _roundToMoney(priorPolicyDiscount);
				}
				
				total = _roundToMoney(policyCharge - priorPolicyDiscount);
				
				result.error = false;
				result.mode = "simultaneous";
				result.policyCharge = _displayAsMoney(policyCharge);
				result.policyChargeBreakdown = _displayAsMoney(policyCharge - simultaneousFee);
				result.simultaneousFee = _displayAsMoney(simultaneousFee);
				result.priorPolicyDiscount = _displayAsMoney(priorPolicyDiscount);
				result.total = _displayAsMoney(total);
				result.message = "Policy: " + _displayAsMoney(policyCharge) + " (" + _displayAsMoney(policyCharge - simultaneousFee) + " + " + _displayAsMoney(simultaneousFee) + ")";
				result.message += "\nPrior Policy Discount: " + _displayAsMoney(priorPolicyDiscount);
				result.message += "\nTotal: " + _displayAsMoney(total);
				break;
		}
	};
	
	var _calcHamilton = function(result) {
		var policyCharge = 0;
		var priorPolicyDiscount = 0;
		var total;
		var chargable;
		
		// Charge tables used in Hamilton county
		var chargeTableOwnerLeaseholder = [
			{min:     1000, rate: 6},
			{min:   100000, rate: 2.75},
			{min:  1000000, rate: 2},
			{min:  5000000, rate: 1.5},
			{min: 10000000, rate: 1.25},
			{min: 15000000, rate: 1}
		];
		var chargeTableLoan = [
			{min:     1000, rate: 5},
			{min:   100000, rate: 2.75},
			{min:  1000000, rate: 2},
			{min:  5000000, rate: 1.5},
			{min: 10000000, rate: 1.25},
			{min: 15000000, rate: 1}
		];
		
		// Eagle scale factor
		var eagleScaleFactor = 1;
		switch (_type) {
			case "eagle_loan_policy":
			case "eagle_owners_policy":
			case "eagle_simultaneous_issue":
				eagleScaleFactor = 1.1;
				break;
		}
		
		// Prior policy scale factor
		var priorPolicyScaleFactor = 0.3;
		
		// Base policy charge
		var basePolicyCharge = 125;
		
		switch (_type) {
			case "eagle_loan_policy":
			case "alta_loan_policy":
				policyCharge = eagleScaleFactor * (basePolicyCharge + _policyChargeFromTable(chargeTableLoan, _loanAmount));
				policyCharge = _roundToMoney(policyCharge);
				
				if (_priorPolicyAmount) {
					var effectivePriorPolicyAmount = (_priorPolicyAmount > _loanAmount) ? _loanAmount : _priorPolicyAmount;
					priorPolicyDiscount = priorPolicyScaleFactor * eagleScaleFactor * (basePolicyCharge + _policyChargeFromTable(chargeTableLoan, effectivePriorPolicyAmount));
					priorPolicyDiscount = _roundToMoney(priorPolicyDiscount);
				}
				
				total = _roundToMoney(policyCharge - priorPolicyDiscount);
				
				result.error = false;
				result.mode = "loan";
				result.policyCharge = _displayAsMoney(policyCharge);
				result.priorPolicyDiscount = _displayAsMoney(priorPolicyDiscount);
				result.total = _displayAsMoney(total);
				result.message = "Policy: " + _displayAsMoney(policyCharge);
				result.message += "\nPrior Policy Discount: " + _displayAsMoney(priorPolicyDiscount);
				result.message += "\nTotal: " + _displayAsMoney(total);
				break;
			
			case "alta_owners_policy":
			case "eagle_owners_policy":
				policyCharge = eagleScaleFactor * (basePolicyCharge + _policyChargeFromTable(chargeTableOwnerLeaseholder, _salesPrice));
				policyCharge = _roundToMoney(policyCharge);
				
				if (_priorPolicyAmount) {
					var effectivePriorPolicyAmount = (_priorPolicyAmount > _salesPrice) ? _salesPrice : _priorPolicyAmount;
					priorPolicyDiscount = priorPolicyScaleFactor * eagleScaleFactor * (basePolicyCharge + _policyChargeFromTable(chargeTableOwnerLeaseholder, effectivePriorPolicyAmount));
					priorPolicyDiscount = _roundToMoney(priorPolicyDiscount);
				}
				
				total = _roundToMoney(policyCharge - priorPolicyDiscount);
				
				result.error = false;
				result.mode = "owners";
				result.policyCharge = _displayAsMoney(policyCharge);
				result.priorPolicyDiscount = _displayAsMoney(priorPolicyDiscount);
				result.total = _displayAsMoney(total);
				result.message = "Policy: " + _displayAsMoney(policyCharge);
				result.message += "\nPrior Policy Discount: " + _displayAsMoney(priorPolicyDiscount);
				result.message += "\nTotal: " + _displayAsMoney(total);
				break;
				
			case "alta_simultaneous_issue":
			case "eagle_simultaneous_issue":
				var amount = _salesPrice;
				var table = chargeTableOwnerLeaseholder;
				
				// Geneate the simultaneous issue fee (35 for normal, 50 for eagle)
				var simultaneousFee = (eagleScaleFactor == 1) ? 35 : 50;
				
				var loanExceedsSalesPriceCharge = 0;
				if (_loanAmount > _salesPrice) {
					loanExceedsSalesPriceCharge = _policyChargeFromTableWithOffset(chargeTableLoan, _loanAmount, _salesPrice);
				}
				//alert("loanExceedsSalesPriceCharge = " + loanExceedsSalesPriceCharge);
				
				policyCharge = eagleScaleFactor * (basePolicyCharge + _policyChargeFromTable(table, amount) + loanExceedsSalesPriceCharge);
				policyCharge += simultaneousFee;
				policyCharge = _roundToMoney(policyCharge);
				
				if (_priorPolicyAmount) {
					var effectivePriorPolicyAmount = (_priorPolicyAmount > _salesPrice) ? _salesPrice : _priorPolicyAmount;
					priorPolicyDiscount = priorPolicyScaleFactor * eagleScaleFactor * (basePolicyCharge + _policyChargeFromTable(table, effectivePriorPolicyAmount));
					priorPolicyDiscount = _roundToMoney(priorPolicyDiscount);
				}
				
				/*
				// CONFIRM: Get the largest of the two and select the right table
				var amount = _loanAmount;
				var table = chargeTableLoan;
				if (_salesPrice > _loanAmount) {
					amount = _salesPrice;
					table = chargeTableOwnerLeaseholder;
				}
				table = chargeTableOwnerLeaseholder;
				
				// Geneate the simultaneous issue fee (35 for normal, 50 for eagle)
				var simultaneousFee = (eagleScaleFactor == 1) ? 35 : 50;
				
				policyCharge = simultaneousFee + eagleScaleFactor * (basePolicyCharge + _policyChargeFromTable(table, amount));
				policyCharge = _roundToMoney(policyCharge);
				
				if (_priorPolicyAmount) {
					priorPolicyDiscount = priorPolicyScaleFactor * eagleScaleFactor * (basePolicyCharge + _policyChargeFromTable(table, _priorPolicyAmount));
					priorPolicyDiscount = _roundToMoney(priorPolicyDiscount);
				}
				*/
				
				total = _roundToMoney(policyCharge - priorPolicyDiscount);
				
				result.error = false;
				result.mode = "simultaneous";
				result.policyCharge = _displayAsMoney(policyCharge);
				result.policyChargeBreakdown = _displayAsMoney(policyCharge - simultaneousFee);
				result.simultaneousFee = _displayAsMoney(simultaneousFee);
				result.priorPolicyDiscount = _displayAsMoney(priorPolicyDiscount);
				result.total = _displayAsMoney(total);
				result.message = "Policy: " + _displayAsMoney(policyCharge) + " (" + _displayAsMoney(policyCharge - simultaneousFee) + " + " + _displayAsMoney(simultaneousFee) + ")";
				result.message += "\nPrior Policy Discount: " + _displayAsMoney(priorPolicyDiscount);
				result.message += "\nTotal: " + _displayAsMoney(total);
				break;
		}
	};
	
	var _calcKnox = function(result) {
		var policyCharge = 0;
		var priorPolicyDiscount = 0;
		var total;
		var chargable;
		
		// Charge table used in Knox county
		var chargeTable = [
			{min:     1000, rate: 6},
			{min:   100000, rate: 2.75},
			{min:  1000000, rate: 2},
			{min:  5000000, rate: 1.5},
			{min: 10000000, rate: 1.25},
			{min: 15000000, rate: 1}
		];
		
		// Eagle scale factor
		var eagleScaleFactor = 1;
		switch (_type) {
			case "eagle_loan_policy":
			case "eagle_owners_policy":
			case "eagle_simultaneous_issue":
				eagleScaleFactor = 1.1;
				break;
		}
		
		// Prior policy scale factor
		var priorPolicyScaleFactor = 0.3;
		
		// Base policy charge
		var basePolicyCharge = 125;
		
		switch (_type) {
			case "eagle_loan_policy":
			case "alta_loan_policy":
				policyCharge = eagleScaleFactor * (basePolicyCharge + _policyChargeFromTable(chargeTable, _loanAmount));
				policyCharge = _roundToMoney(policyCharge);
				
				if (_priorPolicyAmount) {
					var effectivePriorPolicyAmount = (_priorPolicyAmount > _loanAmount) ? _loanAmount : _priorPolicyAmount;
					priorPolicyDiscount = priorPolicyScaleFactor * eagleScaleFactor * (basePolicyCharge + _policyChargeFromTable(chargeTable, effectivePriorPolicyAmount));
					priorPolicyDiscount = _roundToMoney(priorPolicyDiscount);
				}
				
				total = _roundToMoney(policyCharge - priorPolicyDiscount);
				
				result.error = false;
				result.mode = "loan";
				result.policyCharge = _displayAsMoney(policyCharge);
				result.priorPolicyDiscount = _displayAsMoney(priorPolicyDiscount);
				result.total = _displayAsMoney(total);
				result.message = "Policy: " + policyCharge;
				result.message += "\nPrior Policy Discount: " + priorPolicyDiscount;
				result.message += "\nTotal: " + total;
				break;
			
			case "alta_owners_policy":
			case "eagle_owners_policy":
				policyCharge = eagleScaleFactor * (basePolicyCharge + _policyChargeFromTable(chargeTable, _salesPrice));
				policyCharge = _roundToMoney(policyCharge);
				
				if (_priorPolicyAmount) {
					var effectivePriorPolicyAmount = (_priorPolicyAmount > _salesPrice) ? _salesPrice : _priorPolicyAmount;
					priorPolicyDiscount = priorPolicyScaleFactor * eagleScaleFactor * (basePolicyCharge + _policyChargeFromTable(chargeTable, effectivePriorPolicyAmount));
					priorPolicyDiscount = _roundToMoney(priorPolicyDiscount);
				}
				
				total = _roundToMoney(policyCharge - priorPolicyDiscount);
				
				result.error = false;
				result.mode = "owners";
				result.policyCharge = _displayAsMoney(policyCharge);
				result.priorPolicyDiscount = _displayAsMoney(priorPolicyDiscount);
				result.total = _displayAsMoney(total);
				result.message = "Policy: " + _displayAsMoney(policyCharge);
				result.message += "\nPrior Policy Discount: " + _displayAsMoney(priorPolicyDiscount);
				result.message += "\nTotal: " + _displayAsMoney(total);
				break;
				
			case "alta_simultaneous_issue":
			case "eagle_simultaneous_issue":
				// Get the largest of the two
				var amount = (_salesPrice > _loanAmount) ? _salesPrice : _loanAmount;
				
				// Geneate the simultaneous issue fee (35 for normal, 50 for eagle)
				var simultaneousFee = (eagleScaleFactor == 1) ? 35 : 50;
				
				policyCharge = simultaneousFee + eagleScaleFactor * (basePolicyCharge + _policyChargeFromTable(chargeTable, amount));
				policyCharge = _roundToMoney(policyCharge);
				
				if (_priorPolicyAmount) {
					var effectivePriorPolicyAmount = (_priorPolicyAmount > _salesPrice) ? _salesPrice : _priorPolicyAmount;
					priorPolicyDiscount = priorPolicyScaleFactor * eagleScaleFactor * (basePolicyCharge + _policyChargeFromTable(chargeTable, effectivePriorPolicyAmount));
					priorPolicyDiscount = _roundToMoney(priorPolicyDiscount);
				}
				
				total = _roundToMoney(policyCharge - priorPolicyDiscount);
				
				result.error = false;
				result.mode = "simultaneous";
				result.policyCharge = _displayAsMoney(policyCharge);
				result.policyChargeBreakdown = _displayAsMoney(policyCharge - simultaneousFee);
				result.simultaneousFee = _displayAsMoney(simultaneousFee);
				result.priorPolicyDiscount = _displayAsMoney(priorPolicyDiscount);
				result.total = _displayAsMoney(total);
				result.message = "Policy: " + _displayAsMoney(policyCharge) + " (" + _displayAsMoney(policyCharge - simultaneousFee) + " + " + _displayAsMoney(simultaneousFee) + ")";
				result.message += "\nPrior Policy Discount: " + _displayAsMoney(priorPolicyDiscount);
				result.message += "\nTotal: " + _displayAsMoney(total);
				break;
		}
	};
	
	var _calcShelby = function(result) {
		var policyCharge = 0;
		var priorPolicyDiscount = 0;
		var total;
		var chargable;
		
		// Charge table used in Knox county
		var chargeTable = [
			{min:    1000, rate: 3.5},
			{min:  100000, rate: 3},
			{min: 1000000, rate: 1}
		];
		
		// Eagle scale factor
		var eagleScaleFactor = 1;
		switch (_type) {
			case "eagle_loan_policy":
			case "eagle_owners_policy":
			case "eagle_simultaneous_issue":
				eagleScaleFactor = 1.1;
				break;
		}
		
		// Prior policy scale factor
		var priorPolicyScaleFactor = 0.3;
		
		// Base policy charge
		var basePolicyCharge = 100;
		
		switch (_type) {
			case "eagle_loan_policy":
			case "alta_loan_policy":
				policyCharge = eagleScaleFactor * (basePolicyCharge + _policyChargeFromTable(chargeTable, _loanAmount));
				policyCharge = _roundToMoney(policyCharge);
				
				if (_priorPolicyAmount) {
					var effectivePriorPolicyAmount = (_priorPolicyAmount > _loanAmount) ? _loanAmount : _priorPolicyAmount;
					priorPolicyDiscount = priorPolicyScaleFactor * eagleScaleFactor * (basePolicyCharge + _policyChargeFromTable(chargeTable, effectivePriorPolicyAmount));
					priorPolicyDiscount = _roundToMoney(priorPolicyDiscount);
				}
				
				total = _roundToMoney(policyCharge - priorPolicyDiscount);
				
				result.error = false;
				result.mode = "loan";
				result.policyCharge = _displayAsMoney(policyCharge);
				result.priorPolicyDiscount = _displayAsMoney(priorPolicyDiscount);
				result.total = _displayAsMoney(total);
				result.message = "Policy: " + _displayAsMoney(policyCharge);
				result.message += "\nPrior Policy Discount: " + _displayAsMoney(priorPolicyDiscount);
				result.message += "\nTotal: " + _displayAsMoney(total);
				break;
			
			case "alta_owners_policy":
			case "eagle_owners_policy":
				policyCharge = eagleScaleFactor * (basePolicyCharge + _policyChargeFromTable(chargeTable, _salesPrice));
				policyCharge = _roundToMoney(policyCharge);
				
				if (_priorPolicyAmount) {
					var effectivePriorPolicyAmount = (_priorPolicyAmount > _salesPrice) ? _salesPrice : _priorPolicyAmount;
					priorPolicyDiscount = priorPolicyScaleFactor * eagleScaleFactor * (basePolicyCharge + _policyChargeFromTable(chargeTable, effectivePriorPolicyAmount));
					priorPolicyDiscount = _roundToMoney(priorPolicyDiscount);
				}
				
				total = _roundToMoney(policyCharge - priorPolicyDiscount);
				
				result.error = false;
				result.mode = "owners";
				result.policyCharge = _displayAsMoney(policyCharge);
				result.priorPolicyDiscount = _displayAsMoney(priorPolicyDiscount);
				result.total = _displayAsMoney(total);
				result.message = "Policy: " + _displayAsMoney(policyCharge);
				result.message += "\nPrior Policy Discount: " + _displayAsMoney(priorPolicyDiscount);
				result.message += "\nTotal: " + _displayAsMoney(total);
				break;
				
			case "alta_simultaneous_issue":
			case "eagle_simultaneous_issue":
				// Get the largest of the two
				var amount = (_salesPrice > _loanAmount) ? _salesPrice : _loanAmount;
				
				// Geneate the simultaneous issue fee (35 for normal, 50 for eagle)
				var simultaneousFee = (eagleScaleFactor == 1) ? 35 : 50;
				
				policyCharge = simultaneousFee + eagleScaleFactor * (basePolicyCharge + _policyChargeFromTable(chargeTable, amount));
				
				if (_priorPolicyAmount) {
					priorPolicyDiscount = priorPolicyScaleFactor * eagleScaleFactor * (basePolicyCharge + _policyChargeFromTable(chargeTable, _priorPolicyAmount));
				}
				
				total = _roundToMoney(policyCharge - priorPolicyDiscount);
				
				result.error = false;
				result.mode = "simultaneous";
				result.policyCharge = _displayAsMoney(policyCharge);
				result.policyChargeBreakdown = _displayAsMoney(policyCharge - simultaneousFee);
				result.simultaneousFee = _displayAsMoney(simultaneousFee);
				result.priorPolicyDiscount = _displayAsMoney(priorPolicyDiscount);
				result.total = _displayAsMoney(total);
				result.message = "Policy: " + _displayAsMoney(policyCharge) + " (" + _displayAsMoney(policyCharge - simultaneousFee) + " + " + _displayAsMoney(simultaneousFee) + ")";
				result.message += "\nPrior Policy Discount: " + _displayAsMoney(priorPolicyDiscount);
				result.message += "\nTotal: " + _displayAsMoney(total);
				break;
		}
	};
	
	var _calcDefault = function(result) {
		var policyCharge = 0;
		var priorPolicyDiscount = 0;
		var total;
		var chargable;
		
		// Charge tables used in all other counties
		var chargeTableOwnerLeaseholder = [
			{min:        0, rate: 4},
			{min:    50000, rate: 3.5},
			{min:   100000, rate: 2.5},
			{min:  1000000, rate: 2},
			{min:  5000000, rate: 1.5},
			{min: 10000000, rate: 1.25},
			{min: 15000000, rate: 1}
		];
		var chargeTableLoan = [
			{min:        0, rate: 3},
			{min:    50000, rate: 2.5},
			{min:   100000, rate: 2},
			{min:  1000000, rate: 1.5},
			{min: 10000000, rate: 1.25},
			{min: 15000000, rate: 1}
		];
		
		var minimumPremium = 50;
		
		// Eagle scale factor
		var eagleScaleFactor = 1;
		switch (_type) {
			case "eagle_loan_policy":
			case "eagle_owners_policy":
			case "eagle_simultaneous_issue":
				eagleScaleFactor = 1.1;
				break;
		}
		
		// Prior policy scale factor
		var priorPolicyScaleFactor = 0.3;
		
		// Base policy charge
		var basePolicyCharge = 0;
		
		switch (_type) {
			case "eagle_loan_policy":
			case "alta_loan_policy":
				policyCharge = eagleScaleFactor * (basePolicyCharge + _policyChargeFromTable(chargeTableLoan, _loanAmount));
				if (policyCharge < minimumPremium) {
					policyCharge = minimumPremium;
				}
				policyCharge = _roundToMoney(policyCharge);
				
				if (_priorPolicyAmount) {
					var effectivePriorPolicyAmount = (_priorPolicyAmount > _loanAmount) ? _loanAmount : _priorPolicyAmount;
					priorPolicyDiscount = basePolicyCharge + _policyChargeFromTable(chargeTableLoan, effectivePriorPolicyAmount);
					if (priorPolicyDiscount < minimumPremium) {
						priorPolicyDiscount = minimumPremium;
					}
					priorPolicyDiscount *= priorPolicyScaleFactor * eagleScaleFactor;
					priorPolicyDiscount = _roundToMoney(priorPolicyDiscount);
				}
				
				total = _roundToMoney(policyCharge - priorPolicyDiscount);
				
				result.error = false;
				result.mode = "loan";
				result.policyCharge = _displayAsMoney(policyCharge);
				result.priorPolicyDiscount = _displayAsMoney(priorPolicyDiscount);
				result.total = _displayAsMoney(total);
				result.message = "Policy: " + _displayAsMoney(policyCharge);
				result.message += "\nPrior Policy Discount: " + _displayAsMoney(priorPolicyDiscount);
				result.message += "\nTotal: " + _displayAsMoney(total);
				break;
			
			case "alta_owners_policy":
			case "eagle_owners_policy":
				policyCharge = eagleScaleFactor * (basePolicyCharge + _policyChargeFromTable(chargeTableOwnerLeaseholder, _salesPrice));
				if (policyCharge < minimumPremium) {
					policyCharge = minimumPremium;
				}
				policyCharge = _roundToMoney(policyCharge);
				
				if (_priorPolicyAmount) {
					var effectivePriorPolicyAmount = (_priorPolicyAmount > _salesPrice) ? _salesPrice : _priorPolicyAmount;
					priorPolicyDiscount = basePolicyCharge + _policyChargeFromTable(chargeTableOwnerLeaseholder, effectivePriorPolicyAmount);
					if (priorPolicyDiscount < minimumPremium) {
						priorPolicyDiscount = minimumPremium;
					}
					priorPolicyDiscount *= priorPolicyScaleFactor * eagleScaleFactor;
					priorPolicyDiscount = _roundToMoney(priorPolicyDiscount);
				}
				
				total = _roundToMoney(policyCharge - priorPolicyDiscount);
				
				result.error = false;
				result.mode = "owners";
				result.policyCharge = _displayAsMoney(policyCharge);
				result.priorPolicyDiscount = _displayAsMoney(priorPolicyDiscount);
				result.total = _displayAsMoney(total);
				result.message = "Policy: " + _displayAsMoney(policyCharge);
				result.message += "\nPrior Policy Discount: " + _displayAsMoney(priorPolicyDiscount);
				result.message += "\nTotal: " + _displayAsMoney(total);
				break;
				
			case "alta_simultaneous_issue":
			case "eagle_simultaneous_issue":
				var amount = _salesPrice;
				var table = chargeTableOwnerLeaseholder;
				
				// Geneate the simultaneous issue fee (35 for normal, 50 for eagle)
				var simultaneousFee = (eagleScaleFactor == 1) ? 35 : 50;
				
				var loanExceedsSalesPriceCharge = 0;
				if (_loanAmount > _salesPrice) {
					loanExceedsSalesPriceCharge = _policyChargeFromTableWithOffset(chargeTableLoan, _loanAmount, _salesPrice);
				}
				//alert("loanExceedsSalesPriceCharge = " + loanExceedsSalesPriceCharge);
				
				policyCharge = eagleScaleFactor * (basePolicyCharge + _policyChargeFromTable(table, amount) + loanExceedsSalesPriceCharge);
				if (policyCharge < minimumPremium) {
					policyCharge = minimumPremium;
				}
				policyCharge += simultaneousFee;
				
				if (_priorPolicyAmount) {
					var effectivePriorPolicyAmount = (_priorPolicyAmount > _salesPrice) ? _salesPrice : _priorPolicyAmount;
					priorPolicyDiscount = basePolicyCharge + _policyChargeFromTable(table, effectivePriorPolicyAmount);
					if (priorPolicyDiscount < minimumPremium) {
						priorPolicyDiscount = minimumPremium;
					}
					priorPolicyDiscount *= priorPolicyScaleFactor * eagleScaleFactor;
				}
				
				total = _roundToMoney(policyCharge - priorPolicyDiscount);
				
				result.error = false;
				result.mode = "simultaneous";
				result.policyCharge = _displayAsMoney(policyCharge);
				result.policyChargeBreakdown = _displayAsMoney(policyCharge - simultaneousFee);
				result.simultaneousFee = _displayAsMoney(simultaneousFee);
				result.priorPolicyDiscount = _displayAsMoney(priorPolicyDiscount);
				result.total = _displayAsMoney(total);
				result.message = "Policy: " + _displayAsMoney(policyCharge) + " (" + _displayAsMoney(policyCharge - simultaneousFee) + " + " + _displayAsMoney(simultaneousFee) + ")";
				result.message += "\nPrior Policy Discount: " + _displayAsMoney(priorPolicyDiscount);
				result.message += "\nTotal: " + _displayAsMoney(total);
				break;
		}
	};
	
	this.calculate = function() {
		var result = {
			error: true,
			message: "Unknown error"
		};
		
		if (_type) {
			switch (_county) {
				case "davidson":
					_calcDavidson(result);
					break;
					
				case "hamilton":
					_calcHamilton(result);
					break;
					
				case "knox":
					_calcKnox(result);
					break;
					
				case "shelby":
					_calcShelby(result);
					break;
					
				default:
					_calcDefault(result);
			}
			
			//result.error = false;
			//result.message = "Done";
		} else {
			result.message = "No policy/issue type selected.";
		}
		
		return result;
	};
	
	this.debug = function() {
		alert("Hello");
	};
	
	this.setCounty = function(newValue) {
		_county = newValue ? newValue : "";
		//alert("_county: " + _county);
	};
	
	this.setLoanAmount = function(newValue) {
		_loanAmount = newValue ? (newValue * 1.0) : 0;
		//alert("_loanAmount: " + _loanAmount);
	};
	
	this.setPriorPolicyAmount = function(newValue) {
		_priorPolicyAmount = newValue ? (newValue * 1.0) : 0;
		//alert("_priorPolicyAmount: " + _priorPolicyAmount);
	};
	
	this.setSalesPrice = function(newValue) {
		_salesPrice = newValue ? (newValue * 1.0) : 0;
		//alert("_salesPrice: " + _salesPrice);
	};
	
	this.setType = function(newValue) {
		_type = (_types.indexOf(newValue) >= 0) ? newValue : "";
		//alert("_type: " + _type);
	};
	
	// Init
	_salesPrice = 0;
	_loanAmount = 0;
	_priorPolicyAmount = 0;
	_type = "";
	_types = $([
		"alta_loan_policy",
		"alta_owners_policy",
		"alta_simultaneous_issue",
		"eagle_loan_policy",
		"eagle_owners_policy",
		"eagle_simultaneous_issue"
	]);
	_county = "";
}

if (typeof Prototype != "undefined") {
	document.observe("dom:loaded", function() {
		function getFieldValue(objForm, strFieldName)
		{
			var ret = "";
			
			if (objForm && strFieldName) {
				if (objForm.elements[strFieldName]) {
					var objField = objForm.elements[strFieldName];
					//alert("strFieldName = " + strFieldName + ", objForm.elements[strFieldName] = " + objField);
					
					// Radio buttons, apparently?
					if (objField.length && !objField.options) {
						//alert("objField.length = " + objField.length);
						for (var i = 0; i < objField.length; i++) {
							//alert("objField[i] = " + objField[i]);
							if (objField[i].checked) {
								ret = objField[i].value;
								break;
							}
						}
					} else {
						// Select
						if (objField.options) {
							ret = objField.options[objField.selectedIndex].value;
						} else {
							// Input/Textarea
							//alert(objField.value);
							ret = objField.value;
						}
					}
				}
			}
			
			return ret;
		}
		
		function getFieldNumber(objForm, strFieldName)
		{
			var ret = 0;
			
			var val = getFieldValue(objForm, strFieldName);
			if (val) {
				// Remove commas (and by way of this, digit grouping)
				val = val.replace(",", "");
				
				// Pull a dollars-and-cents-format floating point number out of the value
				var matches = val.match(/\d+(.\d{1,2})?/);
				//alert("matches: " + matches);
				if (matches) {
					return (matches[0] * 1.0);
				}
			}
			
			return ret;
		}
		
		$$("form.jsTitleCalc").each(function(item) {
			var calcButton = item.select("input.calculate").first();
			if (calcButton) {
				item.calc = new jsTitleCalc();
				
				calcButton.observe("click", function() {
					item.calc.setCounty(getFieldValue(item, "county"));
					//alert("County = " + getFieldValue(item, "county"));
					
					item.calc.setLoanAmount(getFieldNumber(item, "loan_amount"));
					//alert("Loan Amount = " + getFieldNumber(item, "loan_amount"));
					
					item.calc.setPriorPolicyAmount(getFieldNumber(item, "prior_policy_amount"));
					//alert("Prior Policy Amount = " + getFieldNumber(item, "prior_policy_amount"));
					
					item.calc.setSalesPrice(getFieldNumber(item, "sales_price"));
					//alert("Sales Price = " + getFieldNumber(item, "sales_price"));
					
					item.calc.setType(getFieldValue(item, "policy_type"));
					//alert("Policy/Issue Type = " + getFieldValue(item, "policy_type"));
					
					var result = item.calc.calculate();
					if (result.error) {
						alert("Error: " + result.message);
					} else {
						//alert("Success: " + result.message);
						var resultContainer = $("calc_result");
						if (resultContainer) {
							while (resultContainer.firstChild) {
								resultContainer.removeChild(resultContainer.firstChild);
							}
							//resultContainer.appendChild(document.createTextNode(result.message));
							
							switch (result.mode) {
								case "loan":
									resultContainer.appendChild(document.createTextNode("Policy Charge: " + result.policyCharge));
									resultContainer.appendChild(document.createElement("br"));
									if (parseFloat(result.priorPolicyDiscount)) {
										resultContainer.appendChild(document.createTextNode("Prior Policy Discount: " + result.priorPolicyDiscount));
										resultContainer.appendChild(document.createElement("br"));
									}
									resultContainer.appendChild(document.createTextNode("Total: " + result.total));
									break;
									
								case "owners":
									resultContainer.appendChild(document.createTextNode("Policy Charge: " + result.policyCharge));
									resultContainer.appendChild(document.createElement("br"));
									if (parseFloat(result.priorPolicyDiscount)) {
										resultContainer.appendChild(document.createTextNode("Prior Policy Discount: " + result.priorPolicyDiscount));
										resultContainer.appendChild(document.createElement("br"));
									}
									resultContainer.appendChild(document.createTextNode("Total: " + result.total));
									break;
									
								case "simultaneous":
									resultContainer.appendChild(document.createTextNode("Policy Charge: " + result.policyCharge));
									resultContainer.appendChild(document.createElement("br"));
									if (parseFloat(result.priorPolicyDiscount)) {
										resultContainer.appendChild(document.createTextNode("Prior Policy Discount: " + result.priorPolicyDiscount));
										resultContainer.appendChild(document.createElement("br"));
									}
									resultContainer.appendChild(document.createTextNode("Total: " + result.total));
									break;
									
							}
						}
					}
					
					//item.calc.debug();
				});
			}
		});
	});
}

