﻿/*
 * 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);
			}
		},

		// 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).bind("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').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 () {
		var config = jQuery(data);
		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);
};

