/*
 * All java script logic for the application. 
 *
 * The code relies on the jQuery JS library to
 * be also loaded.
 */
// application initialization on dom ready
var DOMUtils = { 
	_listeners : []
};
DOMUtils.registerBehaviors = function(listener){
	var index = jQuery.inArray(listener,DOMUtils._listeners);
	if( index < 0 ) {
		DOMUtils._listeners.push(listener);
	}
};
DOMUtils.unregisterBehaviors = function(listener){
	var index = jQuery.inArray(listener,DOMUtils._listeners);
	if( index > -1 ) {
		DOMUtils._listeners.splice(index,1);
	}
};
DOMUtils.enhanceDOM = function (root) {
	var base = root || document.body;
	
	// Enable ContentAsset banners
	jQuery('.presentify',base).presentify({itemCSS:'.contentasset'});
	
	// Enable base functionality
	app.init(base);
	
	//Fix column heights
	jQuery('.menu-container .level2').each(function(){
		var newheight = 0;
		var tmpheight = 0;
		jQuery(this).children('.column').each(function(){
			tmpheight=jQuery(this).height();
			if(tmpheight > newheight) newheight = tmpheight;
		});
		if(newheight) jQuery(this).children('.column').each(function(){jQuery(this).height(newheight);});
	});
	
	// sub menu-drop down reveal code
	jQuery(".navigation-container .level2").each(function(){
		var that = jQuery(this).find(".column:first");
		var innerWidth = parseInt(that.css("width"))+parseInt(that.css("padding-left"))+parseInt(that.css("padding-right"));
		jQuery(this).width(jQuery(this).children(".column").length * innerWidth);
	});
	var navOffsetWidth = jQuery("#navigation-container").offset().left + jQuery("#navigation-container").outerWidth();
	jQuery(".navigation-container .menu-container").css({top:"-3000px",opacity:"0"});
	
	jQuery(".navigation-container .category-container:has(a.top-cat)").each(function(){
		var menu = jQuery(this);
		var menuOffsetWidth = menu.offset().left + menu.find(".menu-container").outerWidth();
		var positionDiff = navOffsetWidth-menuOffsetWidth;
		if(positionDiff<0) menu.find(".menu-container").css({marginLeft:(positionDiff+"px")});
		menu.find(".menu-container a").click(function(){jQuery(this).parents(".menu-container:first").css({top:"-3000px",opacity:"0"});});
		menu.find(".top-cat").click(function(){jQuery(this).next(".menu-container:first").css({top:"-3000px",opacity:"0"});});
	}).mouseenter(function(){
		jQuery(".hoverKey").trigger("mouseleave");
		var menu = jQuery(this).addClass("hover");
		Cufon.refresh(menu.find("a.top-cat"));
		var menuOffsetWidth = menu.offset().left + menu.find(".menu-container").outerWidth();
		var positionDiff = navOffsetWidth-menuOffsetWidth;
		if(positionDiff<0) menu.find(".menu-container").css({marginLeft:(positionDiff+"px")});
		jQuery(".navigation-container .menu-container").css({top:"-3000px",opacity:"0"});
		menu.find(".menu-container:first").css({top:"32px",opacity:"1"});
		//menu.find(".menu-container:first").css({top:"34px"}).animate({opacity:"1"},300);
	}).mouseleave(function(){
		var menu = jQuery(this).removeClass("hover");
		menu.find(".menu-container:first").css({top:"-3000px",opacity:"0"});
		//menu.find(".menu-container:first").animate({opacity:"0"},100,function(){jQuery(this).css({top:"-3000px"});});
		Cufon.refresh(menu.find("a.top-cat"));
	});
	
	// Home page behavior
    jQuery('.carousel.oneproduct',base).carouselify({itemWidth:700,batchSize:1,hitBox:'.carousel-container .product-module'});
	jQuery('.carousel.twoproduct',base).carouselify({itemWidth:350,batchSize:2,hitBox:'.carousel-container .product-module'});
	jQuery('.carousel.threeproduct',base).carouselify({itemWidth:233,batchSize:3,hitBox:'.carousel-container .product-module'});
	jQuery('.carousel.fourproduct',base).carouselify({itemWidth:175,batchSize:4,hitBox:'.carousel-container .product-module'});
	jQuery('.carousel.threeproducthorz',base).carouselify({itemWidth:300,batchSize:3,hitBox:'.carousel-container .product-module'});
	jQuery('.carousel.home_1x4',base).carouselify({itemWidth:120,batchSize:4,hitBox:'.carousel-container .product-module'});
	
    // product detail enhancements
	PDPUtils.enhanceDOM(base);
	
	// search results enhancements
	SRPUtils.enhanceDOM(base);
	
	
};

function LoadSpecs() {
	//alert("We need to have Zack remove JS from the product descriptions.");
}

var _app = (function(jQuery){

	if (!jQuery) {
		alert("jQuery is not loaded yet!");
		return null;
	}
	
	// Global dw private data goes here	

	// dw scope public
	return {
		resources		: {},  // resource strings used in js
		constants		: {}, // platform constants, initialized in htmlhead.isml
		containerId		: "content",
		ProductCache	: null,  // app.Product object ref
		clearDivHtml	: "<div class=\"clear\"><!-- W3C Clearing --></div>",
		currencyCodes	: {}, // holds currency code/symbol for the site

		// default dialog box settings
		dialogSettings: jQuery.dialogOpt,

		// default tooltip settings
		tooltipSettings: {
				delay: 0,
				showURL: false,
				extraClass: "pretty fancy",
				top: 15,
				left: 5
		},

		// global form validator settings
		validatorSettings: {
			errorClass : 'error_message',
			errorElement: 'span',
			
		    onfocusout: function(element) {
				// Remove anything pre-existing to let validator create/modify from scratch
				//jQuery(element).parents('.formfield_container').find('.error_message').remove();
				//jQuery(element).parents('.formfield_container').find('.error_label').removeClass('error_label').addClass('labeltext');
				//alert(element.name);
				if ( !this.checkable(element) ) {
					this.element(element);
				}
			}
		},

		// app initializations called from jQuery(document).ready at the end of the file
		init: function(base) {
			var root = base || document.body;
			
			// register initializations here
			// quick view dialog div
			if( jQuery("#QuickViewDialog").size()==0 )
				jQuery("<div/>").attr("id", "QuickViewDialog").html(" ").appendTo(document.body);

			// micicart object initialization
			app.minicart.init();
			
			// initialize form validator customizations
			app.validator();

			// extract hidden data and turn them into jQuery data objects
			app.hiddenData();
			
//			// renders horizontal/vertical carousels for product slots
//			jQuery('#horicarousel').jcarousel({
//	        	scroll: 1
//		    }); 
//
//		    jQuery('#vertcarousel').jcarousel({
//		        scroll: 1,
//				vertical: true
//		    });	

			// Add call to Demandware Javascript function for Active Merchandising
			// capture recommendation of each product when it becomes visible in the carousel on Page Load
			if (jQuery('.carousel.oneproduct .carousel-container .captureproductid').text() != "") {
				for (var i = 0 ; i < 1; i++) {
					var pid = jQuery('.carousel.oneproduct .carousel-container .captureproductid:eq(' + i + ')').text();
					dw.ac.capture({id:pid, type:dw.ac.EV_PRD_RECOMMENDATION});
				}
			}
			
			if (jQuery('.carousel.twoproduct .carousel-container .captureproductid').text() != "") {
				for (var i = 0 ; i < 2; i++) {
					var pid = jQuery('.carousel.twoproduct .carousel-container .captureproductid:eq(' + i + ')').text();
					dw.ac.capture({id:pid, type:dw.ac.EV_PRD_RECOMMENDATION});
				}
			}
			
			if (jQuery('.carousel.threeproduct .carousel-container .captureproductid').text() != "") {
				for (var i = 0 ; i < 3; i++) {
					var pid = jQuery('.carousel.threeproduct .carousel-container .captureproductid:eq(' + i + ')').text();
					dw.ac.capture({id:pid, type:dw.ac.EV_PRD_RECOMMENDATION});
				}
			}	
			
			if (jQuery('.carousel.fourproduct .carousel-container .captureproductid').text() != "") {
				for (var i = 0 ; i < 4; i++) {
					var pid = jQuery('.carousel.fourproduct .carousel-container .captureproductid:eq(' + i + ')').text();
					dw.ac.capture({id:pid, type:dw.ac.EV_PRD_RECOMMENDATION});
				}
			}
		},
	
		// sub namespace app.ajax.* contains application specific ajax components
		ajax: {
			Success: "success",
			currentRequests: {}, // request cache

			// ajax request to get json response
			// @param - reqName - String - name of the request
			// @param - async - boolean - asynchronous or not
			// @param - url - String - uri for the request
			// @param - data - name/value pair data request
			// @param - callback - function - callback function to be called
			getJson: function(options) {
				var thisAjax = this;

				// do not bother if the request is already in progress
				// and let go null reqName
				if (!options.reqName || !this.currentRequests[options.reqName]) {
					this.currentRequests[options.reqName] = true;
					if(options.async == "undefined") options.async = true;
					// make the server call
					jQuery.ajax({
						contentType: "application/json; charset=utf-8",
						dataType: "json",
						url		: options.url,
						cache	: true,
						async	: options.async,
						data	: options.data,

						success: function(response, textStatus) {
							thisAjax.currentRequests[options.reqName] = false;

							if (!response.Success) {
								// handle failure
							}

							options.callback(response, textStatus);
						},

						error: function(request, textStatus, error) {
							if (textStatus === "parsererror") {								
								alert('bad response, parser error='+request+", options.url="+options.url);
							}
							
							options.callback({Success: false, data:{}});
						}
					});
				}
			},

			// ajax request to load html response in a given container
			// @param - reqName - String - name of the request
			// @param - url - String - uri for the request
			// @param - data - name/value pair data request
			// @param - callback - function - callback function to be called
			// @param - selector - string - id of the container div/span (#mycontainer) - it must start with '#'
			load: function(options) {


				//jQuery(options.selector).load(options.url, options.data, options.callback);

				var thisAjax = this;

				// do not bother if the request is already in progress
				// and let go null reqname
				if (!options.reqName || !this.currentRequests[options.reqName]) {
					this.currentRequests[options.reqName] = true;
					// make the server call
					jQuery.ajax({
						dataType: "html",
						url		: options.url,
						cache	: true,
						data	: options.data,

						success: function(response, textStatus) {
							thisAjax.currentRequests[options.reqName] = false;
							
							if (options.selector) {
								jQuery(options.selector).html(response);
							}

							(options.callback != undefined ? options.callback(response, textStatus): null)
						},

						error: function(request, textStatus, error) {
							if (textStatus === "parsererror") {								
								alert('bad response, parser error');
							}

							options.callback(null, textStatus);
						}
					});
				}
			}
		},

		// loads a product into a given container div
		// params
		// 		containerId - id of the container div, if empty then global app.containerId is used
		//		source - source string e.g. search, cart etc.
		//		label - label for the add to cart button, default is Add to Cart
		//		url - url to get the product
		//		id - id of the product to get, is optional only used when url is empty
		getProduct: function(options) { // id, source, start
			var cId 		= options.containerId || app.containerId;
			var source 		= options.source || "";
			var a2cBtnLabel = options.label || null;

			// show small loading image
			jQuery("#"+cId).html(app.showProgress("productloader"));

			var productUrl = options.url ? options.url : app.util.appendParamToURL(app.URLs.getProductUrl, "pid", options.id);
						
			productUrl = app.util.appendParamToURL(productUrl, "source", source);

			app.ajax.load({selector: "#"+cId, url: productUrl, callback: function(responseText, textStatus){
				// update the Add to cart button label if one provided
				(a2cBtnLabel != null ? jQuery("#"+cId+" .addtocart_button:last").html(a2cBtnLabel) : '');
			}});
		},

		// sub name space app.minicart.* provides functionality around the mini cart
		minicart: {
			state : 0, // flag, whether cart is open or not
			url   : '',  // during page loading, the Demandware URL is stored here
			timer : null, // timer for automatic close of cart item view

			// initializations
			init: function() {
				// reset all the existing event bindings
				app.minicart.reset();

				// bind hover event to the cart total link at the top right corner
				//jQuery(".minicarttotal").hover(function(e){(app.minicart.isShow() ? '': app.minicart.slide());});
			
				jQuery('#minicart-container').mouseenter(function(e) {
					clearTimeout(app.minicart.timer);
					app.minicart.timer = null;
				}).mouseleave(function(e) {
					clearTimeout(app.minicart.timer);
					app.minicart.timer = null;
					// after a time out automatically close it
					app.minicart.timer = setTimeout( 'app.minicart.close()', 30 );
				});

				// register close button event
				jQuery('#minicart-container #minicartclose').click(function() {
					// reset all the events bindings
					app.minicart.reset();
					app.minicart.close(0);
				});
			},
			
			// returns a boolean if a minicart is visible/shown or hidden
			isShow: function() {
				return jQuery('#minicart-container').css('display') == 'none' ? false : true;
			},
			
			// reset minicart
			reset: function() {
				//jQuery(".minicarttotal").unbind("hover");
				jQuery('#minicart-container').unbind("mouseenter").unbind("mouseleave");
				jQuery('#minicart-container #minicartclose').unbind("click");
			},

			// shows the given content in the mini cart
			show: function(html) {
				jQuery('#minicart').html(html);
				
				
				
				// bind all the events
				app.minicart.init();
				
				if(app.minicart.suppressSlideDown && app.minicart.suppressSlideDown()) {
					// do nothing
					// the hook 'MiniCart.suppressSlideDown()' should have done the refresh
				}
				else {
					app.minicart.slide();
				}
			},
			
			// slide down and show the contents of the mini cart
			slide: function() {
				if(app.minicart.suppressSlideDown && app.minicart.suppressSlideDown()) {
					return;
				}
					
				// show the item
				jQuery('#minicart-container').show();//show("slide", { direction: "up" }, 1000);

				clearTimeout(app.minicart.timer);
				app.minicart.timer = null;
					
				// after a time out automatically close it
				app.minicart.timer = setTimeout( 'app.minicart.close()', 6000 );
			},


			// adds a product to the mini cart
			add: function(progressImageSrc, postdata, callback)
			{
				// get the data of the form as serialized string
				var postdata = postdata;

				// get button reference
				var addButtons = [];

				// the button to update
				var addButton = null;
				
				// it is an array of buttons, but we need only one all
				// other combinations are strange so far
				if (addButtons.length == 1)	{
					addButton = addButtons[0];
				}

				var previousImageSrc = null;

				// show progress indicator
				if (addButton != null) {
					previousImageSrc = addButton.src;
					addButton.src = progressImageSrc;
				}

				// handles successful add to cart
				var handlerFunc = function(req)	{
					
					
					// hide progress indicator
					if (addButton != null) {
						addButton.src = previousImageSrc;
					}
					
					if(req.indexOf('NoInventory_NoInventory') > 0)
					{
						//alert("no Inventory");
						//Dialog.alertNoButtons(req.responseText.replace('NoInventory_NoInventory', ''), {windowParameters: {className: '',height: 400, width: 500}, okLabel: 'Close'});
						//return false;
						req = req.replace('NoInventory_NoInventory', '');
					}
					// replace the content
					//jQuery('#QuickViewDialog').html(req);

					// bind all the events
					//app.minicart.init();
					if(app.minicart.suppressSlideDown && app.minicart.suppressSlideDown()) {
						// do nothing
						// the hook 'MiniCart.suppressSlideDown()' should have done the refresh
					} else {
						//app.minicart.slide();
						minicartShow(req);
						minimizeSlide(function() {
							jQuery('#QuickViewDialog').fadeTo('fast',1.0, function(){
								jQuery(this).filterFont();
								jQuery('.configurator .configurator-options').find('.open').removeClass('open').addClass('wasOpen');
								jQuery('.configurator .add-to-cart-container img.busy').addClass('noDisplay');
							});
							if (callback) callback();
						});
					}
				}

				// handles add to cart error
				var errFunc = function(req) {
					// hide progress indicator
					if (addButton != null) {
						addButton.src = previousImageSrc;
					}				
				}

				// closes a previous mini cart
				app.minicart.close();

				// add the product
				jQuery.ajax({
								type	: "POST",
								url		: app.minicart.url,
								cache	: true,
								data	: postdata,
								success	: handlerFunc,
								error	: errFunc
							});
			},

			// closes the mini cart with given delay
			close: function(delay) {
				if ( app.minicart.timer != null || delay == 0) {
					clearTimeout( app.minicart.timer );
					app.minicart.timer = null;			
					jQuery('#minicart-container').fadeOut(); // hide with "slide" causes to fire mouse enter/leave events sometimes infinitely thus changed it to fadeOut
				}
			},

			// hook which can be replaced by individual pages/page types (e.g. cart)
			suppressSlideDown: function() {
				return false;
			}
		},

		// close quick view dialog if open and refresh the page
		refreshCart: function() {
			app.quickView.close();

			// refresh without posting
			location.href = location.href;
		},
		
		cart : {
			add_url  : '',
			show_url : '',
			add: function(postdata) {				
				jQuery.ajax({
					type	: "POST",
					url		: app.cart.add_url,
					cache	: true,
					data	: postdata,
					success : function(resp) { //window.location.href = app.cart.show_url; 
					}					
				});
			}
		},

		// Product quick view object
		quickView: {

			bindEvents: function(options) {
				// hide quickview buttons
				jQuery(options.buttonSelector).hide();

				// hovering
				jQuery(options.imageSelector).hover(
					function(e) {
						jQuery(this).children(options.buttonSelector).show();
						return false;
					},
					function(e) {
						jQuery(this).children(options.buttonSelector).hide();
						return false;
					}
				);

				// click binding for quick view
				//jQuery(options.buttonLinkSelector).click(function(e) {
				//	app.quickView.show({url: this.href, source: "quickview"});
				//	return false;
				//});

				/*
				To make bookmarking and browser back-button work correctly the browser URL needs 
				to change. To force that change we do a full-page load (not AJAX) when going from 
				search result page to product detail page.
				The implementation supports loading the product detail content with AJAX: just 
				uncomment this code block to bind the event handler.
				
				// click binding for name link
				if(options.productNameLinkSelector) {
					jQuery(options.productNameLinkSelector).click(function(e) {
						app.getProduct({url: this.href, source: "search"});
						return false;
					});
				}
				*/
			},

			// show quick view dialog and send request to the server to get the product
			// options.source - source of the dialog i.e. search/cart
			// options.url - product url
			show: function(options) {
				app.createDialog({id: 'QuickViewDialog', options: {
			    	height: 530,
			    	width: 800,
			    	dialogClass: 'quickview',
			    	title: 'Product Quickview',
			    	resizable: false
				}});

			    jQuery('#QuickViewDialog').dialog('open');
			    app.getProduct({containerId: "QuickViewDialog", source: options.source, url: options.url, label: options.label});
			},
			// close the quick view dialog
			close: function() {
				jQuery('#QuickViewDialog').dialog('close');
				jQuery('.configurator .configurator-options').find('.wasOpen').removeClass('wasOpen').addClass('open');
				maximizeSlide();
			}
		},


		createDialog: function(options) {
			//id dialog container doesnt exists, then add 
			if (jQuery("#"+options.id).length == 0) jQuery("<div id='"+options.id+"' />").appendTo(document.body);

			jQuery('#'+options.id).dialog(jQuery.extend(true, {}, app.dialogSettings, options.options));
		},


		tooltip: function(options) {
			if (options.id.charAt(0) !== '#') {
				options.id = "#"+options.id;
			}
			jQuery(options.id).tooltip(jQuery.extend({}, app.tooltipSettings, options.options));
		},
		/*
		 *	Opens a new window with the provided url and dimension. Used
		 *	for Scene7 and other situations.
		 *
		 *	@param url the url to open
		 *	@param width the window width
		 *	@param height the window height
		 */
		openPopup: function( url, width, height ) {
			if (url != null) {
				if (width != null && height != null) {
					window.open(url, "", "width=" + width +", height=" + height +", scrollbars=no, resizable=yes");
				}
				else {
					window.open(url, "", "scrollbars=no, resizable=yes");
				}
			}
		},
		balloonText: function(msg,containerClass,balloonPosition){
			if(balloonPosition == null) balloonPosition = 'balloon';
			return '<a href="javascript:void(0);" class="' + containerClass + ' balloon-container" tabindex="1000"><span class="' + balloonPosition + '">'+msg+'<span class="balloon-spike" /></span></a>';
		},
		validator: function() {
			// override default required field message
			jQuery.validator.messages.required = function($1, ele, $3) {
				var the_dta = jQuery(ele).data("data");
				if( the_dta==null ) return "";
				var article = "a";
				if( the_dta[0]=='A' ||the_dta[0]=='E' ||the_dta[0]=='I' ||the_dta[0]=='O' ||the_dta[0]=='U' ){
					article = "an";
				}
				var Msg = 'Please enter '+article+' '+the_dta;
				if(jQuery(ele).parents('.overlabel').length)
					Msg = jQuery.balloonText(Msg,'errorBox','balloon-right');
				return Msg;
			};

			// register form validator for form elements
			// except for those which are marked "suppress"
			jQuery.each(jQuery("form:not(.suppress)"), function() {
				jQuery(this).validate(app.validatorSettings);
			});
		},

		// grab anything inside a hidden span and append it to its immediate previous sibling
		hiddenData : function() {
			jQuery.each(jQuery(".hidden"), function() {
				jQuery(this).prev().data("data", jQuery(this).html());
			});
		},

		// sub namespace app.producttile.* contains utility functions for product tiles
		producttile : {
			// initializes all product tiles contained in the current page
			initAll: function() {
				// bind quick view button toggling and click
				var quickViewOptions = {
					buttonSelector: "div.producttile div.quickview-button",
					imageSelector: "div.producttile div.image",
					buttonLinkSelector: "div.producttile div.quickview-button a"
				};
				//app.quickView.bindEvents(quickViewOptions);
				
				// prepare swatch palettes and thumbnails
				jQuery("div.producttile div.swatches div.hidden").hide();
				jQuery("div.producttile div.swatches a.swatch img.hiddenthumbnail").hide();
				
				// show the palette
				jQuery("div.producttile div.swatches > a").click(function(e) {
					var cont = jQuery(this).parent().find("div.palette");
					cont.show().focus();
					return false;
				});
				
				// hide the palette
				jQuery("div.producttile div.swatches div.hidden").mouseout(function(e) {
					// fix for event bubbling (http://www.quirksmode.org/js/events_mouse.html)
					if(!e) var e = window.event;
					var tg = (window.event) ? e.srcElement : e.target;
					if(tg.nodeName != 'DIV') return;
					var reltg = (e.relatedTarget) ? e.relatedTarget : e.toElement;
					while(reltg != tg && reltg.nodeName != 'BODY')
						reltg = reltg.parentNode
					if (reltg == tg) return;
					
					// mouseout took place when mouse actually left layer
					// handle event now
					jQuery(this).hide();
					return false;
				});
				
				// thumb nail toggling
				jQuery("div.producttile div.swatches div.palette a.swatch").bind("mouseover mouseout", function(e) {
					var swatch = jQuery(this);
					app.producttile.toggleVariationThumbnail(swatch);
				});
				
				// color swatch selection
				jQuery("div.producttile div.swatches div.palette a.swatch").click(function(e) {
					var swatch = jQuery(this);
					app.producttile.selectVariation(swatch);
					// omit following the swatch link
					return false;
				});
			},

			// selects a certain variation in a product tile, replaces the current image with
			// the correct variation image, changes the link to the detail
			// page and the quick view
			selectVariation : function(swatch) {
				// get the new and the original image
				var currentImg = jQuery(swatch.parents()[3]).find(".productimage img");
				var newImg = swatch.children("img.hiddenthumbnail");
				if(!currentImg || !newImg) return;
				
				// get the anchors
				var nameAnchor = swatch.parents(".producttile").find(".name a");
				var quickViewAnchor = swatch.parents(".producttile").find(".quickview-button a");
				
				// change the link url to the detail page and quick view
				var newUrl = swatch.attr("href");
				nameAnchor.attr("href", newUrl);
				quickViewAnchor.attr("href", newUrl);
				
				// remove all current markers
				jQuery(swatch.parents()[0]).find("a.swatch").removeClass("selected");
				
				// mark swatch as selected
				swatch.addClass("selected");
				// we just remove the markers at the images; the actual elements
				// are correct, since they were already swapped by mouse over
				currentImg.removeClass("temp original");
				newImg.removeClass("temp original");
			},

			// shows the thumb nail of a product; this function is used to
			// temporally display a new image and restore the original one
			toggleVariationThumbnail : function(swatch) {
				// get the new and the original image
				var currentImg = jQuery(swatch.parents()[3]).find(".productimage img");
				var newImg = swatch.children("img.hiddenthumbnail");
				if(!newImg || !currentImg) return;
					
				// we do nothing in case the swatch is already selected
				if(swatch.hasClass("selected")) return;
				
				if(currentImg.hasClass("temp")) {
					// current image is just a temp image
					// restore original and reset temp image
					var currentCopy = currentImg.clone().hide().removeClass("temp").addClass("hiddenthumbnail");
					var newCopy = newImg.clone().show().removeClass("original hiddenthumbnail");
					currentImg.replaceWith(newCopy[0]);
					newImg.replaceWith(currentCopy[0]);
				} else {
					// we create copies of each image, replace
					// the current with the copies and mark them with classes
					var currentCopy = currentImg.clone().hide().addClass("original hiddenthumbnail");
					var newCopy = newImg.clone().show().addClass("temp").removeClass("hiddenthumbnail");
					currentImg.replaceWith(newCopy[0]);
					newImg.replaceWith(currentCopy[0]);
				}
			}
		},

		// sub namespace app.util.* contains utility functions
		util : {
			multiUpdate : function(elemId, url, mapping) {
				var element = jQuery(elemId);
				jQuery.ajax({
					dataType: "html",
					url		: url,
					cache	: true,

					success: function(response, textStatus) {
						var responseNode = jQuery(response);
						var entries = mapping.split(",");
						for( var i=0, ii=entries.length; i<ii; i++ ) {
							var sourceTarget = entries[i].split(":");
							if( sourceTarget.length == 1 ) {
								jQuery(sourceTarget[0]).html(responseNode.find(sourceTarget[0]).html());
							} else if( sourceTarget == 2 ) {
								jQuery(sourceTarget[1]).html(responseNode.find(sourceTarget[0]).html());
							}
						}
					},

					error: function(request, textStatus, error) {
						if (textStatus === "parsererror") {								
							alert('bad response, parser error');
						}
					}
				});
				
			},
			
			// disables browser auto completion for the given element
			disableAutoComplete : function(elemId) {
				jQuery("#"+elemId).attr("autocomplete", "off");
			},

			// trims a prefix from a given string, this can be used to trim
			// a certain prefix from DOM element IDs for further processing on the ID
			trimPrefix : function(str, prefix) {
				return str.substring(prefix.length);
			},

			// appends the parameter with the given name and
			// value to the given url and returns the changed url
			appendParamToURL : function(url, name, value) {
				var c = "?";
				if(url.indexOf(c) != -1) {
					c = "&";
				}
				return url + c + name + "=" + encodeURIComponent(value);
			}
		},

		// sub namespace app.dialog.* provides convenient functions to handle dialogs
		// note, that this code relies on single dialog modals (multi dialog, e.g. modal in modal is not supported)
		dialog : {
			// opens a dialog using the given url
			open : function(url, title) {
				// create the dialog container if not present already
				if(jQuery("#dialogcontainer").length == 0) {
					jQuery(document.body).append("<div id=\"dialogcontainer\"></div>");
				}

				// set a default title
				title = title || "Dialog";

				// finally load the dialog, set the dialog title
				
				app.ajax.load({
					selector: "#dialogcontainer",
					url: url,
					callback: function() {
						app.dialog.checkOpen();
						app.dialog.setTitle(title);
					}
				});
			},

			// initializes the dialog with common dialog actions, like closing upon canceling
			// use this function in the dialog rendering template to re-bind common actions
			// upon dialog reload
			init : function() {
				jQuery(document).ready(function() {
					// binds the action to all buttons defining an action through the "name" attribute
					jQuery("#dialogcontainer button").each(function() {
						jQuery(this).click(function() {
							var action = jQuery(this).attr("name");
							if(action) {
								app.dialog.submit(action);
							}
							return false;
						});
					});

					// cancel button binding
					jQuery("#dialogCancelBtn").click(function() {
						app.dialog.close();
						return false;
					});
				});
			},

			// sets the title of the dialog
			setTitle : function(title) {
				jQuery("#dialogcontainer").dialog("option", "title", title);
			},

			// checks, if the dialog is in the state "open" and sets the state if not presently set
			// this function is implicitly called by app.dialog.open(url, title) in order to initialize
			// the dialog properly; use this function to recover the "open" state of a dialog
			checkOpen : function() {
				if(!jQuery("#dialogcontainer").dialog("isOpen"))
				{
					jQuery("#dialogcontainer").dialog({
						autoOpen: false,
						modal: true,
						overlay: {
				    		opacity: 0.5,
				     		background: "black"
						},
				    	height: 425,
				    	width: 460,
				    	resizable: false
					});
					jQuery("#dialogcontainer").dialog("open");
				}
			},

			// closes the dialog and triggers the "close" event for the dialog
			close : function() {
				jQuery("#dialogcontainer").dialog("destroy");
				jQuery(document.body).trigger("dialogClosed");
			},

			// attaches the given callback function upon dialog "close" event
			onClose : function(callback) {
				if(callback != undefined) {
					jQuery(document.body).bind("dialogClosed", callback);
				}
			},

			// triggers the "apply" event for the dialog
			triggerApply : function() {
				jQuery(document.body).trigger("dialogApplied");
			},

			// attaches the given callback function upon dialog "apply" event
			onApply : function(callback) {
				if(callback != undefined) {
					jQuery(document.body).bind("dialogApplied", callback);
				}
			},

			// triggers the "delete" event for the dialog
			triggerDelete : function() {
				jQuery(document.body).trigger("dialogDeleted");
			},

			// attaches the given callback function upon dialog "delete" event
			onDelete : function(callback) {
				if(callback != undefined) {
					jQuery(document.body).bind("dialogDeleted", callback);
				}
			},

			// submits the dialog form with the given action
			submit : function(action) {
				// set the action
				jQuery("#dialogcontainer form").append("<input name=\"" + action + "\" type=\"hidden\" />");

				// serialize the form and get the post url
				var post = jQuery("#dialogcontainer form").serialize();
				var url = jQuery("#dialogcontainer form").attr("action");

				// post the data and replace current content with response content
		  		jQuery.ajax({
				   type: "POST",
				   url: url,
				   data: post,
				   dataType: "html",
				   success: function(data){
		  				jQuery("#dialogcontainer").empty().html(data);
				   },
				   failure: function(data) {

					   alert("Server connection failed!");
				   }
				});
			}
		}
	}
})(jQuery);

//Create final app object
if(typeof app === 'undefined') window.app = {};
jQuery.extend(true, app, _app);

var PDPUtils = {
	currentSubCategory : 'empty',
	
	scrollify : function(wrappedset) {
		if( jQuery('.productlist tr:visible',wrappedset[0]).size()<=5 ) {
			wrappedset.find(".scrollable").addClass("noscroll");
		} else {
			wrappedset.find(".scrollable").removeClass("noscroll");
		}	
	},

	expandSection : function(expandosection, callback) {
		/*Currently closed*/
		/*Check for gender-hand, return if there is no current selection*/
		var selGenderHandElement = jQuery('#pdpVarAttrDiv .gender-hand li.selected')[0];
		if( selGenderHandElement==null ) {
			if( expandosection.parents('.shafts').size()<1 ) 
				return false;
		}
		jQuery('div.callout').hide('fast');
		expandosection.removeClass('expandable-section');
		expandosection.addClass('expanded-section');
		var esection = expandosection;
		var ecallback = callback;
		expandosection.stop().animate({'width':'940px'},function(){
			PDPUtils.scrollify(jQuery(this));
			jQuery(this).find('.scrollable').show('fast');
			if( ecallback ) ecallback();
		});//.find('.scrollable').fadeIn('normal');
	},

	compressSection : function(expandosection) {
		/*Currently open*/
		expandosection.find('.scrollable').hide('normal');//,function(){
		expandosection.stop().animate({'width':'569px'},function(){
			if( jQuery('.gender-hand li.selected')[0]==null ) {
				// Make sure that the first callout has the gender/hand message
				jQuery(jQuery('div.callout')[0]).addClass('nogenderhand');
			} else {
				// Make sure that the first callout has the press the + button message
				jQuery(jQuery('div.callout')[0]).removeClass('nogenderhand');
			}
			jQuery('div.callout').show('fast');
			
			expandosection.removeClass('expanded-section');
			expandosection.addClass('expandable-section');
		});//});
	},
	filterSubcategory : function(el) {
		var attrValue = jQuery(el).text();
		if( attrValue.indexOf('Sets')>-1 ) {
			jQuery('.productdetail-options div.v1258').show();
			jQuery('.productdetail-options div.v1267').hide();
			jQuery('.productdetail-options div.v71').hide();
		} else {
			jQuery('.productdetail-options div.v1258').hide();
			jQuery('.productdetail-options div.v1267').show();
			jQuery('.productdetail-options div.v71').show();
			if( attrValue.indexOf('Individual')>-1 ) {
				jQuery('.productdetail-options li.v1267:has(a:contains("Iron"))').show();
				jQuery('.productdetail-options li.v1267:has(a:contains("Wedge"))').hide();
			} else {
				jQuery('.productdetail-options li.v1267:has(a:contains("Iron"))').hide();
				jQuery('.productdetail-options li.v1267:has(a:contains("Wedge"))').show();
			}
		}
		jQuery('.productlist tr').hide();
		var subcatRows = jQuery('.productlist tr:has(td:contains('+attrValue+'))');
		subcatRows.show();
		if (PDPUtils.currentSubCategory != attrValue){
			$('.productdetail-options li.v71').hide();
			var visibleItems = $('td.pinehurstSubcategory:contains("' + attrValue +'")').siblings('.productlist td.v71:not(empty)');
			visibleItems.each( function(index) {
				var loftValue = $(this).html();
				$('.productdetail-options li.v71:contains("'+loftValue+'")').show();
			});
			PDPUtils.currentSubCategory = attrValue;
		}
		PDPUtils.filterRefinemetOptions();
	},
	filterVariants : function(el, mutuallyExclude) {

		if( jQuery(el).parents('li').hasClass('unorderable') ) return false;
		
		var attrID = el.className.split(" ")[0];
		var attrValue = el.id;
		var mux = !!mutuallyExclude;
		
		// Check if selected
		var wasChecked = jQuery(el).parents('li').hasClass('selected');
		var isChecked = !wasChecked;
		
		if( !wasChecked && mux ) {
			jQuery(el).parents('li').siblings().removeClass('selected');
		}
		jQuery(el).parents('li').toggleClass('selected');
		
		// Show all
		if( jQuery('#tabs:visible').size()>0 ) {
			var selTabLink = jQuery("#tabs .ui-tabs-selected a");
			PDPUtils.filterSubcategory( selTabLink[0] );
		} else {
			jQuery('.productlist tr').show();
		}
	
		// If gender hand was picked, then clear out all the others
		if( el.className.indexOf('vGenderHand')>-1 ) {
			jQuery('.refinement_category li.selected').removeClass('selected');
		}
		
		// At this point the UI represents the Users wishes
		// For each variation attribute, which has a selected checkbox ...
		// 
		// First hide the blank ones ... but don't remove from DOM
		jQuery('.productlist tr:has(td.NA.'+attrID+')').hide();
		var unselectedSiblings = jQuery('.var-attr:has(li.selected) li:not(.selected) a');
		var usSize = unselectedSiblings.size();
		if( usSize > 0 ) {
			// Hide unselected
			unselectedSiblings.each(function(){
				jQuery('.productlist td.'+this.id).parents('tr').hide();
			});
		}
		
		// Apply coloring to odd rows (moved to callback)
		
		// Make sure gender hand is selected before we expose the grid
		// Otherwise, close it

		var expandosection = jQuery('.productlist').parents('.alpha');
		if( attrID == 'vGenderHand' && isChecked ) {
			PDPUtils.expandSection(expandosection, function(){
				PDPUtils.oddifyRows(jQuery('.productlist')[0]);
				var sorts = jQuery('.options-header .asc,.options-header .des');
				if( sorts.size()==0 ){
					PDPUtils.sortRows(jQuery('.productlist tr:visible td:visible')[0].className.split(" ")[1],'asc');
				}
				PDPUtils.filterRefinemetOptions(attrID);});
		} else if( attrID == 'vGenderHand' && jQuery('.gender-hand li.selected')[0]==null ) {
			PDPUtils.compressSection(expandosection);
		} else {
			PDPUtils.scrollify(expandosection);
		}
		
		//disable unselectable refinements if the product panel is expanded
		PDPUtils.filterRefinemetOptions(attrID);

		// Add default sorting if not already sorted
		PDPUtils.oddifyRows(jQuery('.productlist')[0]);
return false;
	},

	filterRefinemetOptions : function(clickedAttributeID, waschecked){
		//alert('number of lines visible: ' + $('.productlist tr:visible').length);
		if ($('.productlist tr:visible').length>=1){
			$('.refinement_category li').each( function(){
				var element = $(this);
				if (!element.hasClass('selected')){
					$(this).find('a').each( function(){
						var innerElement = $(this);
						var attributeID = innerElement.parents('div.var-attr').attr('class').replace('var-attr ','');
						var attributeValue = innerElement.html();
						var selector = '.productlist td.'+attributeID+':contains("'+ attributeValue + '")';
						if ($(selector).parents("tr:visible").length < 1) {
							innerElement.parents('li').addClass('unorderable').fadeTo(0.1,0.6);
						} else {
							innerElement.parents('li').removeClass('unorderable').fadeTo(0.1,1);
						}
					});
				}
			});
			//hide all empty
			$('.options-header td:empty').each( function(){
				var ie = $(this);
				var className = ie.attr('class');
				$('.productlist td.'+className).css({visibility:'hidden'});
				$(this).css({visibility:'hidden'});
			});
//			$('.productlist tr:has(td:empty:visible)').hide();
		} else {
			$('.refinement_category li').each( function(){
				var innerElement = $(this);
				innerElement.find('a').attr('disabled', '');
				innerElement.attr('style', '');
			});
		}
	},

	sortBy : function( el ) {
		var descending = jQuery(el).parents('td').hasClass('des');
		var colName = jQuery(el).parents('td')[0].className.split(' ')[0];
		PDPUtils.sortRows(colName,descending ? 'des' : 'asc');
	},

	sortRows : function( column, direction ) {
		var rows = jQuery('.productlist tr').remove();
		var columnValues = jQuery.map(rows.find('td.'+column),function(node){return jQuery(node).text();});
		var sortedValues = columnValues.sort();
		
		if( direction=='asc' ) {
			sortedValues.reverse();
			jQuery('.options-header td.'+column).addClass('des');
			jQuery('.options-header td.'+column).removeClass('asc');
		} else {
			jQuery('.options-header td.'+column).addClass('asc');
			jQuery('.options-header td.'+column).removeClass('des');
		}
		
		jQuery('.options-header td.'+column).siblings().removeClass('des');
		jQuery('.options-header td.'+column).siblings().removeClass('asc');
		
		// unique it
		sortedValues = PDPUtils.unique(sortedValues);
		
		// Remove all rows and replace them by text value
		jQuery.each(sortedValues, function(val){
			var match = this;
			var rows2 = rows.find('td:contains('+this+')').filter(function() {
	            return (jQuery(this).text() == match);
	        }).parents('tr');
			jQuery('.productlist').append(rows2);
		});
		
		PDPUtils.oddifyRows(jQuery('.productlist')[0]);
		
		// Allows for selection of variant rows for add to cart
		jQuery('.productlist tr').rolloverify().click(function(){
			jQuery(this).toggleClass("selected").siblings().removeClass("selected");
			if( jQuery(this).hasClass("selected") ) {
				var sku = this.id.split("-")[1];
				jQuery(".selectedSKU").html("<span class='bold'>Product SKU:</span> <span class='sku'>"+sku+"</span>");
				PDPUtils.enableAddToCart();
			} else {
				PDPUtils.disableAddToCart();
				jQuery(".selectedSKU").html("");
			}
		});

	},

	unique : function(inArray) {
		var arr = inArray || [];
		var result = [];
		for( var i=0, ii=arr.length; i<ii; i++ ) {
			if( !PDPUtils.contains(result, arr[i]) ) {
				result.push(arr[i]);
			}
		}
		return result;
	},

	contains : function(arr, elem) {
		var inArr = arr || [];
		for( var i=0, ii=inArr.length; i<ii; i++ ) {
			if( inArr[i]==elem ) return true;
		}
		return false;
	},

	enableAddToCart : function() {
		jQuery("#main div.addtocart .addtocartBtn").removeAttr("disabled");
		jQuery("#main div.addtocart").removeClass("disabled"); 
	},

	disableAddToCart : function() {
		//jQuery("#main div.addtocart .addtocartBtn").attr("disabled", "disabled");
		jQuery("#main div.addtocart").addClass("disabled"); 
	},
	
	oddifyRows : function( table ) {
		jQuery('tr:visible:even',table).removeClass('odd').addClass('odd');
		jQuery('tr:visible:odd',table).removeClass('odd');
	},
	addSelectionToCart : function( parameters, useLightBox ) {
		PDPUtils.disableAddToCart();
			
		if (useLightBox) {
			app.createDialog({
				id:'QuickViewDialog',
				options:{
					width:700,
					height:600,
					dialogClass:"minicart",
					title:"Items Added to Your Cart",
					bgiframe:true,
					draggable:false,
					autoResize:true,
					close:function(e, ui){
						window.location.reload();
						return false;
					},
					open:null
				}
			});

			jQuery('#QuickViewDialog').load(app.minicart.url, parameters);
			jQuery('#QuickViewDialog').empty().append(app.showProgress());
			jQuery('#QuickViewDialog').dialog('open');
		} else {
			var actionurl = jQuery("#PDPConfigurator").attr("action") +"?"+ jQuery.param(parameters);		
			jQuery("#PDPConfigurator").attr("action",actionurl).submit();
		}
	
		return false;
	},
	
	addSelectionToCartOLD : function( pidstring, quantity, cgid, cluboptions, useLightBox ) {
		PDPUtils.disableAddToCart();
		
		queryString = "pid=" + pidstring;		
		queryString += "&Quantity=" + quantity;
		
		if (cgid) {
			queryString += "&cgid=" + cgid;
		}
		
		if (cluboptions) {
			var pids = pidstring.split("|");
			for (var i = 0; i < cluboptions.length; i++) {
				var cluboption = cluboptions[i];			
				for (var j=0; j < pids.length; j++) {				
					queryString += '&dwopt_'+ pids[j] +'_' + cluboption.oid + '=' + cluboption.ovid;
				}
			}
		}
		
		queryString = encodeURI(queryString);
			
		if (useLightBox) {
			app.createDialog({
				id:'QuickViewDialog',
				options:{
					width:700,
					height:600,
					dialogClass:"minicart",
					title:"Items Added to Your Cart",
					bgiframe:true,
					draggable:false,
					autoResize:true,
					close:function(e, ui){
						window.location.reload();
						return false;
					},
					open:null
				}
			});

			jQuery('#QuickViewDialog').load(app.minicart.url,queryString);
			jQuery('#QuickViewDialog').empty().append(app.showProgress());
			jQuery('#QuickViewDialog').dialog('open');
		} else {
			var actionurl = jQuery("#PDPConfigurator").attr("action") +"?"+ queryString;		
			jQuery("#PDPConfigurator").attr("action",actionurl).submit();
		}
	
		return false;
	},
	
	showProductToolTip: function( element ){
		if (element) {
			var toolTipDiv = $('.image_container .productDetailToolTip');
			//if the tool tip div does not exist we just create it
			if (toolTipDiv.size()==0) {
				var imageDiv = $('.image_container').append('<div class="productDetailToolTip"></div>');
				toolTipDiv = $('.image_container .productDetailToolTip');
			}
			var productToolTip = $(element).find('div.productToolTip');
			if (productToolTip.size()>0) {
				toolTipDiv.html(productToolTip.html()).show();
			}
		}
	},

	hideProductToolTip: function( ){
		var toolTipDiv = $('.image_container .productDetailToolTip');
		//if the tool tip div does not exist we just create it
		if (toolTipDiv.size()>0) {
			toolTipDiv.hide();
		}
	},

	enhanceDOM : function(root) {
		var base = root||document.body;
		
		// Opens/closes the variant list
		jQuery('td.plusBtn', base).click(function(){
			var expandosection = jQuery(this).parents('.alpha');
			if( expandosection.hasClass('expandable-section') ) {
				PDPUtils.expandSection(expandosection, function(){PDPUtils.oddifyRows(jQuery('.productlist')[0]);});
			} else {
				PDPUtils.compressSection(expandosection);
			}
			return false;
		});
		
		// Allows for selection of variant rows for add to cart
		jQuery('.productlist tr').rolloverify().click(function(){
			jQuery(this).toggleClass("selected").siblings().removeClass("selected");
			if( jQuery(this).hasClass("selected") ) {
				PDPUtils.enableAddToCart();
				var sku = this.id.split("-")[1];
				jQuery(".selectedSKU").html("<span class='bold'>Product SKU:</span> <span class='sku'>"+sku+"</span>");
			} else {
				PDPUtils.disableAddToCart();
				jQuery(".selectedSKU").html("");
			}
		});
		
		// Make unorderable variation attribtues look disabled
		jQuery('.unorderable',base).fadeTo("fast",0.6);
	
		// Filterables
		jQuery('.filterable',base).click(function(){
			if( jQuery(this).hasClass('vGenderHand') ) {
				PDPUtils.filterVariants(this,true);
			} else {
				var enableAdditionalFiltering = false;
				//if vGender attribute is present we check if any of the values was already selected
				//if not we don't allow additional filtering
				if ($('.vGenderHand.filterable').length>0 ) {
					$('.vGenderHand.filterable').each( function(i) {
						if ($(this).parent('li').hasClass('selected')) {
							enableAdditionalFiltering = true;
						}
					})
				} else {
					enableAdditionalFiltering = true;
				}
				if (enableAdditionalFiltering) {
					PDPUtils.filterVariants(this);
				} else {
					alert('Additional filtering is not allowed until you have chosen your Gender/Hand.');
				}
			}
			return false;
		});
	}
};

var SRPUtils = {};
SRPUtils.enhanceDOM = function(root){
	// init all refinement bindings
	var base = root||document.body;
	
	if(app.search) app.search.updateRefineBindings(base);
	
	// init refinement toggling
//	jQuery("#search-refinements div.navgroup h3",base).click(function(e) {
//		jQuery(this).toggleClass("collapsed");
//		jQuery(this).nextAll("div.refine_attributes").toggle();
//	});
	
	// Search result page behavior
	jQuery('.click-box',base).mouseenter(function(){
		jQuery(this).parents('.product-module').addClass('hover');
	}).mouseleave(function(){
		jQuery(this).parents('.product-module').removeClass('hover');
	});
};

jQuery.fn.enhancify = function() {
	if( this.size()>0 )
		DOMUtils.enhanceDOM(this[0]);
	
	return this;
}

jQuery.fn.carouselify = function(_options){
	var options = {itemWidth:175,batchSize:4,hitBox:'.carousel-container .product-module'};
	jQuery.extend(options,_options);

	this.each(function(){
		var that = this;
		jQuery(options.hitBox,that).rolloverify().click(function(){
			var href = jQuery('a',this).attr('href');
			location.href = href;
			return false;
		});
		jQuery(this).find('.carousel-next').click(function(){
			// Look for numProducts .end.text() and .begin.text()
			var begin = jQuery('.begin',that).text()-0;
			var end = jQuery('.end',that).text()-0;
			var old_begin = begin;
			// get min(begin+4,end)
			var numProducts = jQuery('.total',that).text()-0;
			if( end+options.batchSize>numProducts ) {
				end = numProducts;
				// hide arrows (if needed)
				jQuery(this,that).css({visibility:'hidden'});
			} else {
				end+=options.batchSize;
			}
			begin = end-options.batchSize+1;
			// push over 175*(old-new)
			var change = "-="+((begin-old_begin)*options.itemWidth)+"px";
			jQuery('.carousel-container',that).animate({marginLeft:change},'normal');	
			// update new begin and end
			jQuery('.carousel-nav .begin',that).text(begin);
			jQuery('.carousel-nav .end',that).text(end);
			
			// show arrows (if needed)
			if( begin > 1)
				jQuery('.carousel-prev',that).css({visibility:'visible'});
			
			// Add call to Demandware Javascript function for Active Merchandising
			// capture recommendation of each product when it becomes visible in the carousel
			for (var i = begin - 1 ; i < end; i++) {
				var pid = jQuery('.carousel-container .captureproductid:eq(' + i + ')').text();
				dw.ac.capture({id:pid, type:dw.ac.EV_PRD_RECOMMENDATION});
			}
			
			return false;
		});
		
		jQuery(this).find('.carousel-prev').click(function(){
			// Look for numProducts .end.text() and .begin.text()
			var begin = jQuery('.begin',that).text()-0;
			var end = jQuery('.end',that).text()-0;
			var old_begin = begin;
			// get min(begin+4,end)
			var numProducts = jQuery('.total',that).text()-0;
			if( (begin-options.batchSize)<1 ) {
				begin = 1;
				// hide arrows (if needed)
				jQuery(this,that).css({visibility:'hidden'});
			} else {
				begin-=options.batchSize;
			}
			end = begin+options.batchSize-1;
			// push over 175*(old-new)
			var change = "+="+((old_begin-begin)*options.itemWidth)+"px";
			jQuery('.carousel-container',that).animate({marginLeft:change},'normal');
			// update new begin and end
			jQuery('.carousel-nav .begin',that).text(begin);
			jQuery('.carousel-nav .end',that).text(end);
			
			// show arrows (if needed)
			if( end < numProducts )
				jQuery('.carousel-next',that).css({visibility:'visible'});
			
			// Add call to Demandware Javascript function for Active Merchandising
			// capture recommendation of each product when it becomes visible in the carousel
			for (var i = begin - 1 ; i < end; i++) {
				var pid = jQuery('.carousel-container .captureproductid:eq(' + i + ')').text();
				dw.ac.capture({id:pid, type:dw.ac.EV_PRD_RECOMMENDATION});
			}
			
			return false;	
		});	
	});
};
jQuery.fn.rolloverify = function(_options) {
	var defaults = {toggleClass:'hover'};
	jQuery.extend(defaults,_options);
	
	this.mouseenter(function(){
		jQuery(this).addClass(defaults.toggleClass);
	}).mouseleave(function(){
		jQuery(this).removeClass(defaults.toggleClass);
	});
	
	return this;
};
jQuery.fn.dialogify = function(_options) {
	var launchDialog = function(event){
		if(typeof event != "undefinded" && event != null && event.data != {}) {
			var dialogParams = {id: "QuickViewDialog", options: event.data};
			if(event.isDefaultPrevented && !event.isDefaultPrevented()) event.preventDefault();
			app.createDialog(dialogParams);
			
			var dialogDiv = jQuery('#'+dialogParams.id);
			try { eval("var callback = "+dialogParams.options.callback+";"); }catch(err){}
			if(dialogParams.options.content) {
				dialogDiv.html(options.content);
				if(typeof callback == "function") callback();
			} else if(typeof dialogParams.options.url != "undefined"){
				dialogDiv.load(dialogParams.options.url,(typeof callback == "function" ? callback : function(){}));
				dialogDiv.empty().append(app.showProgress());
			} else return true;
			dialogDiv.dialog('open');			
			//Remove the dialog from DOM on close
			jQuery('.ui-dialog-titlebar-close').click(function(){dialogDiv.dialog('destroy');});			
		} //break out if event object inaccessible and "a" tag click continues with href value 
		else return true;
	};
	jQuery(this).each(function(){
		var obj = jQuery(this);
		var defaults = {
		   	width: 660,
			height: 440,
		   	resizable: false,
		   	bgiframe: true,
		   	draggable: false,
		   	url: obj.attr("href"),
		   	title: obj.attr("title")
		};
		//add & overwrite "rel" values to defaults array
		var relData = obj.attr("rel");
		try {
			eval("jQuery.extend(defaults, _options, {"+(relData && relData.indexOf("=")>=0 ? relData.replace(/\|/gi,"', " ).replace(/\=/gi,": '")+"'" : "")+"});");
		} catch(err) {
			jQuery.extend(defaults, _options);
		}

		//Set proper types to each value of default array
		jQuery.each(defaults, function(i,val){defaults[i] = (val=='true' ? true : (val=='false' ? false : (i=='width'||i=='height' ? val-0 : val)));});
		
		obj.bind("click.dialogify",defaults,launchDialog);
		if(defaults.autoOpen == true)
			obj.trigger("click.dialogify",defaults);
	});
	return this;
};

function minicartShow(content) {
	app.createDialog({id: 'QuickViewDialog', options: {
    	height: 441,
    	width: 660,
    	dialogClass: 'minicart',
    	title: 'Just Added to Your Cart...',
    	resizable: false
	}});
	
	// indicate progress
	jQuery("#content").fadeTo("normal",0.6);

	jQuery('#QuickViewDialog').html(content);

	jQuery('#QuickViewDialog').dialog('open');
}

function toggleLoginRadio( el ) {
	if( el && el.id=="create_account_radio" ) {
		if( el.checked ) {
			jQuery('.checkoutSave').show('normal');
		} else {
			jQuery('.checkoutSave').hide('normal');

		}
	} else if( el && el.id=="guest_checkout_radio" ) {
		if( el.checked ) {
			jQuery('.checkoutSave').hide('normal');
		} else {
			jQuery('.checkoutSave').show('normal');

		}
	}
}
var presentify = {
	showNextContentAsset : function () {
		var next = jQuery(presentify.selectedContentAsset).next()[0];
		var nextPageBtn = jQuery(presentify.selectedPageBtn).next()[0];
		if( next==null ) {
			next = jQuery(presentify.selectedContentAsset).siblings(presentify.itemCSS)[0];
			nextPageBtn = jQuery(presentify.selectedPageBtn).siblings('.pageBtn')[1];
		}
		var zIndex = jQuery(presentify.selectedContentAsset).css('z-index');
		if( zIndex<2 ) {
			zIndex=20;
			jQuery(presentify.selectedContentAsset).css({zIndex:zIndex});
		}
		if(!next) {
			return;
		}
		jQuery(next).css({zIndex:zIndex-1}).show();
		jQuery(presentify.selectedContentAsset).fadeOut('slow');

		jQuery(presentify.selectedPageBtn).removeClass('current');
		presentify.selectedContentAsset = next;
		presentify.selectedPageBtn = nextPageBtn;
		//jQuery(presentify.selectedContentAsset).fadeIn('slow');
		jQuery(presentify.selectedPageBtn).addClass('current');
		presentify.timer = setTimeout(presentify.showNextContentAsset,6000);
	}
};
jQuery.fn.presentify = function(_options){
	var defaults = {itemCSS:'.contentasset'};
	jQuery.extend(defaults,_options);
	
	presentify.itemCSS = defaults.itemCSS;
	
	// Look for children and set up the pagination
	var contentassets = this.find(defaults.itemCSS);
	if( contentassets==null || contentassets.size()==0 ) return;
	var height = jQuery(contentassets[0]).height();
	this.height(height);
	var numAssets = contentassets.size();
	contentassets.hide();
	presentify.selectedContentAsset = contentassets[0];
	this.prepend('<div class="pagination" />');
	var pageDiv = this.find('.pagination');
	jQuery(presentify.selectedContentAsset).show();
	var playPauseBtn = jQuery("<a class='pageBtn pause'>Pause</a>").click(function(){
		var that = jQuery(this);
		if( that.hasClass('pause') ) {
			clearTimeout(presentify.timer);
			that.removeClass('pause');
			that.addClass('play');
			that.text('Play');
		} else {
			that.removeClass('play');
			that.addClass('pause');
			that.text('Pause');
			presentify.showNextContentAsset();
		}
	});
	pageDiv.append(playPauseBtn);
	contentassets.each(function(index){
		var that = this;
		jQuery(this).css({position:'absolute',zIndex:10-index}).mouseenter(function(){
			clearTimeout( presentify.timer );
		}).mouseleave(function(){
			if( pageDiv.find('.pause').size()==1 ) {
				clearTimeout( presentify.timer );
				presentify.timer = setTimeout(presentify.showNextContentAsset,6000);
			}
		});
		var link = jQuery("<a class='pageBtn'>"+(index+1)+"</a>&nbsp;").click(function(){
			if( that == presentify.selectedContentAsset ) return false;
			var zIndex = jQuery(presentify.selectedContentAsset).css('z-index');
			if( zIndex<2 ) {
				zIndex=20;
				jQuery(presentify.selectedContentAsset).css({zIndex:zIndex});
			}
			jQuery(that).css({zIndex:zIndex-1}).show();
			jQuery(presentify.selectedContentAsset).fadeOut('slow');
			presentify.selectedContentAsset = that;
			//jQuery(presentify.selectedContentAsset).fadeIn('slow');
			jQuery(this).addClass('current').siblings().removeClass('current');
			presentify.selectedPageBtn = this;
			
			return false;
		});
		pageDiv.append(link);
	});
	presentify.selectedPageBtn = this.find('.pageBtn')[1];
	jQuery(presentify.selectedPageBtn).addClass('current');
	presentify.timer = setTimeout(presentify.showNextContentAsset,6000);
}
jQuery.fn.enableBtn = function(enable){
	jQuery(this).each(function(){
		if(enable== null || enable)
			jQuery(this).removeAttr("disabled").parent().removeClass("disabled");
		else jQuery(this).attr("disabled","disabled").parent().addClass("disabled");
	});
	return this;
};

/*//unreferenced code
function updateMiniCart(el, pid) {
	var parentRow = "#"+jQuery(el).parents("tr.tablerow")[0].id;
	var form = jQuery(el).parents('form');
	var name = el.name;
	var PID = pid;
	form.ajaxSubmit({ 
		url:form.attr('action')+"?"+name+"="+PID,
		success:function(responseText){
			var node = jQuery(responseText);
			//jQuery(parentRow).html(node.find(parentRow).html());
			//jQuery(".cart").html(node.find(".cart").html());
			//jQuery('.cartordertotals').html(node.find('.cartordertotals').html());
			//initBehaviors(jQuery(parentRow)[0]);
		}
	});
	return false;
}

function updateMiniCartMini(el, pid) {
	//var parentRow = "#"+jQuery(el).parents("tr.tablerow")[0].id;
	var form = jQuery(el).parents('form');
	var name = el.name;
	var PID = pid;
	form.ajaxSubmit({ 
		url:form.attr('action')+"?"+name+"="+PID,
		success:function(responseText){
			var node = jQuery(responseText);
			//jQuery(parentRow).html(node.find(parentRow).html());
			//jQuery(".cart").html(node.find(".cart").html());
			//jQuery('.cartordertotals').html(node.find('.cartordertotals').html());
			//initBehaviors(jQuery(parentRow)[0]);
		}
	});
	return false;
}
*/
jQuery.fn.filterFont = function(callback) {
		if(jQuery.browser.msie && this.get(0))
			this.get(0).style.removeAttribute('filter');
		if(callback != undefined)
			callback.call(this[0]);
		return this;
};
jQuery.fn.resetClick = function(){
	var initialValue = null;
	switch(jQuery(this).attr("type")){
		case 'password':
        case 'select-multiple':
        case 'select-one':
        case 'text':
        case 'textarea':
        	initialValue = jQuery(this).attr("value");
        	break;
    }
	function clearClick(DOMObject){
		switch(jQuery(DOMObject).attr("type")){
			case 'password':
	        case 'select-multiple':
	        case 'select-one':
	        case 'text':
	        case 'textarea':
	        	DOMObject.value = "";
	        	break;
	        /*case 'checkbox':
	        case 'radio':
	        	DOMObject.checked = false;*/
		}
	}
	
	jQuery(this).bind("focus", function(){
		jQuery(this).addClass("focus");
		clearClick(this);
	});
	jQuery(this).blur(function(){
		jQuery(this).unbind("focus");
		if((jQuery(this).attr("value")=="")||(this.value==null)||(this.value===null)) {
			jQuery(this).removeClass("focus").attr("value",initialValue);
			jQuery(this).bind("focus", function(){
				jQuery(this).addClass("focus");
				clearClick(this);
			});
		}
	});
};
jQuery.fn.initHoverClass = function(){
	jQuery(this).hover(function(){jQuery(this).addClass('hover');},
			function(){jQuery(this).removeClass('hover');});
	return this;
};
jQuery(document).ready(function() {
	jQuery("input.select-all").click(function(){
		jQuery(this).focus();
		jQuery(this).select();
		});
	//initConfigurator(document.body);
	
	var valueArray = jQuery(".clear-click").each(function(){jQuery(this).resetClick();});
});
function initConfigurator(root){
	jQuery(".configurator .radio-container input",root).click(function(){
		// Custom has single value, Stock has two
		var that = jQuery(this);
		var outUrl = that.val();

		parentSlide(this).addClass('loading-indicator');
		
		// For custom, preselect the no choice value
		app.ajax.load({url:outUrl,data:{format:'ajax'},callback:function(data){
			//TODO: Remove after Find A Store AB Test is complete
			var config = jQuery(data);
			config.find(".find-a-store-container").replaceWith(jQuery(".find-a-store-container"));
			jQuery('.configurator').replaceWith(config);
			//jQuery('.configurator').replaceWith(data);
		}});
	});
	jQuery(".configurator .check-container a, .configurator .check-container div",root).click(function(e){
		e.preventDefault();
		
		// Collect all selected SKU's
		var skuList = "";
		var clubList = "";
		var thisSlide = parentSlide(this);
		var myID = jQuery(this).parents('.row').attr('id');
		var totalPrice = 0.0;
		var totalClubs = 0;
		
		var highestAvailability = 0;
				
		var parentLI = jQuery(this).parents('li');
		
		if( parentLI.hasClass('disabled') ) {
			return false;
		} else {
			parentLI.toggleClass('selected');
		}
		
		thisSlide.find(".check-container li.selected a, .check-container li.selected div").each(function(){
			// turn ID into web param
			var variantID = this.id.replace("pid-","");
			var club = jQuery("span.club",this).text();
			if( skuList.length>0 ) skuList+="|";
			if( clubList.length>0 ) clubList+=", ";
			skuList += variantID;
			clubList += club; 
			
			if( matchingVariants && variantID && matchingVariants[variantID] ) {
				totalClubs += matchingVariants[variantID].clubCount;
				totalPrice += matchingVariants[variantID].price;
			}
			
			var availability = jQuery("span.detail",this).text();
			var level = jQuery.inArray(availability, availabilityLevels);
			if( level>highestAvailability ) {
				highestAvailability = level;
			}
		});

		jQuery('#clubCount').text(totalClubs);
		jQuery('.totals .availability .value').text(availabilityLevels[highestAvailability]);
		
		var optionPrice = 0.0;
		jQuery('.length-grip-wrap option:selected').each(function(){
			optionPrice+=(jQuery(this).val()-0);
		});
		
		var shaftPrice = jQuery('#shaftPerClubPrice').text();
		
		if( shaftPrice.indexOf('-')>-1 ) shaftPrice = 0.0;
		
		var shaftTotal = shaftPrice*totalClubs;
		var optionTotal = optionPrice*totalClubs;
		
		if( shaftTotal > 0 ) {
			totalPrice-=shaftTotal;
		}
		
		var grandTotal = totalPrice+shaftTotal+optionTotal;
		
		var subTotalPrice = totalPrice>0 ? "$ "+totalPrice.toFixed(2) : "-";
		var shaftTotalPrice = shaftTotal>0 ? "$ "+shaftTotal.toFixed(2) : "-";
		var optionTotalPrice = optionTotal>0 ? "$ "+optionTotal.toFixed(2) : "-";
		var grandTotalPrice = grandTotal>0 ? "$ "+grandTotal.toFixed(2) : "-";
		
		if( optionTotal>0.0 ) {
			jQuery('#custom-options-subtotal .label').text("Custom Options ($ "+optionPrice.toFixed(2)+" per club):");
		}
		
		jQuery('#subTotal').text(subTotalPrice);
		jQuery('#shaftTotal').text(shaftTotalPrice);
		jQuery('#optionTotal').text(optionTotalPrice);
		jQuery('#grandTotal').text(grandTotalPrice);
		
		jQuery('.addToCartBtn span').text(skuList);

		var totalsCont = jQuery("#totals-container");
		var frompriceCont = jQuery("#frompricing-container");
		if(subTotalPrice=="-" && shaftTotalPrice=="-" && optionTotalPrice=="-" && grandTotalPrice=="-") {
			totalsCont.css({display:"none"});
			frompriceCont.css({display:"block"});
		} else {
			totalsCont.css({display:"block"});
			frompriceCont.css({display:"none"});
		}
		
		
		var wishlistHref = jQuery('.add-to-wishlist').attr('href');
		
		if (wishlistHref != null) // VIP does not have a Wishlist
		{
			var index = wishlistHref.indexOf("pid=");
			if( index==-1 ) {
				wishlistHref = jQuery('.add-to-wishlist').attr('orighref');
				if (wishlistHref != null)
				{
					index = wishlistHref.indexOf("pid=");
					wishlistHref = wishlistHref.substring(0,index)+"pid="+skuList;
				}
			}			
		}		
		
		var params = [];
		var pids = skuList.split("|");
		jQuery('.length-grip-wrap .select-container .option_value:selected').each(function(el){
			var oid = jQuery(this).parents('select').attr('id');
			var ovid = this.id.replace("ov","");
			for( var i=0, ii=pids.length; i<ii; i++ ) {
				params.push('dwopt_'+pids[i]+'_'+oid+'='+ovid);
			}
		});
		
		var optionsHref = params.join('&');
		
		if (wishlistHref != null) // VIP does not have a Wishlist
		{
			jQuery('.add-to-wishlist').attr('href', wishlistHref+"&"+optionsHref);
		}
		
		if( skuList.length>0 ) {
			jQuery('.addToCartBtn').removeAttr('disabled');
			jQuery('.add-to-wishlist').removeAttr('disabled',null);
			jQuery('.add-to-wishlist').removeClass('disabled');
			jQuery('.addToCartBtn').parents('.add-to-cart-container').removeClass('disabled');
		} else {
			jQuery('.addToCartBtn').attr('disabled','disabled');
			jQuery('.add-to-wishlist').attr('disabled','disabled');
			jQuery('.add-to-wishlist').addClass('disabled');
			jQuery('.addToCartBtn').parents('.add-to-cart-container').addClass('disabled');
		}
		var selLists = thisSlide.find('.selection-list .'+myID).text(clubList);
		if( clubList.length>0 ) {
			jQuery('.foot').removeClass('disabled');
			jQuery('.foot button').removeAttr('disabled');
			selLists.removeClass('empty');
			selLists.find('strong').text('Selected:');
		} else {
			jQuery('.foot').addClass('disabled');
			jQuery('.foot button').attr('disabled','disabled');
			selLists.addClass('empty');
			selLists.find('strong').text('No clubs selected.');
		}
				
		// Update availability
		var that = jQuery(this);
		return false;
	});
	
	jQuery('.configurator .select-container select',root).change(function(){
		// Custom has single value, Stock has two
		var that = jQuery(this);
		var outUrl = that.find('option:selected').val();
		
		var nextSelect = that.next('select');
		if( nextSelect.length > 0 ) {
			nextSelect.find('option:selected').attr('selected',null);
			nextSelect.find('option:first').attr('selected','selected');
		}
		
		if( jQuery(this).parents('.length-grip-wrap').size()==0 ) {
			parentSlide(this).addClass('loading-indicator');

			app.ajax.load({url:outUrl,data:{format:'ajax'},callback:function(data){
				var config = jQuery(data);
				jQuery('.configurator').replaceWith(data);
			}});
			return false;
		} else {
			// Grab the priceOffset and place it into the two places where we need it
			var newText = that.find('option:selected').text();
			var myID = this.id;
			var thisSlide = that.parents('.slide');
			thisSlide.find('.foot span.'+myID).text(newText);
			updateOptionPricing(this);
									
			//If we're customized and the availability is less than 5-7 days then make it 5-7 days
			var isCustomized = false; 
			jQuery('.length-grip-wrap .select-container .option_value:selected').each(function() {
				isCustomized = jQuery.trim(jQuery(this).text()).indexOf("Standard") != 0;
				if (isCustomized) { 
					return false;
				};
			});
			
			if (isCustomized) {
				var fiveToSevenDaysText = "5-7 Days";
				var availabilityText = jQuery('.totals .availability .value').text();
				var currentAvailabilitylevel = jQuery.inArray(availabilityText, availabilityLevels);			
				var fiveToSevenDays = jQuery.inArray(fiveToSevenDaysText, availabilityLevels);
				if (currentAvailabilitylevel < fiveToSevenDays) {
					jQuery('.totals .availability .value').data("availabilityText", availabilityText);
					jQuery('.totals .availability .value').text(fiveToSevenDaysText);
				};			
			} else {
				var availabilityText = jQuery('.totals .availability .value').data("availabilityText");
				if (availabilityText) {
					jQuery('.totals .availability .value').text(availabilityText);
				};
			};
			
			return true;
		}
	});
	
	jQuery("#product-customization .radio-list a",root).click(function(e){
		e.preventDefault();
		var that = jQuery(this);
		if( that.parents('li').hasClass('selected') ) {
			// No need to re-lookup
			return false;
		}
		var href = that.attr('href');
		
		// Update UI accordingly
		selectVariationAttribute(that.parents('li'));
		
		var myRow = that.parents('.row');
		var myRowID = myRow.attr('id');
		var configuratorSlides = jQuery(".configurator .slide");
		// If this is the last step, then just change the link on the next button
		if( that.parents(".slide:first").next().hasClass("slide") && (myRowID=='v67' || myRowID=='v71' || (myRowID=='v3' && myRow.parents('.Putters').size()>0) && configuratorSlides.length > 1)) {
			that.parents('.slide').find('.nextSlidePreselect').attr('href',href);
		} else {
			// Tell server about it
			parentSlide(this).addClass('loading-indicator');

			app.ajax.load({url:href,data:{format:'ajax'},callback:function(data){
				//TODO: Remove after Find A Store AB Test is complete
				var config = jQuery(data);
				config.find(".find-a-store-container").replaceWith(jQuery(".find-a-store-container"));
				jQuery('.configurator').replaceWith(config);
				//jQuery('.configurator').replaceWith(data);
			}});
		}
		return false;
	});
	
	jQuery(".configurator .foot .nextPillBtn",root).unbind("click").bind("click", function(){
		if(!jQuery(this).parents('.foot').hasClass('disabled')) {
			var outQuery = "";
			
			// Gather this slides parameters
			var thisSlide = jQuery(this).parents('.slide');
			thisSlide.addClass('loading-indicator');
			
			jQuery(this).find(".nextInstruction").remove();
			jQuery(this).parents('.foot').addClass('disabled');
			
			openNextSlide(this);
		}
			return false;
	}).each(function(){
		//remove single slide next button from configurator
		var thisSlide = jQuery(this).parents('.slide');
		if(thisSlide.next(".slide").length == 0){
			jQuery(this).parents(".foot:first").empty();
		}
	});
	
	jQuery(".configurator .head",root).click(function(){
		if(jQuery(this).parent().hasClass('complete')){
			// If this slide is the 'club-head' slide, we should just re-load
			//  the configurator from scratch
			var thisSlide = jQuery(this).parents('.slide');
			var href2 = jQuery('#configurator-url-2').attr('href');
			/*var openSlide =*/ jQuery(".configurator .open:last").addClass('loading-indicator');	
			if( thisSlide.hasClass('club-head') ) {
				var href = jQuery('#configurator-url').attr('href');
				app.ajax.load({url:href,data:{format:'ajax'},callback:function(data){
					//Get new configurator
					//jQuery('.configurator').replaceWith(data);
					transitionSlide(data);
				}});
			} else if( !thisSlide.hasClass('length-grip-wrap') && href2 && href2.length>0 ) {
				app.ajax.load({url:href2,data:{format:'ajax'},callback:function(data){
					//Get new configurator
					//jQuery('.configurator').replaceWith(data);
					transitionSlide(data);
				}});
			} else if(jQuery(this).parent().hasClass("complete")) {
				// If not, then just open it.
				openThisSlide(this);
			}
		}
		return false;
	});
	
	/*
	jQuery(".configurator .addToCartBtn",root).click(function(e) {
		if(jQuery(this).parents(".add-to-cart-container:first").hasClass("disabled")) return false;
		e.preventDefault();
		jQuery(this).attr('disabled','disabled');
		jQuery(this).prev('img.busy').removeClass('noDisplay');
		var params = []; 
		var pid = jQuery(this).find("#variant-spec").text();
		var pids = pid.split('|');
		var vid = jQuery('#edittedVariantID').text();
		params.push('pid='+pid);

		if( vid && vid.length>0 ) {
			params.push('vid='+vid);
		}
		params.push('Quantity=1');			
		jQuery('.length-grip-wrap .select-container .option_value:selected').each(function(el){
			var oid = jQuery(this).parents('select').attr('id');
			var ovid = this.id.replace("ov","");
			for( var i=0, ii=pids.length; i<ii; i++ ) {
				params.push('dwopt_'+pids[i]+'_'+oid+'='+ovid);
			}
		});
			
		var actionurl = jQuery("#PDPConfigurator").attr("action") +"?"+ params.join('&');
		jQuery("#PDPConfigurator").attr("action",actionurl).submit();
	
		return false;
	});
	*/
	
	// General dialog functions
	jQuery('.configurator .dialogify').dialogify();
}

function updateOptionPricing( el ) {

	var optionPrice = 0.0;
	jQuery('.length-grip-wrap option:selected').each(function(){
		optionPrice+=(jQuery(this).val()-0);
	});
	
	var clubCount = jQuery('#clubCount').text()-0;
	
	var existingOptionTotal = jQuery('#optionTotal').text();	
	var existingGrandTotal = jQuery('#grandTotal').text();
	
	var existingOptionTotalValue = 0.0;
	var existingGrandTotalValue = 0.0;
	var start = existingOptionTotal.indexOf('$');
	if( start>-1 ){
		existingOptionTotalValue = existingOptionTotal.substring(start+1)-0;
	}
	start = existingGrandTotal.indexOf('$');
	if( start>-1 ){
		existingGrandTotalValue = existingGrandTotal.substring(start+1)-0;
	}
	
	var optionTotal = (optionPrice*clubCount);
	var grandTotal = existingGrandTotalValue-existingOptionTotalValue+optionTotal;
	
	var optionTotalPrice = optionTotal>0 ? "$ "+optionTotal.toFixed(2) : "-";
	var grandTotalPrice = grandTotal>0 ? "$ "+grandTotal.toFixed(2) : "-";
	
	if( optionTotal>0 ) {
		jQuery('#custom-options-subtotal .label').text("Custom Options ($"+optionPrice.toFixed(2)+" per club):");
	} else {
		jQuery('#custom-options-subtotal .label').text("Custom Options:");
	}
	
	jQuery('#optionTotal').text(optionTotalPrice);
	jQuery('#grandTotal').text(grandTotalPrice);
}

/* from product.isml */
function selectVariationAttribute( el ) {
	var thisSlide = parentSlide(el);
	
	
	// Capture current state of the slide here for future use
	// with event handlers intact
//	if( thisSlide.hasClass('club-head') ){
//		var existClone = jQuery('#slideStore .club-head');
//		if( existClone.length==0 ) {
//			existClone = thisSlide.clone(true);
//			jQuery('#slideStore').append(existClone);
//		}
//	}

	// update buttons
	el.siblings().removeClass('selected');
	el.addClass('selected');
	
	// update selection
	updateVariantSelection(el);

	// show foot selection if needed
	if( hasSelections(thisSlide) ) {
		showFootSection(thisSlide);
	} 
	
	// show next button if needed
	if( !hasEmptySelections(thisSlide) ) {
		showNextButton(thisSlide);
	} 
}
function unselectVariationAttribute( el ) {
	el.removeClass('selected');

	var thisSlide = parentSlide(el); 
	
	// update selection
	clearVariantSelection(el);
	
	// hide foot selection if needed
	if( !hasSelections(thisSlide) )
		hideFootSection(thisSlide);
	
	// hide next button if needed
	hideNextButton(thisSlide);
}
function hasSelections(thisSlide) {
	var allSpans = thisSlide.find('.foot .selection-list span');
	var emptySpans = thisSlide.find('.foot .selection-list span.empty');
	return (emptySpans.size() < allSpans.size() && allSpans.size()>0);
}
function hasEmptySelections(thisSlide) {
	return (thisSlide.find('.foot .selection-list span.empty').size()>0);
}
function hideNextButton( thisSlide ) {
	thisSlide.find('.foot button').attr('disabled','disabled');
	thisSlide.find('.foot').addClass('disabled');
}
function showNextButton( thisSlide ) {
	thisSlide.find('.foot button').removeAttr('disabled');
	thisSlide.find('.foot').removeClass('disabled');
}
function hideFootSection(thisSlide) {
	thisSlide.find('.foot .selection-list').css('visibility','hidden'); 
}
function showFootSection(thisSlide) {
	thisSlide.find('.foot .selection-list').css('visibility','visible'); 
}
function clearVariantSelection(el) {
	var sel = el.parents('.row')[0].id;
	var thisSlide = parentSlide(el);
	thisSlide.find('.selection-list .'+sel).text("").addClass('empty');
}
function updateVariantSelection(el) {
	var thisSlide = parentSlide(el);
	var sel = el.parents('.row')[0].id;
	var selText = null;
	if( sel=='shaft-manu-model-flex' ) {
		var parentEl = jQuery(el).parents('.radio-container');
		if( parentEl.size()>0 ) {	
			sel = parentEl[0].id;			
			// Get text from label
			selText = jQuery(el).parents('label').text();
		} else {
			sel = el.attr('id');
			// Get text from label
			selText = jQuery(el).find('option:selected').text();
		}
	} else {
		selText = el.find('a').text();
	}

	// Open up the next row setting for selection
	var nextSetting = jQuery(el).parents('.row').next('.row');
	//if( nextSetting.size()>0 ) { nextSetting.removeClass('disabled');}
	if( sel && sel!="" )
		thisSlide.find('.selection-list .'+sel).text(selText).removeClass('empty');
}
function openNextSlide(el) {
	var thisSlide = parentSlide(el);
	var nextSlide = thisSlide.next('.slide');
	// Get update from the server to fill out values
	var nextSlidePreselect = thisSlide.find('.nextSlidePreselect');
	if( nextSlidePreselect.size()>0 ) {
		var href = nextSlidePreselect.attr('href');
		parentSlide(this).addClass('loading-indicator');
		// Cache the url for non-club-head slides
		if( thisSlide.hasClass('club-head') ) {
			jQuery('#configurator-url-2').attr('href',href);
		}
		app.ajax.load({url:href,data:{format:'ajax'},callback:function(data){
			transitionSlide(data);
		}});
	} else {
		if( nextSlide.size()>0 ) {
			thisSlide.removeClass('loading-indicator').filterFont();
			completeSlide(thisSlide, function(){openSlide(nextSlide);});
		} 
	}
}
function openThisSlide(el) {
	// Close all slides after this one & ?clear selections?
	var thisSlide = parentSlide(el);
	var nextSlide = thisSlide.next('.slide');
	while( nextSlide.size()==1 ) {
		// Close the slide
		closeSlide(nextSlide);
		// Clear head and foot selections
		clearSlideSelections(nextSlide);
		nextSlide = nextSlide.next('.slide');
	}
	// Open this one ... with selections intact
	openSlide(thisSlide);//.removeClass('complete').addClass('open');
}
function parentSlide(el) {
	return jQuery(el).parents('.slide');
}
function openSlide(el) {
	el.removeClass('complete').addClass('open');
	maximizeSlide();
}
function closeSlide(el) {
	minimizeSlide(function(){
		el.removeClass('complete').removeClass('open');
	});
}
function completeSlide(el,callback) {
	minimizeSlide(function(){
		el.removeClass('open').addClass('complete');
		if(typeof callback == 'function') callback.call();
	});
}
function clearSlideSelections(el) {
	// Clear selected spans
	el.find('.selection-list span').text('').addClass('empty');
	// Hide selected textline
	el.find('.selection-list').css('visibility','hidden');
	// Hide next button
	el.find('button').css('display','none');
}
function showCustomShafts(el){
	jQuery(el).parents(".row").find(".select-container").css('display','block');
}
function hideCustomShafts(el){
	jQuery(el).parents(".row").find(".select-container").css('display','none');
}
function maximizeSlide(fromCurrentHeight, callback){
	if(fromCurrentHeight==null) fromCurrentHeight=false;
	else if(typeof fromCurrentHeight == 'function') callback = fromCurrentHeight;
		else fromCurrentHeight=true;

	var slideFrame = jQuery('.configurator .open:first').css({overflow:'hidden'}).removeClass('loading-indicator').addClass('transitioning');
	var slideHeight = slideFrame.height();
	var slideHead = slideFrame.find('.head:first').css({backgroundColor:'#eeeee6'})
	if (fromCurrentHeight == true) slideFrame.height(slideHead.height()); 
	else slideFrame.height(23);
	slideHead.animate({backgroundColor:'#242426'},500);
	slideHead.find('h3:first').css({backgroundColor:'#eeeee6',color:'#333'}).animate({backgroundColor:'#242426',color:'#fff'},500);
	slideFrame.removeClass('loading-indicator').animate({height:slideHeight+'px'}, 500, function(){
		jQuery(this).css({display:'',height:'',overflow:''}).attr('style','').removeClass('transitioning');
		slideHead.attr('style','');
		slideHead.children().attr('style','');
		if(typeof callback == 'function') callback.call();
		return jQuery(this);
	});
}
function minimizeSlide(callback){
	var slideFrame = jQuery('.configurator .open').css({overflow:'hidden'}).removeClass('loading-indicator').addClass('transitioning');
	var slideHead = jQuery('.configurator .open .head').animate({backgroundColor:'#eeeee6'},500);
	slideHead.find('h3:first').animate({color:'#333',backgroundColor:'#eeeee6'},500);
	slideHead.children(':visible:not(h3:first)').fadeOut(500);
	slideFrame.animate({height:'23px'}, 500, function(){
		jQuery(this).css({display:'',height:'',overflow:''}).attr('style','').removeClass('transitioning');
		slideHead.attr('style','');
		slideHead.children().attr('style','');
		if(typeof callback == 'function') callback.call();
		return jQuery(this);
	});
}
function transitionSlide(data){
	minimizeSlide(function(){
		//TODO: Remove after Find A Store AB Test is complete
		var config = jQuery(data);
		config.find(".find-a-store-container").replaceWith(jQuery(".find-a-store-container"));
		jQuery('.configurator').replaceWith(config);
		maximizeSlide();
	});
}

var availabilityLevels = ["-","1-3 Days","3-5 Days","5-7 Days","1-2 Weeks","3-4 Weeks","6-8 Weeks","Out of Stock"];

//Needed to implement post-load process for Power Reviews on Shop. PowerReviews take only document object. this adds ".write" method to jQuery Objects.  
jQuery.fn.write = function(input){jQuery(this).append(input);};
