/*
 * Der REWE-Portionsrechner als jQuery plugin.
 * 
 */

// Statische Funktionen für interne Verwendung
jQuery.calculator = {
	
	/**
	 * Aktualisiert die berechnete Bestellmenge im Rechner.
	 * 
	 * @param calculator Das jQuery-Objekt des Rechner-Elements
	 * @returns Der berechnete Wert
	 */
	updateCalculation: function(calculator) {
		var amount = jQuery.calculator.parseNumber(calculator.find('input.amount').val());
		var packageWeight = jQuery.calculator.parseNumber(calculator.find('input.package_weight').val());
		var orderAmount = amount * packageWeight;
		
		calculator.find('span.order_amount').text(jQuery.calculator.formatNumber(orderAmount));
		
		return orderAmount;
	},
	
	/**
	 * Wandelt einen String in eine Zahl um. Dabei sind in dem String als
	 * Tausender- und Dezimaltrennzeichen sowohl '.' als auch ',' erlaubt. Lässt
	 * sich der String nicht in eine Zahl umwandeln, wird der optionale
	 * Vorgabewert zurückgegeben, wenn dieser angegeben wurde. Ist dieser nicht
	 * definiert, wird Number.NaN zurückgegeben.
	 * 
	 * @param input
	 *            Der Eingabestring
	 * @param defaultValue
	 *            (optional) Ein Vorgabewert, falls keine Zahl gelesen werden
	 *            kann
	 * @returns Eine Zahl oder der Vorgabewert, falls die Umwandlung fehlschlug
	 */
	parseNumber: function(input, defaultValue) {
		input = input.replace(/,/g, '.');
		
		var parts = input.split('.');
		if (parts.length > 2) {
			input = parts
				.slice(0, -1)
				.join()
				.concat('.')
				.concat(parts[parts.length - 1]);
		}
		
		var value = Number(input);
		if (defaultValue != undefined && isNaN(value)) {
			return defaultValue;
		} else {
			return value;
		}
	},

	/**
	 * Wandelt eine Zahl in einen String zur Ausgabe um. Als Dezimaltrennzeichen
	 * wird das Komma (',') verwendet. Handelt es sich bei dem übergebenen Wert
	 * um keine Zahl, wird der optionale Vorgabewert zurückgegeben, wenn dieser
	 * angegeben ist. Ist dieser nicht definiert, wird ein leerer String
	 * zurückgegeben.
	 * 
	 * @param value
	 *            Die Zahl
	 * @param defaultValue
	 *            (optional) Ein Vorgabewert, falls keine Zahl gelesen werden
	 *            kann
	 * @returns Die für die Ausgabe formatierte Zahl
	 */
	formatNumber: function(value, defaultValue) {
		if (isNaN(value)) {
			if (defaultValue != undefined) {
				return defaultValue;
			} else {
				return '';
			}
		}
		
		return value.toFixed(2).replace(/\./g, ',');
	}
};

/**
 * Die Pluginmethode, die den Portionsrechner erzeugt und anzeigt. Als Parameter wird
 * das Stückgewicht erwartet, anhand dessen die Mengenberechnung durchgeführt wird.
 * 
 * @param packageWeight Das Stückgewicht des Gewichtsartikels
 * @returns Das jQuery-Objekt
 */
jQuery.fn.calculator = function(packageWeight) {
	if (isNaN(packageWeight) || packageWeight <= 0) {
		packageWeight = 1;
	}
	
	return this.each(function() {
		var elem = jQuery(this);
		
		var calculator = jQuery('div.calculator:first');
		if (calculator.length == 0) {
			// Es existiert noch kein Rechener -> neu erzeugen
			elem.after('<div class="calculator"> </div>');
			calculator = elem.next();
			
			calculator
				.append('<h3>Portionsrechner</h3>')
				.append('<div class="formula"><input type="text" class="amount text" /> x <input type="text" class="text package_weight" /> kg = <span class="order_amount"> </span> kg</div>')
				.append('<div class="controls"><a href="#" title="Übernehmen" class="apply">Übernehmen</a> <a href="#" title="Schließen" class="close">&#xd7;</a></div>');
			
			var inputField = calculator.find('input.amount');
			
			calculator
				.css({
					top: elem.position().top - inputField.position().top,
					left: elem.position().left - inputField.position().left
				})
				.fadeOut(0);
		} else {
			// Bereits bestehenden Rechner auf ausgewählten Artikel ändern
			calculator.find('input.amount').unbind('keyup');
			calculator.find('input.package_weight').unbind('keyup');
			calculator.find('a.close').unbind('click');
			calculator.find('a.apply').unbind('click');
			
			var inputField = calculator.find('input.amount');
			
			calculator.animate({
				top: elem.position().top - inputField.position().top,
				left: elem.position().left - inputField.position().left
			}, 'fast', null, function() {
				calculator.insertAfter(elem);
			});
		}
		
		var orderAmount = jQuery.calculator.parseNumber(elem.val(), 0);
		var amount = orderAmount / packageWeight;
		
		calculator.find('span.order_amount').text(jQuery.calculator.formatNumber(orderAmount));
		calculator.find('input.package_weight')
			.val(jQuery.calculator.formatNumber(packageWeight))
			.keyup(function(e) {
				jQuery.calculator.updateCalculation(calculator);
			});
		calculator.find('input.amount')
			.val(jQuery.calculator.formatNumber(amount))
			.keyup(function(e) {
				jQuery.calculator.updateCalculation(calculator);
			});
		
		// Schließen-Link
		calculator.find('a.close')
			.click(function(e) {
				calculator.fadeOut('slow', function() {
					calculator.remove();
				});
				return false;
			});
		
		// Übernehmen-Link
		calculator.find('a.apply')
			.click(function(e) {
				var orderAmount = jQuery.calculator.updateCalculation(calculator);
				if (!isNaN(orderAmount) && orderAmount > 0) {
					elem.val(jQuery.calculator.formatNumber(orderAmount));
				} else {
					elem.val('');
				}
				
				calculator.fadeOut('slow', function() {
					calculator.remove();
				});
				return false;
			});
		
		calculator.fadeIn('fast', function() {
			if(jQuery.browser.msie) {
				this.style.removeAttribute('filter'); // Behebt Text-Renderingfehler im IE
			}
		});
	});
};
