/**
 * @author 	buenger
 * @version	1.0
 * 
 * Depends on the following external classes/libraries:
 * 	- Utilities.class.js
 * 	- PPI.class.js
 *  - mootools 1.2 
 */
function Credit () {
	
	//User Input Variables
	var runtime;
	var price;
	var nomInterest;
	var effInterest;
	var hasPPI = true;
	var deposit = 0;
	
	//Output Variables
	this.PPIRate;
	this.PPITotal;
	this.rate;
	this.totalCharges;
	this.interestCharges;
	
	var _self = this;
	
	this.setRuntime = function (a_runtime) {
		runtime = Number(a_runtime);
	}
	
	this.setPrice = function (a_price) {
		price = Number(a_price);
	}
	
	this.setDeposit = function (a_deposit) {
		deposit = Number(a_deposit);
	}
	
	this.setNomInterest = function (a_nomInterest) {
		nomInterest = Number(a_nomInterest);
		effInterest = Utilities.getEffInterest(nomInterest);
	}
	
	this.setEffInterest = function (a_effInterest) {
		effInterest = Number(a_effInterest);
		nomInterest = Utilities.getNomInterest(effInterest);
	}
	
	this.setPPI = function (a_hasPPI) {
		hasPPI = a_hasPPI;
	}
	
	this.calculate = function () {
		
		if (!checkValues()) {
			handleUndefinedError();
			return;
		}
		if (!checkPrice()) {
			handlePriceError();
			return;
		}
		if (!checkMinRuntime()) {
			handleRuntimeError();
			return;
		}
		this.PPITotal = (hasPPI) ? Utilities.round(getTotalPPI()): 0;
		this.rate = Utilities.round(getRate(price + this.PPITotal, nomInterest / 1200, runtime));
		this.PPIRate = (this.rate - Utilities.round(getRate(price, nomInterest / 1200, runtime)));
		this.totalCharges = Utilities.round(getTotalCharges());
		this.interestCharges = Utilities.round(getInterestCharges());
		
		
		handleSuccess();					
	}
	
	function checkValues () {
		var ctrl = true;
		
		if (deposit == undefined || isNaN(deposit)) ctrl = false;
		if (nomInterest == undefined || isNaN(nomInterest)) ctrl = false;
		if (effInterest == undefined || isNaN(effInterest)) ctrl = false;
		if (hasPPI == undefined) ctrl = false;
		
		return ctrl;
	}
	
	function checkMinRuntime () {
		return (runtime >= Settings.getCreditMinRuntime() && runtime != undefined && !isNaN(runtime));
	}
	
	function checkPrice () {
		return (price <= Settings.getCreditMaxPrice() && price >= Settings.getCreditMinPrice() && price != undefined && !isNaN(price));
	}
	
	function getRatePPI ()	{
		return getTotalPPI() / runtime;
	}
	
	function getTotalPPI () {
		var rate = getRate(price, nomInterest / 1200, runtime);
		var tmpRate = (rate >= PPI.getCreditPPITreshold()) ? PPI.getCreditPPITreshold() : rate;
		return (PPI.getCreditPPI(runtime) * runtime * tmpRate);
	}
	
	function getRate (a_price, a_zinssatz, a_runtime) {
		var PMT = (a_price * a_zinssatz) / (1 - Math.pow(1 + a_zinssatz, -a_runtime));
		return Utilities.round(PMT);
	}
	
	function getTotalCharges () {
		return (runtime * _self.rate) + deposit;
	}
	
	function getInterestCharges () {
		return (_self.rate * runtime - ((price - deposit) + Utilities.round(_self.PPITotal)));
	}
	
	function getAnnualInterestCharges () {
		return (_self.rate * runtime - ((price - deposit) + Utilities.round(_self.PPITotal))) / runtime * 12;
	}
	
	//Error handling, implements Event extension (mootools 1.2)
	function handleSuccess () {
		_self.fireEvent("success", _self);
	}
	
	function handleRuntimeError () {
		_self.fireEvent("error", "runtime");
	}
	
	function handlePriceError () {
		_self.fireEvent("error", ["price", Settings.getCreditMinPrice(), Settings.getCreditMaxPrice()]);
	}
	
	function handleUndefinedError () {
		_self.fireEvent("error", "undefined");
	}
	
	//Event extension (mootools 1.2)
	$extend(this, new Events());
}

