/*
 * All java script logic for the application.
 *
 * The code relies on the jQuery JS library to
 * be also loaded.
 */

var app = (function(jQuery){
  
	if (!jQuery) {
		alert(app.resources["MISSING_LIB"]);
		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
		containerId		: "content",
		ProductCache	: null,  // app.Product object ref to the current/main product
		clearDivHtml	: "<div class=\"clear\"><!-- W3C Clearing --></div>",
		currencyCodes	: {}, // holds currency code/symbol for the site

		// default dialog box settings
		dialogSettings: {
				bgiframe: true, // this is required mainly for IE6 where drop downs bleed into dialogs!!! it depends on 
				autoOpen: false,
				buttons: {},
				modal: true,
				overlay: {
		    		opacity: 0.5,
		     		background: "black"
				},
		    	height: 550,
		    	width: 650,
		    	title: '',
		    	// show: "slow", This is causing dialog to break in jquery 1.3.2 rel, show: "slide" works but not desired
		    	hide: "normal",
		    	draggable:false,
		    	resizable: false
		},

		// default tooltip settings
		tooltipSettings: {
				delay: 0,
				showURL: false,
				extraClass: "tooltipshadow",
				top: 15,
				left: 5
		},

		// global form validator settings
		validatorSettings: {
			errorClass : 'errormessage',
			errorElement: 'span',
			
		    onfocusout: function(element) {
				if ( !this.checkable(element) ) {
					this.element(element);
				}				
			}
		},

		// app initializations called from jQuery(document).ready at the end of the file
		init: function() {
			// register initializations here
			
			// quick view dialog div
			jQuery("<div/>").attr("id", "QuickViewDialog").html(" ").appendTo(document.body);

			// minisubscription object initialization
			this.minisubscription.init();
			
			// minicart object initialization
			this.minicart.init();

			// execute unobtrusive js code
			this.execUjs();
			
			this.recommendation.init();
			
			// renders horizontal/vertical carousels for product slots
			jQuery('#horicarousel').jcarousel({
	        	scroll: 1,
				itemVisibleInCallback: app.captureCarouselRecommendations
		    });

		    jQuery('#vertcarousel').jcarousel({
		        scroll: 1,
				vertical: true,
				itemVisibleInCallback: app.captureCarouselRecommendations
		    });	

		    /*rounds corners of elements with "rounded" class (jQuery manipulation for IE only)*/
		    try
		    {
		    	jQuery('.rounded:not(".top,.bottom")').corner("3px"); //all corners
				jQuery('.rounded:not(".bottom")').corner("top 3px"); //top left & top right
				jQuery('.rounded:not(".top")').corner("bottom 3px"); //bottom left & bottom right*/
		    }
			  catch(err)
			    {
			    //Handle errors here
			    }
			

			//jQuery('.navgroup > ul > li > a').corner("3px"); //all corners on left nav links in IE
			
			//if (jQuery('.sbxtab').length > 0) this.sbxtabs();
		},
	
		// 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(app.resources["BAD_RESPONSE"]);
							}
							
							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(app.resources["BAD_RESPONSE"]);
							}

							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+" .addtocartbutton:last").html(a2cBtnLabel) : '');
			}});
		},
		
		

		
		
		// sub name space app.hitlist.* provides functionality around the hitlist carousel
		hitlist: {
	
			// scroll the contents of myBag left or right if there more items
			scroll: function(direct) {
			
				if (!(jQuery("#hitlist .pagescroll").length) ) {
					//alert("returning");
					return;
				}
	
				var pagewidth = 720;
				var speed = 400;
				
				var totalpages = 0;
				var page = 0;
				
				jQuery("#hitlist .pagescroll ul li").each(function(index) {
					totalpages += 1;
					if (jQuery(this).is(".selected")) page = index; 
				});
				
				totalpages -= 2; //accounts for the left and right buttons, which are also <li>s 
				
	
				if (direct == "right" && page < totalpages) {
					jQuery(".hitlistcarousel .hlccontent").animate({"left": "-="+pagewidth}, speed);
					jQuery("#hlistpage" + page).removeClass("selected");
					jQuery("#hlistpage" + (page+1)).addClass("selected");
					page += 1;
				} else if (direct == "left" && page > 1) {
					jQuery(".hitlistcarousel .hlccontent").animate({"left": "+="+pagewidth}, speed);
					jQuery("#hlistpage" + page).removeClass("selected");
					jQuery("#hlistpage" + (page-1)).addClass("selected");
					page -= 1;
				} 
				else if (!isNaN(direct) && direct != page) {
					var posneg = "";
					var val = parseInt(direct) - page;
					if (val > 0) posneg = "-";
					else if (val < 0) posneg = "+";
	
					jQuery(".hitlistcarousel .hlccontent").animate({"left": posneg+"="+Math.abs(val)*pagewidth}, speed);
					jQuery("#hlistpage" + page).removeClass("selected");
					jQuery("#hlistpage" + (page+val)).addClass("selected");
					
					page = parseInt(direct); 
				}
				
				//after page scroll is complete, set left or right arrow to unselectable, if nec.
				if (page < totalpages) {
					jQuery("#hlistpageright").removeClass("unselectable");
					if (page == 1) jQuery("#hlistpageleft").addClass("unselectable");
				}
				if (page > 1) {
					jQuery("#hlistpageleft").removeClass("unselectable");
					if (page == totalpages)jQuery("#hlistpageright").addClass("unselectable");
				}
			}
		},
	
			
			
			
		
		// sub name space app.minisubscription.* provides functionality around the mini cart
		minisubscription: {
			url   : '',  // during page loading, the Demandware URL is stored here
			timer : null, // timer for automatic close of cart item view
			delay : 300,
			// initializations
			init: function() {
				// reset all the existing event bindings
				app.minisubscription.reset();

				// bind hover event to the transparent trigger overlay
				jQuery("#minisubscription").hover(
					function(e){ //mouse enter
						clearTimeout(app.minisubscription.timer);
						app.minisubscription.timer = null;
						if(app.minisubscription.isShow() == false) app.minisubscription.timer = setTimeout( 'app.minisubscription.slide()', 300 ); // after a delay open the flyout
					},
					function(e){ //mouse leave
						clearTimeout(app.minisubscription.timer);
						app.minisubscription.timer = null;
						app.minisubscription.timer = setTimeout( 'app.minisubscription.close()', 100 ); // after a time out automatically close the flyout
					}
				);
				
				/*
				jQuery('.minisubscription .flyout')
				.mouseenter(function(e) {
					clearTimeout(app.minisubscription.timer);
					app.minisubscription.timer = null;
				})
				.mouseleave(function(e) {
					clearTimeout(app.minisubscription.timer);
					app.minisubscription.timer = null;
					// after a time out automatically close it
					app.minisubscription.timer = setTimeout( 'app.minisubscription.close()', 100 );
				});
				*/
				
				/*
				// register close button event
				jQuery('.minisubcontent .minisubclose').click(function() {
					// reset all the events bindings
					app.minisubscription.reset();
					app.minisubscription.close(0);
				});
				*/

				//grow or shrink minisubscription div horizontally
				/*
				 * jQuery('.minisubscription #msradioleft').click(function() {
				 * 		app.minisubscription.resize("390px","hide");
				 * });
				 * jQuery('.minisubscription #msradioright').click(function() {
				 * 		app.minisubscription.resize("580px","show");
				 * });
				 */
			},

			/*
			// grow or shrink the flyout from the right
			resize: function(newwidth, hideShow) {
				var num = parseInt(newwidth.replace("px",""));
				var newFlyoutWidth = num + "px";
				var newContentWidth = (num-8) + "px";
				jQuery('.minisubscription .flyout').css("overflow","hidden");
				if (hideShow == "show") {
					jQuery('.minisubscription .minisubcontent').css('width',newContentWidth);
					jQuery('.minisubscription .minisubcontent .justadded').show();
					jQuery('.minisubscription .minisubcontent .vertdivider').show();
				}
				jQuery('.minisubscription .flyout').animate({"width": newFlyoutWidth}, "fast",
					function(){
						if (hideShow == "hide") {
							jQuery('.minisubscription .minisubcontent .justadded').hide();
							jQuery('.minisubscription .minisubcontent .vertdivider').hide();
							jQuery('.minisubscription .minisubcontent').css('width',newContentWidth);
						}
					}
				);
			},
			*/
			
			// returns a boolean if a minisubscription is visible/shown or hidden
			isShow: function() {
				return jQuery('#subflyout').is(':hidden') ? false : true;
			},
			
			// reset minisubscription
			reset: function() {
				jQuery("#minisubscription").unbind("hover");
				//jQuery('.minisubscription .flyout').unbind("mouseenter").unbind("mouseleave");
				//jQuery('.minisubcontent .minisubclose').unbind("click");
			},

			// shows the given content in the mini cart
			show: function(html) {
				jQuery('#minisubscription').html(html);
				
				// bind all the events
				app.minisubscription.init();
				
				if(app.minisubscription.suppressSlideDown && app.minisubscription.suppressSlideDown()) {
					// do nothing
					// the hook 'minisubscription.suppressSlideDown()' should have done the refresh
				}
				else {
					app.minisubscription.slide();
					// after a time out automatically close the flyout
					app.minisubscription.timer = setTimeout( 'app.minisubscription.close()', 6000 );
				}
			},
			
			// slide down and show the contents of the mini cart
			slide: function() {
				// if the suppressSlideDown is overridden in the .isml, OR if the minicart flyout is currently visible, do not show minisubscription flyout
				if(app.minisubscription.suppressSlideDown && app.minisubscription.suppressSlideDown()) {
					return;
				}

				//show the tab rollover, show flyout, and change arrow to point up
				//jQuery('.mysubtab').stop(true, true).show();
				jQuery("#subarrw").addClass('msover');
				jQuery('#mysubtab').show();
				jQuery('#subflyout').stop(true, true).slideDown('fast');//show("slide", { direction: "up" }, 1000);
				
				// Check first if the subscription flyout is present
				if (app.minicart.isShow) {
					//be sure the minicart flyout is closed
					app.minicart.close(0);					
				}

				clearTimeout(app.minisubscription.timer);
				app.minisubscription.timer = null;
				//app.minisubscription.timer = setTimeout( 'app.minisubscription.close()', 4000);

			},

			// scroll the contents of myBag left or right if there more items
			scroll: function(direct) {				
				if (!(jQuery(".minisubcontent .pagescroll").length) ) {
					return;
				}

				var speed = 400;
				var pagewidth = jQuery("#minisubscroll ul").outerWidth();
				var totalpages = 0;
				var page = 0;
				
				jQuery(".minisubcontent .pagescroll ul li").each(function(index) {
					totalpages += 1;
					if (jQuery(this).is(".selected")) page = index;
				});
				
				totalpages -= 2; //accounts for the left and right buttons, which are also <li>s 
				

				if (direct == "right" && page < totalpages) {
					jQuery("#minisubscroll").animate({"left": "-="+pagewidth}, speed);
					jQuery("#mspage" + page).removeClass("selected");
					jQuery("#mspage" + (page+1)).addClass("selected");
					page += 1;
				}
				else if (direct == "left" && page > 1) {
					jQuery("#minisubscroll").animate({"left": "+="+pagewidth}, speed);
					jQuery("#mspage" + page).removeClass("selected");
					jQuery("#mspage" + (page-1)).addClass("selected");
					page -= 1;
				}
				else if (!isNaN(direct) && direct != page) {
					var posneg = "";
					var val = parseInt(direct) - page;
					if (val > 0) posneg = "-";
					else if (val < 0) posneg = "+";

					jQuery("#minisubscroll").animate({"left": posneg+"="+Math.abs(val)*pagewidth}, speed);
					jQuery("#mspage" + page).removeClass("selected");
					jQuery("#mspage" + (page+val)).addClass("selected");
					
					page = parseInt(direct); 
				}
				
				//after page scroll is complete, set left or right arrow to unselectable, if nec.
				if (page < totalpages) {
					jQuery("#mspageright").removeClass("unselectable");
					if (page == 1) jQuery("#mspageleft").addClass("unselectable");
				}
				if (page > 1) {
					jQuery("#mspageleft").removeClass("unselectable");
					if (page == totalpages) jQuery("#mspageright").addClass("unselectable");
				}
			},
			
			// closes the minisub with given delay
			close: function(delay) {
				if ( app.minisubscription.timer != null || delay == 0) {
					clearTimeout( app.minisubscription.timer );
					app.minisubscription.timer = null;		
					
					jQuery('#subflyout').stop(true, true).slideUp('fast',function(){
						jQuery('#mysubtab').hide();
						//app.minisubscription.init(); // re-bind all the events
					});
					
					//change the arrow direction next to the my subscription text
					jQuery("#subarrw").removeClass('msover');
					if(jQuery("#justadded").length) jQuery("#justadded").remove();
				}
			},

			// hook which can be replaced by individual pages/page types (e.g. cart)
			suppressSlideDown: function() {
				return false;
			},
			
			update: function(pid) {
				if (pid == undefined){
					pid	= 0;		
				}
				var JustAddedurl = app.util.appendParamToURL(app.URLs.minisubscription, "pid", pid);
				app.ajax.load({selector: "#minisubscription", url: JustAddedurl, callback: function(){					
					app.minisubscription.init();
					jQuery('html, body').animate({scrollTop:0},'300',function(){app.minisubscription.slide();});		
				}});
			}
		},

		// sub name space app.minicart.* provides functionality around the mini cart
		minicart: {
			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 transparent trigger overlay
				jQuery("#minicart").hover(
					function(e){ //on mouse enter
						clearTimeout(app.minicart.timer);
						app.minicart.timer = null;
						if(app.minicart.isShow() == false) app.minicart.timer = setTimeout( 'app.minicart.slide()', 300 ); // after a slight delay open the flyout
					},
					function(e){ //on mouse leave
						clearTimeout(app.minicart.timer);
						app.minicart.timer = null;
						app.minicart.timer = setTimeout( 'app.minicart.close()', 100 ); // after a slight delay automatically close the flyout
					}
				);
				
				/*
				// bind hover event to the cart total link at the top right corner
				//jQuery(".minicarttotal .cartlabel").hover(function(e){(app.minicart.isShow() ? '': app.minicart.slide());});
			
				jQuery('.minicart .flyout')
				.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()', 100 );
				});
				*/
				
				/*
				// register close button event
				jQuery('.minicartcontent .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('#cartflyout').is(":hidden") ? false : true;
			},
			
			// reset minicart
			reset: function() {
				jQuery("#minicart").unbind("hover");
				//jQuery(".minicarttotal .cartlabel").unbind("hover");
				//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.isShow() ? '': app.minicart.slide());
				}
			},
			
			// slide down and show the contents of the mini cart
			slide: function(timerset) {
				var timerset = timerset;
				
				// if the suppressSlideDown is overridden in the .isml, OR if the minisubscription flyout is currently visible, do not show minicart flyout
				if(app.minicart.suppressSlideDown && app.minicart.suppressSlideDown()) {
					return;
				}

				// Check first if the subscription flyout is present
				if (app.minisubscription.isShow) {
					//close the minisubscription flyout
					app.minisubscription.close(0);					
				}

				// show the item
				//jQuery('#mycarttab').stop(true, true).show();
				jQuery('#mycarttab').show();
				jQuery('#cartflyout').stop(true, true).slideDown('fast');//show("slide", { direction: "up" }, 1000);
				jQuery('#cartarrw').addClass('msover');

				clearTimeout(app.minicart.timer);
				app.minicart.timer = null;
					
				// after a time out automatically close it
				if (timerset) app.minicart.timer = setTimeout( 'app.minicart.close()', timerset );
			},
			
			// scroll the contents of myBag left or right if there more items
			scroll: function(direct) {
				
				if ( !(jQuery(".minicart .pagescroll").length) ) {
					return;
				}

				var pagewidth = 165;
				var speed = 400;
				
				var totalpages = 0;
				var page = 0;
				
				jQuery(".minicart .pagescroll ul li").each(function(index) {
					totalpages += 1;
					if (jQuery(this).is(".selected")) page = index; 
				});
				
				totalpages -= 2; //accounts for the left and right buttons, which are also <li>s 
				

				if (direct == "right" && page < totalpages) {
					jQuery("#myBag #scrollme").animate({"left": "-="+pagewidth}, speed);
					jQuery("#mbpage" + page).removeClass("selected");
					jQuery("#mbpage" + (page+1)).addClass("selected");
					page += 1;
				}
				else if (direct == "left" && page > 1) {
					jQuery("#myBag #scrollme").animate({"left": "+="+pagewidth}, speed);
					jQuery("#mbpage" + page).removeClass("selected");
					jQuery("#mbpage" + (page-1)).addClass("selected");
					page -= 1;
				}
				else if (!isNaN(direct) && direct != page) {
					var posneg = "";
					var val = parseInt(direct) - page;
					if (val > 0) posneg = "-";
					else if (val < 0) posneg = "+";

					jQuery("#myBag #scrollme").animate({"left": posneg+"="+Math.abs(val)*pagewidth}, speed);
					jQuery("#mbpage" + page).removeClass("selected");
					jQuery("#mbpage" + (page+val)).addClass("selected");
					
					page = parseInt(direct); 
				}
				
				//after page scroll is complete, set left or right arrow to unselectable, if nec.
				if (page < totalpages) {
					jQuery("#mbpageright").removeClass("unselectable");
					if (page == 1) jQuery("#mbpageleft").addClass("unselectable");
				}
				if (page > 1) {
					jQuery("#mbpageleft").removeClass("unselectable");
					if (page == totalpages)jQuery("#mbpageright").addClass("unselectable");
				}
			},

			// adds a product to the mini cart
			// @params
			// progressImageSrc - source/url of the image to show when the item is being added to the cart
			// postdata - form data containing the product information to be added to mini-cart
			// callback - call back function/handler
			// noneventful - suppress jQuery animations: fly to bag, scroll to top
			add: function(progressImageSrc, postdata, callback, noneventful)
			{
				// 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;
					}

					// replace the content
					jQuery('#minicart').html(req);
					
					// bind all the events
					app.minicart.init();
					
					if (callback) callback();

					if (noneventful) return false;
					
					//function to animate product image into minicart
					function animateToBag(pid){
						if (!pid) return false;
						if (jQuery("#pi_"+pid)[0]==false) return false;
						var prodImg = jQuery("#pi_"+pid);
						var offsetBag = jQuery('#minicart').offset();
						var offsetProd = prodImg.offset();
						var moveY = offsetBag.top+50 - offsetProd.top;
						var moveX = offsetProd.left - offsetBag.left+80;
						//alert(offsetProd.left+" : "+offsetBag.left+80+" : "+moveX);

						prodImg.clone().appendTo(document.body).attr("id","productImageClone");
						var cloneImg = jQuery('#productImageClone');
						cloneImg.css({'position' : 'absolute', 'left' : offsetProd.left, 'top' : offsetProd.top, 'z-index' : '101' });
						
						cloneImg.animate({
						    height: 	'toggle',
						    width:		'toggle',
						    left:		offsetBag.left+80,
						    top:		offsetBag.top+50,
						    opacity:	0.25
						  }, 1000, 'swing', function() {
						    // Animation complete (callback)
							cloneImg.remove();
						  });
					}

					//animate product image into minicart
					animateToBag(postdata.pid);
					
					//scroll to top of window first, then invoke flyout
					jQuery('html, body').animate({scrollTop:0},'300',function(){app.minicart.slide(4000);});
					
					return false;
				}

				// 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();

				/*
				 * Kailex 2/1/10
				 * Add function updated to show cart modal with product already added. it gives the user option to update quantity or remove product.
				 */
				
				 jQuery.ajax({
					type	: "POST",
					url		: app.minicart.url,
					cache	: true,
					data	: postdata,
					success	: handlerFunc,
					error	: errFunc
				});
				

			},

			// updates product in quickview
			// @params
			// progressImageSrc - source/url of the image to show when the item is being added to the cart
			// postdata - form data containing the product information to be added to mini-cart
			// prodid - product id
			// callback - call back function/handler
			update: function(progressImageSrc, postdata, prodid, callback)
			{
				var productUrl = app.util.appendParamToURL(app.URLs.cartShowMini, "prodid", prodid);
				productUrl = app.util.appendParamToURL(productUrl, "source", "cart");
				productUrl = app.util.appendParamToURL(productUrl, "label", "Update");

				jQuery.ajax({
					type	: "POST",
					url		: app.URLs.cartShowMiniUpdateQty,
					cache	: true,
					data	: postdata,
					success	: function() {
						jQuery.ajax({
							type	: "POST",
							url		: productUrl,
							cache	: true,
							data	: postdata,
							success	: callback
						});
					}
				});
				
				/*
				// handles success
				var handlerFunc = function(req)	{
					// replace the content
					jQuery('.cart').html(req);
				}
				
				// update the product
				jQuery.ajax({
								type	: "json",
								url		: app.URLs.cartShowMiniUpdateQty,
								data	: postdata,
								success	: handlerFunc

							});
				
				var handlerFunc2 = function(req)	{
					// replace the content
					jQuery('.cart').html(req);
				}
				var handlerFunc = function(req)	{
					jQuery.ajax({
						type	: "POST",
						url		: productUrl,
						success	: handlerFunc2
					});
				}
				
				jQuery.ajax({
					type	: "POST",
					url		: app.URLs.cartShowMiniUpdateQty,
					data	: postdata,
					success	: handlerFunc
				});
				*/

			},

			orderStatusLoading: function(progressImageSrc)
			{
				jQuery('#od').html("<div><img src="+progressImageSrc+"></div>Loading...Please wait...");
			},	

			orderStatus: function(customerno, pagingurl,loadURL)
			{
				var customerno = customerno;
				if (pagingurl) {
					var statusurl = app.minicart.orderstatusurlpaging;
				} else {
					var statusurl = app.minicart.orderstatusurl;
				}
								
				statusurl += '?customerno='+customerno;
				
								
				// handles success
				handlerFunc = function(req)	{
					// replace the content
					jQuery('#orders').html(req);
					
					var pagination = jQuery(".pagination");					
					var anchor = pagination.find("li").find("a");					
					anchor.click(function(){
						pUrl = jQuery(this).attr("href");						
						customerno =customerno.indexOf("&start")==-1?customerno:customerno.split("&start")[0]
						var pUrl = pUrl.split("&start");						
						var pParam = "&start" + pUrl[1];
						
						jQuery('#orders').html("")
						jQuery('#orders').append("<div id='od'></div>");
						app.minicart.orderStatusLoading(loadURL);	
						app.minicart.orderStatus(customerno + pParam,false)
						return false;
					})	
					
					
				}
				// handles error
				var errFunc = function(req) {
					//jQuery('#t1').html(req);
				}

				jQuery.ajax({
								type	: "json",
								url		: statusurl,
								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;		
				
					//use the following if IE6 ? :
					jQuery('#cartflyout').stop(true, true).slideUp('fast',function(){jQuery('#mycarttab').hide();});
					
					//...otherwise :
					//jQuery('.minicart .flyout').fadeOut();
					//jQuery('.mycarttab').fadeOut();
					
					//change the arrow direction next to the my subscription text
					jQuery("#cartarrw").removeClass('msover');
				}
			},

			// 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;
		},

		// Product shop now object
		shopNow: {
			// initializations
			bindEvents: function(options) {
				//options -
				//buttonSelector: "div.producttile div.shopnowbutton",
				//imageSelector: "div.producttile div.image",
				//buttonLinkSelector: "div.producttile div.shopnowbutton a"
							
			
				//jQuery(options.buttonSelector).hide();
			
				var timer;
				
				jQuery(".producttile").mouseenter(
						function(e) {
							if (jQuery('#shopnowflyout').length == 0) {
								jQuery(this).css('z-index',5);
								if (!jQuery(this).hasClass(".listview")) {
									jQuery(this).find("#shopnow").slideDown(200);							
								}
								//jQuery(".shopnowbutton").show();	
								//jQuery(this).children(options.buttonSelector).show();
							}
						
																				
							//jQuery(".shopnowflyout").focus();
						
							return false;
						}).mouseleave(
						function(event) {
							if (jQuery('#shopnowflyout').length == 0) {
										
								if(document.activeElement.className=='quantityinput' || document.activeElement.className=='variantdropdownid'){
									
									var event = jQuery(document.activeElement).data('events');
									
									var select =jQuery(document.activeElement);
									
									//lost the focus on select
									var fn = function(){
													  document.activeElement.blur();                 // most browsers 
													  document.activeElement.hideFocus = true;       // internet explorer
													  document.activeElement.style.outline = 'none'; // mozilla
													  jQuery(".shopnowflyout").focus();
													  jQuery(".shopnowflyout").unbind("mouseenter");
													  jQuery(".shopnowflyout").unbind("mousemove"); 
													 }
									
									
									var hasNoChangeEvent=true;
									
									//check the select if already has a change event
									jQuery.each(event,function(type,obj){
										if(type=='change'){																					
											//jQuery.each(obj,function(j,h){												
											//	func = h
											//});	
											//alert(document.activeElement.className);	
													select.unbind("changed");
													select.bind("changed",function(){																									
														jQuery(".shopnowflyout").mouseenter(fn)
														
														// set remove focus on select element after selection														
														jQuery(".shopnowflyout").mousemove(function(){														  
															jQuery(document.activeElement).trigger("removefocusedOnSelect",[select.id]);  														  
														})
													})
													 
													 //remove focus on select element after selection
													 select.unbind("removefocusedOnSelect")
													 select.bind("removefocusedOnSelect",function(event,elem){
														 jQuery(fn);
													 })
													
													hasNoChangeEvent=false;
										}	
									});
									
									//if select element has no change event
									if(hasNoChangeEvent){
										select.unbind("change");
										select.change(function(){																																											
											jQuery(".shopnowflyout").mouseenter(fn)	
											
											//set remove focus on select element 
											jQuery(".shopnowflyout").mousemove(function(){														  
												jQuery(document.activeElement).trigger("removefocusedOnSelect",[select.id]);  														  
											})
											
											//remove focus on select element after selection
											select.unbind("removefocusedOnSelect")
											select.bind("removefocusedOnSelect",function(event,elem){
												jQuery(fn);
											})
											
										})
										
									}
									
									// prevent mouse leave from triggering
									return false;										
								}; 
							
			 					jQuery(this).css('z-index',0);
			 					
			 					//if Grid View, close shopnow when you roll off 
			 					if (!jQuery(this).hasClass(".listview")) {
									jQuery(this).find(".shopnow").stop();
					 				jQuery(this).find(".shopnow").css('height','');
					 				jQuery(this).find(".shopnow").css('overflow','');					 				
				 					jQuery(this).find(".shopnow").slideUp(0);
									jQuery(this).children(options.buttonSelector).hide();
			 					}

								//app.shopNow.close();
							}
							return false;
												
						});
				
				
				// click binding for shopnow quickview flyout
				jQuery(options.buttonLinkSelector).click(function(e) {
					if (jQuery("#shopnowflyout").length > 0) {
						jQuery("#shopnowflyout").parents(".producttile").css("z-index","0");
						jQuery("#shopnowflyout").remove();
						return false;
					} 
					
					var _this = jQuery(this);
					var flyoutUrl = _this.attr("href");
					
					if (_this.parent().hasClass("subflyout")) flyoutUrl = app.util.appendParamToURL(flyoutUrl,"sub","true");	
					
					_this.parents(".producttile").css("z-index",5);
					app.shopNow.show({url: flyoutUrl, container: _this.parent()});						
										
					return false;
				});
			},
		 
			shopNowFlyout: jQuery('<div id="shopnowflyout" class="shopnowflyout"><div class="shopnowflyouttop"></div><div id="shopnowcontent" class="shopnowflyoutbottom"></div></div>'),

			//isIE7: ($.browser.msie  && parseInt($.browser.version) == 7),
			
			show: function(options) {
				//if (app.shopNow.isIE7) {
				//	app.shopNow.shopNowFlyout.find("#shopnowcontent").html(jQuery("<img/>").attr("src", app.URLs.loadingSmallImg).attr("class", "loader"));					
				//} else {
				//	app.shopNow.shopNowFlyout.find("#shopnowcontent").html("");
				//}				
				var hitlist = jQuery("#hitlist");
				
				if (hitlist.css("display")=="block" && options.container.parents("#hitlist").length > 0) {
					hitlist.append('<div id="shopnowflyout" class="shopnowflyout"><div class="shopnowflyouttop"></div><div id="shopnowcontent" class="shopnowflyoutbottom"></div></div>')
					var fly =jQuery("#shopnowflyout");										
					fly.css("position","absolute");
					var w = options.container.parents(".producttile").width();
					var h = fly.outerHeight(true);
					var fw = fly.width();
					var hl = hitlist.offset().left
					var hlEndpoint = hitlist.width() + hl;
					var lastRowPointBoundary = hlEndpoint - (w + (w/2));
					var ofl = options.container.parents(".producttile").offset().left;
					var lf =  ofl - hl;
					
					fly.css("left", lf + "px");
					
					if (ofl >= lastRowPointBoundary) {
						fly.css("margin-left","-202px");						
					}
					
					if (options.container.find(".add2sub").length>0) {
						fly.css("top","131px");
					} else if (options.container.find(".add2bag").length>0) {
						//this will fix the hop up size for items with add2bag buttons only
						//please inform Edgar San Jose before editing this part. 8/1/11
						if(options.container.parents(".shopnow").find(".add2sub").length==0){
							fly.css("top","131px");
						}else{
							fly.css("top","110px");
						}
					}
					
				} else {
					app.shopNow.shopNowFlyout.find("#shopnowcontent").html(jQuery("<img/>").attr("src", app.URLs.loadingSmallImg).attr("class", "loader"));	
					options.container.append(app.shopNow.shopNowFlyout);	
				}	
				
				var urlprod=options.url; 
				
				if(window.location.href.indexOf("https")>-1){
					urlprod =urlprod.replace(/http/g,"https"); 					
				}
				
				jQuery.ajax({
					type:"GET",
					url:urlprod,
					dataType: "html",
					success: function(data){
						jQuery("#shopnowcontent").html(data);
					},
					failure: function(data){}
				});

				jQuery(".producttile").click(function(e) {
					if (jQuery(this).find("#shopnowflyout").length > 0) {
						return false;
					} 
					
					app.shopNow.close();
				});

				jQuery("body").click(function(e) {
					//Hide the menus if visible
					if(jQuery(e.target).get(0).tagName!="SELECT"){						
						app.shopNow.close();	
					}
				});
			},
			
			close: function(shopnowstay) {	
				var shopnowflyout = jQuery("#shopnowflyout");
				if (shopnowflyout.length == 0) return false;
				jQuery(".producttile").unbind("click");
				jQuery(".producttile").css('z-index',0);
				jQuery("body").unbind("click");
				//app.minisubscription.reset();
				//app.minisubscription.close(0);
				
				shopnowflyout.remove();
	
				if(jQuery(".listview").length==0){
					jQuery(".shopnow").hide();
				}	
				
			}
		},
		
		
		// Product quick view object
		quickView: {
			// bind browser events
			// options
			// buttonSelector - css selector for the quickview button
			// imageSelector - css selector for product image
			// buttonLinkSelector - css selector for quickview button link (a tag)
			// productNameLinkSelector - css selector for product name link (a tag)
			bindEvents: function(options) {
				// hide quickview buttons
				jQuery(options.buttonSelector).hide();

				/*
				 * Commented by Mark Llena on January 7, 2011 not to show the  
				 * quickview button when you hover over the product tile
				// hovering 
				
				
				jQuery(".producttile").hover(
						function(e) {
							if (!jQuery(this).is(".listview")) {
								jQuery(this).find(".shopnow").slideDown(200);
								jQuery(".quickviewbutton").show();
							}
							jQuery(this).children(options.buttonSelector).show();
							return false;
						},
						function(e) {
							if (!jQuery(this).is(".listview")) {
				 				jQuery(this).find(".shopnow").stop();
				 				jQuery(this).find(".shopnow").css('height','');
				 				jQuery(this).find(".shopnow").css('overflow','');
								jQuery(this).find(".shopnow").slideUp(0);
							}
							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: '',
			    	resizable: false
				}});

			    jQuery('#QuickViewDialog').dialog('open');
			    app.getProduct({containerId: "QuickViewDialog", source: options.source, url: options.url, label: options.label});
			},
			showCartMini: function(options) {
				app.createDialog({id: 'QuickViewDialog', options: {
			    	height: 500,
			    	width: 800,
			    	dialogClass: 'quickview',
			    	title: app.resources["SHOWCARTMINI_MESSAGE"],
			    	resizable: false
				}});

			    jQuery('#QuickViewDialog').dialog('open');
			    app.getProduct({containerId: "QuickViewDialog", source: options.source, url: options.url, label: options.label});
			},
			showAVBox: function(options) {
				app.createDialog({id: 'QuickViewDialog', options: {
			    	height: 250,
			    	width: 646,
			    	dialogClass: 'quickview',
			    	title: app.resources["SHOWAVBOX_MESSAGE"],
			    	resizable: false
				}});

			    jQuery('#QuickViewDialog').dialog('open');
			    app.getProduct({containerId: "QuickViewDialog", source: options.source, url: options.url, label: options.label});
			},
			// This is for the custom alert box to be used
			// in the entire page. Created by Mark Llena
			showAlert: function(options) {
				app.createDialog({id: 'QuickViewDialog', options: {
					buttons: { "Ok": function() { $(this).dialog("close"); } },
			    	height: (options.height==null ? 127 : options.height),
			    	width: (options.width==null ? 300 : options.width),
			    	dialogClass: 'addressHop',
			    	title: options.title,
			    	resizable: false
				}});

			    jQuery('#QuickViewDialog').dialog('open');
			    jQuery('#QuickViewDialog').addClass((options.cssClass==null ? "customAlert" : options.cssClass));
			    jQuery('#QuickViewDialog').html(options.message);
			    $(".addressHop .ui-dialog-buttonpane button:last").addClass("btnOk");
			},
			// close the quick view dialog
			close: function() {
				jQuery('#QuickViewDialog').dialog('close');
			}
		},

		// helper method to create a dialog with the given options
		// options - dialog box options along with id of the container
		createDialog: function(options) {
			jQuery('#'+options.id).dialog(jQuery.extend({}, app.dialogSettings, options.options));
		},

		// shows tooltip popup
		// options
		// id - id of the container
		// options - tooltip popup options
		tooltip: function(options) {
			if (options.id.charAt(0) !== '#') {
				options.id = "#"+options.id;
			}
			if (options.addclass != null) {
				if (options.addclass.charAt(0) !== ' ') options.addclass = " "+options.addclass;
				app.tooltipSettings.extraClass += options.addclass;
			}
			jQuery(options.id).tooltip(jQuery.extend({}, app.tooltipSettings, options.options));

			if (options.addclass != null) { //reset the app.tooltipSettings.extraClass value, if changed
				app.tooltipSettings.extraClass = app.tooltipSettings.extraClass.slice(0,app.tooltipSettings.extraClass.indexOf(options.addclass));
			}
		},

		// renders a progress indicator on the page; this function can be used
		// to indicate an ongoing progress to the user; the optional parameter "className"
		// can be used to attach an additional CSS class to the container
		showProgress : function(className) {
			var clazz = "loading";
			if (className) clazz += " " + className;
			return jQuery("<div class=\"" + clazz + "\"/>").append(jQuery("<img/>").attr("src", app.URLs.loadingSmallImg));
		},

		// validation plugin intialization
		validator: function() {
			// override default required field message
			jQuery.validator.messages.required = function($1, ele, $3) {
				return "";
			};
			
			/**
			 * Add phone validation method to jQuery validation plugin.
			 * Text fields must have 'phone' css class to be validated as phone
			 * phoneUS is copied from http://docs.jquery.com/Plugins/Validation/CustomMethods/phoneUS
			 */
			
			/*
			jQuery.validator.addMethod("phone", function(phone_number, element) {
				// find out the country code
				var data 	= jQuery(element).data("data");
				var country = (data && data.country && data.country != "") ? data.country : "US"; // default to US phone validation
				
				// preserve this instance
				var that = this;
				
				
				// country specific phone validation handlers
				var phoneCA,
					phoneUS = phoneCA = function() {
						phone_number = phone_number.replace(/\s+/g, "");
						
						return that.optional(element) || phone_number.length > 9 &&
						//phone_number.match(/^[2-9][0-9]{2}[\-]{1}[0-9]{3}[\-]{1}[0-9]{4}$/);
						phone_number.match(/^(2-9)?(\([0-9]\d{2}\)|[0-9]\d{2})-?[0-9]\d{2}-?\d{4}$/);
					}
				
				window["eval"]("var phoneHandler = (typeof phone" + country + " != 'undefined') ? phone"+country+": null;");
				
			    // call the country specific phone validation handler
				return (phoneHandler && typeof phoneHandler == "function" ? phoneHandler() : true);
			}, app.resources["INVALID_PHONE"]);
			 */
			// 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 dom element and append it to its immediate previous sibling
		 * as data attribute i.e. jQuery().data("data", hiddenStr)
		 * if the hidden data specifies json in the class then this routine would attempt to 
		 * convert the hidden data into json object before adding it as data attribute.
		 * after adding the data, the hidden span/element is removed from the DOM.
		 */
		hiddenData : function() {
			jQuery.each(jQuery(".hidden"), function() {
				var hiddenStr = jQuery(this).html();
				
				if (hiddenStr === "") {
					return;
				}
				
				// see if its a json string
				if (jQuery(this).hasClass("json")) {
					// try to parse it as a json
					try {
						hiddenStr = window["eval"]("(" + hiddenStr + ")");
					}
					catch(e) {}				
				}
				
				jQuery(this).prev().data("data", hiddenStr);
				
				jQuery(this).remove();
			});
		},
		
		/**
		 * Process country drop downs and attach a change listener so that phone field 
		 * can be validated properly based on the currently selected country.
		 */
		addCountryListener: function() {
			var countryHandler = function(e) {
				var selectedCountry = 0;
				// for each field of type phone in the current form, set its country as a data attribute
				// to be used while doing phone field validatiaon see app.validator addMethod.
				jQuery(this).parents("form:first").find("input.phone").each(function() {
					var data = jQuery(this).data("data");
					var currentData = (data && typeof data == 'object') ? data : {};
					currentData.country = selectedCountry;
					jQuery(this).data("data", currentData);
				});						
			}
			jQuery("select.country").change(countryHandler).each(countryHandler);
		},
		
		formvalidation:{
			init:function(errorcontainer,parentcontainer,submit,errormsg){
			this._error_container = (errorcontainer==null)? "":errorcontainer;
			this._parent_container =parentcontainer;
			this._submit = submit;
			this.errCont = jQuery("." + errorcontainer);
			this.errmsg = errormsg!=null? errormsg:'The following information was invalid: ';
			this.stopbinding = false;
	
			var errCont= this.errCont;
			
			if(this._error_container!="") jQuery("." + errorcontainer).css("display","none");
			
			var ctrl = jQuery("." + this._parent_container).find(".form-to-validate");
			var btn = (jQuery("#" + submit).length >0 ?jQuery("#" + submit) :jQuery("." + submit).length >0?jQuery("." + submit):null)
			var btnSubmit = jQuery("." + parentcontainer).find(":submit");
			

			
			//var form = jQuery("#" + submit).get(0).tagName;
			//click event
			
			
			
			
			
			if (btn!=null) {
				
				if(!btn.attr("errorcontainer")){					
					btn.attr("errorcontainer", this._error_container);
					btn.attr("parentcontainer", this._parent_container);
					btn.attr("errorcont", this.errCont);
					
				}

				btn.click(function(){
					//pass associated element, since we dont have new initialization switch approach implemented
					app.formvalidation.seterrorcontainer(jQuery(this).attr("errorcontainer"));
					app.formvalidation.setparentcontainer(jQuery(this).attr("parentcontainer"));
					app.formvalidation.seterrorcont(jQuery(this).attr("errorcont"));
					
					if(app.formvalidation.isbind()) return;
					var err = app.formvalidation.errorshow();
					
					if (err.length > 0) {						
						app.formvalidation.message.show(err)
						return false;						
					} else if(!app.formvalidation.isvalid()){
												
						app.formvalidation.message.show("Some field(s) are invalid!.");
						return false;
					}
				});
				
				this.submit = btn; 
			} else if (btnSubmit.length>0) {
				if(!btnSubmit.attr("errorcontainer")){					
					btnSubmit.attr("errorcontainer", this._error_container);
					btnSubmit.attr("parentcontainer", this._parent_container);
					btnSubmit.attr("errorcont", this.errCont);
					
				}
				
				btnSubmit.click(function(){
					//pass associated element, since we dont have new initialization switch approach implemented
					app.formvalidation.seterrorcontainer(jQuery(this).attr("errorcontainer"));
					app.formvalidation.setparentcontainer(jQuery(this).attr("parentcontainer"));
					app.formvalidation.seterrorcontainer(jQuery(this).attr("errorcont"));
					
					
					
					//alert(app.formvalidation.isbind());
					if(app.formvalidation.isbind()) return;
					
					var err = app.formvalidation.errorshow();								
					
					if(err.length > 0){
						app.formvalidation.message.show(err)
						return false;						
					} else if (!app.formvalidation.isvalid()){						
						app.formvalidation.message.show("Some field(s) are invalid!.");
						return false;
					}
				});
				
				this.submit = btnSubmit;
				
			}
			
			
			var elems = jQuery("." + parentcontainer).find(".form-to-validate");
			
			//add reference to button submit
			var sbmt = this.submit;
			
			jQuery.each(elems,function(i,e){
				jQuery(this).data("button_submit",sbmt);				
			})
			
			
			jQuery.each(ctrl,function(i,e){
				if (jQuery(ctrl).get(0).tagName!="SELECT") {
					jQuery(this).bind("blur keyup", function(){	
						if(app.formvalidation.isbind()) return true;
						
						app.formvalidation.errorshow({element:this});
					});
				} else {
					jQuery(this).bind("change", function(){	
						if(app.formvalidation.isbind()) return true;
						
						app.formvalidation.errorshow({element:this});
					});
				}
				
				jQuery(this).keypress(function(e){
					if(e.which==13 || e.keyCode==13){						
						var sub = jQuery(this).data("button_submit");
						
						
						app.formvalidation.seterrorcontainer(sub.attr("errorcontainer"));
						app.formvalidation.setparentcontainer(sub.attr("parentcontainer"));
						
						
						if(app.formvalidation.isbind()) return true;
						
						var err = app.formvalidation.errorshow();							
						
						if (err.length>0) {								
							app.formvalidation.message.show(err)								
							return false;
						}
					}
				});
			});
		},
		
		errorshow: function(options){			
			var _default = {element:null,
							show:'auto',
							errormsg:"",
							inline:false
							}
			if (options) {
				jQuery.extend(_default, options);										
			}
			
			var errcontainer=null;
			
			if(this._error_container!="")errcontainer = jQuery("." + this._error_container); 
			
			var elem = jQuery(_default["element"]);
			var errmsg = this.errmsg;		
			
			if(_default["errormsg"]!=""){errmsg=_default["errormsg"]}
			
			var errelement="";
			
			if(!_default["inline"]){
				var ctrl;			
				

				if(_default["element"]){
					ctrl = jQuery(_default["element"]);
				}else{
					ctrl = jQuery("." + this._parent_container).find(".form-to-validate");
				}
												
				jQuery.each(ctrl,function(i,e){					
					//check error type
					//String validation
					switch(jQuery(this).attr("expression")) {
						case 'string':
							if (jQuery.trim(jQuery(this).val())=="") {
								errelement += ((errelement.length==0)? ' ': ', ') + jQuery(this).attr("error");
								jQuery(this).addClass("errormessageinputvalidator");
							} else {
								errelement = errelement.replace(/jQuery(this).attr("error")/g,"");
								jQuery(this).removeClass("errormessageinputvalidator");
							}
							
							break;
						case 'password':
							if (jQuery(this).val().length<6 ) {
								errelement += ((errelement.length==0)? ' ': ', ') + jQuery(this).attr("error");
								jQuery(this).addClass("errormessageinputvalidator");
							} else {
								errelement = errelement.replace(/jQuery(this).attr("error")/g,"");
								jQuery(this).removeClass("errormessageinputvalidator");
							}
							
							break;
						case 'email':						
							var email = jQuery(this).val();
							var filter = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
							
							if(!filter.test(email)){
								errelement += ((errelement.length==0)? ' ': ', ') + jQuery(this).attr("error");
								jQuery(this).addClass("errormessageinputvalidator");
							} else {
								errelement = errelement.replace(/jQuery(this).attr("error")/g,"");
								jQuery(this).removeClass("errormessageinputvalidator");
							}
							
							break;
						case 'phone':
							if(!app.formvalidation.validatephone(jQuery(this).val())){
								errelement += ((errelement.length==0)? ' ': ', ') + jQuery(this).attr("error");
								jQuery(this).addClass("errormessageinputvalidator");
							} else {
								errelement = errelement.replace(/jQuery(this).attr("error")/g,"");
								jQuery(this).removeClass("errormessageinputvalidator");
							}
							break;
						case 'number':
							if(!app.formvalidation.validatenumber(jQuery(this).val())){
								errelement += ((errelement.length==0)? ' ': ', ') + jQuery(this).attr("error");
								jQuery(this).addClass("errormessageinputvalidator");
							} else {
								errelement = errelement.replace(/jQuery(this).attr("error")/g,"");
								jQuery(this).removeClass("errormessageinputvalidator");
							}
							break;	
							
						case 'zip':
							if(!app.formvalidation.validatezip(jQuery(this).val())){
								errelement += ((errelement.length==0)? ' ': ', ') + jQuery(this).attr("error");
								jQuery(this).addClass("errormessageinputvalidator");
							} else {
								errelement = errelement.replace(/jQuery(this).attr("error")/g,"");
								jQuery(this).removeClass("errormessageinputvalidator");
							}
							break;							
						default:
							var expr = jQuery(this).attr("expression");
							
							if (expr.length>0) {
								expr =expr.replace(/@/g,"'");		
								var json = eval("[" + expr + "]");	
												
								if(json[0].compare!=undefined){
									if(json[0].compare.value1.val()!=json[0].compare.value2.val()){
										errelement += ((errelement.length==0)? ' ': ', ') + jQuery(this).attr("error");
										jQuery(this).addClass("errormessageinputvalidator");
										
									}
									
									if((json[0].compare.value1.val()==json[0].compare.value2.val()) && json[0].compare.value1.val().length>0){
										
										errelement = errelement.replace(/jQuery(this).attr("error")/g,"");
										jQuery(this).removeClass("errormessageinputvalidator");
										
										// check if type is correct
										if(json[0].compare.type!=undefined){
											switch(json[0].compare.type) {
												case 'string':
													if(!app.formvalidation.validatestring(json[0].compare.value2.val())){
														errelement += ((errelement.length==0)? ' ': ', ') + jQuery(this).attr("error");
														jQuery(this).addClass("errormessageinputvalidator");
													} else {
														errelement = errelement.replace(/jQuery(this).attr("error")/g,"");
														jQuery(this).removeClass("errormessageinputvalidator");
													}												
												break;
												case 'password':
													if(!app.formvalidation.validatepassword(json[0].compare.value2.val())){
														errelement += ((errelement.length==0)? ' ': ', ') + jQuery(this).attr("error");
														jQuery(this).addClass("errormessageinputvalidator");
													} else {
														errelement = errelement.replace(/jQuery(this).attr("error")/g,"");
														jQuery(this).removeClass("errormessageinputvalidator");
													}	
												break;
												case 'email':
													//alert('type' + json[0].compare.value2.val());
													if(!app.formvalidation.validateemail(json[0].compare.value2.val())){
														errelement += ((errelement.length==0)? ' ': ', ') + jQuery(this).attr("error");
														jQuery(this).addClass("errormessageinputvalidator");
													} else {
														errelement = errelement.replace(/jQuery(this).attr("error")/g,"");
														jQuery(this).removeClass("errormessageinputvalidator");
													}	
												break;
												case 'phone':
													if(!app.formvalidation.validatephone(json[0].compare.value2.val())){
														errelement += ((errelement.length==0)? ' ': ', ') + jQuery(this).attr("error");
														jQuery(this).addClass("errormessageinputvalidator");
													} else {
														errelement = errelement.replace(/jQuery(this).attr("error")/g,"");
														jQuery(this).removeClass("errormessageinputvalidator");
													}	
												break;
												case 'number':
													if(!app.formvalidation.validatenumber(json[0].compare.value2.val())){
														errelement += ((errelement.length==0)? ' ': ', ') + jQuery(this).attr("error");
														jQuery(this).addClass("errormessageinputvalidator");
													} else {
														errelement = errelement.replace(/jQuery(this).attr("error")/g,"");
														jQuery(this).removeClass("errormessageinputvalidator");
													}	
												break;
												case 'zip':
													if(!app.formvalidation.validatezip(json[0].compare.value2.val())){
														errelement += ((errelement.length==0)? ' ': ', ') + jQuery(this).attr("error");
														jQuery(this).addClass("errormessageinputvalidator");
													} else {
														errelement = errelement.replace(/jQuery(this).attr("error")/g,"");
														jQuery(this).removeClass("errormessageinputvalidator");
													}	
												break;											
												
											}	
										
										
									} 									
									}							
									
								}else{
									if(eval(expr)){
										errelement += ((errelement.length==0)? ' ': ', ') + jQuery(this).attr("error");
										jQuery(this).addClass("errormessageinputvalidator");
									} else {
										errelement = errelement.replace(/jQuery(this).attr("error")/g,"");
										jQuery(this).removeClass("errormessageinputvalidator");
									}
								}
							}
						}
				});
			} else {
				if(_default["errormsg"]!=""){
					errelement += ((errelement.length==0)? ' ': ' ');
					jQuery(_default["element"]).addClass("errormessageinputvalidator");
				} else {
					errelement = errelement.replace(/jQuery(this).attr("error")/g,"");
					jQuery(_default["element"]).removeClass("errormessageinputvalidator");
				}
			}
			
			var errorreturn="";
			
			if(errelement.length >0 &&  (_default["show"]=="true" || _default["show"]=="auto") ){
				//alert(errmsg + errelement);
				///errcontainer.fadeIn("slow");
				//errcontainer.html(errmsg + errelement);
				errorreturn = errmsg +  errelement;
			} else if (_default["inline"] && _default["errormsg"]!="") {
				if(errcontainer!=null){
					errcontainer.html(errmsg);
					errcontainer.fadeIn("slow");	
				}
				
				errorreturn = errmsg;
			} else {
				if(errcontainer!=null){
					//errcontainer.fadeOut("fast");
					errorreturn = "";	
				}
			}

			return errorreturn;
		},
		
		clear: function(){
			jQuery(".form-to-validate").removeClass("errormessageinputvalidator");
			jQuery("." + this._error_container).css("display","none");
		},
		
		isvalid:function(){			
			var erlen = jQuery("." + this._parent_container).find(".errormessageinputvalidator");
			var error = app.formvalidation.errorshow();	
			var errtext="";
			
			if(!error) errtext =error;	
			
			
			return (errtext=="" && erlen.length==0)? true:false;
			
			//return (jQuery("." + this._parent_container).find(".errormessage").length==0);
		},
		buttonsubmit:function(){
			return this.submit;			
		},
		seterrorcontainer:function(s){
			this._error_container = s;
		},
		setparentcontainer:function(s){
			this._parent_container = s;
		},
		seterrorcont:function(s){
			this.errCont = s;
		},
		message :{
			show:function(msg){
				if(app.formvalidation.errorcontainerID()!=""){
					var errCont = jQuery("." + app.formvalidation.errorcontainerID())
					if(!msg){
						var err = app.formvalidation.errorshow();
						if(errCont.length>0){
							errCont.fadeIn("slow");
							errCont.html(err);						
						}
					} else {
						if(errCont){
							errCont.fadeIn("slow");
							errCont.html(msg);								
						}	
					}			
				}
			},
			
			hide:function(){
				if(app.formvalidation.errorcontainerID()!=""){
					var errCont = jQuery("." + app.formvalidation.errorcontainerID())
					if(errCont.length>0)errCont.fadeOut("fast");	
				}
				
			}
			
		},
		errorcontainerID:function(){
			return this._error_container;			
		},
		parentcontainerID:function(){
			return this._parent_container;
		},
		validatephone:function(phone){
			var phonenum =  /^\(?(\d{3})\)?[- ]?(\d{3})[- ]?(\d{4})$/;
				return phonenum.test(phone);
		},
		validateemail:function(email){
			var email = email
			var filter = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
			return filter.test(email);
		},
		validatestring:function(str){
			return str!='';
		},
		validatepassword:function(pw){
			return (pw.length>5 && pw.length<21);
		},
		validatezip:function(zip){
			var filter = /^\d{5}(-\d{4})?$/;
			return filter.test(zip);
		},
		validatenumber:function(n){
			var num = /^[0-9]+$/;
			return num.test(n);
		},
		refreshvalidator:function(option){
			var _default = {showmsg:false}
			if (option) {
				jQuery.extend(_default, option);										
			}
			
			
			var err = app.formvalidation.errorshow();
			
			if (err.length > 0) {
				if(_default["showmsg"]){
					app.formvalidation.message.show(err)						
				}
				
				return false;						
			} else if(!app.formvalidation.isvalid()){
				if(_default["showmsg"]){
					app.formvalidation.message.show("Some field(s) are invalid!.");	
				}										
				return false;
			}
		},
		suspendbinding:function(){
			this.stopbinding=true;
		},
		isbind:function(){
			return this.stopbinding;
		},
		continuebinding:function(){
			this.stopbinding=false;
		}
		},		
		recommendation : {
			init :function(){
			var rec_itemClear =  function(){
				jQuery(".rec_page").css({"display":"none"});			
				} 

			var paging_itemClear = function(){
				jQuery(".rec_paging").css("display","none")	
			}
			
			jQuery.each(jQuery(".rec_page"),function(){
				var carousel= jQuery(this).find("ul");
				var paging = jQuery(this).find(".hdnPaging"); 

				var p = eval("[" + paging.val() + "]");
				var pagescroll = jQuery("." + p[0].pagescroll );

				if(parseInt(p[0].pCount)>1){
					pagescroll.find("li:first-child").addClass("selected");
					
				}else{
					pagescroll.find('#hlistpageright').addClass("unselectable");
					pagescroll.find('#hlistpageleft').addClass("unselectable");
				}

				//clear selected
				var clear_pagingSelect =  function(){
					jQuery.each(pagescroll.find("ul li"),function(){			
						jQuery(this).removeClass("selected");
					})
				}
				var itemload = function itemLoadCallbackFunction(carousel, state)
				{
				           // carousel.add(17, "I'm item #" + 17);
				}
				
					
				var f = function carousel_Callback(carousel){								 						 
						 var pMaxCount = parseInt(p[0].pCount);				 
						 var scroll = jQuery("." + p[0].pagescroll ).find("ul").find("li.pageIndex");

					 	
					 		scroll.bind("click" ,function(){
								var p = jQuery(this);
								
							
								if(parseInt(p.text())==pMaxCount){jQuery(this).parent().find("#hlistpageright").addClass("unselectable");}else{jQuery(this).parent().find("#hlistpageright").removeClass("unselectable")};
								if(parseInt(p.text())==1){jQuery(this).parent().find("#hlistpageleft").addClass("unselectable");}else{jQuery(this).parent().find("#hlistpageleft").removeClass("unselectable")};
								
								
								
								jQuery(clear_pagingSelect);
								
								
								
								p.addClass("selected");
		
								
								//move the carousel							
								
								
								if(parseInt(p.text())-1 <=1){									
									carousel.scroll((parseInt(p.text())-1) * 5);									
								}else{									
									carousel.scroll(((parseInt(p.text())-1) * 4) + 1);
								}
								
								
								//alert(ul.css("left"));
								
								//ul.animate({left:(parseInt(ul.css("left")) + (-172)) + "px"})								
								
								pagescroll.data("currIndex",p.text());
								
							
								
								app.shopNow.close();
								return false;

						})
						
					

						
						// left/right arrow button
						pagescroll.find('#hlistpageleft').bind('click', function() {
							if(jQuery(this).hasClass("unselectable")) return false;
							var selIndex = parseInt(pagescroll.data("currIndex"));
							
							if(selIndex > 1){
								selIndex-=1
								jQuery(clear_pagingSelect);
								var cur = pagescroll.find('#hlistpage' +  (selIndex))
								
								
								cur.addClass("selected");
								pagescroll.data("currIndex",(selIndex))

								if(selIndex==1){				
									jQuery(this).addClass("unselectable");
								} 
								pagescroll.find('#hlistpageright').removeClass("unselectable");		
							}
							
							if(parseInt(selIndex)-1 <=1){									
								carousel.scroll((parseInt(selIndex)-1) * 5);									
							}else{									
								carousel.scroll(((parseInt(selIndex)-1) * 4) + 1);
							}
							
							//carousel.prev();
							app.shopNow.close();
							return false;
						});

					 	pagescroll.find('#hlistpageright').bind('click', function(){
					 		if(jQuery(this).hasClass("unselectable")) return false;
					 		
					 		var selIndex = parseInt(pagescroll.data("currIndex"));
							
							
							if(selIndex < pMaxCount){
								selIndex+=1
								jQuery(clear_pagingSelect);
								var cur = pagescroll.find('#hlistpage' +  (selIndex))
								
								cur.addClass("selected");
								pagescroll.data("currIndex",(selIndex))

								if(selIndex==pMaxCount){				
									jQuery(this).addClass("unselectable");
								} 
								
								pagescroll.find('#hlistpageleft').removeClass("unselectable");		
							}
							
							if(parseInt(selIndex)-1 <=1){									
								carousel.scroll((parseInt(selIndex)-1) * 5);									
							}else{									
								carousel.scroll(((parseInt(selIndex)-1) * 4) + 1);
							}
							//carousel.next();
							app.shopNow.close();
							return false;
						});
				}
							 			
				//intialize the carousel
				carousel.jcarousel({
					visible: 4,
					vertical: false,
					buttonNextHTML:"",
					buttonPrevHTML:"",			
					initCallback: f,
					itemLoadCallback:itemload
				});
				
				//set default page index to 1
				pagescroll.data("currIndex",1);				
			});
			var dcount=0;
			jQuery.each(jQuery(".rec_paging"),function(i,e){
				if(jQuery(this).css("display")=="block"){
					dcount +=1;	
				}				
			})
			
			if(dcount==0){
				jQuery("#hitlist").css("display","none")
				
			}
			
			
		},
		itemClear : function(){
				jQuery(".rec_page").css({"display":"none"});										
			
		},
		pagingClear :function(){
				jQuery(".rec_paging").css("display","none")		
		}
		},
		
		/**
		 * Unobtrusive js api calls go here.
		 */
		 execUjs: function() {
			// process hidden data in the html markup and cnnvert it into data object(s)
			this.hiddenData();
			
			// initialize form validator plugin
			this.validator();
			
			// process country form fields and attach listeners
			this.addCountryListener();
		},
		
		// capture recommendation of each product when it becomes visible in the carousel
		captureCarouselRecommendations : function(c, li, index, state) {
			jQuery(li).find(".captureproductid").each(function() {
				dw.ac.capture({id:this.innerHTML, type:dw.ac.EV_PRD_RECOMMENDATION});
			});
		},

		// 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.quickviewbutton",
					imageSelector: "div.producttile div.image",
					buttonLinkSelector: "div.producttile div.quickviewbutton a"
				};
				
				app.quickView.bindEvents(quickViewOptions);
				

				// bind shop now button toggling and click
				var shopNowOptions = {
					buttonSelector: "div.producttile div.shopnowbutton",
					imageSelector: "div.producttile div.image",
					buttonLinkSelector: "div.producttile div.shopnowbutton a"
				};
				app.shopNow.bindEvents(shopNowOptions);
				
				
		
				
				
				// prepare swatch palettes and thumbnails
				jQuery("div.producttile div.swatches div.invisible").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.invisible").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(".quickviewbutton a");
				var imageAnchor = swatch.parents(".producttile").find(".productimage 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);
				imageAnchor.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;
					
				var selectedSwatch = jQuery(swatch.parents()[0]).find("a.selected");
				var selectedImg = selectedSwatch.children("img.hiddenthumbnail");

				// 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 
					var newCopy = selectedImg.clone().show().removeClass("original hiddenthumbnail"); 
					currentImg.replaceWith(newCopy[0]); 
				} else { 
					// we create a copy of the swatch image, replace 
					// the current and mark it with classes 
					var newCopy = newImg.clone().show().addClass("temp").removeClass("hiddenthumbnail"); 
					currentImg.replaceWith(newCopy[0]); 
				}
				

				/*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 : {
			// disables browser auto completion for the given element
			disableAutoComplete : function(elemId) {
				jQuery("#"+elemId).attr("autocomplete", "off");
			},

			// trims a prefix from a given string, this can be used to trim
			// a certain prefix from DOM element IDs for further processing on the ID
			trimPrefix : function(str, prefix) {
				return str.substring(prefix.length);
			},

			// appends the parameter with the given name and
			// value to the given url and returns the changed url
			appendParamToURL : function(url, name, value) {
				var c = "?";
				if(url.indexOf(c) != -1) {
					c = "&";
				}
				return url + c + name + "=" + encodeURIComponent(value);
			},

			// 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;
			}
		},

		// 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);
					}
				});
			},

			// opens a dialog using the given url
			openDialog : 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.initialize(290, 450);
						app.dialog.setTitle(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
			initialize : function(height, width) {
				if(!jQuery("#dialogcontainer").dialog("isOpen"))
				{
					jQuery("#dialogcontainer").dialog({
						bgiframe: true,
						autoOpen: false,
						modal: true,
						overlay: {
				    		opacity: 0.5,
				     		background: "black"
						},
				    	height: height,
				    	width: width,
				    	resizable: false
					});
					jQuery("#dialogcontainer").dialog("open");
				}
			},
			
			// 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({
						bgiframe: true,
						autoOpen: false,
						modal: true,
						overlay: {
				    		opacity: 0.5,
				     		background: "black"
						},
				    	height: 550,
				    	width: 650,
				    	resizable: false
					});
					jQuery("#dialogcontainer").dialog("open");
				}
			},

			// closes the dialog and triggers the "close" event for the dialog
			close : function() {
				jQuery("#dialogcontainer").dialog("close");
				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(app.resources["SERVER_ERROR"]);
				   }
				});
			}
		},
		
		leftnav : {
			active : function(activeMenuLink) {
				//expects activeMenuLink: a string value of the class or id of the <li> to set as the "active" menu option in the left nav. ex: '#homecard'
				//if none, it will determin if the <a> href value is equal to the current document's url
			
				if (activeMenuLink != null) {
				
					//select active menu option based on class or id string
					jQuery(".leftnav > ul > "+activeMenuLink+" a").addClass("selected");
		
					//deselect on hover			
					jQuery(".leftnav > ul > li > a").mouseover(function(){jQuery(".leftnav > ul > li > a.selected").removeClass("selected");});
		
					//reselect on mouseleave
					jQuery(".leftnav").mouseleave(function(){jQuery(".leftnav > ul > "+activeMenuLink+" a").addClass("selected");});
				}
				else {

					//select active menu option based on page url
					var pageurl = jQuery(location).attr('href');
					
					//alert(pageurl);
					//alert(jQuery(".leftnav > ul > li > a").attr('href'));
					
					jQuery(".leftnav > ul > li > a").each(function(){
						if (jQuery(this).attr('href') == pageurl) jQuery(this).addClass("selected");
					});
		
					//deselect on hover			
					jQuery(".leftnav > ul > li > a").mouseover(function(){jQuery(".leftnav > ul > li > a.selected").removeClass("selected");});
		
					//reselect on mouseleave
					jQuery(".leftnav").mouseleave(function(){
						jQuery(".leftnav > ul > li > a").each(function(){
							if (jQuery(this).attr('href') == pageurl) jQuery(this).addClass("selected");
						});
					});
				}
			}
		},
		
		sbxtabs : function() {
			//run this function after page load to stylize tabs in content assets, works in conjuction with .sbxtab style in default.css
			jQuery('.sbxtab').corner("top 3px");
			jQuery('.sbxtab').addClass("rounded top"); //in case page has not finished loading when this function runs
			jQuery(".sbxtab > ul > li").each(function(){
				jQuery(this).prepend('<div class="roundednavtop">&nbsp;</div>');
				jQuery(this).append('<div class="roundednavbottom">&nbsp;</div>');
			});

			
			
			// building the scroller
			var li = jQuery(".sbxtab > ul > li")
			var width=0;			
			jQuery.each(li, function(){
				width +=jQuery(this).outerWidth();
			});
			
			
			var ul = jQuery(".sbxtab ul");
			
			if(width > jQuery(".sbxtab").outerWidth()){
				ul.css("width",(width + 30) + "px");
				ul.wrap("<div class='sbx-clip' />");
				var clip = jQuery(".sbx-clip");
				
				clip.before("<div class='btnPrev'>&nbsp;</div>");
				clip.after("<div class='btnNext'>&nbsp;</div>");
				
				var side = jQuery(".btnPrev").outerWidth() + jQuery(".btnNext").outerWidth();
				clip.css("width",jQuery(".sbxtab").outerWidth() - (side + 2));
				
				jQuery('.sbxtab').wrapAll("<div class='sbx-tab-wrapper' />");
				
				jQuery(".btnPrev").addClass("btnPrevOff");
			}
		
			var lw = jQuery(".sbxtab").find("ul").find("li:first-child").outerWidth();
			
			jQuery(".sbxtab").find("ul").data("animatecomplete",true);
			
			jQuery(".sbx-tab-wrapper").data("scroll",{
											left:0,
											prevLI:jQuery(".sbxtab").find("ul").find("li:first-child"),
											currentLI:jQuery(".sbxtab").find("ul").find("li:first-child")})
											
			
											
			jQuery(".btnNext").click(function(){
				var _ul= jQuery(".sbxtab ul");
				if(!_ul.data("animatecomplete"))return false;
				
				var d = jQuery(".sbx-tab-wrapper").data("scroll");
				var curLI = d.currentLI;				
				var left = (d.left==0)? 0:d.left;

				//alert("text:" +curLI.next().find("span").text() +  " CurLI:" + curLI.outerWidth()  + "  d.leftNext:" + curLI.next().outerWidth());
											
				if(jQuery(".sbxtab").find("ul").find("li:last-child").prev().attr("id")==curLI.attr("id")){					
					jQuery(this).addClass("btnNextOff");
					jQuery(".btnPrev").removeClass("btnPrevOff");
				}
				
				
				
				if(jQuery(curLI).next().length==0){return false;}

				_ul.data("animatecomplete",false);
				if(left==0){					
					left=curLI.outerWidth() * -1;					
				}else{
					left = ((Math.abs(left) + curLI.outerWidth() ) * -1);					
				}
				_ul.stop(true,true).animate({"left":(left) + "px"},"200",function(){					
					jQuery(".sbx-tab-wrapper").data("scroll",{
						left: left,
						prevLI:curLI,
						currentLI:jQuery(curLI).next()				
					})
					_ul.data("animatecomplete",true);
					if(jQuery(this).hasClass("btnNextOff"))jQuery(this).removeClass("btnNextOff");
					if(jQuery(".btnPrev").hasClass("btnPrevOff"))jQuery(".btnPrev").removeClass("btnPrevOff");
				});						
				
				
			})
			
			
			jQuery(".btnPrev").click(function(){
				var _ul= jQuery(".sbxtab ul");
				if(!_ul.data("animatecomplete"))return false;
				
				var d = jQuery(".sbx-tab-wrapper").data("scroll");
				var curLI = d.prevLI;
				
				
				if(jQuery(".sbxtab").find("ul").find("li:first-child").attr("id")==curLI.attr("id")){					
					jQuery(this).addClass("btnPrevOff");
					jQuery(".btnNext").removeClass("btnNextOff");
				}
				
				if(jQuery(d.currentLI).prev().length==0){
					_ul.css("left","0px");					
					return false
				};
				
				var p = jQuery(d.prevLI).outerWidth() + parseInt(ul.css("left")); 
				
				
				_ul.data("animatecomplete",false);
				_ul.stop(true,true).animate({"left":p + "px"},"200",function(){
					jQuery(".sbx-tab-wrapper").data("scroll",{
						left: p,
						prevLI:jQuery(curLI).prev(),
						currentLI:jQuery(d.prevLI)					
					})									
					_ul.data("animatecomplete",true);
					if(jQuery(this).hasClass("btnPrevOff"))jQuery(this).removeClass("btnPrevOff");
					if(jQuery(".btnNext").hasClass("btnNextOff"))jQuery(".btnNext").removeClass("btnNextOff");
				});							
				
				
			})
			
			
			jQuery(".sbxtab").after('<div class="clear"></div>');
			
			
			
			
			//determine if there is an "activetab", if not, set first tab to "activetab"
			if (jQuery(".sbxtab").find("li.activetab").length != 1) {
				jQuery(".sbxtab").find("li.activetab").removeClass("activetab");
				jQuery(".sbxtab").find("ul").find("li:first-child").addClass("activetab");
			}
			
			
			//hide all tab content, unless associated tab is "activetab"
			jQuery(".sbxtab").find("ul").find("li").each(function(){				
				var eachtabid = jQuery(this).attr("id").replace("-tab", "");
				
				if (jQuery(this).hasClass("activetab")) jQuery("#"+eachtabid).show();
				else jQuery("#"+eachtabid).hide();
			});
			
		
				
			//alert(jQuery(".sbxtab").outerWidth() + '  w:' + width);
							
			jQuery(".sbxtab").find("ul").find("li").click(function(){
				if (jQuery(this).hasClass("activetab")) {
					return false;
				}

				//hide other tabs
				jQuery(".sbxtab").find("ul").find("li").each(function(){
					jQuery(this).removeClass("activetab");
					var eachtabid = jQuery(this).attr("id").replace("-tab", "");
					jQuery("#"+eachtabid).hide();
				});
				
				//show this tab
				jQuery(this).addClass("activetab");
				var tabid = jQuery(this).attr("id").replace("-tab", "");
				jQuery("#"+tabid).show();

				return false;
			});
		},
		
		videohopup : function (vfile){
			//vfile: the full path of the video file to play
			
			//first, set the cursor to indicate progress/working
			jQuery('body').css('cursor', 'progress');
			
			var vf = vfile;
			
			function playvideo() {
				jwplayer('videoplayer').setup({
				    'flashplayer': app.URLs.flashplayer,
				    'file': vf,
				    'controlbar': 'bottom',
				    'width': '600',
				    'height': '362',
				    'autostart': 'true',
				    'stretching': 'fill',
				    'events': {
						'onReady': function(event) {
						  	jQuery('body').css('cursor', 'default');
						}
					 }
				});
			}
		
			if (!jQuery("#dialogcontainer #videoplayer")[0]) {
				jQuery("<div/>").attr("id", "dialogcontainer").css({ display: 'none', 'padding-top': '1%', 'padding-left': '3%'}).html("<div id='videoplayer'>Loading...</div>").appendTo(document.body);
			}
			jQuery('#dialogcontainer').dialog({
				bgiframe: true,
				autoOpen: false,
				open : function() {			
					jQuery(document).trigger('dialogopen');
				},
				modal: true,
				width: 640,
				height: 410,
				title: '',
				resizable: false
			});
			jQuery('#dialogcontainer').dialog('open');	
			playvideo();
		}
	}
})(jQuery);

// application initialization on dom ready
jQuery(document).ready(function(){
	app.init();
});

