jQuery.noConflict();
// Initialize detailPageItems on page ready
jQuery(function() {
        detailPageItems.initialize();
        //requires amazon.jquery.tabs to work properly
        if(jQuery.fn.tabs){
            var newOptions = {
                tabsClass: '.tabHeaders > li',
                tabsSelected: '.selected',
                tabPanels: '.tab',
                tabPrefix: '#productInfoTab'
            }
            jQuery(".productInfoTabs").tabs(newOptions);
        }    
    });

(function($){
        
        $.fn.pluginInit = function() {
                var callee = arguments.callee;
        if (this.length > 1) {
            for (var i = 0; i < this.length; i++) {
                $(this[i]).callee.apply(this, arguments);
            }
            return this;
        }
    }; 
    /**
     * A jQuery abstract (has no data, but defines some methods) base class for variation selections.
     * @param {Object} initializer
     */
    $.fn.variationBase = function(initializer){
        this.setInitializer = function(initializer) {
            if (initializer && initializer.model) {
                this.model = initializer.model;
            }
        };
        this.getValues = function(){	      
            return this.model.values;
        };
        this.getValueFromIndex = function(attr_idx) {
            return this.getValues()[attr_idx];
        };
        this.getIndexFromValue = function(attr_val) {
            var rval = -1;
            this.getElements().each(function(i,elm){
                    if(!elm) return true; // continue
                    if($(elm).find("input").val() == attr_val || $(elm).find("a").text() == attr_val) {
                        rval = i;
                        return false;
                    }
                });
            return rval;
        };
        this.getElementFromIndex = function(idx) {
            return this.getElements().eq(idx);
        };
        this.getSelectedIndex = function() {
            return this.getSelectedElement().index();
        };
    };

    /**
     * A jQuery class for variations displayed as swatches.
     * @param {Object} initializer
     */
    jQuery.fn.variationSwatches = function(initializer){
        if(this.length > 1) return $.fn.pluginInit.call(this, initializer);
                
        var $this = this;
        var base = new $.fn.variationBase;
        $.extend(true, this, base);
        this.setInitializer(initializer);
        var $this = this;

        this.getElements = function() {
            return $("ul.colorSwatches li", $this);
        };
        this.getSelectedElement = function() {
            return this.getElements().filter(".selected");
        };
        this.setSelectedValue = function(val) {
            this.getSelectedElement().removeClass("selected");
            return this.getElementFromValue(val).eq(0).addClass("selected");            
        };
        this.getElementFromValue = function(val) {
            return this.getElements().filter(function() {
                    var selection = $("input", this);
                    if(selection.length > 0) return val == selection.val();
                    selection = $("a",this);
                    return val == selection.text();
                });
        };
        this.getSelectedValue = function() {
            var rval = null;
            var selection = $("input", this.getSelectedElement());
            if(selection.length > 0) rval = selection.val();
            if(!rval) {
                selection = $("a", this.getSelectedElement());
                rval = selection.text();
            }            
            return rval;
        };
        this.enableElement = function(idx) {	        
            var elm = this.getElementFromIndex(idx);
            return elm.removeClass("swatchGray").removeClass("noOffersAvailable");
        };
        
        this.disableElement = function(idx) {   
	       var elm = this.getElementFromIndex(idx);
           return elm.addClass("swatchGray").addClass("noOffersAvailable");
        };            
        this.enableElementFromValue = function(val) {
            var idx = this.getIndexFromValue(val);
            return this.enableElement(idx);
        };
        this.disableElementFromValue = function(val) {	     
            var idx = this.getIndexFromValue(val);           
            return this.disableElement(idx);
        };         
             
        this.enableEMWAElementFromValue = function(val) {
            var elm = this.getElementFromValue(val);
            return elm.addClass("emwaEnabled");
        };
        this.disableEMWAElementFromValue = function(val) {	     
            var elm = this.getElementFromValue(val);
            return elm.removeClass("emwaEnabled");
        }; 
        this.checkAttributeMap = function(attributeMap,attribute){
	        
	        for ( i in attributeMap ){
		        if ( attributeMap[i].attributeName == attribute && attributeMap[i].attributeValue == true ){
			        return true;
		        }
	        }   
	        
	        return false;	        
        };
                
        /**
         * setElementStates() is a required method of this system. It accepts a list of variation values.
         * It adds css classes to distinguish the buyable, non buyable and emwa states.
         * @param {variation value list} values
         */
       
           this.setElementStates = function(values) {     
	        
	           
           var model_values = this.getValues(); 
           var attributeMap;
	        for(var i in model_values) {
               
                for (j in values) {	  
	              attributeMap = values[j].attributes;	                      
	              contains = false;       	                
	              
                  if ( values[j].dimensionValue == model_values[i] &&  this.checkAttributeMap(attributeMap,"buyable")) {		                    
	                   contains = true;
	                   this.enableElementFromValue(model_values[i]);
	                   this.disableEMWAElementFromValue(model_values[i]);    
	                   break;             
                  } else if ( values[j].dimensionValue == model_values[i] && this.checkAttributeMap(attributeMap,"emwa")) {
	                  contains = true;
                          this.enableElementFromValue(model_values[i]);
	                  this.enableEMWAElementFromValue(model_values[i]);
	                  break;
                  }
                  
                }
                
                if ( ! contains ) {	             
                      this.disableEMWAElementFromValue(model_values[i]); 	
	              this.disableElementFromValue(model_values[i]);  
                }
                
                if ( this.getSelectedValue() == model_values[i] ) {
	                this.setSelectedValue(model_values[i]);
                }
            } 
            return this.getElements();
        };
        
        

        //
        // Swatches have a selection message; other variation selection elements do not
        $this.defaultMessage = $("#colorSwatchDefaultMsg").val();        
        /**
         * Return the selection message that was defined when the page was initially loaded.
         */
        this.getDefaultMessage = function() {
            return $this.defaultMessage;
        };
        /**
         * Set the selection message (usually the selected color)
         * @param {Object} msg
         */
          this.setSelectionMessage = function(colorElement, msg) {
               if ( jQuery(colorElement).length > 0 ) {
                    var parentSelector = jQuery(colorElement).parent().prev(".colorMsgLabel");
                    return $(parentSelector).text(msg);  
                }          
           };        
                
        /**
         * Swatches have element titles; other variation selection elements don't. The presence of titles enable the tootip
         * functionality of disabled swatches.
         * @param {boolean} othersAreSelected informs method about which messge to choose.
         */
        this.updateElementTitles = function(othersAreSelected) {	     
            this.getElements().each(function(index, domEle) {
                    if(!domEle) return true; // continue
                    var jEl = jQuery(domEle);            
                    if (jEl.hasClass("swatchGray")) {
                        if(!othersAreSelected) othersAreSelected = "";
                        jEl.attr("title", "Sorry, this color is not available in your selected " + othersAreSelected);
                    }
                    else if (jEl.hasClass("noOffersAvailable")) {
                        if(othersAreSelected)
                            {
                                jEl.attr("title", swatchMessages.colorTempUnavailableForThisSize); 
                            }
                        else
                            {
                                jEl.attr("title", swatchMessages.colorTempUnavailableForAllSizes); 
                            }
                    }
                    else {
                        jEl.attr("title", ""); 
                    }
                    jEl.bindTooltip();
                }
                );
        };
        return this;
    };

    /**
     * A jQuery class for variations displayed as a dropdown menu
     * @param {Object} vattr_model
     */
    $.fn.variationSelections = function(initializer){
        if(this.length > 1) return $.fn.pluginInit.call(this, initializer);
        var base = new $.fn.variationBase;
        $.extend(true, this, base);
        var $this = this;
        this.setInitializer(initializer);

        this.getElements = function() {
            return $("option", $this);
        };
        this.first_option = this.getElements().eq(0).clone();
        this.getSelectedElement = function() {
            return this.getElements().filter(function(){return $(this).attr("selected")});
        };
        this.setSelectedValue = function(val) {
            this.getSelectedElement().removeAttr("selected");
            return this.getElementFromValue(val).attr("selected", "selected");
        };
        this.getElementFromValue = function(val) {
            return this.getElements().filter(function() {return this.value==val;});
        };
        this.getSelectedValue = function(){
            var rval = this.getSelectedElement().val();
            if(rval == "") rval = null;
            return rval;
        };
        this.setSelectedIndex = function(idx) {
            return this.getElements().eq(idx).attr("selected", "selected");
        };
        this.getElementValues = function(){
	        var elms =   this.getElements();
	        var values = [];
	        for ( var i in elms ){
		       if ( elms[i].value != null  && elms[i].value != "" ) {
		          values.push(elms[i].value);   
	           }
			}	      
	        return values;
        };        
        this.enableElement = function(idx) {
            //
            // do nothing.
            // in the context of a drop down, enabling an option means simply leaving it in the list                     
            return this.getElementFromIndex(idx);
        };
        this.disableElement = function(idx) {
            //
            // remove this option from the list of available options
            // in the context of a drop down, disabling an option means removing it from the list
            return this.getElements().slice(idx, idx+1);
        };
        this.enableElementFromValue = base.enableElementFromValue;
        this.disableElementFromValue = base.disableElementFromValue;

        /**
         * See comments for the same method defined in variationSwatches()
         * 
         * @param {variation value list} values
         */
       
   
        this.checkAttributeMap = function(attributeMap,attribute){
	        
	        for ( i in attributeMap ){
		        if ( attributeMap[i].attributeName == attribute && attributeMap[i].attributeValue == true ){
			        return true;
		        }
	        }   
	        
	        return false;	        
        };
        
        this.setElementStates = function(values) {
	        
	    var selectedValue = this.getSelectedValue();         
            /* disabling auto select
            if(values.length == 1) selectedValue = values[0].dimensionValue;
            */

            this.getElements().remove();
            $this.append(this.first_option); 
                
            for(var i in values) {	
                var attributeMap = values[i].attributes;
                var opt = $("<option/>");
                opt.val(values[i].dimensionValue);
                opt.text(values[i].dimensionValue);  
          
                
                if ( this.checkAttributeMap(attributeMap,"emwa") ) {
	                opt.attr("class","emwaOption");   
                }
                
               if(selectedValue == values[i].dimensionValue) 
                  opt.attr("selected", "selected");                  
                  $this.append(opt);
               } 
                         
            return this.getElements();
        };
        	
        this.updateElementTitles = function(othersAreSelected){
            // noop
        };
        return this;
    };

    /**
     * A jQuery class for variations displayed as a single hidden input
     * @param {Object} vattr_model
     */
    $.fn.variationHiddenInput = function(initializer){
        if(this.length > 1) return $.fn.pluginInit.call(this, initializer);
        var base = new $.fn.variationBase;
        $.extend(true,this,base);
        var $this = this;
        this.setInitializer(initializer);

        //
        // reuse a few (required) methods from variationSelections              
        base = new $.fn.variationSelections;
        this.getSelectedValue = base.getSelectedValue;
        this.updateElementTitles = base.updateElementTitles;
        this.enableElementFromValue = base.enableElementFromValue;
        this.disableElementFromValue = base.disableElementFromValue;
        this.enableElement  = base.enableElement;
        this.disableElement = base.disableElement;

        this.getElements = function() {
            return $("input", $this).eq(0);
        };

        this.first_option = this.getElements().eq(0).clone();
        this.getSelectedElement = function() {
            return this.getElements().eq(0);
        };
        this.getElementFromValue = function(val) {
            return this.getElementFromIndex(0);
        };
        this.setSelectedValue = function(val) {
            return this.getElementFromIndex(0);
        };
        this.setSelectedIndex = function(idx) {
            return this.getElements().eq(idx);
        }
        //
        // for this type of variation, this required method is a noop
       
        this.setElementStates = function(values){
	        return this.getElements();
        }
        this.setSelectionMessage = function(elem, msg) {};        
                
        return this;
    };
})(jQuery);

/**
 * This class is comprised of a path and a value. The path is represented as a list of strings.
 * The matches() method is used by the framework to determine if a current selection state matches
 * an asin. A null path element is treated like a wildcard. 
 * 
 * Example:
 * 
 * pvp = new PathValuePair(["S", "Orange"], "BT00C6CZ7E");
 * pvp.matches(["S", "Orange"]);  // true
 * pvp.matches(["S", null]);      // true, think S/wildcard
 * pvp.matches([null, "Orange"]); // true, think wildcard/Orange
 * pvp.matches([null, null]);     // true, think wildcard/wildcard
 * pvp.matches(["S"]);            // false, path is wrong length
 * pvp.matches(["L", null]);      // false, first path element isn't "S"
 * pvp.matches(["S", "Purple"]);  // false, second path element isn't "Orange"
 */
function PathValuePair(path, value) {
    var $this = this;    
    $this.path = path;    
    $this.value = value;

    this.matches = function(path_expression) {
        if(path_expression.length != $this.path.length) return false;
        for(i = 0; i < $this.path.length; ++i) {
            var p = path_expression[i];
            var thisp = $this.path[i];
            if(typeof(p) != 'undefined' && p != "" && p != " " && typeof(thisp) != 'undefined' && thisp != "" && thisp != " " && p != $this.path[i]) {
                return false;
            }
        }
        return true;
    };
    return $this;
};

function VariationDimensionMap(name, variationData){	
	var $this = this;
	$this.name = name;
	$this.variationData =  variationData;
	
	return $this;	
};


function VariationData(dimensionValue, attributes){	
	var $this = this;
	$this.dimensionValue = dimensionValue;
	$this.attributes = attributes;
	
	return $this;
};

function attributeMap(attributeName, attributeValue){
    var $this = this;
	$this.attributeName = attributeName;
	$this.attributeValue = attributeValue;
	
	return $this;
};


(function($){
    /**
     * buyBoxModel wraps the json data model with a few useful methods. The most important method here is remainingVariants()
     * @param {Object} initializer
     */
    jQuery.fn.buyBoxModel = function(initializer){
        if(this.length > 1) return $.fn.pluginInit.call(this, initializer);
        var $this = this;
        $this.model = initializer.model;

        /**
         * Given a selection path, return the corresponding ASIN, if it exists.
         * @param {Object} selections
         */          
         
        this.getASINValue = function (selections,asinList){
                
	            for(var dim in selections) {      
	                if(selections[dim] != null && asinList != null && asinList[selections[dim]] != null) {
	                    asinList = asinList[selections[dim]];                   
	                } else {	                
	                    asinList = null;
	                    break;
	                }
	            }            
	            return asinList;
            }
                  
        this.getASIN = function(selections) {	        
            if(null == selections) return null;
            
            var buyableASINs = $this.model.buyableASINs;
            
            var emwaASINs = $this.model.emwaASINs;
            
            var asin;
            
            asin = this.getASINValue(selections,buyableASINs);
            
            if ( null == asin ){
	            asin = this.getASINValue(selections,emwaASINs);
            }
           
            return asin;
            
        };        
    
		this.checkIfElementExists = function(dimension, dimemsionList){
		for(var i=0; i<dimemsionList.length;i++){		      
			if ( dimension == dimemsionList[i] ) {			        
				return true;
			} 
		}
		return false;
		}
        
		
	
       
        /**
         * Merge the EMWA variations with Buyable variations
         * Create the VariationDimensionMap
         */          
         
        
        var buyableVariationDimensions = [];
        var emwaVariationDimensions = [];
        var allVariationDimensions = [];
        $this.variationDimensionsMap = [];
     
    
        for(var i in $this.model.variationDimensions) { 
	        var variationData = [];	       
	        
			buyableVariationDimensions = $this.model.variationDimensions[i].values.slice();
			if ( $this.model.emwaVariationDimensions && $this.model.emwaVariationDimensions[$this.model.variationDimensions[i].name]  ){
			   emwaVariationDimensions = $this.model.emwaVariationDimensions[$this.model.variationDimensions[i].name].slice();
			}
		
			allVariationDimensions = $this.model.variationDimensions[i].values.slice();
		
		    /* Add all buyable variationData */
	        for ( k in 	buyableVariationDimensions ){
		        variationData.push(new VariationData(buyableVariationDimensions[k],[new attributeMap("buyable",true)])); 
	        }
	        
	        for ( j in emwaVariationDimensions ) {
	            if (! $this.checkIfElementExists(emwaVariationDimensions[j],buyableVariationDimensions)) {		 		               	          
		            allVariationDimensions.push(emwaVariationDimensions[j]);
		            /* Add emwa variationData */
		            variationData.push(new VariationData(emwaVariationDimensions[j],[new attributeMap("emwa",true)]));    
	            } 
	        }
        
	        
	        $this.variationDimensionsMap.push(new VariationDimensionMap($this.model.variationDimensions[i].name,variationData));	   
	        $this.model.variationDimensions[i].values = allVariationDimensions.slice(); 
	             
        }
        
    
        //method to get merge in 2 arrays
        //
        // initialize pair lists, asinPairs and holePairs. Holes are
        // paths that don't resolve to an asin
                
        var pPairs = [];
        $this.asinPairs = pPairs;
        $this.holePairs = [];
        
        $this.emwaPairs = [];
        //
        // initialize a queue of paths
        var q = [];
        if($this.model && $this.model.variationDimensions &&
           $this.model.variationDimensions.length > 0 &&
           $this.model.variationDimensions[0].values) {
            for(var i in $this.model.variationDimensions[0].values) {
                var p = [$this.model.variationDimensions[0].values[i]];                
                q.push(new PathValuePair(p,null));
            }           
        }     
            
        var emwaASINs = $this.model.emwaASINs;
            
        while(q.length > 0) {
            var pPair = q.shift();
            var p = pPair.path;
            var dim = p.length;
            if(dim == $this.model.variationDimensions.length) {
                
                //
                // If the path's length equals the number of
                // dimensions of the buy box, save it               
                
                var asin = this.getASIN(p);
                var emwaAsin = this.getASINValue(p,emwaASINs);
              
                //Set EMWA pairs
                if ( emwaAsin ) {	                 
                    // Save the asin
                    pPair.value = emwaAsin;
                    $this.emwaPairs.push(pPair);
                }
                
                if (asin) {                    
                    //
                    // Save the asin
                    pPair.value = asin;
                    $this.asinPairs.push(pPair);
                } else {
                    //
                    // Save the hole

                    $this.holePairs.push(pPair);                                       
                }
            } else {

                //
                // add another element to the path, and push it onto
                // the queue

                for(var i in $this.model.variationDimensions[dim].values) {
                    var newPath = [];
                    jQuery.extend(true, newPath, p);
                    newPath.push($this.model.variationDimensions[dim].values[i]);
                    q.push(new PathValuePair(newPath, null));
                }
            }
        }
        
        var $paths = new Array();
        var $pathPair = [];	
		
		this.setOtherDimensionStatus = function ( pairs ,selections ){
		
			var vDimensions = $this.model.variationDimensions;       
			var dimensionArray = [];
			
			for(var i=0; i<vDimensions.length; ++i) {
				dimensionArray.push({});               
			}
			
			for(var i in pairs) {
			
				var path = pairs[i].path;
				
				for (var sdim in selections) {
					var selection = selections[sdim];  
					
					if(selection) {	                        
						/* We're only interested in holes/emwa due to selections */
						for (var dim in path) {
							//first we check if the path is really in the hole
							var tempPath = [];
							$.extend(true, tempPath, selections);
							tempPath[dim] = path[dim];
							
							
							for (var j in pairs) {
                                if (pairs[j].matches(tempPath)) {
    								dimensionArray[dim][path[dim]] = 1;
    								break;
								}
							}
						}     
					}
				}
			}
			return dimensionArray;
		}
		
		
        /**
         * Returns an object with the same structure as model.variationDimensions, but with only the values that are left to choose from.
         * Return value is intended for use in redrawing the selector elements.
         * @param {Object} selections -- a list of path elements, in the order defined by model.variationDimensions.
         * Each element must be a valid value in its dimension, or it must be null. Nulls act as wildcards.
         */
        this.remainingVariants = function(selections) {
	        
	                              
            //
            // Strategy of this method
            //
            // Overdetermine the set of dimension values to disable
            // using the list of holes. Don't disable in the selected
            // dimensions. Then, remove from that set asins whose path
            // matches the selection path. The dimension values that
            // remain are disabled.
            //
            // STEPS:
            // 1. Make a deep copy of variationDimensions for return
            // 2. Iterate over the list of hole paths, saving values in a set for disabling
            // 2.1 For each dimension in the hole path, save values in the other dimensions 
            // 3. Iterate over the list of asin paths, removing from the set those that match the selection path
            // 4. Remove the values collected in the set from the return value

          
           
            var rval = [];
            var emwaVal = [];
            $this.emwaRemainingVal = [];
            var vDimensions = $this.model.variationDimensions;           
            $.extend(true, rval, vDimensions);
            $.extend(true, emwaVal, vDimensions);
            
            var remainingValues = [];
            //
            // Save matching dimension values in a set
              
            emwaSets = [];      
            var valueSets = [];
           
            for(var i=0; i<vDimensions.length; ++i) {
                valueSets.push({});
                emwaSets.push({});
            }

            
            valueSets = this.setOtherDimensionStatus ($this.holePairs,selections);
            emwaSets = this.setOtherDimensionStatus ($this.emwaPairs,selections);                  
          
            for(var i in $this.asinPairs) {
                var pair = $this.asinPairs[i];
                if(pair.matches(selections)) {
                    for(var dim in pair.path) {
                        var value = pair.path[dim];                        
                        delete valueSets[dim][value];
                    }
                }
            }   
          
       
            for(var dim in vDimensions) {	            
	            var variationData = [];
	                      
	            var attributeName;
	            var attributeValue;
	            var addVariation = false;
	            
                var values = vDimensions[dim].values;                                
                for(var i in values) {
	              
	                var value = values[i];
	                addVariation =false;
	                
	               
	                if(valueSets[dim][value] == null) {		                                 
	                    attributeName = "buyable"; 
	                    addVariation =true;
                    }                   
	                
                    
	                 if(emwaSets[dim][value] != null) {	  		                              
	                    attributeName = "emwa";
	                    addVariation =true;
                    }
                    
                     if ( addVariation ) {
                        variationData.push(new VariationData(value,[new attributeMap(attributeName,true)]));   
                    }
                }                      
                      
                remainingValues.push(new VariationDimensionMap(vDimensions[dim].name,variationData));                
            } 
           
           
            return remainingValues;
        };

        /**
         * returns the numeric index of the given dimension name
         * @param {Object} dimension_name
         */
        this.getDimensionIndexFromName = function(dimension_name) {
            var vdims = $this.model.variationDimensions;
            for(var i in vdims) {
                if(vdims[i].name == dimension_name) return i;
            }
            return -1;
        };
        /**
         * Returns the corresponding selection path of the given
         * asin. This method is only called when the detail page
         * restores state after a sign-in loop.
         * @param {string} asin
         */
        this.getPathFromASIN = function(asin) {
            for (var i in $this.asinPairs) {
                var pair = $this.asinPairs[i];
                if (pair.value == asin) 
                    return pair.path;
            }
            return null;
        };
        /**
         * For a given selection path, returns true if it corresponds to an asin, false otherwise
         * @param {Object} path
         */
        this.isPathAvailable = function(path) {
            for (var i in $this.asinPairs) {	            
                var pair = $this.asinPairs[i];
                if (pair.matches(path))                    
                    return true;
            }
            return false;
        };              
        return this;
    };

    /**
     * This is the container of all selection elements on a detial
     * page. This is where a selection event is handled, and its most
     * important method is handleSelectionEvent
     * @param {list of variation elements} elms
     * @param {instance of buyBoxModel} buyBoxModel
     */
    jQuery.fn.selectionElements = function(elms, buyBoxModel){
        if(this.length > 1) return $.fn.pluginInit.call(this, initializer);
        var $this = this;
        $this.selms = $(elms);
        $this.handlers = [];
        $this.clickedDimensions = [];
        this.registerSelectionEventHandler = function(methodContext) {
            $this.handlers.push(methodContext);
        };
        $this.model = buyBoxModel;
        this.getElements = function() {
            return $this.selms;
        };
        this.getElementByIndex = function(idx) {
            return $this.getElements().get(idx);
        };
        this.getElementByName = function(dimensionName) {
            var idx = $this.model.getDimensionIndexFromName(dimensionName);
            return this.getElementByIndex(idx);
        };
        
        this.getASIN = function() {
            var asin = null;
            var selections = [];
            this.getElements().each(function(i,elm){	            
                    if(!elm) return true; // continue
                    var sv = elm.getSelectedValue();                    
                    if (null == sv) {
                        //
                        // if any selected value is null, set the list to null
                        selections = null;
                        return false;
                    }
                    else {
                        selections.push(sv);
                    }
                });       
            if(selections != null && selections.length > 0) {
                //
                // if any selected values were null, we can skip the call to get ASIN()                          
              asin = $this.model.getASIN(selections);              
            }            
            return asin;
        };
        this.setASIN = function(asin) {
            var path = $this.model.getPathFromASIN(asin);
            if(path) {
                for(var i in path) {
                    this.getElementByIndex(i).setSelectedValue(path[i]);
                }
            }
            this.notify();
            return this;
        };
        
        this.reset = function() {
            var $this = this;
            this.getElements().each(function(i,elm){
                    if(!elm) return true; // continue
                    var values = $this.model.model.variationDimensions[i].values;    
                  
                    elm.setElementStates($this.model.variationDimensionsMap[i].variationData);
                    var selectedValue = values.length == 1 ? values[0] : "";
                    elm.setSelectedValue(selectedValue);
                    elm.updateElementTitles(false);
                });
            this.notify();
        };
        /**
         * Method that is executed when user makes a selection
         * @param {Object} selectionIndex
         */
        this.handleSelectionEvent = function(selectionIndex) {	        
            var selectedValues = new Array(this.getElements().length);

            $this.clickedDimensions.push(selectionIndex);
            var newClickedDimensions = [];

            /**
            *
            * Loop through our clicked dimensions and cut off when you reach the last
            * dimension currently clicked; this resets everything after that.
            */
            for(i=0; i<$this.clickedDimensions.length; i++){
                newClickedDimensions.push($this.clickedDimensions[i]);
                if($this.clickedDimensions[i] == selectionIndex){
                      $this.clickedDimensions = newClickedDimensions;
                      break;
                }
            }
            
        
            var othersAreSelected = false;
            //
            // begin by building the path of selected values
            this.getElements().each(function(i,elm){
                    var sv = null;
                    //Only add to selected values if its part of clicked dimensions
                    for(k=0; k<$this.clickedDimensions.length; k++){
                        if( i == $this.clickedDimensions[k]){
                            if (elm) sv = elm.getSelectedValue();
                            selectedValues[i]=sv;
                            if (i != selectionIndex) {
                                //
                                // this bool informs the selection of title value for disabled swatches
                                othersAreSelected = (othersAreSelected || (sv != null));
                            } 
                        }
                    }

                    
                });
          
          
            
            var joinedSelectedLabels = this.joinLowerCaseAttributeLabels("/", true);
            if(othersAreSelected && joinedSelectedLabels) othersAreSelected = joinedSelectedLabels;


            if (!$this.model.isPathAvailable(selectedValues)) {
            
                //
                // Selection can't resolve to an asin. This can happen
                // when the user selects from the same variation twice
                // in a row
                
                for(var i in selectedValues) {
                    if(i != selectionIndex) selectedValues[i] = null;                    
                }
            }
                        
            //
            // toggle the values of the other elements
            var remaining = $this.model.remainingVariants(selectedValues);  
            this.getElements().each(function(i, elm){
                    if (i == selectionIndex || !elm) 
                        return true; // continue    
                        
                    elm.setElementStates(remaining[i].variationData);                                                                    
                    elm.updateElementTitles(othersAreSelected);
                });
            this.notify();
        };

        this.notify = function() {
            //
            // call the observers
            for(var i in $this.handlers) {
                var method = $this.handlers[i].method;
                var context = $this.handlers[i].context;
                method.apply(context);
            }
        };

        this.joinLowerCaseAttributeLabels = function(separator, includeSelected) {
            // the global swatchMessges contains lowercase labels for all variation attributes
            if(!window.swatchMessages || !swatchMessages.variationNames) return null;
            var rval = "";
            var $this = this;
            this.getElements().each(function(i, elm){
                    if (!elm) return true; // continue
                    var included = includeSelected ? elm.getSelectedValue() : !elm.getSelectedValue();
                    if (!included) return true; // continue
                    rval = rval + swatchMessages.variationNames[$this.model.model.variationDimensions[i].name] + separator;
                });
            return rval.substr(0, rval.length - separator.length);
        };
        return this;
    };
})(jQuery);
var detailPageItems = {
    // reference to JSON data object
    jsonData : null, 
    // current asin
    asin : null, 
    //price element
    priceElement : null, 
    //color swatch element
    colorSwatchElement : null, 
    // quantity element
    quantityElement : null, 
    //cart element
    cartElement : null, 
    //EmailMeWhenAvailable element
    emwaElement : null, 
    //sign in element
    signIn : null, 
    // list of swatches
    colorSwatch : null, 
    //emwa
    emwaButton:null,
    imageFrame:null,
    initialAsin:null,
    tafSigninLink:null,
    showFullDescriptionLink:null,
    //This string sets the "cartAddMethod" variable. This is used to populate Analytics info.
    cartAddMethodString: "",
    // add to cart button
    addToCartButton : null,
   
    initialize : function() {
        if(jQuery('.miniDetailPage').length > 0){
            this.cartAddMethodString = "Product Quick View";
        } else {
            this.cartAddMethodString = "Product Page";
        }
        this.jsonData = detailData;
        this.asin = jQuery("input:hidden[name=item.0.asin]");
        this.initializePriceElement();
        this.buyBoxModel = new jQuery.fn.buyBoxModel({
                "model": detailData.buyBox.model
            });
                        
        //
        // color_name and size_name are still special. Find their indexes in the buy box model,
        // then find them in the dom, then insert them in the selectionElements structure.
        var size_name_dim_idx = this.buyBoxModel.getDimensionIndexFromName("size_name");
        var color_name_dim_idx = this.buyBoxModel.getDimensionIndexFromName("color_name");
        var color_model = {"model": detailData.buyBox.model.variationDimensions[color_name_dim_idx]};
        if(jQuery("#colorSwatches").find("input[name=item.0.color]").length > 0) {
            this.colorSwatchElement = jQuery("#colorSwatches").variationHiddenInput(color_model);
        } else {
            this.colorSwatchElement = jQuery("#colorSwatches").variationSwatches(color_model);
        }
        var sElements = new Array(this.buyBoxModel.model.variationDimensions.length);

        var size_model = {};
        if(size_name_dim_idx >= 0) {
            size_model = {"model" : detailData.buyBox.model.variationDimensions[size_name_dim_idx]};
        }
        var sizeElement;
        if(jQuery("#size_dropdown").find("input[name=item.0.size]").length > 0) {
            sizeElement = jQuery("#size_dropdown").variationHiddenInput(size_model);
        } else {
            sizeElement = jQuery("#size_dropdown").variationSelections(size_model);
        }
        if(sizeElement.length > 0) {
            sElements[size_name_dim_idx] = sizeElement;
        }
        if (this.colorSwatchElement.length > 0) {
            sElements[color_name_dim_idx] = this.colorSwatchElement;
        }
            
        //
        // All the other dimensions must appear as id dimension_name + "_dropdown"
        for(var i in this.buyBoxModel.model.variationDimensions) {
                var vd = this.buyBoxModel.model.variationDimensions[i]; 
                if(vd.name == "size_name" || vd.name == "color_name") continue;
                var elm = jQuery("#" + vd.name + "_dropdown").variationSelections({"model" : vd});
                sElements[i] = elm;
        }
        this.selectionElements = new jQuery.fn.selectionElements(sElements, this.buyBoxModel);
        this.selectionElements.registerSelectionEventHandler({
                "method": this.updateItems,
                    "context": this
                    });
        this.selectionElements.registerSelectionEventHandler({"method": this.updateImage, "context":this});
        this.selectionElements.registerSelectionEventHandler({"method": this.changeAmazoom, "context":this});
        var cse = this.colorSwatchElement;
        var updateSwatchMessage = function() {
            var msg = cse.getSelectedValue();
            if (msg) {
               cse.setSelectionMessage(cse.getSelectedElement(), msg);
            }           
        };
        this.selectionElements.registerSelectionEventHandler({
                "method": updateSwatchMessage,
                    "context": this
                    });                  
        this.quantityElement = jQuery("[name=item.0.qty]");
        this.cartElement = jQuery("#addToCart");
        this.emwaElement = jQuery("#emwa");
        this.signIn = jQuery("#eSignIn");
        this.signInRedirectQuery = jQuery("#signInRedirectQuery");        
        this.emwaButton=jQuery("#emwaButton");
        this.tafSigninLink=jQuery("#tellAFriendSignInRedirect");
        this.showFullDescriptionLink=jQuery("#showFullDescription");
        this.addToCartButton = jQuery("#addToCartButton");
        this.bindElementWithEvents();
        this.setDefaultSwatchStates();
        // update items in case of single size/color at load time

        this.initialAsin=this.asin.val();
        this.selectionElements.reset();
        this.restoreState();
    }
    , isBaseProduct : function() {
        if(window.detailData && detailData.currentAsinData) {
            if (detailData.currentAsinData.isVariationalParent != null && detailData.currentAsinData.isVariationalParent)
                return false;
            else
                return detailData.currentAsinData.Asin == this.asin.val();
        }
        else {
            return false;
        }
    }
    , initializePriceElement : function() {
        var priceElement = jQuery(".productDetailPrice");
        var definitionList = priceElement.find("dl");
        var youSaveLabelElm = priceElement.find("dt.savings");
        var youSaveElement  = priceElement.find("dd.savings");

        //
        // If savings not initialized, add invisible youSave section
        // so buyable items can show savings

        if(youSaveLabelElm.length == 0 || youSaveElement.length == 0) {
            youSaveLabelElm.remove();
            youSaveElement.remove();
            youSaveLabelElm = jQuery("<dt/>").attr("class", "savings");
            definitionList.append(youSaveLabelElm);
            youSaveElement = jQuery("<dd/>").attr("class", "savings");
            definitionList.append(youSaveElement);
        }

        this.initialPriceElement = priceElement.clone();
    }
    , //all the event bindings for detail page goes here
    bindElementWithEvents : function() {	   
        this.addToCartButton.bindTooltip({considerParent: false, paddingTop: 8});
        var parentThis = this;
        var selms = jQuery(parentThis.selectionElements.selms);
        selms.each(function(i, elm) {
            if(!elm) return true; // continue
            var m=function(){	          
                parentThis.selectionElements.handleSelectionEvent(i);
            };
            elm.change(m);
        });

        // bind onchange event for quantity
        if(this.quantityElement.length > 0) {
            this.quantityElement.bind("change", function() {
                    jQuery("#addToCartErrMsg").hide();
                });
        }
        // bind onclick for cart
        if(this.cartElement.length > 0) {
            var formObj = jQuery('#addItemMainFormFloating');
            formObj.submit( function() {
                    parentThis.processAddToCartButtonClick(this);
                    return false; 
                });
     
        }
        //bind onclick for show fill description (View More)
        if(this.showFullDescriptionLink.length > 0)
            {
                this.showFullDescriptionLink.click(function(){
                        jQuery("#productDescriptionContent").html(productDescription.description);
                        parentThis.showFullDescriptionLink.hide();
                        return false;
                    });
            }
       
        this.emwaButton.click(function(){
                EmwaPopoverItem.showEMWAPopUp(parentThis.asin.val(),null);
            });
        this.showJsVersion();
        this.hideNonJsVersion();
        //bind swatch events
        this.findAndAttachSwatchEvents();
        //bind quantity events
        if(this.quantityElement.length > 0) {
            this.quantityElement.bind('change', function() {
                    if(parentThis.quantityElement.val() > 0) {
                        parentThis.addToCartButton.attr('title','');
                    } else {
                        var msg = jQuery("input:hidden[name=quantityInvalidMessage]").val();
                        parentThis.addToCartButton.attr('title',msg);
                    }
                });
        }
    }
    , //update items in detail page
    updateItems : function() {	    
        var asinVal = this.selectionElements.getASIN();
        if(asinVal != null) {
            this.asin.val(asinVal);
            //update the availability message to be displayed
            this.updateAvailability(asinVal);
            var showEMWA = (this.jsonData.asinData[asinVal].isAsinAvailable == "false" && this.jsonData.asinData[asinVal].isEmailMeWhenAvailable == "true") ? asinVal : "";            
            jQuery("#dialogButtons").find("input[name=asin]").attr("value", asinVal);
            this.updateEMWA(showEMWA);
            tafData.tafAsin=asinVal;
        }
        else if(!this.isBaseProduct()) {
            //
            // If not a base product, clear the asin

            this.asin.val("");
            this.updateAvailability(asinVal);
            this.updateEMWA("");
            tafData.tafAsin=this.initialAsin;
        } else {

            //
            // this is a base product

            asinVal = this.asin.val();
        }        
        this.updateAddToCartButton(asinVal);
        this.updatePrice();
        if(this.quantityElement.length > 0)this.updateQuantity(asinVal);
        if(this.tafSigninLink.length>0) 
            this.updateTAFRedirectURLString(); 
    }
    , updatePrice : function() {
        var asinVal = this.selectionElements.getASIN();
        if(!asinVal && this.isBaseProduct()) {
            asinVal = this.asin.val();
        }
        var newPriceElement = this.initialPriceElement.clone();
        if(asinVal != null && asinVal != "") {
            //Get the elements associated with price
            var ourPriceLabelElm = newPriceElement.find("dt.salePrice");
            var ourPriceElement  = newPriceElement.find("dd.salePrice");
            var ourPriceNonSaleLabelElm = newPriceElement.find("dt.price");
            var ourPriceNonSaleElement  = newPriceElement.find("dd.price");
            var regularPriceLabelElm = newPriceElement.find("dt.listPrice");
            var regularPriceElement  = newPriceElement.find("dd.listPrice");
            var youSaveLabelElm = newPriceElement.find("dt.savings");
            var youSaveElement  = newPriceElement.find("dd.savings");
            // fetch all price data
            var jda = this.jsonData.asinData && this.jsonData.asinData[asinVal];
            var regularPrice = jda && jda.formattedRegularPrice;
            var buyingPrice = jda && jda.formattedBuyingPrice;
            var youSaveAmount = jda && jda.youSaveAmountOnRegularPrice;
            var youSavePercent = jda && jda.youSavePercentOnRegularPrice;
            // Store validity
            var regularPriceValid = (regularPrice != null && regularPrice != "");
            var buyingPriceValid = (buyingPrice != null && buyingPrice != "");
            var isSaleItem = (buyingPriceValid && regularPriceValid && parseFloat(buyingPrice.substr(1)) < parseFloat(regularPrice.substr(1))) ? true : false;
            if(ourPriceElement.length > 0 || ourPriceNonSaleElement.length > 0) {
                var ourPriceLabelText = "";
                var classToUse = "price";
                if(isSaleItem) {
                    ourPriceLabelText = saleLabel;
                    classToUse = "salePrice";
                }
                if(buyingPriceValid) {
                    ourPriceLabelElm.html(ourPriceLabelText);
                    ourPriceLabelElm.attr("class",classToUse);
                    ourPriceElement.html(buyingPrice);
                    ourPriceElement.attr("class",classToUse);

                    ourPriceNonSaleLabelElm.html(ourPriceLabelText);
                    ourPriceNonSaleLabelElm.attr("class",classToUse);
                    ourPriceNonSaleElement.html(buyingPrice);
                    ourPriceNonSaleElement.attr("class",classToUse);
                }
            }
            if(regularPriceElement.length > 0 || ourPriceNonSaleElement.length > 0) {
                if(buyingPriceValid && regularPriceValid) {
                    if(isSaleItem){
                        regularPriceElement.html(regularPrice);
                        regularPriceElement.attr("class","listPrice");
                        youSaveLabelElm.text(youSaveLabel);
                        youSaveElement.text(youSaveAmount+" ("+youSavePercent+")");
                    }else{
                        regularPriceElement.html("");
                    }
                    newPriceElement.find('.productPricingMessage').hide();
                } else {
                    newPriceElement.find('.productPricingMessage').show();
                }
            }
        }
        jQuery(".productDetailPrice").replaceWith(newPriceElement);
    }
    , updateQuantity : function (asinVal) {
        var isBuyable = (asinVal != null);
        if(isBuyable) {
            this.quantityElement.removeAttr("disabled");
        }
        else {
            this.quantityElement.attr("disabled", "disabled");
        }
    }
    , findAndAttachSwatchEvents : function() {
        var parentThis = this;
        if(this.colorSwatchElement.getElements().length > 0) {
            this.colorSwatchElement.getElements().hover(function() {
                    parentThis.changeColorSwatchHoverIn(this); }
                , function() {
                    parentThis.changeColorSwatchHoverOut(this); }
                ).click(function() {
                        parentThis.changeColorSwatchClick(this); }
                    ).keypress(function(e) {
                            if(e.which == 13 ) {
                                parentThis.changeColorSwatchClick(this);
                            }
                        });
        }
        else {
            var colorEl = this.colorSwatchElement.find("input:hidden[name=item.0.color]");
            this.colorSwatchElement.setSelectionMessage(colorEl, colorEl.val()); 
        }
    }
    , setDefaultSwatchStates : function() {
        var $this = this;
        this.selectionElements.getElements().each(function(ei,elm){
                if(!elm) return true; // continue
                var values = elm.getValues();
                for(var vi in values) {
                    var selections = new Array($this.buyBoxModel.model.variationDimensions.length);
                    selections[ei] = values[vi];          
                    if(!$this.buyBoxModel.isPathAvailable(selections)) {		                                   
                        elm.disableElement(vi);
                    }
                }
            });
    }
    , changeColorSwatchHoverIn : function(colorThis) {
        var jObj = jQuery(colorThis);
        if (!jObj.hasClass('selected')) {
            jObj.addClass("swatchHover");
            this.updateColorValue(jObj, jObj.find("input[name=swatchColor]").val());            
        }
    }
    , changeColorSwatchHoverOut : function(colorThis) {
        var jObj = jQuery(colorThis);
        if (jObj.attr("class").indexOf('selected') == - 1 && jObj.hasClass('swatchHover')) {            
            jObj.removeClass("swatchHover");
             var selectedElem = jObj.siblings().filter(".selected");
             if(jQuery(selectedElem).length > 0) {
                this.updateColorValue(jObj, this.colorSwatchElement.getSelectedValue());
              } else {
              this.updateColorValue(jObj, '');
              }  
        }
    }
    , changeColorSwatchClick : function(colorThis) {	  
        var jObj = jQuery(colorThis);
        var classValue = jObj.attr("class");      
        //Ignore the select event if swatch is grayed out
        if(jObj.hasClass('swatchGray')) {
            return false;
        }
        if(jObj.hasClass('selected')) {
            jObj.removeClass("selected").removeClass("swatchHover");
        }
        else {
            this.resetSwatches();
            jObj.addClass("selected");
        }
        this.updateColorValue(jObj, this.colorSwatchElement.getSelectedValue());       
        var idx = this.buyBoxModel.getDimensionIndexFromName("color_name");      
        this.selectionElements.handleSelectionEvent(idx);       
    }
    , updateColorValue : function(colorElement, color) {       
        var msg = (color != null && color != "") ? color : this.colorSwatchElement.getDefaultMessage();
        this.colorSwatchElement.setSelectionMessage(colorElement, msg);             
    }
    , resetSwatches : function() {
         this.colorSwatchElement.getElements().removeClass('selected').removeClass('swatchHover');    
         jQuery("div.colorSwatches .colorMsgLabel").each( function (index, element) {
         jQuery(element).text(jQuery("#colorSwatchDefaultMsg").val());                   
      });        
    }
    , updateAvailability : function (asinVal) {
        var jsEnabled = jQuery(".javascriptEnabled");
        var hiddenAvail = jsEnabled.find(".hiddenAvailability");
        var avail = jsEnabled.find(".productAvailabilityMessage");
        //the condition below is true if some child variation is selected -- availability message should be updated in that case
        if(asinVal != null) {
            var availMsg = this.jsonData.asinData[asinVal].ShortAvailabilityMessage;
            //if this asin is OOS and emwa enabled pickup availability message from hiddenEmwaOOSAvailabilityMessage
            if (this.jsonData.asinData[asinVal].isAsinAvailable == "false" && this.jsonData.asinData[asinVal].isEmailMeWhenAvailable == "true") {
                availMsg = jsEnabled.find(".hiddenEmwaOOSAvailabilityMessage").html();
            }
            hiddenAvail.find(".hiddenAvailabilityMessage").html(availMsg);
            avail.hide();
            hiddenAvail.show();
        }
        else {
            hiddenAvail.hide();
            avail.show();
        }
    },
    updateAddToCartButton : function (asinVal) {	    
        if(asinVal == "") asinVal = null;
        if(asinVal != null) {
            this.addToCartButton.attr("title", "");
            this.addToCartButton.addClass("addToCartEnabledButton").removeClass("addToCartDisabledButton").removeClass("disabled");
        }
        else {
            this.addToCartButton.removeClass("addToCartEnabledButton").addClass("addToCartDisabledButton").addClass("disabled");

        }
        var msg = "Please make a selection to add this item to your cart";
        var sizeElement = this.selectionElements.getElementByName("size_name");
        if(asinVal != null) {
            msg = "";
        } else {
            var firstPart = jQuery("input:hidden[name=addToCartHoverBeginMessage]").val() + " ";
            var joinedLowercaseLabels = this.selectionElements.joinLowerCaseAttributeLabels("/", false);
            var lastPart = " " + jQuery("input:hidden[name=addToCartHoverEndMessage]").val();
            msg = firstPart + joinedLowercaseLabels + lastPart;
        }
        if(this.quantityElement.val() <= 0) {
            msg = jQuery("input:hidden[name=quantityInvalidMessage]").val();
        }
        this.addToCartButton.attr("title", msg);
    },
    processAddToCartButtonClick : function(formName) {
        if(this.quantityElement.length > 0 && !this.quantityElement.attr("disabled")) {
            if( this.quantityElement.val() > 0 ) {
                this.addToCart("addItemMainFormFloating");
            }
        }
    }

    , updateImage : function() {
        if(typeof(productImageItem)!='undefined'){
            productImageItem.imageUpdater(this.colorSwatchElement.getSelectedValue());
        }
    }   
   
    ,updateEMWA : function(asinVal) {	    
        var emwaSelectorButton=jQuery(".emwa");
        var sizeElement = this.selectionElements.getElementByName("size_name");  
        if(asinVal != "") {
            if(this.emwaElement.length > 0) {          
                this.emwaElement.attr("class", "sEMWA");
                this.emwaElement.attr("title","");
                emwaSelectorButton.attr("class","emwa emwaEnabledButton");
                emwaSelectorButton.removeAttr("disabled");
                jQuery("#dColorVal").text(this.colorSwatchElement.getSelectedValue());               
                jQuery("#dSizeVal").text(sizeElement.getSelectedValue()); 
            this.cartElement.hide();
            if(this.signInRedirectQuery.length > 0)                       
                this.signInRedirectQuery.val(this.getRedirectQueryString());
         }
        }
        else {        
            if(this.emwaElement.length > 0) {	           
                if((typeof(emwaVariables) != 'undefined')&&emwaVariables.isAllVariationsEMWA)
                    {	                   
                        var emwaTitle=emwaVariables.selectColorAndSizeForEMWAMessage;
                        if(sizeElement != null && sizeElement.getSelectedValue() != null) {
                            emwaTitle = emwaVariables.selectColorForEMWAMessage;
                        }
                        else if(this.colorSwatchElement != null && this.colorSwatchElement.getSelectedValue() && this.colorSwatchElement.getSelectedValue() != "") {
                            emwaTitle = emwaVariables.selectSizeForEMWAMessage;
                        }
                        emwaSelectorButton.attr("class","emwaSelectorButton emwaDisabledButton ");
                        emwaSelectorButton.attr("disabled","disabled");
                        this.emwaElement.attr("title",emwaTitle);
                    }
                else {
                    this.emwaElement.attr("class", "hEMWA");
                    this.cartElement.show();
                }
            }
        }
    },
        
    getRedirectQueryString : function()
    {	    
        var redirectQuery = this.signInRedirectQuery.val();        
        redirectQuery =  "childAsin=" + this.asin.val()+"&emwaSubscribe=true";
        return redirectQuery;
    },

    restoreState:function()
    {
        var selectedASIN = jQuery("input[name=selectedAsin]");                
        if(typeof(emwaData)!='undefined')
            {	            
                EmwaPopoverItem.showEMWAPopUp(emwaData.emwaSubscribeChildAsin,null);
                this.selectionElements.setASIN(emwaData.emwaSubscribeChildAsin);
            
            } 
        else if(tafData.showTAFPopupOnLoad)
            {
                this.selectionElements.setASIN(tafData.tafAsin);
            }
        else if(selectedASIN && selectedASIN.length > 0 && selectedASIN.val() && selectedASIN.val() != "")
            {
                this.selectionElements.setASIN(selectedASIN.val());
            
            }
    },
        
    showJsVersion:function(){
        jQuery('.javascriptEnabled').show();
        jQuery('#colorSwatches').show();
    },

    hideNonJsVersion:function()
    {
        jQuery('.javascriptDisabled').hide();
    },
  
    addToCart: function (formId){
    	var previousActiveItemTotalQuantity = jQuery("span[class=itemCount]").text();
        var layoutDomain = jQuery("input[name=miniCartLayoutDomain]").val();
        if(!layoutDomain) layoutDomain = "Webstore/SSR";
        var parentThis = this;
        jQuery.ajax({
                type     : "POST",
                    url      : addToCartPageSecureURL,
                    data     : "layoutDomain="+layoutDomain+"&layoutId=Expandable2&activeItemThumbImageHeight=82&activeItemThumbImageWidth=82&scaleType=SX&enableAnalytics=true&cartAddMethod=" + parentThis.cartAddMethodString + "&previousActiveItemTotalQuantity=" + previousActiveItemTotalQuantity + "&" + jQuery('#'+formId).serialize(),
                    error    : function(html, status) {alert(status);},
                    success  : function(html, status) {

                    if(html) {                       
                       
                        jQuery('html, body', parent.document).animate({
                                scrollTop: 0
                                    }, 0);
                        
                        jQuery('#miniCart',parent.document).parent("div").html(html);

                        var cartPop = jQuery('.dynamicMiniCart',parent.document);

                        cartPop.css({
                                "display": "block"
                                    });

                        // swap images when cart starts to slide down
                        jQuery("#miniCartBottomContracted", parent.document).css("display","none");
                        jQuery("#miniCartBottomExpanded", parent.document).css("display","block");
                        
                        cartPop.hide();

                        cartPop.slideDown(1500);

                        window.setTimeout(function(){
                                // swap images back after callback
                                cartPop.slideUp(2500,function(){
                                        jQuery("#miniCartBottomContracted", parent.document).css("display","block");
                                        jQuery("#miniCartBottomExpanded", parent.document).css("display","none");
                                    });

                            }, 8000);
                        if(typeof(miniDetailTabs) != 'undefined'){
                            miniDetailTabs.closePopup();
                        }
                    }

                },
                    timeout  : 100000
                    });
    },

    updateTAFRedirectURLString : function()
    {
        var asin=this.asin.val();
        if(asin==null||asin=="")
            asin=this.initialAsin;
        var redirectUrl = this.tafSigninLink.attr("href");
        var startIndex = redirectUrl.indexOf("childAsin",redirectUrl.indexOf("redirectUrl"));
        startIndex = redirectUrl.indexOf("%3D",startIndex)+3;
        var endIndex = redirectUrl.indexOf("%26",startIndex);
        redirectUrl = redirectUrl.substring(0,startIndex) + asin + redirectUrl.substring(endIndex);
        this.tafSigninLink.attr("href",redirectUrl);
    },

    changeAmazoom:function()
    {
        var parentThis=this;

        if(this.imageFrame==null) {
            this.imageFrame = jQuery("<iframe id='ImageFrame' scrolling='no' frameborder='0' allowtransparency='false' ></iframe>");
            var imageBodyParent = jQuery('#imageBody').parent();
            imageBodyParent.append(this.imageFrame);
        }

        var color=this.colorSwatchElement.getSelectedValue();
        if(color!=null&&color!=""&&color!='null'){
            var asin=this.jsonData.colorData[color].Asin;
            this.imageFrame.attr("src","/richContent/"+asin);
            jQuery("#imageBody").hide();
            jQuery("#alternateImagesBody").hide();
            this.imageFrame.load(function(){
                parentThis.imageFrame.show();
            });
        }
        else {
            this.imageFrame.hide();
            jQuery("#imageBody").show();
            jQuery("#alternateImagesBody").show();
        }
    }
}; 


