Initialiser.modules.behaviour = function(){
	
	// ============================================================
	//	New page type detection: based on the safePageConfig object
	// ============================================================
	if (typeof safePageConfig == 'object') {
		
		switch (safePageConfig.pageName) {
			case 'DiscountDetailsDisplay' : //Displaying details of a discount or promotion
				$('#buttonBackAStep').click(function(){
					history.back(1);
					return false;
				});
				
			break;
			case 'ProductDisplay' : //The PDP
				
				//----------------------------------
				//	Overlay-load some links:
				//----------------------------------
				
				var infoOverlays = $('.extraInfoLink , .infolink a', '#productDetailToolLinks')
				      .add('a.attributehelplink').click(function(){
				        
				        $.get($(this).attr('href'), function(response){
			          
				          if ($(response).find('h1').parent().length){

                    if (!$('#overlayWorkingCanvas').length) {
                      $('body').append('<div id="overlayWorkingCanvas" style="display:none"></div>');
                    }

                    var glossaryContent = $(response).find('h1').parent().attr('id', 'overlayBodyContent');
                        glossaryContent.find('a[href*=window.close()]').remove();

                    $('#overlayWorkingCanvas')
                      .html('<div class="overlayWindowBody"><div class="liner"></div><div class="closeWidget" title="Close this overlay"></div></div>')
                      .find('.liner').append(glossaryContent);

                    overlayBody = $('#overlayWorkingCanvas');

            	    $.openDOMWindow({
            				  overlayColor: '#FFF',
            					windowSource:'inline',
            					windowSourceID: '#overlayWorkingCanvas',
            					width: 900
            				});
        				}
      				});
		          return false;
      			});
				
				$('.closeWidget', '#DOMWindow').live('click', function(){
				    infoOverlays.closeDOMWindow();
				})
				
				$('#glossaryHelpLink').click(function(){
				
				  $.get($(this).attr('href'), function(response){
				    //Extract the contents from the right element for display.
				    if ($(response).find('#bodycontent').length){

              if (!$('#overlayWorkingCanvas').length) {
                $('body').append('<div id="overlayWorkingCanvas" style="display:none"></div>');
              }
              
              var glossaryContent = $(response).find('#bodycontent').attr('id', 'overlayBodyContent');
              
              $('#overlayWorkingCanvas')
                .html('<div class="overlayWindowBody"><div class="liner"></div><div class="closeWidget" title="Close this overlay"></div></div>')
                .find('.liner').append(glossaryContent);
              
              overlayBody = $('#overlayWorkingCanvas');
              
      	    $.openDOMWindow({
      				  overlayColor: '#FFF',
      					windowSource:'inline',
      					windowSourceID: '#overlayWorkingCanvas',
      					width: 900
      				});
    				}
				  });
				  
  				return false;
				})
				
				//----------------------------------				
				//	The 'check availability' actions:
				//----------------------------------
				
				//	Some helper functions
				//----------------------------------
				
				var serializeForm = function(form) {
					var formContents = {};
						form.find('input, select').each(function(){
							
							
							if (!formContents[this.name]) {
								formContents[this.name] = $(this).val();
							} else if (typeof formContents[this.name] == 'array') {
								formContents[this.name].push($(this).val());
							} else {
								formContents[this.name] = [formContents[this.name], $(this).val()]
							}
						});
						
					return formContents;
				}
				
				//Caching key elements
				var $addToCartForm = $('#addToCartForm'),
					availabilityChecker = $('#formAvailabilityCheck'),  //Submit this to check availability
					userZipCode = $('#zipCodeEntry'), //The user input for the zip code
					validationMessage = $addToCartForm.find('.validationMessage');
					
				//When we need to show a validation message
				validationMessage
					.bind('availability.showMessage', function(event, message){
						validationMessage.html(message).slideDown(100);
						return false;
					})
					.bind('availability.hideMessage', function(){
						validationMessage.filter(':visible').slideUp(100).html('');
						return false;
					});
				
				 $addToCartForm.bind('availability.setStatus', function(event, status){
				  
					switch (status) {
						case true:
						case 'available':
						
							$addToCartForm
								.addClass('available').removeClass('unavailable')
								
                if ( $.browser.msie && $.browser.version > 8)  $('div.buttonProtector').hide();
						break;
						
						case false:
						case 'unavailable':
							$addToCartForm.addClass('unavailable').removeClass('available');						
              if ( $.browser.msie && $.browser.version > 8) $('div.buttonProtector').show();
						break;
						
						default:
							$addToCartForm.removeClass('available unavailable');
              if ( $.browser.msie && $.browser.version > 8) $('div.buttonProtector').show();
						break;
					}
				 });
				
				//Check the product for availability with the server, given a particular ID	
				var checkAvailability = function(zipToCheck) {
					$('#zipToCheck').val(zipToCheck);
					
					$.get(availabilityChecker.attr('action'),
						serializeForm(availabilityChecker),
						function(data){
							
							//A hack to get IE to read the XML properly:
							var xml;
							if (typeof data == 'string' && $.browser.msie) {
								xml = new ActiveXObject("Microsoft.XMLDOM");
								xml.async = false;
								xml.loadXML(data);
							} else {
								xml = data;
							}
							
							try { var resultText = xml.getElementsByTagName("result")[0].childNodes[0].nodeValue; }
							catch(e) {
							  resultText = /<result>(.+)<\/result>/i.exec(data)[1];
							}
							
							//Successful *request* - check the response for availability
							updateAvailability(resultText == 'available' ? true : false);//update the availability of the component
							$addToCartForm.find('.zipDisplay').text(zipToCheck);
						},
						function(){
							//Failed request
							updateAvailability(false);
						}, ($.browser.msie) ? 'text' : 'xml');
				}
				
				var validateZip = function(zipToCheck) {
					var zipCodePattern = /^\d{5}$/;
					return zipCodePattern.test(zipToCheck);
				}
				
				var updateAvailability = function(availability) {
					$addToCartForm.removeClass('checkInProgress addToCartComplete');
					$addToCartForm.trigger('availability.setStatus', availability);
				}
				
				var checkAvailButton = 	$addToCartForm.find('button.checkAvailability');
				
					checkAvailButton.click(function(){
					var zip = userZipCode.val(); //Fetch the zip code

					if (validateZip(zip)) { //If it looks sensible, run the check
						$addToCartForm.addClass('checkInProgress');
						checkAvailability(zip);
						validationMessage.trigger('availability.hideMessage');
					} else {
						validationMessage.trigger('availability.showMessage', 'Please enter a 5 digit US zip code.');
						userZipCode.focus();
					}
					

					return false;
				});
				
				$addToCartForm.find('a.changeZip').click(function(){
					updateAvailability('reset'); //Update and show the zip code entry field again
					validationMessage.trigger('availability.hideMessage');
					userZipCode.focus();
				});
				
				$addToCartForm.find('div.buttonProtector').click(function(){
					var zip = userZipCode.val(); //When the 'protector' catches a click, focus to the zip code field, or if that's populated, the button

					if (validateZip(zip)) {
						checkAvailButton.focus();
					} else {
						userZipCode.focus();
					}
					
					validationMessage.trigger('availability.showMessage', 'Please enter your zip and check availability first.');
					
					return false;
				});
				
				//Helpers for the zip code entry field:
				userZipCode
					.focus(function(){
						if (this.value == this.defaultValue) {
							this.value = ''; //Clear the helper value
							$(this).removeClass('helperText');
						}
						if (!$(this).is('.dirty')) {
							$(this).addClass('dirty').val('').attr('maxlength', '5');	
						}
					})
					.blur(function(){
						if (!$(this).data('pressed') || !$(this).val().length) {
							this.value = this.defaultValue;
							if (!validateZip(this.defaultValue)) {$(this).addClass('helperText')} //Only reset the helperText clas if the default value wasn't a previous zipcode
						}
						if ($(this).val() == '') $(this).removeAttr('maxlength').val(this.defaultValue).removeClass('dirty');
					})
					.keypress(function(e){
						$(this).data('pressed', true);
						
						//When the Enter key is pressed inside the field, we don't want the surrounding 'real' form to submit,
						//instead we want to 'submit' the mini form inside that handles the zip check
						if (e.keyCode == 13) {
							e.preventDefault();		//Run the check, but prevent the surrounding form from being submitted
							
							var zip = userZipCode.val(); //Fetch the zip code

							if (validateZip(zip)) { //If it looks sensible, run the check
								$addToCartForm.addClass('checkInProgress');
								checkAvailability(zip);
								validationMessage.trigger('availability.hideMessage');
							} else {
								validationMessage.trigger('availability.showMessage', 'Please enter a 5 digit US zip code.');
								userZipCode.focus();
							}
							
						}
					});
					
				//If the browser has pre-filled the zipcode field, mark it as such:
				if (validateZip(userZipCode.val())) {
					userZipCode.removeClass('helperText');
					$addToCartForm.addClass('checkInProgress');
					checkAvailability(userZipCode.val());
				}
				
				//If it's a non-regional product, flag it as always available
				if ($addToCartForm.is('.nonRegional')) {
					updateAvailability(true);
				}
				
				//----------------------------------
				// AJAXify the add to cart action
				//----------------------------------	
				

				var $productDetail = $('#OrderItemAddForm'),
					buttons = $('#addToCart, #addToWishList'),
					attributePickers = $productDetail.find('select, input');
					
				//This just allows us to work out which button was clicked to submit the form
				var clickedButton;
				
				buttons.click(function(e){
					clickedButton = [];
					buttons.removeAttr('clicked');
					
					$(this).attr('clicked', 'true');
					if ($.browser.msie) {
						clickedButton = $(this);
						$productDetail.submit();
					}
				});
				
				//IE needs explicit 'click to submit'?
			
				
				$productDetail.submit(function(){
					var triggerElement = clickedButton.length ? clickedButton : $productDetail.find('button[clicked=true]');
					
					var formIsValid = validateSelectedOptions(this, false);
					
					if (typeof formIsValid == 'object') { //If the validation returns an object, we know it's failed.
						validationMessage.trigger('availability.showMessage', formIsValid.message);
						$(formIsValid.elements).addClass('highlighted');
						
					} else if (formIsValid == true) {
						//Hide any validation messages/pointers that are showing
						validationMessage.trigger('availability.hideMessage')
						attributePickers.removeClass('highlighted');
						
						var addType; //Can be 'cart' or 'wishlist'
						
						//The form needs to be adjusted depending on which button was clicked
						if (triggerElement.is('#addToCart')) {
							
							//Set up the form to add to cart:
							$productDetail.attr('action','/webapp/wcs/stores/servlet/OrderItemAdd');
							//$productDetail.find('input[name=URL]').val('OrderCalculate?URL=/webapp/wcs/stores/servlet/ProductDisplay'); //Not sure what this is used for - doesn't seem to have any effect
							
							addType = 'cart';
						} else if (triggerElement.is('#addToWishList')) {
							//Set up the form to add to the wish list
							$productDetail.attr('action','/webapp/wcs/stores/servlet/InterestItemAdd');
							
							addType = 'wishlist';
						}
						
						//Show the 'in progress' message
						$('#addToCartInProgress span.addType').html(addType);
						$addToCartForm.addClass('addToCartInProgress');
						
						//Serialise the form
						var addToCartData = serializeForm($productDetail.children('.attributeSelection')); //Selecting the .attributeSelection element filters out the form fields that are only used for availability checks.

						if ( $.browser.msie && $.browser.version > 8) { 
						  $('#canAddToCart').hide();
						  $('#addToCartInProgress').show();
						}
						//Send it to the server
						$.ajax({
							type: 'POST',
							url: $productDetail.attr('action'),
							data: addToCartData,
							success: function(response){
								//The add to cart worked:
															
								//turn off the 'in progress'
								$addToCartForm.removeClass('addToCartInProgress');
								if ( $.browser.msie && $.browser.version > 8) {
								  $('#addToCartInProgress').hide();
								  $('#addToCartSuccess').show();
								  
								}
								
								//Check that the addition worked:
								if ($('#basketStatusMessage.messageSuccess, #wishlistStatusMessage.messageSuccess', response).length) {
									var successMessage;

                  //Show the success message
									switch (addType) {
										case 'cart' :
											//Show the success message

											$addToCartForm.addClass('addToCartComplete').removeClass('addToWishlistComplete');

											//update the cart summary (not required after adding to wishlist)
											$('#minishopcart li.items .minishopcartitem').fadeTo('fast', 0.01, function(){
												$('#minishopcart li.items .minishopcartitem').load('/webapp/wcs/stores/servlet/TestView?action=cartStatus #minishopcart li.items .minishopcartitem > *', function(data){
													$('#minishopcart li.items .minishopcartitem').fadeTo('fast', 1);
													if ($.browser.msie) {$('#minishopcart li.items .minishopcartitem').css('opacity', '')}
												});
											});

										break;
										case 'wishlist' :
											//Show the success message
											$addToCartForm.addClass('addToWishlistComplete').removeClass('addToCartComplete');
										break;									
									}
								} else {
									//The server returned an error:
									$('#addToCartFailed').html(
										'<p><span class="icon"></span>We\'re sorry, something went wrong while adding your product.</p>' + 
										'<button type="button" id="continueShopping">Try again</button>&nbsp; or &nbsp;' + 
										'<button rel="chatpdp" class="clickToChatButton" type="button">Chat live with us</a>'
									);
									$addToCartForm.addClass('addToCartFailed').removeClass('addToCartComplete addToWishlistComplete');
									
								}
																
							},
							error:function(jqXHR, textStatus, errorThrown){	//The add to cart failed:
								window.broken = jqXHR;
							}
							});
						}
						
					return false;
				});
				
				
				//When the 'continue shopping' link is clicked, reset the form to allow another 'add to cart'
				$('#continueShopping', $productDetail).live('click', function(){
					$addToCartForm.removeClass('addToCartComplete addToWishlistComplete addToCartFailed'); //This hides the 'finished' states to re-display the buttons
				});
				
				
			  //When the 'add to myRegistry' button is clicked:
			  $('#addToMyRegistry').click(function(){
			    var formIsValid = validateSelectedOptions(this, false);
			    
			    if (typeof formIsValid == 'object') { //If the validation returns an object, we know it's failed.
						validationMessage.trigger('availability.showMessage', formIsValid.message);
						$(formIsValid.elements).addClass('highlighted');
						
					} else if (formIsValid == true) {
						//Hide any validation messages/pointers that are showing
						validationMessage.trigger('availability.hideMessage')
						attributePickers.removeClass('highlighted');

						CreateAddToMyRegistryWidget();
					}
			    
			  });
				
			break;
			
			case 'Error404' : //A bit of a hack to allow static page content to display on an error page (such as 404)
				
			break;	
					
			default:
				
			break;
		}
		
		switch (safePageConfig.pageGroup) {
		  case 'checkout' :
			  //Show a 'please wait' ticket on the checkout pages when submitting:
			  
			  //First, find the location for, and construct the message element:
			  var $checkoutForm = $('form', '#checkout_container, #basket_container'),
			      $buttonBar = $('#page_actions, #basket_actions, div.buttonBar, div.actions');
			      
			      //For sleepys, we may need to dig down to a 'buttonPanel' within the buttonBar
			      if ($buttonBar.find('.buttonPanel').length) { $buttonBar = $buttonBar.find('.buttonPanel') }

			      if ($buttonBar.length) {
			        $buttonBar.append('<div id="checkoutProgressMessage">Please wait a moment</div>');
              
              //Because Sleepys.com uses horrible links with onclick events instead of submit buttons,
  			      //we're binding a custom event which can be fired in several ways:
  			      $checkoutForm.bind('inProgress', function(){
  			        $(this).addClass('checkoutInProgress');	//When the form is submitted, flag the form as in progress. CSS will take care of the rest.
  			      });
  			      
			        $buttonBar.find('a.button').not('.buttonSecondary').click(function(){
                $buttonBar.addClass('checkoutInProgress');
			        });
			        
      			  $checkoutForm.submit(function(){
      			    $(this).trigger('inProgress');
      			  });
			      }
			  
			break;
	  }

	}


	// ============================================================
	//	Global page functions
	// ============================================================

	//The header forms:
	$('#miniStoreLocatorZipInput')
	.bind('click keydown focus', function(){
		if (!$(this).is('.dirty')) {
			$(this).addClass('dirty').val('').attr('maxlength', '5');	
		}
	})
	.blur(function(){
		if ($(this).val() == '') $(this).removeAttr('maxlength').val(this.defaultValue).removeClass('dirty');
	});


	//If a 404 error is detected: (Can't use page identifier for this, as page name varies depending on the requested URL)
	//This is a bit of a hack - we use a link to a static page in an eSpot, and retrieve the contents at that link over AJAX.
	if ($('#errorContentLink').length) {
		var contentLink = $('#errorContentLink'),
			contentTarget = $('<div id="staticContentTarget"></div>').insertBefore(contentLink);

			contentTarget.load(contentLink.attr('href'));
			contentLink.remove();
	}

}

Initialiser.modules.browserChecks = function(){
  
  //Check for unsupported browsers:
  if ($.browser.msie && $.browser.version < 7) {
    safe.showNotificationBar('It looks like you\'re using an <a href="http://windows.microsoft.com/en-US/internet-explorer/products/ie/home">unsupported version of Internet Explorer</a>. Please be aware that some parts of the site might look strange or not work properly.', {barId: 'browserWarningBar-sleepys', additionalClasses: 'warning browserWarning'})
  }
  
  //Check for IE8 compatibility mode:
  if ($.browser.msie && (document.documentMode && document.documentMode == 7)) {
    safe.showNotificationBar('It seems like your Internet Explorer is in compatibility view. For best results, you should turn compatibility view off. <a title="How to turn compatibility view off" href="http://answers.microsoft.com/en-us/ie/forum/ie8-windows_7/turn-off-compatibility-view/33bb7aaf-ab73-47e6-8b5d-d466162ee1cc" target="_blank">Click here</a> for instructions.', {barId: 'browserWarningBar-sleepys', additionalClasses: 'warning browserWarning'})
  }
}
