/**********
objLoan start
**********/
function objLoan(){
	//Inputs
	this.premierBroker = 0;
	this.fullDoc = 0;
	this.R = 0;
	this.C = 0;				//constant term
	this.L = 0;				//loan fees
	this.LTVDen = 0;		//Denominator portion of LTV
	this.LTVConst = 0;		//Constant portion of LTV numerator
	this.gLOverride = 0;
	this.gROverride = 0;
	this.ppIntDate1 = "";
	this.ppIntDate2 = "";
	this.InterestRate = 0;	//as an integer
	
	//Calc Outputs
	this.T = 0;
	this.R = 0;
	this.ppInt = 0;			//prepaid interest
	this.interestDays = 0;	//prepaid interest days
	this.LTV = 0;			//Actual LTV
	this.reducedFee = 0;	//the Reduced Doc fee (i.e. the difference in a given row from the feeCol - 1st feeCol

	//Internal (private) Variables
	var Pl = 0;
	var Pr = .2;
	var Rmin = 10000;
	var arFee = new Array();
	var pbFeeBreak = 500;		//premier broker fee break
	var pbPtBreak = .01;		//premier broker point break
	var PnD = 0;				//helper variable which is the Int Rate/365 * Interest Days
	var RConstant = 0;			//should R be held constant?
	var LConstant = 0;			//should L be held constant?
	var isConsistent = false;	//are the calculated values consistent with all requirements?
	var feeRow = 0;				//the Loan Fee table row being used
	var feeCol = 0;				//the Loan Fee table col being used
	var A = 2500;				//Additional fee for 70% and 75% columns

	//setup the loan fee array
	/*
	Loan Amt 			Full/65%	70%*	75%*
	$30,000–39,900 		$3,900 		$4,900 	$5,900
	$40,000–49,900 		$4,900 		$5,900 	$6,900
	$50,000–89,900 		$5,900 		$6,900 	$7,900
	$90,000–150,000 	7% 			7%** 	7%**
	
	* Full Doc loans are priced as if they were 65% CLTV.
	** Add $2,500
	*/
	arFee[0] = new Array(39999, 3900, 4900, 5900);
	arFee[1] = new Array(49999, 4900, 5900, 6900);
	arFee[2] = new Array(89999, 5900, 6900, 7900);
	arFee[3] = new Array(null, .07, .07, .07);	

	//Public Methods
	this.dupeLoan = function(oLoan){
		oLoan.C = this.C;
		oLoan.gLOverride = this.gLOverride;
		oLoan.gBOverride = this.gBOverride;
		oLoan.InterestRate = this.InterestRate;
	}
	this.calcLoanAmount = function(){
		/*Summary
		1. Use the initial value of C + Minimum Reserve (unless overwridden) as an estimated Loan Amount and assume the LTV <= 65%
		2. From this, determine an intial Loan Fee estimate
		3. Use the appropriate equation to calculate all values
		4. Determine if the results are consistent with the Loan Fee table and the minimum value of R
			* check R first...If R is less than minimum, set it to minimum and hold it constant and repeat steps
			* check Loan Amount and LTV next			
		5. Repeat steps 3 and 4 until the returned values are consistent with the table
		*/
		//initialize the helper variable PnD
		this.calcPnD();

		//set initial state for LConstant, RConstant
		RConstant = this.gROverride;
		LConstant = this.gLOverride;

		//set initial state for LTV and Loan Amount (this is the initial guess)
		this.T = this.C + 0;
		if(RConstant == 1){
			this.T += this.R;
		}else{
			this.T += Rmin;
		}
		this.calcLTV();

		/**********Safety Loop**/
		var j = 1;
		/***********************/

		isConsistent = false;
		while(!isConsistent){
			//determine what fee column should be used
			feeCol = getFeeCol(this.LTV, this.fullDoc);
			
			//determine the intial Loan Fee estimate if required
			if(this.gLOverride == 0){
				this.L = 0;
				for(var i=0; i<4; i++){
					feeRow = i;
					if(i == 3){
						Pl = arFee[i][feeCol];
						if(this.premierBroker == 1) Pl -= pbPtBreak;
						LConstant = 0;
						break;
					}
					if(this.T <= arFee[i][0]){
						this.L = arFee[i][feeCol];
						if(this.premierBroker == 1) this.L -= pbFeeBreak;
						LConstant = 1;
						break;
					}
				}
			}
			
			//determine the reducedFee
			if(feeCol == 1 || this.gLOverride == 1){
				if(this.gLOverride == 0){
					//no extra fees for Full Docs, but don't update unless loan fees are not overridden
					this.reducedFee = 0;
				}
			}else{
				if(feeRow != 3){
					this.reducedFee = arFee[feeRow][feeCol] - arFee[feeRow][1];
				}else{
					this.reducedFee = A;
				}
			}
			//alert(LConstant);
			//alert(RConstant);
			//determine the calculation method
			if(LConstant == 0 && RConstant == 0){
				this.fNoConstant();
			}
			if(LConstant == 1 && RConstant == 0){
				this.fLConstant();
			}
			if(LConstant == 0 && RConstant == 1){
				this.fRConstant();
			}
			if(LConstant == 1 && RConstant == 1){
				this.fLRConstant();
			}
			this.calcLTV();
			//check to see if the results are consistent with the table
			/*alert("FeeRow = " + feeRow + "\n" + "FeeCol = " + feeCol + "\n" + "T = " + this.T + "\n" + "L = " + this.L + "\n" + 
				"R = " + this.R + "\n" + "LTV = " + this.LTV);
			*/
			
			//if overriding both R and L, no consistency check needs to be done
			if(this.gLOverride == 1 && this.gROverride == 1){
				break;
			}
			
			isConsistent = true;
			//is R consistent?
			if(isConsistent && RConstant == 0 && this.R < Rmin){
				isConsistent = false;
				this.R = Rmin;
				RConstant = 1;
			}
			
			//if R is consistent and we are overriding L, no further checks need be done
			if(isConsistent && this.gLOverride == 1){
				break;
			}
			
			//is the Loan Amount consistent with the fee Row?
			if(isConsistent){
				if(feeRow != 3){	//no reason to check any further...that's the highest row...must be consistent
					for(var i=0; i<3; i++){
						if(this.T <= arFee[i][0]){
							if(i == feeRow){
								break;
							}else{
								isConsistent = false;
								break;
							}
						}
					}
				}
			}
			
			//is the LTV consistent with the fee Col?
			if(isConsistent){
				if(feeCol != getFeeCol(this.LTV, this.fullDoc)){
					isConsistent = false;
				}
			}
			/*************Safety Loop*/			
			j++;
			if(j>5) break;
			/*************************/
		}
		/*alert("FINAL" + "\n" + "FeeRow = " + feeRow + "\n" + "FeeCol = " + feeCol + "\n" + "T = " + this.T + "\n" + "L = " + this.L + "\n" + 
				"R = " + this.R + "\n" + "LTV = " + this.LTV);
				*/
	}
	//**********
	function getFeeCol(LTV, fullDoc){
		if(fullDoc == 1){
			return 1;
		}
		if(LTV <= 65){
			return 1;
		}
		if(LTV <= 70){
			return 2;
		}
		return 3;
	}
	//**********
	this.calcLTV = function(){
		if(this.LTVDen + 0 != 0){
			this.LTV = (this.T + this.LTVConst)/this.LTVDen * 100.0;
		}else{
			this.LTV = 0;
		}
	}
	//**********
	this.calcPnD = function(){
		var str1 = this.ppIntDate1 + "";
		var str2 = this.ppIntDate2 + "";
		
		var dat1, dat2, dateDiff;

		if(str1.length == 0 || str2.length == 0){
			PnD = 0;
		}else{
			dat1 = new Date(str1);
			dat2 = new Date(str2);
			
			if(isNaN(dat1) || isNaN(dat2)){
				PnD = 0;
			}else{
				dateDiff = Math.round((dat2-dat1)/1000/60/60/24) + 1;
				this.interestDays = dateDiff;
				if(dateDiff <= 0) dateDiff = 0;
				PnD = this.InterestRate/365/100 * dateDiff;
			}
		}
	}
	//**********
	this.fNoConstant = function(){
		if(feeCol == 1){
			this.T = this.C/(1-Pl-Pr+PnD*(Pr-1));
			this.L = Pl*this.T;
		}else{
			this.T = (this.C + A)/(1-Pl-Pr+PnD*(Pr-1));
			this.L = Pl*this.T + A;
		}
		this.R = Pr*this.T;
		this.ppInt = (this.T - this.R)*PnD;
	}
	//**********
	this.fLConstant = function(){
		this.T = (this.C + this.L)/(1-Pr)/(1-PnD);
		this.R = Pr*this.T;
		this.ppInt = (this.T - this.R)*PnD;
	}
	//**********
	this.fRConstant = function(){
		if(feeCol == 1){
			this.T = (this.C + this.R*(1-PnD))/(1-Pl-PnD);
			this.L = Pl*this.T;
		}else{
			this.T = (this.C + A + this.R*(1-PnD))/(1-Pl-PnD);
			this.L = Pl*this.T + A;
		}
		this.ppInt = (this.T - this.R)*PnD;		
	}
	//**********
	this.fLRConstant = function(){
		this.T = (this.C + this.L)/(1-PnD) + this.R;
		this.ppInt = (this.T - this.R)*PnD;
	}
	//**********
}
/**********
objLoan end
**********/

