jQuery.fn.flow = function(options) {
	var config = {
		visible: 5,
		maxWidth: 125,
		maxHeight: 175,
		speed: 450,
		easing: 'easeInOutSine'
	}

	var o = $.extend(config, options); // extend variables
	var instance = this;
	var parent = instance.parent();
	var slider = instance.find('ul');
	var li = parent.find('li');
	var liSize = li.size();
	var c = 0;
	var i = 0;
	var n = 0;
	var p = 0;
	var limit = {} // the limit object
	var running = false;

	// Slide!
	function slide(d) {
		if(running) return false; // do nothing if it's animating

		p = parseInt(slider.css('left'));

		if(d == 'l') {
			p += liS;
			n = c-1;
		} else {
			p -= liS;
			n = c+1;
		}

		if(n >= 0 && n < liSize) {
			running = true;

			slider.animate({ left: p }, o.speed, o.easing, function() {
				running = false;
			});

			d == 'l' ? li.eq(c).animate({ width: wS, marginTop: sP, fontSize: fS }, o.speed, o.easing).prev().animate({ width: wL, marginTop: 0, fontSize: fS*1.2 }, o.speed, o.easing) : li.eq(c).animate({ width: wS, marginTop: sP, fontSize: fS }, o.speed, o.easing).next().animate({ width: wL, marginTop: 0, fontSize: fS*1.2 }, o.speed, o.easing);

			c = n;

			// Get XML
			/*$.ajax({
				type: 'GET',
				url: '/productsproxy.cfm',
				data: 'productid=' + li.eq(c).attr('rel'),
				dataType: 'json',
				success: function(json) {
					displayproductinfo(json, true);
				}
			});
			*/
			updateInfo();
		}
	}

	function displayproductinfo(data, redraw) {
		var cH = $('#rangeCarousel').height();

		var update = [
			{ "cell": "rangeInfo h3", "data": data.NAME },
			{ "cell": "col1title", "data": data.COL1TITLE },
			{ "cell": "col2title", "data": data.COL2TITLE },
			{ "cell": "energykj_1", "data": data.ENERGYKJ_1 },
			{ "cell": "energykj_2", "data": data.ENERGYKJ_2 },
			{ "cell": "energykcal_1", "data": data.ENERGYKCAL_1 },
			{ "cell": "energykcal_2", "data": data.ENERGYKCAL_2 },
			{ "cell": "protein_1", "data": data.PROTEIN_1 },
			{ "cell": "protein_2", "data": data.PROTEIN_2 },
			{ "cell": "carbs_1", "data": data.CARBS_1 },
			{ "cell": "carbs_2", "data": data.CARBS_2 },
			{ "cell": "carbs_sugar_1", "data": data.CARBS_SUGAR_1 },
			{ "cell": "carbs_sugar_2", "data": data.CARBS_SUGAR_2 },
			{ "cell": "carbs_starch_1", "data": data.CARBS_STARCH_1 },
			{ "cell": "carbs_starch_2", "data": data.CARBS_STARCH_2 },
			{ "cell": "fat_1", "data": data.FAT_1 },
			{ "cell": "fat_2", "data": data.FAT_2 },
			{ "cell": "fat_saturates_1", "data": data.FAT_SATURATES_1 },
			{ "cell": "fat_saturates_2", "data": data.FAT_SATURATES_2 },
			{ "cell": "fat_monounsaturates_1", "data": data.FAT_MONOUNSATURATES_1 },
			{ "cell": "fat_monounsaturates_2", "data": data.FAT_MONOUNSATURATES_2 },
			{ "cell": "fat_polyunsaturates_1", "data": data.FAT_POLYUNSATURATES_1 },
			{ "cell": "fat_polyunsaturates_2", "data": data.FAT_POLYUNSATURATES_2 },
			{ "cell": "fat_transfat_1", "data": data.FAT_TRANSFAT_1 },
			{ "cell": "fat_transfat_2", "data": data.FAT_TRANSFAT_2 },
			{ "cell": "fibre_1", "data": data.FIBRE_1 },
			{ "cell": "fibre_2", "data": data.FIBRE_2 },
			{ "cell": "sodium_1", "data": data.SODIUM_1 },
			{ "cell": "sodium_2", "data": data.SODIUM_2 },
			{ "cell": "salt_1", "data": data.SALT_1 },
			{ "cell": "salt_2", "data": data.SALT_2 },
			{ "cell": "ingredients", "data": data.INGREDIENTS },
			{ "cell": "allergyadvice", "data": data.ALLERGYADVICE },
			{ "cell": "updatedat", "data": data.UPDATEDAT }
		];

		$('#rangeInfo').fadeOut(500, function() {
			for(i = 0; i < update.length; i++) {
				$('#' + update[i].cell).text(update[i].data);
			}
			
			$(this).fadeIn(500, function() {
				//var nH = $('#rangeCarousel').height();

				//if($.browser.msie && cH !== nH) {
					
					//console.log(h);
					//$('#rangeCarousel').css('height', h);
					//curvyCorners.adjust(document.getElementById('rangeCarousel'), 'height', nH);
					//curvyCorners.redraw();
				//}
			});
		});
		/*
		for(i = 0; i < update.length; i++) {
			$('#' + update[i].cell).text(update[i].data);
		}

		var h = $('#rangeCarousel').innerHeight();

		if($.browser.msie) {
			var h = $('#rangeCarousel').innerHeight();
			$('#rangeCarousel').css('height', 2000);
			curvyCorners.redraw();
		}
		*/

		

/* 		if(redraw === true && $.browser.msie) {
			curvyCorners.redraw(); // redraw curvy corners for IE
		} */

		/*
		$('#rangeInfo').fadeOut(500, function() {
			var me = $(this); // cache the selector

			$('#rangeInfo h3').html(data.NAME);
			$('#col1title').html(data.COL1TITLE);
			$('#col2title').html(data.COL2TITLE);
			$('#energykj_1').html(data.ENERGYKJ_1);
			$('#energykj_2').html(data.ENERGYKJ_2);
			$('#energykcal_1').html(data.ENERGYKCAL_1);
			$('#energykcal_2').html(data.ENERGYKCAL_2);
			$('#protein_1').html(data.PROTEIN_1);
			$('#protein_2').html(data.PROTEIN_2);
			$('#carbs_1').html(data.CARBS_1);
			$('#carbs_2').html(data.CARBS_2);
			$('#carbs_sugar_1').html(data.CARBS_SUGAR_1);
			$('#carbs_sugar_2').html(data.CARBS_SUGAR_2);
			$('#carbs_starch_1').html(data.CARBS_STARCH_1);
			$('#carbs_starch_2').html(data.CARBS_STARCH_2);
			$('#fat_1').html(data.FAT_1);
			$('#fat_2').html(data.FAT_2);
			$('#fat_saturates_1').html(data.FAT_SATURATES_1);
			$('#fat_saturates_2').html(data.FAT_SATURATES_2);
			$('#fat_monounsaturates_1').html(data.FAT_MONOUNSATURATES_1);
			$('#fat_monounsaturates_2').html(data.FAT_MONOUNSATURATES_2);
			$('#fat_polyunsaturates_1').html(data.FAT_POLYUNSATURATES_1);
			$('#fat_polyunsaturates_2').html(data.FAT_POLYUNSATURATES_2);
			$('#fat_transfat_1').html(data.FAT_TRANSFAT_1);
			$('#fat_transfat_2').html(data.FAT_TRANSFAT_2);
			$('#fibre_1').html(data.FIBRE_1);
			$('#fibre_2').html(data.FIBRE_2);
			$('#sodium_1').html(data.SODIUM_1);
			$('#sodium_2').html(data.SODIUM_2);
			$('#salt_1').html(data.SALT_1);
			$('#salt_2').html(data.SALT_2);
			$('#ingredients').html(data.INGREDIENTS);
			$('#allergyadvice').html(data.ALLERGYADVICE);
			$('#updatedat').html(data.UPDATEDAT);

			if($.browser.msie) curvyCorners.redraw(); // redraw curvy corners for IE

			me.fadeIn(500); // we should only fade in once the original fade has been completed
		});
		*/
	}

	function updateInfo() {
		$.ajax({
				type: 'GET',
				url: '/productsproxy.cfm',
				data: 'productid=' + li.eq(c).attr('rel'),
				dataType: 'json',
				success: function(data) {
					var update = [
						{ "cell": "rangeInfo h3", "data": data.NAME },
						{ "cell": "col1title", "data": data.COL1TITLE },
						{ "cell": "col2title", "data": data.COL2TITLE },
						{ "cell": "energykj_1", "data": data.ENERGYKJ_1 },
						{ "cell": "energykj_2", "data": data.ENERGYKJ_2 },
						{ "cell": "energykcal_1", "data": data.ENERGYKCAL_1 },
						{ "cell": "energykcal_2", "data": data.ENERGYKCAL_2 },
						{ "cell": "protein_1", "data": data.PROTEIN_1 },
						{ "cell": "protein_2", "data": data.PROTEIN_2 },
						{ "cell": "carbs_1", "data": data.CARBS_1 },
						{ "cell": "carbs_2", "data": data.CARBS_2 },
						{ "cell": "carbs_sugar_1", "data": data.CARBS_SUGAR_1 },
						{ "cell": "carbs_sugar_2", "data": data.CARBS_SUGAR_2 },
						{ "cell": "carbs_starch_1", "data": data.CARBS_STARCH_1 },
						{ "cell": "carbs_starch_2", "data": data.CARBS_STARCH_2 },
						{ "cell": "fat_1", "data": data.FAT_1 },
						{ "cell": "fat_2", "data": data.FAT_2 },
						{ "cell": "fat_saturates_1", "data": data.FAT_SATURATES_1 },
						{ "cell": "fat_saturates_2", "data": data.FAT_SATURATES_2 },
						{ "cell": "fat_monounsaturates_1", "data": data.FAT_MONOUNSATURATES_1 },
						{ "cell": "fat_monounsaturates_2", "data": data.FAT_MONOUNSATURATES_2 },
						{ "cell": "fat_polyunsaturates_1", "data": data.FAT_POLYUNSATURATES_1 },
						{ "cell": "fat_polyunsaturates_2", "data": data.FAT_POLYUNSATURATES_2 },
						{ "cell": "fat_transfat_1", "data": data.FAT_TRANSFAT_1 },
						{ "cell": "fat_transfat_2", "data": data.FAT_TRANSFAT_2 },
						{ "cell": "fibre_1", "data": data.FIBRE_1 },
						{ "cell": "fibre_2", "data": data.FIBRE_2 },
						{ "cell": "sodium_1", "data": data.SODIUM_1 },
						{ "cell": "sodium_2", "data": data.SODIUM_2 },
						{ "cell": "salt_1", "data": data.SALT_1 },
						{ "cell": "salt_2", "data": data.SALT_2 },
						{ "cell": "ingredients", "data": data.INGREDIENTS },
						{ "cell": "allergyadvice", "data": data.ALLERGYADVICE },
						{ "cell": "updatedat", "data": data.UPDATEDAT }
					];

					$//('#rangeInfo').fadeOut(500, function() {
						for(i = 0; i < update.length; i++) {
							$('#' + update[i].cell).text(update[i].data);
						}
						
						//$(this).fadeIn();
					//});
				}
			});

		//if($.browser.msie) {
					
					//console.log(h);
					//$('#rangeCarousel').css('height', h);
					//curvyCorners.adjust(document.getElementById('rangeCarousel'), 'height', '2000px');
					//curvyCorners.redraw();
				//}
	}

	// XML Parse, update information
	function xmlParse(xml) {
		$('#rangeInfo').fadeOut(500, function() {
			$(xml).find('row').each(function() {
				alert('row');
			});
		});

		$('#rangeInfo').fadeIn(500);
	}

	// Return jQuery object
	return this.each(function() {
		// If only 1 li is found, position it absolutely and don't create the carousel
		if(liSize == 1) {
			li.eq(0).css('width', o.maxWidth);

			// And position it centrally
			slider.css({
				left: (instance.width() - o.maxWidth)/2,
				marginTop: (parent.height() - o.maxHeight)/2
			});
			
			/*
			$.ajax({
  				type: 'GET',
  				url: '/productsproxy.cfm',
  				data: 'productid=' + li.eq(0).attr('rel'),
  				dataType: 'json',
  				success: function(json) {
					displayproductinfo(json, false);
				}
  			});
			*/
			
			updateInfo();
		} else {
				// Calculate and set widths
  			c = Math.floor(liSize / 2); // find the central element
  			wL = o.maxWidth; // get the width of the central element
  			wS = parseInt(wL * 0.90); // calculate the widths of the small elements
  			liP = parseInt(((instance.width() - (((o.visible-1)*wS)+wL)) / o.visible)); // calculate the necessary padding
  			liL = wL+liP; // calculate the outer width of the central element
  			liS = wS+liP; // calculate the outer width of the small elements

  			// Set the widths and padding
  			li.css({
  				width: wS,
  				paddingLeft: liP/2,
  				paddingRight: liP/2
  			});

  			// set the width for the central element
  			li.eq(c).css('width', wL);

  			tW = ((liSize-1)*liS) + liL; // calculate the total width
  			iHl = o.maxHeight // get the height of the central image
  			iHs = Math.floor(o.maxHeight * 0.90) // get the height of the small image
  			sP = iHl - iHs; // calculate the difference in height for padding

  			// set the padding for the small elements
  			li.not(':eq('+c+')').css('marginTop', sP);

  			// calculate the font size
  			fS = parseInt(li.css('fontSize'));
  			li.eq(c).css('fontSize', fS*1.2);

  			// Set the height, weight and position of the ul
  			slider.css({
  				width: tW,
  				marginTop: parseInt((parent.height()-o.maxHeight)/2),
  				left: 0 // Set left value to avoid 'auto' value
  			});

  			// Calculate and set the slider boundries
  			limit.min = -tW + ((o.visible-Math.floor(o.visible/2))*liS);
  			limit.max = Math.floor(o.visible/2)*liS;

  			// Create previous button
  			$('<div/>', {
  				click: function() {
  					slide('l');
  				}
  			}).addClass('btnPrev').appendTo(parent);

  			// Create next button
  			$('<div/>', {
  				click: function() {
  					slide('r');
  				}
  			}).addClass('btnNext').appendTo(parent);

  			if(liSize <= o.visible) {
  				iP = Math.floor((o.visible-liSize)/2)*liS;
  			} else {
  				if(liSize%2 == 0) {
  					iP = -Math.ceil((liSize-o.visible)/2)*liS;
  				} else {
  					iP = -Math.floor((tW-instance.width())/2);
  				}
  			}

  			// set the position
  			slider.css('left', iP);

			updateInfo();
					
			/*
			$.ajax({
  				type: 'GET',
  				url: '/productsproxy.cfm',
  				data: 'productid=' + li.eq(c).attr('rel'),
  				dataType: 'json',
  				success: function(json) {
					displayproductinfo(json, false);
				}
  			});
			*/
		}
	});
}
