/*
 *
 * Dependencies:
 *	jquery-1.4.js
 *	microtemplating
 *	jquery.ba-serializeobject.min.js
 *
 */
(function($){

	$.fn.cwsMortgageCalculator = function(options) {
		
		$.fn.cwsMortgageCalculator.defaults = {
			debug: false,
			presets:{
					price		: ["0", "currency"],
					lotprice    : ["$0", "currency"],	
					percentdown : ["0%", "percent"],
					rate        : ["0%", "percent"],
					taxes       : ["$0", "currency"],
					insurance   : ["$0", "currency"],
					term        : ["30", "number"]
			},
			templates:{
				results: ['#cwsMortgageCalculatorResults', '#cwsMortgageCalculatorResultsTemplate']
			},
			btnReset: "#btn_reset",
			btnCalculate: "#btn_calculate"
		};
		
		var options = $.extend($.fn.cwsMortgageCalculator.defaults, options);

		var $self, data;
				
		function getValue(theString){
			var noJunk = "";
			var withDollar = "";
			var foundDecimal = 0;
			var foundAlphaChar = 0;
			
			theString += "";
			for (i=0; i <= theString.length; i++) {
				var thisChar = theString.substring(i, i+1);
				
				if (thisChar == ".") {
					foundDecimal = 1;
					noJunk = noJunk + thisChar;
				}
				
				if ((thisChar < "0") || (thisChar > "9")) {
					if ((thisChar != "$") && (thisChar !=".") && (thisChar != ",") && (thisChar != " ") && (thisChar !="")) foundAlphaChar = 1;
				} else {
					withDollar = withDollar + thisChar
					noJunk = noJunk + thisChar
				}
				
				if ((thisChar == "$") || (thisChar == ".") || (thisChar == ",")) {
					withDollar = withDollar + thisChar
				}
			}
			
			if (foundDecimal) { 
				return parseFloat(noJunk); 
			} else if (noJunk.length > 0) { 
				return parseInt(noJunk); 
			} else {
				return 0;
			}
		}
		
		function formatUSCurrency(theNumber) {
		  var isNegative = 0
		  if (theNumber != "") {
		
			var workingNumber = theNumber + "" // Evaluate to a string
		
			if (workingNumber.charAt(0) == "-") {
			  isNegative = 1;
			  workingNumber = workingNumber.substring(1, workingNumber.length)
			}
		
			var withoutChars = ""
			for (x=0; x<=((workingNumber.length)-1); x++) {
			  thisChar = workingNumber.charAt(x)
			  charAsNum = parseInt(thisChar)
			  if ( ((thisChar >= "0") & (thisChar <= "9")) || (thisChar == ".")  ) {
			withoutChars += workingNumber.charAt(x)
			  }
			}
			workingNumber = withoutChars
			decimalPoint = workingNumber.indexOf(".")
		
			if (decimalPoint == -1) {
			  dollarValue = workingNumber
			  centsValue = "00"
			  } else if (decimalPoint == 0) {
			  dollarValue = "0"
			  centsValue = workingNumber.substring(decimalPoint + 1, workingNumber.length)
			} else {
				dollarValue = workingNumber.substring(0, decimalPoint)
				if (decimalPoint == (workingNumber.length - 1)) {
			  centsValue = "00";
				} else {
				  centsValue = getValue(workingNumber.substring(decimalPoint + 1, workingNumber.length));
				  centsValue += "0";
				  centsValue = centsValue.charAt(0) + centsValue.charAt(1)
				}
			}
		
			var theString = dollarValue;
			var totalCommas = Math.floor((theString.length - 1) / 3)
		
			var dollarAmt = ""
			x=dollarValue.length
			position = 0
			while (x > 0) {
			x = x - 1
				thisChar = dollarValue.charAt(x)
			rounded = Math.round(position/3)
			if ( (position/3 == rounded ) & (position != 0) ) {
				   dollarAmt = "," + dollarAmt
			}
				dollarAmt = thisChar +  dollarAmt
			position = position + 1
			}
		
			if (isNegative) {
			  theString = "$" + dollarAmt + "." + centsValue
			  //theString = "($" + dollarAmt + "." + centsValue + ")"
			} else {
			  theString = "$" + dollarAmt + "." + centsValue
			}
			return (theString);
		  } else {
			return("$0.00");
		  }
		}
		
		function formatPercent(theNumber,decimalPlaces) {
		  theNumber = getValue(theNumber);
		  if (theNumber < 1) { theNumber = theNumber * 100; }
		  with (Math) theNumber = (round(theNumber * pow(10,decimalPlaces))) / pow(10,decimalPlaces);
		  return(theNumber + "%");
		}
		
		function formatPercentpts(theNumber,decimalPlaces) {
		  theNumber = getValue(theNumber);
		  with (Math) theNumber = (round(theNumber * pow(10,decimalPlaces))) / pow(10,decimalPlaces);
		  return(theNumber + "%");
		}
		
		function removeCents(theNumber) {
		  var isNegative = 0
		
		  if (theNumber != "") {
		
			var workingNumber = theNumber + "" // Evaluate to a string
		
			if (workingNumber.charAt(0) == "-") {
			  isNegative = 1;
			  workingNumber = workingNumber.substring(1, workingNumber.length)
			}
		
			theNumber = getValue(workingNumber)
		
			theNumber = Math.round(theNumber * 100) / 100;
			theNumber = theNumber + ""
			decimalPoint = theNumber.indexOf(".")
		
			if (decimalPoint == -1) {
			  dollarValue = theNumber
			} else if (decimalPoint == 0) {
			  dollarValue = 0
			} else {
			  dollarValue = theNumber.substring(0, decimalPoint)
			}
		
			var dollarAmt = ""
			x=dollarValue.length
			position = 0
			while (x > 0) {
			x = x - 1
				thisChar = dollarValue.charAt(x)
			rounded = Math.round(position/3)
			if ( (position/3 == rounded ) & (position != 0) ) {
				   dollarAmt = "," + dollarAmt
			}
				dollarAmt = thisChar +  dollarAmt
			position = position + 1
			}
		
			if (isNegative == 1) {
			  theString = "-$" + dollarAmt
			  //theString = "($" + dollarAmt + "." + centsValue + ")"
			} else {
			  theString = "$" + dollarAmt
			}
		
			dollarValue = "$" + dollarAmt
			return(theString)
		  } else {
			return("$0")
		  }
		}
		
		function monthlyPayment(term, rate, loanAmount) {
			if (rate > 1) { (rate = rate / 100); }
			rateMonthly = (rate / 12);
			
			totalPayments = (term * 12);
			if (rate == 0) {
				payment = (loanAmount / totalPayments)
			} else {
				payment = (loanAmount * rateMonthly) / (1 - Math.pow((1+rateMonthly), (-1*totalPayments)) )
			}
			return(payment)
		}
		
		function figureLoanAPR (loanYears, iRateAnnual, loanAmount, monthly) {
			loanMonths = loanYears * 12;
			if (iRateAnnual > 1) { (iRateAnnual = iRateAnnual / 100); }
			iRateMonthly = iRateAnnual / 12;
			
			prepaidFinanceCharges = Math.round(((.01 * loanAmount) + 375 + (((loanAmount * iRateAnnual) / 365) * 30)) * 100) / 100;
			
			aprPrinciple = Math.round((loanAmount - prepaidFinanceCharges) * 100) / 100;
			compoundX = Math.pow( (1 + iRateMonthly) , (-1 * loanMonths) );
			
			loanAPR = ((monthly * (1 - (compoundX) )) / aprPrinciple) * 12 * 100;
			loanAPR = Math.round(loanAPR * 1000) / 1000;
			return(loanAPR);
		}
		
		function calculate(evt) {
			if(evt){
				var $target = $(evt.target);
				var targetId = $target.attr('id');
				var targetVal = $target.val();				
				$.each(options.presets,function(key,value) {						
					if(key == targetId){
						switch(value[1]){
							case 'currency':
								$target.val(formatUSCurrency(targetVal));
								break;
							case 'percent':
								$target.val(formatPercent(targetVal, 2));
								break;
							case 'number':
								break;
							default:
								$target.val(formatUSCurrency(targetVal));
						}
					}
				});
			}
			
			var userdata    = $("#"+$self.attr('id') + " :input").serializeObject();
			var price       = getValue(userdata.price);
			var lotprice    = getValue(userdata.lotprice);	
			var percentdown = getValue(userdata.percentdown);
			var rate        = getValue(userdata.rate);
			var taxes       = getValue(userdata.taxes);
			var insurance   = getValue(userdata.insurance);
			var term        = getValue(userdata.term);	
			
			var mortgage;
			var results = null;
			var error = null;			
			var cost = '';
			var downpayment = '';
			var mortgage = '';
			var downpayment = '';
			var closingCosts = '';
			var prePaids = '';
			var reserves = '';
			var totalCash = '';
			var payment = '';
			var monthlyTAX = '';
			var monthlyMI = '';
			var PITI = '';
			
			// Check Error Class
			if (percentdown > 100) {
				$('#percentdown').addClass('error');
			}else{
				$('#percentdown').removeClass('error');
			}
			if(price == 0){
				$('#price').addClass('error');
			}else{
				$('#price').removeClass('error');
			}
			if(rate == 0){
				$('#rate').addClass('error');
			}else{
				$('#rate').removeClass('error');
			}
							
			if (percentdown > 100) {
					error = 'Your down payment should never exceed 100%.'
					error += 'You have entered a down payment of ' + percentdown + '%.'					
			} else if ( (price == 0) || (rate == 0) ) {
					error = 'Sorry...Some important information is missing from your form.'
					error += 'Please fill-in all necessary fields, and click "Calculate" again.';
			} else {

				if (percentdown < 100) {
					downpayment = (percentdown * price)/100
				} else {
					downpayment = percentdown
				}

				//// MORTGAGE AND percentdown AMOUNTS
				
				ratioDown = downpayment/price * 100
				
				if (term >= 25) {
					if (ratioDown >= 20) {
						MIfactor = 0
					} else if (ratioDown >= 15) {
						MIfactor = .39
					} else if (ratioDown >= 10) {
						MIfactor = .52
					} else if (ratioDown >= 5) {
						MIfactor = .78
					} else {
						MIfactor = 1.04
					}
				} else if (term == 20) {
					if (ratioDown >= 20) {
						MIfactor = 0
					} else if (ratioDown >= 15) {
						MIfactor = .21
					} else if (ratioDown >= 10) {
						MIfactor = .41
					} else if (ratioDown >= 5) {
						MIfactor = .67
					} else {
						MIfactor = .79
					}
				} else {
					if (ratioDown >= 20) {
						MIfactor = 0
					} else if (ratioDown >= 15) {
						MIfactor = .21
					} else if (ratioDown >= 10) {
						MIfactor = .41
					} else if (ratioDown >= 5) {
						MIfactor = .67
					} else {
						MIfactor = .79
					}
				}

				//// INSURANCE RATES - NOT BEING USED
				
				////propertyInsur = 17.5
				////if (taxes == 0) taxes = propertyInsur
			
				////homeownersInsur = 3
				////if (insurance == 0) insurance = homeownersInsur
			
				//// TAX BRACKET
				if (term == 15) taxBracket = 15
				if (term == 20) taxBracket = 17
				if (term == 25) taxBracket = 28
				if (term == 30) taxBracket = 33
				
				cost 			= price + lotprice
				mortgage 		= cost - downpayment
				payment 		= monthlyPayment(term, rate, mortgage)
				
				//maxMortgage    = payment
				monthlyTAX     	= (taxes + insurance) / 12
				
				monthlyMI 	   	=  (MIfactor * mortgage) / 12 / 100
				
				PITI 	   		= payment + monthlyTAX + monthlyMI
				PITI           	= Math.round(PITI * 100) / 100;
				
				payment        	= Math.round(payment * 100) / 100;
				monthlyTAX     	= Math.round(monthlyTAX * 100) / 100;
				monthlyMI      	= Math.round(monthlyMI * 100) / 100;
			
			 	//// LOAN AMOUNT & APR
				monthly = payment + monthlyMI
				amountFinanced = mortgage - (mortgage * .01) - 375 - (mortgage * rate / 100 / 365 * 30)
			
				loanAmount = price - downpayment
				APR = figureLoanAPR(term, rate, loanAmount, monthly)
			
			 	/// CLOSING COSTS
				closingCosts = (mortgage * .01) + 850 + (mortgage / 1000 * 2.1)
			
			 	//// PREPAIDS
				prePaids = (price * rate / 100 / 365 * 30) + ((taxes + insurance) / 12) + (monthlyMI * 2)
			
			 	//// RESERVES
				if (ratioDown >= 20) {
					reserves = PITI
				} else {
					reserves = PITI * 2
				}
			
			 	//// TOTAL CASH
				totalCash = downpayment + closingCosts + prePaids + reserves
			
			 	//// FORMAT RESULTS
				downpayment    	= formatUSCurrency(downpayment)
				mortgage     	= formatUSCurrency(mortgage)
				payment         = formatUSCurrency(payment)
				cost            = formatUSCurrency(cost)
				monthlyTAX      = formatUSCurrency(monthlyTAX)
				monthlyMI		= formatUSCurrency(monthlyMI)
				PITI            = formatUSCurrency(PITI)
				price           = formatUSCurrency(price)
				APR             = formatPercent(APR,3)
				closingCosts    = formatUSCurrency(closingCosts)
				prePaids    	= formatUSCurrency(prePaids)
				reserves    	= formatUSCurrency(reserves)
				totalCash    	= formatUSCurrency(totalCash)
			
			 	//// REMOVE CENTS
				price 	 		= removeCents(price)
				cost 	 		= removeCents(cost)
				downpayment  	= removeCents(downpayment)
				mortgage 	 	= removeCents(mortgage)
				closingCosts 	= removeCents(closingCosts)
				prePaids     	= removeCents(prePaids)
				reserves     	= removeCents(reserves)
				totalCash    	= removeCents(totalCash)
				
				results = {
					cost:cost,
					downpayment:downpayment,
					mortgage:mortgage,
					closingCosts:closingCosts,
					prePaids:prePaids,
					reserves:reserves,
					totalCash:totalCash,
					payment:payment,
					monthlyTAX:monthlyTAX,
					monthlyMI:monthlyMI,
					PITI:PITI
				};
			}
			
			//// DISPLAY RESULTS		
			data = {results:results,error:error}			
			$(options.templates.results[0]).html(parseTemplate($(options.templates.results[1]).html(), data));
			
		}
		
		function setPresets(){
			$.each(options.presets,function(key,value) {						
				if($('#'+key)){
					$('#'+key).val(value[0])
				}
			});
			calculate(null);
		}
		
		function init(){
			data = null;
			$("#"+$self.attr('id') + " :input").bind("change", calculate);
			$(options.btnReset).bind("click", setPresets);
			$(options.btnCalculate).bind("click", calculate);
			setPresets();
		}
		
		// =============== SETUP =============== //
		return this.each(function() {
			$self = $(this);
			init();		  
		}); 
			
	};
	
})(jQuery);