var Calculators = Calculators || {};
Calculators.planning = Calculators.planning || {};

Calculators.planning.GrossToNetPaycheck = function GrossToNetPaycheck(gross, ytdGross, shelteredContributionRate, preTaxDeductions, payPeriod, filingStatus, numberOfAllowances, postTaxDeductions, postTaxReimbursements, stateAndLocalWithholdingRate) {
	this.gross = new Calculators.type.Money(gross);
	this.ytdGross = new Calculators.type.Money(ytdGross);
	this.shelteredContributionRate = new Calculators.type.Rate(shelteredContributionRate);
	this.preTaxDeductions = new Calculators.type.Money(preTaxDeductions);
	this.payPeriod = new Number(payPeriod);
	this.filingStatus = filingStatus;	
	this.numberOfAllowances = new Number(numberOfAllowances);
	this.postTaxDeductions = new Calculators.type.Money(postTaxDeductions);
	this.postTaxReimbursements = new Calculators.type.Money(postTaxReimbursements);
	this.stateAndLocalWithholdingRate = new Calculators.type.Money(stateAndLocalWithholdingRate);
	this.allowanceDeduction = this.numberOfAllowances * Calculators.tax.CurrentYearTaxData.PERSONAL_ALLOWANCE / this.payPeriod;	
	
	this.getGross = function() {
		return this.gross;
	}
	
	this.getYtdGross = function() {
		return this.ytdGross;
	}
	
	this.getShelteredContributionRate = function() {
		return this.shelteredContributionRate;
	}
	
	this.getPreTaxDeductions = function() {
		return this.preTaxDeductions;
	}
	
	this.getPayPeriod = function() {
		return this.payPeriod;
	}	
	
	this.getFilingStatus = function() {
		return this.filingStatus;
	}	
	
	this.getNumberOfAllowances = function() {
		return this.numberOfAllowances;
	}
	
	this.getPostTaxDeductions = function() {
		return this.postTaxDeductions;
	}
	
	this.getPostTaxReimbursements = function() {
		return this.postTaxReimbursements;
	}
	
	this.getStateAndLocalWithholding = function() {
		return new Calculators.type.Money(this.stateAndLocalWithholdingRate.getAmount() * this.gross.subtract(this.shelteredContributionRate.getAmount() * this.gross.getAmount()).subtract(this.preTaxDeductions).subtract(this.allowanceDeduction).getAmount());
	}	
	
	this.getTotalPreTaxDeductions = function () {
		var totalDeductions = (this.gross.amount * this.shelteredContributionRate.amount);
		totalDeductions += this.preTaxDeductions.amount;
		return new Calculators.type.Money(totalDeductions);
	}
	
	this.getFederalWithholding = function () {
		var annualGross = this.gross.amount * this.payPeriod;
		annualGross -= this.getTotalPreTaxDeductions().amount * this.payPeriod;
		var withholdingTable = new Calculators.tax.WithholdingTable(this.filingStatus);
		var federalWithholding = withholdingTable.getFederalWithholding(annualGross, this.numberOfAllowances);
		return new Calculators.type.Money(federalWithholding / this.payPeriod);
	}
	
	this.getOASDI = function () {
		var maxOASDI = Calculators.tax.CurrentYearTaxData.FICA_MAX * Calculators.tax.CurrentYearTaxData.FICA_OASDI_PCT;
		var YTDPaidOASDI = (this.ytdGross.getAmount() * Calculators.tax.CurrentYearTaxData.FICA_OASDI_PCT);
		var YTDPaidOASDIAndNormalPaycheckAmount = (this.gross.getAmount() + this.ytdGross.getAmount()) * Calculators.tax.CurrentYearTaxData.FICA_OASDI_PCT;
		var periodOASDI = YTDPaidOASDIAndNormalPaycheckAmount - YTDPaidOASDI;
		var remaningAnnualOASDI = (maxOASDI < YTDPaidOASDI) ? 0 :  maxOASDI - YTDPaidOASDI;
		var OASDIforThisCheck = (periodOASDI < remaningAnnualOASDI) ? periodOASDI : remaningAnnualOASDI;
		return new Calculators.type.Money(OASDIforThisCheck);
	}
	
	this.getMedicare = function() {
		return new Calculators.type.Money(this.getGross().getAmount() * Calculators.tax.CurrentYearTaxData.MEDICARE_WITHOLDING);
	}
	
	this.getPostTaxNet = function () {
		return this.postTaxReimbursements.subtract(this.postTaxDeductions);
	}
	
	this.getNet = function() {
		return this.gross.subtract(this.getTotalPreTaxDeductions()).subtract(this.getFederalWithholding()).subtract(this.getOASDI()).subtract(this.getMedicare()).subtract(this.getStateAndLocalWithholding()).add(this.getPostTaxNet());
	}
}

