(function($){
	
	var products = {};
	
	function cacheProduct(id, html){
		products[id] = html;
	}
	
	function initPopupBox(){
		var $div = $('#popup-product-box'), $cont = $div.find('.popup-content:first'),
			size = getWindowSize();
		$div.remove();
		//if (!$div.size()){
			$div = $('<div id="popup-product-box" class="popup-product js-product">'
				+'<div class="mask"></div><div class="product-content">'
				+'<a href="#close" class="close"></a><div class="product"></div></div></div>');
			$div.appendTo($('body:first'));
			$div.width(size[0]).height(size[1]);
			$cont = $div.find('.product-content:first');
			var top = (size[3]-$cont.height())/2;
			if (top < 0) top = 10;
			$cont.css({
				'top' : top+'px',
				'left' : (size[2]-$cont.width())/2+'px'
			});
			
			$div.find('.mask:first').click(function(){
				$div.hide();
			});
			
			$div.find('.close').click(function(){
				$div.hide();
				return false;
			});
		//}
		return $cont;
	}

	$.fn.jProductItem = function(o){
		var defaults = {
			extendedCart : false,
			postUrl	: '/shopping-cart'
		};
		var options = $.extend(defaults, o || {});
		
		function popupProduct(url, id, readOnly){
			var $cont = $('#popup-product-box div.product:first');
			
			function initProduct(el){
				$(el).jProductItem({
					extendedCart : options.extendedCart,
					postUrl : options.postUrl
				});
			}
			
			function showProduct(id){
				$cont = initPopupBox();
				$cont.find('.product:first').html(products[id]);
				initProduct($cont);
				$cont.parents('.popup-product:first').show();
			}
			
			if (products[id]){
				showProduct(id);
			} else {
				$('body').showLoading();
				$.post(url, {ajax : 1, readOnly : readOnly ? 1 : 0}, function(res){
					$('body').hideLoading();
					if (res.html){
						cacheProduct(id, res.html);
						showProduct(id);
					}
					if (res.msg) showError(res.msg);
				}, 'json');
			}
		}
		
		function updateInput(el, info){
			$(el).removeClass('sold').attr('title', '');
			if (!$(el).attr('disabled')){
				if (info.count + info.quantity > (info.onsale ? info.sale : info.stock) || info.out)
					$(el).addClass('sold').attr('title', _T('Sold'));
			}
		}

		function checkItem(el, fn){
			if (!/^\d$/.test($(el).val())) $(el).val($(el).val().replace(/[^0-9]+/g, ''));
			
			$.jShoppingCart.check(el, function(res, which, info){
				updateInput(el, info);
			});
		}
		
		function checkItemBlur(el){
			// Hide tooltip
			$(el).jShoppingCartTooltip(null, null, null, true);
		}
		
		return this.each(function(){
			var $item = $(this), $zoomed = $item.find('div.zoomed > img');
			
			$item.find('div.js-color-chooser').each(function(){
				var margin = false;
				$item.find('input[name^="quantity["]').each(function(){
					if ($(this).attr('name').indexOf('][') > 0 
						&& $(this).attr('name').indexOf('][0]') <= 0 && $(this).attr('name').indexOf('[0][') <= 0){
						margin = true;
					}
					return false;
				});
				$(this).jColorChooser({
					marginTop : margin,
					onScrollStop : function(){
						// to show tooltips in correct position
						$(window).resize();
					}
				});
			});
			
			$item.find('ul.images a').click(function(){
				$zoomed.attr('src', $(this).attr('href'));
				return false;
			});
			
			function updateItem(){
				$item.find('input[name^="quantity"]').each(function(){
					updateInput(this, $.jShoppingCartStockInfo(this));
				});
			}
			
			// quantity manipulations
			var $inps = $item.find('input[name^="quantity"]');
			$inps.keyup(function(e){
				if (e.which == 13){
					checkItem(this, function(res){
						if (res) $item.find('.js-add-btn').click();
					});
				}
			}).keydown(function(e){
				if (e.which >= 96 && e.which <= 105 || e.which >= 48 && e.which <= 57){
					// numbers
				} else if (e.which == 8 || e.which == 9 || e.which == 13 || e.which == 46 || (e.which >= 37 && e.which <= 40)) {
					// special keys: tab, backspace, enter, delete and arrows.
				} else {
					return false;
				}
			}).blur(function(){
				checkItemBlur(this);
			});
			$inps.each(function(){
				$(this).bind('keyup keypress focus', $.debounce(function(){
					checkItem(this);
				}, 300));
			});

			if (false && typeof $.fn.mousewheel == 'function'){
				// Doris does not want to use mouse wheel feature.
				$inps.mousewheel(function(event, delta){
					var val = parseFloat($(this).val()) || 0, info = $.jShoppingCartStockInfo(this),
						max = info.onsale ? info.sale - info.count : info.max - info.count;
					
					if (delta > 0){
						if (val < max) $(this).val(val + 1);
					} else {
						if (val > 0) $(this).val(val - 1);
					}
					if ($(this).val() == 0) $(this).val('');
					return false;
				});
			}
			updateItem();
			
			// add item to shopping cart
			$item.find('.js-add-btn').click(function(){
				$.jShoppingCart.add(this, function(res){
					if (res) 
						updateItem(); 
					else {
						$item.find('.js-color-chooser').each(function(){
							var $inp = $item.find(':input[name^="quantity"].wrong:first'),
								$cc = $(this).data('jColorChooser');
							$cc.scrollTo($inp.focus(), true);
						});
					}
				});
				return false;
			});
			
			// show product detail view
			$item.find('a.js-product').click(function(){
				popupProduct($(this).attr('href'), $(this).parents('li:first').attr('value'), $(this).attr('rel') == 'read-only');
				return false;
			});
		});
	}
	
	$.fn.jProductCatalog = function(o){
		var defaults = {
			urlProducts	: '/products',
			urlCart		: '/shopping-cart'
		};
		var options = $.extend(defaults, o || {});
		options.extendedCart = $('#shopping-cart').hasClass('edit-shopping-cart') ? true : false;
		
		return this.each(function(){
			var $div = $(this);

			function initList(){
				var $list = $div.find('.js-product-list');
				$list.find('> li').jProductItem({
					extendedCart : options.extendedCart,
					postUrl : options.urlCart
				});
				
				function getPostData(o){
					var obj = o || {};
					obj.page = $div.find('ul.pages li.js-checked').attr('value');
					return $div.find('.js-filter-box').getFields(obj);
				}
				
				function loadList(scrollTop){
					if (!scrollTop) scrollTop = false;
					$div.showLoading();
					$.post(options.urlProducts, getPostData({ ajax : 1 }), function(res){
						$div.html(res);
						initList();
						$div.hideLoading();
						if (scrollTop && typeof $.fn.scrollTo == 'function'){
							$(document).scrollTo($div, 500, {axis : 'y', easing : 'easeOutBack'});
						}
					}, 'html');
				}
				
				$div.find('ul.pages a').click(function(){
					var page = $(this).parents('li:first').attr('value');
					$div.find('ul.pages > li.js-checked').removeClass('js-checked');
					$div.find('ul.pages > li[value="'+page+'"]').addClass('js-checked');
					loadList(true);
					return false;
				});
				
				$div.find('.js-filter-box :input').change(function(){
					$div.find('ul.pages > li.js-checked').removeClass('js-checked');
					loadList();
				});
				
			}
			
			initList();
		});
	}
	
})(jQuery);

