/**
 * sjq = shop jQuery
 */
var sjq = jQuery.noConflict();


/**
 * Intiliase all global objects
 */
sjq(document).ready(function () {
	LEGO.shopNav.init();
	LEGO.miniBag.init();
	LEGO.wishlist.init();
	LEGO.header.init();
	LEGO.footer.init();
	LEGO.styling.init();
	LEGO.storeSearch.init();
	sjq("#store-locator-widget input[type='text']").bottomBannerInputPrompt();
	sjq("#subscribe-widget input[type='text']").bottomBannerInputPrompt();
	sjq(".btn-big,.btn-medium,.btn-small,.btnHelpTip,.btnHelpTipBottom").buttonFocus();
	sjq("html").addClass("test-page-loaded");
	sjq("#pageOverlay").remove();

	LEGO.globalFunctionsComplete = true;
});

if (!window.console)  {
	/**
	 * A catch all to stop developers leaving firebug console method references
	 * laying about
	 */
	window.console =  {
		log: function(o){
			LEGO.debug.showDebug(this.message("log"), o);
		},
		debug: function(o){
			LEGO.debug.showDebug(this.message("debug"), o);
		},
		info: function(o){
			LEGO.debug.showDebug(this.message("info"), o);
		},
		error: function(o){
			LEGO.debug.showDebug(this.message("error"), o);
		},
		message: function(type){return "And please remove the console." + type + "() call !!"}
	}
}

LEGO.debug = LEGO.debug ? LEGO.debug : {
	/**
	 * Description: Creates a debug output in the right hand corner of the page,
	 * a poor mans console which works in Windows and is lighter than Firebug
	 * lite Usage: LEGO.dubug.showDebug("Description", object):
	 */
	enabled: false,
	showDebug : function (func, args) {
		if(this.enabled) {
			sjq("#debug-panel").remove();
			var html = sjq('<div style="position:fixed; right:0; top:0; background: #cccccc;padding:15px; text-align:left;" id="debug-panel"></div>');
			var dl = sjq("<dl></dl>");
			for (property in args) {
				dl.append("<dt>"+ property + "</dt><dd>" + args[property] + "</dd>");
			}
			html.append("<h5>Function: "+func+"</h5>Arguments:<br />");
			html.append(dl);
			
			sjq("body").append(html);
		}
	}
}

LEGO.styling = LEGO.styling ? LEGO.styling : {
	
	init: function(){
		// FIXME: Most of these aren't global !!!
		var globalCorneredElements = [
			"#vip-small-widget",
			".medium-widget",
			"#change-shipping-country",
			".list-item",
			"#online-shop-widget",
			"#store-finder-widget",
			"#store-locator-widget",
			"#subscribe-widget",
			"#social-media-widget",
			"#todays-specials", 
			"#popular-themes", 
		     "#top-sellers", 
			"#recommended-products", 
			"#recently-viewed",
			"#orderhistory-recentorders", 
			"#orderhistory-ordernumberdetails", 
			"#orderhistory-ordercontents", 
			"#orderhistory-relatedorderactiviy", 
			"#orderhistory-allorders", 
			"#orderhistory-checkstatus",
			"#gift-cards-content",
			"#gift-cards-nav",
			"#shop-from-catalog", 
			"#view-catalogs", 
			"#request-catalog",
			".wish-list-empty", 
			"#email-wishlist-form", 
			"#wishlist-review-email-container", 
			"#wishlist-review-email-container #checkout-steps", 
			"#order-not-complete-until", 
			"#column-1 #order-review-section"
		];
		this.roundedCorners.applyCornersToElements(globalCorneredElements);				

		
		// initialises all product thumbnails
		sjq('.product-thumbnail').productThumbnail();
	},
	
	nodes: '<span class="top-left"></span><span class="top"></span><span class="top-right"></span><span class="right"></span><span class="left"></span><span class="bottom-left"></span><span class="bottom"></span><span class="bottom-right"></span>',
	
	roundedCorners: {
		
		cssClassName: "box-cornered",
		applyCornersToElements: function(elementArray){
			for(el in elementArray){
				this.applyCornersToElement(elementArray[el]);
			}	
		},
		applyCornersToElement: function(element){
			sjq(element).append(LEGO.styling.nodes).addClass(this.cssClassName);
		}
	}
}

LEGO.phoneNumberPattern = /[\s-/(/)]/g;
LEGO.forms = LEGO.forms ? LEGO.forms : {
	countryInputFormats: [{code:'US',mob:'(999) 999-9999',home:'(999) 999-9999'}],
	applyPhoneFormatMasking: function(){
		if(typeof sjq.mask == 'object') {
			var formats = this.countryInputFormats;
			// Use override (arguments[0].country) or page LEGO.currentLocale as a fall back:
			var currentCountry = (arguments.length && arguments[0].country != undefined && arguments[0].country.length) ? arguments[0].country : LEGO.currentLocale;
			for(country in formats){
				if(currentCountry.indexOf(formats[country].code) > -1){
					window.setTimeout(function(){
					sjq("input.mobile-format").mask(formats[country].mob);
					sjq("input.home-format").mask(formats[country].home);
					
					sjq("input.mobile-format, input.home-format").blur(function(event){
						var input = sjq(event.currentTarget);
						input.val(LEGO.forms.revertPhoneMasking( input.val() ));
					});
						},
						2000
					);
				} else {
					sjq("input.mobile-format, input.home-format").trigger("unmask");
				}
			}
		} else {
			throw new Error("jquery mask plugin isn't loaded, check jquery.masked-input-X.min.js is imported");
		}
	},
	revertPhoneMasking: function(input) {
		var str = new String(input); 
		return str.replace(LEGO.phoneNumberPattern,"");
	}
}

LEGO.popups = LEGO.popups ? LEGO.popups : {
	setup: function(){
		jQuery('#closeButton').bind('click', this.close);
	},
	close: function(){
		window.opener.focus(); 
		setTimeout(function(){window.close();self.close()},300)
	},
	open: function(url, type){
		window.open(url,type.name,"status="+type.status+",width="+type.width+",height="+type.height+",scrollbars="+type.scrollbars+",left="+type.left+",top="+type.top);
	}
}

LEGO.shopNav = LEGO.shopNav ? LEGO.shopNav : {
	childNavs: [],
	hoverDelay: 300,
	loadingHTML: sjq('<div id="shopnav-loading"><span class="top"></span><span class="right"></span><span class="left"></span></span><span class="bottom"></span></div>'),
	init: function(){
		this.bindMouseOverLoading();
		
		//add hover arrows for nav menus
		sjq("#shop-navigation-bar li.nav-link-default a:first-child").append('<span class="nav-arrow"></span>');
		
		//ie7 doesnt support 'display:table-cell' so space nav elements with js
		if(sjq('html').is('.ie7')){
			this.adjustResizableNavElements();
		}
	},
	bindMouseOverLoading: function(){
		var timeout;
		sjq.each(sjq("#shop-navigation-bar li"), function(index,element){

			//minibag manages itself
			if (element.id == 'shopnav-minibag') { return; }
			
			sjq(element).hover(
				function(event){
					handleHover(event,this);
				},
				function(event){
					handleHoverOut();
				}
			);

		});

		function handleHoverOut(){
			clearTimeout(timeout);
			sjq("#shop-navigation-bar > li > div").hide();
			sjq(".hover").removeClass("hover");
		}
						
		function handleHover(event,element) {

			event.stopImmediatePropagation();
			timeout = window.setTimeout(function(){
				//IE7-8 fix: add hover class directly for correct styling with pie.htc
				sjq(element).add('a:first-child', element)
					.addClass('hover');
						
				if(typeof LEGO.shopNav.childNavs[element.id] === 'undefined'){

					for(index in LEGO.categoryIdMaps){
						if (LEGO.categoryIdMaps[index].pageId == element.id){
							
							if (element.id == 'shopnav-minibag' && !LEGO.showCheckoutLink) {
								return;
							}

							sjq(element).append(LEGO.shopNav.loadingHTML);
							var templateUrl = LEGO.categoryIdMaps[index].template;

							sjq.ajax({
								url: templateUrl,
								cache: false,
								success: function(data){
								
										sjq("#shopnav-loading").remove();
										LEGO.shopNav.childNavs[element.id] = sjq(data);
										//cache for later
										sjq(element).append(LEGO.shopNav.childNavs[element.id]);										
									
									// initialise any new product thumbnails
									var productThumbs = sjq('.product-thumbnail',element);
									if(productThumbs.length > 0){
										productThumbs.productThumbnail();
										sjq('.add-to-cart', productThumbs).click(function(){
											handleHoverOut();
										});
									}
									
								},
								error: function(jqXHR, textStatus, errorThrown){

									sjq("#shopnav-loading").remove();
									throw new Error ("Error loading shop navigation:\njqXHR: " + jqXHR + "\ntextStatus: " + textStatus + "\nerrorThrown: " + errorThrown );
									
								},
								dataType: "html"
							});
							
						}
					}

				} else {
					if(!sjq(LEGO.shopNav.childNavs[event.currentTarget.id]).is(":visible")) {
						sjq(LEGO.shopNav.childNavs[event.currentTarget.id]).show();
					}
				}
			
			}, LEGO.shopNav.hoverDelay);
		}
		
	},
	adjustResizableNavElements:function(){
		//minibar nav is fixed width, all other are resizable
		var resizableLis = sjq('ul#shop-navigation-bar > li:not(#shopnav-minibag)');
		var currentResizablesWidth = 0;
		var targetResizablesWidth = sjq('ul#shop-navigation-bar').width() - sjq('li#shopnav-minibag').width();
		resizableLis.each(function(i, elem){
			currentResizablesWidth += sjq(elem).width();
		});
		var resizeRatio = targetResizablesWidth / currentResizablesWidth;
		resizableLis.each(function(i, elem){
			currentResizablesWidth += sjq(elem).width();
			sjq(elem).width( sjq(elem).width()*resizeRatio );
		});	
	}
}


LEGO.miniBag = {
	enabled: true,
	addToCartSelectors: "#addToCart",
	recentlyAddedTimeout:4000,
	recentlyAddedTimer:null,
	isHovering: false,
	isRecentlyAdded:false,
	closeTimeout: 4000,
	closeTimer:null,
	navBtn:sjq('#shopnav-minibag'),
	
	init: function(){
		var self = this;
		//minibag nav button hover events
		//special case in the nav bar
		self.navBtn.hover(
			function(event){
				if(self.enabled) {
					// filter out extra hover events that can occur when inserting
					// content
					if(self.isHovering){
						self.clearCloseTimer();
						return;
					}
					self.isHovering = true;
					self.showMiniBag();
				}
			},
			function(event){
				if(self.enabled) {
					self.isHovering = false;
					self.isRecentlyAdded = false;
					self.hideMiniBag();
				}
			}
		);
		
		sjq(this.addToCartSelectors).bind("click", function(event){
			event.preventDefault();
			self.addToCart(event.currentTarget);
		});
		
		//need to make minibag is always visible
		sjq(window).scroll(function(event, b, c){
			self.updateFloating();
		});
		self.updateFloating();
	},
	
	showLoadingSpinner:function(){
		this.hideMiniBag();//hide any existing popups
		this.navBtn.append(LEGO.shopNav.loadingHTML);
		this.updateFloating();
	},
	
	showMiniBag: function(forceReload, minibagHtml){
		var self = this;
		
		//if panel is already shown dont reload (unless we're being forced to reload)
		if(sjq('#mini-bag:visible, #just-added:visible').length > 0 && !forceReload){
			return;
		}
		
		self.navBtn.addClass('hover');

		if(minibagHtml){
			self.navBtn.html(minibagHtml);
			self.showAppropriatePanel();
		}else if(sjq('#mini-bag').length == 0 || self.isRecentlyAdded){
			self.navBtn.append(LEGO.shopNav.loadingHTML);	
			self.loadMiniBag();
		}else{	
			self.showAppropriatePanel();
		}
		
	},
	
	addToCart: function(submitBtn, options) {
		var self = this;
		var form = sjq(submitBtn).parents("form[name='addToCartForm']")//sjq("form[name='addToCartForm']");
		var miniBagURL = LEGO.miniBagURL+"?currentPageURL="+LEGO.currentPageURL;
		options = options || {};
		sjq(".addToCartSuccess", form).val(miniBagURL);
		sjq(".addToCartError", form).val(miniBagURL);
				
		self.showLoadingSpinner();
		sjq.ajax({
			url: sjq(form).attr("action"),
			type : 'post',
			data: sjq(form).serialize(),
			cache: false,
			success:function(minibagHtml){
				self.cartItemAdded(minibagHtml);
				if(options.callback) {
					options.callback();
				}
			},
			error: function(jqXHR, textStatus, errorThrown){
				throw new Error ("Error loading minibag:\njqXHR: " + jqXHR + "\ntextStatus: " + textStatus + "\nerrorThrown: " + errorThrown );
			},
			dataType: "html"
		});
	},
	
	showAppropriatePanel: function(){		
		if(this.isRecentlyAdded){
			sjq('#just-added').show();
			sjq('#mini-bag').hide();
			this.beginHide();				
		}else{
			sjq('#mini-bag').show();
			sjq('#just-added').remove();
		}
		this.updateFloating();
	},
	
	//fetches latest minibag from server
	loadMiniBag:function(){
		var self = this;			
		var templateUrl = LEGO.categoryIdMaps[LEGO.categoryIdMaps.length-1].template + '?justAdded=true';
				
		sjq.ajax({
			url: templateUrl,
			success: function(panelHTML){
				self.navBtn.html(panelHTML);
				self.showAppropriatePanel();
			},
			cache: false,
			error: function(jqXHR, textStatus, errorThrown){
				sjq("#shopnav-loading").remove();
				throw new Error ("loading shop navigation:\njqXHR: " + jqXHR + "\ntextStatus: " + textStatus + "\nerrorThrown: " + errorThrown );
			},
			dataType: "html"
		});	
	},
	
	//sets the minibag to 'float' (remain at top of viewport no matter where user scrolls too)
	updateFloating:function(){
		var floatThreshold = 220;
		var isFloater = sjq(window).scrollTop() > floatThreshold;
		sjq('.minibag-modal, #shopnav-loading').toggleClass('floater', isFloater);
	},
	
	fireAnalyticsCartEvents: function() {
		if (LEGO.analyticsEnabled) {
			sjq.ajax({
				url: "/json/analyticsProductGeneratorJSON.jsp",
				success: function(data){
					if (data["isCartCreated"]) {
						LEGOSiteStats.ShopProductCreateNewCart(data["productCodes"],LEGO.selectedCountry);
					}
					if (data["addedItems"] != "") {
						LEGOSiteStats.ShopProductAddToCart(data["productCodes"],LEGO.selectedCountry);
					}
				},
				error: function(jqXHR, textStatus, errorThrown){
					throw new Error ("Error getting JSON data:\njqXHR: " + jqXHR + "\ntextStatus: " + textStatus + "\nerrorThrown: " + errorThrown );
				},
				dataType: "json"
			});
		}
	},
	
	hideMiniBag:function(){
		sjq("#mini-bag").hide();
		sjq("#just-added").remove();
		this.navBtn.removeClass('hover');
		this.clearCloseTimer();
	},
	
	//starts a timer to close the dialog - this may get cancelled though
	beginHide: function(){
		var self = this;
		
		//clear-up any existing timer
		self.clearCloseTimer();
		
		self.closeTimer = setTimeout(function(){
			if(!self.isHovering){
				self.hideMiniBag();
			}else{
				//user is still hovering so clear timers for now
				self.clearCloseTimer();
			}
		}, self.closeTimeout);
	},
	
	clearCloseTimer:function(){
		clearTimeout(this.closeTimer);
		this.closeTimer = null;
	},
	
	//tracks the recent adding of items - see isRecentlyAdded
	cartItemAdded: function(minibagHtml){
		var self = this;
		
		self.isRecentlyAdded = true;
		
		//if recent add timer exists, reset it
		if(self.recentlyAddedTimer){
			clearTimeout(self.recentlyAddedTimer);
			self.recentlyAddedTimer = undefined;
		}
		
		//reset isRecentlyAdded a set period after no more items are added
		self.recentlyAddedTimer = setTimeout(function(){
			self.isRecentlyAdded = false;
			self.recentlyAddedTimer = undefined;
		}, self.recentlyAddedTimeout);
		
		this.showMiniBag(true, minibagHtml);
		self.fireAnalyticsCartEvents();
	}
}


LEGO.header = LEGO.header ? LEGO.header : {
	init: function(){
		sjq("#country-selector-link a, #shopping-bag-change-shipping-destination a").bind("click", this.openCountrySelectorModal);
	},
	openCountrySelectorModal: function(event) {
		event.preventDefault();
		sjq.ajax({
			url: event.currentTarget.href,
			cache: false,
			success: function(data){
				//TODO: use openModal method with predefined size
				LEGO.modal.openModal(null, {overflow: 'scroll', source:data, width:900, height:570});
				// IE<9 doesnt natively support :last-child so add a helper
				// class
				sjq('#country-selector > ul > li:last-child').addClass('lastchild');
			},
			error: function(jqXHR, textStatus, errorThrown){
				throw new Error ("Could not open modal country selector:\njqXHR: " + jqXHR + "\ntextStatus: " + textStatus + "\nerrorThrown: " + errorThrown );
			},
			dataType: "html"
		});
	}
}


LEGO.footer = LEGO.footer || {

	init: function(){
		var self = this;
	
		//email subscribe form handler
		sjq('#subscribeEmails button[type="submit"]').click(function(event){
			event.preventDefault();
			self.submitEmailSubscribeForm(sjq(this));
		}),
		sjq('#lego-cookie-info').click(function(event){ //open cookie link in a modal
			event.preventDefault();
			LEGO.modal.openModal(event, {name: LEGO.modal.cookieInfo, href: event.target.href, scroll:true});
		})
		
	},
	
	//
	submitEmailSubscribeForm: function(submitBtn){
		var self = this; 
		var form = submitBtn.parents("form[name='subscribeEmails']");
		
		sjq.ajax({
			url: sjq(form).attr("action"),
			type : 'post',
			data: sjq(form).serialize(),
			
			success:function(response){
				
				sjq('#subscribe-widget .form-error').remove();
				
				if(response.emailSubscriptionSuccess){
					self.updateEmailSubscribeUI();
				}else{
					//LEGO.ajax.displayValidationErrors(response.data.fieldErrors);	
					//display errors to user
					var errors = response.data.fieldErrors;
					if(errors.email){
						self.appendErrorMsg(sjq('#subscribe-widget .email').parent(), errors.email, 'test-Erroremail');
					}
					if(errors.birthDate){
						self.appendErrorMsg(sjq('#subscribe-widget .dateOfBirth-day'), errors.email, 'test-ErrorbirthDate');
					}
				}
			},
			error: function(jqXHR, textStatus, errorThrown){
				throw new Error ("Error loading minibag:\njqXHR: " + jqXHR + "\ntextStatus: " + textStatus + "\nerrorThrown: " + errorThrown );
			},
			dataType: "json"
		});
	},
	
	appendErrorMsg:function(target, msg, testClass){
		testClass = testClass || ''; //default
		var html = '<span class="form-error ' + testClass + '">' + msg + '</span>';
		target.before(html);
	},
	
	//fetches ui html fragment for the email subscribe panel
	updateEmailSubscribeUI: function(){
		sjq.get('/banners/fragments/subscribeEmails.jsp')
		.success(function(html){
			sjq('#subscribe-widget').replaceWith(html);
			LEGO.styling.roundedCorners.applyCornersToElement('#subscribe-widget');
		});
	}	
}


LEGO.util = LEGO.util ? LEGO.util : {
	endsWith: function (str, suffix) {
	    return str.indexOf(suffix, str.length - suffix.length) !== -1;
	},
	getUrlParameters: function() {
		var map = {};
		var parts = window.location.href.replace(/[?&]+([^=&]+)=([^&]*)/gi, function(m,key,value) {
			map[key] = value;
		});
		return map; 
	},
	getURLParameter : function(name) {   
		if (!name) return null;  
		var match = (new RegExp('[?&]' + name + '=([^&#]+)')).exec(window.location.search);  
		return match ? decodeURIComponent(match[1]) : null;          
	}
}

LEGO.ajax = LEGO.ajax ? LEGO.ajax : {
	/**
	 * Auto submits the form on dropdown selection change (or any other elem
	 * that supports change events)
	 * 
	 * updateSources - jquery selector for 1 or more update event firing inputs
	 * e.g. "#myselectbox, #otherinput" submitTarget - the target submit button
	 * to fire when change occurs
	 */
	bindAutoSubmit: function(updateSources, submitTarget){
		sjq(updateSources).live('change', function(){
			sjq(submitTarget).click();
		});
		sjq(updateSources).css("visibility", "visible");
	},
	ajaxForm : function(form, successCallback, errorCallback) {
		var call = {
				url: LEGO.ajax.stripAnchors(sjq(form).attr("action")),
				type: "post",
		        contentType: "application/x-www-form-urlencoded; charset=UTF-8",
				data: sjq(form).serialize(),
				cache: false,
				success: function(result){
					successCallback(result);
				},
				error: function(jqXHR, textStatus, errorThrown){
					if (errorCallback) {
						errorCallback(jqXHR, textStatus, errorThrown);
					} else {
						throw new Error ("Error loading:\njqXHR: " + jqXHR + "\ntextStatus: " + textStatus + "\nerrorThrown: " + errorThrown );
					}
				},
				dataType: "html"		
			};
		sjq.ajax(call);
	},
	submitForm: function (form, handlerName, callbackHandler, preSubmitFunction) {
		sjq.ajax({
			url: LEGO.ajax.stripAnchors(form.attr("action")),
			type: "post",
	        contentType: "application/x-www-form-urlencoded; charset=UTF-8",
			data: LEGO.ajax.preSubmit(form, handlerName, preSubmitFunction),
			success: function(data){
				if(callbackHandler){
					callbackHandler(data);
				}
			},
			error: function(jqXHR, textStatus, errorThrown){
				throw new Error ("Error loading:\njqXHR: " + jqXHR + "\ntextStatus: " + textStatus + "\nerrorThrown: " + errorThrown );
			},
			dataType: "json"
		});
		return false;
	},
	stripAnchors : function (url) {
		// IE work around for anchors ('#') in the form action url with breaks
		// the formhandler method call
			var index = url.indexOf("#");
			return (index > -1)? url.substring(0,index) : url;
	},
	preSubmit: function(form, handlerName, preSubmitFunction) {
		if (undefined != preSubmitFunction) {
			preSubmitFunction(form);
		}
		return form.serialize() + "&" + handlerName;
	},
	bindForm: function(target, eventName, callbackHandler, preSubmitFunction) {
		var form = target.closest('form');
		sjq(target).unbind(eventName);
		sjq(target).bind(eventName, function(event) {
			event.preventDefault();
			LEGO.ajax.submitForm(form, event.currentTarget.name, callbackHandler, preSubmitFunction);
		});
	},
	
	displayValidationErrors: function (fieldErrors) {
		sjq('.field-error').remove();
		var firstErrorKey;
		for (var fieldName in fieldErrors) {
			if (undefined == firstErrorKey) {
				firstErrorKey = fieldName;
			}
			var errorSpan = '<span class="test-Error' + fieldName + ' field-error">' + fieldErrors[fieldName] + '</span>';
			sjq('[name$="' + fieldName + '"]').not('[type="hidden"]').before(errorSpan);
		}
		sjq('[name$="' + firstErrorKey + '"]').focus();
	},
	
	displayValidationPopupErrors: function (fieldErrors) {
		sjq('.field-error, .form-error, .form-error ~ hr').remove();
		sjq('label.error').removeClass("error");
		var firstErrorKey;
		for (var fieldName in fieldErrors) {
			if (undefined == firstErrorKey) {
				firstErrorKey = fieldName;
			}
			var errorSpan =
				'<span class="test-Error' + fieldName + ' field-error">\
					<span></span>\
					<span></span>'
					+ fieldErrors[fieldName] + 
				'</span>';
			var fieldElement = sjq('[name$="' + fieldName + '"]').not('[type="hidden"]');
			fieldElement.parent().prepend(errorSpan);
			fieldElement.closest("label").addClass("error");
			fieldElement.hover(
				function(){sjq(this).parent().addClass("hover");},
				function(){sjq(this).parent().removeClass("hover");}
			);
		}
		sjq('[name$="' + firstErrorKey + '"]').focus();
	}
}

// TODO: review whether this should be here
LEGO.wishlist = LEGO.wishlist ? LEGO.wishlist : {
	init: function(){
		sjq("#wishlist-items-empty").bind("click", this.openWishListModal);
		sjq("#wish-list-sign-in-link").live("click", LEGO.wishlist.openSignInModal);
		sjq("#wish-list-sign-up-link").live("click", LEGO.wishlist.openSignInModal);
	},
	openWishListModal: function(event) {
		event.preventDefault();
		sjq.ajax({
			url: event.currentTarget.href,
			cache: false,
			success: function(data){
				//TODO: use openModal method with predefined size
				LEGO.modal.openModal(null, {name:LEGO.modal.large, overflow: 'scroll', source:data})
			},
			error: function(jqXHR, textStatus, errorThrown){
				throw new Error ("Could not open modal wish list:\njqXHR: " + jqXHR + "\ntextStatus: " + textStatus + "\nerrorThrown: " + errorThrown );
			},
			dataType: "html"
		});
	},
	openSignInModal: function(event) {
		LEGO.modal.close();			
		setTimeout(function(){
			LEGO.modal.openModal(event, {name:LEGO.modal.legoId, href:event.target.href})
		}, 700); // THIS TIMEOUT NEEDS TO BE LONGER THAN THE FADE OUT IN
					// LEGO.modal..close()
		event.preventDefault();
	}
}

LEGO.storeSearch = LEGO.storeSearch ? LEGO.storeSearch : {
	init: function(){
		sjq(".store-locator-button").click(function() {
			var storeSearchLocation = sjq(this).parent().find(".store-locator-input").val();
			window.location.href = "/" + LEGO.currentLocale + "/retail/findAStore.jsp?location="+storeSearchLocation;
			return false;
		});
	}
}
/**
 * Uses the input label as the input prompt text. Requires the following: 1)
 * Format: <label><span>text</span><input /></label> 2) CSS to overlay the
 * span over the input
 */
sjq.fn.bottomBannerInputPrompt = function(){
	var element = sjq(this);
	var label = element.parent().find("> span:first-child");
	element.css("cursor: text;");
	var showLabel = function(){
		if (element.val() == "") {
			label.show();
		} else {
			label.hide();
		}
	}
	showLabel();
	element.bind("focus", function(){
		label.hide();
	});
	element.bind("focusout keyup", function(){
		showLabel();
	});
	label.click(function(){
		element.focus();
	});
}

/**
 * initialises a product thumbnail widget
 */
sjq.fn.productThumbnail = function(){

	return this.each(function(i,thumb) {		
		// quick view button
		sjq('a.btn-quick-view', thumb).click(function(event){
			event.preventDefault();
			var linkUrl = event.currentTarget.href;
			LEGO.scene7.openProductQuickView(linkUrl);		
		});
		
		// add to cart button
		sjq('.thumb-add-to-cart', thumb).click(function(event){
			event.preventDefault();
			var productCode = sjq(event.currentTarget).attr('productcode')
			addToCart(productCode);
		});
		
		// add to wish list
		sjq('.thumb-add-to-wishlist', thumb).click(function(event){
			event.preventDefault();
			document.addRecToWishList.productCode.value = sjq(this).attr('productCode');
			sjq("form[name='addRecToWishList']").submit();
		});
		
		// cap title length
		// TODO: account for html markup in the text
		var MAX_TITLE_LENGTH = 40;
		var link = sjq('h4 > a', thumb);
		var span = sjq('h4 > span', thumb);
		var titleText = sjq.trim( link.html() );
		var productCode = sjq.trim( span.html() );
		
		var lengthToDisplay = MAX_TITLE_LENGTH - (productCode.length + 1);
		if(titleText.length > lengthToDisplay){
			var trimedTitleText = titleText.slice(0, lengthToDisplay-1) + '&hellip;';
			link.html(trimedTitleText)
				.attr('title', titleText);				
		}
		
		// handle thumbnail hover events
		// for IE8/7 (.htc) button styling to work, the hover class has to be
		// added directly to the quick view button
		sjq(thumb).bind({
			mouseover: function() {
				sjq('.btn-quick-view', this).addClass('hover');
			},
			mouseout: function() {
				sjq('.btn-quick-view', this).removeClass('hover');
			}
		});	
	});
	
	// thumbnail helper functions
	
	function addToCart(productCode) {
		document.addProductToCartFromListing.productCode.value = productCode;
		document.addProductToCartFromListing.quantity.value = 1;
		var form = sjq("form[name='addProductToCartFromListing']");
		
		LEGO.miniBag.showLoadingSpinner();
		LEGO.ajax.ajaxForm(form, function(minibagHtml) {
			LEGO.miniBag.cartItemAdded(minibagHtml);
		});
	}
};


/**
 *	Add 'focus' class to buttons as they gain focus, this allow navigation by keyboard
 */
sjq.fn.buttonFocus = function(){
	return this.each(function(i,button) {
		sjq(button).focusin(
			function(event){
				sjq(event.currentTarget).addClass("focus");
			}
		);
		sjq(button).blur(
			function(event){
				sjq(event.currentTarget).removeClass("focus");
			}
		);
	});
}

/**
 * some places require buttons (for functional reasons) but need to be styled as links - in that case use this
 */
sjq.fn.replaceButtonWithLink = function(){
	return this.each(function(i,btn) {		
		btn = sjq(btn);
		var btnText = btn.is('button') ? btn.html() : btn.val();
		var link = sjq('<a class="link-replacing-button" href="#">' + btnText + '</a>');
		var btnClasses = btn.attr('class');
		
		link.addClass(btnClasses)
			.click(function(event){
				event.preventDefault();
				btn.click();
			});
		
		btn.hide()
			.removeClass(btnClasses)
			.after(link);
	});
};

/**
 * A work around for the PIE.htc problem of not always displaying buttons on IE8/9. Flushing the css visibility resolves the issue
 */
sjq.fn.flushButtonVisibility = function(){
	return this.each(function(i,btn) {
		setTimeout(function(){
			sjq(btn).css("visibility", "visible");
		},500);
	});
};
