(function(products) {
	// Public
	products.detail = function(formEl, imagesEl) {
		var PLACEHOLDER_IMAGE = '/resources/site/images/products/placeHolders/placeHolder.zoom.jpg',
			WISHLIST_FUSEACTIONS = $.w('wishList.addItem wishList.addItems');

			$formContainer = $(formEl),
			$imagesContainer = $(imagesEl);

		function initSubmitButtons() {
			$formContainer.find('input[type=image].submit').hide().addClass('replaced');
		}

		function initValidation() {
			function validate() {
				var	quantity = parseInt($formContainer.find('[name^=quantity]').val(), 10),
					errors = [];

				if (isNaN(quantity) || !quantity) {
					errors.push('Please enter a valid quantity');
				}
				
				$formContainer.find('[name^=productOptionIDs]').each(function() {
					var $this = $(this);

					if (!$this.val()) {
						var message = $this.is('select') ? 
										$this.find('option:first').text() : 
										'Please select all options';
						errors.push($.trim(message));
					}
				});

				return $.uniq(errors);
			}

			function showErrors(el, errors) {
				var $errors = WEBLINC.templates.render('productDetailValidationErrors', errors);

				$(el)
					.siblings('.validation-errors')
						.empty()
						.append($errors)
						.show()
						.end()
					.sibilngs('.form-submit').addClass('disabled');
			}

			function hideErrors(el) {
				$(el)
					.siblings('.validation-errors').hide().end()
					.sibilngs('.form-submit').removeClass('disabled');
			}

			$formContainer
				.find('input,select')
					.bind('change blur keyup', function() {
						var valid = !!validate().length;
						$formContainer.find('a.form-submit')[valid ? 'addClass' : 'removeClass']('disabled');
					 })
					.end()
				.find('a.form-submit')
					.hover(
						function() { 
							var errors = validate();
							if (errors.length) { showErrors(this, errors); }
						},
						function() { hideErrors(this); }
					)
					.end()
				.find('form')
					.submit(function(e) {
						if (validate().length) {
							e.preventDefault();
							e.stopImmediatePropagation();
						}
					});
		}

		function initAddToCart() {
			$formContainer.find('form').submit(function(e) {
				var $form = $(this);
				if ($.inArray($form.find('input[name=fuseaction]').val(), WISHLIST_FUSEACTIONS) > -1) {
					return true;
				}

				e.preventDefault();
				WEBLINC.widget.dialog.close();
				var $dialog = WEBLINC.templates
								.render('productDetailAddToCart')
									.appendTo('body')
									.dialog({ dialogClass:'ui-dialog-addedtocart' });

				$form.ajaxSubmit(function() {
					var $cartHeader = $('div.header-cart');
					WEBLINC.section.cart.resetQuickView();
					$cartHeader.mouseover();

					$dialog.html(WEBLINC.templates.render('productDetailAddedToCart'));
					$.delay(function() {
						WEBLINC.widget.dialog.close();
						$cartHeader.mouseout();
					}, 4000);
				});
			});
		}

		function initOptionDependency() {
			$('.depends-on-option').each(function() {
				var $this = $(this),
					nameAttr = $this.attr('name'),
					dependencies = $this.metadata()['depends-on'] || {};

				function allDependenciesMet() {
					var keys = $.obj.keysFor(dependencies);
					return $.inject(keys, true, function(met, dependency) {
						return met && $(dependency).val() === dependencies[dependency];
					});
				}

				$.each(dependencies, function(dependency, value) {
					$(dependency)
						.change(function() {
							if ($(this).val()) {
								allDependenciesMet() ?
									$this.attr('name', nameAttr).show() :
									$this.attr('name', '').hide();
							}
						})
						.trigger('change');
				});
			});
		}

		function initAlternates() {
			$imagesContainer.delegate('div.alternates ul li a', 'click', function(e) {
				e.preventDefault();
				var zoomUrl = $(this).metadata().zoom || PLACEHOLDER_IMAGE;

				$imagesContainer
					.find('div.primary img')
						.attr('src', this.href)
						.end()
					.find('div.hoverzoom')
						.css({ background: 'transparent url(' + zoomUrl + ') no-repeat' });
			});

			$formContainer.find('.alternates-changing').each(function() {
				var $this = $(this),
					event = $this.is('select') ? 'change' : 'click';

				$this.bind(event, function() {
					var alternatesData = $(this).find(':selected,.selected').metadata().alternates || [],
						$images = WEBLINC.templates.render('productDetailAlternates', alternatesData);

					$imagesContainer
						.find('div.alternates')
							.empty()
							.append($images)
								.find('a:first')
									.trigger('click');
				});
			});
		}

		function initZoom() {
			$imagesContainer.find('a.hoverzoom').hoverzoom({
				customPreviewElt: WEBLINC.templates.render('productDetailHoverZoomPreview'),
				onMouseEnter: function() { $(document).trigger('overlay.on'); },
				onMouseLeave: function() { $(document).trigger('overlay.off'); }
			});
		}

		function initShareLinks() {
			$formContainer
				.find('li.share')
					.hover(
						function() { $(this).find('ul').show(); },
						function() { $(this).find('ul').hide(); }
					)
					.find('ul')
						.hide();
		}
		
		function initReviews() {
			var RATINGS_CLASSES = $.w('one two three four five');
			
			$('.rating-summary .rating-stars:not(.outfit .rating-summary .rating-stars)')
				.css('cursor','pointer');

			$('.review-write:not(.outfit .review-write)').bind('scrolled', function() {
				$(".v-productreview-list-reviewform").slideToggle(1000);
			});

			$('div.rating-stars ul').each(function() {
				var $list = $(this);

				function setRatingClass(el) {
					var cssClass = RATINGS_CLASSES[$list.find('li').index(el)];
					$list.attr('class', 'clearfix ' + cssClass); 
				}

				$list
					.find('li')
						.hover(
							function() { setRatingClass(this); }, 
							function() {
								$list.find('li').each(function() {
									if($(this).find('input[name=rating]').is(':checked')) {
										setRatingClass(this);
									} else {
										var $selectedLi = $list.find('input[name=rating]:checked').closest('li');
										setRatingClass($selectedLi.get(0));
									}
								});
							}
						)
						.click(function() {
							$(this).find('input[name=rating]').attr('checked', 'checked');
							setRatingClass(this);
						});
			});
		}

		initSubmitButtons();
		initValidation();
		initAddToCart();
		initOptionDependency();
		initAlternates();
		initZoom();
		initShareLinks();
		initReviews();
	};
	
	// Private
})($.namespace('WEBLINC.section.products'));
