/**
 * Mortgage Calculator v 1.0
 *
 * @author Vít Mádr
 * @copyright Vít Mádr - all rights reserved
 */
MortgageCalculator = {

	round: function(x, places, fixed) {
		return fixed ? x.toFixed(places) : (Math.round(x * Math.pow(10, places))) / Math.pow(10, places);
	},

	repeatString: function(s, n) {
		var a = [];
		while (a.length < n){ a.push(s); }
		return a.join("");
	},

	formatThousands: function(nStr, sep) {
		if (!sep) { sep = " "; }
		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' + sep + '$2');
		}
		return x1 + x2;
	},

	formatNumber: function(v, r, fixed, tsep) {
		var r = this.round(v, r, fixed);
		r = this.formatThousands(r, tsep);
		return r;
	},

	localize: function(str, strings) {
		var r = str;
		var marker;
		for (var k in strings) {
			for (var j in strings[k]) {
				marker = new RegExp("\\{" + k + "." + j + "\\}", "g");
				r = r.replace(marker, strings[k][j]);
			}
		}
		return r;
	}

};

MortgageCalculator.Calculator = function() {
	this.jqEl = jQuery(arguments[0]);
	this.init(arguments[1]);
};

MortgageCalculator.Calculator.prototype = jQuery.extend(MortgageCalculator.Calculator.prototype, {

	defaults: {
		options: {
			currency: "EUR",
			round: 2,
			amount: 500000,
			repayment: 15, // years
			avgRate: 5.5, // average interest rate
			lang: "EN",
			installPath: "/MortgageCalculator/",
			locales: {
				EN: {
					strings: {
						Title: "Indicative mortgage calculator",
						AmountTitle: "Mortgate amount",
						RepaymentTitle: "Repayment length",
						AvgRateTitle: "Average interest rate",
						MonthRepaymentTitle: "Monthly annuity payment",
						QuarterRepaymentTitle: "Quaterly annuity payment",
						YearRepaymentTitle: "Yearly annuity payment",
						Calculate: "Calculate",
						Years: "Years"
					},
					currency: { thousandsSeparator: ",", decimalsSeparator: "." }
				}
			}
		}
	},
	options: {},
	name: "Mcalc",
	domId: "Mcalc",
	jqEl: null,
	lang: "EN",
	defaultLang: "EN",
	installPath: null,
	tplPath: null,
	locales: null,
	format: null,

	currency: "EUR",
	amount: null,
	repayment: null,
	avgRate: null,
	monthRepayment: null,
	quarterRepayment: null,
	yearRepayment: null,
	round: 2,

	/* --- */

	init: function(o) {
		this.options = jQuery.extend(true, this.defaults.options, o);
		this.installPath = this.options.installPath;
		this.tplPath = this.installPath + "/tpl/Calculator.tpl";
		this.lang = this.options.lang;
		this.locales = this.options.locales;
		this.locale = jQuery.extend(true, this.locales[this.defaultLang], this.locales[this.lang]);
		this.currency = this.options.currency;
		this.amount = this.options.amount;
		this.repayment = this.options.repayment;
		this.avgRate = this.options.avgRate;
		this.domId = this.name;
		this.round = this.options.round;
	},

	implement: function() {
		this.jqEl.replaceWith("<div id=\"" + this.domId + "\" class=\"Mcalc\"></div>");
		var calc = this;
		this.jqEl = jQuery("#" + this.domId).load(this.tplPath, { lang: this.lang }, function() {
			calc.open();
		});
	},

	localize: function() {
		this.jqEl.html(MortgageCalculator.localize(this.jqEl.html(), {
			"locale.strings": this.locale.strings,
			calc: { currency: this.currency, domId: this.domId }
		}));
	},

	open: function() {
		this.localize();
		var calc = this;
		this.jqEl.find("button").click(function(e) { calc.calcButtonOnClick(e, this); });
		this.jqEl.find("input").change(function(e) { calc.inputOnChange(e, this); });
		if (jQuery.fn.format) {
			calc.format = { locale: calc.lang.toLowerCase() };
			if (0) {
				calc.format.format = "#" + calc.locale.currency.thousandsSeparator + "###" + (calc.round ? (calc.locale.currency.decimalsSeparator + MortgageCalculator.repeatString("0", calc.round)) : "");
			}
			this.jqEl.find("input.tiAmount").blur(function() { jQuery(this).format(calc.format); });
			this.jqEl.find("input.tiAvgRate").blur(function() { jQuery(this).format(calc.format); });
		}
		this.load();
		this.calc();
		this.loadResult();
	},

	load: function() {
		this.jqEl.find("input.tiAmount").val(this.amount);
		this.jqEl.find("input.tiAmount").trigger("blur");
		this.jqEl.find("input.tiRepayment").val(this.repayment);
		this.jqEl.find("input.tiAvgRate").val(this.avgRate);
		this.jqEl.find("input.tiAvgRate").trigger("blur");
	},

	loadResult: function() {
		this.jqEl.find("tr.rMonthRepayment td .val").text(this.monthRepayment);
		this.jqEl.find("tr.rQuarterRepayment td .val").text(this.quarterRepayment);
		this.jqEl.find("tr.rYearRepayment td .val").text(this.yearRepayment);
	},

	getRepaymentByDiv: function(amount, repayment, avgRate, div) {
		var avgRatePercent = avgRate / 100;
		var r = amount * (((avgRatePercent / div) * Math.pow(1 + (avgRatePercent / div), div * repayment)) / (Math.pow(1 + (avgRatePercent / div), div * repayment) - 1));
		r = MortgageCalculator.formatNumber(r, this.round, true, this.locale.currency.thousandsSeparator);
		return r;
	},

	getMonthRepayment: function(amount, repayment, avgRate) {
		return this.getRepaymentByDiv(amount, repayment, avgRate, 12);
	},

	getQuarterRepayment: function(amount, repayment, avgRate) {
		return this.getRepaymentByDiv(amount, repayment, avgRate, 4);
	},

	getYearRepayment: function(amount, repayment, avgRate) {
		var avgRatePercent = avgRate / 100;
		var r = amount * ((avgRatePercent * Math.pow(1 + avgRatePercent, repayment)) / (Math.pow(1 + avgRatePercent, repayment) - 1));
		r = MortgageCalculator.formatNumber(r, this.round, true, this.locale.currency.thousandsSeparator);
		return r;
	},

	calc: function() {
		this.monthRepayment = this.getMonthRepayment(this.amount, this.repayment, this.avgRate);
		this.quarterRepayment = this.getQuarterRepayment(this.amount, this.repayment, this.avgRate);
		this.yearRepayment = this.getYearRepayment(this.amount, this.repayment, this.avgRate);
	},

	calcButtonOnClick: function(e, sender) {
		this.calc();
		this.loadResult();
	},

	inputOnChange: function(e, sender) {
		this[jQuery(sender).attr("name")] = jQuery.fn.format ? jQuery(sender).parse(this.format) : parseFloat(jQuery(sender).val());
	}

});

//[JQUERY.BIND]
(function($) {

	$.fn.mortgageCalculator = function(o) {
		var jqEl = jQuery(this);
		var r = (jqEl.length > 1) ? [] : null;
		if (jqEl.length > 1) {
			jqEl.each(function(i, el) {
				r[i] = new MortgageCalculator.Calculator(el, o);
				r[i].implement();
			});
		} else if (jqEl.length == 1) {
			r = new MortgageCalculator.Calculator(jqEl.get(0), o);
			r.implement();
		}
		return r;
	};

})(jQuery);
// END [JQUERY.BIND]
