/**
* @fileoverview venda.js: A module for use across all Venda pages, VCP and front end/ACE.
* <p/>
* This module defines a single global symbol named "Venda".
* Venda refers to the top level namespace object used in all Venda javascript
* all utility functions are stored as properties of this namespace
* functions should generally be stored in separate files held in the Venda subdirectory.
*/

//Check that the 'Venda' global object exists, if not then create it.
if (typeof Venda == "undefined" || !Venda) {
    /**
	 * @class The global Venda class.
     * @constructor
	 */
    var Venda = function () { };
}

/**
 * Construct a new namespace object.
 * <p/>
 * Be careful when naming packages. Reserved words may work in some browsers
 * and not others. For instance, the following will fail in Safari:
 *
 * <pre>Venda.namespace("really.long.nested.namespace");</pre>
 *
 * This fails because "long" is a future reserved word in ECMAScript
 *
 * @type object
 * @param {string} Arguments 1-n namespaces to create
 * @returns {object} A reference to the last namespace object created
 * @author <a href="http://developer.yahoo.com/yui/docs/YAHOO.js.html">YUI</a>
 */
Venda.namespace = function() {
    var a=arguments, o=null, i, j, d;
    for (i=0; i<a.length; i=i+1) {
        d=a[i].split(".");
        o=Venda;
		
        // Venda is implied, so it is ignored if it is included
        for (j=(d[0] == "Venda") ? 1 : 0; j<d.length; j=j+1) {
            o[d[j]]=o[d[j]] || {};
            o=o[d[j]];
        }
    }
    return o;
};

//Create name spaces for Venda.Widget
Venda.namespace("Widget");

// Create name spaces for Venda.Platform
Venda.namespace("Platform");

/**
 * @fileoverview Venda.Platform - A module for use across all the platform (includes VCP and website areas)
 * This will file will contain small universal functions that would be useful throughout the platform. These functions are stored as properteis of the 'platform'  symbol.
 * @author Aron San <asan@venda.com>
 */

/**
 * Stub function is used to support JSDoc.
 * @class Venda.Platform
 * @constructor
 */
Venda.Platform = function(){};

/**
 * Gets the value of a specified URL parameter
 * @param {String} currURL 		this is the URL which you wish to get the URL parameter value from
 * @param {String} urlParam 	this is the name of the URL parameter you want to get the value for
 * @return match 							unescaped value for parameter specified urlParam if true else false
 */
Venda.Platform.getUrlParam = function(url,urlParam) {
	//declare regular expression to be use.
	var re = new RegExp('[?&]'+urlParam+'=([^&]+)');
	var match = url.match(re);
	return match ? unescape(match[1]) : false;
};

/**
 * Produces encoded HTML to be safely displayed on a webpage which mitigates XSS risks.
 * @param {String} 							value to escape
 * @return container.innerHTML 	escaped value
 */
Venda.Platform.escapeHTML = function(strToEscape) {
	var container = document.createElement('span');
	container.appendChild(document.createTextNode(strToEscape));
	return container.innerHTML;
};


/**
 * Given a select box dropdown name and a value will show the divs in arrayToShow
 * and hide the divs in arrays to hide. If not equal to name will do opposite.
 * The function will also blank any existing input text fields and dropdown selects
 * within the divs that are being hidden
 * @param {String} selectBoxName
 * @param {String} selectBoxValue
 * @param {array of strings} arrayToShow
 * @param {arraty of strings} arrayToHide
 */
Venda.Platform.SelectBoxToggle = function( selectBoxName, selectBoxValue, arrayToHide, arrayToShow, rSpeed ) {
	var spd = ( typeof rSpeed === "undefined" ) ? 0 : rSpeed;

	var hideFields = function () {
	  if ( this.value == selectBoxValue ) {
		for ( var i=0; i < arrayToHide.length; i++) {
		  jQuery("#"+arrayToHide[i]+" > *").each( function() {
			if( this.type =='text' ){
			  this.value='';
			}
			else if( this.type =='select-one'){
			  jQuery("#"+this.id+" > *").each ( function() {
				if( this.value=='' ){
				  this.selected=true;
				}
			  } );
			}
		  });
		  jQuery("#"+arrayToHide[i]).hide(spd);
		}
		for ( var i=0; i < arrayToShow.length; i++) {
		  jQuery("#"+arrayToShow[i]).show(spd);
		}
	  }
	  else {
		for ( var i=0; i < arrayToShow.length; i++) {
		  jQuery("#"+arrayToShow[i]+" > *").each( function() {
			if( this.type =='text' ){
			  this.value='';
			}
			else if( this.type =='select-one'){
			  jQuery("#"+this.id+" > *").each ( function() {
				if( this.value=='' ){
				  this.selected=true;
				}
			  } );
			}
		  });
		  jQuery("#"+arrayToShow[i]).hide(spd);
		}
		for ( var i=0; i < arrayToHide.length; i++) {
		  jQuery("#"+arrayToHide[i]).show(spd);
		}
	  }
	}; 

	jQuery("#"+ selectBoxName).each( hideFields ).bind('change', hideFields );
};
/**
 * Original author : Lalit Patel
 * Website: http://www.lalit.org/lab/jsoncookies
 * License: Creative Commons Attribution-ShareAlike 2.5
 *          http://creativecommons.org/licenses/by-sa/2.5/
 */

function CookieJar(options) {
  this.initialize(options);
}

CookieJar.prototype = {
	options: {},

	/**
	 * Initializes the cookie jar with the options.
	 */
	initialize: function(options) {
		this.options = {
			expires: 3600, // seconds (1 hr)
			path:    '',   // cookie path
			domain:  '',   // cookie domain
			secure:  ''	   // secure ?
		};

		for(var prop in options || {})
		  this.options[prop] = options[prop];

		if (this.options.expires != '') {
			var date = new Date();
			date.setTime(date.getTime() + (this.options.expires * 1000));
			this.options.expires = '; expires=' + date.toGMTString();
		}
		
		if (this.options.path != '')
			this.options.path = '; path=' + escape(this.options.path);
		
		if (this.options.domain != '')
			this.options.domain = '; domain=' + escape(this.options.domain);
		
		if (this.options.secure == 'secure')
			this.options.secure = '; secure';
		else
			this.options.secure = '';
	},

	/**
	 * Adds a name values pair.
	 */
	put: function(name, value) {
		var cookie = this.options;
		switch(typeof value) {
			case 'undefined':
			case 'function' :
			case 'unknown'  : return false;
			case 'boolean'  : 
			case 'string'   : 
			case 'number'   : value = String(value.toString());
		}
		var cookie_str = name + "=" + escape(value);
		try {
			document.cookie = cookie_str + cookie.expires + cookie.path + cookie.domain + cookie.secure;
		} catch (e) {
			return false;
		}
		return true;
	},

	/**
	 * Removes a particular cookie (name value pair) form the Cookie Jar.
	 */
	remove: function(name) {
		var cookie = this.options;
		try {
			var date = new Date();
			date.setTime(date.getTime() - (3600 * 1000));
			var expires = '; expires=' + date.toGMTString();
			document.cookie = name + "=" + expires + cookie.path + cookie.domain + cookie.secure;
		} catch (e) {
			return false;
		}
		return true;
	},

	/**
	 * Return a particular cookie by name;
	 */
	get: function(name) {
		var cookies = document.cookie.match(name + '=(.*?)(;|$)');
		if (cookies)
			return unescape(cookies[1]);
		else
			return null;
	},

	/**
	 * Empties the Cookie Jar. Deletes all the cookies.
	 */
	empty: function() {
		var keys = this.getKeys();
		var size = keys.length;
		for(var i = 0; i < size; i++)
			this.remove(keys[i]);
	},

	/**
	 * Returns all cookies as a single object
	 */
	getPack: function() {
		var pack = {};
		var keys = this.getKeys();
		var size = keys.length;
		for(var i = 0; i < size; i++)
			pack[keys[i]] = this.get(keys[i]);
		return pack;
	},

	keyRe: /[^=; ]+(?=\=)/g,

	/**
	 * Returns all keys.
	 */
	getKeys: function() {
		var keys  = [];
		var str   = document.cookie;
		while((match = this.keyRe.exec(str)) != undefined)
		 	keys.push(match[0].replace(/^\s*|\s*$/g, ''));
		return keys;
	}
};

// general.js



function splitEmailAdd(usemail){
var stringlist=new Array();
while(usemail.length>30){
stringlist.push(usemail.slice(0,30));
usemail=usemail.substr(30);
}
if(usemail.length){
stringlist.push(usemail);
}
document.write(stringlist.join('<br>'));
}
turnonToggle=1;
shown=new Image();
shown.src="/venda-support/images/bulleton.gif";
hidden=new Image();
hidden.src="/venda-support/images/bulletoff.gif";
function dynamicContent(where,what){
identifyTag=where.tagName;
if(identifyTag=="A"){
ajaxFunction(where+'&layout=noheaders&temp=subcategories',what);
if(turnonToggle==1){toggle(where);}
}else if(identifyTag=="INPUT"||identifyTag=="SELECT"){
ajaxFunction(where.value,what);
}
}
var EventUtil=new Object;
EventUtil.addEventHandler=function(oTarget,sEventType,fnHandler){
if(oTarget.addEventListener){
oTarget.addEventListener(sEventType,fnHandler,false);
}else if(oTarget.attachEvent){
oTarget.attachEvent("on"+sEventType,fnHandler);
}else{
oTarget["on"+sEventType]=fnHandler;
}
};
EventUtil.removeEventHandler=function(oTarget,sEventType,fnHandler){
if(oTarget.removeEventListener){
oTarget.removeEventListener(sEventType,fnHandler,false);
}else if(oTarget.detachEvent){
oTarget.detachEvent("on"+sEventType,fnHandler);
}else{
oTarget["on"+sEventType]=null;
}
};
function getElementsByClassName(className,tag,elm){
var testClass=new RegExp("(^|\\s)"+className+"(\\s|$)");
var tag=tag||"*";
var elm=elm||document;
var elements=(tag=="*"&&elm.all)?elm.all:elm.getElementsByTagName(tag);
var returnElements=[];
var current;
var length=elements.length;
for(var i=0;i<length;i++){
current=elements[i];
if(testClass.test(current.className)){
returnElements.push(current);
}
}
return returnElements;
}
function addOneMoreColumnOnOrderSummaryPage(){
var oOrderSummaryDiv=document.getElementById("orderconfirmation");
if(oOrderSummaryDiv){
var oWizrTable=getElementsByClassName("wizrtable","table",oOrderSummaryDiv);
for(i=0;i<oWizrTable.length;i++){
var oTR=oWizrTable[i].getElementsByTagName("tr");
for(j=0;j<oTR.length;j++){
var oTD=oTR[j].getElementsByTagName("td");
for(k=0;k<oTD.length;k++){
var oColspan=oTD[k].attributes.getNamedItem("colspan");
if(oColspan){
if(oColspan.value=="4"){
var oNewTD=document.createElement("td");
oTR[j].appendChild(oNewTD);
}
}
}
}
}
}
}
EventUtil.addEventHandler(window,"load",addOneMoreColumnOnOrderSummaryPage);
function fnParseURL(sData){
var e=/((http|ftp):\/)?\/?([^:\/\s]+)((\/\w+)*\/)([\w\-\.]+[^#?\s]+)(#[\w\-]+)?$/;
if(sData.match(e)){
return{
url:RegExp['$&'],
protocal:RegExp.$2,
host:RegExp.$3,
path:RegExp.$4,
file:RegExp.$6,
hash:RegExp.$7
};
}else{
return{
url:"",
protocal:"",
host:"",
path:"",
file:"",
hash:""
};
}
}
function fnGetQueryString(sData){
var sHash=new Array;
sHash.getValue=function(sKey){
if(this[sKey]==undefined){
return"";
}else{
return this[sKey];
}
}
var sTokens=sData.split("&");
for(var i=0;i<sTokens.length;i++){
var sFields=sTokens[i].split("=");
if(sFields.length==2){
sHash[sFields[0]]=sFields[1];
}
}
return sHash;
}
function fnAssignNewLayout(sCompareURL,sNewLayout,oAllLinks){
var sLink="";
for(var i=0;i<oAllLinks.length;i++){
sLink=oAllLinks[i].href;
if(sLink.indexOf("/page/contactus")==-1){
if(sLink.indexOf(sCompareURL)!=-1){
if(sLink.indexOf("layout=")!=-1){
var sCurrentLayout=fnGetQueryString(fnParseURL(sLink).file).getValue("layout");
sLink=sLink.replace("layout="+sCurrentLayout,"layout="+sNewLayout);
}else{
if(sLink.indexOf("#")!=-1){
sLink=sLink.replace("\#","&layout="+sNewLayout+"\#");
}else{
sLink=sLink+"&layout="+sNewLayout;
}
}
oAllLinks[i].href=sLink;
}
}else{
oAllLinks[i].target="_blank";
}
}
}
function grabURL(currURL,urlParam){
var url=unescape(currURL);
var spliter='&';
var sField=spliter+urlParam+'=';
if(url.search(sField)==-1){
sField='?'+urlParam+'=';
}
var urlArray=url.split(sField);
if(urlArray[1]){
var paramArray=urlArray[1].split(spliter);
return(paramArray[0]);
}
}
function popup(url,width,height,name){
if(width==''||width==null)width=400;
if(height==''||height==null)height=425;
if(name==''||name==null)name="details";
var props="toolbar=no,location=no,status=no,scrollbars=yes,resizable=yes,titlebar=no,menubar=no,width="+width+",height="+height;
w=window.open(url,name,props);
if(w)w.focus();
}
function addOnloadEvent(fnc){
if(typeof window.addEventListener!="undefined")
window.addEventListener("load",fnc,false);
else if(typeof window.attachEvent!="undefined"){
window.attachEvent("onload",fnc);
}
else{
if(window.onload!=null){
var oldOnload=window.onload;
window.onload=function(e){
oldOnload(e);
window[fnc]();
};
}
else
window.onload=fnc;
}
}
var is={
ie:navigator.appName=='Microsoft Internet Explorer',
java:navigator.javaEnabled(),
ns:navigator.appName=='Netscape',
ua:navigator.userAgent.toLowerCase(),
version:parseFloat(navigator.appVersion.substr(21))||
parseFloat(navigator.appVersion),
win:navigator.platform=='Win32'
}
is.mac=is.ua.indexOf('mac')>=0;
if(is.ua.indexOf('opera')>=0){
is.ie=is.ns=false;
is.opera=true;
}
if(is.ua.indexOf('gecko')>=0){
is.ie=is.ns=false;
is.gecko=true;
}
// sitewide
//Below 2 Functions to limit text input - used in gift wrap screen
function TrackCount(fieldObj,countFieldName,maxChars){
	var countField = eval("fieldObj.form."+countFieldName);
	var diff = maxChars - fieldObj.value.length;
	
	// Need to check & enforce limit here also in case user pastes data
	if (diff < 0){
	  fieldObj.value = fieldObj.value.substring(0,maxChars);
	  diff = maxChars - fieldObj.value.length;
	}
	countField.value = diff;
};
function LimitText(fieldObj,maxChars){
	var result = true;
	if (fieldObj.value.length >= maxChars) {
		result = false;
		alert('Please limit the text ' + maxChars+ ' characters.');	
	}
	if (window.event)
	window.event.returnValue = result;
	return result;
};

//store locator validation
function checkPostcode(formObj,fieldObj,textMsg) {
	var formObj = "document." + formObj;
	var formObjField = formObj + "." + fieldObj + ".value";
	formObjField = eval(formObjField);
	if ((formObjField == textMsg) || (formObjField == "")) {
		alert("Please enter the full postcode.");
		return false;
	}
	else {
		formObj = eval(formObj)
		formObj.submit();
	}
};

//Element - Email newsletter signup / EMWBIS
function checkemail(str) {
	var filter =/^\w+[\+\.\w-]*@([\w-]+\.)*\w+[\w-]*\.([a-z]{2,7}|\d+)$/i;
	return (filter.test(str))
};

function validateEmail(mail,msg) {
	if (checkemail(mail.email.value)) {
		mail.submit();
	} else {
		alert(msg);
		mail.email.focus();
	}
};

function openNav(openicat,openicat2){
	if (typeof activateNav != 'undefined'){
		// default toggle if turnonToggle does not exist
		if (typeof turnonToggle === 'undefined') { var turnonToggle = 1; }
		// show first level subcategories
		if (openicat != "") {
			if (turnonToggle == 1) {
				showOrHide(1,openicat);
			}
			// show second level subcategories
			if (openicat2 != "") {
				if (turnonToggle == 1) {
					showOrHide(1,openicat2);
				}
			}
		}
	}
};

// addEvent script from http://www.accessify.com/features/tutorials/the-perfect-popup/
function addEvent(elm, evType, fn, useCapture){if(elm.addEventListener){elm.addEventListener(evType, fn, useCapture);return true;}else if (elm.attachEvent){var r = elm.attachEvent('on' + evType, fn);return r;}else{elm['on' + evType] = fn;}};

// erase recently viewed items cookie when user logs out
function eraseCookieIfLoggedOut(cookieName) {
	var urlParam = '';
	var loggedout = 4;
	urlStr = document.location.href.split('&');
	for (i=0; i<urlStr.length; i++) {
		var t = urlStr[i].split('=');
		if (t[0] == "log")	{
			urlParam = t[1];
		}
	}
	if (urlParam==loggedout) {
		//erase the cookie cookieName
		new CookieJar({path: '/'}).remove(cookieName);
	}
	return  urlParam;
};

addEvent(window, 'load', function() { eraseCookieIfLoggedOut("RVI") }, false);

// show element
  	 function showHidden(id,frameRef){
  	         if (frameRef) {
  	         //show in specified frame. Frame must have same parent
  	         var doc = parent.frames[frameRef].document;
  	         } else {
  	         //show in current frame
  	         var doc = document;
  	         }
  	         var ele = doc.getElementById(id);
  	         if (ele){
  	         ele.style.visibility = "visible";
  	         ele.style.display = "inline";
  	         }
  	 };
  	 //hide element
  	 function hideThis(id){
  	         var ele = document.getElementById(id);
  	         if (ele){
  	         ele.style.visibility = "hidden";
  	         ele.style.display = "none";
  	         }
  	 };

// toggle.js

	 function trigger(clicked) {
	toggle(document.getElementById(clicked));
};

function toggle(clicked) {
	// strip "control" from the id of what was clicked
	ref=clicked.id.replace(/control/,"");
	// vars for referring to control and area
	control=document.getElementById("control"+ref);
	area=document.getElementById("tab"+ref); 
	
	if (area.style.display=="") {
	// div hasn't been clicked yet check if it is off (has a class of "cannotsee") or on ("cansee")
	if (area.className.indexOf("cannotsee")>=0) {
		// className contains cannotsee so turn it on
		showOrHide(1,ref);
	} else if (area.className.indexOf("cansee")>=0) {
		// className contains cansee so turn it off
		showOrHide(0,ref);
	}
	} else if (area.style.display=="block") {
		showOrHide(0,ref);
	} else if (area.style.display=="none") {
		showOrHide(1,ref);
	}
};

function showOrHide(show, who) {
	// vars for referring to area and control
	area=document.getElementById("tab"+who);
	// only set these if something was clicked
	// eg. image loop can't be toggled it just borrows showOrHide function so control is null
	control=document.getElementById("control"+who);
	if (control) {
		var linkChild=[control.firstChild, control.lastChild];
		//alert(linkChild[control.lastChild]);
		for (var x=0; x<linkChild.length; x++) {		
			if (linkChild[x].tagName=="SPAN") {
				text=linkChild[x];		
			} else if (linkChild[x].tagName=="IMG") {
				icon=linkChild[x];
			}		
		}
	} 
	if (show==0) {
		// hide the area
		area.style.display="none";
		if (control) {
			// change the control image to an arrow (hidden) and update the text
			if (window.icon) {icon.src=hidden.src;}
			if (window.hiddenText) {
				// note hiddenText var is defined in the template as it won't translate here
				text.innerHTML=hiddenText;
			}
		}
	} else if (show==1) {
		// show the area
		area.style.display="block";
		if (control) {
			// change the control image to a cross (shown) and update the text
			if (window.icon) {icon.src=shown.src;}
			if (window.shownText) {
				// note shownText var is defined in the template as it won't translate here
				text.innerHTML=shownText;
			}
		}
	}
	
};
/*this function use for attribute toggle only, and it can't use with multiple class*/
function changeALOT(strTagHead,strTag,strClass,textId)
{
	text = document.getElementById(textId);

	for (i=0;i<document.getElementsByTagName(strTag).length; i++) 
	{
		if (document.getElementsByTagName(strTag).item(i).className == strClass)
		{
			if(document.getElementsByTagName(strTag).item(i).style.display!= "none")
			{
				document.getElementsByTagName(strTag).item(i).style.display="none";
				text.style.display="";
			}
			else
			{
				document.getElementsByTagName(strTag).item(i).style.display="";
				text.style.display="none";
			}
		}
	}
	for (i=0;i<document.getElementsByTagName(strTagHead).length; i++) 
	{
		if (document.getElementsByTagName(strTagHead).item(i).className == strClass)
		{
			if(document.getElementsByTagName(strTagHead).item(i).style.display!= "none")
			{
				document.getElementsByTagName(strTagHead).item(i).style.display="none";
				text.style.display="";
			}
			else
			{
				document.getElementsByTagName(strTagHead).item(i).style.display="";
				text.style.display="none";
			}
		}
	}
};

//attributes.js

// Functions to handle the dynaminc modifcation of attribute drop downs, images
// and prices

// Global store for all the products and attribute lists
var attributeStore = new Object;
attributeStore.savedDropdowns = new Object;

// Create and/or retrieve a product instance identified by uuid
function getProduct ( uuid ) {

	var product = attributeStore[uuid] || new Product(uuid);
	attributeStore[uuid] = product;
	return product;
}

// Create a new product object given the details we have
function Product ( uuid ) {

	this.uuid = uuid;
	this.attributes = new Array( 'att1', 'att2', 'att3', 'att4' );
	this.prices = new Array( 'atrmsrp', 'atrsell', 'atrwas' );
	this.attributeValues = new Object;

	// Store the attribute names (e.g. att1 => 'Colour', att2 => 'Size')
	this.setAttributeNames = function ( attributeNames ) {
		this.attributeNames = attributeNames;
	}

	// Text strings for currency symbols, default sale text, sale text, etc
	this.setLabels = function ( strings ) {
		this.labels = strings;
	}

	// Store attributes for screening the drop downs
	this.setAttributeData = function ( attributeValues, data ) {
		var attributeString = this.attributeString(attributeValues);
		data['attributeString'] = attributeString;
		this.attributeValues[attributeString] = { values: attributeValues, data: data };

		// Track the minimum prices for defaulting
		for ( var i in this.prices ) {
			if ( data[ this.prices[i] ] ) {
				this.storeMinimum( this.prices[i], data[ this.prices[i] ] );
			}
		}
	}

	// Store a record of the minimum value of a named attribute
	this.storeMinimum = function ( name, value ) {
		value = parseFloat(value);  // extract a number
		this.minimum = this.minimum || new Object;
		if ( ( !isNaN(value) && value < this.minimum[name] )
		  || !this.minimum[name] ) {
			this.minimum[name] = value;
		}
	}

	// Join the attribute values together to give us a unique string by which to
	// look up prices/images, etc when the user chooses their attributes.
	this.attributeString = function ( attributeValues ) {
		var attributes = this.attributes; // att1, att2, etc
		var attributeString = '';
		for ( var i = 0 ; i < attributes.length; i++ ) {
			if ( attributeValues[attributes[i]] != undefined ) {
				attributeString = attributeString + attributeValues[attributes[i]];
			}
		}
		return attributeString;
	}

	// OnChange of an attribute drop down, restrict the availability of the
	// remaining dropdowns and update any page elements necessary
	this.changeAttributes = function ( select ) {

		// Get a list of what has been selected and a copy of the full (ordered)
		// list of each attribute
		var selected = new Object;
		for ( var attribute in this.attributeNames ) {

			var selectId = this.getElementId(attribute);

			// If the element exists...
			var selectElement;
			if ( selectElement = document.getElementById( selectId ) ) {

				// Note down what is currently selected
				selected[attribute] = selectElement[selectElement.selectedIndex].value;

				// Take a copy the first time to avoid copying filtered lists.
				if ( attributeStore.savedDropdowns[selectId] == undefined ) {

					attributeStore.savedDropdowns[selectId] = new Array;
					for ( var i = 0; i < selectElement.options.length; i++ ) {
						attributeStore.savedDropdowns[selectId][i] = selectElement.options[i];
					}
				}

				// And reset the lists to their original state
				for ( var i = 0; i < attributeStore.savedDropdowns[selectId].length; i++ ) {
					selectElement.options[i] = attributeStore.savedDropdowns[selectId][i];
				}
			}
		}

		// Create a little closure by which to filter the available attributes
		var attributeNames = this.attributeNames; // Copied here for the filter closure
		var filterAttributesFunction = function ( element, index, array ) {
			// We must match each element which has been selected.
			for ( var attribute in attributeNames ) {

				// And even if we do, it must match your selection
				if ( selected[attribute] && attribute <= select.name ) {
					// Must match your selection
					if ( element['values'][attribute] != selected[attribute] ) {
						return false; 
					}
				}
			}
			return true;
		};

		// Work out the acceptable values using our closure
		var allowed = new Object;

		// Match every attribute against the selected options
		var toFilter = new Array;
		for ( var atrsku in this.attributeValues ) {
			toFilter.push( this.attributeValues[atrsku] );
		}

		var filteredAttributes = toFilter.filter( filterAttributesFunction );
		for ( var filtered in filteredAttributes ) {
			for ( var att in filteredAttributes[filtered]['values'] ) {
				allowed[att] = allowed[att] || new Object;
				allowed[att][ filteredAttributes[filtered]['values'][att] ] = true;
			}
		}

		// Foreach attribute, 
		for ( var att in allowed ) {

			// Only act on subsequent attributes
			if ( att <= select.name ) {
				continue;
			}
			// check each select
			var selectId = this.getElementId(att);

			var selectElement;
			if ( selectElement = document.getElementById( selectId ) ) {

				// Delete any elements which are not in the newly filtered list
				// Going backwards so we don't mess up the index as we delete things
				// out of it
				for ( var i = selectElement.options.length - 1; i > 0; i-- ) {
					if ( !( selectElement.options[i].value in allowed[att] ) ) {
						selectElement.options[i] = null;
					}
				}
			}
		}

		// Change anything that's asked us to change it
		this.updateElements( select );
	}

	// Change anything that's asked us to change it
	this.updateElements = function ( select ) {
		// Make any changes to the page based on this selection
		for ( var elementType in this.elements ) {

			var elementId = this.elements[elementType];
			var element = document.getElementById( elementId );

			if ( !element ) {
				alert( "Unable to find element '" + elementId + "' for " + elementType );
				continue;
			}

			// Bit of a hack for 'media items'
			if ( element.nodeName == 'IMG' ) {
				var chosenAttribute = select[select.selectedIndex].value;
				if ( this.type[elementType][chosenAttribute] != undefined ) {
					element.src = this.type[elementType][chosenAttribute];
				}
			}
			else if ( element.nodeName == 'SPAN' || element.nodeName == 'DIV' ) {
				
				var value; // value contains the price string (was, sell, msrp, saving)
				var label; // label contains the text of the price label 
				
				var attributeString = this.chosenAttributeString();	
				if ( this.validCombination(attributeString) ) {
					var attributeSku = this.attributeValues[attributeString];

					if ( elementType in attributeSku['data'] ) {
							value = attributeSku['data'][elementType] || '';
							label = this.labels[elementType] || '';
					}
				}
				else {
					value = this.minimum[elementType] || '';
					label = this.labels[ 'default_' + elementType ] || '';					
				}
				
				// Look for a label, too
				var labelElement = document.getElementById( elementId + 'Label' );
				if ( value == '' ) {
					// Hide the elements if we don't have a value for
					// them.
					element.style.display = 'none';
					labelElement.style.display = 'none';
					element.innerHTML = '';
					labelElement.innerHTML = '';
					if ( !labelElement ) {
						labelElement.style.display = 'none';
					}
				}
				else {
					if (value.toFixed) {
						value = value.toFixed(2);//if browser supports toFixed() method, fix to 2 dp
					}
					if ( this.labels['currsym'] != '' ) {
						value = this.labels['currsym'] + value;
					}

					//element.innerHTML = value;
					while (element.hasChildNodes()) {
						element.removeChild(element.lastChild);
					}
					element.appendChild(document.createTextNode(value));
					element.style.display = 'inline';
					if ( labelElement ) {
						//labelElement.innerHTML = label;
						while (labelElement.hasChildNodes()) {
							labelElement.removeChild(labelElement.lastChild);
						}
						labelElement.appendChild(document.createTextNode(label));
						labelElement.style.display = 'inline';
					}
				}
			}
		}
	}

	// Build an attribute String based on which of this product's attributes are
	// currently selected
	this.chosenAttributeString = function () {
		var attributeValues = new Object;
		for ( var attribute in this.attributeNames ) {
			if ( attribute in this.elements ) {
				var element = document.getElementById(this.elements[attribute]);
				if ( element ) {
					attributeValues[attribute] = element[element.selectedIndex].value
				}
				else {
					alert( "Can't find element: '" + this.elements[attribute] + "'" );
				}
			}
		}
		return this.attributeString(attributeValues);
	}

	// Initial hacky way of updating images (they only work on att1 and are
	// generated separately)
	this.setChanges = function ( args ) {
		this.type = this.type || new Object;
		this.type[ args['type'] ] = args['map'];
	}

	// Register an element as belonging to this product instance.
	this.registerElement = function () {
		this.elements = this.elements || new Object;
		for ( var i = 0; i < arguments.length; i++ ) {
			this.elements[ arguments[i]['type'] ] = arguments[i]['id'];
		}
	}

	// Fetch an element back
	this.getElementId = function ( element ) {
		return this.elements[element];
	}

	// Work out if this is a valid thing to add to the basket.
	// target and next come from the previous CheckAtt() - I'm pretty sure they
	// could be avoided by better use of an input type="image" and getting the
	// JS out if the way in an onClick
	this.checkAttributes = function ( form, target, next ) {

		// Set the form target 
		if ( target != "" )  {
			form.target = target;
		}
		// Set the hidden field in the form
		if ( next != "" )  {
			form.next.value = next;
		}
		
		// Make sure the combination exists
		// Make sure there are enough of them
		var attributeString = this.chosenAttributeString();
		var quantity = form.qty.value || 1; // sensible default?
		if ( this.validCombination(attributeString) ) {
			return true;
		}
		alert("Please select an available size first from the drop-down menu.");
		return false;
	}

	// Is this a valid attribute combo?
	this.validCombination = function ( attributeString ) {
		if ( attributeString in this.attributeValues )
		{
			return true;
		}
		return false;
	}

}

// Return the subset of a list for which the given expression is true.
// Synonymous to perl's grep.
// http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:filter
if (!Array.prototype.filter) {
	Array.prototype.filter = function ( fun ) {
		var len = this.length;
		if (typeof fun != 'function')
		  throw new TypeError();

		var res = new Array();
		var thisp = arguments[1];

		for ( var i = 0; i < len; i++ ) {
		  if (i in this) {
			var val = this[i]; // in case fun mutates this
			if (fun.call(thisp, val, i, this))
			  res.push(val);
		  }
		}

		return res;
	  };
}


/// ebiz.js

/**
* @fileoverview ebiz.js: A module used for client specific functionality
*
* This module defines a single symbol named "Venda.Ebiz"
* all ebiz utility functions are stored as properties of this namespace
* functions that are spacific this site shoudl be added to this file only.
*/

//Declare namespace for ebiz
Venda.namespace("Ebiz");

/**
* Split a string so it can be displayed on multiple lines so it does not break display layout - used on order confirmation and order receipt page
* @param {string} strToSplit string that needs to be split
* @param {Integer} rowLen length of row which will hold the string
* @param {string} displayElem the html container which will display the splitted string
*/
Venda.Ebiz.splitString = function(strToSplit, rowLen, dispElem) {
	var stringlist = new Array();
	while (strToSplit.length > rowLen) {
		stringlist.push( strToSplit.slice(0,rowLen));
		strToSplit=strToSplit.substr(rowLen);
	}
	if (strToSplit.length) {
		stringlist.push(strToSplit);
	}
		document.getElementById(dispElem).innerHTML = stringlist.join('<br>');
};

/**
* A skeleton function for validating user extened fields - needs to be amended by the build team
* @param {object} frmObj HTML form containing user extended field elements
*/
Venda.Ebiz.validateUserExtendedFields = function(frmObj) {
	if(frmObj) {
		/*if ( (frmObj.usxtexample1.checked==false) && (frmObj.usxtexample2.checked==false) && (frmObj.usxtexample3.checked==false))  {
			alert("Please tick at least one checkbox");
			return false;
		} */
		return true;
	}
	return false;
};


   var feedComcj = new CookieJar({expires:'',path: '/'}); 
           if(Venda.Platform.getUrlParam(window.location.href,'source')!=""){ 
                   var feedComparamValue = Venda.Platform.getUrlParam(window.location.href,'source'); 
                   var feedComCookie = feedComcj.put("source",feedComparamValue); 
           } 
		   


	
/* clear inputs on click */	
function ClearInput(value, id){ // This calls our function ClearInput, and the two variables we will need for it to function the original value and the id.
var input = document.getElementById(id); // Gets the input field based on its id.

if(value == input.value){ // If the default value is equal to the current value.
input.value = ''; // Empty It.
}else{ // Else the value is not equal to the current input field value.
input.value = input.value; // Leave it the same.
} // End Else.
} // Close Function.	

	 