/*
 * All java script logic for the application.
 *
 * The code relies on the jQuery JS library to
 * be also loaded.
 */
function jq(myid){ return '#'+myid.replace(/:/g,"\\:").replace(/\./g,"\\.");}
function jid(myid){ return jq(myid);}

var app = (function(jQuery){

	if (!jQuery) {
		alert("jQuery is not loaded yet!");
		return null;
	}
	
	// Global dw private data goes here	

	// dw scope public
	return {
		URLs			: {}, // holds dw specific urls, check htmlhead.isml for some examples
		resources		: {},  // resource strings used in js
		constants		: {}, // platform constants, initialized in htmlhead.isml
		currencyCodes	: {}, // holds currency code/symbol for the site


		// app initializations called from jQuery(document).ready at the end of the file
		init: function() {

			// execute unobtrusive js code
			this.execUjs();
			
			// micicart object initialization
			app.minicart.init();
			
			// active links helper
			jQuery('.listingtop a, .listingtop-white a').live( "click", function(){
				jQuery(this).addClass('clicked');
			});
			
			jQuery('.producttile .image a, .producttile .productName a').live( "click", function(){
				jQuery(this).parents('.producttile').addClass('clicked');
			});
			
		},
	
		// 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 + " error " + error);
							}
							
							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) {

				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);
						}
					});
				}
			}
		},
		
		// 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
			showCartUrl : '',
			addWishlistUrl : '',
			timer : null, // timer for automatic close of cart item view
			
			currentItemIndex: 0,
			maxItemIndex: 0,

			// initializations
			init: function() {
				// reset all the existing event bindings
				app.minicart.reset();

				// bind click event to the cart total link at the top right corner
				jQuery(".minicarttotal").live( "click", function(e){
					
					if (typeof(IS_PT_CHECKOUT) != "undefined")
					{
						if (IS_PT_CHECKOUT){
						 return false;	
						}
					}
					window.location.href = app.minicart.showCartUrl;
					return false;
				});
				
				jQuery("#minicart").live( "mouseenter", function(e) {
					clearTimeout(app.minicart.timer);
					app.minicart.timer = null;
					app.minicart.slide();
				}).live( "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()', 150 );
				});

				// register close button event
				jQuery('#minicartcontent #minicartclose').live( "click", function() {
					app.minicart.close(0);
				});
			},
			
			// returns a boolean if a minicart is visible/shown or hidden
			isShow: function() {
				return jQuery('#minicartcontent').css('display') == 'none' ? false : true;
			},
			
			// reset minicart
			reset: function() {
				//jQuery(".minicarttotal").unbind("click");
				jQuery(".minicarttotal").unbind("mouseover");
				jQuery(".minicarttotal").unbind("mouseout");
				jQuery('#minicartcontent').unbind("mouseenter").unbind("mouseleave");
				jQuery('#minicartcontent #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;
				}
				if(app.searchsuggest.hasFocus)
				{
					app.searchsuggest.acSearchField.blur();
				}
				
				jQuery('#minicart a.linkminicart').addClass('on');
				
				// show the item
				jQuery("div.minicartitem").not('.showing').hide();
				// setTimeout( 'jQuery("#minicartcontent").slideDown("fast")', 30 );
				jQuery("#minicartcontent").slideDown("fast");
				
				clearTimeout(app.minicart.timer);
				app.minicart.timer = null;
					
				// after a time out automatically close it
				app.minicart.timer = setTimeout( 'app.minicart.close()', 2000000 );
			},
			// adds a wishlist to the mini cart 
			addWishlist: function(progressImageSrc, postdata, callback)
			{
				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;
				}
				
				var handlerFunc = function(req) {
					document.body.style.cursor = "default";
					// hide progress indicator
					if(addButton != null) {addButton.src = previousImageSrc; }
					
					// replace the content
					
					jQuery('#minicart').html(req);
					
					if(app.minicart.suppressSlideDown && app.minicart.suppressSlideDown()) {
						// do nothing
						// the hook 'MiniCart.suppressSlideDown'
					}
					else {
						app.minicart.slide();
					}
					if (callback) callback();
				}
				
				// handles add to cart error
				var errFunc = function(req) {
					document.body.style.cursor = "default";
					// hide progress indicator
					if (addButton != null) {
						addButton.src = previousImageSrc;
					}				}

				// closes a previous mini cart
				app.minicart.close();
				
				document.body.style.cursor = "wait";

				// add the product
				jQuery.ajax({
					type	: "POST",
					url		: app.minicart.addWishlistUrl,
					cache	: true,
					data	: postdata,
					success	: handlerFunc,
					error	: errFunc
				});
				
			},
			// adds a product to the mini cart
			add: function(progressImageSrc, postdata, callback)
			{
				//alert("Are We Getting Here?");
				// 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)	{
					document.body.style.cursor = "default";
					// hide progress indicator
					if (addButton != null) {
						addButton.src = previousImageSrc;
					}
					
					// replace the content
					
					jQuery('#minicart').html(req);
					

					if(app.minicart.suppressSlideDown && app.minicart.suppressSlideDown()) {
						// do nothing
						// the hook 'MiniCart.suppressSlideDown()' should have done the refresh
					}
					else {
						app.minicart.slide();
					}
					if (callback) callback();
				}

				// handles add to cart error
				var errFunc = function(req) {
					document.body.style.cursor = "default";
					// hide progress indicator
					if (addButton != null) {
						addButton.src = previousImageSrc;
					}				}

				// closes a previous mini cart
				app.minicart.close();
				
				document.body.style.cursor = "wait";

				// 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 a.linkminicart').removeClass('on');
					
					app.minicart.currentItemIndex = 0;
					jQuery('#minicartcontent').hide(); 
					//jQuery('#minicartcontent').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;
			},
			
			// pages forth within the minicart items
			pageForth: function() {
				if (app.minicart.currentItemIndex == app.minicart.maxItemIndex) {
					app.minicart.showItem(0);
				} else {
					app.minicart.showItem(app.minicart.currentItemIndex + 1);
				}
			},
			
			// pages back within the minicart items
			pageBack: function() {
				if (app.minicart.currentItemIndex == 0) {
					app.minicart.showItem(app.minicart.maxItemIndex);
				} else {
					app.minicart.showItem(app.minicart.currentItemIndex - 1);	
				}
			},
			
			// helper function to show the minicart item with at given item index
			showItem: function(itemIndex) {
				if(itemIndex < 0 || itemIndex > app.minicart.maxItemIndex) {
					return;
				}
				
				app.minicart.currentItemIndex = itemIndex;
				jQuery("div.minicartitem").hide().removeClass('showing');
				jQuery("div#minicartitem-" + itemIndex).show().addClass('showing');
				jQuery("div#minicartcontent span.current").html(itemIndex + 1);
			}
		},


	
		/**
		 * Unobtrusive js api calls go here.
		 */
		 execUjs: function() {
			
		},
		
		// sub namespace app.producttile.* contains utility functions for product tiles
		producttile : {
			// initializes all product tiles contained in the current page
			initAll: function() {

				// tile hover
				jQuery('#search .repeatedItemA, .featuredProduct').live('mouseover mouseleave', function(event) {
					  if (event.type == 'mouseover') {
							jQuery(this).addClass("productHover");
							
							if (!jQuery(this).hasClass('loaded')) {
								// preload full images from swatches
								jQuery(this).find('div.swatches').find('a.swatch').each(function(){
									// grab colorway info
									var imageData = jQuery.parseJSON(jQuery(this).attr("data"));
									jQuery("#"+imageData.productID + "-productImage").children('div.preload').append('<img id="' + imageData.variationColor + '" src="' + imageData.imageURL + '" style="display: none;"/>');
								});
								jQuery(this).addClass('loaded');
							}
							
					  } else {
						  jQuery(this).removeClass("productHover");
						  jQuery(this).find('div.swatches div.hidden-swatches:visible').hide();
					  }
				});
				
				// handle swatch click
				jQuery(".productlisting .producttile .swatches a.swatch").live("click", function(event) {
					// grab parent
					var parentObj = jQuery(this).parents(".swatches");
					var productImage = parentObj.parent().children('div.productImage');
					var thisImageUrl = jQuery(this).attr('rel');

					jQuery(productImage.children('a').children('img.product')).attr("src", thisImageUrl);
					
					//bui.crossFadeProductImages(productImage.children('a').children('img.product'), thisImageUrl);
					
					var thisProductURL = jQuery(this).attr('href');

					// set selected class
					parentObj.find("a").removeClass("selected");
					jQuery(this).addClass("selected");

					// update name and href of variation
					productImage.children('a').attr("href", thisProductURL);
					parentObj.next('div.productName').children('h2').children('a').attr("href", thisProductURL);
					
					return false;
				});

				jQuery(".producttile .swatches a.view-swatches").live("click", function(event) {
					jQuery(this).next('.hidden-swatches').show();
				});

				jQuery(".producttile .swatches div.hidden-swatches").live('mouseleave', function(event) {
					jQuery(this).hide();
				});
			}
		},
		


		// sub namespace app.util.* contains utility functions
		util : {
			// 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) {
				if ( typeof name == 'object' )
				{
					return url + '?' + jQuery.param( name );
				}
				
				var c = "?";
				if(url.indexOf(c) != -1) {
					c = "&";
				}
				return url + c + name + "=" + encodeURIComponent(value);
			},

			// dynamically loads a CSS file
			loadCSSFile : function(url) {
				var elem = document.createElement("link");
				elem.setAttribute("rel", "stylesheet");
				elem.setAttribute("type", "text/css");
				elem.setAttribute("href", url);

				if(typeof elem != "undefined") {
					document.getElementsByTagName("head")[0].appendChild(elem);
					app.util.loadedCSSFiles.push(url);
				}
			},

			// array to keep track of the dynamically loaded CSS files
			loadedCSSFiles : [],

			// removes all dynamically loaded CSS files
			clearDynamicCSS : function() {
				for(var i=0; i<app.util.loadedCSSFiles.length; i++) {
					app.util.unloadCSSFile(app.util.loadedCSSFiles[i]);
				}
			},

			// dynamically unloads a CSS file
			unloadCSSFile : function(url) {
				var candidates = document.getElementsByTagName("link");
				for(var i=candidates.length; i>=0; i--) {
					if(candidates[i] && candidates[i].getAttribute("href") != null && candidates[i].getAttribute("href").indexOf(url) != -1) {
						candidates[i].parentNode.removeChild(candidates[i]);
					}
				}
			},

			// checks if cookies are enabled
			cookiesEnabled : function() {
				var currentCookie = document.cookie;
				document.cookie = "Enabled=true";
				var cookieValid = document.cookie;
				var result = false;

				if(cookieValid.indexOf("Enabled=true") != -1) {
					result = true;
				}

				document.cookie = currentCookie;
				return result;
			},
			
			// changes the selection of the given form select to the given value
			changeFormSelection: function (selectElem, selectedValue) {
				if(!selectElem) return;
				var options = selectElem.options;
				var valu;
				var txt;
				if(options.length > 0) {
					// find index of value to select
					var idx = 0;
					for(var i=0; i<options.length; i++) {
						if(options[i].value != selectedValue) continue;
						valu = options[i].value;
						txt =  options[i].text;
						idx = i; break;
					}
					selectElem.selectedIndex = idx;
					//alert(selectElem + '|' + txt + '|'+ valu + '|' + selectedValue + '|' + idx + '|' + jQuery(selectElem + "[value='"+valu+"']").val() + '|' + jQuery(selectElem + "[value='"+idx+"']").val());
					if (jQuery(selectElem + "[value='"+idx+"']").val() === undefined)
					{ 
						//alert('reset valu');
						valu = idx; //jQuery(selectElem + "[value='"+idx+"']").index()
					}
					else 
					{ 
						valu = jQuery(selectElem + "[value='"+idx+"']").val(); 

					} 
					//alert(valu);
					//jQuery(selectElem).selectmenu('value', valu);
				}
			}
		}
	}
})(jQuery);

// application initialization on dom ready
jQuery(document).ready(function(){
	app.init();
});
