	var lastOrderLine = -1;

	/* Using default settings if not configured */
	if(JDB_FILE === undefined)          var JDB_FILE = 'functions.jquery.php';
	if(ERR_BAD_VALUE === undefined)     var ERR_BAD_VALUE = 'Błędna wartość';
	if(ERR_REQUIRED === undefined)      var ERR_REQUIRED = 'Pole jest wymagane';
	if(ERR_EMAIL === undefined)         var ERR_EMAIL = 'Niepoprawny adres e-mail';
	if(PICTURES_DIR === undefined)      var PICTURES_DIR = 'pictures/';
	if(PICTURES_HEIGHT === undefined)   var PICTURES_HEIGHT = 100;
	if(NO_PICTURE === undefined)        var NO_PICTURE = PICTURES_DIR + 'brak_zdjecia.png';
	if(NO_PICTURE_WIDTH === undefined)  var NO_PICTURE_WIDTH = 150;
	if(NO_PICTURE_HEIGHT === undefined) var NO_PICTURE_HEIGHT = 50;
	if(PRODUCTS_OPTIONS === undefined)  var PRODUCTS_OPTIONS = '';

	function getNewLineHTML(lineNo) {
		var html =
	'<div id="orderLine' + lineNo + '" class="orderLine">\n' +
	'	<div class="orderLineNo">' + (lineNo + 1) + '</div>\n' +
	'	<div class="orderLineProduct">\n' +
	'		<select class="productID" id="productID' + lineNo + '" name="productID[' + lineNo + ']">\n' +
	'			<option value="0">Wybierz produkt...</option>\n' +
	'			' + PRODUCTS_OPTIONS + '\n' +
	'		</select><br>\n' +
	'		<img class="productPicture" id="productPicture' + lineNo + '" alt="" title="">\n' +
	'	</div>\n' +
	'	<div id="orderLineProductData' + lineNo + '" class="orderLineProductData">\n' +
	'		<div class="orderLineAmount">\n' +
	'			<input type="text" class="productAmount" id="productAmount' + lineNo + '" name="productAmount[' + lineNo + ']" value="1" onchange="validateAmount(this); updateOrderPrice(' + lineNo + ')">\n' +
	'		</div>\n' +
	'		<div class="orderLineQuantity" id="orderLineQuantity' + lineNo + '">&nbsp;</div>\n' +
	'		<div class="orderLinePriceUnit">\n' +
	'			<input type="hidden" id="productPriceUnit' + lineNo + '" name="productPriceUnit[' + lineNo + ']" value="0">\n' +
	'			<div id="productPriceUnitDisplay' + lineNo + '">&nbsp;</div>\n' +
	'		</div>\n' +
	'		<div class="orderLinePrice">\n' +
	'			<input type="hidden" id="productPrice' + lineNo + '" name="productPrice[' + lineNo + ']" value="0">\n' +
	'			<div id="productPriceDisplay' + lineNo + '">&nbsp;</div>\n' +
	'		</div>\n' +
	'		<div class="orderLineActions"><a href="#Wyczyść" onclick="clearOrderLine(' + lineNo + ')">[wyczyść]</a></div>\n' +
	'	</div>\n' +
	'	<br class="clear">\n' +
	'	<br class="dummy">\n' +
	'</div>\n';

		return html;
	}

	function refreshAddLineLink() {
		var i = 0;

		for(i = 0; i <= lastOrderLine; i++)
			if($("#productID" + i).val() == 0) {
				$("#orderAddLineDiv").hide();
				return;
			}

		$("#orderAddLineDiv").fadeIn();
	}

	function formatPrice(number) {
		var numberString = String(number);

		if(numberString.indexOf('.') == -1)
			return (numberString + ',00 zł');

		var numParts = numberString.split('.');
		var numPart1 = numParts[0];
		var numPart2 = numParts[1];

		if(!numPart1)
			numPart = '0';

		if(numPart2) {
			numPart2 = numParts[1]
			numPart2 = String(numPart2.match(/[0-9]{1,3}/g));

			if(numPart2.length == 0)
				numPart2 += '00';
			else if(numPart2.length == 1)
				numPart2 += '0';
			else {
				var digit1 = numPart2.substr(0, 1);
				var digit2 = numPart2.substr(1, 1);
				var digit3 = numPart2.substr(2, 1);

				if(digit3 >= 5) {
					if(digit2 != 9)
						digit2++;
					else {
						digit2 = 0;

						if(digit1 != 9)
							digit1++;
						else {
							digit1 = 0;
							numPart1++;
						}
					}
				}
				numPart2 = String(digit1) + String(digit2);
			}
		}
		else
			numPart2 = '00';

		return (numPart1 + ',' + numPart2 + ' zł');
	}

	function getLineNoFromElementName(name) {
		var no = name.match(/[0-9]+/g);
		return no;
	}

	function fillOrderLine(productID, lineNo) {
		if(productID == 0)
			return;

		$.getJSON(JDB_FILE, {'function': 'get_product', 'productID': productID}, function(jProduct) {
			$("#orderLineQuantity" + lineNo).html(jProduct[0].quantity_unit + ' (' + jProduct[0].quantity + ')');
			$("#productPriceUnit" + lineNo).val(jProduct[0].price);
			$("#productPrice" + lineNo).val(jProduct[0].price);
			$("#productPriceUnitDisplay" + lineNo).html(formatPrice(jProduct[0].price));
			$("#productPriceDisplay" + lineNo).html(formatPrice(jProduct[0].price));
			$("#orderLineProductData" + lineNo).show();

			$("#productPicture" + lineNo).fadeOut("fast", function() {
				$.getJSON(JDB_FILE, {'function': 'check_picture', 'catalogueNo': jProduct[0].catalogue_no}, function(jPicture) {
					if(jPicture[0].file !== undefined) {
						height = jPicture[0].height;

						if(height <= PICTURES_HEIGHT)
							width = jPicture[0].width;
						else {
							width = Math.round(PICTURES_HEIGHT * jPicture[0].width / height);
							height = PICTURES_HEIGHT;
						}

						$("#productPicture" + lineNo).attr('src', jPicture[0].file);
						$("#productPicture" + lineNo).attr('width', width);
						$("#productPicture" + lineNo).attr('height', height);
					}
					else {
						$("#productPicture" + lineNo).attr('src', NO_PICTURE);
						$("#productPicture" + lineNo).attr('width', NO_PICTURE_WIDTH);
						$("#productPicture" + lineNo).attr('height', NO_PICTURE_HEIGHT);
					}
					$("#productPicture" + lineNo).attr('alt', jProduct[0].catalogue_no);
					$("#productPicture" + lineNo).attr('title', jProduct[0].catalogue_no);
				});
				$("#productPicture" + lineNo).fadeIn("slow");
			});
			updateOrderPrice(lineNo);
		});
	}

	function clearOrderLine(lineNo) {
		$("#productID" + lineNo).val(0);
		$("#orderLineQuantity" + lineNo).html('');
		$("#productPriceUnit" + lineNo).val(0);
		$("#productPrice" + lineNo).val(0);
		$("#productPriceUnitDisplay" + lineNo).html('');
		$("#productPriceDisplay" + lineNo).html('');
		$("#orderLineProductData" + lineNo).hide();

		$("#productPicture" + lineNo).attr('width', '0');
		$("#productPicture" + lineNo).attr('height', '0');
		$("#productPicture" + lineNo).fadeOut();

		updateTotalPrice();
		refreshAddLineLink();
	}

	function class_productID_change() {
		$("select.productID").change(function() {
			var selfValue = this[this.selectedIndex].value;
			var selfLineNo = getLineNoFromElementName(this.name);

			if(selfValue != 0)
				fillOrderLine(selfValue, selfLineNo);
			else
				clearOrderLine(selfLineNo);

			refreshAddLineLink();
		});
	}

	function addOrderLine() {
		lastOrderLine += 1;

		$("#orderLines").append(getNewLineHTML(lastOrderLine));
		clearOrderLine(lastOrderLine);
		class_productID_change();
		refreshAddLineLink();
	}

	function updateTotalPrice() {
		var totalPrice = 0;
		var i = 0;

		for(i = 0; i <= lastOrderLine; i++)
			if($("#productID" + i).val() != 0)
				totalPrice += 1.0 * $("#productPrice" + i).val();

		$("#orderSubTotalPrice").html(formatPrice(totalPrice));

		if($("#orderDiscount").val() > 0)
			totalPrice -= totalPrice / 100.0 * $("#orderDiscount").val();

		$("#orderTotalPrice").html(formatPrice(totalPrice));
	}

	function updateOrderPrice(lineNo) {
		$("#productPrice" + lineNo).val($("#productPriceUnit" + lineNo).val() * $("#productAmount" + lineNo).val());
		$("#productPriceDisplay" + lineNo).html(formatPrice($("#productPrice" + lineNo).val()));

		updateTotalPrice();
	}

	function validateAmount(trgObject) {
		var val = trgObject.value;

		if(isNaN(val) || val * 1 < 1) {
			trgObject.value = 1;
			alert(ERR_BAD_VALUE);
		}
	}

	function validateDiscount(trgObject) {
		var val = trgObject.value;

		if(isNaN(val) || val * 1 < 0) {
			trgObject.value = '';
			alert(ERR_BAD_VALUE);
		}
	}

	$(document).ready(function(){
		addOrderLine();

		$("#orderDiscount").change(function() {
			updateTotalPrice();
		});

		jQuery.validator.messages.required = ERR_REQUIRED;
		jQuery.validator.messages.email = ERR_EMAIL;

		$("#order").validate();
	});

