/*$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
    le.sbg.js - Standard buy grid functionality 
    sbg is the standard buy grid and center of the Product Page universe.  It is
    a singleton object that is instantiated in the window.onload event.  It has
    public variables that are referenced by other areas of functionality, including
    the inline shopping bag.  It is also implemented and extended by the collections
    buy grid.
    Its only parameter is the index of the buyGrids array in which it lies.
$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$*/
function sbg(num,key) {
    var thisSbg                         = this;
    var sAIndex = num;
    var saKey = key;
    /*==============================================================
        global interface elements, some defined right away, some not 
    ==============================================================*/
    var addToBagButton;
    var addToBagButtonEnabled			= true;
    var removeItemFromPurchase			= document.getElementById("itemForPurchase_cb_" + num);
    var removeItemFromPurchaseBox;
    var buyGrid                         = document.getElementById("buyGrid_prd_" + num);
    var colorSelector                   = document.getElementById("colorChooser_prd_" + num);
    var altImagesSelector				= document.getElementById("altImages_prd_" + num);
    var legacyImage						= document.getElementById("legacyImage_prd_" + num);
    var legacyImageAlert				= document.getElementById("legacyImageAlert_prd_" + num);
    var altImages;
    var altImageSetCollection;
    var colorChips;
    var colorRecap;
    var coordinates                     = document.getElementById("coordinates");
    var detailsButton                   = document.getElementById("detailsButton_prd_" + num);
    var detailsButtonChild              = document.getElementById("detailsButtonChild_prd_" + num);
  //  var sizeButton                   = document.getElementById("sizeButton_prd_" + num);
   // var sizeButtonChild              = document.getElementById("sizeButtonChild_prd_" + num);
    var dropShipDayPhoneEntry;
    var dropShipAltPhoneEntry;
    var emailButton;
    var giftBoxSelector;
    var giftBoxPrice;
    var itemNumberRecap                 = document.getElementById("itemNumber_prd_" + num);
    var itemCode			            = document.getElementById("itemCode_prd_" + num);
    var itemPriceRecap                  = document.getElementById("productPrice_prd_" + num + "_1");
    var nowPriceRecap                  = document.getElementById("nowPrice_prd_" + num);
    var monogramSelector;
    var monogramIt;
    var nicknameEntry;
    var multiItemNicknameEntry;
    var shippingSelector;
    var multiItemShippingSelector;
    var shipToArray                     = new Array();
    var shipToPeople;    
    var nicknameEntryBox;
    var nicknameHelpButton;
    var personalSizeSuggestionButton; 
  //  var productSize                  = document.getElementById("productSize_prd_" + num);
    var productDetails                  = document.getElementById("productDetails_prd_" + num);
    var productGrid                     = document.getElementById("productGrid_prd_" + num);
    var productName                     = document.getElementById("productName_prd_" + num).innerHTML;
    var productSummary                  = document.getElementById("productSummary_prd_" + num);
    var quantitySelector                = document.getElementById("quantity_prd_" + num);
    var quantityAmounts;
    var sizeChartButton;
    var sizeChooser                     = document.getElementById("sizeChooser_prd_" + num);
    var sizeChips                       = new Array();
    var sizeRecap;
    var sizeDropdown;
    var secondarySizeChooser            = document.getElementById("secondarySizeChooser_prd_" + num);
    var secondarySizeChips              = new Array();
    var secondarySizeRecap;
    var styleLabelChooser               = document.getElementById("styleLabelChooser_prd_" + num);
    var styleLabelChips;
    var mainFeatureTypeSelector         = document.getElementById("mainFeatureTypeSelector_prd_" + num);
    var mainFeatureTypeChips;
    var featureTypeSelectors            = getElementsByClassName(buyGrid, "div", "featureTypeSelector");
    var featureTypeChips                = new Array();
    var featureTypeCombinationError     = document.getElementById("featureTypeCombinationError_prd_" + num);
    var mainFeatureLongText;
    var secondaryFeatureLongTextList    = new Object();
    var secondaryFeatureLongText;
    var summaryButton                   = document.getElementById("summaryButton_prd_" + num);
    var summaryButtonChild              = document.getElementById("summaryButtonChild_prd_" + num);
    var tryItOnButton;
    var giftBoxInfoButton;
    var monogramInfoButton;
    var shipTaxButton;
    var cancelUpdateButton				= document.getElementById("cancelUpdateButton_prd_" + num);
    var isCollection	                = false;
    var hasStyleSearchBeenProcessed		= false;
    /*===================
        Utility variables
    ===================*/
    var styleArray                      = new Array();
    // a small array of style numbers without the "SN-" or other clutter
    var snArray                         = new Array();
    // gender code numbers based on genderCodes array
    var genderCodeNum;
    // prevents duplicate core metrics tags
    var tagged                          = false;
    /*==============================
        Message and error containers
    ==============================*/
    var backOrderMessage                = document.getElementById("backOrder_prd_" + num);
    var invalidSizeColorMessage         = document.getElementById("invalidSizeColor_prd_" + num);
    var mainFeatureTypeErrorContainer   = document.getElementById("mainFeatureTypeSelectorError_prd_" + num);
    var featureTypeErrorContainer       = document.getElementById("featureTypeSelectorError_0_prd_");
    var colorSelectorErrorContainer     = document.getElementById("colorSelector_error_prd_" + num);
    var sizeSelectorErrorContainer      = document.getElementById("sizeSelector_error_prd_" + num);
    var secondarySizeSelectorErrorContainer = document.getElementById("secondarySizeSelector_error_prd_" + num);
    var giftBoxErrorContainer           = document.getElementById("giftBoxError_prd_" + num);
    var monogramErrorContainer          = document.getElementById("monogramError_prd_" + num);
    var shipQuantityErrorContainer      = document.getElementById("shipAndQuantityError_prd_" + num);
    var buyGridFooterErrorContainer     = document.getElementById("buyGridFooterError_prd_" + num);
    var dropShipDayPhoneErrorContainer  = document.getElementById("specialtyShippingDaytimeError_prd_" + num);
    var dropShipAltPhoneErrorContainer  = document.getElementById("specialtyShippingAlternateError_prd_" + num);
    var selection = new selectionObj();
    selection.styleText = productName;
    selection.styleValidState = true;
    var recap                           = {
        color                           : document.getElementById("colorRecap_prd_" + num),
        size                            : document.getElementById("sizeRecap_prd_" + num),
        price                           : document.getElementById("priceRecap_prd_" + num)
    };
    /*==================
        Public variables
    ==================*/
    this.selection                      = selection;
    this.coordinates                    = coordinates;
    this.productGrid                    = productGrid;
    this.addToBagButton                 = addToBagButton;
    this.invalidSizeColorMessage	    = invalidSizeColorMessage;
    this.recap							= recap;
    this.monogramIt                     = monogramIt;
    this.key 							= key;
    this.number							= num;
    this.currentlyActive 				= true;
    this.selection.buyGridNumber = num;
    this.monogramSelector;
    // used to track when the style changes in the buygrid
    this.currentStyle = null;
    /*======================================================
        Get a collection of plain Jane style numbers from sA
    ======================================================*/
    this.buildSNArray = function() {
        for (i in sA[saKey]) {
        	if(typeof sA[saKey][i] == "object" && sA[saKey][i] instanceof Array)
        	{
        		var spltStyle = i.split("-")[1];
        		doDebug("[buildSNArray] adding style " + spltStyle);
        		snArray.push(spltStyle);
        	}  
        }
        doDebug("[buildSNArray] snArray = " + snArray.join(","));
    };
    /*===========================================
        because not every buy grid is the same...
    ===========================================*/
    this.buildUI = function() {
        var funcName = "[buildUI] ";
        if (genderCodes[num] == "F") {
            genderCodeNum = 1;
        } else if (genderCodes[num] == "M") {
            genderCodeNum = 2;
        }
        if (document.getElementById("addToBagButton_prd_" + num) != null) {
        	addToBagButton = document.getElementById("addToBagButton_prd_" + num).getElementsByTagName("a")[0];
        } else if (document.getElementById("addToCollectionButton_prd_" + num) != null) {
	        isCollection = true;
        	addToBagButton = document.getElementById("addToCollectionButton_prd_" + num).getElementsByTagName("a")[0];
        }
        // quantity selector
        if (quantitySelector != null) {
            quantityAmounts = quantitySelector.getElementsByTagName("select")[0];
        }
        // things that depend on size variation being available
        if (document.getElementsByName("tryItOnSizeRecommendationLink") != null) {
        	personalSizeSuggestionButton = document.getElementsByName("tryItOnSizeRecommendationLink");
        }
    	if (document.getElementById("giftBoxChooser_prd_" + num) != null) {
    		giftBoxInfoButton = document.getElementById("giftBoxChooser_prd_" + num).getElementsByTagName("a")[0];
    	}
    	if (document.getElementById("monogramChooser_prd_" + num) != null) {
    		monogramInfoButton = document.getElementById("monogramChooser_prd_" + num).getElementsByTagName("a")[0];
    	}   
        if (sizeChooser != null) {
            /*==================================================
                The size chips are divs within divs within divs.
            ==================================================*/
            // get the first set of nodes
            var sizeChipDomArr1 = sizeChooser.childNodes;
            var sizeChipDomArr2 = new Array();
            for (var i = 0; i < sizeChipDomArr1.length; i++) {
                // if the node is an HTML node, get the internal divs
                if (sizeChipDomArr1[i].getElementsByTagName) {
                    sizeChipDomArr2 = sizeChipDomArr1[i].getElementsByTagName("div");
                    for (var j = 0; j < sizeChipDomArr2.length; j++) {
                        // assign the internal divs to the global sizeChips array
                        sizeChips.push(sizeChipDomArr2[j]);
                    }
                }
            }
        } 
        // if we have a secondary size chooser, like we have for the womens' swimsuits
        // with dress/cup size
        if (secondarySizeChooser != null) {
          var secondarySizeChipDOMElements = secondarySizeChooser.childNodes;
          for (i = 0; i < secondarySizeChipDOMElements.length; i++) {
              var sizeEle = secondarySizeChipDOMElements[i];
              if (sizeEle.tagName == "DIV") {
                  doDebug(funcName + "adding secondary size code " + sizeEle.id);
                  secondarySizeChips.push(sizeEle);
              }
          }
        }
        if (document.getElementById("sizeChooserSelectBox_prd_" + num) != null) {
        	sizeDropdown = document.getElementById("sizeChooserSelectBox_prd_" + num).getElementsByTagName("select")[0];
        } else if (sizeChooser != null && sizeChooser.getElementsByTagName("select")[0] != null) {
            sizeDropdown = sizeChooser.getElementsByTagName("select")[0];
        }
        if (document.getElementById("sizeChoice_prd_" + num) != null) {
            sizeRecap = document.getElementById("sizeChoice_prd_" + num).getElementsByTagName("span")[1];
        }
        if (document.getElementById("secondarySizeChoice_prd_" + num) != null) {
            secondarySizeRecap = document.getElementById("secondarySizeChoice_prd_" + num).getElementsByTagName("span")[1];
        }
        if (document.getElementsByName("tryItOnSizeTryItLink") != null) {
        	tryItOnButton = document.getElementsByName("tryItOnSizeTryItLink");
        }
        if (document.getElementsByName("sizechartlink") != null) {
        	sizeChartButton = document.getElementsByName("sizechartlink");
        }
        // things that depend on color variation being available
        if (colorSelector != null) {
    	    colorChips = colorSelector.getElementsByTagName("img");
    	    colorRecap = document.getElementById("colorChoice_prd_" + num).getElementsByTagName("span")[1];
    	}
    	if (altImagesSelector != null) {
			altImages = altImagesSelector.getElementsByTagName("img");
			altImageSetCollection = altImagesSelector.getElementsByTagName("div");
			for (i = 0; i < altImageSetCollection.length; i++) {
			  doDebug(funcName+"altImageSetCollection["+i+"]="+altImageSetCollection[i].id);
			}
		}
        // things that depend on gift boxing being available
        if (document.getElementById("giftBoxSelector_prd_" + num) !=  null) {
        	giftBoxSelector = document.getElementById("giftBoxSelector_prd_" + num).getElementsByTagName("input")[0];
            giftBoxPrice = parseFloat(giftBoxSelector.value);
        }
        // things that depend on mongramming being available
        if (document.getElementById("monogramSelector_prd_" + num) != null) {
        	monogramSelector = document.getElementById("monogramSelector_prd_" + num).getElementsByTagName("input")[0];
        	this.monogramSelector = monogramSelector;
        }
        // things that depend on multi-style selection
        if (mainFeatureTypeSelector != null) {
        	mainFeatureTypeChips = mainFeatureTypeSelector.getElementsByTagName("input");
        } 
        if (featureTypeSelectors != null && featureTypeSelectors.length > 0) {
            var i;
            var j;
            featureTypeChips = new Array();            
            for (i = 0; i < featureTypeSelectors.length; i++) {
                var ftChips = featureTypeSelectors[i].getElementsByTagName("input");
                for (j = 0; j < ftChips.length; j++) {
                    featureTypeChips.push(ftChips[j]);
                }
            }
        }
        if (styleLabelChooser != null) {
            styleLabelChips = styleLabelChooser.getElementsByTagName("input");
        }
        // collection buy grids don't have an email link for each product
        if (document.getElementById("emailFriendButton_prd_" + num) != null) {
            emailButton = document.getElementById("emailFriendButton_prd_" + num).getElementsByTagName("a");
        }
        if (document.getElementById("nicknameHelp") != null) {
            nicknameHelpButton = document.getElementById("nicknameHelp").getElementsByTagName("a")[0];
        }
        /* if we are not a multiItem page we need to grab these controls whether we are the first 
         * buygrid or not, otherwise only grab these controls if we are the firstBuyGrid in the 
         * multi item buyGrid stack
         */
     	if(!multiItem || firstBuyGridKey == null ){
     		nicknameEntry                   = document.getElementById("nicknameSelector_prd_" + num);
    		multiItemNicknameEntry 			= document.getElementById("nicknameSelector");
    		shippingSelector                = document.getElementById("shipToSelector_prd_" + num);
    		multiItemShippingSelector 		= document.getElementById("shipToBox");
    		firstBuyGridKey = saKey;
    	}
        // collection buy grids don't have a nickname entry for each product
        if (nicknameEntry != null) {
        	nicknameEntryBox = nicknameEntry.getElementsByTagName("input")[0];
        }
    	// collection buy grids don't have one of thse for every product
    	if (shippingSelector != null) {
    	    shipToPeople = shippingSelector.getElementsByTagName("select")[0];
    	}
 		// setup multi-item shipping drop down box selector
        if(shippingSelector == null && multiItemShippingSelector != null){
        	shippingSelector = multiItemShippingSelector;
        	shipToPeople = multiItemShippingSelector.getElementsByTagName("select")[0];
        }
        // setup multi-item shipping to box selector
        if(nicknameEntry == null && multiItemNicknameEntry != null){
        	nicknameEntry = multiItemNicknameEntry;
        	nicknameEntryBox = multiItemNicknameEntry.getElementsByTagName("input")[0];
        }
        // setup shipping info link selector
        if (document.getElementById("shipInfo") !== null) {
            shipTaxButton = document.getElementById("shipInfo").getElementsByTagName("a")[0];
        }
 		if(removeItemFromPurchase != null){
 			removeItemFromPurchaseBox = removeItemFromPurchase.getElementsByTagName("input")[0];
 		}
        if (document.getElementById("dayTimePhoneInputs_prd_" + num) != null) {
            dropShipDayPhoneEntry = document.getElementById("dayTimePhoneInputs_prd_" + num).getElementsByTagName("input");
        }
        if (document.getElementById("alternativePhoneInputs_prd_" + num) != null) {
            dropShipAltPhoneEntry = document.getElementById("alternativePhoneInputs_prd_" + num).getElementsByTagName("input");
        }
        /*
   		doDebug("[buildUI] making new thisSbg.pantsHemmingSelector? sizeWaist_prd_" + num + " = " + document.getElementById("sizeWaist_prd_" + num));
    	if (document.getElementById("sizeWaist_prd_" + num) != null) {
        	thisSbg.pantsHemmingSelector = new hem(num);
    	}
        */
        // this handles an error container that easily goes missing
        if (document.getElementById("invalidSizeColor_prd_" + num) != null) {
            invalidSizeColorMessage = document.getElementById("invalidSizeColor_prd_" + num);
        } else if (document.getElementById("invalidSizeColor_prd_" + num) == null && document.getElementById("colorSelector_error_prd_" + num) != null) {
            invalidSizeColorMessage = document.getElementById("colorSelector_error_prd_" + num);
            invalidSizeColorMessage.className = "invalidSizeColor";
        } else if (document.getElementById("invalidSizeColor_prd_" + num) == null && document.getElementById("sizeSelector_error_prd_" + num) != null) {
            invalidSizeColorMessage = document.getElementById("sizeSelector_error_prd_" + num);
            invalidSizeColorMessage.className = "invalidSizeColor";
        }
        selection.styleText = productName;
    }
    /*===========================================================================
        Builds a list of people to ship to.  Separated out because it needs to be
        done before the events are registered.
    ===========================================================================*/
    this.buildShipToList = function () {
        doDebug("INSIDE buildShipToList");
        // collection buy grids don't have one of thse for every product
    	if (shipToPeople == null) {
    		return;
    	}
    	var i;  
    	shipToPeople.innerHTML = "";      
        for (i = 0; i < customerInfo.addressList.length; i++) {
          doDebug("buildShipToList addr " + i + " = " + customerInfo.addressList[i].nickname);
          shipToArray[i] = customerInfo.addressList[i].addressKey;
          var e = document.createElement("option");
          shipToPeople.appendChild(e);
          e.value = customerInfo.addressList[i].addressKey;
          e.text = customerInfo.addressList[i].nickname;
        }
        var e = document.createElement("option");
        shipToPeople.appendChild(e);
        e.value = "-2";
        e.text = shipToSomeoneElseText;
    };
    this.showLegacyImageAlert = function() {
		legacyImageAlert.className = css.imageViewer.showAlert;
		setTimeout(buyGrids[saKey].hideAlert, 3000);
	};
	this.hideAlert = function() {
		legacyImageAlert.className = css.imageViewer.hideAlert;
	};
    /*==============================================================================
        Assigns events to interface elements either directly or buy calling a buildX 
        function.
    ==============================================================================*/
    this.registerEvents = function() {
		// multiItem
		if(removeItemFromPurchase != null){
			removeItemFromPurchaseBox.onclick = this.removeItemFromPurchaseSelect;
		}
		// collection buy grid doesn't have one of these for every product
		if (summaryButton != null) {
        	summaryButton.onclick = thisSbg.flipProductSummary;
        }
        // legacy image error handling 
        if (legacyImage != null) {
        	// set the prev. img src so that the onerror code can use it if needed.
        	legacyImage.prevSrc = legacyImage.src;
        	legacyImage.onerror = function() {
        		if (legacyImage.prevSrc) {
        			buyGrids[saKey].showLegacyImageAlert();
        			legacyImage.src = legacyImage.prevSrc;	
        		}
        	};
        }
    //    if (sizeButton != null) {
      //  	sizeButton.onclick = thisSbg.flipProductSize;
     //   }
        // depends on product details being available
        if (detailsButton != null) {
        	detailsButton.onclick = thisSbg.flipProductDetails;
        }
        // collection buy grid doesn't have one of these for every product
        if (emailButton != null) {
            var i;
            for (i = 0; i < emailButton.length; i++) {
        	   emailButton[i].onclick = thisSbg.emailPopup;
            }
        }
    	// begin things that depend on size variation being available
        if (sizeChartButton != null) {
            var i;
            for (i = 0; i < sizeChartButton.length; i++) {
        	   sizeChartButton[i].onclick = thisSbg.callLEPopup;
            }
        }
        if (tryItOnButton != null) {
            var i;
            for (i = 0; i < tryItOnButton.length; i++) {
        	   tryItOnButton[i].onclick = thisSbg.tryItOnPopup;
            }
       	}
       	if (personalSizeSuggestionButton !=  null) {
            var i;
            for (i = 0; i < personalSizeSuggestionButton.length; i++) {
        	   personalSizeSuggestionButton[i].onclick = thisSbg.personalSizeSuggestionPopup;
            }
       	}
        if (shipTaxButton != null) {
            shipTaxButton.onclick = thisSbg.callLEPopup;
        }
       	if (addToBagButton != null) {
        	addToBagButton.onclick = thisSbg.addToBag;
        }
       	if (giftBoxInfoButton != null) {
        	giftBoxInfoButton.onclick = thisSbg.callLEPopup;
        }
       	if (monogramInfoButton != null) {
        	monogramInfoButton.onclick = thisSbg.callLEPopup;
        }
		// collection buy grids don't have one of these for every product
		if (nicknameEntryBox != null) {
        	nicknameEntryBox.onchange = thisSbg.addNickname;
        }
        if (nicknameHelpButton != null) {
            nicknameHelpButton.onclick = thisSbg.callLEPopup;
        }
        if (mainFeatureTypeSelector != null) {
        	thisSbg.buildMainFeatureTypeSelector();
        }
        if (featureTypeSelectors != null) {
            thisSbg.buildFeatureTypeSelector();
        }
        // depends on color variation being available
        if (thisSbg.buildColorSelector != null) {
            thisSbg.buildColorSelector();
        }
        // depends on color variation being available
        if (thisSbg.buildAltImageSelector != null) {
            thisSbg.buildAltImageSelector();
        }
        // depends on size variation being available
        if (thisSbg.buildSizeChooser != null) {
            thisSbg.buildSizeChooser();
        }
        // depends on size variation being available
        if (thisSbg.buildSecondarySizeChooser != null) {
            thisSbg.buildSecondarySizeChooser();
        }
        if (thisSbg.buildStyleLabelChooser != null) {
            thisSbg.buildStyleLabelChooser();
        }
        // depends on gift boxing being available
        if (giftBoxSelector != null) {
        	thisSbg.buildGiftBoxSelector();
        }
        // depends on monogramming being available
        if (monogramSelector != null){ 
        	thisSbg.buildMonogramSelector();
        }
        if (dropShipDayPhoneEntry != null && dropShipDayPhoneEntry != undefined) {
            thisSbg.buildPhoneEntry();
        }
       	if (cancelUpdateButton != null) {
            // go to checkout
    		cancelUpdateButton.onclick = function() {
        	   window.location = hostname + "/cgi-bin/ShoppingBag.cgi?refer=" + encodeURIComponent(ppPath);
            }
        } 
        thisSbg.buildQuantitySelector();
        thisSbg.buildShippingSelector();
    };
    this.modifyFromShoppingBag = function() {
        var funcName = "[modifyFromShoppingBag] ";
        var selectionista = thisSbg.buildSelectionFromQueryString();
        doDebug(funcName + "Selection object: " + selectionista.toString());
        selectionista.itemID = getQueryVariable("itemId");
        selection.itemID = getQueryVariable("itemId");
        if (selectionista.colorCode != null && selectionista.colorCode != "") {
          selection.colorCode = selectionista.colorCode;
        }
        if (selectionista.sizeCode != null && selectionista.sizeCode != "") {
          selection.sizeCode = selectionista.sizeCode;
        }
        if (selectionista.style != null && selectionista.style != "") {
          selection.style = selectionista.style;
        }
        selection.featureCodes = thisSbg.getStyleSecondaryFeatureList(selection.style);
        if (styleLabelChooser == null) {
            selectionista.style = thisSbg.getStyleNumber();
        }
        thisSbg.setFeatureSelection();
		doDebug(funcName + "selection.style="+selection.style+" color="+selection.colorCode+ " size="+selection.sizeCode);
        makeBuyGridSelections(buyGrids[saKey], selectionista);
        thisSbg.compareSelectionToSku();
        thisSbg.checkFeatureTypeCombinationError();
        thisSbg.updateItemNumber();
        var updateImageSrc = addToBagButton.getElementsByTagName("img")[0].src.replace(/addToBagButton_grey.gif/g,'update_item.gif');
        addToBagButton.getElementsByTagName("img")[0].alt = "update this item";
        show(cancelUpdateButton);
        addToBagButton.getElementsByTagName("img")[0].src = updateImageSrc;
    };
    this.makeSelectionsFromQueryString = function() {
        var selectionista = thisSbg.buildSelectionFromQueryString();
        doDebug("[orderMoreFromShoppingBag] Selection object: " + selectionista.toString());
        makeBuyGridSelections(buyGrids[saKey], selectionista);
        thisSbg.getStyleNumber();
        thisSbg.compareSelectionToSku();
    };
    /*=======================================================
        Gets the style number based on featureType selections
    =======================================================*/
    this.getStyleNumber = function() {
        var funcName = "[getStyleNumber] ";
        var breakme = false;
        var i;
        var j;
        doDebug(funcName + "selection.style=" + selection.style + " coming into method for " + sAIndex + " " + pageTypes[sAIndex]);
        doDebug(funcName + "selection.colorCode=" + selection.colorCode);
        if (mainFeatureTypeChips != null) {
          doDebug(funcName + "mainFeatureTypeChips.length=" + mainFeatureTypeChips.length);
          doDebug(funcName + "snArray.length=" + snArray.length);
        }
        // if there is a main feature type and there is more than one style on this page.
        if (mainFeatureTypeChips != null && mainFeatureTypeChips.length > 0 && snArray.length > 1) {
//            for (i = 0; i < mainFeatureTypeChips.length; i++) {
//               if (mainFeatureTypeChips[i].checked && snArray[i] !== undefined) {
//                    selection.viewID = mainFeatureTypeChips[i].value;
//                    selection.style = snArray[i];
//                }
//            }
            selection.viewID = mainFeatureTypeChips[0].value;
            selection.style = snArray[0];
            doDebug(funcName+"main style set to "+selection.style);
        }
        if (featureTypeSelectors != null) {
          doDebug(funcName + "featureTypeSelectors.length=" + featureTypeSelectors.length);
        }       
        // if there are secondary feature type selectors
        if (featureTypeSelectors != null && featureTypeSelectors.length > 0) {
            for (i in sA[saKey]) {
            	if(typeof sA[saKey][i] == "object" && sA[saKey][i] instanceof Array){
	                for (j = sA[saKey][i].length - 1; j >= 0; j--) {
	                    if (compareArrays(sA[saKey][i][j].featureCode, selection.featureCodes) === true) {
	                        doDebug(funcName+"featureCodes in secondary feature data=" + selection.featureCodes);
	                        breakme = true;
	                        selection.style = i.split("-")[1];
	                        break;
	                    }
	                    if (breakme === true) break;
	                }
	                if (breakme === true) break;
                }
            }
        } 
        if (styleLabelChooser != null) {
          doDebug(funcName + "styleLabelChooser.length=" + styleLabelChooser.length);
        }    
        if (styleLabelChooser != null && styleLabelChips.length > 0) {
            var j;
            for (j = 0; j < styleLabelChips.length; j++) {
                if (styleLabelChips[j].checked) {
                    selection.style = styleLabelChips[j].value.split("-")[1];
                }
            }
        }
        if (selection.style == "")  {
        	doDebug(funcName+"no style found, fall back to first in array");
            for (i in sA[saKey]) {
              	// required because buyGridNum property was tacked onto the sA object
                if(typeof sA[saKey][i] == "object" && sA[saKey][i] instanceof Array){
                	selection.style = i.split("-")[1];
                	break;
                }
            }
        }
        thisSbg.getStyleNumberWithColorVariant();
        doDebug(funcName+"selection.style after getStyleNumberWithColorVariant() = " + selection.style);
        if ((dropShipDayPhoneEntry == null || dropShipDayPhoneEntry == undefined) && tagged === false && getQueryVariable("action") != "modify") {
            s_omtr.pageName = priceCode[selection.style] + '_PP_' + zeroPadDigits(selection.style) + '_' + trimAll(productName.replace(/\'/, ""));      
            tagged = true;
        }
        if (getQueryVariable("action") == "modify" && tagged === false) {
            s_omtr.pageName = priceCode[selection.style] + '_PP_' + zeroPadDigits(selection.style) + '_' + trimAll(productName.replace(/\'/, ""));   
            tagged = true;
        }
       	thisSbg.compareSelectionToSku();
       	thisSbg.buildRecap();
        styleArray = sA[saKey]["SN-" + selection.style];
        doDebug(funcName + "on exit, selection.style=" + selection.style);
        doDebug(funcName + "on exit, selection.colorCode=" + selection.colorCode);
        // if style change, then send the update event
        if(this.currentStyle != selection.style){
        	this.currentStyle = selection.style;
        	
        	var action = getQueryVariable("action");
        	if(! hasStyleSearchBeenProcessed && action != null && action.match(/DTP_SEARCH/)){
        		thisSbg.sendDirectStyleSearch();
        		hasStyleSearchBeenProcessed = true;
        	}else{
        		thisSbg.sendChangeStyleMetric();
        	}
        }
        return selection.style;
    };
   this.updateStyleLabelChooser = function() {
        var funcName = "[updateStyleLabelChooser] ";
        doDebug(funcName+"selection.style="+selection.style);       
        if (styleLabelChooser != null && styleLabelChips.length > 0) {
            var j;
            for (j = 0; j < styleLabelChips.length; j++) {
                var chipStyleNum = styleLabelChips[j].value.split("-")[1];
                if (chipStyleNum == selection.style) {
                    doDebug(funcName+"match found at position="+j);
                    styleLabelChips[j].checked = true;
                } else {
                    styleLabelChips[j].checked = false;
                }
            }
        }
   }
    /*/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
        Flip between the product summary and the product details.
    /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\*/
/*	this.flipProductSize = function() {
        hide(productDetails);
        hide(productSummary);
        show(productSize);
        sizeButton.className = css.sbg.tabDownParent;
		sizeButtonChild.className = css.sbg.tabDownChild;
        // depends on product details being available
        if (detailsButton != null) {
        	detailsButton.className = css.sbg.tabUpParent;
			detailsButtonChild.className = css.sbg.tabUpChild;
        }
        summaryButton.className = css.sbg.tabUpParent;
		summaryButtonChild.className = css.sbg.tabUpChild;
    };*/
    this.flipProductSummary = function() {
    //	hide(productSize);
        hide(productDetails);
        show(productSummary);
        summaryButton.className = css.sbg.tabDownParent;
		summaryButtonChild.className = css.sbg.tabDownChild;
        //sizeButton.className = css.sbg.tabUpParent;
	//	sizeButtonChild.className = css.sbg.tabUpChild;
        // depends on product details being available
        if (detailsButton != null) {
        	detailsButton.className = css.sbg.tabUpParent;
			detailsButtonChild.className = css.sbg.tabUpChild;
        }
    };
    this.flipProductDetails = function() {
    //	hide(productSize);
        hide(productSummary);
        show(productDetails);
        // depends on product details being available
	    if (detailsButton != null) {        
    	    detailsButton.className = css.sbg.tabDownParent;
			detailsButtonChild.className = css.sbg.tabDownChild;
    	}
    	//sizeButton.className = css.sbg.tabUpParent;
	//	sizeButtonChild.className = css.sbg.tabUpChild;    
        summaryButton.className = css.sbg.tabUpParent;
		summaryButtonChild.className = css.sbg.tabUpChild;
    };
    /*/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
        Popup processing.  Pretty standard stuff that implements LE_Popup.
    /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/*/
    this.callLEPopup = function(sid, link) {
        var popupURL;
        if (link != null) {
            popupURL = link;
        } else {
            popupURL = this.href;
        }
        LE_popup(popupURL);
        return false;
    };
    this.emailPopup = function() {
        var funcName = "[emailPopup] ";
        var styleKey = "SN-"+selection.style;
        var catalogNumber = sA[saKey].styleList[styleKey];
        var catStr = catalogNumber.displayStyleNumber+""+catalogNumber.mediaCode+catalogNumber.checkDigit;
        doDebug(funcName+catalogNumber.displayStyleNumber+":"+catalogNumber.mediaCode+":"+catalogNumber.checkDigit);
        var link = this.href;
        var repl = "styl_num="+catStr+"&";
        var resLink = link.replace(/styl_num=[^&]*&/,repl);
        doDebug(funcName+"resLink="+resLink);
        thisSbg.callLEPopup(theSid, resLink);
        return false;
    };
    this.tryItOnPopup = function() {
        dressModel(getCookie("SESSION_ID").split(",")[0], thisSbg.getStyleNumber(), selection.colorCode, genderCodeNum, countryCode);
        return false;
    };
    this.personalSizeSuggestionPopup = function() {
        OpenMVMFit(thisSbg.getStyleNumber(), genderCodes[num], countryCode);
        return false;
    };
    /*/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
        The buildX functions are used to build the interface and assign events
        to HTML elements.  These functions also check to see if something has been
        entered on the page.  If something has been entered, the data is processed
        into the selection object.
    /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\*/
	this.buildMainFeatureTypeSelector = function() {
	    var funcName = "[buildMainFeatureTypeSelector] ";
        if (mainFeatureTypeChips != null && mainFeatureTypeChips.length > 0) {
            var i;
            var mainFeatureTypeElements = mainFeatureTypeSelector.getElementsByTagName("span");
            for (i = 0; i < mainFeatureTypeChips.length; i++) {
                // var featNum = mainFeatureTypeChips[i].value.split("_")[2].replace(/.html/,"");
                mainFeatureTypeChips[i].onclick = thisSbg.mainFeatureTypeSelect;
                if (mainFeatureTypeChips[i].checked) {
                    mainFeatureLongText = mainFeatureTypeElements[(i*2)+1].innerHTML;
                    doDebug(funcName+"mainFeatureLongText="+mainFeatureLongText);
                    thisSbg.getStyleNumber();
                }
            }
        }
    };
    this.buildFeatureTypeSelector = function() {
        var funcName = "[buildFeatureTypeSelector] ";
        if (featureTypeChips !== null && featureTypeChips.length > 0) {
            var i;
            var f;
            for (f = 0; f < featureTypeSelectors.length; f++) {
	            var featureTypeElements = featureTypeSelectors[f].getElementsByTagName("span");
	            for (i = 0; i < featureTypeElements.length; i++) {
	            	doDebug(funcName+"i="+i+" "+featureTypeElements[i].id+" "+featureTypeElements[i].value+" "+featureTypeElements[i].innerHTML);
	            }
	            for (i = 0; i < featureTypeChips.length; i++) {
	                var featNum = featureTypeChips[i].value;
	                var featTxt;
	                if (featureTypeElements[((i*2)+1)] != undefined &&
	                    featureTypeElements[((i*2)+1)].innerHTML != undefined) {
		                featTxt = featureTypeElements[((i*2)+1)].innerHTML;
		                secondaryFeatureLongTextList[featNum] = featTxt;
		            }
	                if (featureTypeChips[i].checked) {
	                    secondaryFeatureLongText = featTxt;
	                    doDebug(funcName+"secondaryFeatureLongText="+secondaryFeatureLongText);
	                    thisSbg.checkFeatureSelection();
	                }
	                featureTypeChips[i].onclick = thisSbg.featureTypeSelect;
	            }
            }
        }
    };
    this.getStyleSecondaryFeatureList = function(styleNumber) {
        var funcName = "[getStyleSecondaryFeatureList] ";
        var styleKey = "SN-" + styleNumber;
        doDebug(funcName + "saKey="+saKey+" styleKey="+styleKey);
        var testSKU = sA[saKey][styleKey][0];
        doDebug(funcName+"testSKU.featureCode = " + testSKU.featureCode);
        return testSKU.featureCode;
    }
    this.checkFeatureSelection = function() {
        var funcName = "[checkFeatureSelection] ";
        var i;
        var j = 0;
        doDebug(funcName+"featureTypeChips.length="+featureTypeChips.length);
        for (i = 0; i < featureTypeChips.length; i++) {
            if (featureTypeChips[i].checked) {
                var featNum = featureTypeChips[i].value;
                selection.featureCodes[j] = featNum ;
                doDebug(funcName+"featureTypeChips[" + i + "].value: " + featureTypeChips[i].value);
                doDebug(funcName+"selection.featureCodes: " + selection.featureCodes.join(","));
                secondaryFeatureLongText = secondaryFeatureLongTextList[featNum];
                j++;
                thisSbg.getStyleNumber();
                thisSbg.checkColors();
            }
        }
       thisSbg.setFeatureSelection();
       thisSbg.checkFeatureTypeCombinationError();
    };
    this.setFeatureSelection = function() {
        var funcName = "[setFeatureSelection] ";
        var i;
        var j = 0;
        doDebug(funcName+"featureTypeChips.length="+featureTypeChips.length+" selection.featureCodes="+selection.featureCodes.join(","));
        if (selection.featureCodes.length == 0) {
            return;
        }
        for (i = 0; i < featureTypeChips.length; i++) {
            var radioValue = featureTypeChips[i].value;
            doDebug(funcName+"featureTypeChips["+i+"]"+" radioValue="+radioValue+" checked="+featureTypeChips[i].checked);
            featureTypeChips[i].checked = false;
            for (j = 0; j < selection.featureCodes.length; j++) {
	            if (selection.featureCodes[j] == radioValue) {
	                doDebug(funcName+"setting checked=true for radioValue="+radioValue);
	                featureTypeChips[i].checked = true;
	            }
            }
        }
    };
    // depends on color variation being available
    this.buildColorSelector = function() {
        if (colorSelector != null) {
    	    var i;
    	    var link;
        	for (i = 0; i < colorChips.length; i++) {
            	colorChips[i].onclick = thisSbg.colorSelect;
				// set up the link for accessibility
        		link = document.getElementById(colorChips[i].id + "_color_link");
        		if (link != null) {
        			link.onclick = thisSbg.colorSelect;
         		}
        	}
        }
	};
	// depends on alternative image setsn being available
    this.buildAltImageSelector = function() {
        var funcName = "buildAltImageSelector";
    	if (altImages != null) {
    		var i;
    		doDebug(funcName+"initializing the onclick function for "+ altImages.length+" alt images");
        	for (i = 0; i < altImages.length; i++) {
           		altImages[i].onclick = thisSbg.altImageSelect;
        	}
        }
	};
    // depends on size variation being available
    this.buildSizeChooser = function() {
		if (sizeDropdown != null) {
            sizeDropdown.onchange = thisSbg.sizeSelectFromDropdown;
        } else if (sizeChips != null) {
            var i;
            var link;
        	for (i = 0; i < sizeChips.length; i++) {
           	    sizeChips[i].onclick = thisSbg.sizeSelect;
				// set up the link for accessibility
        		link = document.getElementById(sizeChips[i].id + "_size_link");
        		if (link != null) {
        			link.onclick = thisSbg.sizeSelect;
         		}
        	}
        } 
	};
    // depends on size variation being available
    this.buildSecondarySizeChooser = function() {
		if (secondarySizeChooser != null) {
            var i;
            var link;
        	for (i = 0; i < secondarySizeChips.length; i++) {
           	    secondarySizeChips[i].onclick = thisSbg.secondarySizeSelect;
   				// set up the link for accessibility
        		link = document.getElementById(secondarySizeChips[i].id + "_size_link");
        		if (link != null) {
        			link.onclick = thisSbg.secondarySizeSelect;
         		}        	    
        	}
        } 
	};
	// this function hides the details of assigning a correct size code based
	// on events. this primarily is used to handle the case when we have split
	// the size code into multiple fields as is done for women's swimsuits with
	// dress size and cup size.
	this.getActualSizeCode = function() {
	    var funcName = "[getActualSizeCode] ";
	    var retVal = "";
	    doDebug(funcName+"num="+num+" selection.sizeCode1="+selection.sizeCode1+" selection.sizeCode2="+selection.sizeCode2);
	    doDebug(funcName+"sbgSecondarySizeRequired="+sbgSecondarySizeRequired[num]);
	    if (sbgSecondarySizeRequired[num]) {
	    	if (selection.sizeCode1 == undefined || selection.sizeCode2 == undefined) {
	    	    retVal = "";
	    	} else {
	    	    var arrKey = selection.sizeCode1 + "_" + selection.sizeCode2;
	    	    if (sizeCodeLookup[num][arrKey] != undefined) {
	    	        retVal = sizeCodeLookup[num][arrKey];
	    	    }
	    	}
	    } else {
	        retVal = selection.sizeCode;
	    }
	    doDebug(funcName+"retVal="+retVal);
	    return retVal;
	};
    this.buildStyleLabelChooser = function() {
        if (styleLabelChooser != null && styleLabelChips.length > 0) {
            var i;
            for (i = 0; i < styleLabelChips.length; i++) {
                styleLabelChips[i].onclick = thisSbg.styleLabelSelect;
            }
        }
    }
	// depends on gift boxing being available
	this.buildGiftBoxSelector = function() {
        if (giftBoxSelector != null) {
        	if (giftBoxSelector.checked) {
            	selection.giftBox = true;
                selection.giftBoxPrice = giftBoxPrice;
        	}
            giftBoxSelector.onclick = thisSbg.giftBoxSelect;
        }
	};
    // depends on monogramming being available
    this.buildMonogramSelector = function() {
        if (monogramSelector != null) {
        	if (monogramSelector.checked) {
            	selection.monogrammed = true;
        	}
        	monogramSelector.onclick = thisSbg.monogramSelect;
        }
    };
    this.buildQuantitySelector = function() {
        if (quantityAmounts != null) {
        	selection.quantity = quantityAmounts.selectedIndex + 1;
        	doDebug("[buildQuantitySelector] The current quantity selected is " + selection.quantity);
        	quantityAmounts.onchange = thisSbg.quantitySelect;
        }
    };
    this.buildShippingSelector = function() {
 		// collection buy grid difference
		if (shipToPeople == null) {
			return;
		}
        selection.shipTo = shipToArray[parseInt(shipToPeople.selectedIndex)];
        selection.shipToNickname = shipToPeople.options[parseInt(shipToPeople.selectedIndex)].text;
        doDebug("[buildShippingSelector] You are currently shipping to " + selection.shipTo);
        if (selection.shipTo == "-2") {
            show(nicknameEntry);
            if (nicknameEntryBox.value !== "" && nicknameEntryBox.value.length <= 16) {
                selection.shipToNickname = nicknameEntryBox.value;
            }
            doDebug("[buildShippingSelector] You are shipping to: " + selection.shipToNickname);
        } else {
            hide(nicknameEntry);
        }
        nicknameEntryBox.onkeyup = thisSbg.checkNicknameChars;
        shipToPeople.onchange = thisSbg.shipToSelect;
    };
    this.buildPhoneEntry = function() {
        var i;
        if (dropShipDayPhoneEntry != null && dropShipDayPhoneEntry != undefined) {
            for (i = 0; i < dropShipDayPhoneEntry.length; i++) {
                dropShipDayPhoneEntry[i].onblur = thisSbg.phoneSelect;
                dropShipDayPhoneEntry[i].onchange = thisSbg.phoneSelect;
            }
            for (i = 0; i < dropShipAltPhoneEntry.length; i++) {
                dropShipAltPhoneEntry[i].onblur = thisSbg.phoneSelect;
                dropShipAltPhoneEntry[i].onchange = thisSbg.phoneSelect;
            }
        }
    };
 	this.removeItemFromPurchaseSelect = function(){
 		selection.removeItemFromPurchase = this.checked; 
 	};
 	this.checkNicknameChars = function(){
 		if(thisSbg.isNicknameCharsValid() == false) {
 			showErrorPopup(messages.error[37].getMessageText(true));
	        document.getElementById("nicknameHeader_prd_" + num).getElementsByTagName("span")[0].className += " errorHiLight";
	        shipQuantityErrorContainer.innerHTML = messages.error[37].getMessageText();  
	        show(shipQuantityErrorContainer);    
 			doDebug('error');
 		} else {
        	document.getElementById("nicknameHeader_prd_" + num).getElementsByTagName("span")[0].className = document.getElementById("nicknameHeader_prd_" + num).getElementsByTagName("span")[0].className.replace(" errorHiLight", "");
        	hide(shipQuantityErrorContainer);
 			doDebug('good');
 		}
 	};
 	this.isNicknameCharsValid = function(){
 		var invalidReg = /[<>\"'%;\(\)&+:=\|]/;
 		if(nicknameEntryBox.value.match(invalidReg)) {
 			return false;
 		} else {
        	return true;
 		}
 	};
    /*/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
        The following functions handle the creation of the selection object.  Most are
        self-explanatory.  The tricky ones have been commented.
    /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/*/
    /*===================================================================================
        When a style is selected, check to see if color, size, and VAS selections have
        occurred.  If not, reload a new page with new information.  If so, asynchronously
        load a new image viewer, product grid with selections maintained, and GGTs (if no
        GGTs have been expanded).
    ===================================================================================*/
    this.mainFeatureTypeSelect = function() {
        var funcName = "[mainFeatureTypeSelect] ";
        doDebug(funcName+"saKey="+saKey+" page type="+pageTypes[sAIndex]);
        // only pull in a buy grid if we are NOT looking at a LE Custom page.
        if (pageTypes[sAIndex] != PAGE_TYPE_LE_CUSTOM) {
            currentlySelectedFit['T' + sA[saKey].productNumber] = this.value;
        	flipBuyGrids(this.value,num,thisSbg,saKey); 
        } else {
            doDebug(funcName+"custom page, so redirect");
	        if (selection.updated === true) {
	            var rememberSelection = buildQueryStringFromSelection(selection, num);
	            if (getQueryVariable("action") != null) {
	                rememberSelection += "&action=" + getQueryVariable("action");
	            }
	            if (getQueryVariable("itemId") != null) {
	                rememberSelection += "&itemId=" + getQueryVariable("itemId");
	            }
	            if (getQueryVariable("CM_MERCH") != null) {
	                rememberSelection += "&CM_MERCH=" + getQueryVariable("CM_MERCH");
	            }
	            window.location.href = this.value + rememberSelection;
	        } else if (selection.updated === false) {
	            var qs = window.location.search;
	            doDebug(funcName+"this.value="+this.value+" qs="+qs);
	            window.location.href = this.value + qs;
	        }
	        hide(mainFeatureTypeErrorContainer);
        }
    };
    this.featureTypeSelect = function() {
        var funcName = "[featureTypeSelect]";
        doDebug(funcName+"entering");
        thisSbg.checkFeatureSelection();
        thisSbg.updateItemNumber();
        thisSbg.compareSelectionToSku();
        if (thisSbg.pantsHemmingSelector != null) {
    		thisSbg.pantsHemmingSelector.selectHemmingType();
    	}
        thisSbg.checkColors();
        thisSbg.buildRecap();
        doDebug(funcName+"You chose " + selection.style);
        hide(featureTypeErrorContainer);
    };
    this.styleLabelSelect = function() {
        thisSbg.getStyleNumber();
        thisSbg.updateItemNumber();
        thisSbg.checkColors();
    };
    this.updateItemNumber = function() {
        if (selection.styleValidState) {
	        if (selection.sku.mediaCode != null && selection.sku.mediaCode != undefined && selection.sku.mediaCode != "") {
	            itemCode.innerHTML = buildItemNumber(selection.style, selection.sku.mediaCode, selection.sku.checkDigit);
	        } else {
	            itemCode.innerHTML = buildItemNumber(selection.style, sA[saKey]["SN-" + selection.style][0].mediaCode, sA[saKey]["SN-" + selection.style][0].checkDigit);
	        }
        }
    };
    this.checkFeatureTypeCombinationError = function() {
        if (selection.styleValidState) {
           thisSbg.updateFeatureTypeCombinationErrorDisplay(false);
        } else {
            thisSbg.updateFeatureTypeCombinationErrorDisplay(true);
        }
    }
	this.updateAltImageViews = function (currentRelLoc, newRelLoc) {
	  var funcName = "[updateAltImageViews] ";
	  if (currentRelLoc == newRelLoc) {
	    return currentRelLoc;
	  }
	  doDebug(funcName+" "+currentRelLoc+" being set to altImagesOff");
	  doDebug(funcName+" "+newRelLoc+" being set to newRelLoc");
	  altImageSetCollection[currentRelLoc].className = "altImagesOff";
	  altImageSetCollection[newRelLoc].className = "altImages";
	  return newRelLoc;
	}
    this.updateViewerColor = function (clrCode) {
        var funcName = "[updateViewerColor] ";
        doDebug(funcName + "entering " + sAIndex +" "+selection.style + " " + clrCode);
        var newImageSetCollectionRelLoc = getImageSetCollectionForStyle(selection.style);
    	var imageSetCollectionRelLoc = sbgImageSets[sAIndex].currentRelativeImageSetLoc;
        var imageSet = sbgImageSets[sAIndex].imageSetCollectionList[imageSetCollectionRelLoc].getImageSetById(sbgImageSets[sAIndex].imageSetCollectionList[imageSetCollectionRelLoc].currentImageSetId);
        var imageName = imageSet.getColorImage(clrCode);
        var imageChanged = false;
        if (altImagesSelector != null && legacyImage === null) {
            doDebug(funcName +"imageSetCollectionRelLoc="+imageSetCollectionRelLoc+" newImageSetCollectionRelLoc="+newImageSetCollectionRelLoc);
	        imageSetCollectionRelLoc = thisSbg.updateAltImageViews(imageSetCollectionRelLoc, newImageSetCollectionRelLoc);
	        sbgImageSets[sAIndex].currentRelativeImageSetLoc = imageSetCollectionRelLoc;
        }
        if (imageName == null) {
        	imageSet = sbgImageSets[sAIndex].imageSetCollectionList[imageSetCollectionRelLoc].getImageSetByColor(clrCode);
        	if (imageSet != null) {
        		imageName = imageSet.getColorImage(clrCode);
        		imageChanged = true;
        	}
        }
        if (altImagesSelector != null && legacyImage === null) {
			doDebug(funcName +"current imageset id " + sbgImageSets[sAIndex].imageSetCollectionList[imageSetCollectionRelLoc].currentImageSetId);
            if (imageName != null) {
            	if (pViewers[sAIndex]) {
	                pViewers[sAIndex].changeImage(imageName, imageSet.width, imageSet.height);
	                if (imageChanged) {
	                	pViewers[sAIndex].reset();
	                }
	                for (i = 0; i < altImages.length; i++) {
	           			altImages[i].parentNode.className=css.sbg.altProductImageUnselected;
	        		}
	        		var selectedAltImage = document.getElementById(imageSet.imageSetId);
	        		selectedAltImage.parentNode.className=css.sbg.altProductImageSelected;
	        	}
            } else { 
            	pViewers[sAIndex].showColorAlert(sA[saKey].colors[clrCode]);
            }
        } else if (legacyImage && imageName != null) {
        	// set the prev. img src so that the onerror code can use it if needed.
        	legacyImage.prevSrc = legacyImage.src;
        	legacyImage.src=imageName+"?hei="+legacyImage.height;
        }
        var i;
        var loopLen = sbgImageSets[sAIndex].imageSetCollectionList[imageSetCollectionRelLoc].imageSetList.length;
        doDebug(funcName+"loopLen="+loopLen+" sAIndex="+sAIndex+" "+clrCode);
        doDebug(funcName+"imageSetCollectionRelLoc="+imageSetCollectionRelLoc);
        for (i=0; i<loopLen; i++) {
        	imageName = sbgImageSets[sAIndex].imageSetCollectionList[imageSetCollectionRelLoc].imageSetList[i].getColorImage(clrCode);
        	doDebug(funcName+"imageName="+imageName);
        	if (imageName !== null) {
        		var altImageThumb = document.getElementById(sbgImageSets[sAIndex].imageSetCollectionList[imageSetCollectionRelLoc].imageSetList[i].imageSetId);
        		if (altImageThumb != null) {
        		    doDebug(funcName+"altImageThumb.id="+altImageThumb.id);
        			altImageThumb.src = imageName+"?$viewerThumb$&amp;crop=0,0,0,0";
	        		if (i == sbgImageSets[sAIndex].imageSetCollectionList[imageSetCollectionRelLoc].imageSetList.length - 1) {
	        			altImageThumb.alt = sA[saKey].colors[clrCode];
	        			altImageThumb.title = sA[saKey].colors[clrCode];
	        		}
        		}
        	}
        } 
    };
    this.colorSelect = function() {
        var i;
        selection.colorCode = this.id.split("_")[0];
        doDebug("[colorSelect] You clicked on " + selection.colorCode);     
        for (i = 0; i < colorChips.length; i++) {
            colorChips[i].parentNode.parentNode.className = css.sbg.colorNotSelected;
        }
        thisSbg.getStyleNumber();
		doDebug("[colorSelect] style number = " + selection.style);
        thisSbg.updateViewerColor(selection.colorCode);
        colorRecap.innerHTML = sA[saKey].colors[selection.colorCode];
        hide(colorSelectorErrorContainer);
        thisSbg.compareSelectionToSku();
        thisSbg.checkSizes();
        thisSbg.checkColors();
        thisSbg.checkFeatureTypeCombinationError();
		thisSbg.updateItemNumber();
        if (selection.sku.inventoryStatus == "N" || (thisSbg.pantsHemmingSelector == null && selection.sizeCode != "" && thisSbg.compareSelectionToSku() == false)) {
            this.parentNode.parentNode.className = css.sbg.colorSelectedNotAvailable;
        } else if (selection.sku.inventoryStatus == "B") {
            this.parentNode.parentNode.className = css.sbg.colorSelectedBackOrdered;
        } else {
            this.parentNode.parentNode.className = css.sbg.colorSelected;
        }
        thisSbg.buildRecap();
        selection.updated = true;
		if (document.getElementById("sizeChoice_prd_" + num) != null) {
        	document.getElementById("colorChoice_prd_" + num).getElementsByTagName("span")[0].className = document.getElementById("sizeChoice_prd_" + num).getElementsByTagName("span")[0].className.replace(" errorHiLight", "");
        }
        return false;
    };
    // this method will scan the currently selected list of skus looking for a 
    // match of the color code. if one is found it will assign selection.style
    // appropriate for that color code. this is needed because we now have the
    // style number varying by color selection.
    // this method returns TRUE if selection.style has been left in a valid
    // state.
    this.getStyleNumberWithColorVariant = function() {
      var funcName = "[getStyleNumberWithColorVariant] ";
      doDebug("========================================================================");
      doDebug(funcName + "selection.viewID = " + selection.viewID);
      doDebug(funcName + "selection.style = " + selection.style);
      doDebug(funcName + "selection.colorCode = " + selection.colorCode);
      doDebug(funcName + "selection.featureCodes = " + selection.featureCodes);
      doDebug(funcName + "snArray.length=" + snArray.length);
      doDebug(funcName + "saKey " + saKey);
      selection.styleValidState = true;
      // if we only have 1 style on this page, do nothing.
      if (snArray.length <= 1) {
      	return true;
      }
      // if this is the duffel bag type page we don't perform a color change test
      if (pageTypes[sAIndex] == 4) {
        return true;
      }
      // if we have no color selection, do nothing.
      if (selection.colorCode == null || selection.colorCode == "") {
        return true;
      }
      // if we are certain this page has no colorway variations, just return
      if (hasMultiColorWay[sAIndex] == false) {
        return true;
      }
      // because you can now have style numbers vary by color code thanks to
      // the perfect suit project we have to perform this nested loop where
      // for the buy grid number we are currently working on we scan the
      // sku list looking for a color code match. then assign the style
      // number based on that sku
	  // doDebug(funcName + " sA[saKey].length =" + sA[saKey].length);
	  for (i = 0; i < snArray.length; i++) {
	    var subKey = "SN-" + snArray[i];
	    var skuLen = sA[saKey][subKey].length;
	    // doDebug(funcName + " subKey " + subKey + " " + skuLen);
	    for (j = 0; j < skuLen; j++) {
	      var sku = sA[saKey][subKey][j];
	      doDebug(funcName + " sku["+j+"]="+sku.sizeCode+" "+sku.colorCode+" "+sku.displayStyleNumber+" "+sku.featureCode);
	      // if there are multiple feature selections that have been made on this page we
	      // have to find only skus that have the same feature code values, otherwise we may get
	      // the wrong style number returned if multiple styles on the page have the same color codes
	      if (compareArrays(sku.featureCode, selection.featureCodes) === true) {
		      if (selection.colorCode == sku.colorCode) {
		        doDebug(funcName + " color code match found at style number "+sku.displayStyleNumber);
		        selection.style = sku.displayStyleNumber;
		        return true;
		      }
	      }
	    }
	  }
	  doDebug(funcName+"WARNING: selection.style has been left in an invalid state");
	  selection.styleValidState = false;
	  return false;
    };
    this.altImageSelect = function() {
    	var imageSetCollectionRelLoc = sbgImageSets[sAIndex].currentRelativeImageSetLoc;
        sbgImageSets[sAIndex].imageSetCollectionList[imageSetCollectionRelLoc].currentImageSetId = this.id;
        for (i = 0; i < altImages.length; i++) {
            altImages[i].parentNode.className=css.sbg.altProductImageUnselected;
        }
        this.parentNode.className=css.sbg.altProductImageSelected;
        doDebug("[altImageSelect] You clicked on " + sbgImageSets[sAIndex].imageSetCollectionList[imageSetCollectionRelLoc].currentImageSetId +":"+ selection.colorCode);
        var imageSet = sbgImageSets[sAIndex].imageSetCollectionList[imageSetCollectionRelLoc].getImageSetById(sbgImageSets[sAIndex].imageSetCollectionList[imageSetCollectionRelLoc].currentImageSetId);
        var imageName = imageSet.getColorImage(selection.colorCode);
        if (legacyImage) {
            if (imageName == null) {
                legacyImage.src=imageSet.colorImages[0].imageName+"?hei="+legacyImage.height;
            } else {
                legacyImage.src=imageName+"?hei="+legacyImage.height;
            }
            return;
        } 
		try {
	        if (imageName != null) {
	            pViewers[sAIndex].changeImage(imageName, imageSet.width, imageSet.height);
	        } else {
	            doDebug("couldn't find image in:"+ selection.colorCode+" using: "+imageSet.colorImages[0].imageName+" "+imageSet.width+"X"+imageSet.width);
	            pViewers[sAIndex].changeImage(imageSet.colorImages[0].imageName, imageSet.width, imageSet.height);
	            pViewers[sAIndex].showColorAlert(sA[saKey].colors[selection.colorCode]);
	        }      
	        pViewers[sAIndex].reset();
	        if (imageSet.zoomRegion) {
	            pViewers[sAIndex].setRGNA(imageSet.zoomRegion);
	        }
	    } catch(e) {
	    	doDebug("exception caught"+e+"no image viewer?");
	    }
    };
    this.checkSizes = function() {
        var funcName = "[checkSizes] ";
        var h;
        var i;
        doDebug(funcName+"selection.colorCode="+selection.colorCode+" selection.sizeCode="+selection.sizeCode+" selection.sizeCode1="+selection.sizeCode1+" selection.sizeCode2="+selection.sizeCode2);
        // Clears the old markers without losing the selection
        // depends on size variation being available
        for (h = 0; sizeChips != null && h < sizeChips.length; h++) {
            if (sizeChips[h].parentNode.id.split("_")[1].replace(/-/, " ").toUpperCase() != selection.sizeCode) {
                sizeChips[h].parentNode.className = css.sbg.sizeSelectedAvailable;
            }
        }
        if (sbgSecondarySizeRequired[num] == true) {
            var sizeInvStat = thisSbg.getSize1StatusList();
            doDebug(funcName+"sizeInvStat.length="+sizeInvStat.length);
            for (i = 0; i < sizeChips.length; i++) {
                var j;
                var sizeEle = sizeChips[i].parentNode;
                var chipSizeCode = sizeEle.id.split("_")[1].replace(/-/, " ").toUpperCase();
                var isSelected = false;
                if (chipSizeCode == selection.sizeCode1) {
                  isSelected = true;
                } 
                for (j = 0; j < sizeInvStat.length; j++) {
                    if (chipSizeCode == sizeInvStat[j].getSizeCode()) {
                        if (sizeInvStat[j].getStatus() == "A") {
                            sizeEle.className = (isSelected) ? css.sbg.sizeSelected : css.sbg.sizeNotSelected;
                        } else if (sizeInvStat[j].getStatus() == "B") {
                            sizeEle.className = (isSelected) ? css.sbg.sizeSelectedBackOrdered : css.sbg.sizeNotSelectedBackOrdered;
                        } else {
                            sizeEle.className = (isSelected) ? css.sbg.sizeSelectedNotAvailable : css.sbg.sizeNotSelectedNotAvailable;
                        }
                    }
                }
            }
        } else {
	        // check the styleArray where color = selected color
	        // if a size not available in that color, gray it out
	        for (i = 0; i < styleArray.length; i++) {
	            if (styleArray[i].colorCode == selection.colorCode) {
	                var j;
	                for (j = 0; sizeChips != null && j < sizeChips.length; j++) {
	                    if (styleArray[i].sizeCode == sizeChips[j].parentNode.id.split("_")[1].replace(/-/g, " ").toUpperCase() && (!styleArray[i].inventoryStatus || styleArray[i].inventoryStatus == "N")) {// && sizeChips[j].parentNode.className != css.sbg.sizeSelectedNotAvailable) {
	                        sizeChips[j].parentNode.className = css.sbg.sizeNotSelectedNotAvailable;
	                    }
	                    if (styleArray[i].sizeCode == sizeChips[j].parentNode.id.split("_")[1].replace(/-/g, " ").toUpperCase() && styleArray[i].inventoryStatus == "B") {// && sizeChips[j].parentNode.className != css.sbg.sizeSelectedBackOrdered) {
	                        sizeChips[j].parentNode.className = css.sbg.sizeNotSelectedBackOrdered;
	                    }
	                    if (styleArray[i].sizeCode == sizeChips[j].parentNode.id.split("_")[1].replace(/-/g, " ").toUpperCase() && styleArray[i].inventoryStatus == "A") { // && sizeChips[j].parentNode.className == css.sbg.sizeNotSelectedBackOrdered) {
	                        sizeChips[j].parentNode.className = css.sbg.sizeNotSelected;
	                    }
	                    if (sizeChips[j].parentNode.id.split("_")[1].replace(/-/g, " ").toUpperCase() == selection.sizeCode && selection.sku.inventoryStatus == "B") {
	                        sizeChips[j].parentNode.className = css.sbg.sizeSelectedBackOrdered;
	                    } else if (sizeChips[j].parentNode.id.split("_")[1].replace(/-/g, " ").toUpperCase() == selection.sizeCode && selection.sku.inventoryStatus == "N") {
	                        sizeChips[j].parentNode.className = css.sbg.sizeSelectedNotAvailable;
	                    } else if (sizeChips[j].parentNode.id.split("_")[1].replace(/-/g, " ").toUpperCase() == selection.sizeCode && selection.sku.inventoryStatus == "A") {
	                        sizeChips[j].parentNode.className = css.sbg.sizeSelected;
	                    }
	                }
	            }
	        }
	    }
	    thisSbg.updateStyleLabelChooser();
        thisSbg.setSecondarySizeChips();
    };
    this.updateSecondarySizeRecap = function() {
        var funcName = "[updateSecondarySizeRecap] ";
        if (secondarySizeRecap != null) {
            if (selection.sizeCode2 != undefined && selection.sizeCode2 != null) {
                doDebug(funcName+"setting to "+selection.sizeCode2);
                secondarySizeRecap.innerHTML = selection.sizeCode2;
            }
        }
    }
    this.sizeSelect = function() {
        var i;
        var selectedSize = this.parentNode.id.split("_")[1].replace(/-/g, " ").toUpperCase();
        var recapString = selectedSize;
        if (sizeAssoc[selectedSize] != undefined) {
            recapString = sizeAssoc[selectedSize];
        }
        doDebug("[sizeSelect] You clicked on " + selectedSize);
        selection.sizeCode = selectedSize;
        if (sbgSecondarySizeRequired[num] == true) {
            selection.sizeCode1 = selectedSize;
        }
        selection.sizeCode = thisSbg.getActualSizeCode();
        for (i = 0; i < sizeChips.length; i++) {
            sizeChips[i].parentNode.className = css.sbg.sizeNotSelected;
        }
        //sizeRecap.innerHTML = sA[saKey].sizes[selection.sizeCode];
        sizeRecap.innerHTML = recapString;
        thisSbg.updateSecondarySizeRecap();
        hide(sizeSelectorErrorContainer);
        thisSbg.compareSelectionToSku();
        thisSbg.checkColors();
        thisSbg.checkSizes();
        if (!selection.sku.inventoryStatus || selection.sku.inventoryStatus == "N") {
            this.parentNode.className = css.sbg.sizeSelectedNotAvailable;
        } else if (selection.sku.inventoryStatus == "B") {
            this.parentNode.className = css.sbg.sizeSelectedBackOrdered;
        } else {
            this.parentNode.className = css.sbg.sizeSelected;
        }
        thisSbg.buildRecap();
        selection.updated = true;
        if (document.getElementById("sizeChoice_prd_" + num) != null) {
            document.getElementById("sizeChoice_prd_" + num).getElementsByTagName("span")[0].className = document.getElementById("sizeChoice_prd_" + num).getElementsByTagName("span")[0].className.replace(" errorHiLight", "");
        }
    };
    this.setSecondarySizeChips = function() {
        var funcName = "[setSecondarySizeChips] ";
        var chipEle;
        if (sbgSecondarySizeRequired[num] == false) {
            return;
        }
        doDebug(funcName+"selection.sizeCode="+selection.sizeCode+" selection.sizeCode1="+selection.sizeCode1+" selection.sizeCode2="+selection.sizeCode2);
        doDebug(funcName+"selection.sku.inventoryStatus="+selection.sku.inventoryStatus);
        var sizeInvStat = thisSbg.getSize2StatusList();
        doDebug(funcName+"sizeInvStat.length="+sizeInvStat.length);
        for (i = 0; i < secondarySizeChips.length; i++) {
            var j;
            var chipSize = secondarySizeChips[i].id.split("_")[3];
            for (j = 0; j < sizeInvStat.length; j++) {
            	if (chipSize == sizeInvStat[j].getSizeCode()) {
	                var isSelected = false;
	                if (selection.sizeCode2 == sizeInvStat[j].getSizeCode()) {
	                    isSelected = true;
	                }
	                doDebug(funcName+"chipSize="+chipSize+" invStatus="+sizeInvStat[j].getStatus()+" isSelected="+isSelected);
	                if (sizeInvStat[j].getStatus() == "A") {
	                    if (isSelected == true) {
	                    	secondarySizeChips[i].className = css.sbg.sizeSelected;
	                    } else {
	                    	secondarySizeChips[i].className = css.sbg.sizeNotSelected;
	                    }
	                } else if (sizeInvStat[j].getStatus() == "B") {
	                    if (isSelected == true) {
	                    	secondarySizeChips[i].className = css.sbg.sizeSelectedBackOrdered;
	                    } else {
	                    	secondarySizeChips[i].className = css.sbg.sizeNotSelectedBackOrdered;
	                    }
	                } else {
	                    if (isSelected == true) {
	                    	secondarySizeChips[i].className = css.sbg.sizeSelectedNotAvailable;
	                    } else {
	                    	secondarySizeChips[i].className = css.sbg.sizeNotSelectedNotAvailable;
	                    }
	                }
	            }
            }
        }
        //thisSbg.checkSizes();
    }
    this.secondarySizeSelect = function() {
        var i;
        var funcName = "[secondarySizeSelect] ";
        selection.sizeCode2 = this.id.split("_")[3];
        doDebug(funcName + "You clicked on " + selection.sizeCode2);
        selection.sizeCode = thisSbg.getActualSizeCode();
        thisSbg.updateSecondarySizeRecap();
        hide(sizeSelectorErrorContainer);
        thisSbg.compareSelectionToSku();
        thisSbg.checkColors();
        thisSbg.checkSizes();
        thisSbg.setSecondarySizeChips();
        thisSbg.buildRecap();
        hide(secondarySizeSelectorErrorContainer);
        selection.updated = true;
    };
    this.sizeSelectFromDropdown = function() {
        var funcName = "[sizeSelectFromDropdown] ";
        doDebug(funcName+"num="+num+" sbgSecondarySizeRequired="+sbgSecondarySizeRequired[num]);
        var selectedSize = sizeDropdown.options[sizeDropdown.selectedIndex].value;
        //selection.sizeCode = "";
        if (sbgSecondarySizeRequired[num] == true) {
            selection.sizeCode1 = selectedSize;
            selection.sizeCode = thisSbg.getActualSizeCode();
        } else {
            selection.sizeCode = selectedSize;
            selection.sizeCode = thisSbg.getActualSizeCode();
        }
        if (selection.sizeCode != null && selection.sizeCode != undefined && selection.sizeCode != "") {
            doDebug(funcName + "You clicked on " + selection.sizeCode);
            hide(sizeSelectorErrorContainer);
            thisSbg.compareSelectionToSku();
            thisSbg.buildRecap();
            thisSbg.checkColors();
            selection.updated = true;
            document.getElementById("sizeChoice_prd_" + num).getElementsByTagName("span")[0].className = document.getElementById("sizeChoice_prd_" + num).getElementsByTagName("span")[0].className.replace(" errorHiLight", "");
        }
    };
    this.checkColors = function() {
        var funcName = "[checkColors] ";
        var h;
        var i;
        for (h = 0; colorChips != null && h < colorChips.length; h++) {
            if (colorChips[h].id.split("_")[0] != selection.colorCode) {
                colorChips[h].parentNode.parentNode.className = css.sbg.colorSelectedAvailable;
            }
        }
        // if we don't have the case where the size code has been split into
        // two different fields.
        if (sbgSecondarySizeRequired[num] == false) {
	        for (i = 0; i < styleArray.length; i++) {
	            if (styleArray[i].sizeCode == selection.sizeCode) {
	                var j;
	                for (j = 0; colorChips != null && j < colorChips.length; j++) {
	                    if (styleArray[i].colorCode == colorChips[j].id.split("_")[0] && ((selection.sizeCode != "" && thisSbg.compareSelectionToSku() == false) || styleArray[i].inventoryStatus == "N")) {// && colorChips[j].parentNode.parentNode.className != css.sbg.colorSelectedNotAvailable) {
	                        colorChips[j].parentNode.parentNode.className = css.sbg.colorNotSelectedNotAvailable;
	                    }
	                    if (styleArray[i].colorCode == colorChips[j].id.split("_")[0] && styleArray[i].inventoryStatus == "B") {// && colorChips[j].parentNode.parentNode.className != css.sbg.colorSelectedBackOrdered) {
	                        colorChips[j].parentNode.parentNode.className = css.sbg.colorNotSelectedBackOrdered;
	                    }
	                    if (styleArray[i].colorCode == colorChips[j].id.split("_")[0] && styleArray[i].inventoryStatus == "A") {// && colorChips[j].parentNode.parentNode.className == css.sbg.colorNotSelectedBackOrdered) {
	                        colorChips[j].parentNode.parentNode.className = css.sbg.colorNotSelected;
	                    }
	                    if (selection.sku.inventoryStatus == styleArray[i].inventoryStatus && selection.colorCode == selection.sku.colorCode) {
	                        if (colorChips[j].id.split("_")[0] == selection.sku.colorCode && (selection.sku.inventoryStatus == "B")) { //|| styleArray[i].inventoryStatus == "B")) {
	                            colorChips[j].parentNode.parentNode.className = css.sbg.colorSelectedBackOrdered;
	                        } else if (colorChips[j].id.split("_")[0] == selection.sku.colorCode && (selection.sku.inventoryStatus == "N")) { //|| styleArray[i].inventoryStatus == "N")) {
	                            colorChips[j].parentNode.parentNode.className = css.sbg.colorSelectedNotAvailable;
	                        } else if (colorChips[j].id.split("_")[0] == selection.sku.colorCode && (selection.sku.inventoryStatus == "A")) { //|| styleArray[i].inventoryStatus == "A")) {
	                            colorChips[j].parentNode.parentNode.className = css.sbg.colorSelected;
	                        }
	                    }
	                }
	            }
	        }
	    } else {  // if we have the case where the size code is split.
  		    var colorStatArray = thisSbg.getColorStatusList();
  		    var j;
  		    for (j = 0; j < colorChips != null && j < colorChips.length; j++) {
  		        var k;
  		        for (k = 0; k < colorStatArray.length; k++) {
  		            var chipColorCode = colorChips[j].id.split("_")[0];
  		            if (chipColorCode == colorStatArray[k].colorCode) {
  		                var thisColorSelected = false;
  		                if (chipColorCode == selection.colorCode) {
  		                    thisColorSelected = true;
  		                }
  		                doDebug(funcName+"updated highlighting of color " + chipColorCode+ " thisColorSelected="+thisColorSelected+" invStatus="+colorStatArray[k].invStatus);
  		                if (colorStatArray[k].invStatus == "A") {
  		                    if (thisColorSelected) {
  		                        colorChips[j].parentNode.parentNode.className = css.sbg.colorSelected;
  		                    } else {
  		                        colorChips[j].parentNode.parentNode.className = css.sbg.colorNotSelected;
  		                    }
  		                } else if (colorStatArray[k].invStatus == "B") {
  		                    if (thisColorSelected) {
  		                        colorChips[j].parentNode.parentNode.className = css.sbg.colorSelectedBackOrdered;
  		                    } else {
  		                        colorChips[j].parentNode.parentNode.className = css.sbg.colorNotSelectedBackOrdered;
  		                    }
  		                } else {
  		                    if (thisColorSelected) {
  		                        colorChips[j].parentNode.parentNode.className = css.sbg.colorSelectedNotAvailable;
  		                    } else {
  		                        colorChips[j].parentNode.parentNode.className = css.sbg.colorNotSelectedNotAvailable;
  		                    }
  		                }
  		            }
  		        }
  		    }
	    }
    };
    this.giftBoxSelect = function() {
        if (this.checked) {
            selection.giftBox = true;
            selection.giftBoxPrice = giftBoxPrice;
            doDebug("[giftBoxSelect] Gift boxing has been checked.");
        } else if (!this.checked) {
            selection.giftBox = false;
            selection.giftBoxPrice = 0;
            doDebug("[giftBoxSelect] Gift boxing has been unchecked.");
        }
        thisSbg.compareSelectionToSku();
        thisSbg.buildRecap();
        selection.updated = true;
    };
    this.monogramSelect = function() {
        if (this.checked) {
            selection.monogrammed = true;
            doDebug("[monogramSelect] Monogramming has been checked.");
            monogramIt = new monogram(num,thisSbg,selection.sku.monoThreadColorCode);
            thisSbg.monogramIt = monogramIt;
            selection.monogram = monogramIt.selection;
        } else if (!this.checked) {
            selection.monogrammed = false;
            if (monogramIt.removeMonogram) {
                monogramIt.removeMonogram();
            }
            doDebug("[monogramSelect] Monogramming has been unchecked.");
            selection.monogram.price = 0;
            monogramIt = null;
            thisSbg.monogramIt = null;
        }
        thisSbg.compareSelectionToSku();
        thisSbg.buildRecap();
        selection.updated = true;
    };
    /*==============================================================================
        The monogram function is running asynchronously, so we can't get the price
        until the monogram is applied.  This is a callback from the monogram object.
    ==============================================================================*/
    this.setMonogramPrice = function() {
        selection.monogram = monogramIt.selection;
        thisSbg.compareSelectionToSku();
        thisSbg.buildRecap();
        selection.updated = true;
        doDebug("[setMonogramPrice] Monogram Price: " + selection.monogram.price);
    };
    this.quantitySelect = function() {
        selection.quantity = this.selectedIndex + 1;
        doDebug("[quantitySelect] You have selected " + selection.quantity + " item(s)");
        thisSbg.compareSelectionToSku();
        thisSbg.buildRecap();
        selection.updated = true;
    };
    this.shipToSelect = function() {
    	for (var i = 0; i < shipToArray.length; i++) {
    		doDebug("[shipToSelect] shipToArray[" + i + "] = " + shipToArray[i]);
    	}
        selection.shipTo = shipToPeople.options[parseInt(this.selectedIndex)].value;
        selection.shipToNickname = shipToPeople.options[parseInt(this.selectedIndex)].text;
        doDebug("[shipToSelect] You will ship to " + selection.shipTo);
        // add nickname
        if (selection.shipTo == "-2") {
        	selection.shipToNickname = "";
        	nicknameEntry.value="";
            show(nicknameEntry);
            doDebug("[shipToSelect] You will need to add a nickname.");
        } else {
            hide(nicknameEntry);
        }
        thisSbg.compareSelectionToSku();
        selection.updated = true;
    };
    this.addNickname = function() {
        if (this.value.length <= 16) {
            selection.shipToNickname = this.value;
            doDebug("[addNickname] You entered " + selection.shipToNickname + " as a nickname");
            hide(shipQuantityErrorContainer);
            if(multiItemShippingSelector == null){
            	document.getElementById("nicknameHeader_prd_" + num).getElementsByTagName("span")[0].className = document.getElementById("nicknameHeader_prd_" + num).getElementsByTagName("span")[0].className.replace(" errorHiLight", "");
        	}
        	else{
        		document.getElementById("nicknameHeader").getElementsByTagName("span")[0].className = document.getElementById("nicknameHeader").getElementsByTagName("span")[0].className.replace(" errorHiLight", "");
        	}
        } else {
            this.focus();
            this.select();
        }
    };
    this.isNicknameDuplicate = function() {
    	// if we are not entering a new nickname then the nickname cannot be a duplicate.
    	if (selection.shipTo != "-2") {
    		return false;
    	}
        for (var i = 0; i < customerInfo.addressList.length; i++) {
            if (trim(selection.shipToNickname.toLowerCase()) === trim(customerInfo.addressList[i].nickname.toLowerCase())) {
                doDebug("[isNicknameDuplicate] selection.shipToNickname = " + selection.shipToNickname);
                doDebug("[isNicknameDuplicate] shipToArray[i] = " + shipToArray[i]);
            	doDebug("[isNicknameDuplicate] You entered a duplicate nickname.");
                return true;
            }
        }
        return false;
    };
    this.phoneSelect = function() {
        if(dropShipDayPhoneEntry != null && dropShipDayPhoneEntry != undefined && thisSbg.checkPhoneNumbers(this.parentNode.id) == true) {
            var phoneNum = this.value;
            phoneNum = thisSbg.cleanPhoneNumber(phoneNum);
            doDebug("[phoneSelect] Phone number: " + phoneNum);
            thisSbg.setPhoneSelection(this.parentNode.id, phoneNum);
        }
    };
    this.cleanPhoneNumber = function(phoneNum) {
        phoneNum = phoneNum.replace(/\-/g, "");
        phoneNum = phoneNum.replace(/\s/g, "");
        phoneNum = phoneNum.replace(/\(/g, "");
        phoneNum = phoneNum.replace(/\)/g, "");
        return phoneNum;
    };
    this.checkPhoneNumbers = function(theID) {
        if (dropShipDayPhoneEntry != null && dropShipDayPhoneEntry != undefined) {
            var theInput = document.getElementById(theID).getElementsByTagName("input")[0];
            var phoneRegEx = /^((\d{1,3}(-| )?\(?\d\)?(-| )?\d{1,3})|(\(?\d{2,3}\)?))(-| )?(\d{3,4})(-| )?(\d{4}){0,1}$/
            var extRegEx = /^[0-9]*$/
            var scrubbed = thisSbg.cleanPhoneNumber(theInput.value);
            if (!theID.match(/Ext/i) && theInput.value.match(phoneRegEx) && scrubbed.length == 10) {
                return true;
            } else if (theID.match(/Ext/i) && theInput.value.match(extRegEx) && scrubbed.length <= 5) {
                return true;
            } else if (theInput.value == "") {
                return true;
            } else {
                return false;
            }
        } else {
            return false;
        }
    };
    this.setPhoneSelection = function(elementID, phoneNum) {
        switch (elementID) {
            case "dayTimePhoneSelector_prd_" + num:
                selection.dropShipDayPhone = phoneNum;
                doDebug("[setPhoneSelection] Day phone: " + selection.dropShipDayPhone);
                document.getElementById("daytimePhone_prd_" + num).getElementsByTagName("div")[0].className = document.getElementById("daytimePhone_prd_" + num).getElementsByTagName("div")[0].className.replace(" errorHiLight", "");
            break;
            case "dayTimePhoneExtentsion_prd_" + num:
                selection.dropShipDayPhoneExt = phoneNum;
                doDebug("[setPhoneSelection] Day phone ext.: " + selection.dropShipDayPhoneExt);
                document.getElementById("daytimePhone_prd_" + num).getElementsByTagName("div")[0].className = document.getElementById("daytimePhone_prd_" + num).getElementsByTagName("div")[0].className.replace(" errorHiLight", "");
            break;
            case "alternativePhoneSelector_prd_" + num:
                selection.dropShipAltPhone = phoneNum;
                doDebug("[setPhoneSelection] Alt phone: " + selection.dropShipAltPhone);
                document.getElementById("alternativePhone_prd_" + num).getElementsByTagName("div")[0].className = document.getElementById("daytimePhone_prd_" + num).getElementsByTagName("div")[0].className.replace(" errorHiLight", "");
            break;
            case "alternativePhoneExtentsion_prd_" + num:
                selection.dropShipAltPhoneExt = phoneNum;
                doDebug("[setPhoneSelection] Alt phone ext: " + selection.dropShipAltPhoneExt);
                document.getElementById("alternativePhone_prd_" + num).getElementsByTagName("div")[0].className = document.getElementById("daytimePhone_prd_" + num).getElementsByTagName("div")[0].className.replace(" errorHiLight", "");
            break;
            default:
                doDebug("[setPhoneSelection] The switch failed on " + elementID);
            break;
        }
    };
    /*========================================================================================
        Builds a line item to be handled by the inline shopping bag.  Currently is used to get
        the image to display as well as to display a debug statement.
    ========================================================================================*/
    this.buildLineItem = function() {
    	var imageSetCollectionRelLoc = sbgImageSets[sAIndex].currentRelativeImageSetLoc;
      	var imageName = sbgImageSets[sAIndex].imageSetCollectionList[imageSetCollectionRelLoc].getColorImageForISB(selection.colorCode);
        selection.productImageURL = imageName + "?wid=100";
        doDebug("[buildLineItem] selection.productImageURL = " + selection.productImageURL);        
        if (selection.style !== "") {
 		    var debugMsg = "[buildLineItem] You have chosen the following:<br />\nStyle: " + selection.style + 
                           "<br />\nColor: " + selection.colorCode + 
                           "<br />\nSize: " +  selection.sizeCode +
                           "<br />\nSecondary Size: " +  selection.sizeCode2 +
                           "<br />\nGift Boxing: " + selection.giftBox + 
                           "<br />\nMonogramming: " + selection.monogrammed +
                           "<br />\nQuantity: " + selection.quantity +
                           "<br />\nShip To: " + selection.shipTo +
                           "<br />\nShip To Nickname: " + selection.shipToNickname;
            doDebug(debugMsg);
        }
    };
    /*============================================================================
        When the add to bag button is clicked, this checks for errors and displays
        messages.  If everything is OK, it calls the selection object's addToBag
        function.
    ============================================================================*/
    this.addToBagCheckErrors = function(includeCookieTest) {
        var funcName = "[addToBagCheckErrors] ";
        var errorMessage = "";
        doDebug(funcName+"selection.colorCode="+selection.colorCode+" selection.sizeCode"+selection.sizeCode+" selection.sizeCode1="+selection.sizeCode1+" selection.sizeCode2="+selection.sizeCode2);
        if (includeCookieTest && isCookieEnabled() == false) {
            errorMessage += messages.error[34].getMessageText(true) + "<p />";
        }
        // waist not selected
        if (thisSbg.pantsHemmingSelector != null && (selection.sizeCode == null || selection.sizeCode == "")) {
            errorMessage += messages.error[1].getMessageText(true) + "<br />";
            sizeSelectorErrorContainer.innerHTML = messages.error[1].getMessageText();
            document.getElementById("waistChoice_prd_" + num).getElementsByTagName("span")[0].className += " errorHiLight";
            show(sizeSelectorErrorContainer);
        } else if ((sizeChooser != null || sizeDropdown != null) && (selection.sizeCode == null || selection.sizeCode == "")) {
	        // if this buy grid requires a secondary size selector and they haven't 
	        // selected one but they have selected a primary size.
	        if (secondarySizeChooser != null && 
	            (selection.sizeCode2 == undefined || selection.sizeCode2 == "") &&
	            selection.sizeCode1 != undefined) {
	            doDebug("MADE IT TO HERE "+messages.error[2].getMessageText());
	            errorMessage += messages.error[2].getMessageText(true) + "<br/>";
	            secondarySizeSelectorErrorContainer.innerHTML = messages.error[2].getMessageText();
	            //document.getElementById("secondarySizeSelector_error_prd_" + num).getElementsByTagName("span")[0].className += " errorHiLight";
	            document.getElementById("secondarySizeSelector_error_prd_" + num).className += " errorHiLight";
	            show(secondarySizeSelectorErrorContainer);
	        } else {
	            errorMessage += messages.error[1].getMessageText(true) + "<br />";
	            sizeSelectorErrorContainer.innerHTML = messages.error[1].getMessageText();
	            document.getElementById("sizeChoice_prd_" + num).getElementsByTagName("span")[0].className += " errorHiLight";
	            show(sizeSelectorErrorContainer);
            }
        }
        // color not selected
        if (colorSelector != null && (selection.colorCode == null || selection.colorCode == "")) {
            errorMessage += messages.error[3].getMessageText(true) + "<br />";
            colorSelectorErrorContainer.innerHTML = messages.error[3].getMessageText();
            document.getElementById("colorChoice_prd_" + num).getElementsByTagName("span")[0].className += " errorHiLight";
            show(colorSelectorErrorContainer);
        }
        // inseam not selected
        if (thisSbg.pantsHemmingSelector != null && thisSbg.pantsHemmingSelector.selectHemming() == false) {
            errorMessage += messages.error[4].getMessageText(true) + "<br />";
            sizeSelectorErrorContainer.innerHTML = messages.error[4].getMessageText();
            document.getElementById("inseamChoice_prd_" + num).getElementsByTagName("span")[0].className += " errorHiLight";
            show(sizeSelectorErrorContainer);
        }
        // size and color combination not available, but the user hits add to bag anyway
        if (selection.sku.inventoryStatus == "N") {
            errorMessage += messages.error[6].getMessageText(true) + "<br />";
        }
        // only check for buy grids that are not on a multi-item page
        if(multiItemShippingSelector == null){
        	if (shippingSelector != null && thisSbg.isNicknameCharsValid() == false) {
				errorMessage += messages.error[37].getMessageText(true) + "<br />";
	            document.getElementById("nicknameHeader_prd_" + num).getElementsByTagName("span")[0].className += " errorHiLight";
	            shipQuantityErrorContainer.innerHTML = messages.error[37].getMessageText();   
	        } else if (shippingSelector != null && thisSbg.isNicknameDuplicate() == true) {
	            errorMessage += messages.error[37].getMessageText(true) + "<br />";
	            document.getElementById("nicknameHeader_prd_" + num).getElementsByTagName("span")[0].className += " errorHiLight";
	            shipQuantityErrorContainer.innerHTML = messages.error[8].getMessageText();      	
			} else if (shippingSelector != null && selection.shipTo == "-2" && (selection.shipToNickname == null || selection.shipToNickname == "")) {
	            errorMessage += messages.error[7].getMessageText(true) + "<br />";
	            shipQuantityErrorContainer.innerHTML = messages.error[7].getMessageText();
	            document.getElementById("nicknameHeader_prd_" + num).getElementsByTagName("span")[0].className += " errorHiLight";
	            show(shipQuantityErrorContainer);
	        }
        }
        // monogram has been chosen but apply button hasn't been clicked
        if (monogramSelector != null && selection.monogrammed == true && monogramIt.applied == false) {
            errorMessage += messages.error[12].getMessageText(true) + "<br />";
            monogramErrorContainer.innerHTML = messages.error[12].getMessageText();
            document.getElementById("monogramSelector_prd_" + num).getElementsByTagName("span")[0].className += " errorHiLight";
            show(monogramErrorContainer);
        }
        // the specialty shipping daytime number is missing
        if (dropShipDayPhoneEntry != null && dropShipDayPhoneEntry != undefined) {
            if (dropShipDayPhoneEntry[0].value == "" || dropShipDayPhoneEntry[0].value == null) {
                errorMessage += messages.error[25].getMessageText(true) + "<br />";
                dropShipDayPhoneErrorContainer.innerHTML = messages.error[25].getMessageText();
                document.getElementById("daytimePhone_prd_" + num).getElementsByTagName("div")[0].className += " errorHiLight";
                show(dropShipDayPhoneErrorContainer);
            }
            // invalid speciality shipping numbers
            if (thisSbg.checkPhoneNumbers("dayTimePhoneSelector_prd_" + num) == false || thisSbg.checkPhoneNumbers("dayTimePhoneExtentsion_prd_" + num) == false) {
                errorMessage += messages.error[24].getMessageText(true) + "<br />";
                dropShipDayPhoneErrorContainer.innerHTML = messages.error[24].getMessageText();
                document.getElementById("daytimePhone_prd_" + num).getElementsByTagName("div")[0].className += " errorHiLight";
                show(dropShipDayPhoneErrorContainer);
            }
            if (thisSbg.checkPhoneNumbers("alternativePhoneSelector_prd_" + num) == false || thisSbg.checkPhoneNumbers("alternativePhoneExtentsion_prd_" + num) == false) {
                errorMessage += messages.error[24].getMessageText(true) + "<br />";
                dropShipAltPhoneErrorContainer.innerHTML = messages.error[24].getMessageText();
                document.getElementById("alternativePhone_prd_" + num).getElementsByTagName("div")[0].className += " errorHiLight";
                show(dropShipAltPhoneErrorContainer);
            }
        }
        // compare selectionToSku shows the inventory message already
	    if (invalidSizeColorMessage != null && invalidSizeColorMessage.style.display == "block") {
			doDebug("[checkBuyGridErrors] invalidSizeColorMessage.style.display = " + invalidSizeColorMessage);
			errorMessage += messages.info.productNotAvailable(num, sA[saKey].colors[selection.colorCode], sA[saKey].sizes[selection.sizeCode]); + "<br />";
        }        
        if (errorMessage != "") {
            return errorMessage;
        } else {
            hide(mainFeatureTypeErrorContainer);
            hide(featureTypeErrorContainer);
            hide(colorSelectorErrorContainer);
            hide(sizeSelectorErrorContainer);
            hide(secondarySizeSelectorErrorContainer);
            hide(giftBoxErrorContainer);
            hide(monogramErrorContainer);
            hide(shipQuantityErrorContainer);
            hide(buyGridFooterErrorContainer);
            hide(dropShipDayPhoneErrorContainer);
            hide(dropShipAltPhoneErrorContainer);
            return null;
        }
    };
    this.addToBag = function() {
        var funcName = "[addToBag] ";
        doDebug(funcName+"inside");
    	if (addToBagButtonEnabled == false) {
    		doDebug("addToBagButton is not enabled");
    		return;
    	}
    	thisSbg.compareSelectionToSku();
    	var errors = thisSbg.addToBagCheckErrors(true)
    	if (errors == null) {
            thisSbg.buildLineItem();
	        doDebug("[addToBag] selection.sku.inventoryStatus = " + selection.sku.inventoryStatus);
	        inlineBag.addSelectionToBag(sAIndex, selection,thisSbg);
	    }else{
	    	showErrorPopup(errors);
	    }
        return false;
    };
    this.disableAddToBagButton = function() {
    	if (addToBagButton != null) {
    		addToBagButtonEnabled = false; 
    		addToBagButton.getElementsByTagName("img")[0].src = addToBagButton.getElementsByTagName("img")[0].src.replace(/addToBagButton_([A-Z]*)\.gif/ig,'adding_$1.gif');
    	}
    	return;
    };
    this.enableAddToBagButton = function() {
    	if (addToBagButton != null) {
    		addToBagButtonEnabled = true; 
    		addToBagButton.getElementsByTagName("img")[0].src = addToBagButton.getElementsByTagName("img")[0].src.replace(/adding_([A-Z]*)\.gif/ig,'addToBagButton_$1.gif');
    	}
       	return;
    };
    this.displayModifyItemButtons = function() {
		var updateImageSrc = addToBagButton.getElementsByTagName("img")[0].src.replace(/addToBagButton_grey.gif/g,'update_item.gif');
      	addToBagButton.getElementsByTagName("img")[0].alt = "update this item";
      	show(cancelUpdateButton);
      	addToBagButton.getElementsByTagName("img")[0].src = updateImageSrc;
    };
    this.getSize1StatusList = function() {
        var funcName = "[getSize1StatusList] ";
        if (sbgSecondarySizeRequired[num] == false) {
            doDebug(funcName+"No secondary size issues, return null");
            return null;
        }
        doDebug(funcName+"selection.style="+selection.style+" styleArray.length="+styleArray.length+" snArray.length="+snArray.length);
        doDebug(funcName+"selection.colorCode="+selection.colorCode+" selection.sizeCode1="+selection.sizeCode1+ " selection.sizeCode2="+selection.sizeCode2);
        var i;
        var k;
        var resArray = new Array();
        var testArray = new Array();
        // loop through all of the styles that appear in this view
		for (k = 0; k < snArray.length; k++) {
		    var kStyle = "SN-"+snArray[k];
		    doDebug(funcName+"scanning style "+kStyle);
		    // loop through the list of skus for this style
	        for (i = 0; i < sA[saKey][kStyle].length; i++) {
	           var sku = sA[saKey][kStyle][i];
	           var skuSizeCodeList = parseSizeCode(sku.sizeCode);
	           if (selection.sizeCode2 == undefined || selection.sizeCode2 == "" || selection.sizeCode2 == skuSizeCodeList[1]) {
		           if (sku.colorCode == selection.colorCode) {
		               var testInvStatus = sku.inventoryStatus;
	  	               //doDebug(funcName+"sku.sizeCode="+sku.sizeCode+" sku.colorCode="+sku.colorCode+" testInvStatus="+testInvStatus+" sizeCode1="+sku.sizeCode1+" sizeCode2="+sku.sizeCode2+ " tstIdx="+tstIdx);
		               var szStat;
		               var tstIdx = arrayContains(testArray, sku.sizeCode1);
		               // if they are missing one or both of the split size selections.
		               if (selection.sizeCode2 == undefined) {
		                   szStat = new size1InvStatus(sku.sizeCode1, "A");
		               } else {  // if a complete size has been selected.
	                       szStat = new size1InvStatus(sku.sizeCode1, testInvStatus);
		               }
		               // now that we have made it to here that means that we have
		               // an instance of szStat correctly populated regardless of
		               // the state of the user's form. so now we just have to grow
		               // the output array accordingly.
		               if (tstIdx < 0) {
		                   resArray.push(szStat);
		                   testArray.push(sku.sizeCode1);
		               } else {
		                   var storedSizeStat = resArray[tstIdx];
		                   resArray[tstIdx] = szStat.compareInventory(storedSizeStat);
		               }
		           }
	           }
	        }
        }
        // just debug output.
        for (i = 0; i < resArray.length; i++) {
          var v = resArray[i];
          doDebug(funcName+"resArray["+i+"]="+v.sizeCode1+" "+v.invStatus);
        }
        return resArray;
    }
    this.updateFeatureTypeCombinationErrorDisplay = function(on) {
        var funcName = "[updateFeatureTypeCombinationErrorDisplay] ";
        if (featureTypeCombinationError != null) {
            if (on) {
                featureTypeCombinationError.innerHTML = sbgItemNotAvail + mainFeatureLongText + " " + sbgWith + secondaryFeatureLongText + " " + sbgIn + sA[saKey].colors[selection.colorCode];
                show(featureTypeCombinationError);
            } else {
            	hide(featureTypeCombinationError);
            }
        }
    }
    this.getSize2StatusList = function() {
        var funcName = "[getSize2StatusList] ";
        if (sbgSecondarySizeRequired[num] == false) {
            doDebug(funcName+"No secondary size issues, return null");
            return null;
        }
        doDebug(funcName+"selection.style="+selection.style+" styleArray.length="+styleArray.length+" snArray.length="+snArray.length);
        doDebug(funcName+"selection.colorCode="+selection.colorCode+" selection.sizeCode1="+selection.sizeCode1+ " selection.sizeCode2="+selection.sizeCode2);
        var i;
        var k;
        var resArray = new Array();
        var testArray = new Array();
        // loop through all of the styles that appear in this view
		for (k = 0; k < snArray.length; k++) {
		    var kStyle = "SN-"+snArray[k];
		    doDebug(funcName+"scanning style "+kStyle);
		    // loop through the list of skus for this style
	        for (i = 0; i < sA[saKey][kStyle].length; i++) {
	           var sku = sA[saKey][kStyle][i];
	           var skuSizeCodeList = parseSizeCode(sku.sizeCode);
	           //doDebug(funcName+"sku.sizeCode:" + skuSizeCodeList[0]+":"+skuSizeCodeList[1]);
	           if (selection.sizeCode1 == undefined || selection.sizeCode1 == "" || selection.sizeCode1 == skuSizeCodeList[0]) {
		           if (sku.colorCode == selection.colorCode) {
		               var testInvStatus = sku.inventoryStatus;
		               //doDebug(funcName+"sku.sizeCode="+sku.sizeCode+" sku.colorCode="+sku.colorCode+" testInvStatus="+testInvStatus+" sizeCode1="+sku.sizeCode1+" sizeCode2="+sku.sizeCode2+ " tstIdx="+tstIdx);
		               var szStat;
		               var tstIdx = arrayContains(testArray, sku.sizeCode2);
		               // if they are missing one or both of the split size selections.
		               if (selection.sizeCode1 == undefined) {
		                   szStat = new size2InvStatus(sku.sizeCode2, "A");
		               } else {  // if a complete size has been selected.
	                       szStat = new size2InvStatus(sku.sizeCode2, testInvStatus);
		               }
		               // now that we have made it to here that means that we have
		               // an instance of szStat correctly populated regardless of
		               // the state of the user's form. so now we just have to grow
		               // the output array accordingly.
		               if (tstIdx < 0) {
		                   resArray.push(szStat);
		                   testArray.push(sku.sizeCode2);
		               } else {
		                   var storedSizeStat = resArray[tstIdx];
		                   resArray[tstIdx] = szStat.compareInventory(storedSizeStat);
		               }
		           }
	           }
	        }
        }
        // just debug output.
        for (i = 0; i < resArray.length; i++) {
          var v = resArray[i];
          doDebug(funcName+"resArray["+i+"]="+v.sizeCode2+" "+v.invStatus);
        }
        return resArray;
    }
    this.getColorStatusList = function() {
        var funcName = "[getColorStatusList] ";
        if (sbgSecondarySizeRequired[num] == false) {
            doDebug(funcName+"No secondary size issues, return null");
            return null;
        }
        var selectedStyle = "SN-"+selection.style;
        doDebug(funcName+"styleArray.length="+styleArray.length+" snArray.length="+snArray.length);
        doDebug(funcName+"selection.colorCode="+selection.colorCode+"selection.sizeCode1="+selection.sizeCode1+ " selection.sizeCode2="+selection.sizeCode2);
        var i;
        var k;
        var resArray = new Array();
        var testArray = new Array();
        // loop through all of the styles that appear in this view
		for (k = 0; k < snArray.length; k++) {
		    var kStyle = "SN-"+snArray[k];
		    doDebug(funcName+"scanning style "+kStyle);
		    // loop through the list of skus for this style
	        for (i = 0; i < sA[saKey][kStyle].length; i++) {
	           var sku = sA[saKey][kStyle][i];
	           var tstIdx = arrayContains(testArray, sku.colorCode);
	//           doDebug(funcName+"sku.sizeCode="+sku.sizeCode+" sku.colorCode="+sku.colorCode+" invStatus="+sku.inventoryStatus+" sizeCode1="+sku.sizeCode1+" sizeCode2="+sku.sizeCode2+ " tstIdx="+tstIdx);
	           if (selection.sizeCode1 == undefined && selection.sizeCode2 == undefined) {
	               var colStat = new colorInvStatus(sku.colorCode, "A");
	               if (tstIdx < 0) {
	               	   resArray.push(colStat);
	               	   testArray.push(sku.colorCode);
	               }
	           } else if ((selection.sizeCode1 == undefined && selection.sizeCode2 != undefined) ||
	                      (selection.sizeCode1 != undefined && selection.sizeCode2 == undefined)){
	               var colStat = new colorInvStatus(sku.colorCode,sku.inventoryStatus);
	               var storedColStat;
	               if (tstIdx < 0) {
	                   resArray.push(colStat);
	               	   testArray.push(sku.colorCode);
	               	   tstIdx = testArray.length-1;
	               }
	               storedColStat = resArray[tstIdx];
	               testArray[tstIdx] = sku.colorCode;
	               resArray[tstIdx] = colStat.compareInventory(storedColStat);
	           } else {
	               var colStat = new colorInvStatus(sku.colorCode,sku.inventoryStatus);
	               var storedColStat;
	               if (tstIdx < 0) {
	                   resArray.push(colStat);
	               	   testArray.push(sku.colorCode);
	               	   tstIdx = testArray.length-1;
	               }
	               storedColStat = resArray[tstIdx];
	               testArray[tstIdx] = sku.colorCode;
	               resArray[tstIdx] = colStat.compareInventory(storedColStat);
	           }
	        }
        }
        // just debug output.
        for (i = 0; i < resArray.length; i++) {
          var v = resArray[i];
          doDebug(funcName+"resArray["+i+"]="+v.colorCode+" "+v.invStatus);
        }
        return resArray;
    }
    /*=================================================================================
        Compares what has been selected to the skus in the style array.  It compares
        sizeCodes and colorCodes.
    =================================================================================*/
    this.compareSelectionToSku = function() {
        var funcName="[compareSelectionToSku] ";
        var selectedStyle = "SN-" + selection.style;
        var isGood = false;
        var inventoryStatus  = "";
        var i;
        doDebug(funcName+"selection.style: " + selection.style);
        doDebug(funcName+"selection.sizeCode: " + selection.sizeCode);
        doDebug(funcName+"selection.sizeCode1: " + selection.sizeCode1);
        doDebug(funcName+"selection.sizeCode2: " + selection.sizeCode2);
        doDebug(funcName+"selection.colorCode: " + selection.colorCode);
        for (i = 0; i < sA[saKey][selectedStyle].length; i++) {
			//doDebug("[compareSelectionToSku] sA[sAIndex][selectedStyle][i].sizeCode = " + sA[sAIndex][selectedStyle][i].sizeCode);
			//doDebug("[compareSelectionToSku] sA[sAIndex][selectedStyle][i].colorCode = " + sA[sAIndex][selectedStyle][i].colorCode);
			if (sA[saKey][selectedStyle][i].colorCode == "" && sA[saKey][selectedStyle][i].sizeCode == "") {
                doDebug("[compareSelectionToSku] No size or color variation.  You have chosen sku number " + selection.sku.skuNumber);
                selection.sku = sA[saKey][selectedStyle][i];
                selection.price = selection.sku.price;
				isGood = true;
        	} else if (sA[saKey][selectedStyle][i].sizeCode == "" && selection.colorCode == sA[saKey][selectedStyle][i].colorCode) {
                selection.sku = sA[saKey][selectedStyle][i];
                selection.price = selection.sku.price;
                doDebug("[compareSelectionToSku] No size variation, color match.  You have chosen sku number " + selection.sku.skuNumber);
                isGood = true;        		
        	} else if (sA[saKey][selectedStyle][i].colorCode == "" && selection.sizeCode == sA[saKey][selectedStyle][i].sizeCode) {
                selection.sku = sA[saKey][selectedStyle][i];
                selection.price = selection.sku.price;
                doDebug("[compareSelectionToSku] No color variation, size match.  You have chosen sku number " + selection.sku.skuNumber);
                isGood = true;        
        	} else if (selection.sizeCode == sA[saKey][selectedStyle][i].sizeCode && selection.colorCode == sA[saKey][selectedStyle][i].colorCode) {
        		selection.sku = sA[saKey][selectedStyle][i];
                selection.price = selection.sku.price;
                doDebug("[compareSelectionToSku] Size and color match.  You have chosen sku number " + selection.sku.skuNumber);
                isGood = true;
            }
        }
		if (isGood == true) {
			inventoryStatus = selection.sku.inventoryStatus;
		}
        // this is a special case we have to handle. it occurs when we have
        // an overloaded size code, selected separately, as is done with 
        // custom swimsuits and the combination just doesn't exist. Example,
        // 4C tends not to exist in swimsuits. So we are going to treat this
        // case as if the SKU isn't available by setting the inventory status
        if ((selection.sizeCode == null || selection.sizeCode == "") &&
            (selection.sizeCode1 != null && selection.sizeCode1 != "") &&
            (selection.sizeCode2 != null && selection.sizeCode2 != "")) {
             inventoryStatus = "I"; // this is a special "Invalid Code"
        }
		doDebug("[compareSelectionToSku] inventoryStatus = " + inventoryStatus);
        if (thisSbg.shouldCheckInventory() == true) {     
            switch (inventoryStatus) {
                case "B":
                    doDebug("[compareSelectionToSku] The item is back ordered.");
                    backOrderMessage.innerHTML = messages.info.productBackOrdered(num, selection.sku.getBackorderDate.monthName, selection.sku.getBackorderDate.day);
                    show(backOrderMessage);
                    hide(invalidSizeColorMessage);
                    isGood = true;
                    break;
                case "N":
                    doDebug("[compareSelectionToSku] The item is not available.");
                    invalidSizeColorMessage.innerHTML = messages.info.productNotAvailable(num, sA[saKey].colors[selection.sku.colorCode], sA[saKey].sizes[selection.sku.sizeCode]);
                    show(invalidSizeColorMessage);
                    hide(backOrderMessage);
                    isGood = false;
                    break;
                case "A":
                    doDebug("[compareSelectionToSku] The item is available.");
                    hide(backOrderMessage);
                    hide(invalidSizeColorMessage);
                    isGood = true;
                    break;
                case "D":
                    doDebug("[compareSelectionToSku] The item is drop-shipped.");
                    hide(backOrderMessage);
                    hide(invalidSizeColorMessage);
                    isGood = true;
                    break;                    
                case "":
                case undefined:
                case "I":
                    doDebug("[compareSelectionToSku] The item selection is invalid.");
                    var sizeString = selection.sizeCode1+""+selection.sizeCode2;
                    invalidSizeColorMessage.innerHTML = messages.info.productNotAvailable(num, sA[saKey].colors[selection.colorCode], sizeString);
                    show(invalidSizeColorMessage);
                    hide(backOrderMessage);
                    isGood = false;
                    break;
                case null:
                    doDebug("[compareSelectionToSku] The item is not available.");
                    invalidSizeColorMessage.innerHTML = messages.info.productNotAvailable(num, sA[saKey].colors[selection.colorCode], sA[saKey].sizes[selection.sizeCode]);
                    show(invalidSizeColorMessage);
                    hide(backOrderMessage);
                    isGood = false;
                    break;
                default:
                    break;
            }
        } else {
            selection.price = 0;
        }
        if (isGood == true) {
            return true;
        } else {
            return false;
        }
    };
    // simplify the perplexing if statement used above
    this.shouldCheckInventory = function () {
        var funcName="[shouldCheckInventory] ";
        doDebug(funcName+"selection.style="+selection.style+" selection.colorCode="+selection.colorCode+" selection.sizeCode="+selection.sizeCode+" selection.sizeCode1="+selection.sizeCode1+" selection.sizeCode2="+selection.sizeCode2);
		// can't select a quantity?
    	if (quantityAmounts == null) {
    		doDebug("[shouldCheckInventory] quantityAmounts = null, return false");
    		return false;
    	}
    	// no size variation, safe to check
    	if (sizeChooser == null && sizeDropdown == null && document.getElementById("waistChooser_prd_" + num) == null) {
    		doDebug("[shouldCheckInventory] sizeChooser == null && sizeDropdown == null && thisSbg.pantsHemmingSelector == null, return true");    	
    		return true;
    	}
    	// there is size variation, make sure size is set before checking inventory
    	if (selection.sizeCode != "" && selection.sizeCode != undefined && selection.sizeCode != null) {
    		doDebug(funcName+"selection.sizeCode != \"\" && selection.sizeCode != undefined && selection.sizeCode != null, return true");    	
			return true;
		}
        // this is a special case we have to handle. it occurs when we have
        // an overloaded size code, selected separately, as is done with 
        // custom swimsuits and the combination just doesn't exist. Example,
        // 4C tends not to exist in swimsuits. So we are going to treat this
        // case as if the SKU isn't available by setting the inventory status
        if ((selection.sizeCode == null || selection.sizeCode == "") &&
            (selection.sizeCode1 != null && selection.sizeCode1 != "") &&
            (selection.sizeCode2 != null && selection.sizeCode2 != "")) {
             doDebug(funcName+"special overloaded size case returning true");
             return true;
        }
		doDebug(funcName+"return false");
		return false;
    }
    /*========================
        Builds the price recap
    ========================*/
    this.buildRecap = function() {
        var funcName = "[buildRecap] ";
        if (recap.color != null && selection.colorCode != "" && selection.colorCode != undefined) {
            recap.color.innerHTML = sA[saKey].colors[selection.colorCode] + " ";
        }
        doDebug(funcName+"selection.sizeCode = " + selection.sizeCode);
        if (selection.sizeCode != "" && selection.sizeCode != undefined) {
        	var displaySizeCode = sA[saKey].sizes[selection.sizeCode];
        	if (displaySizeCode == undefined) {
        		displaySizeCode = "";
        	}
        	if (thisSbg.pantsHemmingSelector != null) {
        		thisSbg.pantsHemmingSelector.buildPantsSizeRecap();
          	} else {
             	recap.size.innerHTML = displaySizeCode + " ";
            }
        } else if (recap.size != undefined) {
            recap.size.innerHTML = "";
        }
        if (monogramIt != null) {
        	monogramIt.setThreadColor(selection.sku.monoThreadColorCode);
        }
        if (selection.getExtendedPrice() != 0) {
            recap.price.innerHTML = toCurrency(selection.getExtendedPrice()) + " ";
        }
        if (recap.price != undefined && recap.price.innerHTML != undefined && selection.price == 0) {
            recap.price.innerHTML = "";
        }
		// build was/now price
		doDebug(funcName+"isCollection = " + isCollection);
		doDebug(funcName+"saKey="+saKey);
		doDebug(funcName+"selection.sku.prevPrice = " + selection.sku.prevPrice);
		doDebug(funcName+"selection.style= " + selection.style);
		doDebug(funcName+"selection.price = " + selection.price);
		doDebug(funcName+"selection.sku.price = " + selection.sku.price);
		doDebug(funcName+"selection.sku.prevPrice = " + selection.sku.prevPrice);
        if (isCollection == false && selection.sku.prevPrice != "" && selection.price != 0 && parseFloat(selection.sku.price) < parseFloat(selection.sku.prevPrice)) {
        	doDebug(funcName+"setting was/now price to "+selection.sku.prevPrice+" "+selection.price);
        	itemPriceRecap.innerHTML = "<span id=\"wasPrice_prd_" + num + "\" class=\"wasPrice\">" + sbgWas +
        							toCurrency(selection.sku.prevPrice) + "</span>" +
									"<span id=\"nowPrice_prd_" + num + "\" class=\"nowPrice\"> " + sbgNow +
									toCurrency(selection.price) + "</span>";
        } else if (isCollection == true && selection.sku.prevPrice != "" && selection.price != 0 && parseFloat(selection.sku.price) < parseFloat(selection.sku.prevPrice)) {
         	doDebug(funcName+"setting collection was/now price");
         	itemPriceRecap.innerHTML = "<span id=\"wasPrice_prd_" + num + "\" class=\"wasPrice\">" + sbgWas +
        							toCurrency(selection.sku.prevPrice) + "</span>" +
									"<span id=\"nowPrice_prd_" + num + "\" class=\"nowPrice\"> " + sbgNow +
									toCurrency(selection.price) + "</span>";
        	//nowPriceRecap.innerHTML = "now " +
									//toCurrency(selection.price) + "</span>";       
        } else if (selection.price != 0) {
        	doDebug(funcName+"setting current price to "+selection.price);
        	itemPriceRecap.innerHTML = toCurrency(selection.price);
        // if we make it to here without changing the price that possibly means that
        // we don't have a complete sku selected but have changed a style number. this
        // can happen for the custom swimsuits when you do a color selection that
        // changes to style number.
        // If we make it here, we are at a style level and have to figure out was/now pricing at a 
        // style level.
        } else if (! isCollection && itemPriceRecap != undefined && selection.style != undefined) {
            var styleKey = "SN-"+selection.style;
            var dispPrice = sA[saKey].styleList[styleKey].maxPrice;
            if(sA[saKey].styleList[styleKey].originalMaxPrice != null && sA[saKey].styleList[styleKey].originalMaxPrice > sA[saKey].styleList[styleKey].maxPrice){
            	itemPriceRecap.innerHTML= "<span id=\"wasPrice_prd_" + num + "\" class=\"wasPrice\">" + sbgWas +
        			toCurrency(sA[saKey].styleList[styleKey].originalMaxPrice) + "</span>" +
					"<span id=\"nowPrice_prd_" + num + "\" class=\"nowPrice\"> " + sbgNow +
					toCurrency(dispPrice) + "</span>";
            }else{          	
            	itemPriceRecap.innerHTML = toCurrency(dispPrice);
            }
        }
    };
    /*/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
        Functions to dynamically select previously chosen options
    /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/*/
    this.selectDefaultColor = function() {
        if (colorChips != null && colorChips.length > 0) { 
            selection.colorCode = colorChips[0].id.split("_")[0];
            colorChips[0].parentNode.parentNode.className = css.sbg.colorSelected;
            colorRecap.innerHTML = sA[saKey].colors[selection.colorCode];
            thisSbg.compareSelectionToSku();
            thisSbg.checkSizes();
            thisSbg.checkColors();
            thisSbg.buildRecap();
            selection.updated = false;
            doDebug("[selectDefaultColor] The default color is " + selection.colorCode);
            thisSbg.getStyleNumber();
        }
    };
    // mainFeatureType is the view id
    this.selectMainFeatureType = function(mainFeatureType) {
        if (mainFeatureTypeChips != null && mainFeatureTypeChips.length > 0) {
            var i;
            for (i = 0; i < mainFeatureTypeChips.length; i++) {
                if (mainFeatureTypeChips[i].value == mainFeatureType) {
                    mainFeatureTypeChips[i].checked = "checked";
                    selection.style = snArray[i];
                }
            }
            thisSbg.getStyleNumber();
        }
    };
    // this function is only called on the initial buy grid load. the
    // intent of this function is to make certain that the default load of 
    // a page actually equates to a style that exists. This function will
    // really only do anything when there is no style for the main feature type
    // and the first secondary feature type and there are multiple colorways
    // in the page. in otherwords, only for the stupid custom swimsuit project.
    this.adjustSecondaryFeatureSelection = function() {
      var funcName = "[adjustSecondaryFeatureSelection] ";
      if (selection.colorCode != undefined && selection.colorCode != null &&
          featureTypeChips.length > 0) {
          var currentColorChipColorPattern = thisSbg.getColorPatternFeature(selection.colorCode);
          var i;
	      for (i in sA[saKey]) {
	        if(typeof sA[saKey][i] == "object" && sA[saKey][i] instanceof Array) {
	        	var spltStyle = i.split("-")[1];
	        	doDebug(funcName+"testing spltStyle= " + spltStyle+" currentColorChipColorPattern="+currentColorChipColorPattern);
	        	var firstSKUColorCode = sA[saKey][i][0].colorCode;
	        	var firstSKUColorPattern = thisSbg.getColorPatternFeature(firstSKUColorCode);
	        	var firstSKUFeatureCode = sA[saKey][i][0].featureCode;
	        	doDebug(funcName+"firstSKUColorCode="+firstSKUColorCode+" pattern code="+firstSKUColorPattern+" firstSKUFeatureCode="+firstSKUFeatureCode);
	        	if (currentColorChipColorPattern == firstSKUColorPattern) {
	        	    selection.style = spltStyle;
	        	    thisSbg.checkFeatureTypeCombinationError();
	        	    thisSbg.updateItemNumber();
	        	    selection.colorCode = firstSKUColorCode;
	        	    var j;
	        	    doDebug(funcName+"color pattern match found selection.style="+selection.style);
	        	    for (j = 0; j < featureTypeChips.length; j++) {
	        	        featureTypeChips[j].checked = false;
	        	        doDebug(funcName+"featureTypeChips["+j+"].value="+featureTypeChips[j].value);
	        	        if (featureTypeChips[j].value == firstSKUFeatureCode) {
	        	            doDebug(funcName+"setting checked for position="+j);
	        	            featureTypeChips[j].checked = true;
	        	        }
	        	    }
	        	    break;
	        	}
	        }  
	      }
      }
    }
    this.getColorPatternFeature = function(clrCode) {
		return colorPatternFeature[clrCode];
    }
    // featureTypes is an array
    this.selectFeatureTypes = function(featureTypes) {
        var i;
        var j;
        if (featureTypes != null && featureTypes.length > 0 && featureTypes[0] != null && featureTypeChips.length > 0) {
            for (i = 0; i < featureTypes.length; i++) {
                for (j = 0; j < featureTypeChips.length; j++) {
                    if (featureTypeChips[j].value == featureTypes[i]) {
                        featureTypeChips[j].click();
                    }
                }
            }
        }
    };
    this.selectColor = function(color) {
        if (colorChips != null && colorChips.length > 0) {
            var i;
            for (i = 0; i < colorChips.length; i++) {
                if (colorChips[i].id.split("_")[0] == color.toUpperCase()) {
                    for (var j = 0; j < colorChips.length; j++) {
                        colorChips[j].parentNode.parentNode.className = css.sbg.colorNotSelected;
                    }
                    selection.colorCode = color.toUpperCase();
                    colorChips[i].parentNode.parentNode.className = css.sbg.colorSelected;
                    colorRecap.innerHTML = sA[saKey].colors[selection.colorCode];
                    thisSbg.checkSizes();
                    thisSbg.compareSelectionToSku();
                    thisSbg.buildRecap();
                    doDebug("[selectColor] The color you selected is " + selection.colorCode);
                }
            }
            // update the image, the image viewer iframe will also update itself onload
			buyGrids[saKey].updateViewerColor(selection.colorCode);	
        }
    };
    this.setSizeCode1 = function(code) {
        selection.sizeCode1 = code;
    };
    this.setSizeCode2 = function(code) {
        selection.sizeCode2 = code;
    };
    this.setSizeCode = function(code) {
    	selection.sizeCode = code;
    };
    this.selectSize = function(size) {
        var funcName = "[selectSize] ";
        var found = false;
        var testSize = size;
        var overloadedSize = false;
        doDebug(funcName+"size="+size+" sizeCode1="+selection.sizeCode1+" sizeCode2="+selection.sizeCode2);
        if (selection.sizeCode1 != null && selection.sizeCode1 != "") {
            testSize = selection.sizeCode1;
            overloadedSize = true;
        }
        if (sizeChips != null && sizeChips.length > 0) {
            var i;       
            var j;
            for (j = 0; j < sizeChips.length; j++) {
               sizeChips[j].parentNode.className = css.sbg.sizeNotSelected;
            }               
            for (i = 0; i < sizeChips.length; i++) {
                var chipSizeCode = sizeChips[i].parentNode.id.split("_")[1]
                doDebug(funcName+"chipSizeCode="+chipSizeCode+" testSize="+testSize);
                if (chipSizeCode == testSize) {
                	found = true;
                    selection.sizeCode = testSize.toUpperCase();
                    selection.sizeCode = thisSbg.getActualSizeCode();
                    doDebug(funcName+"resulting size code="+selection.sizeCode);
                    sizeChips[i].parentNode.className = css.sbg.sizeSelected;
                    if (overloadedSize) {
                        sizeRecap.innerHTML = testSize;
                    } else {
                        sizeRecap.innerHTML = sizeAssoc[selection.sizeCode];
                    }
                    thisSbg.setSecondarySizeChips();
                    thisSbg.updateSecondarySizeRecap();
                    thisSbg.checkColors();
                    thisSbg.compareSelectionToSku();
                    thisSbg.buildRecap();
                    break;
                }
            }
          	if(! found){
          	    doDebug(funcName+"size code never found");
            	selection.sizeCode = null;
               	sizeRecap.innerHTML = "";
            }
        } else if (sizeDropdown != null && sizeDropdown.options.length > 0) {
            var i;
            for (i = 0; i < sizeDropdown.options.length; i++) {
                if (sizeDropdown.options[i].value == size) {
                	found = true;
                    sizeDropdown.options[i].selected = true;
                    selection.sizeCode = sizeDropdown.options[i].value;
                    selection.sizeCode = thisSbg.getActualSizeCode();
                    thisSbg.compareSelectionToSku();
                    thisSbg.buildRecap();
                }
                if(! found){
                	selection.sizeCode = null;
                	sizeDropdown.options[0].selected = true;
                }
            }
        } else if (thisSbg.pantsHemmingSelector != null && thisSbg.pantsHemmingSelector.waistChooser.options.length > 0) {
            var i;
            for (i = 0; i < thisSbg.pantsHemmingSelector.waistChooser.options.length; i++) {
                if (thisSbg.pantsHemmingSelector.waistChooser.options[i].value == size) {
                	found = true;
                    thisSbg.pantsHemmingSelector.waistChooser.options[i].selected = "selected";
                    selection.sizeCode = thisSbg.pantsHemmingSelector.waistChooser.options[i].value;
                    selection.sizeCode = thisSbg.getActualSizeCode();
                    thisSbg.pantsHemmingSelector.selectWaist();
                }
                if(! found){
                	selection.sizeCode = null;
                	thisSbg.pantsHemmingSelector.waistChooser.options[0].selected = "selected";
                }
            }
        }
        doDebug(funcName+"The size you selected is " + selection.sizeCode);
    };
    this.selectGiftBox = function() {
        var funcName = "[selectGiftBox] ";
        if (giftBoxSelector != null) {
            giftBoxSelector.click();
            doDebug(funcName+"You selected giftboxing.");
        } else {
            showErrorPopup(messages.error[26].getMessageText(true));
        }
    };
    this.selectQuantity = function(quantity) {
        if (quantityAmounts != null && quantityAmounts.length > 0) {
            var i;
            for (i = 0; i < quantityAmounts.options.length; i++) {
                if ((parseInt(quantityAmounts.options[i].index) + 1) == parseInt(quantity)) {
                    quantityAmounts.options[i].selected = true;
                    selection.quantity = parseInt(quantityAmounts.options[i].index) + 1;
                    thisSbg.compareSelectionToSku();
                    thisSbg.buildRecap();
                    doDebug("[selectQuantity] The quantity you selected is " + selection.quantity);
                }
            }
        }
    };
    this.selectPants = function(pantsObj, waistSize) {
		thisSbg.selectSize(waistSize);
        thisSbg.selectPantsInseam(pantsObj.length);
        thisSbg.selectPantsCuffing(pantsObj.cuffed);
    };
    this.selectMonogram = function(monogramObj) {
        if (monogramSelector != null) {
 			var typeCode;
            var styleCode;
            var locCode;
            var wholeShebang;
            selection.monogrammed = true;
     		//monogramIt = monogramObj;
     		monogramSelector.checked = true;
            // need to compensate for whackjob differences without refactoring everything
            if (monogramObj.selection == null) {
                typeCode = monogramObj.type;
                styleCode = monogramObj.style;
                locCode = monogramObj.location;
                wholeShebang = new Object();
                wholeShebang.selection = new Object();
                wholeShebang.selection.type = typeCode;
                wholeShebang.selection.style = styleCode;
                wholeShebang.selection.location = locCode;
                wholeShebang.selection.siText = monogramObj.siText;
                wholeShebang.selection.wordText = monogramObj.wordText;
                wholeShebang.selection.multiInitialArr = monogramObj.multiInitialArr;
                wholeShebang.selection.multiLineArr = monogramObj.multiLineArr;
                wholeShebang.selection.price = monogramObj.price;
                wholeShebang.selection.done = monogramObj.done;
                monogramIt = new monogram(sAIndex,thisSbg,selection.sku.monoThreadColorCode);
                monogramIt.selection = wholeShebang.selection;
            } else {
                monogramIt = monogramObj;
                typeCode = monogramObj.selection.type;
                styleCode = monogramObj.selection.style;
                locCode = monogramObj.selection.location;
            }
            thisSbg.selectMonogramType(typeCode);
            thisSbg.selectMonogramStyle(styleCode);
            thisSbg.selectMonogramLocation(locCode);
            thisSbg.selectMonogramText(monogramIt);
            thisSbg.clickApplyMonogram();
        } else {
            showErrorPopup(messages.error[27].getMessageText(true));
        }
    };
    /*/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
        Wrappers so that these functions can be public from the buy grid
        object yet sort of private in their home objects.  Why?  Because
        trying to reference these is near impossible otherwise.  I would
        have to expose entire monogram and school uniform objects, which
        should remain private.
    /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\*/
    this.selectPantsInseam = function(inseam) {
        thisSbg.pantsHemmingSelector.pickInseam(inseam);
    };
    this.selectPantsCuffing = function(cuffing) {
        thisSbg.pantsHemmingSelector.pickCuffing(cuffing);
    };
    this.selectMonogramType = function(monoType) {
        monogramIt.selectType(monoType);
    };
    this.selectMonogramStyle = function(monoStyle) {
        monogramIt.selectStyle(monoStyle);
    };
    this.selectMonogramLocation = function(monoLocation) {
        monogramIt.selectLocation(monoLocation);
    };
    // too much processing, so throw in the whole monogram selection object
    this.selectMonogramText = function(monoObj) {
        monogramIt.selectText(monoObj);
    };
    this.clickApplyMonogram = function() {
        monogramIt.applyMonogram();
    };
    this.selectShipTo = function(shipToID,shipToNickname) {
        if (shipToPeople != null && shipToPeople.length > 0) {
            var i;
            var selected = false;
            for (i = 0; i < shipToPeople.options.length; i++) {
                if (shipToPeople.options[i].value == shipToID) {
                	try {
                    	shipToPeople.options[i].selected = true;
                    	if(shipToID == "-2"){
                    		show(nicknameEntry);
                    		nicknameEntryBox.value = shipToNickname;
                    	}else{
                    		hide(nicknameEntry);
                    	}
                    	selection.shipToNickname = shipToNickname;  
                    } catch(e) {
                    	doDebug("[selectShipTo] IE (only?) error setting selected " + e);
                    }
                    selection.shipTo = shipToPeople.options[i].value;
                    thisSbg.compareSelectionToSku();
                    thisSbg.buildRecap();
                    doDebug("[selectShipTo] You chose to ship to " + selection.shipTo);
                }
            }
        }
    };
	this.buildSelectionFromQueryString = function() {
	    var funcName = "[buildSelectionFromQueryString] ";
	    var querySelection = new selectionObj();
	    /*=====================================
	        Style number, size code, color code
	    =====================================*/
	    var querySku = getQueryVariable("sku_0").split(":");
	    doDebug(funcName+"Query sku: " + querySku);
	    if (querySku[0] != null && querySku[0] != "") { 
	        tempStyleStr = trimLeadingZeros(decodeURIComponent(querySku[0]));
	        querySelection.style = tempStyleStr.substring(0,tempStyleStr.length-3);
	        doDebug(funcName+"Style number: " + querySelection.style);
	    }    
	    if (querySku[1] != null && querySku[1] != "") {
	        querySelection.sizeCode = decodeURIComponent(querySku[1]);
	        doDebug(funcName+"Size code: " + querySelection.sizeCode);
	        var sizeCodeArr = parseSizeCode(querySelection.sizeCode);
	        var i;
	        if (sizeCodeArr.length > 0) {
		        for (i = 0; i < sizeCodeArr.length; i++) {
		            doDebug(funcName+"sizeCodeArr["+i+"]="+sizeCodeArr[i]);
		        }
		        querySelection.sizeCode1 = sizeCodeArr[0];
		        querySelection.sizeCode2 = sizeCodeArr[1];
	        }
	    }
	    if (querySku[2] != null && querySku[2] != "") {
	        querySelection.colorCode = querySku[2];
	        doDebug(funcName+"Color code: " + querySelection.colorCode);
	    }
	    var queryInseam = getQueryVariable("inseamLength_0");
	    if (queryInseam != null && queryInseam != "") {
	    	querySelection.hemmed = true;
	        if (queryInseam == "UNF") {
	            querySelection.hemming.finished = false;
	        }
	        querySelection.hemming.length = queryInseam;
	        doDebug(funcName+"Inseam: " + querySelection.hemming.length);
	        doDebug(funcName+"Finished? " + querySelection.hemming.finished);
	    }
	    var queryCuffed = getQueryVariable("cuffed_0");
	    if (queryCuffed != null && queryInseam != "") {
	        if (parseInt(queryCuffed) === 1) {
	            queryCuffed = true;
	        } else if (parseInt(queryCuffed) === 0) {
	            queryCuffed = false;
	        }
	        querySelection.hemming.cuffed = queryCuffed;
	        doDebug(funcName+"Cuffed?" + querySelection.hemming.cuffed);
	    }
	    /*==========
	        Quantity
	    ==========*/
	    var queryQuantity = getQueryVariable("qty_0");
	    if (queryQuantity != null && queryQuantity != "" && parseInt(queryQuantity) > 0) {
	        querySelection.quantity = parseInt(queryQuantity);
	        doDebug(funcName+"Quantity: " + querySelection.quantity);
	    }
	    /*==========
	        Gift box
	    ==========*/
	    var queryGiftBox = getQueryVariable("giftBoxing_0");
	    if (queryGiftBox != null && queryGiftBox != "") {
	        querySelection.giftBox = true;
	        doDebug(funcName+"Gift box? " + querySelection.giftBox);
	    }
	    /*=====================
	        Monogramming basics
	    =====================*/
	    var queryMonoTypeCode = getQueryVariable("monoTypeCode_0");
	    if (queryMonoTypeCode != null && queryMonoTypeCode != "") {
	        querySelection.monogrammed = true;
	        querySelection.monogram = new monogram(sAIndex,thisSbg);
	        querySelection.monogram.selection.style = queryMonoTypeCode;
	        doDebug(funcName+"Monogrammed?" + querySelection.monogrammed);
	        doDebug(funcName+"Monogram Style: " + querySelection.monogram.selection.style);
	    }
	    var queryMonoLoc = getQueryVariable("monoLoc_0");
	    if (queryMonoLoc != null && queryMonoLoc != "") {
	        querySelection.monogram.selection.location = queryMonoLoc;
	        doDebug(funcName+"Monogram Location: " + querySelection.monogram.selection.location);
	    }
	    /*===========================
	        Monogram value processing
	    ===========================*/
	    var queryMonoValue = decodeURIComponent(getQueryVariable("monoValue_0"));
	    var queryMonoIsInitial = getQueryVariable("monoIsInitial_0");
	    if (queryMonoValue != null && queryMonoValue != "") {
	        if (queryMonoIsInitial != null && queryMonoIsInitial != "" && queryMonoIsInitial == "1") {
	            // Three Initials
	            if (queryMonoValue.length > 1) {
	                querySelection.monogram.selection.type = "Initials";
	                querySelection.monogram.selection.multiInitialArr[0] = queryMonoValue.charAt(0);
	                querySelection.monogram.selection.multiInitialArr[1] = queryMonoValue.charAt(1);
	                querySelection.monogram.selection.multiInitialArr[2] = queryMonoValue.charAt(2);
	                doDebug(funcName+"Multi Initials: " + querySelection.monogram.selection.multiInitialArr.join(","));
	            } else {
	            // Single Initial
	                querySelection.monogram.selection.type = "Single Initial";
	                querySelection.monogram.selection.siText = queryMonoValue;
	                doDebug(funcName+"Singline Initial: " + querySelection.monogram.selection.siText);
	            }
	        } else {
	            // Assume it's a name or word
	            querySelection.monogram.selection.type = "Word";
	            querySelection.monogram.selection.wordText = queryMonoValue;
	            doDebug(funcName+"Word Text: " + querySelection.monogram.selection.wordText);
	        }
	        // Check for new line characters.  If they exist, it's a multi-line.
	        if (queryMonoValue.match(/\|/) != null) {
	            querySelection.monogram.selection.type = "Multi-Line";
	            querySelection.monogram.selection.multiLineArr = queryMonoValue.split("|");
	            doDebug(funcName+"Multi Line: " + querySelection.monogram.selection.multiLineArr.join(","));
	        }
	        doDebug(funcName+"Monogram Type: " + querySelection.monogram.selection.type);
	    }
	     /*===========================
	        ship to
	    ===========================*/   
	    var queryAddressID = getQueryVariable("addressID_0");
	    // default to "me"
	    if (queryAddressID == "" || queryAddressID == null ) {
	    	queryAddressID = "-1";
	    }
	    querySelection.shipTo = queryAddressID;
	     doDebug(funcName+"leaving");
	    return querySelection;
	};
    this.sendChangeStyleMetric = function(){
		s_omtr = s_gi(s_account);
        s_omtr.linkTrackVars='products,events,eVar4,eVar19';
        s_omtr.linkTrackEvents='prodView,event2,event28,event29,event30,event31';
        s_omtr.events='prodView,event2,event28,event29,event30,event31';    
		s_omtr.products=';' + priceCode[selection.style] + '_' + selection.style + ';;;event28=' + sA[saKey].totalSku + '|event29=' + sA[saKey].totalAvailSku + '|event30=' + sA[saKey].totalNotAvailSku + '|event31=' + sA[saKey].totalBackOrderSku + ';evar4=' + getCategoryID();
        s_omtr.tl(true,'o','link');
    }
    
    this.sendDirectStyleSearch = function(){
   	 	var action = getQueryVariable("action");
   	 	var query = getQueryVariable("query");
		s_omtr = s_gi(s_account);
		s_omtr.linkTrackVars='prop1,prop2,prop4,events,eVar1,eVar3,eVar4,eVar12,products';
		s_omtr.linkTrackEvents='prodView,event1,event2,event28,event29,event30,event31';
		s_omtr.events='prodView,event1,event2,event28,event29,event30,event31';
		s_omtr.products=';' + priceCode[selection.style] + '_' + selection.style + ';;;event28=' + sA[saKey].totalSku + '|event29=' + sA[saKey].totalAvailSku + '|event30=' + sA[saKey].totalNotAvailSku + '|event31=' + sA[saKey].totalBackOrderSku + ';evar4=' + getCategoryID();
		s_omtr.prop1= query;
		s_omtr.prop2=1;
		s_omtr.prop4='Item Number';
		s_omtr.evar1= query;
		s_omtr.evar3='search';
		s_omtr.evar12='Item Number';
		s_omtr.tl(true,'o','link'); 
    }
    
    // constructor
    this.buildSNArray();
    this.buildUI();
    this.buildShipToList();
    this.registerEvents();
    this.getStyleNumber();
    this.selectDefaultColor();
}
/*========================================================================================================================
    Uses the dynamic selection functions in a buy grid object to make selections for either
    a fit change or a modification.
    buyGrid - A buy grid object
    selObj - A selection object
========================================================================================================================*/
function makeBuyGridSelections(buyGrid, selObj) {
    var funcName = "[makeBuyGridSelections] ";
	doDebug(funcName+"buyGrid="+buyGrid);
	doDebug(funcName+"selObj.colorCode="+selObj.colorCode+" sizeCode="+selObj.sizeCode+" sizeCode1="+selObj.sizeCode1+" sizeCode2="+selObj.sizeCode2);
    /*
    if (selObj.style != null && selObj.style != "") {
        buyGrid.selectMainFeatureType(selObj.viewID);
    } else {
        doDebug("[selectTheOldStuff] There is no style number.  Not selecting anything.");
        return false;
    }
    */
    if (selObj.featureCodes != null && selObj.featureCodes.length > 0) {
        buyGrid.selectFeatureTypes(selObj.featureCodes);
    }
    if (selObj.colorCode != null && selObj.colorCode != "" && selObj.colorCode != undefined) {
        buyGrid.selectColor(selObj.colorCode);
    }
    if (selObj.sizeCode1 != "" && selObj.sizeCode2 != "") {
        buyGrid.setSizeCode1(selObj.sizeCode1);
   		buyGrid.setSizeCode2(selObj.sizeCode2);
   		buyGrid.selectSize(selObj.sizeCode1);
   		buyGrid.setSizeCode(selObj.sizeCode);
    }
    if (selObj.sizeCode != null && selObj.colorCode != "" && selObj.colorCode != undefined) {
        // also covers pants waist size
        buyGrid.selectSize(selObj.sizeCode);
    }
    if (selObj.hemming.length != null && selObj.hemming.length != "" && selObj.hemming.length != undefined) {
        buyGrid.selectPants(selObj.hemming, selObj.sizeCode);
    }
    if (selObj.giftBox === true || selObj.giftBox === "true") {
        buyGrid.selectGiftBox();
    }
    doDebug(funcName+ "selObj.monogrammed = " + selObj.monogrammed);
    if (selObj.monogrammed === true || selObj.monogrammed === "true") {
        buyGrid.selectMonogram(selObj.monogram);
    }
    doDebug(funcName+"selObj.quantity = " + selObj.quantity);
    if (parseInt(selObj.quantity) > 0) {
        buyGrid.selectQuantity(parseInt(selObj.quantity));
    }
    if (selObj.shipTo != null && selObj.shipTo != "" && selObj.shipTo != undefined) {
        buyGrid.selectShipTo(selObj.shipTo,selObj.shipToNickname);
    }
    // always copy the itemID forward for modify condition
    if (selObj.itemID !== undefined) {
    	buyGrid.selection.itemID = selObj.itemID;
   	}
};
/*===================================================
    When settings need to be saved, this is called.
    It should be the first thing in the query string.
===================================================*/
function buildQueryStringFromSelection(selection) {
    var str = "?fitChange=true&";
    str = str + "sku=" + selection.style + selection.sku.mediaCode + selection.sku.checkDigit + ":" + encodeURIComponent(selection.sizeCode) + ":" + selection.colorCode + 
    "&qty=" + selection.quantity;
    if (selection.itemID != null && selection.itemID != "") {
        str = str + "&itemID=" + selection.itemID;
        isUpdateItem = true;
    }
    if (selection.giftBox) {
        str = str + "&giftBoxing=true";
    }
    if (selection.monogrammed) {
        str = str + "&monoLoc=" + selection.monogram.location;
        str = str + "&monoTypeCode=" + selection.monogram.style;
        var monoValue;
        switch (selection.monogram.type) {
            case "Single Initial":
                str = str + "&monoIsInitial=true";
                monoValue = selection.monogram.siText;
                break;
            case "Initials":
                str = str + "&monoIsInitial=true";
                monoValue = selection.monogram.multiInitialArr.join("");
                break;
            case "Multi-Line":
                monoValue = selection.monogram.multiLineArr.join("|");
                break;
            default:
                monoValue = selection.monogram.wordText;
                break;
        }
        str = str + "&monoValue=" + encodeURIComponent(monoValue);
        str = str + "&monoColor=" + selection.sku.monoThreadColorCode;
    }
    if (selection.hemmed == true) {
        if(selection.hemming.finished == false) {
            str = str + "&inseamLength=UNF";
        } else if(selection.hemming.length != null && selection.hemming.length != "") {
            str = str + "&inseamLength=" + selection.hemming.length;
            if (selection.hemming.cuffed) {
                str = str + "&cuffed=true";
            }
        }
    }
    if (selection.dropShipDayPhone != null && selection.dropShipDayPhone != "") {
        var dropShipDayPhone= "&primContactPhone=" + selection.dropShipDayPhone;
        if (selection.dropShipDayPhoneExt != null && selection.dropShipDayPhoneExt != "") {
            dropShipDayPhone = dropShipDayPhone + "/"  + selection.dropShipDayPhoneExt;
        }
        str = str + dropShipDayPhone;
    }       
    if (selection.dropShipAltPhone != null && selection.dropShipAltPhone != "") {
        var dropShipAltPhone= "&secContactPhone=" + selection.dropShipAltPhone;
        if (selection.dropShipAltPhoneExt != null && selection.dropShipAltPhoneExt != "") {
            dropShipAltPhone = dropShipAltPhone + "/"  + selection.dropShipAltPhoneExt;
        }
        str = str + dropShipAltPhone;
    }
    if (selection.shipTo != null && selection.shipTo != "") {
        str += "&addressID=" + selection.ShipTo;
    }
    doDebug("[buildQueryStringFromSelection] string=" + str);
    return str;
}
function getImageSetCollectionForStyle(srcStyle) {
	for (i = 0; i < styleImageSetLookup.length; i++) {
	    for (j = 0; j < styleImageSetLookup[i].length; j++) {
	    	if (srcStyle == styleImageSetLookup[i][j]) {
	    		doDebug("[getImageSetCollectionForStyle] image set match " + i + " on style " + srcStyle);
	    		return i;
	    	}
	    }
	}
	return 0;
}
/*=============================================================================================
    When an item is modified from the shopping bag, a product page will be called with a query
    string containing variables that will be converted into a selection object.  This selection
    object will be passed to makeBuyGridSelections().
==============================================================================================*/
function trimLeadingZeros(srcString) {
  var len = srcString.length;
  var res = "";
  var nonZeroFound = false;
  for (i = 0; i < len; i++) {
    var ch = srcString.charAt(i);
    if (ch != '0') {
      nonZeroFound = true;
    }
    if (nonZeroFound) {
      res = res + ch;
    }
  }
  return res;
}
function arrayContains(arr, val) {
  var i;
  for (i = 0; i < arr.length; i++) {
      if (arr[i] == val) {
          return i;
      }
  }
  return -1;
};
function findNonDigitLocation(src) {
	if (src == undefined || src.length < 2) {
		return -1;
	}
	var c = src.charAt(0);
	if (isDigit(c) == false) {
		return -1;
	}
	var len = src.length;
	var i;
	for (i = 0; i < len; i++) {
		c = src.charAt(i);
		if (isDigit(c) == false) {
			return i;
		}
	}
	return -1;
};
function parseSizeCode(srcSizeCode) {
    var funcName = "[parseSizeCode] ";
    var testString = srcSizeCode;
    var result = new Array();
    var length = testString.length;
    var spaceLoc = 0;
    var firstNonDigitLoc = 0;
    // doDebug(funcName+"("+srcSizeCode+")");    
    spaceLoc = testString.indexOf(" ");
    firstNonDigitLoc = findNonDigitLocation(testString);
    var firstNonDigitChar = "";
    if (firstNonDigitLoc >= 0) {
        firstNonDigitChar = testString.charAt(firstNonDigitLoc);
    }
    var hFound = (firstNonDigitChar == 'H') ? true : false;
    var xFound = (firstNonDigitChar == 'X') ? true : false;
    var wFound = (firstNonDigitChar == 'W') ? true : false;
    var tFound = (firstNonDigitChar == 'T') ? true : false;
    // if an X or T is found this isn't an overloaded size code.
    if (xFound || tFound) {
        return result;
    }
    // if a non-digit character was found, if the non-digit character
    // is an H or W and it is also the last character in the size string then 
    // assume it is not an overloaded size code: ex: 10H or 22W.
    // if the first non-digit charaacter is an H or a W assume that all 
    // characters beyond that one are the second size.
    if (firstNonDigitLoc >= 0) {
        if (hFound || wFound) {
            if (firstNonDigitLoc == (length-1)) {
                return result;
            } else {
                var offset = (hFound || wFound) ? 1 : 0;
                result.push(trim(testString.substring(0, firstNonDigitLoc+offset)));
                result.push(trim(testString.substring(firstNonDigitLoc+offset)));
                return result;
            }
        } else {
            result.push(trim(testString.substring(0,firstNonDigitLoc)));
            result.push(trim(testString.substring(firstNonDigitLoc)));
            return result;
        }
    }
    // if we have made it to here we have now taken care of all X, H and W
    // cases. the only think left is if there is a space between the 2 fields.
    // ex. 15 34
    if (spaceLoc > -1) {
        result.push(trim(testString.substring(0,spaceLoc)));
        result.push(trim(testString.substring(spaceLoc+1)));
        return result;
    }
    return result;
};
