var init = true;
function debug (debugValue) {
	//alert(debugValue);
}

String.prototype.trim = function() {
	return this.replace(/^\s+|\s+$/g,"");
}
String.prototype.ltrim = function() {
	return this.replace(/^\s+/,"");
}
String.prototype.rtrim = function() {
	return this.replace(/\s+$/,"");
}

// The SKU item object
function AlternativeImage (name, altText, smallImage, largeImage, hugeImage) {
	this.name = name;
	this.altText = altText;
	this.smallImage = smallImage;
	this.largeImage = largeImage;
	this.hugeImage = hugeImage;
}

AlternativeImage.prototype.getName = function() {return this.name;};
AlternativeImage.prototype.getAltText = function() {return this.altText;};
AlternativeImage.prototype.getLargeImage = function() {return this.largeImage;};
AlternativeImage.prototype.getHugeImage = function() {return this.hugeImage;};
AlternativeImage.prototype.getSmallImage = function() {return this.smallImage;};

function SkuAlternativeImages () {
	this.array = new Array();
}

SkuAlternativeImages.prototype.put = function( alternativeImage ) {
    if( ( typeof alternativeImage != "undefined" ) ) {
        this.array[this.array.length] = alternativeImage;      
    }
}

function Price (nowPrice, wasPrice, wasWasPrice, savingPercentage, savingAmount, showWasPricePercentage, showWasPriceAmount, showWasWasPriceAmount ) {
	this.nowPrice = nowPrice;
	this.wasPrice = wasPrice;
	this.wasWasPrice = wasWasPrice; //sku wasWas display
	this.savingAmount = savingAmount;
	this.savingPercentage = savingPercentage;
	this.showWasPricePercentage = showWasPricePercentage;
	this.showWasPriceAmount = showWasPriceAmount;
	this.showWasWasPriceAmount = showWasWasPriceAmount; //sku wasWas display
}

Price.prototype.getNowPrice = function() {return this.nowPrice;};
Price.prototype.getWasPrice = function() {return this.wasPrice;};
Price.prototype.getWasWasPrice = function() {return this.wasWasPrice;};
Price.prototype.getSavingAmount = function() {return this.savingAmount;};
Price.prototype.getSavingPercentage = function() {return this.savingPercentage;};
Price.prototype.getShowWasPricePercentage = function() {return this.showWasPricePercentage;};
Price.prototype.getShowWasPriceAmount = function() {return this.showWasPriceAmount;};
Price.prototype.getShowWasWasPriceAmount = function() {return this.showWasWasPriceAmount;};

function SkuSettings (price, alternativeImages, mfPartnumber, purchasable) {
	this.alternativeImages = alternativeImages;
	this.price = price;
	this.mfPartnumber = mfPartnumber;
	this.purchasable = purchasable;
	//alert(purchasable);
}

SkuSettings.prototype.getPrice = function() {return this.price;};
SkuSettings.prototype.getAlternativeImages = function() {return this.alternativeImages;};
SkuSettings.prototype.getMfPartnumber = function() {return this.mfPartnumber;};
SkuSettings.prototype.getPurchasable = function() {return this.purchasable;};


//SkuSettings.prototype.put = function(alternativeImages, prices);

// KeyValue - Defines the keys for our hashmap
function KeyValue( key, value) {
    this.key = key;
    this.value = value;
}

// Map - defines the hash map array
function Map() {
    this.array = new Array();
}

Map.prototype.put = function( key, value ) {
    if( ( typeof key != "undefined" ) && ( typeof value != "undefined" ) ) {
        this.array[this.array.length] = new KeyValue( key, value);
    }
}

Map.prototype.get = function( key ) {

	//console.log("map.get('" + key + "')");
    for( var k = 0 ; k < this.array.length ; k++ ) {
    	//console.log("checking specified key[" + key + "] against stored key[" + this.array[k].key + "]");
        if( this.array[k].key == key ) {
				//console.log('retrieved: ' + this.array[k].value);
				if (typeof(this.array[k].value) == 'object') {
					for (element in this.array[k].value) {
						//console.log('****' + element + ': ' + this.array[k].value[element]);
					}
				}
            return this.array[k].value;
        }
    }
    return "";
}

Map.prototype.length = function() {
    return this.array.length;
}

// On initial load we re move the options from the sub-options until user has selected previous option
function initOptions(multipleProducts) {
	
	// reset the diouble click variable
	
	// If this is a page with multiple products then we need to ensure we set all possible dropdowns
	var maxNoOfProducts = 1;
	var maxNoOfOptions = 10;
	var displayPriceLabel = true;
	if (multipleProducts) {
		maxNoOfProducts = 10;
		displayPriceLabel  = false;
	}

	//New - retrieve the price elements from the dom and pack their ID's
	if (jQuery) {
		var productEntries = $('#bodycontent form div.priceElement, #productActions .priceElement');

		var priceElementIDs = [];
		productEntries.each(function(){
			priceElementIDs.push(this.id);
		})
		//console.log(priceElementIDs);
		
		maxNoOfProducts = priceElementIDs.length;
	}
	
	// Iterate through each product on the page (Assumes max of 10 for say a bundle/quick shop page)
	for (prodIdx = 0; prodIdx < maxNoOfProducts; prodIdx++) {
		
		var productPrefix = "";
		if (maxNoOfProducts > 1) {
			productPrefix = priceElementIDs[prodIdx];
		}
		
		var lastSelectedId  = "";	
		var lastSelectedElement  = "";	
		var lastSelectedOptionNo = 0;
		
		var previousSelected = false;
		// Iterate through each drop down box and check if it has a selected option
		for (initIdx = 1; initIdx <= maxNoOfOptions; initIdx++) {
			var elementId = productPrefix + "attrValue" + (initIdx);		
			
			if (document.getElementById(elementId)) {
				var definingOption = document.getElementById(elementId);
				if (definingOption != "undefined") {
					// If the dropdown is selected then we need to ensure it is sorted
					var selIndex = definingOption.selectedIndex;
					var selValue = definingOption.options[selIndex].value;

					//alert("init opts selValue=" + selValue);
					if (selIndex > 0) {
						//sortSelect(definingOption, true);
						previousSelected = true;						
						lastSelectedId = productPrefix;
						lastSelectedElement = definingOption;
						lastSelectedOptionNo = initIdx;
						
						// Ensure the correct option is still selected
					    for (var loop=1; loop<definingOption.options.length; loop++) {
					    	if (selValue === definingOption.options[loop].value) {
					    		definingOption.selectedIndex = loop;
								// Due to how the browser renders this on a refresh, we have encode the values back again
								definingOption.options[loop].value = definingOption.options[loop].value.replace(/&/gi,'&amp;');
								//alert("in init:"+definingOption.options[loop].value);
					        }
					    }
					} else {
						if (initIdx==1 || previousSelected) {
							// Lets sort the current drop down 
							sortSelect(definingOption, true);
						} else {
							definingOption.length = 1; // We always leave the default option around
							definingOption.disabled="true";				
						}
						previousSelected = false; // This option has not been selected yet so preven tsubsequent options from being enabled
					}
				}
			} else {
				//debug ("Reached end of attributes");
				initIdx = maxNoOfOptions + 1;
			}		

		}

		// Save the default price details for use later
		var priceElementId = productPrefix ? productPrefix : 'priceelement' ;
		
		//console.log(document.getElementById(priceElementId));
		
		
		if (document.getElementById(priceElementId)) {

			defaultPriceDetails.put(priceElementId.toUpperCase(), document.getElementById(priceElementId).innerHTML);
			//defaultPriceDetails.put("wasPriceDisclaimer", document.getElementById("wasPriceDisclaimer").innerHTML);			
		}

		// Now that we have reselected all required options we need to ensure the correct price is shown using the last selected options
		// but only if a option selected
		if (previousSelected) {
		    switchSkuSettings(document.OrderItemAddForm, lastSelectedElement, lastSelectedId, lastSelectedOptionNo, true);
		}
		

	}
	
	init = false;
}

function validateSelectedOptions (aForm, multipleProducts) {

	var maxNoOfProducts = 1;
	var maxNoOfOptions = 10;
	if (multipleProducts) {
		maxNoOfProducts = 10;
	}
	
	for (prodIdx = 1; prodIdx <= maxNoOfProducts; prodIdx++) {
		var productPrefix = "";
		
		// Adding this prefix condition for validating the selections in the range's page
		if((typeof aForm.FromAttributeValuePrefix != 'undefined') && aForm.FromAttributeValuePrefix.value != ''){
			productPrefix = aForm.FromAttributeValuePrefix.value;
		}else{
			if (maxNoOfProducts > 1) {
				productPrefix = "p" + prodIdx;
			}
		}
		
		// Only validate if the add checkbox is present and set or noty present at all 
		var checkBoxId = productPrefix + "_selected";
		var bValidate=true;
		if (document.getElementById(checkBoxId)) {
			var includeProduct = document.getElementById(checkBoxId);
			if (!includeProduct.checked) {
				bValidate=false;
			}
		}
		
		if (bValidate) {
		for (i = 1; i <= maxNoOfOptions; i++) {
				var elementId = productPrefix + "attrValue" + (i);
				if (document.getElementById(elementId)) {
					var definingOption = document.getElementById(elementId);
					if (definingOption !== "undefined") {
						var selIndex = definingOption.selectedIndex;
						var errorText = definingOption.options[0].text + " " + definingOption.options[0].value;
						if (selIndex <= 0 && definingOption.options.length > 1) {
							return false;
						}
					}
				} else {
					i = maxNoOfOptions + 1;
				}		
			}		
		}
	}

	return true;
}

function handleSpecialChars(selValue){
	//handle encoded ampersand followed by eol
	var ampIdx=selValue.search(/\&amp;$/g);
	while(ampIdx>=0){
		selValue=insertString(selValue, ampIdx+5, "amp;");
		ampIdx=selValue.search(/\&amp;$/g);
	}
	//handle encoded ampersand followed by whitespace
	ampIdx=selValue.search(/\&amp;[\s\&]/g);
	while(ampIdx>=0){
		selValue=insertString(selValue, ampIdx+5, "amp;");
		ampIdx=selValue.search(/\&amp;[\s\&]/g);
	}						
	//handle non-ampersand special characters
	ampIdx=selValue.search(/\&[^(amp;)].*/g);
	while(ampIdx>=0){
		selValue=insertString(selValue, ampIdx+1, "amp;");
		ampIdx=selValue.search(/\&[^(amp;)]/g);
	}
	return selValue;
}
	
function insertString(origString, insertPos, insertStr) {
	var firstPart=origString.substring(0, insertPos);
	firstPart=firstPart+insertStr;
	var secondPart=origString.substring(insertPos);
	return firstPart+secondPart;
}
function getRightKeyValue(keyValue,optionNumber){
   if(keyValue=="undefined" || keyValue==null || keyValue ==""){
       return "";
   }
   var testMap = map;
   //if try to retrieve the data for the first option, we should retrieve the data from optionMap
   if(optionNumber == 1){
      testMap = optionValueMap;
   }
   var skuSettingsTmp = testMap.get(keyValue);
   if(skuSettingsTmp != "undefined" && skuSettingsTmp != null && skuSettingsTmp!=""){
       return keyValue;
	
   }
   var keyValue1 = keyValue.replace(/"/gi,'&#034;');
   keyValue1 = keyValue1.replace(/'/gi,"&#039;");		   
   skuSettingsTmp = testMap.get(keyValue1);
   if(skuSettingsTmp != "undefined" && skuSettingsTmp != null && skuSettingsTmp!=""){       
       return keyValue1;			           			       
   }
   var keyValue2 = handleSpecialChars(keyValue);
   skuSettingsTmp = testMap.get(keyValue2);
   if(skuSettingsTmp != "undefined" && skuSettingsTmp != null && skuSettingsTmp!=""){
       return keyValue2;	           			       
   }
   return keyValue;
}


// Defining a new map for coloecting all the products color options in the range page
var allProductColorSelects = new Map();

// Adding a color option into productColorSelects map
function addingProudctColorOption(colorName, colorValue){
	if(allProductColorSelects.get(colorName) == ""){
		allProductColorSelects.put(colorName, colorValue);
	}
}

//Inital the color Swatcher by showing the all product's color option in the range page
function inintialCororSwatcher(colorSwatcherDiv){
	for(i = 0; i < allProductColorSelects.array.length; i++){
		// Not needed with Geoff's new colour swatch taglib
		//colorSwatcherDiv.innerHTML = colorSwatcherDiv.innerHTML + '<span class="image" onclick="selectAllProductColors(\'' + allProductColorSelects.array[i].key + '\')"/> ' + allProductColorSelects.array[i].key + ' </span>';
		
	}
}

//When color swatcher was clicked, all the product's color option must be changed relevantly in the rang page
//So this function is to implements it.
function selectAllProductColors(selectedColor){
	for(formPos = 0; formPos < document.forms.length; formPos++){
		if(document.forms[formPos].name.indexOf('OrderItemAddForm_') > -1 &&  document.forms[formPos].name.indexOf('OrderItemAddForm_') == 0){
			changeProductColorSelection(document.forms[formPos], selectedColor);
		}
	}
}

//Changing the certain product's color option
function changeProductColorSelection(form, selectedColor){
	for(productsPos = 0; productsPos <= 10; productsPos++){
		var elementId = 'p_' + form.name.replace(/OrderItemAddForm_/g, '') + "_attrValue" + (productsPos + 1); 
		if (document.getElementById(elementId)) {
			var definingOption = document.getElementById(elementId);
			if (definingOption !== "undefined") {
				if(definingOption.options.length > 1){
					if(definingOption.options[0].value == 'Colour'){
						for(j = 1; j < definingOption.options.length; j++){
							if(definingOption.options[j].value == selectedColor){
								if(definingOption.selectedIndex != j){
									definingOption.selectedIndex = j;
									break;
								}
							}
						}
					}
				}
			}
		}
	}
}

// Iterate all the color options, and checking the color has been clicked on the swatcher whether different from the color selected list
// If it's different from the color selecte list, than change the color selected option and calling the switchSkuSettings()
function swatcherColorSettings(aForm, aField, keyPrefix, optionNumber,displayPriceLabel, selectedColorValue){
	var changedFlag = false;
	for (i = 0; i <= 10; i++) {
		var elementId = keyPrefix + "attrValue" + (i+1);
		if (document.getElementById(elementId)) {
			var definingOption = document.getElementById(elementId);
			if (definingOption !== "undefined") {
				if(optionNumber == (i + 1)){
					for(j = 0; j < definingOption.options.length; j++){
						if(definingOption.options[j].value == selectedColorValue){
							if(definingOption.selectedIndex != j){
								definingOption.selectedIndex = j;
								changedFlag = true;
								break;
							}
						}
					}
				}
			}
		}
	}
	
	if(changedFlag){
		switchSkuSettings(aForm, aField, keyPrefix, optionNumber, displayPriceLabel);
	}
}


// Thios function changes the images and prices
// based upon the selected options
function switchSkuSettings( aForm, aField, keyPrefix, optionNumber, displayPriceLabel) {
	
	
	//console.log('aForm: ' + aForm);
	//console.log('aField: ' + aField);
	//console.log('keyPrefix: ' + keyPrefix);
	//console.log('optionNumber: ' + optionNumber);
	//console.log('displayPriceLabel: ' + displayPriceLabel);
	
	// We build up a key value based upon all the definining attributes selected
	// TODO We assume max of 10 defining attributes at this stage, need to make this more generic
	var keyValue = "";
	var allOptionsSelected = true;
	var previousOptionSelected = true;
	var firstOptionValue = "";

	// For the current product on the page (support Product Display/ Bundle and Quick Shop so may be more thasn 1 product)
	// Check if all the options are selected and chaneg the price and image for the selected sku as necessary
	// We locate each select field named attrValue for the current product on the page and check if they are all selected
	for (i = 0; i <= 10; i++) {
		var elementId = keyPrefix + "attrValue" + (i+1);
		//debug("checking for element:" + elementId);
		
		
	
		if (document.getElementById(elementId)) {
			var definingOption = document.getElementById(elementId);
			if (definingOption !== "undefined") {
				//console.log("found attribute " + elementId);

				if (eval((i+1) > optionNumber)) {
					// We have gone past the options that was selected so we need to reset this option
					definingOption.selectedIndex = 0;
				} 
				var selIndex = definingOption.selectedIndex;
				var selValue = definingOption.options[selIndex].value;

				//alert("selectedIndex:" + selIndex + " selValue=" + selValue);			
				if (selIndex <= 0) {
					allOptionsSelected = false;
				} else {
					var selValue = definingOption.options[selIndex].value;
					//var dealedSelValue="";
					// Since the browser will render the values in the drop down by decoded we have to reencode the & character before we look it up
					// We dont reencode if this is called from the initOptions method as the valules will at this point be correct
					if (!init) {
						//alert("init=" + init + " selValue:" + selValue);
						//ampersands need special handling. pad &amp; with another amp;
						//add by Michael Zhou 05/09/08
						//Have no need to do handleSpecialChars(..), because in DynamicProductJavaScriptSetup.jspf
						//The rendered js code just looks like-
						//  map.put("Men&#039;s_Yes", skuSettings);
						//  optionValueMap.put("Men&#039;s", optionValues);
						//there they just use '..&#039;..' as a key. 
						//When did handleSpecialChars(selValue), the key has been changed into '..&amp;#039;..'
						//We must use a consistent key to retrieve the data. I disable the function handleSpecialChars.
					    //add end MZ
					    //need to try more times

						//selValue=handleSpecialChars(selValue);
						//selValue = selValue.replace(/&/gi,'&amp;');
						//dealedSelValue = handleSpecialChars(selValue);
						//alert("selValue:"+selValue +"***dealedSelValue:" +dealedSelValue);
					}
					//alert("selValue=" + selValue);
					//selValue = selValue.replace(/\"/g,'&#034;').replace(/&quot;/gi,'&amp;quot;');
					//selValue = selValue.replace(/\"/g,'&#034;');
					//selValue = selValue.replace(/&amp;/gi,'&amp;amp;');
					//selValue = selValue.replace(/&quot;/gi,'&amp;quot;');
					if (i === 0) {
						firstOptionValue = selValue.rtrim();
					}
					
					if (selValue == "") {
						allOptionsSelected = false;
					} else {
					
						/* Start CR07 - identifying sku in use so can add class */
						
						var SelectedSkuId = '#' + elementId		
						$('.outOfStockMessage').hide()
						$('.buttonAddToBasket').show()					
						$('#dropdownoptions').find('.select').removeClass('selectedSku'); /* clear previous class */
						$(SelectedSkuId).addClass('selectedSku');
						
						/* End CR07 - identifying sku in use so can add class */
					
						if (keyValue != "") {
							keyValue = keyValue + "_";
						} else {
							keyValue = keyPrefix;
						}
						keyValue = keyValue + selValue.rtrim();					
						//alert("keyValue=:" + keyValue);
					}
				}
				
        keyValue = getRightKeyValue(keyValue,optionNumber);
                
				// We change the options for the next set of dropdowns if this is the one that has changed
				//debug("About to check " + (i+1) + " > " + optionNumber);
				if (eval((i+1) > optionNumber)) {
					//debug("Lets update the sub options for keyValue:" + keyValue);
					////console.log(previousOptionSelected);
					if (previousOptionSelected) {
						var subOptions = optionValueMap.get(keyValue);	
							//console.log('% ran key get from' + keyValue);
										
						if (subOptions !== "undefined" && subOptions !== null && subOptions != "") {
							//debug("Found sub options");
							definingOption.removeAttribute('disabled');
							//debug("Settings length to " + (subOptions.length+1));
							definingOption.length = subOptions.length+1;
							for (var subIdx = 0; subIdx < subOptions.length ; subIdx++ ) {
							
								currOptText = subOptions[subIdx];
								// replace &amp; twice to cope with the double escaped, "&amp;amp;" situation...
								// NB. this code does not yet cope with &apos; - may need to be added later.
								//currOptText = currOptText.replace(/&amp;/gi, '&');
								//currOptText = currOptText.replace(/&amp;/gi, '&');
								
								/*Pip Hodge - Issue DUN/01/000320 - uncommented the below two lines of code
								 *to ensure these characters show correctly in dropdowns. */
								currOptText = currOptText.replace(/&#034;/gi, '"');								
								currOptText = currOptText.replace(/&quot;/gi,'"');
								
								definingOption.options[subIdx+1].text = currOptText;
								definingOption.options[subIdx+1].value = subOptions[subIdx]; //.replace(/&amp;/gi,'&');
							}
							sortSelect(definingOption, true);
						} else {
							////console.log(subOptions);
							definingOption.length = 1;
							definingOption.disabled="true";
						}
					} else {
						definingOption.length = 1;
						definingOption.disabled="true";
					}
					
					// We are resetting this suboption so we cannot have selected all options
					allOptionsSelected = false;
				}
				
				//debug("current selected index =" + selIndex);
				if (selIndex <= 0) {
					previousOptionSelected = false;
				}
			}
		} else {
			//debug ("Reached end of attributes");
			//console.log('previous selected:' + previousOptionSelected);
			break;
		}	
			//console.log('previous selected:' + previousOptionSelected);	
	}
	
	var priceElementId = 'priceelement' + keyPrefix;
	var mfPartnumberElementId = 'mfPartnumber' + keyPrefix;
	var wasPriceDisclaimerId = 'wasPriceDisclaimer' + keyPrefix;
	var purchasable = 'purchasable' + keyPrefix;
	
	//console.log(mfPartnumberElementId);
	
	//alert("switchSkuSettings: looking for priceelement:" + priceElementId + " keyPrefix:" + keyPrefix);
	if (allOptionsSelected == true) {
		//alert("tony: switchSkuSettings: Lets find if the images or prices need to be changed using keyValue:" + keyValue);
		var skuSettings = map.get(keyValue);
			//console.log('& ran key get from' + keyValue);
        if (skuSettings === "undefined" || skuSettings === null || skuSettings === "") {
        		// The key values need to be double escaped here such that & -> &amp;amp; and " -> &amp;quot;
        		// NB. there is no functionality for &apos; yet - this may need to be added later.
                //keyValue = keyValue.replace(/&/g,'&amp;');
                //keyValue = keyValue.replace(/&amp;#034;/gi,'&quot;');
                //keyValue = keyValue.replace(/&/g,'&amp;');

				//alert("switchSkuSettings: Lets find if the images or prices need to be changed using converted keyValue:" + keyValue);
         skuSettings = map.get(keyValue);
        }
        
		if (skuSettings !== "undefined" && skuSettings !== null && skuSettings !== "") {
			// default to true if not passed
			if(!displayPriceLabel) {	
				displayPriceLabel = true; 
			}
			
			// We found the details so let change the price information
			var priceString = "";
			
			var nowLabel = "";
			if (skuSettings.getPrice().getShowWasPricePercentage() == true || skuSettings.getPrice().getShowWasPriceAmount() == true
				|| skuSettings.getPrice().getShowWasWasPriceAmount() == true
			) {
				nowLabel = "Now ";
			}
			//console.log('& Displaying price' + skuSettings.getPrice().getNowPrice());
		
			priceString += '<ul>';

				priceString += '<li class="additionalPricingInfo"><ul>';

				if (skuSettings.getPrice().getShowWasPriceAmount() == true && skuSettings.getPrice().getShowWasWasPriceAmount() == true) { //nK added waswas prices
					priceString += '<li class="wasWasPrice"><span class="label">Was </span><span class="amount">' + skuSettings.getPrice().getWasWasPrice() + '</span></li>';
				}		
				if (skuSettings.getPrice().getShowWasPriceAmount() == true) {
					priceString += '<li class="wasPrice darkerWas"><span class="label">Was </span><span class="amount">' + skuSettings.getPrice().getWasPrice() + '</span></li>';
					/* SF removed 'save up to amount' (or percent) script from here as not using for DM or Dorma  */
				}
			
				if (skuSettings.getPrice().getShowWasPriceAmount() == false && skuSettings.getPrice().getShowWasWasPriceAmount() == true) { //shift waswas to was if there IS a waswas and there IS NOT a was
				priceString += '<li class="wasPrice darkerWas"><span class="label">Was </span><span class="amount">' + skuSettings.getPrice().getWasWasPrice() + '</span></li>';
				}
			
				priceString += "</ul></li>";
				
				/* SF [Start] added conditionals here to be able to add classes to change price colour if was price present */
				/*  (contents of the 'else' is original script) */
				if (skuSettings.getPrice().getShowWasPriceAmount() == true || skuSettings.getPrice().getShowWasWasPriceAmount() == true) {	
					priceString += '<li class="mainPrice mainPriceHasWasPrice">';
						// add price label if required
						if(displayPriceLabel) {
							priceString += '<span class="label">' + nowLabel + "</span> ";
						} else {
							priceString += '<span class="label">' + nowLabel + "</span> ";
						}
						priceString += '<span class="amount">' + skuSettings.getPrice().getNowPrice() 
						
						priceString += "</span>";
					priceString += "</li>";	
					}
					else {
					priceString += '<li class="mainPrice">';
						// add price label if required
						if(displayPriceLabel) {
							priceString += '<span class="label">' + nowLabel + "</span> ";
						} else {
							priceString += '<span class="label">' + nowLabel + "</span> ";
						}
						priceString += '<span class="amount">' + skuSettings.getPrice().getNowPrice() 
						priceString += "</span>";
					priceString += "</li>";
				}
				
				/* SF [End] added conditionals here to be able to add classes to change price colour if was price present */

				//Insert the partnumber holder:
				
				priceString += '<li id="' + mfPartnumberElementId + '" class="partNumber"></li>';
				
				if (!document.getElementById('wasPriceDisclaimer')) priceString += '<li id="' + wasPriceDisclaimerId + '"></li>';
			
			priceString += "</ul>";

			//If jQuery is available, hide the price gracefully while we make the switch:
			
			if(jQuery) {
				var thisPriceElement = $('#' + priceElementId);
				if (!$('#' + priceElementId).length) {
					priceElementId = priceElementId.replace('p_', '');
					thisPriceElement = $('#' + priceElementId);	
				}
				thisPriceElement.fadeOut(200, function(){
					thisPriceElement.html(priceString);
					thisPriceElement.closest('form').find('.attributeSelector.higlight, #attributeSelector.higlight').addClass('validated');
					thisPriceElement.fadeIn(200);
				});
			} else {
				document.getElementById(priceElementId).innerHTML=priceString;
			}
			if(skuSettings.getMfPartnumber() !== "undefined" && skuSettings.getMfPartnumber() !== null && skuSettings.getMfPartnumber() !== "" ){
			
				// We found the details so let change the mfpartnumber information
				var mfPartnumberString = '';	
				mfPartnumberString += '<span class="label">Product code\: </span>';
				mfPartnumberString += '<span class="partnumber value">' + skuSettings.getMfPartnumber() + '</span>';
				//alert(mfPartnumberString);
				if (document.getElementById(mfPartnumberElementId)) document.getElementById(mfPartnumberElementId).innerHTML = mfPartnumberString;
			}
			
			
			// Displays out of stock message and hides add to basket button		
			if(skuSettings.getPurchasable() == "false"){
				$('.focus .selectedSku, #attributeSelector .selectedSku').parent().parent().find('#quantity').after('<div class="outOfStockMessage">This item is currently not in stock</div>');
				$('.focus .selectedSku').parent().parent().find('.buttonAddToBasket').hide(); /* Range */
				$('#attributeSelector .selectedSku').parent().parent().parent().find('.buttonAddToBasket').hide(); /* PDP */
			}
			if(skuSettings.getPurchasable() == "true"){
				$('.focus .outOfStockMessage').hide();
				$('.focus .buttonAddToBasket, #productdetailscontainer .buttonAddToBasket').show();
			}

		} else {
			document.getElementById(priceElementId).innerHTML='<span class="noPrice">No price available.</span>';
			if (document.getElementById(mfPartnumberElementId)) document.getElementById(mfPartnumberElementId).innerHTML = "";
		}
	} else {
		if(jQuery) {
			var thisPriceElement = $('#' + priceElementId);
			if (!$('#' + priceElementId).length) {
				priceElementId = priceElementId.replace('p_', '');
				thisPriceElement = $('#' + priceElementId);
			}
			thisPriceElement.fadeIn(200, function(){
				thisPriceElement.html(defaultPriceDetails.get(priceElementId.toUpperCase()));
				thisPriceElement.closest('form').find('.attributeSelector.higlight, #attributeSelector.higlight').removeClass('validated');
				
				if (document.getElementById(wasPriceDisclaimerId)) {
					document.getElementById(wasPriceDisclaimerId).innerHTML = defaultPriceDetails.get("wasPriceDisclaimer");
				} else {
					//Range pages need per-product disclaimers, so don't come presupplied with a placeholder:		
				}
				if (document.getElementById(mfPartnumberElementId)) document.getElementById(mfPartnumberElementId).innerHTML = "";
				thisPriceElement.fadeIn(200);
			});
		} else {
			document.getElementById(priceElementId).innerHTML = defaultPriceDetails.get(priceElementId.toUpperCase());
			document.getElementById(wasPriceDisclaimerId).innerHTML = defaultPriceDetails.get("wasPriceDisclaimer");
			if (document.getElementById(mfPartnumberElementId)) document.getElementById(mfPartnumberElementId).innerHTML = "";
			
		}
	}
	
	// NOw we change the main image if the first option has been selecetd 
	var mainImageElement = document.getElementById("mainimage");
	
	if (mainImageElement != null && mainImageElement != "undefined") {
        var mainImageLargeLinkElement = document.getElementById("pdlargerimage");
        var mainImageLargeImageElement = document.getElementById("pdlargerimage");	
        // For zoom	
        var hugeImageElement = document.getElementById("zoomItemImg")
        if (defaultMainImageSource == "") {
			defaultMainImageSource = mainImageElement.src;
			defaultMainImageAltText = mainImageElement.alt;
			if (hugeImageElement) defaultHugeImageSource = hugeImageElement.value;
			//alert(defaultHugeImageSource + "=" + hugeImageElement.value);

			defaultMainImageLargeLinkSource = mainImageLargeLinkElement.href;
			startPos = defaultMainImageLargeLinkSource.indexOf("imageName=");
			defaultMainImageLargeLinkSource = defaultMainImageLargeLinkSource.substring(startPos+10, defaultMainImageLargeLinkSource.length);
			endPos = defaultMainImageLargeLinkSource.indexOf("&");
			defaultMainImageLargeLinkSource = defaultMainImageLargeLinkSource.substring(0, endPos);

		}
		currentMainImageLargeLinkSource = mainImageLargeLinkElement.href;
	
		startPos = currentMainImageLargeLinkSource.indexOf("imageName="); 
		if (startPos!=-1) { //This allows the script to work with straight image file links
			currentMainImageLargeLinkSource = currentMainImageLargeLinkSource.substring(startPos+10, currentMainImageLargeLinkSource.length);
			endPos = currentMainImageLargeLinkSource.indexOf("&");
			currentMainImageLargeLinkSource = currentMainImageLargeLinkSource.substring(0, endPos);
		}
		
		if (firstOptionValue != "") {
			
			//console.log('###' + firstOptionValue);
			
			aSkuImage = skuAlternativeImages.get(firstOptionValue);
			
           if (aSkuImage != "undefined" && aSkuImage!= null && aSkuImage !== "") {
                  
  						if (mainImageElement) {
                    	if (jQuery) {
	                    	$(mainImageElement).fadeTo(200, 0.01, function(){
	                    	 	$(mainImageElement)
	                    	 	.load(function(){
															$(this)
																.fadeTo(200, 1)
															})
	                    	 	.attr('src', aSkuImage.getLargeImage());
	                    	});
	                    
												//Both IE and safari fail to fire the 'load' event when an image is in the cache
												//This forces a fadeIn after 200ms
												window.setTimeout(function(){
													$(mainImageElement).fadeIn(200);
													}
												, 200);
	                    
	                    } else {
	                    		mainImageElement.src = aSkuImage.getLargeImage();
	                    }
                    
	                   mainImageElement.alt = aSkuImage.getAltText();
                    
	                    // For zoom
	                    if (hugeImageElement) hugeImageElement.src = aSkuImage.getHugeImage();
										
											/*  This is dependent on having additional text for each image - which we don't have
													Needs to be loosely coupled to avoid breaking if the elements aren't present */
											/*
												var mainImageLargeLinkText = document.getElementById("largeimagelinkText");
												var pdlargerimageNonLinkeDiv = document.getElementById("pdlargerimageNoneLinkDiv");
												var pdlargerimageLinkDiv = document.getElementById("pdlargerimageLinkDiv");
												if(aSkuImage.getHugeImage().indexOf('.') < 0){
													mainImageLargeLinkText.style.display="none";
													pdlargerimageNonLinkeDiv.style.display="block";
													pdlargerimageLinkDiv.style.display="none";
													pdlargerimageNonLinkeDiv.appendChild(mainImageElement);
												}else{
													mainImageLargeLinkText.style.display="block";
													pdlargerimageLinkDiv.style.display="block";
													pdlargerimageNonLinkeDiv.style.display="none";
													mainImageLargeImageElement.appendChild(mainImageElement);
												}
											*/

	                    // Set the large image link as well
	                    mainImageLargeLinkElement.href = mainImageLargeLinkElement.href.replace(currentMainImageLargeLinkSource, aSkuImage.getHugeImage());
	                    mainImageLargeImageElement.href = mainImageLargeImageElement.href.replace(currentMainImageLargeLinkSource, aSkuImage.getHugeImage());
							}
            } else {
					if (mainImageElement) {
                    mainImageElement.src = defaultMainImageSource;
                    mainImageElement.alt = defaultMainImageAltText;
                    mainImageLargeLinkElement.href = mainImageLargeLinkElement.href.replace(currentMainImageLargeLinkSource, defaultMainImageLargeLinkSource);
                    mainImageLargeImageElement.href = mainImageLargeImageElement.href.replace(currentMainImageLargeLinkSource, defaultMainImageLargeLinkSource);
                    if (hugeImageElement) hugeImageElement.src = defaultHugeImageSource;
					}
            }

			// Ensure the main image param is set - used to avoid flicker of page when reloading
			if (document.getElementById("itemImg")) document.getElementById("itemImg").value = mainImageElement.src;
			if (document.getElementById("itemAlt")) document.getElementById("itemAlt").value = mainImageElement.alt;
			                 
            // For zoom
			if (document.getElementById("zoomItemImg") && hugeImageElement) {		
				document.getElementById("zoomItemImg").value = hugeImageElement.src;
			}

		} else {
			
			if (mainImageElement) {
					mainImageElement.src = defaultMainImageSource;
					mainImageElement.alt = defaultMainImageAltText;
			
		            // For zoom
						if (document.getElementById("zoomItemImg") && hugeImageElement) {		
							hugeImageElement.src = defaultHugeImageSource;
							document.getElementById("zoomItemImg").value = hugeImageElement.src;
						}
			
					// Switch the large image link back to the default
					mainImageLargeLinkElement = mainImageLargeLinkElement.href.replace(currentMainImageLargeLinkSource, defaultMainImageLargeLinkSource);			
					mainImageLargeImageElement.href = mainImageLargeImageElement.href.replace(currentMainImageLargeLinkSource, defaultMainImageLargeLinkSource);
				}
			}
	}

//	debug("All options selected = " + allOptionsSelected);
}

// Define page level variables
var skuAlternativeImages = new Map();
var map = new Map();
var optionValueMap = new Map();		
var defaultPriceDetails = new Map();
var defaultMainImageSource = "";
var defaultMainImageAltText = "";
var defaultHugeImageSource = "";

// Some generic sort functions for select fields
// sort function - ascending (case-insensitive)
function sortFuncAsc(record1, record2) {
    var value1 = record1.optText.toLowerCase();
    var value2 = record2.optText.toLowerCase();
	if (value1 > value2) return(1);
    if (value1 < value2) return(-1);
    return(0);
}

// Some generic sort functions for select fields
// sort function - ascending (case-insensitive)
function sortFuncNumericAsc(record1, record2) {
    return(record1.optText - record2.optText);
}

// sort function - descending (case-insensitive)
function sortFuncDesc(record1, record2) {
    var value1 = record1.optText.toLowerCase();
    var value2 = record2.optText.toLowerCase();
    if (value1 > value2) return(-1);
    if (value1 < value2) return(1);
    return(0);
}

function sortSelect(selectToSort, ascendingOrder) {
    /*
    Inhibiting, sorting now done on the back end
    alert("in sort");
    if (arguments.length == 1) ascendingOrder = true;    // default to ascending sort

    // copy options into an array
    // NB We skip first row as this is always 'Please select...'
    var allNumeric = true;
    var myOptions = [];
    for (var loop=1; loop<selectToSort.options.length; loop++) {
        myOptions[loop-1] = { optText:selectToSort.options[loop].text, optValue:selectToSort.options[loop].value };
        if (allNumeric) {
        	allNumeric = (!isNaN(myOptions[loop-1].optText));
        }
    }

    // sort array
    if (ascendingOrder) {
    	if (allNumeric) {
            myOptions.sort(sortFuncNumericAsc);
    	} else {
	        myOptions.sort(sortFuncAsc);
    	}
    } else {
    	if (allNumeric) {
	        myOptions.sort();
       	} else {
	        myOptions.sort(sortFuncDesc);
       	}
    }

    // copy sorted options from array back to select box
    selectToSort.options.length = 1;
    
//  SCO01/04/000014
//  Unencode "double escaped" HTML character entities in the Option texts such that &amp;quot; -> &quot; 
//  and &amp;amp; -> &amp and place them in the Select object.
    for (var loop=0; loop<myOptions.length; loop++) {
        var optObj = document.createElement('option');
        optObj.value = myOptions[loop].optValue;
        
        var beforeConvert = myOptions[loop].optText;
        //it looks like no need to deal with, the value can not contain &amp;amp; add by Michael Zhou 05/09/08
        var afterConvert = beforeConvert.replace(/&amp;/gi,"&");   	

        optObj.innerHTML = afterConvert;
        selectToSort.appendChild(optObj);	
    }
    */
}



//*******************************************************
// Refresh product details page when colour changes
// Only used for clients that do not load colour
// as a defning option
//*******************************************************
function refreshColour (aForm, aField) {

	// Construct url to refresh to
	var selIndex = aField.selectedIndex;
	var url = aField.options[selIndex].value;

	// Now add other field values so that we dont lose selected options
	var maxNoOfOptions = 10;
	for (i = 1; i <= maxNoOfOptions; i++) {
		// Append ant selected options to the url
		var elementId = "attrValue" + (i);		
		if (document.getElementById(elementId)) {
			var definingOption = document.getElementById(elementId);
			if (definingOption != "undefined") {
				var selIndex = definingOption.selectedIndex;
				if (selIndex > 0) {
					var selValue = definingOption.options[selIndex].value;
					var selName = definingOption.name;
					url += "&" + selName + "=" + selValue;
				}
			}
		}
	}
	
	if (document.getElementById("WC_CachedProductOnlyDisplay_FormInput_quantity_In_OrderItemAddForm_1")) {
		var qty = document.getElementById("WC_CachedProductOnlyDisplay_FormInput_quantity_In_OrderItemAddForm_1");
		url += "&" + qty.name + "=" + qty.value;
	}
	
	// TODO Add the current qty and any other selected options to the request
	window.location.href = url;

}

	
	
