var rated_m = function () {


	if (typeof(window.jQuery) == 'undefined') {
		alert('ERROR - jQuery required');
		return false;
	}
	
	
	
	
	var ASSET_BASE_URL = 'http://s3.amazonaws.com/ratedm_asset/editoral';




//-----------------------------------------------------------------------------
// START: _lookbook
	var _lookbook = function () {
		// configuration
		var _configuration = {
			DIV_ID_LOOKBOOK_IMAGE:                     'lookbook-image',
			DIV_ID_LOOKBOOK_IMAGE_ZOOM:                'lookbook-image-zoom',
			DIV_ID_LOOKBOOK_IMAGE_CAROUSEL:            'lookbook-image-carousel',
			DIV_ID_LOOKBOOK_IMAGE_CAROUSEL_PAGING:     'lookbook-image-carousel-paging',
			
			DIV_ID_PRODUCT_IMAGE:                      'product-image',
			DIV_ID_PRODUCT_IMAGE_ZOOM:                 'product-image-zoom',
			DIV_ID_PRODUCT_CAROUSEL:                   'product-carousel',
			DIV_ID_PRODUCT_CAROUSEL_PAGING:            'product-carousel-paging',

			DIV_ID_PRODUCT_DETAIL_PANEL:               'product-detail-panel',
			DIV_ID_PRODUCT_SOCIAL_PANEL:               'product-social-panel',

			CAROUSEL_THUMBNAIL_WIDTH:                  110,
			CAROUSEL_THUMBNAIL_HEIGHT:                 70,
			CAROUSEL_PADDING_WIDTH:                    108,// 3 * 36px (arrow width)
			CAROUSEL_MIN_VISIBLE_THUMBNAILS:           1,

			CAROUSEL_PAGING_HEIGHT:                    70,
			CAROUSEL_PAGING_BOTTOM:                    0,
			CAROUSEL_PAGING_ARROW_WIDTH:               30,

			PRODUCT_DETAIL_PANEL_WIDTH:                310,
			PRODUCT_SOCIAL_PANEL_WIDTH:                195,
			
			NAV_DEFAULT_RIGHT:                         30,
			
			HOTSPOT_BUBBLE_HEIGHT:                     149
		};




		var _m = function () {
			var _loading                        = false;
			var _lookbook                       = null;
			var _lookbookImagesSelectedIndex    = -1;
			var _product                        = null;
			var _relatedProducts                = null;
			var _productComments                = null;
			var _productCommunityPhotos         = null;
			var _productImagesSelectedIndex     = -1;
			var _selectedProductColorAssetId    = -1;
			var _commentNewsletterSignupOpted   = true;
			var _shareNewsletterSignupOpted     = true;




			var _loadLookbookCallback = function (response) {
				_loading = false;

				if (response === false || response['success'] === false) {
					_c.onLoadError();
					return;
				}

				_lookbook                     = response['data'];
				_lookbookImagesSelectedIndex  = 0;

				_v.transition('loading-lookbook-complete');
			};
			
			
			
			
			var _loadProductCallback = function (response) {
				_loading = false;

				if (response === false || response['success'] === false) {
					_c.onLoadError();
					return;
				}

				_product                     = response['data']['product'];
				_relatedProducts             = response['data']['related_products'];
				_productComments             = response['data']['comments'];
				_productCommunityPhotos      = response['data']['community_photos'];
				_productImagesSelectedIndex  = 0;

				_v.transition('loading-product-complete');
			};
			
			
			
			
			var _submitProductComment = function (commentSubmissionData) {
				_v.showCommentError(false);

				var valid = true;

				if (!commentSubmissionData) {
					valid = false;
				} else if (!commentSubmissionData['name'] || commentSubmissionData['name'].length == 0 || commentSubmissionData['name'] == 'Name') {
					valid = false;
				} else if (!_validateEmail(commentSubmissionData['email'], 'Email Address')) {
					valid = false;
				}
				
				if (!valid) {
					_v.showCommentError('error-invalid');
					return;
				}

				_v.showCommentPosting();
				
				// need to add which product this is for (adding to the submission
				// data here rather than to the string so we can use it within the
				// loop immediately following)
				commentSubmissionData['product'] = _product['id'];
				
				var data = [];
				data.push('newsletter='+ (_commentNewsletterSignupOpted ? 'Y' : 'N'));
				for (var i in commentSubmissionData) {
					data.push(i +'='+ encodeURIComponent(commentSubmissionData[i])); 
				}

				$.ajax({
					'url':       '/api/create/comment',
					'type':      'POST',
					'data':      data.join('&'),
					'success':   function (response) { _submitProductCommentCallback(response); },
					'error':     function (response) { _submitProductCommentCallback(false); }
				});
			};
			
			
			
			
			var _submitProductCommentCallback = function (response) {
				if (response === false || response['success'] === false) {
					_v.showCommentError('error');
					return;
				}

				_v.showCommentError('confirmation');
			};




			return {
				initialize:function () {
					// lookbook requires overflow hidden on site
					$('#site').css('height', '100%');
					$('#site').css('width', '100%');
					$('#site').css('overflow', 'hidden');
				},
				
				
				
				
				submitProductComment:function (commentSubmissionData) {
					_submitProductComment(commentSubmissionData);
				},




				loadLookbook:function (id) {
					if (_loading) { return; } _loading = true;

					_lookbook             = null;
					_lookbookImagesIndex  = 0;

					_v.transition('loading-lookbook');

					$.ajax({
						url:      '/api/get/lookbook',
						data:     'collection='+ encodeURIComponent(id),
						success:  function (response) { _loadLookbookCallback(response); } ,
						error:    function (response) { _loadLookbookCallback(false); }
					});
				},
				
				
				
				
				getLookbook:function () {
					return _lookbook;
				},
				getLookbookImages:function () {
					return _lookbook ? _lookbook['images'] : [];
				},
				getLookbookImagesSelectedIndex:function () {
					return _lookbookImagesSelectedIndex;
				},
				getSelectedLookbookImage:function () {
					return _lookbook ? _lookbook['images'][_lookbookImagesSelectedIndex] : null;
				},
				getProduct:function () {
					return _product;
				},
				setProduct:function (product) {
					_product                     = product;
					_productImagesSelectedIndex  = 0;
				},
				getRelatedProducts:function () {
					return _relatedProducts;
				},
				getProductComments:function () {
					return _productComments;
				},
				getProductCommunityPhotos:function () {
					return _productCommunityPhotos;
				},
				getProductImages:function () {
					return _product ? _product['images'] : [];
				},
				getProductImagesSelectedIndex:function () {
					return _productImagesSelectedIndex;
				},
				getSelectedProductImage:function () {
					return _product ? _product['images'][_productImagesSelectedIndex] : null;
				},
				isLookbookMode:function () {
					return _lookbook != null;
				},




				setLookbookImagesSelectedIndex:function (index) {
					if (index == _lookbookImagesSelectedIndex) { return; }
					
					_lookbookImagesSelectedIndex = index;

					_v.transition('update-lookbook-selected-index');
				},
				
				
				
				
				setProductImagesSelectedIndex:function (index, skipCheck) {
					if (index == _productImagesSelectedIndex && _selectedProductColorAssetId == -1 && !skipCheck) { return; }

					_productImagesSelectedIndex = index;

					_v.transition('update-product-selected-index');
				},
				
				
				
				
				setSelectedProductColorAsset:function (colorAssetId) {
					_selectedProductColorAssetId = colorAssetId;
				},
				getSelectedProductColorAsset:function () {
					return _selectedProductColorAssetId;
				},



				loadProduct:function (id, fromLookbook) {
					if (_loading) { return; } _loading = true;

					_product                    = null;
					_productLoadedFromLookbook  = fromLookbook;

					_v.transition('loading-product');

					$.ajax({
						url:      '/api/get/product',
						data:     'product='+ encodeURIComponent(id),
						success:  function (response) { _loadProductCallback(response); } ,
						error:    function (response) { _loadProductCallback(false); }
					});
				},




				toggleProductCommentNewsletterOptIn:function () {
					_commentNewsletterSignupOpted = !_commentNewsletterSignupOpted;
				},
				isProductCommentNewsletterOptIn:function () {
					return _commentNewsletterSignupOpted;
				},



				toggleProductShareNewsletterOptIn:function () {
					_shareNewsletterSignupOpted = !_shareNewsletterSignupOpted;
				},
				isProductShareNewsletterOptIn:function () {
					return _shareNewsletterSignupOpted;
				}
			};
		}();




		var _v = function () {
			// ui elements
			var _lookbookBackgroundDiv                        = null;
			var _lookbookImageDiv                             = null;
			var _lookbookImageZoomHitDiv                      = null;
			var _lookbookImageZoomResetDiv                    = null;
			var _lookbookCarouselDiv                          = null;
			var _lookbookCarouselPagingDiv                    = null;
			var _productImageDiv                              = null;
			var _productImageZoomHitDiv                       = null;
			var _productImageZoomResetDiv                     = null;
			var _productCarouselDiv                           = null;
			var _productCarouselPagingDiv                     = null;
			var _productDetailPanelDiv                        = null;
			var _productSocialPanelDiv                        = null;
			var _hotspotBubbleDiv                             = null;
			var _relatedBubbleDiv                             = null;
			var _productImageLoader                           = null;
			
			// ui state (not model state, just for the ui)
			var _lookbookImageOpen                            = false;
			var _lookbookImageZoomEnabled                     = false;
			var _lookbookImageZoomed                          = false;
			var _lookbookImageDragOriginX                     = 0;
			var _lookbookImageDragOriginY                     = 0;
			var _lookbookCarouselOpen                         = false;
			var _lookbookCarouselFirstVisibleIndex            = 0;
			var _productImageOpen                             = false;
			var _productImageZoomEnabled                      = false;
			var _productImageZoomed                           = false;
			var _productImageDragOriginX                      = 0;
			var _productImageDragOriginY                      = 0;
			var _productImageZoomFactor                       = 1;
			var _productCarouselOpen                          = false;
			var _productCarouselFirstVisibleIndex             = 0;
			var _productDetailPanelOpen                       = false;
			var _productSocialPanelOpen                       = false;
			var _productSocialPanelPreviouslyOpen             = false;
			var _productSocialPanelContent                    = null;
			var _productCommentsIndex                         = 0;
			var _productPhotosIndex                           = 0;
			var _closeHotspotBubbleTimeout                    = 0;
			var _useStartingAssetOnce                         = true;




			var _setLookbookImageOpen = function (open, skipAnimation) {
				if (open == _lookbookImageOpen) { return; } _lookbookImageOpen = open;

				if (skipAnimation) {
					if (_lookbookImageOpen) {
						_lookbookImageDiv.show();
					} else {
						_lookbookImageDiv.hide();
					}
				} else {
					if (_lookbookImageOpen) {
						_lookbookImageDiv.fadeIn(200, 'easeOutQuad');
					} else {
						_lookbookImageDiv.fadeOut(200, 'easeOutQuad');
					}
				}

				setTimeout(function () { _resizeLookbookImage(); }, 10);
			};
			
			
			
			
			var _setLookbookImageZoomEnabled = function (enabled) {
				if (enabled == _lookbookImageZoomEnabled) { return; } _lookbookImageZoomEnabled = enabled;

				if (_lookbookImageZoomEnabled) {
					_lookbookImageZoomHitDiv.show();
				} else {
					_lookbookImageZoomHitDiv.hide();
				}
			};
			
			
			
			
			var _setLookbookImageZoomed = function (zoomed, point) {
				if (zoomed == _lookbookImageZoomed) { return; } _lookbookImageZoomed = zoomed;
				
				var image     = _m.getSelectedLookbookImage();
				var imageTag  = _lookbookImageDiv.children('img');
				
				if (imageTag.length <= 0) {
					return;
				}
				
				if (!_lookbookImageZoomed) {
					_setLookbookImageDragEnabled(false);
					
					_lookbookImageDiv.css('top', 'auto');
					_lookbookImageDiv.css('left', '50%');
					_lookbookImageDiv.css('bottom', '-10px');
					_resizeLookbookImage();
					_setLookbookImageZoomEnabled(true);
					_lookbookImageZoomResetDiv.hide();
					return;
				}

				var nativeWidth          = parseInt(imageTag.css('width').replace('px', ''));
				var nativeHeight         = parseInt(imageTag.css('height').replace('px', ''));
				var relativeX            = point['x'] - _lookbookImageDiv.offset().left;
				var relativeY            = point['y'] - _lookbookImageDiv.offset().top;
				var relativeXPercentage  = relativeX / nativeWidth;
				var relativeYPercentage  = relativeY / nativeHeight;

				_lookbookImageDiv.css('left', 'auto');
				_lookbookImageDiv.css('bottom', 'auto');
				_lookbookImageDiv.css('margin-left', '0px');

				_setLookbookImageDragEnabled(true);
				_setLookbookImageHotspotsEnabled(false);

				var zoomHeight       = nativeHeight * 1.5;
				var zoomWidth        = (nativeWidth / nativeHeight) * zoomHeight;
				var zoomTop          = point['y'] - (zoomHeight * relativeYPercentage);
				var zoomLeft         = point['x'] - (zoomWidth * relativeXPercentage);

				imageTag.animate({
					'height':       zoomHeight
				},{
					'duration':     500,
					'easing':       'easeOutQuad'
				});
				
				_lookbookImageDiv.animate({
					'top':          zoomTop,
					'left':         zoomLeft
				},{
					'duration':     500,
					'easing':       'easeOutQuad'
				});
				
				_setLookbookImageZoomEnabled(false);
				_lookbookImageZoomResetDiv.show();
			};
			
			
			
			
			var _setLookbookImageHotspotsEnabled = function (enabled) {
				var hotspotDivs = _lookbookImageDiv.find('.hotspot');
				if (enabled) {
					hotspotDivs.show();
				} else {
					hotspotDivs.hide();
				}
			};
			
			
			
			
			var _setLookbookImageDragEnabled = function (enabled) {
				var cursor    = enabled ? 'move' : 'auto';
				var imageTag  = _lookbookImageDiv.children('img');

				imageTag.css('cursor', cursor);
				
				if (enabled) {
					imageTag.bind('mousedown', _startLookbookImageDrag);
					$(document).bind('mouseup', _stopLookbookImageDrag);
				} else {
					imageTag.unbind('mousedown', _startLookbookImageDrag);
					$(document).unbind('mouseup', _stopLookbookImageDrag);
				}
			};
			
			
			
			
			var _startLookbookImageDrag = function (event) {
				event.preventDefault();

				var relativeX              = event.clientX - _lookbookImageDiv.offset().left;
				var relativeY              = event.clientY - _lookbookImageDiv.offset().top;
				_lookbookImageDragOriginX  = relativeX;
				_lookbookImageDragOriginY  = relativeY;

				$(document).bind('mousemove', _lookbookImageDrag);
			};
			
			
			
			var _stopLookbookImageDrag = function (event) {
				event.preventDefault();

				_lookbookImageDragOriginX  = 0;
				_lookbookImageDragOriginY  = 0;

				$(document).unbind('mousemove', _lookbookImageDrag);
			};
			
			
			
			
			var _lookbookImageDrag = function (event) {
				var imageTag     = _lookbookImageDiv.children('img');
				var imageHeight  = parseInt(imageTag.css('height').replace('px', ''));
				var imageWidth   = parseInt(imageTag.css('width').replace('px', ''));
				
				var windowDimensions  = _getWindowDimensions();
				var dragTop           = event.clientY - _lookbookImageDragOriginY;
				var dragLeft          = event.clientX - _lookbookImageDragOriginX;
				
				if ((dragTop + imageHeight) < windowDimensions['height']) {
					dragTop = windowDimensions['height'] - imageHeight;
				} else if (dragTop > windowDimensions['height'] - 100) {
					dragTop = windowDimensions['height'] - 100;
				}
				
				if (dragLeft + imageWidth > windowDimensions['width']) {
					dragLeft = windowDimensions['width'] - (imageWidth + 100);
				} else if (dragLeft + imageWidth < 100) {
					dragLeft = -imageWidth + 100;
				}

				_lookbookImageDiv.css('top', dragTop);
				_lookbookImageDiv.css('left', dragLeft);
			};




			var _setProductImageZoomEnabled = function (enabled) {
				if (enabled == _productImageZoomEnabled) { return; } _productImageZoomEnabled = enabled;

				if (_productImageZoomEnabled) {
					_productImageZoomHitDiv.show();
				} else {
					_productImageZoomHitDiv.hide();
				}
			};
			
			
			
			
			var _setProductImageZoomed = function (zoomed, point, skipResizeOrColorClick) {
				if (zoomed == _productImageZoomed) { return; } _productImageZoomed = zoomed;

				var isColorImage  = _m.getSelectedProductColorAsset() != -1 && _m.getSelectedProductColorAsset() != null;
				var image         = _m.getSelectedProductImage();
				var imageTag      = _productImageDiv.children('img');

				if (imageTag.length <= 0) {
					return;
				}
				
				if (!_productImageZoomed) {
					_setProductImageDragEnabled(false);
					
					_productImageDiv.css('top', 'auto');
					_productImageDiv.css('left', '50%');
					_productImageDiv.css('bottom', '-10px');
					
					if (!skipResizeOrColorClick) {
						if (isColorImage) {
							_c.onProductColorClick(_productDetailPanelDiv.find('.product-colors').find('a[rel='+ _m.getSelectedProductColorAsset() +']'));
						} else {
							_resizeProductImage();
						}
					}

					_setProductImageZoomEnabled(true);
					_productImageZoomResetDiv.hide();
					return;
				}

				var nativeWidth          = parseInt(imageTag.css('width').replace('px', ''));
				var nativeHeight         = parseInt(imageTag.css('height').replace('px', ''));
				var relativeX            = point['x'] - _productImageDiv.offset().left;
				var relativeY            = point['y'] - _productImageDiv.offset().top;
				var relativeXPercentage  = relativeX / nativeWidth;
				var relativeYPercentage  = relativeY / nativeHeight;
				
				_productImageDiv.css('left', 'auto');
				_productImageDiv.css('bottom', 'auto');
				_productImageDiv.css('margin-left', '0px');
				
				_setProductImageDragEnabled(true);
				
				var zoomHeight       = nativeHeight * 2;
				var zoomWidth        = (nativeWidth / nativeHeight) * zoomHeight;
				var zoomTop          = point['y'] - (zoomHeight * relativeYPercentage);
				var zoomLeft         = point['x'] - (zoomWidth * relativeXPercentage);

				imageTag.animate({
					'height':       zoomHeight
				},{
					'duration':     500,
					'easing':       'easeOutQuad'
				});
				
				_productImageDiv.animate({
					'top':          zoomTop,
					'left':         zoomLeft
				},{
					'duration':     500,
					'easing':       'easeOutQuad'
				});

				_setProductImageZoomEnabled(false);
				_productImageZoomResetDiv.show();
			};
			
			
			
			
			var _setProductImageDragEnabled = function (enabled) {
				var cursor    = enabled ? 'move' : 'auto';
				var imageTag  = _productImageDiv.children('img');

				imageTag.css('cursor', cursor);
				
				if (enabled) {
					imageTag.bind('mousedown', _startProductImageDrag);
					$(document).bind('mouseup', _stopProductImageDrag);
				} else {
					imageTag.unbind('mousedown', _startProductImageDrag);
					$(document).unbind('mouseup', _stopProductImageDrag);
				}
			};
			
			
			
			
			var _startProductImageDrag = function (event) {
				event.preventDefault();

				var relativeX              = event.clientX - _productImageDiv.offset().left;
				var relativeY              = event.clientY - _productImageDiv.offset().top;
				_productImageDragOriginX   = relativeX;
				_productImageDragOriginY   = relativeY;

				$(document).bind('mousemove', _productImageDrag);
			};
			
			
			
			var _stopProductImageDrag = function (event) {
				event.preventDefault();

				_productImageDragOriginX  = 0;
				_productImageDragOriginY  = 0;

				$(document).unbind('mousemove', _productImageDrag);
			};
			
			
			
			
			var _productImageDrag = function (event) {
				var imageTag          = _productImageDiv.children('img');
				var imageHeight       = parseInt(imageTag.css('height').replace('px', ''));
				var imageWidth        = parseInt(imageTag.css('width').replace('px', ''));

				var windowDimensions  = _getWindowDimensions();
				var dragTop           = event.clientY - _productImageDragOriginY;
				var dragLeft          = event.clientX - _productImageDragOriginX;
				var isColorImage      = _m.getSelectedProductColorAsset() != -1 && _m.getSelectedProductColorAsset() != null;

				if (isColorImage) {
					if (dragTop + imageHeight < 100) {
						dragTop = -imageHeight + 100;
					} else if (dragTop > windowDimensions['height'] - 100) {
						dragTop = windowDimensions['height'] - 100;
					}

					if (dragLeft > windowDimensions['width'] - 100) {
						dragLeft = windowDimensions['width'] - 100;
					} else if (dragLeft + imageWidth < 100) {
						dragLeft = -imageWidth + 100;
					}
				} else {
					if ((dragTop + imageHeight) < windowDimensions['height']) {
						dragTop = windowDimensions['height'] - imageHeight;
					} else if (dragTop > windowDimensions['height'] - 100) {
						dragTop = windowDimensions['height'] - 100;
					}

					if (dragLeft + imageWidth > windowDimensions['width']) {
						dragLeft = windowDimensions['width'] - (imageWidth + 100);
					} else if (dragLeft + imageWidth < 100) {
						dragLeft = -imageWidth + 100;
					}
				}

				_productImageDiv.css('top', dragTop);
				_productImageDiv.css('left', dragLeft);
			};




			var _setProductImageOpen = function (open, skipAnimation) {
				if (open == _productImageOpen) { return; } _productImageOpen = open;

				if (skipAnimation) {
					if (_productImageOpen) {
						_productImageDiv.show();
					} else {
						_productImageDiv.hide();
					}
				} else {
					if (_productImageOpen) {
						_productImageDiv.fadeIn(200, 'easeOutQuad');
					} else {
						_productImageDiv.fadeOut(200, 'easeOutQuad');
					}
				}

				setTimeout( function () { _resizeProductImage(); }, 10);
			};




			var _setLookbookCarouselOpen = function (open, skipAnimation) {
				if (open == _lookbookCarouselOpen) { return; } _lookbookCarouselOpen = open;
				_setCarouselOpen(_lookbookCarouselDiv, _lookbookCarouselPagingDiv, _lookbookCarouselOpen, skipAnimation);
			};




			var _setProductCarouselOpen = function (open, skipAnimation) {
				if (open == _productCarouselOpen) { return; } _productCarouselOpen = open;
				_setCarouselOpen(_productCarouselDiv, _productCarouselPagingDiv, _productCarouselOpen, skipAnimation);
			};
			
			
			
			
			var _setCarouselOpen = function (carouselDiv, carouselPagingDiv, open, skipAnimation) {
				var carouselHeight        = _configuration.CAROUSEL_THUMBNAIL_HEIGHT;
				var carouselBottom        = open ? 0 : -_configuration.CAROUSEL_THUMBNAIL_HEIGHT;
				var carouselPagingBottom  = open ? _configuration.CAROUSEL_PAGING_BOTTOM : -_configuration.CAROUSEL_PAGING_HEIGHT;

				if (skipAnimation) {
					carouselDiv.css('bottom', carouselBottom +'px');
					carouselPagingDiv.css('bottom', carouselPagingBottom +'px');					
				} else {
					carouselDiv.animate({
						'bottom':    carouselBottom +'px'
					},{
						'duration':  200,
						'easing':    'easeOutQuad'
					});

					carouselPagingDiv.animate({
						'bottom':    carouselPagingBottom +'px'
					},{
						'duration':  200,
						'easing':    'easeOutQuad'
					});
				}
			};
			
			
			
			
			var _setProductDetailPanelOpen = function (open, skipSlide) {
				if (open == _productDetailPanelOpen) { return; } _productDetailPanelOpen = open;

				if (!skipSlide) {
					_slidePanelsImagesAndCarousels();
				}
			};
			
			
			
			
			var _setProductSocialPanelOpen = function (open, content) {
				if (content == _productSocialPanelContent && open == _productSocialPanelOpen) { return; }

				if (open) {
					if (open && _productSocialPanelOpen) {
						_productSocialPanelPreviouslyOpen = true;
					}
					_productSocialPanelOpen = true;
				} else {
					if (content != null && _productSocialPanelPreviouslyOpen) {
						_productSocialPanelPreviouslyOpen   = false;
						_productSocialPanelOpen             = true;

						switch (content) {
							case 'post-comment':
								content = 'comment';
								break;
								
							case 'comment':
								content = 'share';
								break;
								
							case 'share':
								content = 'comment';
								break;
						}
					} else {
						content                            = _productSocialPanelContent;
						_productSocialPanelPreviouslyOpen  = false;
						_productSocialPanelOpen            = false;
					}
				}

				_productSocialPanelContent = content;
				_productSocialPanelDiv.children('.content').hide();
				_productSocialPanelDiv.children('.content-'+ _productSocialPanelContent).show();
				_slidePanelsImagesAndCarousels();
			};
			
			
			
			
			var _slidePanelsImagesAndCarousels = function () {
				var detailPanelRight = _productDetailPanelOpen ? 0 : -_configuration.PRODUCT_DETAIL_PANEL_WIDTH;
				if (_productSocialPanelOpen) {
					detailPanelRight += _configuration.PRODUCT_SOCIAL_PANEL_WIDTH;
				}

				_productDetailPanelDiv.stop().animate({
					'right':        detailPanelRight
				},{
					'duration':     500,
					'easing':       'easeOutQuad'
				});

				var socialPanelRight = _productSocialPanelOpen ? 0 : -_configuration.PRODUCT_SOCIAL_PANEL_WIDTH;
				_productSocialPanelDiv.stop().animate({
					'right':        socialPanelRight
				},{
					'duration':     500,
					'easing':       'easeOutQuad'
				});
				
				var tempWidth             = 0;
				var tempMarginLeft        = 0;
				var tempMarginLeftOffset  = 0;
				var navRight              = _configuration.NAV_DEFAULT_RIGHT;
				var navTop                = 0;

				if (_productDetailPanelOpen) {
					tempMarginLeftOffset  -= (_configuration.PRODUCT_DETAIL_PANEL_WIDTH / 2);
					navRight              += _configuration.PRODUCT_DETAIL_PANEL_WIDTH;
					navTop                 = -75;
				}
				if (_productSocialPanelOpen) {
					tempMarginLeftOffset  -= (_configuration.PRODUCT_SOCIAL_PANEL_WIDTH / 2);
					navRight              += _configuration.PRODUCT_SOCIAL_PANEL_WIDTH;
					navTop                 = -75;
				}

				if (_lookbookImageDiv.children('img').length > 0) {
					tempWidth       = parseInt(_lookbookImageDiv.children('img').css('width').replace('px'));
					tempMarginLeft  = -(tempWidth / 2) + tempMarginLeftOffset;

					_lookbookImageDiv.animate({
						'margin-left':  tempMarginLeft
					},{
						'duration':     500,
						'easing':       'easeOutQuad',
						'queue':        false
					});
					
					_lookbookImageZoomHitDiv.animate({
						'margin-left':  tempMarginLeft
					},{
						'duration':     500,
						'easing':       'easeOutQuad',
						'queue':        false
					});
				}
				
				if (_productImageDiv.children('img').length > 0) {
					tempWidth       = parseInt(_productImageDiv.children('img').css('width').replace('px'));
					tempMarginLeft  = -(tempWidth / 2) + tempMarginLeftOffset;

					_productImageDiv.animate({
						'margin-left':  tempMarginLeft
					},{
						'duration':     500,
						'easing':       'easeOutQuad',
						'queue':        false
					});

					_productImageZoomHitDiv.animate({
						'margin-left':  tempMarginLeft
					},{
						'duration':     500,
						'easing':       'easeOutQuad',
						'queue':        false
					});
				}

				$('#header').children('.nav').animate({
					// 'top':       navTop, -- keeping open for now
					'right':     navRight
				},{
					'duration':  500,
					'easing':    'easeOutQuad',
					'queue':     false
				});
			};




			var _buildLookbookImage = function () {
				_lookbookImageDiv.fadeOut(200, 'easeOutQuad', function () {
					var thisDiv = $(this);
					thisDiv.empty();
					
					var lookbook             = _m.getLookbook();
					var image                = _m.getSelectedLookbookImage();
					var hotspots             = image['hotspots'];
					var tempHotspot          = null;
					var tempHotspotLink      = null;
					var tempHotspotDiv       = null;
					for (var i=0; i<hotspots.length; i++) {
						tempHotspot = hotspots[i];

						tempHotspotDiv = $('<div>');
						tempHotspotDiv.attr('class', 'hotspot');
						tempHotspotDiv.addClass('hotspot-'+ lookbook['collection_slug']);
						tempHotspotDiv.css('top', tempHotspot['y'] +'px');
						tempHotspotDiv.css('left', tempHotspot['x'] +'px');

						tempHotspotLink = $('<a>');
						tempHotspotLink.attr('href', 'javascript:void(0)');
						tempHotspotLink.html((i + 1));
						tempHotspotLink.appendTo(tempHotspotDiv);

						tempHotspotDiv.appendTo(thisDiv);

						tempHotspotLink.bind('click', function () {
							_c.onHotspotClick($(this).parent().index());
						});
						tempHotspotLink.bind('mouseenter', function () {
							_c.onHotspotRolled($(this).parent(), $(this).parent().index());
						});
						tempHotspotLink.bind('mouseleave', function () {
							_c.onHotspotRolledOut($(this).parent(), $(this).parent().index());
						});
					}

					var imageTag = $('<img>');
					imageTag.attr('src', _imageToAssetUrl(image));
					imageTag.appendTo(thisDiv);
					imageTag.load(function () {
						_resizeLookbookImage();
						$(this).parent().fadeIn(200, 'easeOutQuad');
					});
				});
				
				_lookbookImageOpen = true;
			};
			
			
			
			
			var _buildProductImage = function (forceAssetUrl, onLoadFunctionReplacement) {
				_productImageDiv.fadeOut(200, 'easeOutQuad', function () {
					var thisDiv = $(this);
					thisDiv.empty();

					var image          = _m.getSelectedProductImage();
					var imageTag       = $('<img>');

					var imageAssetUrl = image ? _imageToAssetUrl(image) : null;
					if (forceAssetUrl) {
						imageAssetUrl = forceAssetUrl;
					}
					
					imageTag.appendTo(thisDiv);

					if (!onLoadFunctionReplacement) {
						imageTag.load(function () {
							_resizeProductImage();
							setTimeout(function () { _slidePanelsImagesAndCarousels(); }, 200);
							$(this).parent().fadeIn(200, 'easeOutQuad');
						});
					} else {
						imageTag.load(function () {
							onLoadFunctionReplacement();
						});
					}
					
					if (imageAssetUrl) {
						imageTag.attr('src', imageAssetUrl);
					} else {
						// if there is no image, then we should load the first product color image
						// this will bypass the onLoadFunctionReplacement but it's ok since this
						// is a special case and the loading of the product color will
						// trigger everything as necessary
						_c.onProductColorClick(_productDetailPanelDiv.find('.product-colors').children('div:first-child').children('a'));
						return;
					}
				});
				
				_productImageOpen = true;
			};
			
			
			
			
			var _buildProductInfo = function () {
				var product           = _m.getProduct();
				var relatedProducts   = _m.getRelatedProducts();
				var productColors     = product['colors'];
				var productSizes      = product['size_letters'].split(',');
				var i                 = 0;

				_productDetailPanelDiv.find('.product-name').html(product['name']);
				_productDetailPanelDiv.find('.product-description').html(product['description']);
				_productDetailPanelDiv.find('.product-sizes').html('Available in '+ productSizes.join(' / '));
				_productDetailPanelDiv.find('.product-materials').html(product['materials']);
				_productDetailPanelDiv.find('.product-collection').children('a').attr('href', '/lookbook/'+ product['collection_slug']).html(product['collection_name']);
				_productDetailPanelDiv.find('.price').html('<span class="price-sign">$</span>'+ _formatProductPrice(product['price']));
				
				if (product['ecommerce_url']) {
					_productDetailPanelDiv.find('.box-button-buy').show();
					_productDetailPanelDiv.find('.box-button-buy').find('a').attr('href', product['ecommerce_url']);
					_productDetailPanelDiv.find('.coming-soon-button').hide();
				} else {
					_productDetailPanelDiv.find('.box-button-buy').hide();
					_productDetailPanelDiv.find('.coming-soon-button').show();
				}

				var productColorsDiv    = _productDetailPanelDiv.find('.product-colors');
				var tempColor           = null;
				var tempColorDiv        = null;
				var tempColorAnchor     = null;

				productColorsDiv.empty();

				for (i=0; i<productColors.length; i++) {
					tempColor = productColors[i];
					
					tempColorAnchor = $('<a>');
					tempColorAnchor.attr('rel', tempColor['asset_id']);
					tempColorAnchor.attr('title', tempColor['name']);
					tempColorAnchor.css('background-color', tempColor['hex']);
					tempColorAnchor.bind('click', function () {
						_c.onProductColorClick($(this));
					});
					tempColorAnchor.bind('mouseenter', function () {
						_c.onProductColorMouseEnter($(this));
					});
					tempColorAnchor.bind('mouseleave', function () {
						_c.onProductColorMouseLeave($(this));
					});

					tempColorDiv = $('<div>');
					tempColorDiv.attr('class', 'product-color');
					tempColorDiv.append(tempColorAnchor);
					tempColorDiv.appendTo(productColorsDiv);
				}
				
				var relatedProductsDiv = _productDetailPanelDiv.find('.related-products');
				relatedProductsDiv.empty();
				
				var tempRelatedProduct      = null;
				var tempRelatedProductDiv   = null;
				var tempImage               = null;
				for (i=0; i<relatedProducts.length; i++) {
					tempRelatedProduct = relatedProducts[i];
					
					tempRelatedProductDiv = $('<div>');
					tempRelatedProductDiv.attr('class', 'related-product');
					tempRelatedProductDiv.attr('rel', tempRelatedProduct['slug']);
					tempRelatedProductDiv.html('<div class="glow"></div>');
					tempRelatedProductDiv.bind('click', function () {
						document.location.href = '/product/'+ $(this).attr('rel');
					});
					
					tempRelatedProductDiv.bind('mouseenter', function () {
						_onRelatedProductMouseenter($(this));
					});
					tempRelatedProductDiv.bind('mouseleave', function () {
						_onRelatedProductMouseleave($(this));
					});

					tempImage = $('<img>');
					tempImage.attr('src', _productToColorAssetUrl(tempRelatedProduct, '_grid'));
					tempImage.appendTo(tempRelatedProductDiv);
					
					tempRelatedProductDiv.appendTo(relatedProductsDiv);
				}
				
				var socialUrl = _c.getShareUrl(product);
				var fbButtonDiv = $('#fb-button');
				fbButtonDiv.html('<fb:like href="'+ socialUrl +'" send="false" layout="button_count" width="450" show_faces="false" font="lucida grande"></fb:like>');
				FB.XFBML.parse(document.getElementById('fb-button'));
				
				var googleButtonDiv = $('#google-button');
				googleButtonDiv.html('<g:plusone href="'+ socialUrl +'" size="standard" annotation="bubble"></g:plusone>');
				gapi.plusone.render("google-button");
			};
			
			
			
			
			var _buildProductInfoLoading = function () {
				var loadingString = 'Loading...';
				
				_productDetailPanelDiv.find('.product-name').html(loadingString);
				_productDetailPanelDiv.find('.product-description').html(loadingString);
				_productDetailPanelDiv.find('.product-sizes').html(loadingString);
				_productDetailPanelDiv.find('.product-materials').html(loadingString);
				_productDetailPanelDiv.find('.product-collection').children('a').html(loadingString);
				_productDetailPanelDiv.find('.price').html('...');
				_productDetailPanelDiv.find('.box-button-buy').hide();
				_productDetailPanelDiv.find('.coming-soon-button').hide();

				var productColorsDiv = _productDetailPanelDiv.find('.product-colors');
				productColorsDiv.empty();
				productColorsDiv.html(loadingString);

				var relatedProductsDiv = _productDetailPanelDiv.find('.related-products');
				relatedProductsDiv.empty();
				relatedProductsDiv.html(loadingString);
				
				$('#fb-button').html('');
				$('#google-button').html('');
			};




			var _buildProductComments = function () {
				var socialPanelDiv  = $('#product-social-panel');
				var commentsDiv     = $('#product-social-panel-comments');
				commentsDiv.empty();

				var comments = _m.getProductComments();

				if (comments.length <= 0) {
					socialPanelDiv.find('.comments-container').hide();
					socialPanelDiv.find('.comments-container-paging').hide();
					socialPanelDiv.find('.no-comments').show();
				} else {
					var tempComment     = null;
					var tempCommentDiv  = null;
					var tempWhoDiv      = null;
					var tempTextDiv     = null;
					for (var i=0; i<comments.length; i++) {
						tempComment = comments[i];

						tempCommentDiv = $('<div>');
						tempCommentDiv.attr('class', 'comment');

						tempTextDiv = $('<div>');
						tempTextDiv.attr('class', 'text');
						tempTextDiv.html(tempComment['text']);
						tempTextDiv.appendTo(tempCommentDiv);

						tempWhoDiv = $('<div>');
						tempWhoDiv.attr('class', 'who');
						tempWhoDiv.html(tempComment['name'] +' '+ tempComment['created_on_formatted']);
						tempWhoDiv.appendTo(tempCommentDiv);

						tempCommentDiv.appendTo(commentsDiv);
					}
					
					socialPanelDiv.find('.comments-container').show();
					socialPanelDiv.find('.comments-container-paging').show();
					socialPanelDiv.find('.no-comments').hide();
				}
			};
			
			
			
			
			var _buildProductCommunityPhotos = function () {
				var socialPanelDiv  = $('#product-social-panel');
				var photosDiv       = $('#product-social-panel-photos');
				photosDiv.empty();
				
				var photos = _m.getProductCommunityPhotos();
				
				if (photos.length <= 0) {
					socialPanelDiv.find('.photos-container').hide();
					socialPanelDiv.find('.photos-container-paging').hide();
					socialPanelDiv.find('.no-photos').show();
				} else {
					var tempPhoto        = null;
					var tempOrientation  = null;
					var tempPhotoDiv     = null;
					var tempFrameDiv     = null;
					var tempImageDiv     = null;
					for (var i=0; i<photos.length; i++) {
						tempPhoto        = photos[i];
						tempOrientation  = parseInt(tempPhoto['is_landscape']) == 1 ? 'horizontal' : 'vertical';

						tempPhotoDiv = $('<div>');
						tempPhotoDiv.attr('class', 'photo photo-'+ tempOrientation);

						tempFrameDiv = $('<div>');
						tempFrameDiv.attr('class', 'frame');
						tempFrameDiv.appendTo(tempPhotoDiv);

						tempImageDiv = $('<div>');
						tempImageDiv.attr('class', 'image');
						tempImageDiv.appendTo(tempPhotoDiv);

						tempPhotoDiv.appendTo(photosDiv);
					}

					var pagingDiv = $('#product-social-panel-photos-paging').find('.paging-label');
					pagingDiv.html('1 of '+ photos.length);
					
					socialPanelDiv.find('.photos-container').show();
					socialPanelDiv.find('.photos-container-paging').show();
					socialPanelDiv.find('.no-photos').hide();
				}
			};




			var _buildLookbookCarousel = function () {
				var thumbnailsDiv          = _lookbookCarouselDiv.children('.thumbnails');
				var images                 = _m.getLookbookImages();
				var clickFunction          = _c.onLookbookCarouselClick;

				_buildImageCarousel(thumbnailsDiv, images, clickFunction, '/assets/images/lookbooks/lookbook_image_thumbnail_1.jpg');
			};
			
			
			
			
			var _buildProductCarousel = function () {
				var thumbnailsDiv          = _productCarouselDiv.children('.thumbnails');
				var images                 = _m.getProductImages();
				var clickFunction          = _c.onProductCarouselClick;

				_buildImageCarousel(thumbnailsDiv, images, clickFunction, '/assets/images/product/product_detail_thumbnail_1.jpg');
			}
			
			
			
			
			var _buildImageCarousel = function (thumbnailsDiv, images, clickFunction, defaultImageUrl) {
				thumbnailsDiv.empty();
				
				var tempImage            = null;
				var tempThumbnailDiv     = null;
				for (var i=0; i<images.length; i++) {
					tempImage = images[i];

					tempThumbnailDiv = $('<div>');
					tempThumbnailDiv.addClass('thumbnail');
					tempThumbnailDiv.append('<div class="overlay">');
					tempThumbnailDiv.append('<img src="'+ _imageToAssetUrl(tempImage, '_thumb') +'">');
					tempThumbnailDiv.appendTo(thumbnailsDiv);
				}

				var thumbnailsWidth = images.length * _configuration.CAROUSEL_THUMBNAIL_WIDTH;
				thumbnailsDiv.css('width', thumbnailsWidth +'px');

				// setting hover and click behavior on all thumbnails after they are constructed
				// rather than using .live since there may be other elements with the .thumbnail
				// class... these elements are freed with a call to empty() on the loading functions
				thumbnailsDiv.children('.thumbnail').each(function () {
					$(this).hover(
					function () {
						$(this).children('.overlay').stop().animate({"opacity": "0"}, "fast");
					},
					function () {
						$(this).children('.overlay').stop().animate({"opacity": ".7"}, "slow");
					});

					$(this).click(function () {
						clickFunction($(this));
					});
				});
			};




			var _resizeLookbookImage = function () {
				var image      = _m.getSelectedLookbookImage();
				var imageTag   = _lookbookImageDiv.children('img');

				if (imageTag.length <= 0) {
					return;
				}

				var imageNativeWidth        = image['native_width'];
				var imageNativeHeight       = image['native_height'];
				var imageNativeAspectRatio  = imageNativeWidth / imageNativeHeight;
				var imageHeight             = $(window).height() - 30;
				var imageWidth              = imageHeight * imageNativeAspectRatio;
				
				// only writing height here b/c using image width calculation
				// just for margin left calculations since we can't rely on 
				// being able to read image width immediately after
				// writing the height
				imageTag.height(imageHeight);
				
				// we set width in IE7
				if (BROWSER_VERSION == 'ie7' || BROWSER_VERSION == 'ie8') {
					imageTag.width(imageWidth);
				}

				var imageMarginLeftOffset  = 0;
				if (_productDetailPanelOpen) {
					imageMarginLeftOffset -= (_configuration.PRODUCT_DETAIL_PANEL_WIDTH / 2);
				}
				if (_productSocialPanelOpen) {
					imageMarginLeftOffset -= (_configuration.PRODUCT_SOCIAL_PANEL_WIDTH / 2);
				}

				var imageMarginLeft = -(imageWidth / 2) + imageMarginLeftOffset;
				_lookbookImageDiv.css('margin-left', imageMarginLeft);

				// hotspots are defined by native width / height so we need to reduce
				// or increase the top and left values by the scale % of width and height
				var hotspots           = image['hotspots'];
				var percentageScaled   = imageWidth / image['native_width'];
				_lookbookImageDiv.children('.hotspot').each(function () {
					var thisDiv    = $(this);
					var hotspot    = hotspots[thisDiv.index()];

					// account for negative half margin on base image so we
					// subtract half of the image's width from the x
					var top        = hotspot['y'];
					var left       = hotspot['x'];
					var newTop     = percentageScaled * top;
					var newLeft    = percentageScaled * left;

					thisDiv.css('top', newTop +'px');
					thisDiv.css('left', newLeft +'px');
				});
				
				// resize lookbook image hit state to match new dimensions
				_lookbookImageZoomHitDiv.css('width', imageWidth);
				_lookbookImageZoomHitDiv.css('height', imageHeight);
				_lookbookImageZoomHitDiv.css('margin-left', imageMarginLeft);
			};
			
			
			
			
			var _resizeLookbookBackground = function () {
				var image = _lookbookBackgroundDiv.children('img');
				
				image.css('width', $(window).width());
				image.css('height', $(window).height());
			};




			var _resizeProductImage = function () {
				var image       = _m.getSelectedProductImage();
				var imageTag    = _productImageDiv.children('img');

				if (image == null || imageTag.length <= 0) {
					return;
				}

				var imageNativeWidth        = image['native_width'];
				var imageNativeHeight       = image['native_height'];
				var imageNativeAspectRatio  = imageNativeWidth / imageNativeHeight;
				var imageHeight             = $(window).height() - 30;
				var imageWidth              = imageHeight * imageNativeAspectRatio;

				// only writing height here b/c using image width calculation
				// just for margin left calculations since we can't rely on 
				// being able to read image width immediately after
				// writing the height
				imageTag.height(imageHeight);

				var imageMarginLeftOffset = 0;
				if (_productDetailPanelOpen) {
					imageMarginLeftOffset -= (_configuration.PRODUCT_DETAIL_PANEL_WIDTH / 2);
				}
				if (_productSocialPanelOpen) {
					imageMarginLeftOffset -= (_configuration.PRODUCT_SOCIAL_PANEL_WIDTH / 2);
				}

				var imageMarginLeft = -(imageWidth / 2) + imageMarginLeftOffset;
				_productImageDiv.css('margin-left', imageMarginLeft);

				// resize product image hit state to match new dimensions
				_productImageZoomHitDiv.css('width', imageWidth);
				_productImageZoomHitDiv.css('height', imageHeight);
				_productImageZoomHitDiv.css('margin-left', imageMarginLeft);
			};
			
			
			
			
			var _resizeLookbookCarousel = function () {
				var images                    = _m.getLookbookImages();
				var thumbnailCount            = images.length;
				var visibleThumbnailCount     = _calculateLookbookCarouselVisibleCount();
				var pagingRequired            = thumbnailCount > visibleThumbnailCount;
				
				var carouselWidth             = visibleThumbnailCount * _configuration.CAROUSEL_THUMBNAIL_WIDTH;
				var carouselMarginleft        = pagingRequired ? _configuration.CAROUSEL_PAGING_ARROW_WIDTH : 0;
				_lookbookCarouselDiv.css('width', carouselWidth +'px');
				_lookbookCarouselDiv.css('margin-left', carouselMarginleft +'px');

				var carouselPagingWidth       = carouselWidth + (_configuration.CAROUSEL_PAGING_ARROW_WIDTH * 2);
				_lookbookCarouselPagingDiv.css('width', carouselPagingWidth +'px');

				_updateLookbookCarouselPagingVisibility();
			};
			
			
			
			
			var _resizeProductCarousel = function () {
				var images                    = _m.getProductImages();
				var thumbnailCount            = images.length;
				var visibleThumbnailCount     = _calculateProductCarouselVisibleCount();
				var pagingRequired            = thumbnailCount > visibleThumbnailCount;

				var carouselWidth             = visibleThumbnailCount * _configuration.CAROUSEL_THUMBNAIL_WIDTH;
				var carouselMarginleft        = pagingRequired ? _configuration.CAROUSEL_PAGING_ARROW_WIDTH : 0;
				_productCarouselDiv.css('width', carouselWidth +'px');
				_productCarouselDiv.css('margin-left', carouselMarginleft +'px');

				var carouselPagingWidth       = carouselWidth + (_configuration.CAROUSEL_PAGING_ARROW_WIDTH * 2);
				_productCarouselPagingDiv.css('width', carouselPagingWidth +'px');

				_updateProductCarouselPagingVisibility();
			};
			
			
			
			
			var _moveLookbookCarousel = function (index, skipAnimation) {
				// perform "safety" checks to never move beyond the first or
				// last thumbnail - since we are using dynamic width, we don't have
				// traditional paging so everything is based off of the current
				// window width and number of visible thumbs (# of visible thumbs =
				// dynamic per page count)
				var images                 = _m.getLookbookImages();
				var thumbnailCount         = images.length;
				var visibleThumbnailCount  = _calculateLookbookCarouselVisibleCount();
				var firstVisibleIndex      = index;

				if ((firstVisibleIndex + visibleThumbnailCount) > thumbnailCount) {
					firstVisibleIndex = thumbnailCount - visibleThumbnailCount;
				}
				if (firstVisibleIndex < 0) {
					firstVisibleIndex = 0;
				}
				_lookbookCarouselFirstVisibleIndex = firstVisibleIndex;

				// making sure to stop all animations to prevent "skittering" on fast
				// clicking the paging arrows
				var marginLeft   = -_lookbookCarouselFirstVisibleIndex * _configuration.CAROUSEL_THUMBNAIL_WIDTH;
				var thumbnails   = _lookbookCarouselDiv.children('.thumbnails');

				// we use "skipAnimation" when moving back into position after window
				// resize triggers a resize of the image carousel since there is no
				// reason to animate in this scenario, only when someone uses the
				// paging arrows click do we need to animate
				if (skipAnimation) {
					thumbnails.css('margin-left', marginLeft);
				} else {
					thumbnails.animate({
						'margin-left':  marginLeft
					},{
						'duration':     450,
						'easing':       'easeOutQuad'
					});
				}

				_updateLookbookCarouselPagingVisibility();
			};
			
			
			
			
			var _moveProductCarousel = function (index, skipAnimation) {
				// perform "safety" checks to never move beyond the first or
				// last thumbnail - since we are using dynamic width, we don't have
				// traditional paging so everything is based off of the current
				// window width and number of visible thumbs (# of visible thumbs =
				// dynamic per page count)
				var images                 = _m.getProductImages();
				var thumbnailCount         = images.length;
				var visibleThumbnailCount  = _calculateProductCarouselVisibleCount();
				var firstVisibleIndex      = index;

				if ((firstVisibleIndex + visibleThumbnailCount) > thumbnailCount) {
					firstVisibleIndex = thumbnailCount - visibleThumbnailCount;
				}
				if (firstVisibleIndex < 0) {
					firstVisibleIndex = 0;
				}
				_productCarouselFirstVisibleIndex = firstVisibleIndex;

				// making sure to stop all animations to prevent "skittering" on fast
				// clicking the paging arrows
				var marginLeft   = -_productCarouselFirstVisibleIndex * _configuration.CAROUSEL_THUMBNAIL_WIDTH;
				var thumbnails   = _productCarouselDiv.children('.thumbnails');

				// we use "skipAnimation" when moving back into position after window
				// resize triggers a resize of the image carousel since there is no
				// reason to animate in this scenario, only when someone uses the
				// paging arrows click do we need to animate
				if (skipAnimation) {
					thumbnails.css('margin-left', marginLeft);
				} else {
					thumbnails.animate({
						'margin-left':  marginLeft
					},{
						'duration':     450,
						'easing':       'easeOutQuad'
					});
				}

				_updateProductCarouselPagingVisibility();
			};




			var _updateLookbookCarouselPagingVisibility = function () {
				var images                 = _m.getLookbookImages();
				var thumbnailCount         = images.length;
				var visibleThumbnailCount  = _calculateLookbookCarouselVisibleCount();

				_updateCarouselPagingVisibility(_lookbookCarouselPagingDiv, _lookbookCarouselFirstVisibleIndex, thumbnailCount, visibleThumbnailCount);
			};
			
			
			
			
			var _updateProductCarouselPagingVisibility = function () {
				var images                 = _m.getProductImages();
				var thumbnailCount         = images.length;
				var visibleThumbnailCount  = _calculateProductCarouselVisibleCount();
				
				_updateCarouselPagingVisibility(_productCarouselPagingDiv, _productCarouselFirstVisibleIndex, thumbnailCount, visibleThumbnailCount);
			};
			
			
			
			
			var _updateCarouselPagingVisibility = function (pagingDiv, firstVisibleIndex, thumbnailCount, visibleThumbnailCount) {
				// paging required if the total count is greater than the visible count
				if (thumbnailCount > visibleThumbnailCount) {
					var next              = pagingDiv.find('.next');
					var nextDisabled      = pagingDiv.find('.next-disabled');
					var previous          = pagingDiv.find('.previous');
					var previousDisabled  = pagingDiv.find('.previous-disabled');

					var isNextActive      = firstVisibleIndex + visibleThumbnailCount < thumbnailCount;
					var isPreviousActive  = firstVisibleIndex > 0;

					if (isNextActive) {
						next.show();
						nextDisabled.hide();
					} else {
						next.hide();
						nextDisabled.show();
					}

					if (isPreviousActive) {
						previous.show();
						previousDisabled.hide();
					} else {
						previous.hide();
						previousDisabled.show();
					}

					pagingDiv.show();
				} else {
					pagingDiv.hide();
				}
			};
			
			
			
			
			var _setLookbookCarouselSelectedIndex = function (index) {
				var thumbnailsDiv          = _lookbookCarouselDiv.find('.thumbnail');
				var selectedThumbnailDiv   = _lookbookCarouselDiv.find('.thumbnail').eq(index);
				var carouselIndex          = index - Math.floor(_calculateLookbookCarouselVisibleCount() / 2);

				thumbnailsDiv.removeClass('selected');
				selectedThumbnailDiv.addClass('selected');

				_moveLookbookCarousel(carouselIndex);
			};
			
			
			
			
			var _setProductCarouselSelectedIndex = function (index) {
				var thumbnailsDiv          = _productCarouselDiv.find('.thumbnail');
				var selectedThumbnailDiv   = _productCarouselDiv.find('.thumbnail').eq(index);
				var carouselIndex          = index - Math.floor(_calculateProductCarouselVisibleCount() / 2);

				thumbnailsDiv.removeClass('selected');
				selectedThumbnailDiv.addClass('selected');

				_moveProductCarousel(carouselIndex);
			};
			
			
			
			var _pageProductComments = function (direction) {
				var commentsDiv  = $('#product-social-panel-comments');
				var newIndex     = direction == 'up' ? _productCommentsIndex - 1 : _productCommentsIndex + 1;
				var maxIndex     = commentsDiv.children('.comment').length - 1;
				
				if (newIndex < 0) {
					newIndex = 0;
				} else if (newIndex > maxIndex) {
					newIndex = maxIndex;
				}
				if (newIndex == _productCommentsIndex) {
					return;
				}
				
				_productCommentsIndex = newIndex;
				
				var marginTop       = 0;
				var tempCommentDiv  = null;
				for (var i=0; i<newIndex; i++) {
					tempCommentDiv    = commentsDiv.children('.comment').eq(i);
					marginTop        -= tempCommentDiv.height() + 20;
				}
				
				commentsDiv.stop().animate({
					'margin-top':  marginTop
				},{
					'duration':    200,
					'easing':      'easeOutQuad'
				});
			};
			
			
			
			
			var _pageProductPhotos = function (direction) {
				var photosDiv    = $('#product-social-panel-photos');
				var newIndex     = direction == 'left' ? _productPhotosIndex - 1 : _productPhotosIndex + 1;
				var maxIndex     = photosDiv.children('.photo').length - 1;

				if (newIndex < 0) {
					newIndex = 0;
				} else if (newIndex > maxIndex) {
					newIndex = maxIndex;
				}
				if (newIndex == _productPhotosIndex) {
					return;
				}
				
				_productPhotosIndex = newIndex;
				
				var marginLeft      = 0;
				var tempPhotoDiv    = null;
				for (var i=0; i<newIndex; i++) {
					tempCommentDiv    = photosDiv.children('.photo').eq(i);
					marginLeft        -= tempCommentDiv.width();
				}
				
				photosDiv.stop().animate({
					'margin-left':  marginLeft
				},{
					'duration':    200,
					'easing':      'easeOutQuad'
				});
				
				var labelDiv = $('#product-social-panel-photos-paging').children('.paging-label');
				labelDiv.html((_productPhotosIndex + 1) +' of '+ (maxIndex + 1));
			};




			var _calculateLookbookCarouselVisibleCount = function () {
				var availableWidth = $(window).width() - _configuration.CAROUSEL_PADDING_WIDTH;
				return _calculateCarouselVisibleCount(_lookbookCarouselDiv, availableWidth);
			};




			var _calculateProductCarouselVisibleCount = function () {
				var availableWidth = $(window).width() - _configuration.CAROUSEL_PADDING_WIDTH;
				if (_productDetailPanelOpen) {
					availableWidth -= _configuration.PRODUCT_DETAIL_PANEL_WIDTH;
				}
				return _calculateCarouselVisibleCount(_productCarouselDiv, availableWidth);
			};
			
			
			
			
			var _calculateCarouselVisibleCount = function (carouselDiv, availableWidth) {
				var thumbnailsCount  = carouselDiv.find('.thumbnail').length;
				var visibleCount     = Math.floor(availableWidth / _configuration.CAROUSEL_THUMBNAIL_WIDTH);

				if (visibleCount < _configuration.CAROUSEL_MIN_VISIBLE_THUMBNAILS) {
					visibleCount = _configuration.CAROUSEL_MIN_VISIBLE_THUMBNAILS;
				} else if (visibleCount > thumbnailsCount) {
					visibleCount = thumbnailsCount;
				}

				return visibleCount;
			};
			
			
			
			
			var _createInputFocusFunctions = function () {
				$('#product-social-panel-post-comment-input-name').bind('focusin', function () {
					var thisDiv = $(this);
					if (thisDiv.val() == 'Name') {
						thisDiv.val('');
					}
				});
				
				$('#product-social-panel-post-comment-input-name').bind('focusout', function () {
					var thisDiv = $(this);
					if (thisDiv.val() == '') {
						thisDiv.val('Name');
					}
				});
				
				$('#product-social-panel-post-comment-input-email').bind('focusin', function () {
					var thisDiv = $(this);
					if (thisDiv.val() == 'Email Address') {
						thisDiv.val('');
					}
				});
				
				$('#product-social-panel-post-comment-input-email').bind('focusout', function () {
					var thisDiv = $(this);
					if (thisDiv.val() == '') {
						thisDiv.val('Email Address');
					}
				});
				
				$('#product-social-panel-share-input-email').bind('focusin', function () {
					var thisDiv = $(this);
					if (thisDiv.val() == 'Your Email') {
						thisDiv.val('');
					}
				});
				
				$('#product-social-panel-share-input-email').bind('focusout', function () {
					var thisDiv = $(this);
					if (thisDiv.val() == '') {
						thisDiv.val('Your Email');
					}
				});
				
				$('#product-social-panel-share-input-friend-email').bind('focusin', function () {
					var thisDiv = $(this);
					if (thisDiv.val() == 'Friend\'s Email') {
						thisDiv.val('');
					}
				});
				
				$('#product-social-panel-share-input-friend-email').bind('focusout', function () {
					var thisDiv = $(this);
					if (thisDiv.val() == '') {
						thisDiv.val('Friend\'s Email');
					}
				});
			};
			
			
			
			
			var _getCommentData = function () {
				var data         = [];
				data['name']     = $('#product-social-panel-post-comment-input-name').val();
				data['email']    = $('#product-social-panel-post-comment-input-email').val();
				data['comment']  = $('#product-social-panel-post-comment-input-comment').val();

				return data;
			};
			
			
			
			
			var _openHotspotBubble = function (div, index) {
				clearTimeout(_closeHotspotBubbleTimeout);
				
				var image         = _m.getSelectedLookbookImage();
				var hotspots      = image['hotspots'];
				var hotspot       = hotspots[index];

				_hotspotBubbleDiv.find('.title').html(hotspot['product_name']);
				_hotspotBubbleDiv.find('.price').html('<span class="price-sign">$</span>'+ _formatProductPrice(hotspot['product_price']));
				_hotspotBubbleDiv.find('.collection').children('a').html(hotspot['collection_name']).attr('href', '/lookbook/'+ hotspot['collection_slug']);

				_hotspotBubbleDiv.find('.details').find('a').unbind();
				_hotspotBubbleDiv.find('.details').find('a').bind('click', function () {
					_c.onHotspotClick(index);
				});

				if (hotspot['product_ecommerce_url']) {
					_hotspotBubbleDiv.find('.buy-now').find('a').attr('href', hotspot['product_ecommerce_url']);
					_hotspotBubbleDiv.find('.buy-now').show();
				} else {
					_hotspotBubbleDiv.find('.buy-now').hide();
				}


				var bubbleTop     = div.offset().top;
				var bubbleBottom  = $(window).height() - bubbleTop;
				var bubbleLeft    = div.offset().left + 5;

				_hotspotBubbleDiv.css('height', 0);
				_hotspotBubbleDiv.css('bottom', bubbleBottom);
				_hotspotBubbleDiv.css('left', bubbleLeft);
				_hotspotBubbleDiv.stop().animate({
					'height':    _configuration.HOTSPOT_BUBBLE_HEIGHT
				},{
					'easing':   'easeOutQuad',
					'duration':  100
				});
			};




			var _closeHotspotBubble = function (immediate, skipAnimation) {
				if (skipAnimation) {
					_hotspotBubbleDiv.css('height', 0);
					return;
				}
				
				if (immediate) {
					_actualCloseHotspotBubble();
				} else {
					clearTimeout(_closeHotspotBubbleTimeout);
					_closeHotspotBubbleTimeout = setTimeout(function () { _actualCloseHotspotBubble(); }, 500);
				}
			};
			
			
			
			
			var _actualCloseHotspotBubble = function () {
				_hotspotBubbleDiv.stop().animate({
					'height':    0
				},{
					'easing':   'easeOutQuad',
					'duration':  100
				});
			};
			
			
			
			
			var _onRelatedProductMouseenter = function (relatedProductDiv) {
				var bubbleTop   = relatedProductDiv.offset().top;
				var bubbleLeft  = relatedProductDiv.offset().left;
				
				_relatedBubbleDiv.css('top', bubbleTop);
				_relatedBubbleDiv.css('left', bubbleLeft);
				_relatedBubbleDiv.show();
			};




			var _onRelatedProductMouseleave = function (relatedProductDiv) {
				_relatedBubbleDiv.hide();
			};




			return {
				initialize:function () {
					$('#site').css('overflow', 'hidden');

					_hotspotBubbleDiv                = $('#hotspot-bubble-lookbook');
					_lookbookBackgroundDiv           = $('#lookbook').children('.background');
					_lookbookImageDiv                = $('#'+ _configuration.DIV_ID_LOOKBOOK_IMAGE);
					_lookbookImageZoomHitDiv         = $('#'+ _configuration.DIV_ID_LOOKBOOK_IMAGE_ZOOM).children('.hit');
					_lookbookImageZoomResetDiv       = $('#lookbook-zoom-reset-button');
					_lookbookCarouselDiv             = $('#'+ _configuration.DIV_ID_LOOKBOOK_IMAGE_CAROUSEL);
					_lookbookCarouselPagingDiv       = $('#'+ _configuration.DIV_ID_LOOKBOOK_IMAGE_CAROUSEL_PAGING);
					_productImageDiv                 = $('#'+ _configuration.DIV_ID_PRODUCT_IMAGE);
					_productImageZoomHitDiv          = $('#'+ _configuration.DIV_ID_PRODUCT_IMAGE_ZOOM).children('.hit');
					_productImageZoomResetDiv        = $('#product-zoom-reset-button');
					_productCarouselDiv              = $('#'+ _configuration.DIV_ID_PRODUCT_CAROUSEL);
					_productCarouselPagingDiv        = $('#'+ _configuration.DIV_ID_PRODUCT_CAROUSEL_PAGING);
					_productDetailPanelDiv           = $('#'+ _configuration.DIV_ID_PRODUCT_DETAIL_PANEL);
					_productSocialPanelDiv           = $('#'+ _configuration.DIV_ID_PRODUCT_SOCIAL_PANEL);
					_relatedBubbleDiv                = $('#product-related-hover-bubble');

					_lookbookCarouselPagingDiv.find('.next').bind('click', function () {
						_moveLookbookCarousel(_lookbookCarouselFirstVisibleIndex + _calculateLookbookCarouselVisibleCount());
					});
					
					_lookbookCarouselPagingDiv.find('.previous').bind('click', function () {
						_moveLookbookCarousel(_lookbookCarouselFirstVisibleIndex - _calculateLookbookCarouselVisibleCount());
					});
					
					_lookbookImageZoomHitDiv.bind('mouseenter', function () {
						$(this).parent().children('.zoomspot').show();
					});
					
					_lookbookImageZoomHitDiv.bind('mouseleave', function () {
						$(this).parent().children('.zoomspot').hide();
					});
					
					_lookbookImageZoomHitDiv.bind('mousemove', function (event) {
						var zoomSpotDiv = $(this).parent().children('.zoomspot');
						zoomSpotDiv.css('top', event.clientY);
						zoomSpotDiv.css('left', event.clientX);
					});
					
					_lookbookImageZoomHitDiv.bind('click', function (event) {
						_c.onLookbookImageZoomClick(event);
					});
					
					_productImageZoomHitDiv.bind('mouseenter', function () {
						$(this).parent().children('.zoomspot').show();
					});
					
					_productImageZoomHitDiv.bind('mouseleave', function () {
						$(this).parent().children('.zoomspot').hide();
					});
					
					_productImageZoomHitDiv.bind('mousemove', function (event) {
						var zoomSpotDiv = $(this).parent().children('.zoomspot');
						zoomSpotDiv.css('top', event.clientY);
						zoomSpotDiv.css('left', event.clientX);
					});
					
					_productImageZoomHitDiv.bind('click', function (event) {
						_c.onProductImageZoomClick(event);
					});
					
					_productDetailPanelDiv.find('.close-button').children('a').bind('click', function () {
						_c.onProductDetailPanelCloseClick();
					});
					
					_productDetailPanelDiv.find('.social-share-link').children('a').bind('click', function () {
						_c.onSocialShareLinkClick();
					});
					
					_productSocialPanelDiv.find('.content-share').find('.close-button').children('a').bind('click', function () {
						_c.onProductSocialPanelShareCloseClick();
					});
					
					$('#product-social-panel-cancel-share-button').find('a').bind('click', function () {
						_c.onProductSocialPanelShareCloseClick();
					});
					
					_productDetailPanelDiv.find('.social-comment-link').children('a').bind('click', function () {
						_c.onSocialCommentLinkClick();
					});
					
					_productSocialPanelDiv.find('.content-comment').find('.close-button').children('a').bind('click', function () {
						_c.onProductSocialPanelCommentCloseClick();
					});
					
					_productSocialPanelDiv.find('.content-post-comment').find('.close-button').children('a').bind('click', function () {
						_c.onProductSocialPanelPostCommentCloseClick();
					});
					
					$('#product-social-panel-post-comment-button').bind('click', function () {
						_c.onSocialPostCommentButtonClick();
					});
					
					$('#product-social-panel-cancel-post-comment-button').bind('click', function () {
						_c.onProductSocialPanelPostCommentCloseClick();
					});
					
					$('#product-social-panel-submit-post-comment-button').bind('click', function () {
						_c.onProductSocialPanelPostCommentSubmitClick();
					});
					
					$('#product-social-panel-comment-signup-checkbox').bind('click', function () {
						_c.onProductSocialPanelPostCommentNewsletterClick();
					});
					
					$('#product-social-panel-share-signup-checkbox').bind('click', function () {
						_c.onProductSocialPanelShareNewsletterClick();
					});
					
					_productSocialPanelDiv.find('.comments-container-paging').children('.arrow-up').children('a').bind('click', function () {
						_c.onPageComments('up');
					});
					
					_productSocialPanelDiv.find('.comments-container-paging').children('.arrow-down').children('a').bind('click', function () {
						_c.onPageComments('down');
					});
					
					_productSocialPanelDiv.find('.photos-container-paging').children('.arrow-left').children('a').bind('click', function () {
						_c.onPagePhotos('left');
					});
					
					_productSocialPanelDiv.find('.photos-container-paging').children('.arrow-right').children('a').bind('click', function () {
						_c.onPagePhotos('right');
					});
					
					_hotspotBubbleDiv.bind('mouseenter', function () {
						clearTimeout(_closeHotspotBubbleTimeout);
					});
					
					_hotspotBubbleDiv.bind('mouseleave', function () {
						clearTimeout(_closeHotspotBubbleTimeout);
						_closeHotspotBubbleTimeout = setTimeout(function () { _closeHotspotBubble(); }, 500);
					});
					
					_productImageZoomResetDiv.find('a').bind('click', function () {
						_c.onProductImageZoomResetClick();
					});
					
					_lookbookImageZoomResetDiv.find('a').bind('click', function () {
						_c.onLookbookImageZoomResetClick();
					});

					// -- keep open for now
					// $('#header').children('.nav').hover(
					// 	function () {
					// 		if (!_productSocialPanelOpen && !_productDetailPanelOpen) { return; }
					// 		
					// 		$(this).animate({
					// 			'top':       0
					// 		},{
					// 			'duration':  200,
					// 			'easing':    'easeOutQuad',
					// 			'queue':     false
					// 		});
					// 	},
					// 	function () {
					// 		if (!_productSocialPanelOpen && !_productDetailPanelOpen) { return; }
					// 		
					// 		$(this).animate({
					// 			'top':       -75
					// 		},{
					// 			'duration':  200,
					// 			'easing':    'easeOutQuad',
					// 			'queue':     false
					// 		});
					// 	}
					// );
					
					$('#product-social-panel-share-facebook').bind('click', function () {
						_c.onShareClick('facebook');
					});
					
					$('#product-social-panel-share-twitter').bind('click', function () {
						_c.onShareClick('twitter');
					});
					
					$('#product-social-panel-share-send-button').bind('click', function () {
						_c.onEmailSendClick();
					});

					_createInputFocusFunctions();
					
					var photosDiv = $('#product-social-panel-photos');
					photosDiv.width(2000);// @TODO - dynamically create width based on photos themselves
					
					_lookbookImageDiv.hide();
					_productImageDiv.hide();
				},




				transition:function (mode) {
					switch (mode) {
						case 'loading-lookbook':
							_lookbookCarouselDiv.children('.thumbnails').empty();
							_lookbookImageDiv.empty();
							break;


						case 'lookbook':
							// very important to unbind load listener and kill
							// product image so that the product image doesn't
							// load then appear over the lookbook image
							// when clicking "back to look"
							if (_productImageLoader) {
								_productImageLoader.src = '';
							}
							_productImageDiv.children('img').attr('src', '');

						
							_setLookbookImageZoomed(false);
							_setLookbookImageZoomEnabled(false);
							_setLookbookImageOpen(true);
							_setLookbookImageHotspotsEnabled(true);
							_setLookbookCarouselOpen(true);

							_setProductImageOpen(false);
							_setProductImageZoomed(false, null, true);
							_setProductImageZoomEnabled(false);

							_setProductCarouselOpen(false);
							_setProductDetailPanelOpen(false);
							_setProductSocialPanelOpen(false, null);
							break;


						case 'loading-lookbook-complete':
							_buildLookbookImage();
							_setLookbookImageZoomEnabled(false);
						
							_buildLookbookCarousel();
							_resizeLookbookCarousel();
							_setLookbookCarouselSelectedIndex(0);
							_setLookbookCarouselOpen(true);
							break;
							

						case 'loading-product':
							_buildProductInfoLoading();
							_setLookbookCarouselOpen(false);
							_setProductDetailPanelOpen(true);
							_setLookbookImageZoomEnabled(true);
							_setLookbookImageHotspotsEnabled(false);
							break;
							
							
						case 'loading-product-complete':
							_buildProductInfo();
							_buildProductComments();
							_buildProductCommunityPhotos();

							if (!_m.isLookbookMode()) {
								_buildProductImage();
							}

							_buildProductCarousel();
							_resizeProductCarousel();
							_setProductCarouselSelectedIndex(0);
							_setProductCarouselOpen(true);
							break;


						case 'open-product':
							var product        = _m.getProduct();
							var startingAsset  = product['starting_asset'];
						
							_resizeProductCarousel();
							_setLookbookCarouselOpen(false);
							_setProductCarouselOpen(true);
							_setProductDetailPanelOpen(true, true);

							if (_useStartingAssetOnce && startingAsset) {
								_useStartingAssetOnce = false;

								if (startingAsset['is_color']) {
									_buildProductImage(startingAsset['asset_url']);
									$('.product-color').children('a[rel='+ startingAsset['id'] +']').addClass('selected');
								} else {
									var images         = product['images'];
									var selectedIndex  = 0;
									for (var i=0; i<images.length; i++) {
										if (images[i]['id'] == startingAsset['id']) {
											selectedIndex = i;
										}
									}

									_m.setProductImagesSelectedIndex(selectedIndex, true);
								}
							} else {
								_buildProductImage();
								_setProductCarouselSelectedIndex(0);
							}

							// special case where we set listeners here since
							// this is not being called post ajax where items were built
							// out and listeners added
							_productCarouselDiv.find('.thumbnail').bind('click', function () {
								_c.onProductCarouselClick($(this));
							});
							
							_productDetailPanelDiv.find('.product-colors').children('.product-color').children('a').bind('click', function () {
								_c.onProductColorClick($(this));
							});
							
							_productDetailPanelDiv.find('.product-colors').children('.product-color').children('a').bind('mouseenter', function () {
								_c.onProductColorMouseEnter($(this));
							});
							
							_productDetailPanelDiv.find('.product-colors').children('.product-color').children('a').bind('mouseleave', function () {
								_c.onProductColorMouseLeave($(this));
							});
							
							_productDetailPanelDiv.find('.related-product').bind('click', function () {
								document.location.href = '/product/'+ $(this).attr('rel');
							});

							_productDetailPanelDiv.find('.related-product').bind('mouseenter', function () {
								_onRelatedProductMouseenter($(this));
							});

							_productDetailPanelDiv.find('.related-product').bind('mouseleave', function () {
								_onRelatedProductMouseleave($(this));
							});

							_setProductImageZoomEnabled(true);
							break;


						case 'update-lookbook-selected-index':
							_setLookbookCarouselSelectedIndex(_m.getLookbookImagesSelectedIndex());
							_setLookbookImageZoomed(false);
							_buildLookbookImage();
							break;


						case 'update-product-selected-index':
							_setLookbookImageOpen(false);
							_setLookbookImageZoomEnabled(false);
							_setProductImageZoomEnabled(true);
							_setProductImageZoomed(false);
							_setLookbookImageZoomed(false);
							_setProductCarouselSelectedIndex(_m.getProductImagesSelectedIndex());
							
							_buildProductImage();
							break;

							
						case 'share':
							_setProductSocialPanelOpen(true, 'share');
							break;

							
						case 'share-close':
							_setProductSocialPanelOpen(false, 'share');
							break;

							
						case 'comment':
							_setProductSocialPanelOpen(true, 'comment');
							break;


						case 'comment-close':
							_setProductSocialPanelOpen(false, 'comment');
							break;
							
							
						case 'post-comment':
							_setProductSocialPanelOpen(true, 'post-comment');
							break;


						case 'post-comment-close':
							_setProductSocialPanelOpen(false, 'post-comment');
							break;
					}
				},
				
				
				
				
				resizeLookbookBackground:function () {
					_resizeLookbookBackground();
				},
				
				
				
				
				resizeLookbookImage:function () {
					_resizeLookbookImage();
				},
				
				
				
				
				resizeProductImage:function () {
					_resizeProductImage();
				},
				
				
				
				
				resizeLookbookCarousel:function () {
					_resizeLookbookCarousel();
				},
				
				
				
				
				resizeProductCarousel:function () {
					_resizeProductCarousel();
				},
				
				
				
				
				enforceLookbookSelectedIndex:function () {
					_moveLookbookCarousel(_lookbookCarouselFirstVisibleIndex, true);
				},




				pageProductComments:function (direction) {
					_pageProductComments(direction);
				},




				pageProductPhotos:function (direction) {
					_pageProductPhotos(direction);
				},




				setLookbookImageZoomed:function (zoomed, point) {
					_setLookbookImageZoomed(zoomed, point);
				},			




				setProductImageZoomed:function (zoomed, point) {
					_setProductImageZoomed(zoomed, point);
				},




				getCommentData:function () {
					return _getCommentData();
				},
				
				
				
				changeProductImageUrl:function (assetUrl) {
					_buildProductImage(assetUrl, function () {
						if (_productImageLoader) {
							_productImageLoader.onload = null;
						}

						_productImageLoader = new Image();
						_productImageLoader.onload = function () {
							var imageNativeWidth        = this.width;
							var imageNativeHeight       = this.height;
							var imageNativeAspectRatio  = imageNativeWidth / imageNativeHeight;
							var imageHeight             = $(window).height() - 30;
							var imageWidth              = imageHeight * imageNativeAspectRatio;

							_productImageDiv.children('img').height(imageHeight);
							
							var imageMarginLeftOffset = 0;
							if (_productDetailPanelOpen) {
								imageMarginLeftOffset -= (_configuration.PRODUCT_DETAIL_PANEL_WIDTH / 2);
							}
							if (_productSocialPanelOpen) {
								imageMarginLeftOffset -= (_configuration.PRODUCT_SOCIAL_PANEL_WIDTH / 2);
							}
							
							var imageMarginLeft = -(imageWidth / 2) + imageMarginLeftOffset;
							_productImageDiv.css('margin-left', imageMarginLeft);
							_productImageDiv.fadeIn(200, 'easeOutQuad');
							
							// resize product image hit state to match new dimensions
							_productImageZoomHitDiv.css('width', imageWidth);
							_productImageZoomHitDiv.css('height', imageHeight);
							_productImageZoomHitDiv.css('margin-left', imageMarginLeft);
							
							setTimeout(function () { _slidePanelsImagesAndCarousels(); }, 50);
						};
						
						setTimeout(function () { _productImageLoader.src = assetUrl; }, 10);
					});

					
					_setLookbookImageOpen(false);
					_setLookbookImageZoomed(false);
					_setLookbookImageZoomEnabled(false);
					_setProductImageOpen(true);
					_setProductImageZoomEnabled(true);
					_setProductImageZoomed(false);
				},
				
				
				
				
				openHotspotBubble:function (div, index) {
					_openHotspotBubble(div, index);
				},
				closeHotspotBubble:function (immediate, skipAnimation) {
					_closeHotspotBubble(immediate, skipAnimation);
				},
				
				
				
				
				reflectProductCommentNewsletterOptIn:function () {
					var checkboxDiv = $('#product-social-panel-comment-signup-checkbox').find('.checkbox');
					if (_m.isProductCommentNewsletterOptIn()) {
						checkboxDiv.addClass('checkbox-selected');
					} else {
						checkboxDiv.removeClass('checkbox-selected');
					}
				},
				reflectProductShareNewsletterOptIn:function () {
					var checkboxDiv = $('#product-social-panel-share-signup-checkbox').find('.checkbox');
					if (_m.isProductShareNewsletterOptIn()) {
						checkboxDiv.addClass('checkbox-selected');
					} else {
						checkboxDiv.removeClass('checkbox-selected');
					}
				},




				deselectProductColors:function () {
					$('.product-color').children('a').removeClass('selected')
				},
				deselectProductCarousel:function () {
					$('#product-carousel').find('.thumbnail').removeClass('selected');
				},
				
				
				
				
				showCommentError:function (whichError) {
					var confirmationDiv  = _productSocialPanelDiv.find('.row-comment-confirmation');
					var errorDiv         = _productSocialPanelDiv.find('.row-comment-error');
					var invalidDiv       = _productSocialPanelDiv.find('.row-comment-error-invalid');
					var postingDiv       = _productSocialPanelDiv.find('.row-comment-posting');
					var buttonsDiv       = _productSocialPanelDiv.find('.row-buttons');

					confirmationDiv.hide();
					invalidDiv.hide();
					errorDiv.hide();
					postingDiv.hide();
					buttonsDiv.show();

					switch (whichError) {
						case 'confirmation':
							$('#product-social-panel-post-comment-input-name').val('Name');
							$('#product-social-panel-post-comment-input-email').val('Email Address');
							$('#product-social-panel-post-comment-input-comment').val('');
							
							confirmationDiv.show();
							setTimeout(function () { confirmationDiv.fadeOut(); }, 1500);
							break;

						case 'error':
						case 'error-invalid':
							_productSocialPanelDiv.find('.row-comment-'+ whichError).show();
							break;

						default:
							// do nothing - false hides everything
							break;
					}
				},
				
				
				
				
				showCommentPosting:function () {
					var confirmationDiv  = _productSocialPanelDiv.find('.row-comment-confirmation');
					var errorDiv         = _productSocialPanelDiv.find('.row-comment-error');
					var invalidDiv       = _productSocialPanelDiv.find('.row-comment-error-invalid');
					var postingDiv       = _productSocialPanelDiv.find('.row-comment-posting');
					var buttonsDiv       = _productSocialPanelDiv.find('.row-buttons');

					confirmationDiv.hide();
					invalidDiv.hide();
					errorDiv.hide();
					buttonsDiv.hide();
					postingDiv.show();
				}
			}
		}();
		
		
		
		
		var _c = function () {
			var _fadeOutEmailConfirmationTimeout = 0;
			
			
			
			var _onWindowResize = function () {
				_v.resizeLookbookBackground();
				_v.resizeLookbookImage();
				_v.resizeLookbookCarousel();
				_v.resizeProductImage();
				_v.resizeProductCarousel();
				_v.enforceLookbookSelectedIndex();
			};
			
			
			
			
			var _onProductColorClick = function (colorAnchorTag) {
				$('.product-color').children('a').removeClass('selected');
				colorAnchorTag.addClass('selected');
				
				var colorAssetId   = colorAnchorTag.attr('rel');
				var colorAssetUrl  = ASSET_BASE_URL +'/editoral_'+ colorAssetId +'.png';

				_m.setSelectedProductColorAsset(colorAssetId);
				_v.changeProductImageUrl(colorAssetUrl);
				_v.deselectProductCarousel();
			};
			
			
			
			
			var _onProductColorMouseEnter = function (colorAnchorTag) {
				var colorName = colorAnchorTag.attr('title');
				$('.product-colors-label').html(colorName);
			};
			
			
			
			
			var _onProductColorMouseLeave = function (colorAnchorTag) {
				$('.product-colors-label').html('');
			};




			var _onShareClick = function (site) {
				var product = _m.getProduct();
				if (product === false || product === null) {
					alert('Please wait for product to finish loading');
					return;
				}
				
				var shareUrl      = _getShareUrl(product);
				var fullShareUrl  = null;
				switch (site) {
					case 'facebook':
						var shareTitle  = 'Rated M - '+ product['name'];
						fullShareUrl    = 'http://facebook.com/sharer.php?u='+ encodeURIComponent(shareUrl) +'&t='+ encodeURIComponent(shareTitle);
						break;

					case 'twitter':
						var status      = 'Check out this product by @RatedMOfficial - '+ shareUrl;
						fullShareUrl    = 'http://twitter.com/home?status='+ encodeURIComponent(status);
						break;
				}
				
				window.open(fullShareUrl);
			};
			
			
			
			
			var _onEmailSendClick = function () {
				var product = _m.getProduct();
				if (product === false || product === null) {
					alert('Please wait for product to finish loading');
					return;
				}
				
				var email        = $('#product-social-panel-share-input-email').val();
				var friendEmail  = $('#product-social-panel-share-input-friend-email').val();
				var message      = $('#product-social-panel-share-input-message').val();
				var valid        = true;
				
				var sendingDiv = $('#product-social-panel').find('.row-email-sending');
				sendingDiv.show();

				var buttonsDiv = $('#product-social-panel').find('.row-buttons');
				buttonsDiv.hide();
				
				var confirmationDiv = $('#product-social-panel').find('.row-email-confirmation');
				confirmationDiv.hide();
				
				var errorDiv = $('#product-social-panel').find('.row-email-error');
				errorDiv.hide();
				
				var invalidDiv = $('#product-social-panel').find('.row-email-error-invalid');
				invalidDiv.hide();
				
				clearTimeout(_fadeOutEmailConfirmationTimeout);
				
				if (!_validateEmail(email, 'Your Email')) {
					valid = false;
				}
				if (!_validateEmail(friendEmail, 'Friend\'s Email')) {
					valid = false;
				}
				
				if (!valid) {
					sendingDiv.hide();
					buttonsDiv.show();
					invalidDiv.show();
					return;
				}
				
				var data   = '';
				data      += 'email='+ encodeURIComponent(email);
				data      += '&friendEmail='+ encodeURIComponent(friendEmail);
				data      += '&message='+ encodeURIComponent(message);
				data      += '&sharedUrl='+ encodeURIComponent(_getShareUrl(product));

				$.ajax({
					'url':      '/api/create/email',
					'type':     'POST',
					'data':     data,
					'success':  function (response) { _sendEmailCallback(response); },
					'error':    function (response) { _sendEmailCallback(false); }
				});
			};




			var _sendEmailCallback = function (response) {
				var email        = $('#product-social-panel-share-input-email');
				var friendEmail  = $('#product-social-panel-share-input-friend-email');
				var message      = $('#product-social-panel-share-input-message');

				email.val('Your Email');
				friendEmail.val('Friend\'s Email');
				message.val('');

				var confirmationDiv  = $('#product-social-panel').find('.row-email-confirmation');
				var errorDiv         = $('#product-social-panel').find('.row-email-error');
				var invalidDiv       = $('#product-social-panel').find('.row-email-error-invalid');
				var sendingDiv       = $('#product-social-panel').find('.row-email-sending');
				var buttonsDiv       = $('#product-social-panel').find('.row-buttons');

				confirmationDiv.hide();
				errorDiv.hide();
				invalidDiv.hide();
				sendingDiv.hide();
				buttonsDiv.show();

				if (response === false || response['success'] === false) {
					errorDiv.show();
					return;
				}

				confirmationDiv.show();
				clearTimeout(_fadeOutEmailConfirmationTimeout);
				_fadeOutEmailConfirmationTimeout = setTimeout(function () { $('#product-social-panel').find('.row-email-confirmation').fadeOut(); }, 1500);
			};
			
			
			
			
			var _getShareUrl = function (product) {
				var selectedImage        = _m.getSelectedProductImage();
				var productColorAssetId  = _m.getSelectedProductColorAsset();
				if (!product) {
					return false;
				}

				var isSharingColorAsset     = productColorAssetId != -1 && productColorAssetId != null;
				var selectedImageUrlSuffix  = isSharingColorAsset ? 'color/'+ productColorAssetId : selectedImage['id'];

				return'http://ratedm.com/product/'+ product['slug'] +'/'+ selectedImageUrlSuffix;
			};




			return {
				initialize:function () {
					$(window).resize(function () {
						_onWindowResize();
					});
					_onWindowResize();
				},
				onLoadLookbook:function (id) {
					_m.loadLookbook(id);
				},
				onLookbookCarouselClick:function (thumbnail) {
					_m.setSelectedProductColorAsset(null);
					_m.setLookbookImagesSelectedIndex(thumbnail.index());
				},
				onHotspotClick:function (index) {
					var image      = _m.getSelectedLookbookImage();
					var hotspots   = image['hotspots'];
					var hotspot    = hotspots[index];
					var productId  = hotspot['product_id'];

					_m.loadProduct(productId, true);
					_v.closeHotspotBubble(true, true);
				},
				onHotspotRolled:function (div, index) {
					_v.openHotspotBubble(div, index);
				},
				onHotspotRolledOut:function (div, index) {
					_v.closeHotspotBubble(false);
				},
				onLoadProduct:function (id) {
					_m.loadProduct(id);
				},
				onOpenProduct:function (product) {
					_m.setProduct(product);
					_v.transition('open-product');
				},
				onProductCarouselClick:function (thumbnail) {
					_m.setSelectedProductColorAsset(null);
					_m.setProductImagesSelectedIndex(thumbnail.index());
					_v.closeHotspotBubble(true, true);
					_v.deselectProductColors();
				},
				onLoadError:function () {
					document.location.href = '/';
				},
				onProductDetailPanelCloseClick:function () {
					if (_m.isLookbookMode()) {
						_v.transition('lookbook');
					}
				},
				onProductColorClick:function (colorAnchorTag) {
					_onProductColorClick(colorAnchorTag);
					_v.closeHotspotBubble(true, true);
				},
				onProductColorMouseEnter:function (colorAnchorTag) {
					_onProductColorMouseEnter(colorAnchorTag);
				},
				onProductColorMouseLeave:function (colorAnchorTag) {
					_onProductColorMouseLeave(colorAnchorTag);
				},
				onProductSocialPanelShareCloseClick:function () {
					_v.transition('share-close');
				},
				onProductSocialPanelCommentCloseClick:function () {
					_v.transition('comment-close');
				},
				onProductSocialPanelPostCommentCloseClick:function () {
					_v.transition('post-comment-close');
				},
				onProductSocialPanelPostCommentSubmitClick:function () {
					var commentSubmissionData = _v.getCommentData();
					_m.submitProductComment(commentSubmissionData);
				},
				onProductSocialPanelPostCommentNewsletterClick:function () {
					_m.toggleProductCommentNewsletterOptIn();
					_v.reflectProductCommentNewsletterOptIn();
				},
				onProductSocialPanelShareNewsletterClick:function () {
					_m.toggleProductShareNewsletterOptIn();
					_v.reflectProductShareNewsletterOptIn();
				},
				onSocialShareLinkClick:function () {
					_v.transition('share');
				},
				onSocialCommentLinkClick:function () {
					_v.transition('comment');
				},
				onSocialPostCommentButtonClick:function () {
					_v.transition('post-comment');
				},
				onPageComments:function (direction) {
					_v.pageProductComments(direction);
				},
				onPagePhotos:function (direction) {
					_v.pageProductPhotos(direction);
				},
				onProductImageZoomClick:function (event) {
					var point   = [];
					point['x']  = event.pageX;
					point['y']  = event.pageY;
					
					_v.setProductImageZoomed(true, point);
					_v.closeHotspotBubble(true, true);
				},
				onProductImageZoomResetClick:function () {
					_v.setProductImageZoomed(false);
				},
				onLookbookImageZoomClick:function (event) {
					var point   = [];
					point['x']  = event.pageX;
					point['y']  = event.pageY;

					_v.setLookbookImageZoomed(true, point);
					_v.closeHotspotBubble(true, true);
				},
				onLookbookImageZoomResetClick:function () {
					_v.setLookbookImageZoomed(false);
				},
				onShareClick:function (site) {
					_onShareClick(site);
				},
				onEmailSendClick:function () {
					_onEmailSendClick();
				},
				getShareUrl:function (product) {
					return _getShareUrl(product);
				}
			};
		}();




		return  {
			initialize:function () {
				_m.initialize();
				_v.initialize();
				_c.initialize();
			},
			loadLookbook:function (id) {
				_c.onLoadLookbook(id);
			},
			loadProduct:function (id) {
				_c.onLoadProduct(id);
			},
			openProduct:function (product) {
				_c.onOpenProduct(product);
			},
			closeProductDetailPanel:function () {
				_c.onProductDetailPanelClose();
			}
		};
	}();
// END: _lookbook
//-----------------------------------------------------------------------------


//-----------------------------------------------------------------------------
// START: _productGrid
var _productGrid = function () {
	var _configuration = {
		HEADER_HEIGHT:                 120,
		FILTER_PANEL_HEIGHT:
		{
			'style':                   150,
			'color':                   150,
			'collection':              84
		},
		FILTER_PANEL_ARROW_WIDTH:      62,
		FILTER_WIDTH:
		{
			'style':                   165,
			'color':                   165,
			'collection':              172
		},
		GRID_CELL_WIDTH:               258
    };




	var _selectedStyleFilters          = [];
	var _selectedColorFilters          = [];
	var _selectedCollectionFilters     = [];
	var _actualSearchProductsTimeout   = 0;
	var _firstVisibleIndex             = {
		'style':       0,
		'color':       0,
		'collection':  0
	};
	
	
	
	
	var _dropdownOpen      = false;
	var _productSortOrder  = null;
	var _loading           = false;




	var _searchProducts = function (skipTimeout) {
		clearTimeout(_actualSearchProductsTimeout);
		
		if (skipTimeout) {
			_actualSearchProducts();
		} else {
			_actualSearchProductsTimeout = setTimeout(function () { _actualSearchProducts(); }, 750);
		}
	};
	
	
	
	
	var _reorderProductSearch = function (filterAnchor) {
		var newSortOrder  = filterAnchor.attr('rel');
		var newLabel      = filterAnchor.html();
		if (newSortOrder === _productSortOrder) { return; } _productSortOrder = newSortOrder;
		
		var gridHeaderDiv = $('#product-grid-header');
		gridHeaderDiv.find('.group-right').children('.filter').children('a').html(newLabel);
		
		var dropdownDiv = gridHeaderDiv.children('.dropdown-box');
		dropdownDiv.find('.filter').removeClass('selected');
		dropdownDiv.find('a[rel='+ _productSortOrder +']').parent().addClass('selected');
		
		_setFilterPanelDropdownOpen(false);
		
		_searchProducts();
	};




	var _actualSearchProducts = function () {
		if (_loading) { return; } _loading = true;
		
		var i = null;

		var colorFilterIds = [];
		for (i in _selectedColorFilters) {
			if (_selectedColorFilters[i]) {
				colorFilterIds.push(i);
			}
		}
		if (colorFilterIds.length == 0) {
			colorFilterIds.push(-1);
		}
		
		var styleFilterIds = [];
		for (i in _selectedStyleFilters) {
			if (_selectedStyleFilters[i]) {
				styleFilterIds.push(i);
			}
		}
		if (styleFilterIds.length == 0) {
			styleFilterIds.push(-1);
		}

		var collectionFilterIds = [];
		for (i in _selectedCollectionFilters) {
			if (_selectedCollectionFilters[i]) {
				collectionFilterIds.push(i);
			}
		}
		if (collectionFilterIds.length == 0) {
			collectionFilterIds.push(-1);
		}

		$.ajax({
			'url':       '/api/get/products',
			'data':      'colors='+ colorFilterIds.join(',') +'&styles='+ styleFilterIds.join(',') + '&collections='+ collectionFilterIds.join(',') +'&sort='+ _productSortOrder,
			'success':   function (response) { _actualSearchProductsCallback(response); },
			'error':     function (response) { _actualSearchProductsCallback(false); }
		});

		$('#product-grid').children('.content').empty();
	};




	var _actualSearchProductsCallback = function (response) {
		_loading = false;
		
		if (response === false || response['success'] === false) {
			document.location.href = '/shop';
			return;
		}
		
		var productGridContentDiv      = $('#product-grid').children('.content');
		var data                       = response['data'];
		var products                   = data['products'];
		var colorsLookup               = data['colors_lookup'];
		var largerProductStyleIds      = [16, 17, 18, 23];// @TODO - use non-hardcoded values
		var tempProduct                = null;
		var tempProductColorIds        = null;
		var tempProductColorAssetIds   = null;
		var tempProductPrice           = null;
		var tempColor                  = null;
		var tempCellHtml               = null;
		var tempCellDiv                = null;
		var tempPriceTagClass          = null;
		var tempSelectedColorIndex     = 0;
		var tempProductLargerClass     = null;

		for (var i=0; i<products.length; i++) {
			tempProduct                = products[i];
			tempProductColorIds        = tempProduct['color_ids'].split(',');
			tempProductColorAssetIds   = tempProduct['color_asset_ids'].split(',');
			tempProductPrice           = _formatProductPrice(tempProduct['price']);
			tempPriceTagClass          = tempProductPrice.length > 2 ? 'price-tag-wide' : 'price-tag';
			tempProductLargerClass     = largerProductStyleIds.indexOf(parseInt(tempProduct['style_id'])) >= 0 ? ' product-image-larger' : '';

			tempSelectedColorIndex = Math.round(Math.random() * tempProductColorAssetIds.length) - 1;
			if (tempSelectedColorIndex < 0) {
				tempSelectedColorIndex = 0;
			}

			tempCellHtml  = '<div class="cell">';
			tempCellHtml += '<div class="cell-content">';
			tempCellHtml += '<div class="product-image';
			tempCellHtml += tempProductLargerClass;
			tempCellHtml += '">';
			tempCellHtml += '<a href="/product/'+ tempProduct['slug'] +'">';
			tempCellHtml += '<img src="'+ _assetIdToAssetUrl(tempProductColorAssetIds[tempSelectedColorIndex], '_grid') +'" />';
			tempCellHtml += '</a>';
			tempCellHtml += '</div>';
			tempCellHtml += '<div class="product-name">'
			tempCellHtml += '<a href="/product/'+ tempProduct['slug'] +'">';
			tempCellHtml += tempProduct['name'];
			tempCellHtml += '</a>';
			tempCellHtml += '</div>';
			tempCellHtml += '<div class="product-info">';
			tempCellHtml += '<div class="collection-name"><a href="/lookbook/'+ tempProduct['collection_slug'] +'">'+ tempProduct['collection_name'] +'</a></div>';
			tempCellHtml += '<div class="'+ tempPriceTagClass +'">';
			
			if (tempProduct['ecommerce_url']) {
				tempCellHtml += '<a href="'+ tempProduct['ecommerce_url'] +'" target="_blank">';
			}
			tempCellHtml += '<span class="price-sign">$</span>'+ tempProductPrice;
			if (tempProduct['ecommerce_url']) {
				tempCellHtml += '</a>';
			}
			
			tempCellHtml += '</div>';
			tempCellHtml += '<div class="product-colors">';
			
			for (var j=0; j<tempProductColorIds.length; j++) {
				tempColor = colorsLookup[tempProductColorIds[j]];

				tempCellHtml += '<div class="product-color">';
				tempCellHtml += '<a href="javascript:void(0);" rel="'+ tempProductColorAssetIds[j] +'"';
				if (j == tempSelectedColorIndex) {
					tempCellHtml += ' class="selected"';
				}
				tempCellHtml += ' style="background-color:'+ tempColor['hex'] +'" title="'+ tempColor['name'] +'"></a>';
				tempCellHtml += '</div>';
			}

			tempCellHtml += '</div>';
			tempCellHtml += '</div>';
			tempCellHtml += '</div>';
			tempCellHtml += '</div>';

			tempCellDiv = $(tempCellHtml);
			tempCellDiv.appendTo(productGridContentDiv);

			tempCellDiv.find('.product-color').children('a').bind('click', function () {
				_onProductColorClick($(this));
			});
		}

		_resizeProductGrid();
	};
	
	
	
	
	var _selectInitialFilters = function () {
		var i                      = 0;
		var startingCollectionIds  = _configuration['starting_collection_ids'];

		if (startingCollectionIds) {
			for (i=0; i<startingCollectionIds.length; i++) {
				$('#filters-collection').children('.filter[rel=collection-'+ startingCollectionIds[i] +']').each(function () {
					_toggleFilter($(this), true, true, true);
				});
			}
		} else {
			$('#filters-collection').children('.filter').each(function () {
				_toggleFilter($(this), true, true, true);
			});
		}

		$('#filters-style').children('.filter').each(function () {
			_toggleFilter($(this), true, true, true);
		});
		
		$('#filters-color').children('.filter').each(function () {
			_toggleFilter($(this), true, true, true);
		});

		// search products will happen as a result of the calls to _toggleFilter
	};
	
	
	
	
	var _toggleAllFilters = function (filterType, isSelected) {
		$('#product-filter-panel-'+ filterType).find('.filter').each(function () {
			_toggleFilter($(this), true, isSelected);
		});

		// search products will happen as a result of the calls to _toggleFilter
	};




	var _toggleFilter = function (filterDiv, isForcedSelection, isSelected, skipSearch) {
		var tokens            = filterDiv.attr('rel').split('-');
		var type              = tokens[0];
		var id                = tokens[1];
		var selectedFilters   = null;

		switch (type) {
			case 'collection':
				selectedFilters = _selectedCollectionFilters;
				break;
				
			case 'style':
				selectedFilters = _selectedStyleFilters;
				break;
				
			case 'color':
				selectedFilters = _selectedColorFilters;
				break;
		}
		if (selectedFilters == null) {
			return;
		}

		selectedFilters[id] = isForcedSelection ? isSelected : !selectedFilters[id];
		if (selectedFilters[id]) {
			filterDiv.find('.checkbox').addClass('checkbox-selected');
		} else {
			filterDiv.find('.checkbox').removeClass('checkbox-selected');
		}

		if (!skipSearch) {
			_searchProducts();
		}
	};




	var _openFilterPanel = function (filterRel) {
		_setFilterPanelsOpen(true, filterRel);
	};




	var _closeFilterPanels = function (filterRel) {
		_setFilterPanelsOpen(false);
	};
	
	
	
	
	var _setFilterPanelsOpen = function (open, filterRel) {
		if (open && !filterRel) {
			return;
		}
		
		if (open) {
			$('.filter[rel=style]').removeClass('selected');
			$('.filter[rel=color]').removeClass('selected');
			$('.filter[rel=collection]').removeClass('selected');
			$('.filter[rel='+ filterRel +']').addClass('selected');
			$('.product-filter-panel').hide();
			$('#product-filter-panel-'+ filterRel).show();
		}
		
		var panelsContainerHeight  = open ? _configuration.FILTER_PANEL_HEIGHT[filterRel] : 0;
		var gridMarginTop          = open ? _configuration.HEADER_HEIGHT + panelsContainerHeight : _configuration.HEADER_HEIGHT;

		$('#product-filter-panels-container').stop().animate({
			'height':    panelsContainerHeight
		},{
			'duration':  200,
			'easing':    'easeOutQuad'
		});


		$('#product-grid').stop().animate({
			'margin-top':    gridMarginTop
		},{
			'duration':      200,
			'easing':        'easeOutQuad'
		});
	};




	var _resizeFilterCarousels = function () {
		_resizeFilterCarousel('style');
		_resizeFilterCarousel('color');
		_resizeFilterCarousel('collection');
	};
	
	
	
	
	var _resizeFilterCarousel = function (filterType) {
		_updateFilterCarouselPagingVisibility(filterType);
		_moveFiltersCarousel(filterType, _firstVisibleIndex[filterType], true);
	};
	
	
	
	
	var _pageFiltersCarousel = function (filterType, direction) {
		var filtersContainerDiv        = $('#product-filter-panel-'+ filterType);
		var filtersPagingContainerDiv  = $('#filters-carousel-paging-'+ filterType);
		var availableWidth             = $(window).width() - (2 * _configuration.FILTER_PANEL_ARROW_WIDTH);
		var visibleCount               = Math.floor(availableWidth / _configuration.FILTER_WIDTH[filterType]);
		var firstVisibleIndex          = _firstVisibleIndex[filterType];
		
		var newIndex = direction == 'previous' ? firstVisibleIndex - visibleCount : firstVisibleIndex + visibleCount;
		_moveFiltersCarousel(filterType, newIndex);
	};
	
	
	
	
	var _moveFiltersCarousel = function (filterType, toIndex, skipAnimation) {
		var filtersContainerDiv        = $('#product-filter-panel-'+ filterType);
		var filtersDiv                 = filtersContainerDiv.find('.filters');
		var filtersPagingContainerDiv  = $('#filters-carousel-paging-'+ filterType);
		var availableWidth             = $(window).width() - (2 * _configuration.FILTER_PANEL_ARROW_WIDTH);
		var visibleCount               = Math.floor(availableWidth / _configuration.FILTER_WIDTH[filterType]);
		var isPagingRequired           = parseInt(filtersDiv.css('width').replace('px', '')) > availableWidth;
		var maxIndex                   = filtersDiv.children('.filter').length - visibleCount;

		if (maxIndex < 0) {
			maxIndex = 0;
		}

		var newFirstVisibleIndex = toIndex;
		if (newFirstVisibleIndex < 0) {
			newFirstVisibleIndex = 0;
		} else if (newFirstVisibleIndex > maxIndex) {
			newFirstVisibleIndex = maxIndex;
		}
		_firstVisibleIndex[filterType] = newFirstVisibleIndex;
		
		var filterWidth  = _configuration.FILTER_WIDTH[filterType];
		var marginLeft   =  -filterWidth * newFirstVisibleIndex;
		if (isPagingRequired) {
			marginLeft += _configuration.FILTER_PANEL_ARROW_WIDTH;
		}

		if (skipAnimation) {
			filtersDiv.css('margin-left', marginLeft +'px');
		} else {
			filtersDiv.stop().animate({
				'margin-left':  marginLeft
			},{
				'duration':     200,
				'easing':       'easeOutQuad'
			});
		}

		_updateFilterCarouselPagingVisibility(filterType);
	};




	var _updateFilterCarouselPagingVisibility = function (filterType) {
		var filtersContainerDiv        = $('#product-filter-panel-'+ filterType);
		var filtersPagingContainerDiv  = $('#filters-carousel-paging-'+ filterType);
		var availableWidth             = $(window).width() - (2 * _configuration.FILTER_PANEL_ARROW_WIDTH);
		var isPagingRequired           = parseInt(filtersContainerDiv.find('.filters').css('width').replace('px', '')) > availableWidth;

		var nextDiv                    = filtersPagingContainerDiv.children('.next');
		var nextDisabledDiv            = filtersPagingContainerDiv.children('.next-disabled');
		var previousDiv                = filtersPagingContainerDiv.children('.previous');
		var previousDisabledDiv        = filtersPagingContainerDiv.children('.previous-disabled');
		var firstVisibleIndex          = _firstVisibleIndex[filterType];
		var visibleCount               = Math.floor(availableWidth / _configuration.FILTER_WIDTH[filterType]);
		var maxIndex                   = filtersContainerDiv.find('.filters').children('.filter').length - visibleCount;

		if (isPagingRequired) {
			var nextEnabled      = firstVisibleIndex < maxIndex;
			var previousEnabled  = firstVisibleIndex > 0;

			if (nextEnabled) {
				nextDiv.show();
				nextDisabledDiv.hide();
			} else {
				nextDiv.hide();
				nextDisabledDiv.show();
			}
			
			if (previousEnabled) {
				previousDiv.show();
				previousDisabledDiv.hide();
			} else {
				previousDiv.hide();
				previousDisabledDiv.show();
			}

			filtersPagingContainerDiv.show();
		} else {
			filtersPagingContainerDiv.hide();
		}
	};




	var _setInitialFilterCarouselWidths = function () {
		var types                     = ['style', 'color', 'collection'];
		var tempFiltersContainer      = null;
		var tempFiltersTotalWidth     = 0;
		
		for (var i=0; i<types.length; i++) {
			tempFiltersTotalWidth  = 0;
			tempFiltersContainer   = $('#filters-'+ types[i]);

			tempFiltersContainer.children('.filter').each(function () {
				tempFiltersTotalWidth += parseInt($(this).css('width'));
			});

			tempFiltersContainer.css('width', tempFiltersTotalWidth +'px');
		}
	};
	
	
	
	
	var _resizeProductGrid = function () {
		var availableWidth    = $(window).width();
		var cellsPerRow       = Math.floor(availableWidth / _configuration.GRID_CELL_WIDTH);
		var cellWidth         = Math.floor(availableWidth / cellsPerRow);
		var remainderWidth    = availableWidth - (cellsPerRow * cellWidth);
		var cellCount         = 0;
		
		$('#product-grid').find('.cell').each(function () {
			cellCount++;
			if (cellCount % cellsPerRow != 0) {
				$(this).width(cellWidth);
			} else {
				$(this).width(cellWidth + remainderWidth);
			}
		});
	};




	var _onWindowResize = function () {
		_resizeFilterCarousel('style');
		_resizeFilterCarousel('color');
		_resizeFilterCarousel('collection');
		_resizeProductGrid();
	};




	var _setFilterPanelDropdownOpen = function (open) {
		if (open == _dropdownOpen) { return; } _dropdownOpen = open;
		
		var dropdownDiv = $('#product-grid-header').children('.dropdown-box');
		
		if (open) {
			dropdownDiv.show();
		} else {
			dropdownDiv.hide();
		}
	};
	
	
	
	
	var _onProductColorClick = function (productColorAnchor) {
		var productImageDiv   = productColorAnchor.parent().parent().parent().parent().children('.product-image');
		var productColorDivs  = productColorAnchor.parent().parent();
		var productImageTag   = productImageDiv.find('img');
		var colorAssetId      = productColorAnchor.attr('rel');

		productColorDivs.children('.product-color').children('a').removeClass('selected');
		productColorAnchor.addClass('selected');
		productImageTag.attr('src', _assetIdToAssetUrl(colorAssetId, '_grid'));
	};




	return {
		initialize:function (configuration) {
			_configuration = $.extend(_configuration, configuration);
			
			$('#site').css('position', 'absolute');
			
			$('#product-grid').find('.product-color').children('a').bind('click', function () {
				_onProductColorClick($(this));
			});
			
			$('#product-grid-header').find('.filter').children('a').bind('click', function () {
				if (_loading) { return; }
				_openFilterPanel($(this).parent().attr('rel'));
			});
			
			$('#product-grid-header').find('.group-right').children('.filter').children('a').bind('click', function () {
				if (_loading) { return; }
				_setFilterPanelDropdownOpen(true);
			});

			$('#product-grid-header').find('.dropdown-box').find('.close-button').children('a').bind('click', function () {
				if (_loading) { return; }
				_setFilterPanelDropdownOpen(false);
			});
			
			$('#product-grid-header').find('.dropdown-box').find('.filter').children('a').bind('click', function () {
				if (_loading) { return; }
				_reorderProductSearch($(this));
			});

			$('.product-filter-panel').find('.close-button').children('a').bind('click', function () {
				_closeFilterPanels();
			});

			$('.product-filter-panel').find('.filter').bind('click', function () {
				if (_loading) { return; }
				_toggleFilter($(this));
			});
			
			$('#product-filter-panel-color-all').bind('click', function () {
				if (_loading) { return; }
				_toggleAllFilters('color', true);
			});

			$('#product-filter-panel-color-none').bind('click', function () {
				if (_loading) { return; }
				_toggleAllFilters('color', false);
			});
			
			$('#product-filter-panel-style-all').bind('click', function () {
				if (_loading) { return; }
				_toggleAllFilters('style', true);
			});
			
			$('#product-filter-panel-style-none').bind('click', function () {
				if (_loading) { return; }
				_toggleAllFilters('style', false);
			});
			
			$('#product-filter-panel-collection-all').bind('click', function () {
				if (_loading) { return; }
				_toggleAllFilters('collection', true);				
			});

			$('#product-filter-panel-collection-none').bind('click', function () {
				if (_loading) { return; }
				_toggleAllFilters('collection', false);
			});
			
			$('#filters-carousel-paging-collection').children('.previous').bind('click', function () {
				_pageFiltersCarousel('collection', 'previous');
			});
			
			$('#filters-carousel-paging-collection').children('.next').bind('click', function () {
				_pageFiltersCarousel('collection', 'next');
			});
			
			$('#filters-carousel-paging-style').children('.previous').bind('click', function () {
				_pageFiltersCarousel('style', 'previous');
			});
			
			$('#filters-carousel-paging-style').children('.next').bind('click', function () {
				_pageFiltersCarousel('style', 'next');
			});
			
			$('#filters-carousel-paging-color').children('.previous').bind('click', function () {
				_pageFiltersCarousel('color', 'previous');
			});
			
			$('#filters-carousel-paging-color').children('.next').bind('click', function () {
				_pageFiltersCarousel('color', 'next');
			});

			_setInitialFilterCarouselWidths();
			_selectInitialFilters();
			
			$(window).resize(function () {
				_onWindowResize();
			});
			_onWindowResize();
		},
		openFilter:function (filter) {
			_openFilter(filter);
		}
	};
}();
// END: _productGrid
//-----------------------------------------------------------------------------


//-----------------------------------------------------------------------------
// START: _header
	var _header = function () {
		var _closeNavTimeout = 0;
		
		
		
		
		var _setHeaderNavOpen = function (isOpen) {
			var headerNavDiv    = $('#header').children('.nav');
			var marginTop       = isOpen ? 0 : -75;

			headerNavDiv.animate({
				'margin-top':   marginTop
			},{
				'duration':     200,
				'easing':       'easeOutQuad'
			});
		};




		return {
			initialize:function () {
				$('#header').children('.nav').bind('mouseenter', function () {
					clearTimeout(_closeNavTimeout);
					_setHeaderNavOpen(true);
				});

				$('#header').children('.nav').bind('mouseleave', function () {
					clearTimeout(_closeNavTimeout);
					_closeNavTimeout = setTimeout(function () { _setHeaderNavOpen(false); }, 300);
				});
			}
		}
	}();
// END: _header
//-----------------------------------------------------------------------------


//-----------------------------------------------------------------------------
// START: _scenery
var _scenery = function () {
	var _initialized                   = false;
	var _sceneryDiv                    = null;
	var _sceneryPagingHoverDiv         = null;
	var _sceneryNativeDimensions       = null;
	var _currentScene                  = null;
	var _onWindowResizeActualInterval  = 0;
	var _snapToSceneTimeout            = 0;
	var _closeHotspotsTimeout          = 0;




	var _configuration = {
		HOTSPOT_BUBBLE_HEIGHT:              149,
		PAGING_DOT_HEIGHT_PLUS_MARGIN:      29
	};




	var _parseNativeDimensions = function (div) {
		var relTokens               = div.attr('rel').split('|');
		var nativeDimensions        = relTokens[0];
		var nativeDimensionTokens   = nativeDimensions.split('x');

		var nativeDimensions              = [];
		nativeDimensions['width']         = nativeDimensionTokens[0];
		nativeDimensions['height']        = nativeDimensionTokens[1];
		nativeDimensions['aspect_ratio']  = nativeDimensions['width'] / nativeDimensions['height'];
		nativeDimensions['orientation']   = nativeDimensions['aspect_ratio'] > 1 ? 'landscape' : 'portrait';

		return nativeDimensions;
	};
	
	
	
	
	var _parseParallaxConfiguration = function (div) {
		var relTokens               = div.attr('rel').split('|');
		var nativeMarginTop         = parseInt(relTokens[1]);
		var parallaxFactor          = 0;

		if (div.hasClass('tagline')) {
			parallaxFactor = 200;
		} else if (div.hasClass('info-box-right') || div.hasClass('info-box-left')) {
			parallaxFactor = 400;
		} else if (div.hasClass('logo')) {
			parallaxFactor = 800;
		} else if (div.hasClass('background')) {
			parallaxFactor = 0;
		} else {
			parallaxFactor = 50;
		}
		
		var parallaxConfiguration                        = [];
		parallaxConfiguration['native_margin_top']       = nativeMarginTop;
		parallaxConfiguration['vertical_center_offset']  = 0;
		parallaxConfiguration['parallax_factor']         = parallaxFactor;

		return parallaxConfiguration;
	};




	var _calculateMarginLeft = function (div, width) {
		var marginLeft = -width / 2;
		
		if (div.hasClass('model-left')) {
			marginLeft -= width * .68;
		} else if (div.hasClass('model-right')) {
			marginLeft += width * .48;
		}

		return marginLeft;
	};
	
	
	
	
	var _onWindowResize = function () {
		_onWindowResizeActual();
		
		// perform a second call because scrollbar rendering as a
		// result of the first call to resize "actual" will not be
		// accounted for in the first call
		clearTimeout(_onWindowResizeActualInterval);
		_onWindowResizeActualInterval = setTimeout(_onWindowResizeActual, 50);
	};




	var _onWindowResizeActual = function () {
		_sceneryDiv.find('.scene').each(function () {
			var thisDiv                = $(this);
			var targetDimensions       = _getWindowDimensions();
			var targetWidth            = targetDimensions['width'];
			var targetHeight           = targetDimensions['height'];
			
			thisDiv.css('width', targetWidth);
			thisDiv.css('height', targetHeight);
		});

		_sceneryDiv.find('.scale').each(function () {
			var thisDiv                = $(this);
			var targetDimensions       = _getWindowDimensions();
			var targetWidth            = targetDimensions['width'];
			var targetHeight           = targetDimensions['height'];
			var targetAspectRatio      = targetDimensions['aspect_ratio'];		
			var scalePercentage        = targetWidth / _sceneryNativeDimensions['width'];

			var thisNativeDimensions   = _parseNativeDimensions(thisDiv);
			var thisNewWidth           = scalePercentage * thisNativeDimensions['width'];
			var thisNewHeight          = thisNewWidth / thisNativeDimensions['aspect_ratio'];
			var thisNewMarginLeft      = _calculateMarginLeft(thisDiv, thisNewWidth);
		
			if (thisNewHeight < targetHeight) {
				scalePercentage        = targetHeight / _sceneryNativeDimensions['height'];
				thisNewHeight          = scalePercentage * thisNativeDimensions['height'];
				thisNewWidth           = thisNewHeight * thisNativeDimensions['aspect_ratio'];
				thisNewMarginLeft      = _calculateMarginLeft(thisDiv, thisNewWidth);
			}
		
			thisDiv.css('width', thisNewWidth).css('margin-left', thisNewMarginLeft);
			thisDiv.css('height', thisNewHeight);
			
			thisDiv.find('.hotspot').each(function () {
				var thisDiv      = $(this);
				var relTokens    = thisDiv.attr('rel').split('x');
				var nativeTop    = relTokens[1];
				var nativeLeft   = relTokens[0];

				var newTop       = scalePercentage * nativeTop;
				var newLeft      = scalePercentage * nativeLeft;
				
				thisDiv.css('top', newTop);
				thisDiv.css('left', newLeft);
			});
		});
		
		_onWindowScroll();
	};
	
	
	
	
	var _onWindowScroll = function () {
		if (!_initialized) { return; }
		
		var targetDimensions       = _getWindowDimensions();
		var targetWidth            = targetDimensions['width'];
		var targetHeight           = targetDimensions['height'];
		var targetAspectRatio      = targetDimensions['aspect_ratio'];
		var scrollTop              = $(window).scrollTop();

		$('.scene').each(function () {
			var thisDiv                 = $(this);
			var scrollTopDistance       = thisDiv.offset().top - scrollTop;
			var isOnScreen              = Math.abs(scrollTopDistance) < thisDiv.height();
			var percentageScrolledAway  = scrollTopDistance / thisDiv.height();
			var isCurrentScene          = Math.abs(Math.round(percentageScrolledAway)) == 0;

			if (isCurrentScene) {
				_setCurrentScene(thisDiv.attr('id').replace('scene-', ''), false, true, true);
			}

			if (isOnScreen) {
				thisDiv.children('.scene-element').each(function () {
					var thisElement                 = $(this);
					var thisParallaxConfiguration   = _parseParallaxConfiguration(thisElement);
					var parallaxOffset              = Math.ceil(percentageScrolledAway * thisParallaxConfiguration['parallax_factor']);
					var marginTop                   = parallaxOffset + thisParallaxConfiguration['native_margin_top'];

					if (!thisElement.hasClass('background')) {
						thisElement.css('margin-top', marginTop +'px');
					}
				});
			}
		});
		
		// timeout duration based on width is due to performance issues on
		// larger sized screens - this is a semi-hack
		var timeoutDuration = targetWidth < 1700 ? 100 : 170;
		clearTimeout(_snapToSceneTimeout);
		_snapToSceneTimeout = setTimeout(function () { _snapToScene(); }, timeoutDuration);
		
		_actualCloseHotspots(true, true);
		
		_hideDotHovers();
	};
	
	
	
	
	var _snapToScene = function () {
		// @JR - "snapping" effect removed for now
		// _actualCloseHotspots(true, true);
		// _setCurrentScene(_currentScene, true, false, true);
	};




	var _setCurrentScene = function (scene, skipCheck, skipAnimation, setDotSelected) {
		if (scene == _currentScene && !skipCheck) { return; } _currentScene = scene;

		if (!skipAnimation) {
			var scrollTop = $('#scene-'+ _currentScene).offset().top;

			if (_footer.isOpen()) {
				scrollTop += _footer.measuredHeight();
			}
			
			$('html, body').stop().animate({
				'scrollTop':   scrollTop
			},{
				'duration':    300,
				'easing':      'easeOutQuad'
			});
		}
		
		if (setDotSelected) {
			var pagingDiv = $('#scenery-paging');
			pagingDiv.children('.dot').removeClass('dot-selected');
			pagingDiv.children('#dot-'+ _currentScene).addClass('dot-selected');
		}
	};
	
	
	
	
	var _openHotspot = function (collectionSlug) {
		clearTimeout(_closeHotspotsTimeout);
		
		var hotspotDiv    = $('#hotspot-'+ collectionSlug);
		var bubbleDiv     = $('#hotspot-bubble-'+ collectionSlug);
		var sceneIndex    = $('#scene-'+ collectionSlug).index();

		var bubbleTop = hotspotDiv.offset().top;
		if (_footer.isOpen()) {
			bubbleTop += _footer.measuredHeight();
		}
		
		var bubbleBottom  = ($(window).height() - bubbleTop) + (sceneIndex * $(window).height());
		var bubbleLeft    = hotspotDiv.offset().left + 5;

		bubbleDiv.css('bottom', bubbleBottom);
		bubbleDiv.css('left', bubbleLeft);
		bubbleDiv.stop().animate({
			'height':    _configuration.HOTSPOT_BUBBLE_HEIGHT
		},{
			'duration':  100,
			'easing':    'easeOutQuad'
		})
	};
	
	
	
	
	var _closeHotspots = function (immediate, skipAnimation) {
		if (immediate) {
			_actualCloseHostpots(skipAnimation);
		} else {
			clearTimeout(_closeHotspotsTimeout);
			_closeHotspotsTimeout = setTimeout(function () { _actualCloseHotspots(skipAnimation); }, 500);
		}
	};
	
	
	
	
	var _actualCloseHotspots = function (skipAnimation) {
		if (skipAnimation) {
			$('.hotspot-bubble').css('height', 0);
		} else {
			$('.hotspot-bubble').animate({
				'height':    0
			},{
				'duration':  100,
				'easing':    'easeOutQuad'
			});
		}
	};
	
	
	
	
	var _showDotHover = function (dotAnchor) {
		var dotsTop     = $('#scenery-paging').offset().top;
		var bubbleText  = dotAnchor.attr('title');
		var bubbleTop   = dotsTop + (dotAnchor.parent().index() * _configuration.PAGING_DOT_HEIGHT_PLUS_MARGIN) - 5;
		
		if (_footer.isOpen()) {
			bubbleTop += _footer.measuredHeight();
		}

		_sceneryPagingHoverDiv.children('.text').html(bubbleText);
		_sceneryPagingHoverDiv.css('top', bubbleTop);
		_sceneryPagingHoverDiv.show();
	};
	
	
	
	
	var _hideDotHovers = function () {
		_sceneryPagingHoverDiv.hide();
	};




	var _initialize = function (divId) {
		_initialized = true;
		
		_sceneryDiv               = $('#'+ divId);
		_sceneryPagingHoverDiv    = $('#scenery-paging-hover-bubble');
		_sceneryNativeDimensions  = _parseNativeDimensions(_sceneryDiv);

		$(window).resize(function () {
			_onWindowResize();
		});
		
		$(window).scroll(function () {
			_onWindowScroll();
		});
		
		$('#scenery-paging').children('.dot').children('a').bind('click', function () {
			_setCurrentScene($(this).attr('rel'), true);
		});

		$('#scenery-paging').children('.dot').children('a').bind('mouseenter', function () {
			_showDotHover($(this));
		});

		$('#scenery-paging').children('.dot').children('a').bind('mouseleave', function () {
			_hideDotHovers();
		});

		$('.hotspot').bind('mouseenter', function () {
			_openHotspot($(this).attr('id').replace('hotspot-', ''));
		});

		$('.hotspot').bind('mouseleave', function () {
			_closeHotspots();
		});
		
		$('.hotspot-bubble').bind('mouseenter', function () {
			clearTimeout(_closeHotspotsTimeout);
		});
		
		$('.hotspot-bubble').bind('mouseleave', function () {
			clearTimeout(_closeHotspotsTimeout);
			_closeHotspotsTimeout = setTimeout(function () { _actualCloseHotspots(); }, 500);
		});

		_onWindowResize();
	};




	return {
		initialize:function (divId) {
			_initialize(divId);
		},
		onWindowScroll:function () {
			_onWindowScroll();
		}
	};
}();
// END: _scenery
//-----------------------------------------------------------------------------


//-----------------------------------------------------------------------------
// START: _footer
var _footer = function () {
	var _configuration = {
		FOOTER_HEIGHT:                      190,
		FOOTER_NETWORKING_BOTTOM_OPEN:      150,
		FOOTER_NETWORKING_BOTTOM_DEFAULT:   10,
		FOOTER_PERCENT_WIDTH_BRAND:         .20,
		FOOTER_MIN_WIDTH_BRAND:             245,
		FOOTER_MAX_WIDTH_BRAND:             285,
		FOOTER_PERCENT_WIDTH_UPDATES:       .15,
		FOOTER_MIN_WIDTH_UPDATES:           175,
		FOOTER_MAX_WIDTH_UPDATES:           400,
		FOOTER_PERCENT_WIDTH_CONNECT:       .30,
		FOOTER_MIN_WIDTH_CONNECT:           267,
		FOOTER_MAX_WIDTH_CONNECT:           355,
		FOOTER_CAINKADE_LOGO_WIDTH:         44
	};




	var _open                         = false;
	var _setFooterOpenActualInterval  = 0;
	var _fadeOutNewsletterTimeout     = 0;




	var _initialize = function () {
		$(window).scroll(function () {
			_onWindowScroll();
		});
		_onWindowScroll();

		$(window).resize(function () {
			_onWindowResize();
		});
		_onWindowResize();
		
		$('#footer-newsletter-name').bind('focusin', function () {
			var thisDiv = $(this);
			if (thisDiv.val() == 'Name') {
				thisDiv.val('');
			}
		});

		$('#footer-newsletter-name').bind('focusout', function () {
			var thisDiv = $(this);
			if (thisDiv.val() == '') {
				thisDiv.val('Name');
			}
		});

		$('#footer-newsletter-email').bind('focusin', function () {
			var thisDiv = $(this);
			if (thisDiv.val() == 'Email Address') {
				thisDiv.val('');
			}
		});

		$('#footer-newsletter-email').bind('focusout', function () {
			var thisDiv = $(this);
			if (thisDiv.val() == '') {
				thisDiv.val('Email Address');
			}
		});
		
		$('#footer-newsletter-submit').bind('click', function () {
			_submitNewsletter();
		});
		
		$('#footer-networking').find('a').bind('mouseenter', function () {
			var thisAnchor       = $(this);
			var hoverBubbleDiv   = $('#footer-networking').children('.hover-bubble');
			var hoverBubbleLeft  = (thisAnchor.parent().index() * 40);
			var hoverBubbleText  = thisAnchor.attr('rel');
			
			var index = thisAnchor.parent().index();
			if (index == 3) {
				hoverBubbleDiv.addClass('hover-bubble-right');
			} else {
				hoverBubbleDiv.removeClass('hover-bubble-right');
			}

			hoverBubbleDiv.html(hoverBubbleText).css('left', hoverBubbleLeft);
			hoverBubbleDiv.show();
		});
		
		$('#footer-networking').find('a').bind('mouseleave', function () {
			var hoverBubbleDiv = $('#footer-networking').children('.hover-bubble');
			hoverBubbleDiv.hide();
		});
	};
	
	
	
	
	var _onWindowScroll = function () {
		var scrollBottomPosition  = $(window).scrollTop() + $(window).height();
		var documentHeight        = $(document).height();
		var isScrolledToBottom    = documentHeight - scrollBottomPosition <= 0;
		
		_setFooterOpen(isScrolledToBottom);
	};




	var _onWindowResize = function () {
		var footerDiv         = $('#footer');
		var windowDimensions  = _getWindowDimensions();
		var targetWidth       = windowDimensions['width'];
		
		footerDiv.width(targetWidth);

		if (targetWidth <= 1024) {
			$('#footer-networking').css('right', 'auto');
			$('#footer-networking').css('left', '840px');
		} else {
			$('#footer-networking').css('right', '25px');
			$('#footer-networking').css('left', 'auto');
		}
		
		var columnWidthBrand = targetWidth * _configuration.FOOTER_PERCENT_WIDTH_BRAND;
		if (columnWidthBrand < _configuration.FOOTER_MIN_WIDTH_BRAND) {
			columnWidthBrand = _configuration.FOOTER_MIN_WIDTH_BRAND;
		} else if (columnWidthBrand > _configuration.FOOTER_MAX_WIDTH_BRAND) {
			columnWidthBrand = _configuration.FOOTER_MAX_WIDTH_BRAND;
		}
		
		var columnWidthUpdates = targetWidth * _configuration.FOOTER_PERCENT_WIDTH_UPDATES;
		if (columnWidthUpdates < _configuration.FOOTER_MIN_WIDTH_UPDATES) {
			columnWidthUpdates = _configuration.FOOTER_MIN_WIDTH_UPDATES;
		} else if (columnWidthUpdates > _configuration.FOOTER_MAX_WIDTH_UPDATES) {
			columnWidthUpdates = _configuration.FOOTER_MAX_WIDTH_UPDATES;
		}
		
		var columnWidthConnect = targetWidth * _configuration.FOOTER_PERCENT_WIDTH_CONNECT;
		if (columnWidthConnect < _configuration.FOOTER_MIN_WIDTH_CONNECT) {
			columnWidthConnect = _configuration.FOOTER_MIN_WIDTH_CONNECT;
		} else if (columnWidthConnect > _configuration.FOOTER_MAX_WIDTH_CONNECT) {
			columnWidthConnect = _configuration.FOOTER_MAX_WIDTH_CONNECT;
		}
		
		if (columnWidthConnect <= 350) {
			columnWidthConnect = _configuration.FOOTER_MIN_WIDTH_CONNECT;

			footerDiv.find('.column-connect').find('.cta').css('width', '155px');
			footerDiv.find('.column-connect').find('.cta-sub').css('width', '155px');
			footerDiv.find('.column-connect').find('.grey-box-button').css('left', '195px');
		} else {
			footerDiv.find('.column-connect').find('.cta').css('width', '100%');
			footerDiv.find('.column-connect').find('.cta-sub').css('width', '100%');
			footerDiv.find('.column-connect').find('.grey-box-button').css('left', '108px');
		}

		footerDiv.find('.column-brand').css('width', columnWidthBrand);
		footerDiv.find('.column-updates').css('width', columnWidthUpdates);
		footerDiv.find('.column-connect').css('width', columnWidthConnect);
	};




	var _setFooterOpen = function (open) {
		if (open == _open) { return; } _open = open;

		var height            = _open ? _configuration.FOOTER_HEIGHT : 0;
		var marginTop         = _open ? -_configuration.FOOTER_HEIGHT : 0;
		var networkingBottom  = _open ? _configuration.FOOTER_NETWORKING_BOTTOM_OPEN : _configuration.FOOTER_NETWORKING_BOTTOM_DEFAULT;

		if (_open) {
			$('#footer-padding').hide();
		} else {
			$('#footer-padding').show();
		}

		$('#footer').stop().animate({
			'height':    height
		},{
			'duration':  200,
			'easing':    'easeOutQuad'
		});

		$('#footer-networking').stop().animate({
			'bottom':    networkingBottom
		},{
			'duration':  200,
			'easing':    'easeOutQuad'
		});

		$('#site').stop().animate({
			'margin-top':    marginTop
		},{
			'duration':     200,
			'step':         function () { _scenery.onWindowScroll(); },
			'complete':     function () { _scenery.onWindowScroll(); },
			'easing':       'easeOutQuad'
		});
	};
	
	
	
	
	var _submitNewsletter = function () {
		var name = $('#footer-newsletter-name').val();
		if (name == 'Name') {
			name = '';
		}

		var email = $('#footer-newsletter-email').val();
		if (email == 'Email Address') {
			email = '';
		}

		clearTimeout(_fadeOutNewsletterTimeout);
		$('#footer-newsletter-error').hide();
		$('#footer-newsletter-success').hide();
		
		if (name == '' || email == '') {
			$('#footer-newsletter-error').show();
			return;
		}

		$.ajax({
			'url':      '/api/create/newsletter-subscription',
			'type':     'POST',
			'data':     'name='+ encodeURIComponent(name) +'&email='+ encodeURIComponent(email),
			'success':  function (response) { _submitNewsletterCallback(response); },
			'error':    function (response) { _submitNewsletterCallback(false); }
		});
	};




	var _submitNewsletterCallback = function (response) {
		if (response === false || response['success'] === false) {
			$('#footer-newsletter-error').show();
			return;
		}

		$('#footer-newsletter-success').show();
		$('#footer-newsletter-name').val('Name');
		$('#footer-newsletter-email').val('Email Address');

		clearTimeout(_fadeOutNewsletterTimeout);
		_fadeOutNewsletterTimeout = setTimeout(function () { $('#footer-newsletter-success').fadeOut('fast'); }, 1500);
	};




	return {
		initialize:function () {
			_initialize();
		},
		isOpen:function () {
			return _open;
		},
		measuredHeight:function () {
			return _configuration.FOOTER_HEIGHT;
		}
	}
}();
// END: _footer
//-----------------------------------------------------------------------------


//-----------------------------------------------------------------------------
// START: _lookbookIndex
var _lookbookIndex = function () {
	var _configuration = {
		NATIVE_WIDTH:               1024,
		NATIVE_HEIGHT:              600,
		BOX_NATIVE_WIDTH:           270,
		BOX_NATIVE_HEIGHT:          363,
		BOX_MIN_WIDTH:              270,
		BOX_MARGIN_RIGHT:           10,
		BOX_CONTAINER_LEFT:         155,
		BOX_CONTAINER_RIGHT:        30,
		
		BOX_TITLE_BASE_FONT_SIZE:   35,
		BOX_TITLE_FONT_SIZE_INC:    35,

		BOX_QUOTE_BASE_FONT_SIZE:   15,
		BOX_QUOTE_FONT_SIZE_INC:    19,
		BOX_QUOTE_PADDING_INC:      5,
		
		BOX_CREDIT_BASE_FONT_SIZE:  10,
		BOX_CREDIT_FONT_SIZE_INC:   2,

		BOX_DESC_BASE_FONT_SIZE:    12,
		BOX_DESC_FONT_SIZE_INC:     8
	};




	var _lookbookIndexDiv     = null;
	var _backgroundDiv        = null;
	var _boxContainerDiv      = null;




	var _onWindowResize = function () {
		_resizeBackground();
		_resizeBoxes();
	};
	
	
	
	
	var _resizeBackground = function () {
		var targetDimensions       = _getWindowDimensions();
		var nativeWidth            = _configuration.NATIVE_WIDTH;
		var nativeHeight           = _configuration.NATIVE_HEIGHT;
		var nativeAspectRatio      = nativeWidth / nativeHeight;

		var thisNewWidth           = targetDimensions['width'];
		var thisNewHeight          = thisNewWidth / nativeAspectRatio;
		var thisNewMarginLeft      = -(thisNewWidth / 2);

		if (thisNewHeight < targetDimensions['height']) {
			thisNewHeight          = targetDimensions['height'];
			thisNewWidth           = thisNewHeight * nativeAspectRatio;
			thisNewMarginLeft      = -(thisNewWidth / 2);
		}

		_backgroundDiv.css('margin-left', thisNewMarginLeft);
		_backgroundDiv.children('img').css('width', thisNewWidth)
		_backgroundDiv.children('img').css('height', thisNewHeight);
	};
	
	
	
	
	var _resizeBoxes = function () {
		var targetDimensions   = _getWindowDimensions();
		var targetWidth        = targetDimensions['width'];
		var targetHeight       = targetDimensions['height'];
		
		var boxContainerWidth  = targetWidth - (_configuration.BOX_CONTAINER_LEFT + _configuration.BOX_CONTAINER_RIGHT) - (2 * _configuration.BOX_MARGIN_RIGHT);
		var boxAspectRatio     = _configuration.BOX_NATIVE_WIDTH / _configuration.BOX_NATIVE_HEIGHT;

		var boxWidth = Math.floor(boxContainerWidth / 3);
		if (boxWidth < _configuration.BOX_MIN_WIDTH) {
			boxWidth = _configuration.BOX_MIN_WIDTH;
		}

		var boxHeight            = boxWidth / boxAspectRatio;
		var scalePercentage      = (boxWidth / _configuration.BOX_NATIVE_WIDTH);
		var fontScalePercentage  = scalePercentage - 1;

		var boxDivs = _boxContainerDiv.children('.box');
		boxDivs.css('width', boxWidth);
		boxDivs.css('height', boxHeight);
		
		var boxBackgroundDivs = boxDivs.children('.background');
		boxBackgroundDivs.css('width', boxWidth);
		boxBackgroundDivs.css('height', boxHeight);
		
		var titleFontSize = _configuration.BOX_TITLE_BASE_FONT_SIZE + Math.floor(fontScalePercentage * _configuration.BOX_TITLE_FONT_SIZE_INC);
		boxDivs.find('.title').css('font-size', titleFontSize +'px');
		
		var quoteFontSize  = _configuration.BOX_QUOTE_BASE_FONT_SIZE + Math.floor(fontScalePercentage * _configuration.BOX_QUOTE_FONT_SIZE_INC);
		var quotePadding   = _configuration.BOX_QUOTE_PADDING_INC + Math.floor(fontScalePercentage * _configuration.BOX_QUOTE_PADDING_INC);
		boxDivs.find('.quote').css('font-size', quoteFontSize +'px');
		boxDivs.find('.quote').css('line-height', (quoteFontSize + 1) +'px');
		boxDivs.find('.quote').css('padding', quotePadding +'px 0 '+ quotePadding +'px 0');
		
		var quoteCreditFontSize = _configuration.BOX_CREDIT_BASE_FONT_SIZE + Math.floor(fontScalePercentage * _configuration.BOX_CREDIT_FONT_SIZE_INC);
		boxDivs.find('.quote-credit').css('font-size', quoteCreditFontSize +'px');
		
		var descFontSize = _configuration.BOX_DESC_BASE_FONT_SIZE + Math.floor(fontScalePercentage * _configuration.BOX_DESC_FONT_SIZE_INC);
		boxDivs.find('.description').css('font-size', descFontSize +'px');
		boxDivs.find('.description').css('line-height', (descFontSize + 3) +'px');
		
		var logoImages = boxDivs.find('.logo').children('img');
		logoImages.height(boxDivs.find('.title').css('height'));
		
		var ruleImage = boxDivs.find('.rule').children('img');
		ruleImage.width(boxWidth - 54);
		ruleImage.height(3);
		
		_scaleClothesDiv('elementary', scalePercentage);
		_scaleClothesDiv('play', scalePercentage);
		_scaleClothesDiv('atelier', scalePercentage);
	};
	
	
	
	
	var _scaleClothesDiv = function (collection, percentage) {
		var boxDiv         = $('.box-'+ collection);
		var clothesImage   = boxDiv.find('.clothes').children('img');

		var clothesDimensions   = clothesImage.attr('rel').split('x');
		var clothesWidth        = clothesDimensions[0];
		var clothesHeight       = clothesDimensions[1];
		var clothesAspectRatio  = clothesWidth / clothesHeight;

		var newWidth   = Math.floor(percentage * (clothesWidth - 10));
		var newHeight  = newWidth / clothesAspectRatio;

		clothesImage.css('width', newWidth);
	};




	var _initialize = function () {
		_lookbookIndexDiv  = $('#lookbook-index');
		_backgroundDiv     = _lookbookIndexDiv.children('.background');
		_boxContainerDiv   = _lookbookIndexDiv.children('.box-container');

		_onWindowResize();
		$(window).resize(function () {
			_onWindowResize();
		});
	};




	return {
		initialize:function () {
			_initialize();
		}
	};
}();
// END: _lookbookIndex
//-----------------------------------------------------------------------------


//-----------------------------------------------------------------------------
// START: _modals
var _modals = function () {
	var _initialize = function () {
		$('#modals').find('.curtain').bind('click', function () {
			_closeAll();
		});
		
		$('#footer-networking-about-link').bind('click', function () {
			_openModal('who-we-are');
		});
		
		$('#footer-who-we-are-link').bind('click', function () {
			_openModal('who-we-are');
		});
		
		$('#footer-privacy-policy-link').bind('click', function () {
			_openModal('privacy-policy');
		});
		
		$('#product-detail-panel').find('.size-guide').children('a').bind('click', function () {
			_openModal('size-guide');
		});

		$('#modal-who-we-are').find('.close-button').children('a').bind('click', function () {
			_closeAll();
		});

		$('#modal-privacy-policy').find('.close-button').children('a').bind('click', function () {
			_closeAll();
		});
		
		$('#modal-size-guide').find('.close-button').children('a').bind('click', function () {
			_closeAll();
		});

		$('#modal-video').find('.close-button').children('a').bind('click', function () {
			_closeAll();
		});
	};




	var _openModal = function (modal) {
		$('.modal').hide();
		$('#modal-'+ modal).show();
		$('#modals').fadeIn(200);
	};




	var _closeAll = function () {
		$('#modals').fadeOut(200);
	};




	return {
		initialize:function () {
			_initialize();
		}
	};
}();
// END: _modals
//-----------------------------------------------------------------------------


//-----------------------------------------------------------------------------
// START: _scrollerInstance
var _scrollerInstance = function () {
	var _configuration = {
		SCROLLER_ARROW_HEIGHT:    18,
		SCROLLER_CLICK_DISTANCE:  18
	};




	var _create = function (scrollerDivId, scrollerContentDivId) {
		var _scrollerDiv                = $('#'+ scrollerDivId);
		var _scrollerContentDiv         = $('#'+ scrollerContentDivId);
		var _scrollerContentHeight      = parseInt(_scrollerContentDiv.css('height').replace('px'));
		var _scrollerContentMaskHeight  = _scrollerContentDiv.parent().height();

		var _gutterDiv            = _scrollerDiv.find('.gutter');
		var _headDiv              = _scrollerDiv.find('.head');
		var _upButtonDiv          = _scrollerDiv.find('.up-button');
		var _downButtonDiv        = _scrollerDiv.find('.down-button');
		
		var _scrollPercentage     = 0;




		// define functions
		var _resizeScroller = function () {
			var scrollerHeight           = parseInt(_scrollerDiv.css('height').replace('px'));
			var remainingScrollerHeight  = scrollerHeight - (2 * _configuration.SCROLLER_ARROW_HEIGHT);

			_gutterDiv.css('height', remainingScrollerHeight);
		};




		var _clickScroll = function (direction) {
			var maxRelativeY = _gutterDiv.height() - _headDiv.height();

			var headTop  = parseInt(_headDiv.css('top').replace('px', ''));
			headTop     += direction == 'down' ? _configuration.SCROLLER_CLICK_DISTANCE : -_configuration.SCROLLER_CLICK_DISTANCE;
			
			if (headTop < 0) {
				headTop = 0;
			} else if (headTop > maxRelativeY) {
				headTop = maxRelativeY;
			}
			
			_scrollPercentage = headTop / maxRelativeY;

			var contentTop = -_scrollPercentage * (_scrollerContentMaskHeight - _scrollerContentHeight);
			_headDiv.css('top', headTop);
			_scrollerContentDiv.css('top', contentTop);
		};




		var _startScrolling = function () {
			$(document).bind('mousemove', _scrolling);
			$(document).bind('mouseup', _stopScrolling);
		};
		
		
		
		
		var _stopScrolling = function () {
			$(document).unbind('mousemove', _scrolling);
			$(document).unbind('mouseup', _stopScrolling);
		};
		
		
		
		
		var _scrolling = function (event) {
			event.preventDefault();
			
			var gutterTop     = _gutterDiv.offset().top;
			var pageY         = event.pageY;
			var relativeY     = pageY - gutterTop;
			var maxRelativeY  = _gutterDiv.height() - _headDiv.height();
			
			if (relativeY < 0) {
				relativeY = 0;
			} else if (relativeY > maxRelativeY) {
				relativeY = maxRelativeY; 
			}

			_scrollPercentage  = relativeY / maxRelativeY;

			var contentTop = -_scrollPercentage * (_scrollerContentHeight - _scrollerContentMaskHeight);
			_headDiv.css('top', relativeY);
			_scrollerContentDiv.css('top', contentTop);
		};




		// initialize ui listeners and make calls to initialize, only if necessary
		if ($('#modals').length > 0) {
			_upButtonDiv.find('a').bind('click', function () {
				_clickScroll('up');
			});
			_downButtonDiv.find('a').bind('click', function () {
				_clickScroll('down');
			});
			_headDiv.bind('mousedown', function (event) {
				event.preventDefault();
				_startScrolling();
			});
			_resizeScroller();
		}




		// no "public" methods as of now
		return {
			
		};
	};




	return {
		create:function (scrollerDivId, scrollerContentDivId) {
			return _create(scrollerDivId, scrollerContentDivId);
		}
	};
}();
// END: _scrollerInstance
//-----------------------------------------------------------------------------



	var _getWindowDimensions = function () {
		var windowWidth = $(window).width();
		if (windowWidth < 1024) {
			windowWidth = 1024;
		}

		var windowHeight = $(window).height();
		if (windowHeight < 600) {
			windowHeight = 600;
		}

		var windowDimensions              = [];
		windowDimensions['width']         = windowWidth;
		windowDimensions['height']        = windowHeight;
		windowDimensions['aspect_ratio']  = windowDimensions['width'] / windowDimensions['height'];
		windowDimensions['orientation']   = windowDimensions['aspect_ratio'] > 1 ? 'landscape' : 'portrait';

		return windowDimensions;
	};
	
	
	
	
	var _formatProductPrice = function (price) {
		var formatted   = price.replace('.00', '').replace('$', '');
		formatted       = parseInt(formatted) != 0 ? formatted : 'TBD';

		return formatted;
	};
	
	
	
	
	var _imageToAssetUrl = function (image, appendString) {
		var filenameTokens   = image['filename'].split('.');
		var filenameBase     = filenameTokens[0];
		var filenameExt      = filenameTokens[1];
		var filenameAppend   = appendString ? appendString : ''; 

		return ASSET_BASE_URL +'/'+ filenameBase + filenameAppend +'.'+ filenameExt;
	};
	
	
	
	
	var _assetIdToAssetUrl = function (assetId, appendString, filenameExtension) {
		var append     = appendString ? appendString : '';
		var extension  = filenameExtension ? filenameExtension : 'png';
		
		return ASSET_BASE_URL +'/editoral_'+ assetId + append +'.'+ extension;
	};




	var _productToColorAssetUrl = function (product, appendString) {
		var colorAssetIds     = product['color_asset_ids'] ? product['color_asset_ids'].split(',') : [];
		var safeAppendString  = appendString ? appendString : '';
		
		if (colorAssetIds.length <= 0) {
			return '';
		}

		return ASSET_BASE_URL +'/editoral_'+ colorAssetIds[0] + safeAppendString +'.png';
	};
	
	
	
	
	var _validateEmail = function (email, defaultString) {
		if (email == null || email == false || email.length == 0 || email == defaultString) {
			return false;
		}

		var emailPattern = /^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/;
		return emailPattern.test(email);
	};




	return {
		header:             _header,
		footer:             _footer,
		lookbook:           _lookbook,
		lookbookIndex:      _lookbookIndex,
		productGrid:        _productGrid,
		scenery:            _scenery,
		modals:             _modals,
		scrollerInstance:   _scrollerInstance
	};
}();
