
/*
 *	Config section moved to config_colorSizeSelect.js (that page must be included first since it initializes the product object)
 */

product.init = function(onlyIndex)
{
	try{ if(!window.products) return false; }catch(e){ return false; } // make sure products[] has been defined before continuing
	
	var start = 0;
	var end = products.length;
	if(onlyIndex != null)
	{
		start = onlyIndex;
		end = onlyIndex+1;
	}
	
	for(var productIndex=start; productIndex < end; productIndex++) // for each product
	{
		if(product.config.page == 'cart')
		{
			if(products[productIndex].enableEdit == false) return true;	
		}
		
		if(!products[productIndex].initialized || product.config.page != 'bp')
		{
			var usedSizes = [];
			var wroteContainer = false;
			
			product.cacheData(productIndex); // TO DO: THIS SHOULDN'T NEED TO BE CALLED FOR EACH PRODUCT
			
			var requiredDimensions = products[productIndex].requiredDimensions;
			var colorsContainer = products[productIndex].colorsContainer;
			var sizesContainer = products[productIndex].sizesContainer;
			var overviewWrapper = products[productIndex].overviewWrapper;
			
			if(product.config.page == 'pdp')
			{
				overviewWrapper.find('.quant_dropdown').show();
				overviewWrapper.find('.quant_message_wrapper').show();
			}
			
			var sizeContainerNames = [];
			var spacerMarkup = '<div style="clear:both;"></div>';
			products[productIndex].sizeContainer = [];
			products[productIndex].sizeLabel = [];
			products[productIndex].colorSwatches = [];
			products[productIndex].sizeButtons = [];
				
			for(var colorIndex=0; colorIndex < products[productIndex].colors.length; colorIndex++)
			{
				var colorContainerName = product.config.element.colors+products[productIndex].colors[colorIndex].classStyleColor;
				
				products[productIndex].colors[colorIndex].colorContainer = overviewWrapper.find('.'+colorContainerName);
				if( products[productIndex].colors[colorIndex].colorContainer.length <= 0 ) // the colors div doesn't exist, so create it
				{
					products[productIndex].colors[colorIndex].colorContainer = $('<div class="'+colorContainerName+' color_swatch_container"></div>').appendTo(colorsContainer);
				}
				var colorContainer = products[productIndex].colors[colorIndex].colorContainer;
				
				colorContainer.empty(); // empty the colors div for that product
				
				var colorAnchor = product.config.colorPrefix+colorIndex+'_'+products[productIndex].colors[colorIndex].classStyleColor;
				
				overviewWrapper.find('.loadingSwatchesMessage').remove();
				
				products[productIndex].colorSwatches[colorIndex] = {
				    colorIndex: colorIndex,
				    classStyleColor: products[productIndex].colors[colorIndex].classStyleColor,
				    el: $('<a id="'+colorAnchor+'" class="'+product.config.cssClass.color+'" href="#" onclick="product.selectColor('+productIndex+', \''+products[productIndex].colors[colorIndex].classStyleColor+'\'); return false;" onmouseover="product.showSizes('+productIndex+', \''+products[productIndex].colors[colorIndex].classStyleColor+'\')" onmouseout="product.showSelected('+productIndex+')">'+products[productIndex].colors[colorIndex].name+'</a>').appendTo(colorContainer)
				};
				
				overviewWrapper.find('#'+colorAnchor).css('background',product.config.defaultSwatchColor+' url('+product.config.folders.swatches+products[productIndex].colors[colorIndex].classStyleColor+product.config.folders.swatchThumb+') no-repeat center');
				
				if(product.config.page == 'cart' && product.config.site == 'mao' && !wroteContainer)
				{
					var size0_label = products[productIndex].colors[colorIndex].skus[0].sizeLabels[0] != null ? products[productIndex].colors[colorIndex].skus[0].sizeLabels[0]+':' : 'Size:';
					if(requiredDimensions > 1)
					{
						sizeContainerNames[1] = 'sizes1_'+products[productIndex].containerNameSuffix;
						var size1_label = products[productIndex].colors[colorIndex].skus[0].sizeLabels[1] != null ? products[productIndex].colors[colorIndex].skus[0].sizeLabels[1]+':' : 'Length:';
						products[productIndex].sizeLabel[1] = overviewWrapper.find('.sizes1_'+products[productIndex].classStyle+'_label');
						products[productIndex].sizeLabel[1].html(size1_label);
						overviewWrapper.find('.size1_row_label').show();
						overviewWrapper.find('.size1_row').show();
						products[productIndex].sizeContainer[1] = overviewWrapper.find('.'+sizeContainerNames[1]);
					}
					else
					{
						overviewWrapper.find('.size1_row_label').hide();
						overviewWrapper.find('.size1_row').hide();
					}
					products[productIndex].sizeLabel[0] = overviewWrapper.find('.sizes0_'+products[productIndex].classStyle+'_label');
					products[productIndex].sizeLabel[0].html(size0_label);
					sizeContainerNames[0] = 'sizes0_'+products[productIndex].containerNameSuffix;
					products[productIndex].sizeContainer[0] = overviewWrapper.find('.'+sizeContainerNames[0]);
					usedSizes[0] = [];
					usedSizes[1] = [];
					wroteContainer = true;
				}
				else
				{
					for(var i=0; i<requiredDimensions; i++)
					{
						sizeContainerNames[i] = 'size'+i+'_container_'+products[productIndex].classStyle;
						if(!wroteContainer)
						{
							var description_title = products[productIndex].colors[colorIndex].skus[0].sizeLabels[0] != null ? products[productIndex].colors[colorIndex].skus[0].sizeLabels[0] : 'Size';
							if(requiredDimensions > 1 && product.config.useSingleSizeLabel !== true)
							{
								if(i == 1) 	description_title = products[productIndex].colors[colorIndex].skus[0].sizeLabels[1] != null ? products[productIndex].colors[colorIndex].skus[0].sizeLabels[1] : 'Length';
							}
							
							var descriptionTitleMarkup = '';
							var sizeLabelMarkup = '';
							if(product.config.element.sizeLabel != null) sizeLabelMarkup = '<span class="'+product.config.element.sizeLabel+i+'_'+productIndex+' size_name">&nbsp;</span>';
							
							if((i == 0 || product.config.useSingleSizeLabel !== true) || (i > 0 && product.config.combineSizeLabels !== true)) descriptionTitleMarkup = '<div class="description_title size'+i+'_label">'+description_title+': '+sizeLabelMarkup+'</div>';
							
							products[productIndex].sizeContainer[i] = $('<div class="'+sizeContainerNames[i]+' sizesContainer size'+i+'_container">'+descriptionTitleMarkup+'</div>').appendTo(sizesContainer);
							products[productIndex].sizeLabel[i] = overviewWrapper.find('.'+product.config.element.sizeLabel+i+'_'+productIndex);
							usedSizes[i] = [];
						}
						if(i == (requiredDimensions-1)) wroteContainer = true;
					}
				}
				var i = 0;
				for(var skuIndex=0; skuIndex < products[productIndex].colors[colorIndex].skus.length; skuIndex++)
				{
					for(var sizeIndex=0; sizeIndex<requiredDimensions; sizeIndex++)
					{
						if(jQuery.inArray(products[productIndex].colors[colorIndex].skus[skuIndex].size[sizeIndex], usedSizes[sizeIndex]) < 0) // if this size has not already been put on page
						{
							var extraClasses = '';
							if(!isNaN(products[productIndex].colors[colorIndex].skus[skuIndex].size[sizeIndex])) extraClasses = ' numeric';
							var sizeName = products[productIndex].colors[colorIndex].skus[skuIndex].size[sizeIndex].replace(' ', '&nbsp;');
							products[productIndex].sizeButtons[i] = {
							    sizeIndex: sizeIndex,
							    size: products[productIndex].colors[colorIndex].skus[skuIndex].size[sizeIndex],
							    el: $('<a id="'+product.config.sizePrefix+productIndex+'_'+sizeIndex+'_'+products[productIndex].colors[colorIndex].skus[skuIndex].size[sizeIndex]+'" class="'+product.config.cssClass.size+extraClasses+'" href="#" onclick="product.selectSize('+productIndex+', '+sizeIndex+', \''+products[productIndex].colors[colorIndex].skus[skuIndex].size[sizeIndex]+'\'); return false;" onmouseover="product.showSizes('+productIndex+', '+sizeIndex+', \''+products[productIndex].colors[colorIndex].skus[skuIndex].size[sizeIndex]+'\')" onmouseout="product.showSelected('+productIndex+')">'+sizeName+'</a>').appendTo(products[productIndex].sizeContainer[sizeIndex])
							};
							usedSizes[sizeIndex].push(products[productIndex].colors[colorIndex].skus[skuIndex].size[sizeIndex]); // add to the array so that not put on page again
							i++;
						}
					}
				}
				
				try{
					for(var i=0; i<requiredDimensions; i++)
					{
						if(usedSizes[i].length == 1) // only one size on the page
						{
							product.selectSize(productIndex, i, usedSizes[i][0]);
						}
					}
				}catch(e){}
			}
			
			// Add appropriate spacers to account for floated elements and avoid using overflow
			$(colorContainer).after(spacerMarkup);
			$(sizesContainer).after(spacerMarkup);
			products[productIndex].initialized = true;
		}
	}
	
	var initialColor = null;
	var productIndex = (!!onlyIndex) ? onlyIndex : 0;
	
	if(product.config.page == 'bp')
	{
		for(var pi=start; pi < end; pi++) // for each product being initialized
		{
			var initialColor = null;
			var indexVal = pi+1;
			if(!products[pi].initSelect)
			{
				initialColor = products[pi].overviewWrapper.find('#initialColor_'+indexVal).attr('value');
				products[pi].initSelect = true;
			}
			if(initialColor) product.selectColor(pi, initialColor);
		}
	} else if (!!products[productIndex]) {
	    if(product.config.page == 'pdp')
		    initialColor = products[productIndex].overviewWrapper.find('#OMColorString').attr('value');
	    else if(product.config.page == 'fi')
		    initialColor = products[productIndex].overviewWrapper.find('#ColorString').attr('value');
	    else if(product.config.page == 'cart')
	        initialColor = products[productIndex].overviewWrapper.find('#origColor').attr('value');
	}
	
	if(initialColor && product.config.page != 'bp') {
	    product.selectColor(productIndex, initialColor);
	}
	
	if (!!products[productIndex]) {
	    if(product.config.page == 'cart')
	    {
    		var size0 = products[productIndex].overviewWrapper.find('#origSize0').attr('value');
    		var size1 = products[productIndex].overviewWrapper.find('#origSize1').attr('value');
    		if(size0) product.selectSize(productIndex, 0, size0);
    		if(size1) product.selectSize(productIndex, 1, size1);
    	}
    	else
    	{
    		var initialSize = products[productIndex].overviewWrapper.find('#initialSize').attr('value');
    	}
    }
	
	if(product.config.page == 'fi')
	{
		var temp = product.getProductAndColorAndSkuIndex(initialSize); // look up size id instead of using sku id
		if(typeof products[temp[0]] != 'undefined' && typeof products[temp[0]].colors[temp[1]] != 'undefined' && typeof products[temp[0]].colors[temp[1]].skus[temp[2]] != 'undefined')
			initialSize = products[temp[0]].colors[temp[1]].skus[temp[2]].sizeId;
	}

	if(initialSize)
	{
		var initialSizes = product.findSizeValuesById(initialSize);
		if(initialSizes)
		{
			var requiredDimensions = products[productIndex].requiredDimensions;
			for(var i=0; i<requiredDimensions; i++)
			{
				product.selectSize(productIndex, i, initialSizes[i]);
			}
		}
	}
	
	if(!!products[productIndex] && product.config.msgs.toolTips.enabled === true) // add JS listeners for tooltip if enabled
	{
		var classStyle = products[productIndex].classStyle,
		atbEl = products[productIndex].overviewWrapper.find('.'+product.config.element.addToBag),
		atwEl = products[productIndex].overviewWrapper.find('.'+product.config.element.addToWishList);
		atbEl.bind('mouseover', {'productIndex':productIndex, 'classStyle':classStyle}, product.showAddToBagToolTip);
		atbEl.bind('mouseout', {'productIndex':productIndex, 'classStyle':classStyle}, product.hideAddToBagToolTip);
		atwEl.bind('mouseover', {'productIndex':productIndex, 'classStyle':classStyle}, product.showAddToWishListToolTip);
		atwEl.bind('mouseout', {'productIndex':productIndex, 'classStyle':classStyle}, product.hideAddToWishListToolTip);
	}
}

// for the cart to determine html elements names for color/container products
product.getContainerNameSuffix = function(productIndex)
{
	var suffix = '';
	var productType = products[productIndex].overviewWrapper.find('#productType').val();
	if(productType == 'colorProduct')
	{
		var origColor = products[productIndex].overviewWrapper.find('#origColor').val();
		for(var colorIndex=0; colorIndex<products[productIndex].colors.length; colorIndex++)
		{
			if(products[productIndex].colors[colorIndex].classStyleColor == origColor)
			{
				suffix = products[productIndex].colors[colorIndex].classStyleColor;
				break;
			}
		}
	}
	else
		suffix = products[productIndex].classStyle;
	
	return suffix;
}

product.findSizeValuesById = function(sizeId)
{
	var sizeValues = false;
	
	for(var productIndex=0; productIndex < products.length; productIndex++) // for each product
	{
		for(var colorIndex=0; colorIndex < products[productIndex].colors.length; colorIndex++) // for each color
		{
			for(var skuIndex=0; skuIndex < products[productIndex].colors[colorIndex].skus.length; skuIndex++) // for each sku
			{
				if(products[productIndex].colors[colorIndex].skus[skuIndex].sizeId == sizeId)
				{
					sizeValues = products[productIndex].colors[colorIndex].skus[skuIndex].size;
					break; // no need to keep searching
				}
			}
		}
	}
	
	return sizeValues;
}

/*
 * for displaying debug messages in the page
 */
product.debug = function(msg, lineBreak) /*
    TODO remove me.
*/
{
	if(lineBreak == null) lineBreak = '<br />';
	if(product.config.debug)
	{
		if( product.config.pageWrapper.find('#'+product.config.element.debug).length <= 0 ) product.config.debugElment = $('<div id="'+product.config.element.debug+'"></div>').appendTo(product.config.pageWrapper);
		product.config.debugElment.show();
		product.config.debugElment.append(msg+' ');
		if(lineBreak) product.config.debugElment.append(lineBreak);
	}
}

/*
 * for displaying messages to the user in the page
 */
product.displayMsg = function(productIndex, msg, webOnly)
{
	if(webOnly === null) webOnly = false;
	products[productIndex].msg.html(msg);
	product.displayWebOnlyStatus(productIndex, webOnly);
}
product.clearMsg = function(productIndex)
{
	products[productIndex].msg.html('&nbsp;');
}

product.getWebOnlyStatus = function(productIndex,colorIndex,skuIndex)
{
	if(product.config.enableWebOnlyStatus !== true) return;
	
	var webOnly = false;
	if(colorIndex != null && skuIndex != null && skuIndex >= 0)
	{
		if(products[productIndex].colors[colorIndex].skus[skuIndex].webOnly === true)
		{
			webOnly = true;
		}
	}
	return webOnly;
}
product.displayWebOnlyStatus = function(productIndex, webOnly, append)
{
	if(product.config.enableWebOnlyStatus !== true) return;
	
	if(append == null) append = true;
	var currMsg;
	
	if(append && products[productIndex].msg.html() != null) currMsg = products[productIndex].msg.html().replace(/^\s+|\s+$/g, '');
	else currMsg = '';
		
	if(webOnly) currMsg+=', Web Exclusive';
	else
	{
		if(product.config.page == 'pdp')
			currMsg+=' &nbsp; <a href="javascript:LaunchFindIt()" onMouseOver="window.status=\'\';return true;" onclick="dcsMultiTrack(\'DCS.dcsuri\',\'/'+jsContextRoot+'/browse/LocateInStoreInitial.jsp\',\'WT.si_n\',\'LocateInStore\',\'WT.si_x\',\'1\',\'WT.ti\',\'AELocateInStore\',\'WT.ac\',\'LocateInStoreInitial\');" style="text-decoration:underline;">Locate in Store</a>';
		else if(product.config.page == 'bp')
			currMsg+=' &nbsp; <a href="javascript:LaunchFindIt(\''+products[productIndex].classStyle+'\', \''+(productIndex+1)+'\');" onmouseover="window.status=\'click for details\';return true;" onmouseover="window.status=\'\';return true;" onclick="dcsMultiTrack(\'DCS.dcsuri\',\'/'+jsContextRoot+'/browse/LocateInStoreInitial.jsp\',\'WT.si_n\',\'LocateInStore\',\'WT.si_x\',\'1\',\'WT.ti\',\'AELocateInStore\',\'WT.ac\',\'LocateInStoreInitial\');">Locate in Store</a>';
	}
	products[productIndex].msg.html(currMsg);
}

product.setAddToBagToolTipMessage = function(productIndex, msg)
{
	products[productIndex].addToBagToolTipMsg.html(msg);
	products[productIndex].wishListToolTipMsg.html(msg);
}

product.showAddToBagToolTip = function(event)
{
	if(product.config.msgs.toolTips.enabled === true && !enableCheckOut) // don't show if disabled in settings or if item is available
	{
		products[event.data.productIndex].addToBagToolTipBg.show();
		products[event.data.productIndex].addToBagToolTipMsg.show();
	}
}
product.hideAddToBagToolTip = function(event)
{
	products[event.data.productIndex].addToBagToolTipBg.hide();
	products[event.data.productIndex].addToBagToolTipMsg.hide();
}

product.showAddToWishListToolTip = function(event)
{
	if(product.config.msgs.toolTips.enabled === true && !enableCheckOut) // don't show if disabled in settings or if item is available
	{
		products[event.data.productIndex].wishListToolTipBg.show();
		products[event.data.productIndex].wishListToolTipMsg.show();
	}
}
product.hideAddToWishListToolTip = function(event)
{
	products[event.data.productIndex].wishListToolTipBg.hide();
	products[event.data.productIndex].wishListToolTipMsg.hide();
}

product.disableAddToCart = function(productIndex)
{
    enableCheckOut = false;
	if(product.config.page == 'pdp') {
	    if (!products[productIndex]) return false;
		if (!products[productIndex].pdpATCbutton) {
		    products[productIndex].pdpATCbutton = products[productIndex].overviewWrapper.find('.'+product.config.element.addToBag);
		}
		products[productIndex].pdpATCbutton.addClass('disabled'); // always an array because of the hidden input that ATG adds
    } else if (product.config.page == 'bp') { /*
		TODO clean this?! use config for id?!
	*/
		if (!products[productIndex]) {
		    $($('#addToCart')[0]).addClass('disabled')
		} else {
		    if (!products[productIndex].bpATCbutton) {
    		    products[productIndex].bpATCbutton = $($('#addToCart')[0]);
    		}
    		products[productIndex].bpATCbutton.addClass('disabled');
    	}
	}
}

product.enableAddToCart = function(productIndex)
{
	enableCheckOut = true;
	if(product.config.page == 'pdp') {
		if (!products[productIndex]) return false;
	    if (!products[productIndex].pdpATCbutton) {
		    products[productIndex].pdpATCbutton = products[productIndex].overviewWrapper.find('.'+product.config.element.addToBag);
		}
		products[productIndex].pdpATCbutton.removeClass('disabled'); // always an array because of the hidden input that ATG adds
    } else if (product.config.page == 'bp') { /*
		TODO clean this?! use config for id?!
	*/
		if (!products[productIndex]) {
		    $($('#addToCart')[0]).removeClass('disabled')
		} else {
    		if (!products[productIndex].bpATCbutton) {
    		    products[productIndex].bpATCbutton = $($('#addToCart')[0]);
    		}
    		products[productIndex].bpATCbutton.removeClass('disabled');
    	}
	}
}

/*
 * remove existing classes for this element and then set the new one
 */
product.changeClass = function(element, cssClass)
{
    if (typeof element.changeClassElementCacheIndex == 'undefined') {  // CACHE ELEMENTS... PERFORMANCE ATTEMPT.
        if (typeof product.changeClassElementCache == 'undefined') {
            product.changeClassElementCache = [];
        }
        element.changeClassElementCacheIndex =  product.changeClassElementCache.length;
        product.changeClassElementCache.push($(element));
    }
    var elm = product.changeClassElementCache[element.changeClassElementCacheIndex];
    
//    var elm = $(element);
	switch(cssClass)
	{
		case product.config.cssClass.unavailable :
			elm.removeClass(product.config.cssClass.available);
			elm.removeClass(product.config.cssClass.unavailableSelected);
			elm.removeClass(product.config.cssClass.availableSelected);
			break;
		case product.config.cssClass.available :
			elm.removeClass(product.config.cssClass.unavailable);
			elm.removeClass(product.config.cssClass.unavailableSelected);
			elm.removeClass(product.config.cssClass.availableSelected);
			break;
		case product.config.cssClass.unavailableSelected :
			elm.removeClass(product.config.cssClass.unavailable);
			elm.removeClass(product.config.cssClass.available);
			elm.removeClass(product.config.cssClass.availableSelected);
			break;
		case product.config.cssClass.availableSelected :
			elm.removeClass(product.config.cssClass.unavailable);
			elm.removeClass(product.config.cssClass.available);
			elm.removeClass(product.config.cssClass.unavailableSelected);
			break;
		default :
			break;
	}
	
	elm.addClass(cssClass);
}

/*
 * change the state of this element based on whether it's available, selected, and being hovered on
 */
product.changeState = function(element, available, selected, hover)
{
	if(available && (selected || hover)) product.changeClass(element, product.config.cssClass.availableSelected);
	else if(!available && (selected || hover)) product.changeClass(element, product.config.cssClass.unavailableSelected);
	else if(available && !selected) product.changeClass(element, product.config.cssClass.available);
	else if(!available && !selected) product.changeClass(element, product.config.cssClass.unavailable);
}

/*
 * select this color and then show the result
 */
product.selectColor = function(productIndex, classStyleColor)
{
	var colorIndex = product.getColorIndex(productIndex, classStyleColor);
	products[productIndex].selected.color = classStyleColor;
	// update form elements for add to cart

	if(product.config.page == 'bp') /*
		TODO should be a switch instead of ifelse!
	*/
	{
		var indexVal = productIndex+1;
		$('#'+product.config.element.bundlePageProdIdPrefix+indexVal).attr('value', products[productIndex].colors[colorIndex].classStyleColor);
		$('#OMColorName_'+indexVal).attr('value', products[productIndex].colors[colorIndex].name);
		$('#OMColorString_'+indexVal).attr('value', products[productIndex].colors[colorIndex].classStyleColor);
		product.changeBgImageThumbs(productIndex, colorIndex);
		updateAddToCart(productIndex + 1); // reset in case disabled
	}
	else if(product.config.page == 'cart')
	{
		document.forms[product.config.element.cartFormName].color.value = classStyleColor;
		if(product.config.swapCartImageOn === 'click') product.swapCartImage(productIndex, classStyleColor);
	}
	else
		document.forms[product.config.element.pdpFormName].color.value = classStyleColor;
	
	if(product.config.page == 'pdp')
	{
		document.forms[product.config.element.pdpFormName].OMColorString.value=classStyleColor;
		
		product.enableAddToCart(productIndex); // reset in case disabled
		product.changeImageThumbs(productIndex, colorIndex);
		
		// swap out price and other necessary form elements
		SwapPrice(products[productIndex].colors[colorIndex].skus[0].listPrice, products[productIndex].colors[colorIndex].skus[0].salePrice);
		SwapEmailFriendLink(classStyleColor);
		SwapPrintLink(classStyleColor);
		products[productIndex].colorNameLabel.html(products[productIndex].colors[colorIndex].name);
	}
	else if(product.config.page == 'fi')
	{
		$('#ColorString').val(classStyleColor);
		$('#ColorName').val(products[productIndex].colors[colorIndex].name);
		$('#colorNameVal').val(products[productIndex].colors[colorIndex].name);
		var temp = [];
		if(typeof classStyleColor != 'undefined') temp = classStyleColor.split('_');
		if(typeof temp[2] != 'undefined') $('#colorIdVal').val(temp[2]);
		product.swapImage(classStyleColor);
	}
	
	product.selectSku(productIndex);
	product.showSelected(productIndex);  // OPTIMIZE... don't need to call this again on roll out
}

/*
 * select this size and then show the result
 */
product.selectSize = function(productIndex, sizeIndex, size)
{
	switch (product.config.page) {
        case 'pdp':
            product.enableAddToCart(productIndex);
            break;
        case 'bp':
            updateAddToCart(productIndex + 1);
            break;
    }
	products[productIndex].selected.size[sizeIndex] = size;
	product.selectSku(productIndex);
	product.showSelected(productIndex);  // OPTIMIZE... don't need to call this again on roll out
}

product.selectSku = function(productIndex)
{
	var indexVal = productIndex+1;
	var allSelected = false;
	if(products[productIndex].selected.color != null && products[productIndex].selected.size[0] != null)
	{
		if(products[productIndex].colors[0].skus[0].size[1] == null || products[productIndex].colors[0].skus[0].size[1] == '') // this product has only one size dimension
			allSelected = true;
		else if(products[productIndex].selected.size[1] != null) allSelected = true;
	}
	
	var colorIndex = null;
	var skuNoInv = '';
	if(products[productIndex].selected.color != null)
	{
		colorIndex = product.getColorIndex(productIndex, products[productIndex].selected.color);
		skuNoInv = product.getSku(productIndex, colorIndex, products[productIndex].selected.size, false); // don't check inventory on this one (for store locator)
	}
	
	if(allSelected && colorIndex != null)
	{
		var sku = product.getSku(productIndex, colorIndex, products[productIndex].selected.size); // check inventory on this one for add to bag
		if(sku < 0)
		{
			sku = '';
			if(product.config.page == 'cart')
			{
				saveEnabled = false;
				saveMessage = 'The selected item is out of stock';
			}
		}
		else
		{
			if(product.config.page == 'cart')
			{
				saveEnabled = true;
				saveMessage = '';
			}
			else if(product.config.page == 'bp')
			{
				if(typeof checkboxStates != 'undefined') // only for M+O right now
				{
					checkboxStates[indexVal-1] = true;
					fixCheck(indexVal);
				}
			}
		}
		
		if(product.config.page == 'bp')
		{
			$('#'+product.config.element.bundlePageAdditionalSkuInputPrefix+indexVal).attr('value', sku);
			$('#'+product.config.element.bundlePageSkuInputPrefix+indexVal).attr('value', sku);
			$('#'+product.config.element.bundlePageLocateInStoreSkuInputPrefix+indexVal).attr('value', skuNoInv);
			$('#'+product.config.element.bundlePageProdIdPrefix+indexVal).attr('value', products[productIndex].colors[colorIndex].classStyleColor);
			if (!!sku && !!skuNoInv) {
			    products[productIndex].selected.cartEnabled = true;
			    products[productIndex].selected.cartMessage = '';
			} else {
    			products[productIndex].selected.cartEnabled = false;
    			products[productIndex].selected.cartMessage = 'Please select valid size and color combinations for all selected items';
			}
		}
		else if(product.config.page == 'fi')
		{
			$('#SizeId').val(sku);
			var skuIndex = product.getProductAndColorAndSkuIndex(sku)[2];
			document.formFindIt.sizeNameVal.value = products[productIndex].colors[colorIndex].skus[skuIndex].size[0] + ' ' + products[productIndex].colors[colorIndex].skus[skuIndex].size[1];
		}
		else
		{
			products[productIndex].size.attr('value', sku);
			products[productIndex].findItSize.attr('value', skuNoInv);
		}
	}
	else
	{
		if(product.config.page == 'bp')
		{
			$('#'+product.config.element.bundlePageAdditionalSkuInputPrefix+indexVal).attr('value', '');
			$('#'+product.config.element.bundlePageSkuInputPrefix+indexVal).attr('value', '');
			$('#'+product.config.element.bundlePageLocateInStoreSkuInputPrefix+indexVal).attr('value', skuNoInv);
			products[productIndex].selected.cartEnabled = false;
			products[productIndex].selected.cartMessage = 'Please select a size and color for all selected items';
		}
		else if(product.config.page == 'fi')
		{
			$('#SizeId').val('');	
		}
		else
		{
			if(product.config.page == 'cart')
			{
				saveEnabled = false;
				saveMessage = 'Please select a size';
			}
			products[productIndex].size.attr('value', '');
			products[productIndex].findItSize.attr('value', skuNoInv);
		}
	}
}

/*
 * show what's available when hovering
 */
product.showSizes = function(productIndex, classStyleColor_sizeIndex, size)
{
	if(typeof(classStyleColor_sizeIndex) == 'string')  // hovering over a color
		products[productIndex].hover.color = classStyleColor_sizeIndex;
	else // hovering over a size dimension
		products[productIndex].hover.size[classStyleColor_sizeIndex] = size;
	
	product.showSelected(productIndex, true);
}

/*
 * search for the sku for a particlar product/color matching the sizes in the sizes array
 */
product.getSku = function(productIndex, colorIndex, sizes, checkInventory, returnIndex)
{
	if(checkInventory == null) checkInventory = true;
	if(returnIndex == null) returnIndex = false;
	
	var sku = -1;
	if(productIndex < 0 || colorIndex < 0) return sku;
	
	var requiredMatches = 2;
	if(products[productIndex].colors[colorIndex].skus[0].size[1] == null || products[productIndex].colors[colorIndex].skus[0].size[1] == '') requiredMatches = 1; // this product has only one size dimension
	
	for(var skuIndex=0; skuIndex < products[productIndex].colors[colorIndex].skus.length; skuIndex++)
	{
		var matches = 0;
		for(var sizeIndex=0; sizeIndex<requiredMatches; sizeIndex++)
		{
			if(products[productIndex].colors[colorIndex].skus[skuIndex].size[sizeIndex] == sizes[sizeIndex]) matches++;
		}
		if(matches >= requiredMatches)
		{
			if(!checkInventory || jQuery.inArray(products[productIndex].colors[colorIndex].skus[skuIndex].sku, products[productIndex].colors[colorIndex].availableSkus) >= 0) // this sku is available
			{
				if(returnIndex) sku = skuIndex;
				else sku = products[productIndex].colors[colorIndex].skus[skuIndex].sku;
				break;
			}
		}
	}
	if(!returnIndex && sku != -1 && product.config.page == 'pdp') SwapPrice(products[productIndex].colors[colorIndex].skus[skuIndex].listPrice, products[productIndex].colors[colorIndex].skus[skuIndex].salePrice);
	return sku;
}

/*
 * search for the color index of this class-style-color
 */
product.getColorIndex = function(productIndex, classStyleColor)
{
	for(var colorIndex=0; colorIndex < products[productIndex].colors.length; colorIndex++) // for each color
	{
		if(products[productIndex].colors[colorIndex].classStyleColor == classStyleColor) return colorIndex;
	}
	return -1;
}

product.swapCartImage = function(productIndex, classStyleColor)
{
	var editComId = $('#editComId').attr('value');
	var elem = '#img_'+products[productIndex].containerNameSuffix+'_'+editComId;
	//Pre-S7: $(elem).attr('src', product.config.folders.cartThumb+classStyleColor+'.jpg');
	$(elem).attr('src', product.config.folders.baseDirectory+classStyleColor+product.config.folders.cartThumb);
}

product.getRequiredDimensions = function(productIndex)
{
	var requiredDimensions = 2;
	if(!!products[productIndex].colors[0])
		if(products[productIndex].colors[0].skus[0].size[1] == null || products[productIndex].colors[0].skus[0].size[1] == '') requiredDimensions = 1;
	return requiredDimensions;
}

/*
 * show what's selected and available (or not)
 */
product.showSelected = function(productIndex, keepHover)
{
	if(keepHover != true) product.clearHover(productIndex);
	product.clear(productIndex);
	
	var useColor = null;
	if(keepHover) useColor = products[productIndex].hover.color ? products[productIndex].hover.color : products[productIndex].selected.color;
	else useColor = products[productIndex].selected.color;
	
	if(useColor)
	{
		var colorIndex = product.getColorIndex(productIndex, useColor); // swap color name
		if(product.config.page == 'cart' && product.config.swapCartImageOn === 'hover') product.swapCartImage(productIndex, useColor); // swap image
		else if(product.config.page == 'bp') product.swapBpLargeThumb(productIndex, colorIndex);
		
		products[productIndex].colorNameLabel.html(products[productIndex].colors[colorIndex].name);
		/*
		 * for swapping image on hover of swatches in PDP.  do not delete in case this is wanted again
		if(product.config.page == 'pdp')
		{
			var useView = lastUsedPDPDetailView;
			if(useView == null || !products[productIndex].colors[colorIndex].hasView[useView]) useView = 0; // the last used view isn't valid for this new color, set back to first view
			product.swapImage(products[productIndex].colors[colorIndex].classStyleColor, useView); // change out the main pdp image
		}
		*/
	}
	
	var useForSize0 = (products[productIndex].hover.size[0] != null) ? products[productIndex].hover.size[0] : products[productIndex].selected.size[0];
	var useForSize1 = (products[productIndex].hover.size[1] != null) ? products[productIndex].hover.size[1] : products[productIndex].selected.size[1];
	var useForColor = (products[productIndex].hover.color != null) ? products[productIndex].hover.color : products[productIndex].selected.color;
	
	var sizeLabel = '&nbsp;';
	var useForSize0Label = useForSize0;
	var useForSize1Label = useForSize1;
	
	if(!isNaN(useForSize0) && !isNaN(useForSize1)) // if both are numeric then add labels (currently W and L so it would display as 32W 34L)
	{
		var useForSize0Label = useForSize0+product.config.sizeLabels[0];
		var useForSize1Label = useForSize1+product.config.sizeLabels[1];
	}
	
	if(product.config.combineSizeLabels === true)
	{
		if(useForSize0 != null && useForSize1 != null) sizeLabel = useForSize0Label+' '+useForSize1Label;
		else if(useForSize0 != null) sizeLabel = useForSize0Label;
		else if(useForSize1 != null) sizeLabel = useForSize1Label;
		if(products[productIndex].sizeLabel[0] != null) products[productIndex].sizeLabel[0].html(sizeLabel);
	}
	else
	{
		if(useForSize0 != null && products[productIndex].sizeLabel[0] != null) products[productIndex].sizeLabel[0].html(useForSize0Label);
		else if(products[productIndex].sizeLabel[0] != null) products[productIndex].sizeLabel[0].html('&nbsp;'); // clear label
		if(useForSize1 != null && products[productIndex].sizeLabel[1] != null) products[productIndex].sizeLabel[1].html(useForSize1Label);
		else if(products[productIndex].sizeLabel[1] != null) products[productIndex].sizeLabel[1].html('&nbsp;'); // clear label
	}
	
	var requiredDimensions = products[productIndex].requiredDimensions;
	var allSelected = false;
	if(useForColor != null && useForSize0 != null)
	{
		if(requiredDimensions == 1)
			allSelected = true;
		else
			if(useForSize1 != null) allSelected = true;
	}
	if(allSelected)
	{
		var colorIndex = product.getColorIndex(productIndex, useForColor);
		var sku = product.getSku(productIndex, colorIndex, [useForSize0, useForSize1]);
		var skuIndex = product.getSku(productIndex, colorIndex, [useForSize0, useForSize1], false, true); // look up sku index (without inventory check)
		if(sku < 0)
		{
			product.displayMsg(productIndex, product.config.msgs.outOfStock, product.getWebOnlyStatus(productIndex,colorIndex,skuIndex));
			if(product.config.msgs.toolTips.enabled === true) product.setAddToBagToolTipMessage(productIndex, product.config.msgs.toolTips.outOfStock);
			switch (product.config.page) {
                case 'pdp':
                    product.disableAddToCart(productIndex);
                    break;
                case 'bp':
                    updateAddToCart(productIndex + 1);
                    break;
            }
		}
		else
		{
			product.displayMsg(productIndex, product.config.msgs.available, product.getWebOnlyStatus(productIndex,colorIndex,skuIndex));
			if(product.config.msgs.toolTips.enabled === true) product.setAddToBagToolTipMessage(productIndex, product.config.msgs.toolTips.available);
			switch (product.config.page) {
                case 'pdp':
                    product.enableAddToCart(productIndex);
                    break;
                case 'bp':
                    updateAddToCart(productIndex + 1);
                    break;
            }
		}
	}
	else
	{
		product.displayMsg(productIndex, product.config.msgs.noSelection, product.getWebOnlyStatus(productIndex));
		if(product.config.msgs.toolTips.enabled === true) product.setAddToBagToolTipMessage(productIndex, product.config.msgs.toolTips.noSelection);
		switch (product.config.page) {
            case 'pdp':
                product.disableAddToCart(productIndex);
		        break;
            case 'bp':
                updateAddToCart(productIndex + 1);
                break;
        }
	}
	
	var colors = products[productIndex].colorSwatches;
	$.each(colors, function(i)
	{
		var colorIndex = colors[i].colorIndex;
		var classStyleColor = colors[i].classStyleColor;
		
		var available = false;
		var selected = false;
		var hover = false;
		
		if(products[productIndex].selected.color == classStyleColor) selected = true;
		if(products[productIndex].hover.color == classStyleColor) hover = true;
		
		// (neither size selected)  &&  (there are available skus for this color)
		if((useForSize0 == null && useForSize1 == null) && (products[productIndex].colors[colorIndex].availableSkus.length > 0))
		{
			available = true;
		}
		else
		{
			for(var skuIndex=0; skuIndex < products[productIndex].colors[colorIndex].skus.length; skuIndex++) // for each sku
			{
				var checkSku = false;
				if(useForSize0 != null && useForSize1 != null) // both sizes selected
				{
					if(useForSize0 == products[productIndex].colors[colorIndex].skus[skuIndex].size[0]
						&& useForSize1 == products[productIndex].colors[colorIndex].skus[skuIndex].size[1])
					{
						checkSku = true;
					}
				}
				else if(useForSize0 != null)
				{
					if(useForSize0 == products[productIndex].colors[colorIndex].skus[skuIndex].size[0])
					{
						checkSku = true;
					}
				}
				else if(useForSize1 != null)
				{
					if(useForSize1 == products[productIndex].colors[colorIndex].skus[skuIndex].size[1])
					{
						checkSku = true;
					}
				}
				
				if(checkSku && jQuery.inArray(products[productIndex].colors[colorIndex].skus[skuIndex].sku, products[productIndex].colors[colorIndex].availableSkus) >= 0) // this sku is available
				{
					available = true;
					break; // no need to keep looping
				}
			}
		}
		product.changeState(colors[i].el, available, selected, hover);
	});
	
	// for each size element for this product
	var sizes = products[productIndex].sizeButtons;
	$.each(sizes, function(i)
	{
		var sizeIndex = sizes[i].sizeIndex;
		var size = sizes[i].size;
				
		if(useForColor != null) // the color for this product has been selected
		{
			var colorIndex = product.getColorIndex(productIndex, useForColor);
			if(colorIndex >= 0) product.showAvailableSizes(sizes[i].el, productIndex, colorIndex, sizeIndex, size);
		}
		else
		{
			for(var colorIndex=0; colorIndex < products[productIndex].colors.length; colorIndex++) // for each color
			{
				if(product.showAvailableSizes(sizes[i].el, productIndex, colorIndex, sizeIndex, size)) break; // break if this has already been determined
			}
		}
	});
	
}

/*
 * show the sizes available for this product/color index
 */
product.showAvailableSizes = function(element, productIndex, colorIndex, sizeIndex, size)
{
	var available = false;
	var selected = false;
	var hover = false;
	
	var useForSize0 = (products[productIndex].hover.size[0] != null) ? products[productIndex].hover.size[0] : products[productIndex].selected.size[0];
	var useForSize1 = (products[productIndex].hover.size[1] != null) ? products[productIndex].hover.size[1] : products[productIndex].selected.size[1];
	var useForColor = (products[productIndex].hover.color != null) ? products[productIndex].hover.color : products[productIndex].selected.color;
	
	if(products[productIndex].selected.size[sizeIndex] == size) selected = true;
	if(products[productIndex].hover.size[sizeIndex] == size) hover = true;
		
	for(var skuIndex=0; skuIndex < products[productIndex].colors[colorIndex].skus.length; skuIndex++) // for each sku
	{
		var checkSku = false;
		
		if(sizeIndex == 0 && useForSize1 != null)
		{
			if(size == products[productIndex].colors[colorIndex].skus[skuIndex].size[0] &&
				useForSize1 == products[productIndex].colors[colorIndex].skus[skuIndex].size[1])
			{
				checkSku = true;
			}
		}
		else if(sizeIndex == 1 && useForSize0 != null) // COMBINE WITH ABOVE
		{
			if(size == products[productIndex].colors[colorIndex].skus[skuIndex].size[1] &&
				useForSize0 == products[productIndex].colors[colorIndex].skus[skuIndex].size[0])
			{
				checkSku = true;
			}
		}
		else if(size == products[productIndex].colors[colorIndex].skus[skuIndex].size[sizeIndex])
		{
			checkSku = true;
		}
		
		if(checkSku && jQuery.inArray(products[productIndex].colors[colorIndex].skus[skuIndex].sku, products[productIndex].colors[colorIndex].availableSkus) >= 0) // this sku is available
		{
			available = true;
			break; // no need to keep looping
		}
	}
	
	product.changeState(element, available, selected, hover);
	if(available) return true;
}

/*
 * clear the styles for both the color and sizes for this product
 */
product.clear = function(productIndex)
{
	product.clearColors(productIndex);
	product.clearSizes(productIndex);
}

/*
 * clear the styles for the colors for this product
 */
product.clearColors = function(productIndex)
{
	products[productIndex].sizesContainer.find('a.'+product.config.cssClass.color).each(function(i)
	{
		product.changeClass(this, product.config.cssClass.unavailable);
	});
}

/*
 * clear the styles for the sizes for this product
 */
product.clearSizes = function(productIndex)
{
	products[productIndex].sizesContainer.find('a.'+product.config.cssClass.size).each(function(i)
	{
		product.changeClass(this, product.config.cssClass.unavailable);
	});
}

/*
 * clear the hover values for this product
 */
product.clearHover = function(productIndex)
{
	products[productIndex].hover.color = null;
	for(var sizeIndex=0; sizeIndex < products[productIndex].hover.size.length; sizeIndex++)
	{
		products[productIndex].hover.size[sizeIndex] = null;
	}
}

/*
 * search for the product and color indexes of this class-style-color
 */
product.getProductAndColorIndex = function(classStyleColor)
{
	var indexes = [-1, -1];
	
	for(var productIndex=0; productIndex < products.length; productIndex++)
	{
		for(var colorIndex=0; colorIndex < products[productIndex].colors.length; colorIndex++) // for each color
		{
			if(products[productIndex].colors[colorIndex].classStyleColor == classStyleColor)
			{
				indexes[0] = productIndex;
				indexes[1] = colorIndex;
				return indexes;
			}
		}
	}
	return indexes;
}

product.getProductAndColorAndSkuIndex = function(sku)
{
	var indexes = [-1, -1, -1];
	
	for(var productIndex=0; productIndex < products.length; productIndex++)
	{
		for(var colorIndex=0; colorIndex < products[productIndex].colors.length; colorIndex++) // for each color
		{
			for(var skuIndex=0; skuIndex < products[productIndex].colors[colorIndex].skus.length; skuIndex++) // for each color
			{
				if(products[productIndex].colors[colorIndex].skus[skuIndex].sku == sku)
				{
					indexes[0] = productIndex;
					indexes[1] = colorIndex;
					indexes[2] = skuIndex;
					return indexes;
				}
			}
		}
	}
	return indexes;
}


/* show additional colors on category page */

var catRevertTimeout = null;
var catRevertDelay = .8; // seconds
catRevertDelay = catRevertDelay * 1000; // convert to miliseconds

var currentFeatureClassStyle = '';

product.showAdditionalColors = function(classStyle, featured)
{
	if(featured==null) featured = false;
	product.hideAdditionalColors(classStyle);
	var linkOffset = $('#'+classStyle+'_link').position();
	if(featured) currentFeatureClassStyle = classStyle;
	$('#'+classStyle).css(
	{
		display:'block',
		position:'absolute',
		top:(linkOffset.top-0)+'px',
		left:(linkOffset.left+0)+'px'
	});
	product.highlightCurrentAdditionalColor(classStyle);
	$('#'+classStyle).bind('mouseover', function(e){
		product.clearCatRevertTimeout();  // make sure box doesn't revert back
	});
	$('#'+classStyle).bind('mouseout', function(e){
		product.setCatRevertTimeout(); // to revert back
	});
}
product.hideAdditionalColors = function(classStyle)
{
	$('#'+classStyle).unbind('mouseover');
	$('#'+classStyle).unbind('mouseout');
	product.clearCatRevertTimeout();
	$('.additional_swatches').hide();
}

product.setCatRevertTimeout = function()
{
	catRevertTimeout = window.setTimeout('product.hideAdditionalColors()', catRevertDelay);
	product.debug('setCatRevert:'+catRevertTimeout, false);
}
product.clearCatRevertTimeout = function()
{
	clearTimeout(catRevertTimeout);
	product.debug('clearCatRevert:'+catRevertTimeout, false);
}

product.swapAdditionalColor = function(classStyle, classStyleColor, catId, productName, size)
{
	var appendSize = size == null ? '' : '&size='+size;
	$('#'+classStyle+'_img').empty();
	if(currentFeatureClassStyle == classStyle)
	{
		$('#section_prodlink').attr('href', '/'+jsContextRoot+'/browse/product.jsp?catId='+catId+'&productId='+classStyle+'&showId='+classStyleColor+appendSize);
		//Pre-S7: $('#section_prodlink').html('<img width="375" height="409" border="0" src="'+product.config.folders.baseDirectory+product.config.folders.featureCatThumb+'/'+classStyleColor+'.jpg" alt="'+productName+'"/>');
		$('#section_prodlink').html('<img border="0" src="'+product.config.folders.baseDirectory+classStyleColor+product.config.folders.featureCatThumb+'" alt="'+productName+'"/>');
	}
	else
	{
		var imgWidth = product.config.folders.catThumb.split("x",1);	
		$('#'+classStyle+'_prodlink').attr('href', '/'+jsContextRoot+'/browse/product.jsp?catId='+catId+'&productId='+classStyle+'&showId='+classStyleColor+appendSize);
		//Pre-S7: $('#'+classStyle+'_img').append('<a href="/'+jsContextRoot+'/browse/product.jsp?catId='+catId+'&productId='+classStyle+'&showId='+classStyleColor+appendSize+'"><img src="'+product.config.folders.baseDirectory+product.config.folders.catThumb+'/'+classStyleColor+'.jpg" width="'+imgWidth+'" border="0" alt="'+productName+'" valueishtml="true"/></a>');
		$('#'+classStyle+'_img').append('<a href="/'+jsContextRoot+'/browse/product.jsp?catId='+catId+'&productId='+classStyle+'&showId='+classStyleColor+appendSize+'"><img src="'+product.config.folders.baseDirectory+classStyleColor+product.config.folders.catThumb+'" border="0" alt="'+productName+'" valueishtml="true"/></a>');
	}
	$('#selectedColor_'+classStyle).val(classStyleColor);
	product.highlightCurrentAdditionalColor(classStyle);
};

product.highlightCurrentAdditionalColor = function(classStyle)
{
	var classStyleColor = $('#selectedColor_'+classStyle).val();
	$('#'+classStyle+' a.swatch').each(function(){
		$(this).removeClass('selected');
	});
	$('#swatchLink_'+classStyle+'_'+classStyleColor).addClass('selected');
}

product.expandGiftWrap = function(commerceId)
{
	$('#giftWrap_'+commerceId).show();
}
product.collapseGiftWrap = function(commerceId)
{
	$('#giftWrap_'+commerceId).hide();
}
product.toggleGiftWrap = function(commerceId)
{
	$('#giftWrap_'+commerceId).toggle();
}
