(function($){

	function getStockInfo(el, q){
		q = q || 0;
		var arr = $(el).attr('rel').split(':'),
			res = {
				stock		: parseFloat(arr[0]),
				stockSet	: parseFloat(arr[1]),
				min			: parseFloat(arr[2]),
				minOnline	: parseFloat(arr[3]),
				minOffline	: parseFloat(arr[4]),
				max			: parseFloat(arr[5]),
				count		: parseFloat(arr[6]),			// ROW quantity in cart
				countSet	: parseFloat(arr[7]),			// SET quantity in cart
				onsale		: arr[8] > 0 ? true : false,
				sale		: parseFloat(arr[9]),			// ROW sale stock
				saleSet		: parseFloat(arr[10]),			// SET sale set stock 
				ignoreMin	: parseFloat(arr[11]),

				quantity	: q,
				out			: false,						// ROW out of stock flag
				outOrig		: false,
				isMin		: false,
				isMax		: false,
				ignoreMinReached : false,
				must		: 0,
				inCart		: false							// if TRUE we are editing cart now, otherwise product item page.
			};
		if (res.onsale){
			res.outOrig = res.count > res.sale;
			res.out = q + res.count > res.sale;
		} else {
			res.outOrig = res.count > res.stock;
			res.out = q + res.count > res.stock;
		}
		if (res.stock <= 0 && !res.onsale || res.onsale && res.sale <= 0) res.out = true;
		res.min = res.out ? res.minOffline : res.minOnline;
		if (res.out){
			if (q + res.count >= res.ignoreMin && res.ignoreMin > 0){
				// ignore minimum backorder beacause benchmark of disregard backorder is reached
				res.isMin = false;
				res.ignoreMinReached = true;
			} else {
				res.isMin = q - (res.onsale ? res.sale : res.stock) + res.count < res.min;
				res.must = res.min + (res.onsale ? res.sale : res.stock);
				if (res.must > res.ignoreMin && res.ignoreMin > 0) res.must = res.ignoreMin;
			}
		} else {
			res.isMin = q + res.countSet < res.min;
		}
		res.isMax = q + res.count > res.max && res.max > 0;
		return res;
	}
	
	function setStockInfo(el, info){
		var str = info.stock + ':' + info.stockSet + ':' + info.min + ':'
			+ info.minOnline + ':' + info.minOffline + ':' + info.max + ':'
			+ info.count + ':' + info.countSet + ':' + (info.onsale ? 1 : 0) + ':'
			+ info.sale + ':' + info.saleSet + ':' + info.ignoreMin;
		$(el).attr('rel', str);
	}
	
	function getProductData(el, set){
		if (!set) set = {onsale : false, sale : 0, saleSet : 0};
		var $el = $(el), res = {ajax: 1, color: [], quantity: {}, action : "put"};
		
		if ($el.get(0).tagName == 'LI'){
			res.product = $el.attr('value');
		} else {
			res.product = $el.find('input[name="product_id"]').val();
		}
		
		$el.find('input[name="color[]"]:checked').each(function(){
			res.color.push($(this).val());
		});
		$el.find('input[name^="quantity"]').each(function(){
			var arr = $(this).attr('name').split('['), value = parseFloat(value = $(this).val());
			if (arr.length == 3){
				var color = parseInt(arr[1].substr(0, arr[1].length - 1)), 
					size = parseInt(arr[2].substr(0, arr[2].length - 1));
				if (!res.quantity[color]) res.quantity[color] = {};
				res.quantity[color][size] = set.onsale && value > set.sale ? set.sale : value;
			} else if (arr.length == 2){
				var id = parseInt(arr[1].substr(0, arr[1].length - 1));
				res.quantity[id] = set.onsale && value > set.sale ? set.sale : value;
			} else {
				res.quantity = set.onsale && value > set.saleSet ? set.saleSet : value;
			}
		});
		res.extended = $.jShoppingCart.extended ? 1 : 0;
		return res;
	}
	
	function putInCart(el, set){
		if (!set) set = {onsale : false, sale : 0, saleSet : 0};
		var $el = $(el);
		$el.showLoading();
		$.post($.jShoppingCart.url, getProductData($el, set), function(res){
			$el.hideLoading();
			if (res.result){
				if (res.html) $.jShoppingCart.reload(res.html);
				if ($el.get(0).tagName == 'LI'){
					//$el.effect('transfer', {to : '#shopping-cart', className : 'ui-effects-transfer'}, 2000);
				} else {
					if ($('#popup-product-box').size())	$el.effect('fold', {}, 500, function(){
						$('#popup-product-box').hide();
					});
				}
				if (res.amount) {
					$el.find('.js-in-cart').text(res.amount);
				}
				if (res.stock) {
					if (typeof res.stock == 'object')
						for (var k in res.stock) $el.find('input[name="quantity'+k+'"]').attr('rel', res.stock[k]);
					else 
						$el.find('input[name="quantity"]').attr('rel', res.stock);
				}
				if (res.msg) showMessage(res.msg);
				//showMessage('Added to cart '+count+' items');
				$el.find('input[name="color[]"]:checked').attr('checked', false);
				$el.find('input[name^="quantity"]').val('');
			} else if (res.msg) {
				showError(res.msg);
			}
		}, 'json');
		
	}
	
	$.jShoppingCartStockInfo = function(el){
		return getStockInfo(el);
	}
	
	$.fn.jShoppingCartTooltip = function(which, info, fn, hideTooltip){
		fn = fn || null;
		hideTooltip = hideTooltip || false;
		var options = {
			dialog : false
		};
		
		return this.each(function(){
			if (hideTooltip){
				$('#shopping-cart-tooltip').remove();
				if (typeof fn == 'function') fn.call(this, true, 'removed', info);
				return false;
			}
			if (this.tagName != 'INPUT' && this.tagName != 'SELECT') return;
			if (!which || !info) return;
			
			var $tip = $('#shopping-cart-tooltip');
			if (!$tip.size()){
				if (options.dialog){
					$tip = $('<div id="shopping-cart-tooltip"><div class="mask"></div><div class="cont"><div class="text"></div><div class="submit"><a href="#submit" class="submit-btn"></a></div><div class="close"><a href="#close"></a></div><div class="right"></div><div class="clear"></div></div></div>');
				} else {
					$tip = $('<div id="shopping-cart-tooltip"><div class="wrap"><div class="cont"><div class="text"></div></div><div class="clear"></div></div><div class="shopping-cart-tooltip-bottom"></div></div>');
				}
				$tip.appendTo($('body:first'));
			}
			var text = '', button = '';
			switch (which){
				case 'invalid':
					text = _T('Incorrect quantity');
					break;
				case 'sale?':
					text = _T('Sale out of stock', {'{stock}' : info.sale, '{quantity}' : info.quantity});
					button = _T('Accept');
					break;
				case 'item?':
					var str = '', inCart = info.count > 0 && !info.inCart;
					if (info.ignoreMinReached){
						str = inCart ? 'Item out of stock+ignored+cart' : 'Item out of stock+ignored';
					} else if (info.isMin){
						str = inCart ? 'Item out of stock+backorder+cart' : 'Item out of stock+backorder';
					} else {
						str = inCart ? 'Item out of stock+cart' : 'Item out of stock';
					}
					text = _T(str, {'{stock}' : info.stock, '{quantity}' : info.quantity, 
						'{remain}' : info.quantity - info.stock, '{cart}' : info.count, 
						'{min}' : info.minOffline, '{must}' : info.must,
						'{amount}' : info.quantity + info.count, '{more}' : info.must - info.count });
					button = _T('Accept');
					break;
				case 'min':
					text = _T('Min. order quantity is', {'{min}' : info.min});
					button = _T('Accept');
					break;
				case 'max':
					text = _T(info.count ? 'Max. order quantity is+cart' : 'Max. order quantity is', 
						{'{max}' : info.max, '{cart}' : info.count, '{amount}' : info.quantity + info.count});
					button = _T('Accept');
					break;
			}
			$tip.removeClass('left-side right-side');
			$tip.find('.wrap').removeClass('left-side right-side');
			$tip.find('.text').html(text);
			$tip.find('.submit-btn').text(button);
			$tip.show();
			
			var $input = $(this);
			
			function initPosition(){
				var left = $input.offset().left + $input.outerWidth(true), $cont = $tip;
				if (options.dialog){
					$tip.css('height', $('body:first').outerHeight()+'px');
					$cont = $tip.find('.cont');
					$('body:first').css('overflow', 'hidden');
				}
				if (left + $cont.outerWidth(true) >= $('body:first').outerWidth()){
					// show at the left side, because not enough space at the right side
					left = $input.offset().left - $cont.outerWidth(true);
					$tip.addClass('left-side');
					$tip.find('.wrap').addClass('left-side');
				} else {
					$tip.addClass('right-side');
					$tip.find('.wrap').addClass('right-side');
				}
				$cont.css('left', left + 'px').css('top', $input.offset().top);
			}
			
			function submit(){
				if (typeof fn == 'function') fn.call($tip.get(0), true, which, info);
				$tip.hide();
				$('body:first').css('overflow', 'auto');
			}
			
			function cancel(){
				if (typeof fn == 'function') fn.call($tip.get(0), false, which, info);
				$tip.hide();
				$('body:first').css('overflow', 'auto');
			}
			
			function close(){
				$tip.remove();
			}
		
			$tip.find('a[href$="#submit"]').unbind('click').click(function(){
				submit();
				return false;
			});
			
			$tip.find('a[href$="#close"]').unbind('click').click(function(){
				cancel();
				return false;
			});
			
			$tip.unbind('click').click(function(){
				if (options.dialog) return false;
				close();
				return false;
			});

			initPosition();
			if (!options.dialog){
				if (typeof fn == 'function') fn.call(this, false, which, info);
			}
			
			$(window).resize(function(){
				initPosition();
			});
		});
	}
	
	function showTooltip(el, which, info, fn){
		if (info.error) $(el).addClass('wrong'); else $(el).removeClass('wrong');
		$(el).jShoppingCartTooltip(which, info, fn);
	}
	
	function hideTooltip(el){
		el = el || null;
		if (el){
			$(el).removeClass('wrong');
			$(el).jShoppingCartTooltip(null, null, null, true);
		} else {
			$('#shopping-cart-tooltip').remove()
		}
	}
	
	function getValueString(el){
		var $li = $(el).parents('li:first'), str = '';
		str = (parseInt($li.find(':input[name$="[Size]"]').val()) || 0) + ':'
			+ (parseInt($li.find('input[name$="[Color]"]:checked').val()) || 0) + ':'
			+ $(el).val();
		return str;
	}
	
	function getPrimaryString(el){
		var $li = $(el).get(0).tagName == 'LI' ? $(el) : $(el).parents('li:first'), str = '';
		str = (parseInt($li.find(':input[name$="[Size]"]').val()) || 0) + ':'
			+ (parseInt($li.find('input[name$="[Color]"]:checked').val()) || 0);
		return str;
	}
	
	var cartSets = [];
	
	function getSetId(el){
		var id = el;
		if (typeof el == 'object'){
			if ($(el).get(0).tagName != 'LI') el = $(el).parents('li:first');
			id = parseInt($(el).attr('value'));
		}
		return id;
	}
	
	function getItemSet(el, includeMe){
		includeMe = includeMe || false;
		var id = getSetId(el), found = null;
		for (var i = 0; i < cartSets.length; i++){
			var set = cartSets[i];
			for (var j = 0; j < set.length; j++){
				if (id == set[j]) found = set;
				if (found) break;
			}
			if (found) break;
		}
		if (includeMe || !found) return found;
		var res = [];
		for (i = 0; i < found.length; i++){
			if (found[i] == id) continue;
			res.push(found[i]);
		}
		return res;
	}
	
	function isItemInSet(el){
		var id = getSetId(el), found = false;
		for (var i = 0; i < cartSets.length; i++){
			var set = cartSets[i];
			for (var j = 0; j < set.length; j++){
				if (id == set[j]) found = true;
				if (found) break;
			}
			if (found) break;
		}
		return found;
	}
	
	function putSet(set){
		cartSets.push(set);
	}
	
	$.jShoppingCart = {
		
		url : '/shopping-cart',
		element : null,
		extended : null,
		footer : {},
		
		// adding items to shopping cart from product info box.
		add : function(el, fn){
			if (!fn) fn = null;
			var self = this, $item = $(el).parents('.js-product:first'), res = true, test = true, total = 0;
				
			function resetValues(){
				$item.find('input[name^="quantity"]').val('');
			}
			
			// check all fields for correct values
			$item.find(':input[name^="quantity"]').each(function(){
				total += parseFloat($(this).val()) || 0;
				if (!self.check(this, null, true)){
					test = false;
					return false;
				}
			});
			if (!test || total == 0){
				if (total == 0) showError(_T('Nothing to add'));
				if (typeof fn == 'function') fn.call(this, false);
				return false;
			}
		
			// check for minimum in stock amount for SET
			var quantity = 0;
			$(el).parents('.js-product:first').find(':input[name^="quantity"]').each(function(){
				quantity += parseFloat($(this).val()) || 0;
			});
			var info = getStockInfo($item.find(':input[name^="quantity"]:first'), quantity);
			if (info.isMin && !info.out){
				showError(_T('Min. order quantity is', {'{min}' : info.min}));
				if (typeof fn == 'function') fn.call(this, false);
				return false;
			}
			
			putInCart($item);
			if (typeof fn == 'function') fn.call(this, true);
			return true;
		},
		
		getCartItemQuantity : function(el, set){
			set = set || false;
			var $ul = $(el).parents('ul:first'), 
				pri = getPrimaryString(el), quantity = 0;
			$ul.find('> li[rel="'+$(el).parents('li:first').attr('rel')+'"]').each(function(){
				if (pri == getPrimaryString(this) || set) 
					quantity += parseFloat($(this).find(':input[name$="[Quantity]"]').val()) || 0;
			});
			return quantity;
		},
		
		getCartStockInfo : function(el, info){
			info = info || {stock : 0};
			var q = this.getCartItemQuantity(el), res = getStockInfo(el, q - info.count);
			res.quantity = q;
			return res;
		},
		
		getCartSetItems : function(el, del){
			del = del || false;
			if ($(el).get(0).tagName != 'LI'){
				el = $(el).parents('li:first');
			}
			var id = $(el).find(':input[name$="[Product]"]').val(), items = [];
			$(this.element).find(':input[name$="[Product]"]').each(function(){
				if ($(this).val() == id){
					var $li = $(this).parents('li:first');
					if (del && !$li.find(':input[name="bulk[]"]').attr('checked') || !del){
						items.push($li.find(':input[name$="[Quantity]"]'));
					}
				}
			});
			return items;
		},
		
		checkInStockMin : function(li, update){
			if (!update) update = false;
			var self = this, $li = $(li), id = $li.find(':input[name$="[Product]"]').val(), items = 0,
				el = $li.find(':input[name$="[Quantity]"]'),
				info = getStockInfo(el), quantity = update ? (self.getCartItemQuantity(el) - info.count) : -info.count;
			$(this.element).find(':input[name$="[Product]"]').each(function(){
				var $item = $(this).parents('li:first'), 
					$inp = $item.find(':input[name$="[Quantity]"]');
				if (id == $(this).val()){
					var stock = self.getCartStockInfo($inp);
					if (!stock.out) items++;
				}
			});
			var info = getStockInfo(el, quantity);
			if (info.isMin && !info.out && items > (update ? 0 : 1)){
				showError(_T(update ? 'Min. order quantity is' : 'Min. order quantity is!', {'{min}' : info.min}));
				return false;
			}
			return true;
		},
		
		// checks for quantity conditions
		check : function(el, fn, errorsOnly){
			fn = fn || null;
			errorsOnly = errorsOnly || false;
			var q = parseFloat($(el).val()) || 0, info = getStockInfo(el, q),
				isCart = !$(el).is('[name^="quantity"]');
			
			if (isCart){
				info = this.getCartStockInfo(el, info);
				info.inCart = true;
				q = info.quantity;
			}
			info.error = true;
			// invalid quantity condition
			if (q <= 0 && ($(el).val() != '' || isCart)){
				showTooltip(el, 'invalid', info, fn);
				return false;
			}
			if (q > 0){
				// maximum amount condition
				if (info.isMax){
					showTooltip(el, 'max', info, fn);
					return false;
				}
				// out of stock condition
				if (info.outOrig && !info.count || info.out 
					|| info.out && info.outOrig && info.inCart){
					if (info.onsale){
						showTooltip(el, 'sale?', info, fn);
						return false;
					} else {
						// check for error not enough quantity for backorder
						if (!info.isMin) info.error = false;

						if (!errorsOnly || errorsOnly && info.error){
							showTooltip(el, 'item?', info, fn);
							return false;
						}
					}
				}
				// minimum out of stock amount condition
				if (info.out && info.isMin){
					showTooltip(el, 'min', info, fn);
					return false;
				}
			}
			hideTooltip(el);
			if (typeof fn == 'function') fn.call(this, true, null, info);
			return true;
		},
		
		//
		update : function(el){
			el = el || null;
			var self = this, test = true, $div = $(this.element), $ul = $div.find('ul:first');
			if (el){
				var $li = $(el).parents("li:first"), el = $li.find(':input[name$="[Quantity]"]'), 
					info = this.getCartStockInfo(el);
				
				// check for minimum in stock amount for SET
				if (!info.out && !this.checkInStockMin($li, true)) return false;
			} else {
				var changed = false;
				$ul.find(':input[name$="[Quantity]"]').each(function(){
					if (getValueString(this) != $(this).data('initValues')){
						changed = true;
						return false;
					}
				});
				if (!changed){
					showError(_T('No items changed'));
					return false;
				}
			}

			// check all fields for correct values
			$ul.find('> li').each(function(){
				var $inp = $(this).find(':input[name$="[Quantity]"]');
				if (!self.check($inp, null, true)){
					$(document).scrollTo($inp.parents('li:first'), 500, {axis : 'y', easing : 'easeOutBack'});
					test = false;
					return false;
				}
			});
			if (!test) return false;
			
			return true;
		},
		
		drop : function(el){
			el = el || null;
			var self = this, $div = $(this.element), ids = [];
			if (el){
				var $li = $(el).parents("li:first"),
					el = $li.find(':input[name$="[Quantity]"]'), 
					info = this.getCartStockInfo(el);
				
				// check for minimum in stock amount for SET
				if (!info.out && !self.checkInStockMin($li)) return false;
				
				ids.push($li.attr('value'));
			} else {
				var $selected = $div.find('ul:first').find('> li :input[name="bulk[]"]:checked'), 
					test = true, stock = null;
				if ($selected.size()){
					$div.find(':input[name$="[Quantity]"]').each(function(){
						var arr = self.getCartSetItems(this, true), total = 0;
						for (var i = 0; i < arr.length; i++){
							var info = getStockInfo(arr[i]);
							total += info.onsale ? info.sale : info.count;
						}
						if (arr.length > 0){
							var info = getStockInfo(arr[0]);
							if (info.minOnline > total){
								el = arr[0];
								stock = info;
								stock.min = info.minOnline;
								test = false;
								return false;
							}
						}
					});
					if (!test){
						$(document).scrollTo($(el).parents('li:first'), 500, {axis : 'y', easing : 'easeOutBack'});
						showTooltip(el, 'min', stock);
						return false;
					}
					$selected.each(function(){
						ids.push($(this).parents('li:first').attr('value'));
					});
				} else {
					showError(_T('No items selected'));
					return false;
				}
			}
			
			$div.showLoading();
			var data = {ajax : 1, "delete": 1, ids : ids};
			hideTooltip();
			$.post($.jShoppingCart.url, data, function(res){
				$div.hideLoading();
				if (res.result){
					if (res.html){
						$div.jShoppingCartBox({html : res.html});
					}
					if (res.msg) showMessage(res.msg);
				} else {
					if (res.msg) showError(res.msg);
				}
				$('#shopping-cart-footer').trigger('initBottom');
			}, 'json');
		},
		
		reload : function(html){
			$(this.element).jShoppingCartBox({html : html});
		},
		
		init : function(el){
			$(el).jShoppingCartBox();
			this.element = el;
			this.extended = $(el).hasClass('edit-shopping-cart') ? true : false;
		}
		
	};
	
	$.fn.jShoppingCartBox = function(o){
		var defaults = {
			html : null,
			reloadEmpty : false
		};
		var options = $.extend(defaults, o || {});
		
		return this.each(function(){
			var $div = $(this), $cont = $div.find('.js-content:first');
			
			if (!$cont.size()) $cont = $div;
			
			function reloadCart(){
			}
			
			function initCart(show){
				if (show && !$div.is(':visible')){
					var $box = $div.prev();
					if (!$box.size()) $box = $div.next();
					if ($box.size()) $box.hide();
					$div.show();
				}
				
				var $form = $div.find('form:first'), $ul = $form.find('ul:first');
				
				if ($form.attr('action')) $.jShoppingCart.url = $form.attr('action');
				
				function postUpdate(){
					$div.find(':input[name^="stock["]').remove();
					$div.showLoading();
					var data = $form.getFields({submit : 1, ajax : 1});
					for (var k in data){
						if (/\[Color\]$/.test(k)){
							if (typeof data[k] == 'object' && data[k][0]){
								data[k] = data[k][0];
							}
						}
					}
					hideTooltip();
					$.post($.jShoppingCart.url, data, function(res){
						$div.hideLoading();
						if (res.result){
							if (res.html){
								//$div.html(res.html);
								//initCart();
								$div.jShoppingCartBox({html : res.html});
							}
							if (res.msg) showMessage(res.msg);
						} else {
							if (res.msg) showError(res.msg);
						}
						$('#shopping-cart-footer').trigger('initBottom');
					}, 'json');
				}
				
				function getProductAmount(el, orig){
					if (!orig) orig = false;
					var amount = 0;
					$div.find('input[name$="[Product]"][value="'+$(el).find('input[name$="[Product]"]').val()+'"]').each(function(){
						var $li = $(this).parents('li:first');
						if (orig){
							amount += parseFloat($li.find('.js-value').text());
						} else {
							amount += parseFloat($li.find('input[name$="[Quantity]"]').val()) || 0;
						}
					});
					return amount;
				}
				
				function resetValues(){
					$ul.find('> li').each(function(){
						var value = parseFloat($(this).find('.js-value').text()) || 0;
						$(this).find('input[name$="[Quantity]"]').val(value);
					});
				}

				// Change color handler
				function onItemChange(el, which){
					which = which || null;
					if ($(el).get(0).tagName != 'LI') el = $(el).parents('li:first');
					var size = 0, color = 0;
					$(el).find(':input[name$="[Size]"]').each(function(){
						if (this.tagName == 'SELECT')
							size = parseFloat($(this).find('> option:selected').val()) || 0;
						else
							size = parseFloat($(this).val()) || 0;
					});
					$(el).find(':input[name$="[Color]"]').each(function(){
						if (this.type == 'checkbox'){
							color = parseFloat($(el).find(':input[name$="[Color]"]:checked').val()) || 0;
							return false;
						} else
							color = parseFloat($(this).val()) || 0;
					});
					
					var $stock = $(el).find(':input[name="stock['+size+']['+color+']"]'),
						$inp = $(el).find(':input[name$="[Quantity]"]');
					$inp.attr('rel', $stock.attr('rel'));
					if ($inp.size() == 1)
						checkItem($inp);
					else
						$(el).find(':input[name$="[Quantity]"]').change();
				}
				
				function checkItem(el){
					if (!/^\d$/.test($(el).val())) $(el).val($(el).val().replace(/[^0-9]+/g, ''));
					
					$.jShoppingCart.check(el);
				}
				
				// color picker for colored items, connects also out of stock color icon
				$div.find('div.js-color-picker').jColorPicker({
					onChange : function(a){
						var $a = $(a);
						$(this).parents('li:first').each(function(){
							var $img = $a.find('img:first');
							$(this).find('img.js-fixed')
								.attr('src', $img.attr('src'))
								.attr('alt', $img.attr('alt'))
								.attr('title', $img.attr('title'));
						});
						onItemChange($(this).parents('li:first'), 'color');
					}
				});
				
				// Edit shopping cart button
				$div.find('.js-edit-btn').unbind('click').click(function(){
					var $form = $div.find('form:first');
					if ($form.size()) redirect($form.attr('action'));
					return false;
				});
				
				// size selectbox handler for sized items, connects also out of stock size label
				$div.find('select[name$="[Size]"]').unbind('change').change(function(){
					$(this).parents('li:first').find('span.js-fixed')
						.text($(this).find('option:selected').text());
					onItemChange($(this).parents('li:first'), 'size');
				});
				
				// Init quantity fields 
				$div.find(':input[name$="[Quantity]"]').each(function(){
					// store init values
					$(this).data('initValues', getValueString(this));
					// init cartSets
					/* 
					var $li = $(this).parents('li:first');
					if (!isItemInSet($li)){
						var set = [];
						set.push(parseInt($li.attr('value')));
						$li.nextAll('[rel="'+$li.attr('rel')+'"]').each(function(){
							set.push(parseInt($(this).attr('value')));
						});
						putSet(set);
					}
					*/
					
					// Change quantity value
					$(this).bind('keyup keypress', $.debounce(function(){
							checkItem(this);
						}, 300))
					.blur(function(){
						hideTooltip(this);
					});
				});
				
				// Update shopping cart button
				$div.find('a[href$="#update"]').unbind('click').click(function(){
					if ($.jShoppingCart.update(this)) postUpdate();
					return false;
				});
				$('#shopping-cart-footer :button[name="update"]').unbind('click').click(function(){
					if ($.jShoppingCart.update()) postUpdate();
					return false;
				});
				
				// Delete (in stock and out of stock) shopping cart buttons
				$div.find('a[href$="#delete"]').unbind('click').click(function(){
					$.jShoppingCart.drop(this);
					return false;
				});
				$('#shopping-cart-footer :button[name="delete"]').unbind('click').click(function(){
					$.jShoppingCart.drop();
					return false;
				});
				
				$div.find(':input[name="selectall"]').unbind('change').change(function(){
					$div.find(':input[name="bulk[]"]').attr('checked', $(this).attr('checked'));
				});
				$div.find(':input[name="bulk[]"]').unbind('change').change(function(){
					if ($div.find(':input[name="bulk[]"]:not(:checked)').size())
						$div.find(':input[name="selectall"]').attr('checked', false);
					else
						$div.find(':input[name="selectall"]').attr('checked', true);
				});
				
				$div.find('.js-product-list').each(function(){
					var el = $(this).get(0).tagName == 'TABLE' ? '> tbody > tr' : '> li';
					$(this).find(el).jProductItem({
						extendedCart : $.jShoppingCart.extended,
						postUrl : $.jShoppingCart.url
					});
				});
				
				$div.jQueryUI();
			}
			
			if (options.reloadEmpty && !$div.find('input[name^="item["]').size()){
				location.href = location.href;
			}
			
			if (options.html){
				$('#shopping-cart-footer').remove();
				var $cart = $(options.html);
				if ($cart.attr('id') == 'shopping-cart'){
					$cont.html($cart.find('.js-content:first').html());
				} else if ($cart.attr('id') == 'shopping-cart-body') {
					$div.html($cart.html());
				} else {
					$cont.html($cart.html());
				}
			}
			
			var footerScrollBinded = false;
			
			function initBottom(){
				var $footer = $('#shopping-cart-footer');
				if (!$footer.size()) return false;
				var footerOffset = $div.find('.shopping-cart-footer-space').offset();
				
				if (!footerOffset) {
					$footer.hide();
					return false;
				}
				
				if (!$footer.parent().is('body')){
					$footer = $footer.detach();
					$footer.appendTo('body');
				}
			
				var footerPosition = {
					'position' : 'absolute',
					'bottom' : 'auto',
					'top' : footerOffset.top+'px'
				}, $wrap = $footer.find('.wrap');
				
				$footer.css(footerPosition).show();
				$footer.find('.body').css('left', footerOffset.left+'px');
				
				$.jShoppingCart.footer.offset = footerOffset;
				$.jShoppingCart.footer.position = footerPosition;
				
				$footer.unbind('initBottom').bind('initBottom', function(){
					initBottom();
				});
				
				if (!footerScrollBinded){
					$(window).scroll(function(){
						var offset = $.jShoppingCart.footer.offset,
							$footer = $('#shopping-cart-footer'), $wrap = $footer.find('.wrap');
						footerScrollBinded = true;
						if ($(window).scrollTop() <= offset.top 
							&& $(window).scrollTop() + $(window).height() > offset.top + $footer.outerHeight(true)){
							$footer.css($.jShoppingCart.footer.position);
							$wrap.removeClass('fixed');
						} else {
							$footer.css({
								'position' : 'fixed',
								'bottom' : 0,
								'top' : 'auto'
							});
							$wrap.addClass('fixed');
						}
					});
				}
				$(window).scroll();
			}
			
			$(document).ready(function(){
				initBottom();
			});

			initCart(options.html ? true : false);
		});
	}
	
})(jQuery);

