/*IE5.0 ARRAY PROTOTYPE PUSH*/

if(typeof Array.prototype.push==="undefined"){
	Array.prototype.push=function(){
		for(var i=0;i<arguments.length;i++){
			this[this.length+i]=arguments[i];
			return this.length;
		}
	}
}
/* Log-in function */
function checkSubmit() {
	document.frm_login.USER.value=(document.frm_login.USER.value).toLowerCase();
	var username = document.frm_login.USER.value;
	var password = document.frm_login.PASSWORD.value;
	if((username== '') || (password=='')){
		alert('Please enter your user name/password');
		return false;
	}
}
/* BB Speed checker */
function openbbchecker(switchVar)
{
	var switcher = switchVar;
	var name=document.getElementById("adslcheckertext").value;
	if( name == '')
	{
		alert(" No PhoneNumber or PostCode is entered ");
	}
	else
	{
		var s='displayADSLCheckerResults.do?'+'adslcheckertext='+name+'&switch='+switcher;
		var oWin = openPopup(s);
	}  
}
/* NEW BB Speed checker */
function openchecker(myform, windowname)
{
	if (! window.focus)return true;
	
	if($("#lineChecker01").validate().form() || $("#lineChecker02").validate().form())
	{
		// Grey out checker button   
		$(".checkNow").addClass("hidden");
		$(".checkNowGrey").removeClass("hidden");
		setTimeout(function() {
			$(".checkNowGrey").addClass("hidden");
			$(".checkNow").removeClass("hidden");
			}, 10000
		);
	}
  
	if($("#lineChecker01").validate().form())
	{
		window.open('', windowname, 'height=450,width=700,toolbar=no,menubar=no,location=no,scrollbars=yes');
		myform.target=windowname;
		return true;
	}
	if($("#lineChecker02").validate().form())
	{
		window.open('', windowname, 'height=450,width=700,toolbar=no,menubar=no,location=no,scrollbars=yes');
		myform.target=windowname;
		return true;
	}	
}
function PCCompatibleCheckerPopup()
{
	var url=document.getElementById('pccompatiblechecker_popupid').value;	
	openPopup(url);
}
/* Pop-up windows */
function openPopup(href)
{
	var rand="window"+Math.floor(Math.random()*9999999999);
	var newWin = window.open(href,rand,"width=600,height=500,titlebar=no,scrollbars=yes");
	newWin.focus();
	return false;
}
function popup(){
	var els=LBI.Common.fuzzyClassName("a","popup:");
	for (var i=0;i<els.length;i++)	{
		els[i].onclick = function ()
		{
			this.removeAttribute("target");
			var cc=this.className;var cs=cc.substr(cc.indexOf("popup:")+6,cc.length);
			// QAS variant specifically for this process
			if (cs.indexOf("qas")===0) {
				var dma=(cs.substr(4,cs.indexOf(")")-1)).split(",");
				// get fields
				var grandparent=LBI.Common.getParentByTagName(this.parentNode,"div");
				var supp=(grandparent.id==="id_div_sec2")?"_sec2":"";
				window.QAS_opener=(supp==="")?"_sec1":"_sec2";
				var postcode=document.getElementById(window.VF_postcode+supp).value;
				var house=document.getElementById(window.VF_house+supp).value;
				var extras="?postcode="+postcode+"&house="+house;
			}	else	{
				var dma=(cs.substr(1,cs.indexOf(")")-1)).split(",");
				var extras="";
			}
			window.open(this.href+extras,'popupwindow','width='+dma[0]+',height='+dma[1]+',resizable=1,scrollbars=1,true,true');
			return false;
		}
	}
}
/* End Pop-up windows */
/*Input button rollover*/

function addHoverToInputImage(){
	$("input.hasRollOver").hover (
		function(){
			$(this).addClass('hover');
		},
		function(){
			$(this).removeClass('hover');
		}
	);
}

function formClear() {
	var inputFields = $("input:text");
	for (i=0; i<inputFields.length; i++) {
		var thisField = inputFields[i];
		var defaultValue = thisField.value;
		thisField.onfocus = function() {
			if (this.value === this.defaultValue) {
				this.value = "";
			}
		}
		thisField.onblur = function() {
			if (this.value == "") {
				this.value = this.defaultValue;
			}
		}
	}			
};

function detectUserState(){	
	var userState = $("#GlobalNav li.first a").text();
	var loginModule = $(".loginAccount");
	var nonJSModule = $(".nonJSAccount");
	var manageAccount = $(".manageYourAccount");
	
	if (nonJSModule !== null){	
		$(".nonJSAccount").addClass("hidden");
		$(".loginAccount").removeClass("hidden");
	}
	
	if(userState.match("Log out")){
		if(loginModule !== null){
			$(".loginAccount").addClass("hidden");
			$(".logoutAccount").removeClass("hidden");
		}
		
		if(manageAccount.length !== 0){
			$(manageAccount).addClass("hidden");

		}
	}
};


/********** VALIDATION FUNCTIONS**********/
/*
REQUIREMENTS: 
	1) form with form_validator:yes inside the class attribute.
	2) container div or tr with validate(something) or validate_cs(something) as part of class attribute where 'something' is used as a to match the rules contained in the validation hash object validationData() (below).
	3) container div or tr also includes a div with class errorMessageText to write out error message
	4) labels for field elements being validated
	
	EXCEPTIONS:
		A) if no container div is possible, a container div with the validate class and just an errorMessageText div will work (e.g. TalkTime Choose Handset intro)
		B) if the text to be given the error class is not a label, add hasPseudoLabel to container tr's class attribute and give the text container element (p, div or span) with class pseudoLabel)  e.g. Talk Time Company Details "I have been at this address for less than three years"
		C) for activationdate validation, all labels are given error class.
		D) Validation is skipped on fields that are inside divs where display is none.
NEW:
	if exising methods and messages do not meet data to validate:
	I) add the text to be displayed to the list of validation error messages.
	II) add the parameter extracted from the class to valScan's switch(method) cases
	III) if necessary, write additional validation function that calls writeError if the data does not validate and clearError if it does.
*/
/* validation hash object. format is:
	
	this.<ruleName>={
		"errormsg" : <mandatory error message string>,
		"errorMsgAlt" : <optional secondary error message string>,
		"logic" : <mandatory string representing validation logic function, or "n/a" if there is no function>
	}
*/
function validationData() {   
   	this.globalError={
		"errormsg" : "Please ensure all required information is complete. See below for details.",
		"logic" : "n/a"
	}
	this.email={
		"errormsg" : "Please re-enter your email address.",
		"logic" : "valtype_cs_gen_email"
	}
	
	this.name={
		"errormsg" : "Please retype your name.",
		"logic" : "valtype_cs_gen_name"
	}
	
	this.lastname={
		"errormsg" : "Please retype your surname.",
		"logic" : "valtype_cs_gen_name"
	}
	
	this.jobtitle={
		"errormsg" : "Please enter your job title.",
		"logic" : "valtype_cs_gen_name"
	}
	
	this.companyname={
		"errormsg" : "Please enter your company name.",
		"logic" : "valtype_cs_gen_name"
	}
	
	this.postcode={
		"errormsg" : "Please enter a valid UK postcode.",
		"logic" : "valtype_cs_gen_postcode"
	}
	
	this.privacyterms={
		"errormsg" : "Please tick the BT privacy policy box to confirm that you've read, understood and agree to them.",
		"logic" : "valtype_cs_gen_checkbox"
	}
	
	this.BTcustomer={
		"errormsg" : "Please select an option.",
		"logic" : "valtype_cs_gen_radio"
	}
	
	this.companysize={
		"errormsg" : "Please select a value.",
		"logic" : "valtype_cs_gen_selectvalue"
	}
	
	this.title={
		"errormsg" : "Please select a value.",
		"logic" : "valtype_cs_gen_selectvalue"
	}	
	
	this.industrytype={
		"errormsg" : "Please select a value.",
		"logic" : "valtype_cs_gen_selectvalue"
	}
	
	this.comments={
		"errormsg" : "Please enter your comment.",
		"logic" : "valtype_cs_gen_textarea"
	}
}
// create global object
window.validationData=new validationData(); 
//initial validation function, runs on load, sets up functions to run on form submission
function validator() {
	init();
	function init()	{
		el=document.getElementsByTagName("form");
		for (var aVal=0;aVal<el.length;aVal++)	{
			if ((el[aVal].className).indexOf("form_validator:yes")!=-1)	{
				el[aVal].onsubmit = function () {

					LBI.Common.removeNodeById("globalError"); // removes any previous global error message
					var critError=LBI.Common.getFirstInstanceByClassName(this,"div","criticalErrorMessage");
					if (critError)	{
						return false;
					}	else	{
						if (validate(this.id))	{
							return true;
						}	else	{
							if (document.getElementById("globalErrorPlaceholder"))	{
								oGPH=document.getElementById("globalErrorPlaceholder");
								if (oGPH)	{
									oGPH.innerHTML=oGPH.innerHTML+"<span class=\"globalErrorMessage\" id=\"globalError\"><strong>"+window.validationData.globalError.errormsg+"</strong></span>";
									window.scrollTo(0,LBI.Common.getAbsoluteY(document.getElementById("globalError"))-20);
								}
							}
							return false;
						}
					}
				}
			}
		}
	}
}
/* gathers all divs and trs which are tested for validation trigger in the class name.
if there are errors, the page jumps to the first one. */
function validate(id)	{
	var errorFlag=false;
	var formel=document.getElementById(id);
	valScan(formel.getElementsByTagName("div"));
	valScan(formel.getElementsByTagName("tr"));
	return errorFlag?false:true;

	function valScan(el)	{
		for (var aScan=el.length-1;aScan>=0;aScan--)	{
			// validation rules
			if ((el[aScan].className).indexOf("validate(")!=-1 || (el[aScan].className).indexOf("validate_cs(")!=-1)	{
				var oWrapper=el[aScan];
				valData(oWrapper);
				if(method==="novalidation"){
					continue;
				}
				oWrapper.errormsg=eval('window.validationData.'+method+'.errormsg');
				var strLogicFunctionName=eval('window.validationData.'+method+'.logic');
				// execute rule (if rule exists)
				eval(strLogicFunctionName+'(oWrapper)');
			}
		}

		// removes error message div from given oWrapper object, returns boolean with removal status
		function removeError(oWrapper)	{
			return LBI.Common.removeNodeByObj(LBI.Common.getFirstInstanceByClassName(oWrapper,"div","error"));
		}
		//removes specific error message from given ID, returns boolean with removal status
		function removeSpecError(strId)	{
			return LBI.Common.removeNodeById(strId);
		}
	}	
	//extract the type of data expected from the class name
	function valData(oWrapper)	{
		var sp=(oWrapper.className).indexOf("validate_cs(");
		var sstr=(oWrapper.className).substring(sp+12,oWrapper.className.length);
		sstr=sstr.substring(0,sstr.indexOf(")"));
		method=sstr;
	}

/*writeError is called by a valtype_<rule name> function if error condition is true. oWrapper is the wrapping div object.
Each wrapped form line to be validated must have a form element and a corresponding LABEL element, otherwise an error alert will appear. */
function writeError(oWrapper)	{
		errorFlag=true;		
		if ((oWrapper.className).indexOf("error")===-1)	{
			oWrapper.className=oWrapper.className+" error";//MAKES WRAPPER HAVE ERROR CLASS
			var oErrorMsg=LBI.Common.getFirstInstanceByClassName(oWrapper,"div","errorMessageText");
			if (oErrorMsg)	{
				oErrorMsg.innerHTML="<div class=\"error\"><strong>"+oWrapper.errormsg+"</strong></div>";
			}	else	{
				alert("DEVELOPER ERROR: missing error message placeholder\n\n"+oWrapper.className);
			}
			var label=oWrapper.getElementsByTagName("label");
			var inpts=oWrapper.getElementsByTagName("input");
			var noInputs=false;
			if(inpts.length===0 && oWrapper.getElementsByTagName("select").length===0){
				noInputs=true;
			}
			if (label.length>0)	{
				var comp=1;
				for (var aLbl=0;aLbl<comp;aLbl++)	{
					label[aLbl].innerHTML="<span class=\"error\">"+label[aLbl].innerHTML+"</span>";
				}
			}	else	{
				alert("DEVELOPER ERROR: accessibility - all form items must have a label\n\n"+oWrapper.className);
			}

		}
	}

/*clearError is called by a valtype_<rule name> function if error condition is false, or occasionally if the error flag
needs clearing before a series of error checks are made. oWrapper is the wrapping div object.*/
	function clearError(oWrapper)	{
		oWrapper.className=oWrapper.className.replace(" error","");
		var errorMsg=getElementsByClassName(oWrapper,"div","errorMessageText");
		errorMsg[0].innerHTML="<!-- nothing in here -->";
		// refine to nodes based approach
		if (errorMsg[0].outerHTML)	{errorMsg[0].outerHTML='<div class="errorMessageText"></div>';}
		var label=oWrapper.getElementsByTagName("label");
		if (label.length>0)	{
			for (var aErr=0;aErr<label.length;aErr++)	{
				var spanErrs=getElementsByClassName(label[aErr],"span","error");
				if(spanErrs.length===0){continue;}
				label[aErr].innerHTML=((label[aErr].innerHTML).replace(/<span class=\"?error\"?>/i,"")).replace(/<\/span>/i,"");
			}

		}
		var tds=oWrapper.getElementsByTagName("td");
		if (tds.length===5)	{
			if (tds[4].innerHTML !== "") {
				tds[4].style.paddingTop = "5px";
			}
		}
	}
	
	/* VALIDATION LOGIC FUNCTIONS *
		for all functions:
	 	oWrapper is wrapping element of form line. errormsg is now a property of object oWrapper
		All write/clear error message inside oWrapper depending on error condition
		NB: See documentation for full explanation of validation rules for each validation logic function.*/
	function valtype_cs_gen_empty(oWrapper)	{
		LBI.Common.getInputVal(oWrapper)===""?writeError(oWrapper):clearError(oWrapper);
	}
	function valtype_cs_gen_radio(oWrapper)	{
		LBI.Common.getRadioSelected(oWrapper)?clearError(oWrapper):writeError(oWrapper);
	}
	function valtype_cs_gen_checkbox(oWrapper)	{
		LBI.Common.getCheckboxVal(oWrapper)?clearError(oWrapper):writeError(oWrapper);
	}
	function valtype_cs_gen_textarea(oWrapper)	{
		(LBI.Common.getTextareaVal(oWrapper)==="")?writeError(oWrapper):clearError(oWrapper);
	}
	function valtype_cs_gen_name(oWrapper)	{
		var rexp=/^([a-z\-\x80-\xFF]+(. )?[ ']?)+$/i;
		(LBI.Common.getInputVal(oWrapper).search(rexp))?writeError(oWrapper):clearError(oWrapper);
	}
	function valtype_cs_gen_email(oWrapper)	{
		var rexp=/^[a-z[\w\.-]*[a-z0-9]@[a-z0-9][\w\.-]*[a-z0-9]\.[a-z][a-z\.]*[a-z]$/i;
		(LBI.Common.getInputVal(oWrapper).search(rexp))?writeError(oWrapper):clearError(oWrapper);
	}
	function valtype_cs_gen_selectvalue(oWrapper)	{
		var vals=LBI.Common.getSelectVals(oWrapper);
		var orTrig=false;
		for (i=0;i<vals.length;i++)	{
			if (vals[i]==="")	{orTrig=true;}
		}
		(orTrig)?writeError(oWrapper):clearError(oWrapper);
	}
	function valtype_cs_gen_postcode(oWrapper)	{
		var rexp=/(^gir\s0aa$)|(^[a-pr-uwyz]((\d{1,2})|([a-hk-y]\d{1,2})|(\d[a-hjks-uw])|([a-hk-y]\d[abehmnprv-y]))\s?\d[abd-hjlnp-uw-z]{2}$)/i; // optional space in postcode validation
		(LBI.Common.getInputVal(oWrapper).search(rexp))?writeError(oWrapper):clearError(oWrapper);
	}
	/*END VALIDATION LOGIC FUNCTIONS*/
}

/*hiddenParent checks the given object oWrapper for its display state. if it is hidden by either of the two
recognized methods used on this journey then validation will not take place, unless validateHidden is specified (e.g. vas teop add employees)  */
function hiddenParent(oWrapper)	{
	var tagName="div";
	var elM=oWrapper;var burst=11;var found=false;
	while (!found && burst>0)	{
		burst--;
		if (elM.parentNode===undefined || !elM.parentNode.tagName)	{ 
			return false;
		}
		elM=elM.parentNode;
	
		if ((elM.tagName).toLowerCase()===tagName && elM.style.display==="none" || elM.className.indexOf("expandableContentCollapsed")!=-1)	{
			if(elM.className.indexOf("validateHidden")!=-1 || elM.className.indexOf("validateAlways")!=-1){return false;}
			return true;
		}
	}
	return false;
}

function validateParentContent(oWrapper)	{
	var tagName="div";
	var elM=oWrapper;var burst=11;var found=false;
	while (!found && burst>0)	{
		burst--;
		if (elM.parentNode===undefined || !elM.parentNode.tagName)	{ 
			return false;
		}
		elM=elM.parentNode;
	
		if ((elM.tagName).toLowerCase()===tagName && elM.style.display==="none" || elM.className.indexOf("expandableContentCollapsed")!=-1)	{
			if(elM.className.indexOf("validateHidden")!=-1 || elM.className.indexOf("validateAlways")!=-1){return elM;}
			return false;
		}
	}
	return false;
}

/********** END VALIDATION FUNCTIONS**********/
/*########################################################################################################*/
/* SUPPORTING FUNCTIONS */
// returns an array of elements withing the wrapping element oElm, of the tag type strTagName (or wildcard), with the classname strClassName
//UPDATED 2007-08-21, DB. Added in 2 replace commands to escape ( and )
//UPDATED 2008-09-12, TB. Replaced with added xpath and native function use

function getElementsByClassName(oElm, strTagName, strClassName){
	var arrElements = (strTagName === "*" && oElm.all)? oElm.all : oElm.getElementsByTagName(strTagName);
	var arrReturnElements = [];
	strClassName = strClassName.replace(/\-/g, "\\-");
	var oRegExp = new RegExp("(^|\\s)" + strClassName + "(\\s|$)");
	var oElement;
	for(var i=0; i<arrElements.length; i++){
		oElement = arrElements[i];		
		if(oRegExp.test(oElement.className)){
			arrReturnElements.push(oElement);
		}	
	}
	return (arrReturnElements);
}

/* END SUPPORTING FUNCTIONS */
/********** GENERAL DOM FUNCTIONS END **********/

/* LEGACY CODE */

/*LIGHTBOX
	a lightbox is a box of content that sits above the main area, which is usually faded out
	designed as an object because validation needs to access some of its functions.
	setting up the tint bg element at init phase works around a obscure IE bug
	REQUIRED:
		class 'PE_lightBox'  (NB case-sensitive) on the div to become a lightbox, this area must also have an id
		class 'PE_lightboxOpen(id_of_lightbox)' on the anchor that triggers the lightbox if triggered by a link
		class 'PE_lightboxIfInvalid(id_of_lightbox)' on the div with the PE_validate() class if the lightbox is triggered by an invalid field (see validate section comments for further details)
	UPDATE : 12.10.08 
		lightbox will now read if it is to load in a flash video player by reading the format of the href of the link that fires it.
		When this happens it takes the Heading text from the link title and the format from an additional class:
			'F_(large)' or 'F(small)'
		It will also use this information to size the content div to the dimensions selected and the flash will be loaded after the lightbox appears.		
*/
Lightbox = {
	active : 0,
	height: 0,
	init : function(){
		var lightboxes = LBI.Common.fuzzyClassName("div","PE_lightBox");
		var lightboxLinks = LBI.Common.fuzzyClassName("a","PE_lightboxOpen");
		for(var i=0;i<lightboxes.length;i++){
			var lightboxContainer = LBI.Common.getParentByTagName(lightboxes[0],"form");
			if(!lightboxContainer){lightboxContainer = document.getElementById("Page")};
			lightboxes[i].style.visibility = "visible";  //remove styles from IE foc prevention
			//take out of position in HTML and insert at end of page, necessary for placing above the tinted background in IE

			var lightbox = lightboxes[i].parentNode.removeChild(lightboxes[i]);
			lightboxContainer.appendChild(lightbox);
			lightbox.className += " hasJS";
			Lightbox.hideLightbox(lightbox);
			Lightbox.addBoxStyles(lightbox);
			Lightbox.addBoxClose(lightbox);
			Lightbox.closeKey(lightbox);
		}
		Lightbox.active = 0;
		Lightbox.setUpTintBg();
		var hasFlash = false;
		for(var h=0;h<lightboxLinks.length;h++){
			lightboxLinks[h].className = lightboxLinks[h].className.replace("hidden","");
			//Added for flash holder lightboxes generated off a link			
			lightboxLinks[h].onclick=function(){
				hasFlash = (Lightbox.testForFlash(this) === true) ? true : false;				
				var thisLightbox = document.getElementById(LBI.Common.getPEClassInfo(this,"PE_lightboxOpen"));
				//Added for flash holder lightboxes
					if (hasFlash === true) {
						if($(".videoText").length !== 0){
							var videoText = $(".videoText", this).text();
						}
						else{
							var videoText = "";
						}
						
						thisLightbox = Lightbox.createFlashLightbox(this, videoText);					
					}
					if(typeof thisLightbox === "undefined") {
						alert("DEV ERROR: no element with ID specified in link's class");
						return;						
					}
				if(hasFlash === true) {
					Lightbox.showLightbox(thisLightbox, this);
				} else {
					Lightbox.showLightbox(thisLightbox);	
				}
				Lightbox.tintBg();
				return false;
			}
		}		
		//lightbox on page load - this should be the last part of init()
		if(location.hash.indexOf("lightbox_") != -1){
			var thisLightbox = document.getElementById(location.hash.replace("#",""));
			if(!thisLightbox){return;}
			Lightbox.showLightbox(thisLightbox);
			Lightbox.tintBg();
		}
	},
	createFlashLightbox : function(elem_lightboxLink, accessText) {
		var lightboxId = LBI.Common.getPEClassInfo(elem_lightboxLink,"PE_lightboxOpen");
		var lightboxHead = (elem_lightboxLink.href.indexOf(".flv") !== -1) ? elem_lightboxLink.title : "";
		var flashHolder = document.createElement("div");		
		flashHolder.id = lightboxId + "_fla";
		var flashType = LBI.Common.getPEClassInfo(elem_lightboxLink,"F_");		
		flashHolder.style.height = LBI.Data.flashType[flashType].height + "px";
		flashHolder.style.width = LBI.Data.flashType[flashType].width + "px";
		
		var textVideo = document.createTextNode(accessText);
		return Lightbox.create(lightboxHead, flashHolder, lightboxId, elem_lightboxLink, textVideo);

	},
	testForFlash : function(elLink) {
		if((elLink.href.indexOf(".swf") !== -1) || (elLink.href.indexOf(".flv") !== -1)) { 
			return true;
		} else {
			return false;	
		}		
	},
	/*dynamically creates a lightbox.
	takes either a string or node object for headNode and contentNode and a string for id*/
	create: function(headNode,contentNode,id,flashRef, videoTextDesc){
		var lightbox = document.createElement("div");
			lightbox.className = "lightBox PE_lightBox";
			//If no flash, lightbox will exist in markup so build from there

					var i=0;
					while(document.getElementById(id)){
						i++;
						var lastUScore = id.lastIndexOf("_");
						var ind = id.substring(lastUScore+1);
						if(parseInt(ind)){
							id = id.substring(0,lastUScore+1) + i;
						}
						else{
							id = id + "_" + i;
						}
				}

			lightbox.id = id;
		var lightboxHead = document.createElement("div");
			lightboxHead.className = "heading";
			if(typeof(headNode) === "string"){
				headNode = document.createTextNode(headNode);
			}
			lightboxHead.appendChild(headNode);
		var lightboxContent = document.createElement("div");
			lightboxContent.className = "content";
			if(typeof(contentNode) === "string"){
				contentNode = document.createTextNode(contentNode);
			}
		
		var accessibleCont = document.createElement("p");
			accessibleCont.className = "videoText";
			accessibleCont.appendChild(videoTextDesc)
		
		lightboxContent.appendChild(contentNode);
		lightboxContent.appendChild(accessibleCont);
		lightbox.appendChild(lightboxHead);											
		lightbox.appendChild(lightboxContent);							

		lightbox.className += " hasJS";
		Lightbox.hideLightbox(lightbox);
		Lightbox.addBoxStyles(lightbox);
		
		if (flashRef !== undefined) {
			Lightbox.addBoxClose(lightbox, true);
			Lightbox.closeKey(lightbox, true);
			var flashType = LBI.Common.getPEClassInfo(flashRef,"F_");			
			lightbox.style.width = (LBI.Data.flashType[flashType].width + 28) + "px";
			var lightboxTop = getElementsByClassName(lightbox, "div", "lightbox-top")[0];
			var lightboxBase = getElementsByClassName(lightbox, "div", "lightbox-base")[0];			
			lightboxTop.style.width = (LBI.Data.flashType[flashType].width + 12) + "px";
			lightboxBase.style.width = (LBI.Data.flashType[flashType].width + 12) + "px";
		} else { Lightbox.addBoxClose(lightbox);}
		var pageDiv = document.getElementById("Page");
		pageDiv.appendChild(lightbox);
		lightbox.style.visibility = "visible";  //remove styles from IE foc prevention
		return lightbox;
	},
	addBoxStyles : function(elem_lightbox){
		//middle - take all children of lightbox and put them into the boxRight div
		var boxRight = document.createElement("div");
			boxRight.className = "lightbox-right";
		while(elem_lightbox.childNodes.length > 0){			
			boxRight.appendChild(elem_lightbox.lastChild);
		}		
		var boxMain = document.createElement("div");
			boxMain.className = "lightbox-main";
			boxMain.appendChild(boxRight);
		elem_lightbox.appendChild(boxMain);
		//top
		var boxTop = document.createElement("div");
			boxTop.className = "lightbox-top"
		var boxTopLeft = document.createElement("div");
			boxTopLeft.className = "lightbox-top-left";
		var boxTopRight = document.createElement("div");
			boxTopRight.className = "lightbox-top-right";
			boxTopLeft.appendChild(boxTopRight);
			boxTopLeft.appendChild(boxTop);
			elem_lightbox.insertBefore(boxTopLeft,elem_lightbox.firstChild);
		//base
		var boxBase = document.createElement("div");
			boxBase.className = "lightbox-base";
		var boxBaseLeft = document.createElement("div");
			boxBaseLeft.className = "lightbox-base-left";
		var boxBaseRight = document.createElement("div");
			boxBaseRight.className = "lightbox-base-right";
			boxBaseLeft.appendChild(boxBaseRight);
			boxBaseLeft.appendChild(boxBase);
			elem_lightbox.appendChild(boxBaseLeft);
	},
	closeLightbox : function(elem_lightbox, isFlash){
		//Added for flash holder lightboxes generated off a link - element needs to be completely removed as cannot run invisibly
		if(isFlash === true) {
			Lightbox.active--;		
		} else {
			
			Lightbox.rehideLightbox(elem_lightbox);
		}
		if(elem_lightbox.className.indexOf("f(") !== -1) {

			var format = this.getFormat(elem_lightbox);			
			if (LBI.Data.flashType[format].eventOnClose === true) {
				LBI.Data.fireOnEvent[format].off();
			}
		}
		Lightbox.removeTintBg();
		//accessibility aid: refocus on the link or validated field that triggered the lightbox
		var lightboxTrigger = LBI.Common.fuzzyClassName("a","PE_lightboxOpen(" + elem_lightbox.id + ")")[0];
		if(!lightboxTrigger){
			var lightboxDiv = LBI.Common.fuzzyClassName("div","PE_lightboxIfInvalid(" + elem_lightbox.id + ")")[0];
			if(lightboxDiv){lightboxTrigger = lightboxDiv.getElementsByTagName("input")[0];}
		}
		if(lightboxTrigger){lightboxTrigger.focus();}
		if(isFlash === true) {
			LBI.Common.removeNodeByObj(elem_lightbox);			
		}
		return false;
	},
	addBoxClose : function(elem_lightbox, hasFlash){
		var closeLinkTxt = document.createTextNode("Close");
		closeLink = document.createElement("a");
		closeLink.href = "#";
		closeLink.id = "close_" + elem_lightbox.id;
		closeLink.className = "closeBtn clearfix";
		closeLink.appendChild(closeLinkTxt);
		closeLink.onclick = function(){
			if(hasFlash === true) {
				Lightbox.closeLightbox(elem_lightbox, true);				
			} else {
				Lightbox.closeLightbox(elem_lightbox);				
			}
			return false;
		}
		
		var lightboxHeading = getElementsByClassName(elem_lightbox,"*","heading")[0];
		lightboxHeading.insertBefore(closeLink,lightboxHeading.firstChild);
		lightboxHeading.className += " clearfix";
		//accessibility aid: add hidden close at bottom of lightbox
		var closeLinkHidden = document.createElement("a");
			closeLinkHidden.appendChild(document.createTextNode("End of in page popup. Close using this link to return to main content."));
			closeLinkHidden.href = "#";
			closeLinkHidden.className = "hidden";
			closeLinkHidden.onclick = closeLink.onclick;
		elem_lightbox.appendChild(closeLinkHidden);
		elem_lightbox.closeButtons = [closeLink,closeLinkHidden];
		//detect cancel buttons in HTML and use those too
		var cancelLinks = LBI.Common.fuzzyClassNameBlock(elem_lightbox,"a","PE_closeLightbox");
		for(var i=0;i<cancelLinks.length;i++){
			cancelLinks[i].onclick = closeLink.onclick;
			elem_lightbox.closeButtons.push(cancelLinks[i]);
		}
	return false;		
	},
	
	closeKey: function(elem_lightbox, hasFlash){
		document.onkeydown = function(e){   
			if (e == null) { // ie
			  keycode = event.keyCode;
			} else { // mozilla
			  keycode = e.which;
			}
			if(keycode == 27){ // close
			  if(hasFlash === true) {
					Lightbox.closeLightbox(elem_lightbox, true);
					//Lightbox.hideLightbox(elem_lightbox);
				} else {
					Lightbox.closeLightbox(elem_lightbox);
					var lightboxes = $(".lightBox");
					
					for (i=0; i<lightboxes.length ;  i++ ){
						$(lightboxes[i]).removeClass("hideLightbox");
						$(lightboxes[i]).addClass("hideLightbox");
					}
				}						
			}  
		}
	 },

	setUpTintBg : function(){
		/*@cc_on @*/
		/*@if (@_jscript_version < 5.6)
			return; // impossible in IE5
		/*@end @*/
		var pageDiv = document.getElementById("Page");
		var tint = document.createElement("div");
		tint.className = "tintedBg";
		pageDiv.insertBefore(tint,pageDiv.firstChild);
	},


	tintBg : function(){
		if(Lightbox.hasCSS() === false){return;}
		var tint = getElementsByClassName(document,"div","tintedBg")[0];
		if(!tint){return;}
		tint.style.height = "0px";
		var pageDimensions = LBI.Common.getFullPageDimensions();
		var newWidth = pageDimensions[0];
		var newHeight = pageDimensions[1];
		if(Lightbox.height > newHeight){
			tint.style.height = Lightbox.height +"px";
		}
		else{
			tint.style.height = newHeight +"px";
		}
		tint.style.width = newWidth +"px";
	},
	removeTintBg : function(){
		if(Lightbox.active > 0){return;}
		var tint = getElementsByClassName(document,"div","tintedBg")[0];
		if(!tint){return;}
		tint.style.width = "0px";
		tint.style.height = "0px";
	},
	showLightbox : function(elem_lightbox, flashRef){		
		if(LBI.Common.isLtIE7 === true){
			Lightbox.hideSelects(elem_lightbox); //hide select boxes due to buggy IE6 handling of them
		}
		if(elem_lightbox.className.indexOf("f(") !== -1) {
			var format = this.getFormat(elem_lightbox);
			if (LBI.Data.flashType[format].addAsClass !== -1 && LBI.Data.flashType[format].addAsClass === true) {
				elem_lightbox.className += " " + format;
			}
			if (LBI.Data.flashType[format].eventOnOpen === true) {
				LBI.Data.fireOnEvent[format].on();
			}
		}		
		elem_lightbox.className = elem_lightbox.className.replace(/ hideLightbox/g,"");
		//set the lightbox in the vertical center of the page, account for relatively-positioned parents
		// if the lightbox is bigger than the viewport, set its top to the top of the viewable screen
		var viewPortCenter = Math.round(LBI.Common.getViewPortHeight() / 2);
		var viewPortMiddle = Math.round(LBI.Common.getViewPortWidth() / 2);		
		var scrolledTop = LBI.Common.getScrollTop();
		var userViewCenter = parseInt(viewPortCenter) + parseInt(scrolledTop);
		var userViewMiddle = parseInt(viewPortMiddle);		
		var lightboxCenter = elem_lightbox.offsetHeight / 2;
		var lightboxMiddle = elem_lightbox.offsetWidth / 2;
		var lightboxRelativeTop = 0;			
		var lightboxRelativeLeft = -170;		
		var parent = elem_lightbox.parentNode;
		while(parent){
			if(parent.nodeName==="#document"){break;}
			if(LBI.Common.getStyle(parent,"position") === "relative"){
				lightboxRelativeTop += parent.offsetTop;
			}
			parent = parent.parentNode;
		}
		if(LBI.Common.getViewPortHeight() < elem_lightbox.offsetHeight){
			elem_lightbox.style.top = scrolledTop - lightboxRelativeTop + "px";
		}
		else{
			elem_lightbox.style.top = userViewCenter - lightboxCenter - lightboxRelativeTop + "px";			
		}		
		elem_lightbox.style.left = userViewMiddle - lightboxMiddle - lightboxRelativeLeft + "px";
		Lightbox.active++;
		Lightbox.height = parseInt(elem_lightbox.offsetHeight) + parseInt(elem_lightbox.offsetTop);
		//accessibility aid: send cursor to close button on the lightbox
		var closebtn = document.getElementById("close_" + elem_lightbox.id);
		var hiddenFocusLink = document.getElementById("hiddenFocus_" + elem_lightbox.id);
		if(!hiddenFocusLink){
			var hiddenFocusLink = document.createElement("a");
				hiddenFocusLink.href = "#";
				hiddenFocusLink.onclick = function(){return false;}
				hiddenFocusLink.id = "hiddenFocus_" + elem_lightbox.id;
				hiddenFocusLink.appendChild(document.createTextNode("In page pop-up layer.  Use close links to return to main content."));
			closebtn.parentNode.insertBefore(hiddenFocusLink,closebtn);
		}
		hiddenFocusLink.focus();	
		hiddenFocusLink.className = "hidden";
		if(flashRef !== undefined) {
			this.createFlashFromElm(elem_lightbox, flashRef);				
		}	
	
	},
	createFlashFromElm : function(elem_lightbox, linkElm) {
		var flashId = elem_lightbox.id + "_fla";					
		var flashType = LBI.Common.getPEClassInfo(linkElm,"F_");
		var height = LBI.Data.flashType[flashType].height + "px";
		var width = LBI.Data.flashType[flashType].width + "px";	
		var flashvars = {};
		if (linkElm.href.indexOf(".flv") !== -1) {
			flashvars.videoSource = linkElm.href;
			swfobject.embedSWF(LBI.Data.flashPlayer, flashId, width, height, "9.0.0", "expressInstall.swf", flashvars, LBI.Data.videoOptions.params, LBI.Data.videoOptions.attributes);
		} else {
			var flashFile = linkElm.href;
			swfobject.embedSWF(flashFile, flashId, width, height, "9.0.0", "expressInstall.swf");
		}
	},
	hideLightbox : function(elem_lightbox){
		if(LBI.Common.isLtIE7 === true){
			Lightbox.showSelects();
		}
		elem_lightbox.className += " hideLightbox";
		var hiddenFocusLink = document.getElementById("hiddenFocus_" + elem_lightbox.id);
		if(hiddenFocusLink){hiddenFocusLink.className = hiddenFocusLink.className.replace("hidden","");}
	},
	rehideLightbox : function(elem_lightbox){
		Lightbox.hideLightbox(elem_lightbox);
		Lightbox.active--;
	},
	//one for set up, one for show/hide
	//hide select boxes due to buggy IE<7 handling of them
	hideSelects : function(){
		var selects = document.getElementsByTagName("select");
		for(var i=0;i<selects.length;i++){
			selects[i].style.visibility = "hidden";
		}
	},
	showSelects : function(){
		var selects = document.getElementsByTagName("select");
		for(var i=0;i<selects.length;i++){
			selects[i].style.visibility = "visible";
		}
	},
	hasCSS : function(){
		var tintedBg = getElementsByClassName(document.body,"div","tintedBg")[0];
		if(LBI.Common.getStyle(tintedBg,"position") != "absolute"){
			return false;
		}
		return true;
	},
	getFormat : function(elem_lightbox) {
		var format = LBI.Common.getPEClassInfo(elem_lightbox,"f");
		if (format !== undefined) {
			if (LBI.Data.flashType[format].height !== undefined) {
				elem_lightbox.style.height = LBI.Data.flashType[format].height + "px";
			}
			if (LBI.Data.flashType[format].width !== undefined) {
				elem_lightbox.style.width = LBI.Data.flashType[format].width + "px";
			}
		}
		return format;
	}
}

/*PNG handling for inline images
based on supersleight.js
Edits:	took off setting for position relative on links
		Added a pngsToIgnore object to the Data object - png fix checks it for each object so we can use png8's (which don't need filtering)
*/
function pngHandling(wrapper){
var supersleight=function(){var root=wrapper;var applyPositioning=true;var shim=LBI.Data.pngFixPath + 't.gif';var shim_pattern=/t\.gif$/i;var fnLoadPngs = function(){if (root) {root = document.getElementById(root);}else {root = document;}if (!root) {return;}for (var i = root.all.length - 1, obj = null; (obj = root.all[i]); i--) {if(LBI.Data.pngsToIgnore.check(obj) === false) {if (obj.currentStyle.backgroundImage.match(/\.png/i) !== null) {bg_fnFixPng(obj);}if (obj.tagName === 'IMG' && obj.src.match(/\.png$/i) !== null) {el_fnFixPng(obj);if (applyPositioning && (obj.tagName === 'A' || obj.tagName === 'INPUT') && obj.style.position === '') {obj.style.position = 'relative';}}}}};var bg_fnFixPng=function(obj){var mode='scale';var bg=obj.currentStyle.backgroundImage;var src=bg.substring(5,bg.length-2);if(obj.currentStyle.backgroundRepeat==='no-repeat'){mode='crop';}
obj.style.filter="progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+src+"', sizingMethod='"+mode+"')";obj.style.backgroundImage='url('+shim+')';};var el_fnFixPng=function(img){var src=img.src;img.style.width=img.width+"px";img.style.height=img.height+"px";img.style.filter="progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+src+"', sizingMethod='scale')";img.src=shim;};return{init:function(){fnLoadPngs();},run:function(){fnLoadPngs();},limitTo:function(el){root=el;}};}();
if(LBI.Common.isLtIE7 === true){
	supersleight.init();
	}
}


//finds all inputs and adds a hover class when rolled over
function setupInputHover() {

	var inputs = document.getElementsByTagName("input");

	for (var i = 0; i < inputs.length; i++) {
		inputs[i].onmouseover = function() {
			this.className += " hover";
		}
		inputs[i].onmouseout = function() {
			this.className = this.className.replace("hover","");
		}
	}	

}

LBI = {};

LBI.Data = {
	bunCompareXML : "/consumer/consumerProducts/js/bundling/",
	bbCompareXML : "/consumer/consumerProducts/js/internet/",
	tariffsXML : "/consumer/consumerProducts/js/home_phone_services/",
	dsoXML : "/consumer/consumerProducts/js/entertainment/",
	jsonPath : "/consumer/consumerProducts/js/entertainment/",
	libPath : "/consumer/consumerProducts/images/products_and_services/entertainment/",
	commonImgPath : "/consumer/consumerProducts/common/products_and_services/",
	visionImgPath : "/consumer/consumerProducts/images/products_and_services/entertainment/",
	bundlingImgPath : "/consumer/consumerProducts/images/products_and_services/bundling/",
	pngFixPath : "/consumer/consumerProducts/common/products_and_services/",
	videoWidth : 640,
	extSrcExt : ".js",
	flashPath : "/consumer/consumerProducts/flash/entertainment/",
	videoPath : "/consumer/consumerProducts/flash/entertainment/videos/",
	flashPlayer : "/consumer/consumerProducts/flash/entertainment/BTVideoPlayer.swf",
	flashPlayerNew : "/consumer/consumerProducts/flash/entertainment/BTVideoPlayer_new.swf",
	flashPlayer01 : "/consumer/consumerProducts/flash/entertainment/BTVideoPlayer_01.swf",
	interactiveDemo : "http://www.productsandservices.bt.com/consumer/consumerProducts/flash/vision_demo/index.html",
	flashExt : ".swf",
	menuSections : ["packages", "phone", "bb", "vision"],
	flashType : {
		large : {
			height : 480,
			width : 640
		},
		small : {
			height : 360,
			width : 640
		},		
		tiny : {
			height : 240,
			width : 400,
			addAsClass : true
		},
		overview : {
			width : 967,
			addAsClass : true,
			eventOnOpen : true,
			eventOnClose : true
		},
		homehub : {
			height : 553,
			width :  940,
			addClass : true
		},
		visionHub : {
			height : 270,
			width :  480
		},
		mainBanner : {
			height : 290,
			width :  978
		},
		inPageFlashAnim : {
			height : 280,
			width :  620
		},		
		infinityDemo : {
			height : 390,
			width :  600
		}
	},
	videoOptions : {
		params : {allowScriptAccess : "sameDomain"},
		attributes : null
	},
	pageVideoOptions : {
		params : {allowScriptAccess : "sameDomain", wmode: "transparent", allowFullScreen: "true"},
		attributes : null
	},
	pageSWFOptions : {
		params : {allowScriptAccess : "sameDomain", wmode: "transparent"},
		attributes : null
	},
	flashDimensions: {
		Reviews: {
			height: "91",
			width: "250",
			params: {
				wmode: "Transparent"
			}
		},
		Preview: {
			height: "168",
			width: "300",
			params: {
				wmode: "Transparent"
			}
		},
		ball: {
			height: "310",
			width: "940"
		},
		bthomepageanim: {
			height: "254",
			width: "978",
			flashVars: {
				videoURL: "http://172.27.64.38/consumer/consumerProducts/flash/entertainment/videos/BT_vision.flv",
				videoXPos: "20",
				videoYPos: "4",
				swfURL: "http://172.27.64.38/consumer/consumerProducts/flash/entertainment/swf/homepageAnim.swf",
				swfXPos: "120",
				swfYPos: "38",
				imgStartURL: "http://172.27.64.38/consumer/consumerProducts/images/products_and_services/entertainment/start_screen.jpg",
				imgCompleteURL: "http://172.27.64.38/consumer/consumerProducts/images/products_and_services/entertainment/end_screen.jpg"
			},
			expressInstall: "expressInstall.swf"
		}
	},
	pngsToIgnore: {
		list: [],
		add: function(elmIgnore){
			this.list.push(elmIgnore);
		},
		check: function(elmToCheck){
			var noMatches = 0;
			for (var a = 0, b = this.list.length; a < b; a++) {
				if (this.list[a] === elmToCheck) {
					noMatches = noMatches + 1;
				} 				
			}
			if (noMatches === 0) {
				return false;
			} else {
				return true;
			}
		}
	},
	fireOnEvent : {
		overview : {
			on : function(){
				LBI.Custom.PEList.PE_sequencer.instLib[0].freezeAnim();
			},
			off : function() {
				LBI.Custom.PEList.PE_sequencer.instLib[0].restartAnim();
			}
		}
	}
}

LBI.Custom = {
	inits: {		/* This is for the non-namespaced functions. */
		/* all class-based ones are initiated separately */
	},
	setup: function(){
		var names = [];
		var nameCount = 0;
		for (var strPEName in LBI.Custom.PEList) {
			names[nameCount] = strPEName;
			nameCount++;
		}
		var nameNum = names.length;
		for (var x = (nameNum - 1); x >= 0; x--) {
			var instNum = LBI.Custom.PEList[names[x]].instLib.length;
			for (var a = 0; a < instNum; a++) {
				if (this.PEList[names[x]].instLib[a].init !== undefined) {
					this.PEList[names[x]].instLib[a].init();
					
				}
			}
		}
		/* With this looping structure, there is no order to the methods called by PEName
		 * If important, this was need to be addressed with a traditional for loop
		 * Edit 20/11/08: load order was important so put the class inits into an array an reversed
		 * through it to fire them as the classes that needed to be fired first were going last.
		 * The correct solution long-term is to search the DOM branch by branch to the furthest branches, using that
		 * to sort the load order into those deepest in the hierachy being fired first
		 */
		/* Run non-namespaced functions inits */
		for (var methName in this.inits) {
			this.inits[methName]();
		}
	},
	
	PERoundUp: function(){
		var arrTmpList = LBI.Common.fuzzyClassName("*", "PE_"); // get each PE_ classed element
		var exists = false;
		LBI.Custom.PEList = [];
		
		for (var a = 0, b = arrTmpList.length; a < b; a++) {
		
			var arrClasses = arrTmpList[a].className.split(" ");
			
			for (var c = 0, d = arrClasses.length; c < d; c++) { // go through classes in className
				if (arrClasses[c].indexOf("PE_") !== -1) {
					var strPEName = LBI.Common.getPEName(arrClasses[c]);
					exists = false;
					for (var name in LBI.Custom.PEList) { // check to see if in PEList
						if (name === strPEName) {
							exists = true
						}
					}
					if (exists === false) { // add if not
						if (LBI.Custom.classLib[strPEName]) { // see if it has a class
							var oInst = LBI.Common.createPE(arrTmpList[a], 0, strPEName);
							LBI.Custom.PEList[strPEName] = {
								name: strPEName,
								instLib: [oInst]
							};
						}
						else {
							//alert(strPEName+" has no constructor"); Commented out for PE_lightbox
							continue;
						}
						
					}
					else {
						if (LBI.Custom.classLib[strPEName] !== undefined) {
							var idx = (LBI.Custom.PEList[strPEName].instLib.length);
							var oInst = LBI.Common.createPE(arrTmpList[a], idx, strPEName);
							LBI.Custom.PEList[strPEName].instLib.push(oInst);
						}
					}
				}
			}
		}
	},
	classLib: {
		base: function(oCore, intIdx){
			this.oCore = oCore;
			this.intIdx = intIdx;
			this.getMembers = function(){
				var intClassNo = this.arrMembers.length;
				for (var x = 0; x < intClassNo; x++) {
					this[this.arrMembers[x]] = getElementsByClassName(this.oCore, "*", this.arrMembers[x]);
				}
			};
		},
		/* Definitions:
		 * area : a tab containing product area-specific content
		 * tab : the coloured tab behind a selected area
		 * backing : the backing to an active area - moves to the current area during the animation
		 * zIndex(on or off) : used on hero sections to allow user access post animation
		 */
		PE_sequencer: {
			arrMembers: ['heros', 'area', 'tabHolder', 'areaHolder', 'tabBacking', 'iconLink'],
			delay: 2000,
			heroFadeTime: 2000,
			fadeFrames: 7,
			rapidTime: 1000,
			rapidFrames: 3,
			zIndexOn: 10,
			zIndexOff: 1,
			/*animComplete: {
				'list' : {
					'hero': false,
					'tab': false
				}
			},*/
			animTabState: null,
			tabAreaEntered: null,
			intAreaWidth: 235,
			arrTabPos: [0, -940, -1880, -2820],
			arrBackingPos: [19, 254, 489, 724],
			heroLeftPos : "0px",
			animCounter : 0,
			tabOpacity : 1,
			iconOpacity : 0,
			checkOnStart: function(){
				//The CSS values checked on the area to ensure it matches the hero displayed
				var requiredValues = {
					iconOpacity: 0,
					backingPos: this.arrBackingPos[0]
				}
				var backingPos = LBI.Common.getStyle(this.tabBacking[0], 'left');
				var startValues = {
					iconOpacity: parseInt(LBI.Common.objOpacity.get(this.elmCurrentIcon), 10),
					backingPos: parseInt(backingPos, 10)
				}
				var flag = true;
				var builder = 0;
				for (var item in requiredValues) {	
					if (requiredValues[item] !== startValues[item]) {
						flag = false;
					}
				}
				return flag;
			},
			init: function(){
				/*
				var arrIE6TabPos = [-470, -235, 0, 235];
				if (LBI.Common.isLtIE7 === true) {
					this.arrBackingPos = arrIE6TabPos;

					this.heroLeftPos = "-489px";
				}
				*/
				for(var a = 0, b = this.iconLink.length; a < b; a++) {
					LBI.Data.pngsToIgnore.add(this.iconLink[a]);					
				}
				this.setUpEvents();
				this.intNextIdx = 1;
				this.animComplete.instObj = this;
				var heroOk = this.setUpHero();
				var areasOk = this.setUpAreas();
				var instObj = this;				
				var begin = function(){
					instObj.swapHero();
					instObj.hideTab(false, 'start up');
				}
				if (areasOk === true && heroOk) {
					instObj.delayedAnim = window.setTimeout(begin, this.delay);
				}
			},
			setUpHero: function(){
				for (var a = 0, b = this.heros.length; a < b; a++) {
					var leftStyle = parseInt(LBI.Common.getStyle(this.heros[a], 'left'));
					if (leftStyle === 0 || leftStyle === -489) {
						this.intCurrentIdx = a;
						this.heros[this.intCurrentIdx].style.zIndex = "10";
						return true;
					}
					else {
						return false;
					}
				}
			},
			setUpAreas: function(){
				this.elmCurrentArea = this.area[this.intCurrentIdx];
				this.elmCurrentIcon = this.iconLink[this.intCurrentIdx];
				if (this.checkOnStart() === true) { //animation should only occur if backing is set up correctly & 
					return true;
				}
				else {
					return false;
				}
			},
			setUpEvents: function(){
				if (this.arrAreaPos === undefined) {
					this.scrollTop = document.documentElement.scrollTop; // grid matches cursor position only when screen is at a held scroll position
					this.findAreaPos();
				}
				/*
				 * On mousemove the cursor position is checked to see if it is within the interface area.
				 * If not, any animations relating to previous interactions are cleared.
				 * If so, the area it's over is checked and cached. If it's the same as the last cache nothing happens.
				 * If it's a different area, a delayed animation is started
				 */
				document.body.onmousemove = function(idx){
					return (function(oEvent){
						var instObj = LBI.Common.getPEObj(idx, "PE_sequencer");
						oEvent = LBI.Common.readEvent(oEvent, 'eventObj');
						var oldInBounds = instObj.inBounds;
						instObj.inBounds = instObj.checkInBounds(oEvent);
						if (instObj.inBounds === true) {
							var areaNo = instObj.getAreaNo(oEvent);
							if (instObj.intOverArea === undefined || (areaNo !== instObj.intOverArea)) {
								if (instObj.delayedTabOver !== undefined) {
									window.clearTimeout(instObj.delayedTabOver);
								}
								var fireGoToTab = function(){
									instObj.markArea(areaNo);
								}
								instObj.delayedTabOver = window.setTimeout(fireGoToTab, 50);
							}
							instObj.isUserControlled = true; //object flag to set that user is now controlling changes so anim is stopped
							instObj.intOverArea = areaNo; // intOverArea caches the last areaNo
						}
						else {
							if (instObj.delayedTabOver !== undefined) {
								window.clearTimeout(instObj.delayedTabOver);
							}
							if(instObj.inBounds !== oldInBounds) {
								if((instObj.animTabState !== undefined) && (instObj.animTabState === 'static')) {
									//instObj.animComplete.update('outOfBounds');//TODO
								}
							}
						}
					});
				}(this.intIdx);
			},
			freezeAnim : function() {
				this.restartAnim.cursorCache = document.body.onmousemove;
				document.body.onmousemove = null;
				return;
				/*window.clearTimeout(this.delayedTabOver);
				window.clearTimeout(this.delayedAnim);
				var anims = this.heros;
				anims.tabBacking = this.tabBacking[0];
				LBI.Common.stopAnim(anims);
				if(this.animTabState === 'static') {
					var activeIdx = this.intCurrentIdx;
				} else {
					var activeIdx = this.intNextIdx;
				}
				var activeIdx = this.intCurrentIdx;
				LBI.Common.objOpacity.set(this.iconLink[activeIdx], 0);
				LBI.Common.objOpacity.set(this.tabHolder[0], 1);
				this.tabHolder[0].style.backgroundPosition = this.arrTabPos[activeIdx] + 'px 2px';
				this.tabBacking[0].style.left = this.arrBackingPos[activeIdx] + 'px';
				for(var a = 0, b = this.heros.length; a < b; a++) {
					LBI.Common.objOpacity.set(this.heros[a], 0);
					this.heros[a].style.left = "-9999em";
					this.heros[a].style.zIndex = this.zIndexOff;							
				}*/
				
			},
			
			restartAnim : function() {	
				document.body.onmousemove = this.restartAnim.cursorCache;
				return;
				/*LBI.Common.objOpacity.set(this.heros[this.intNextIdx], 1);
				this.heros[this.intNextIdx].style.left = this.heroLeftPos;
				this.heros[this.intNextIdx].style.zIndex = this.zIndexOn;
				if(this.inBounds === false) {
					this.intCurrentIdx = this.intNextIdx - 1;
					this.animCounter = 0;
					this.tabOpacity = 1;
					this.iconOpacity = 0;
					this.animComplete.update('outOfBounds');		//restarts anims, but also increments			
				}*/
										
			},
			markArea: function(areaIdx){
				if (this.inBounds === false) {
					return;
				}
				this.activeArea = areaIdx;
				if(this.animTabState === 'static') {
					this.goToArea();
				}
			},
			animComplete : {
				list : {'hero' : false, 'tab' : false},
				add : function(anim) {
					this.list[anim] = true;
				},
				reset : function() {
					var list = this.list;
					for (animType in list) {
						list[animType] = false;
					}
				},
				update : function(from) {
					instObj = this.instObj;
					var flag = true;
					//check all flags in list are true
					for (var animPart in instObj.animComplete.list) {
						if (flag === true && instObj.animComplete.list[animPart] === true) {
							flag = instObj.animComplete.list[animPart];
						}
						else {
							flag = false;
						}
					}
					//now run repeat animation once you're out of the area
					if ((flag === true) || (from === "outOfBounds")) {
						instObj.animTabState = 'static';
						instObj.intCurrentIdx = instObj.intNextIdx;
						if((instObj.inBounds === true)) {
							if((instObj.activeArea !== undefined) && (instObj.activeArea !== instObj.intCurrentIdx)) {							
								instObj.goToArea();
							}
						} else {
							instObj.repeatAnim(from);
						}
					}					
				}
			},
			goToArea : function() {
				this.intNextIdx = this.activeArea;
				this.hideTab(true);
				this.swapHero(true);
				this.animComplete.reset();										
			},
			//makes the anim loop
			repeatAnim: function(from){	
				var instObj = this;
				if(instObj.isUserControlled === true){//stop animation after user gains control
					return;
				}
				instObj.intNextIdx = (instObj.intCurrentIdx === instObj.heros.length - 1) ? 0 : (instObj.intCurrentIdx + 1);
				if(from === 'outOfBounds') {
					var time = 4000;
				} else {
					var time = 2000;
				}
				var runAgain = function(){					
					instObj.swapHero(false);					
					instObj.hideTab(false);
				}							
				instObj.delayedAnim = window.setTimeout(runAgain, 4000);					
				instObj.animComplete.reset();
			},			
			hideTab: function(rapidTime, from){		
				var runTime = this.getRTime(rapidTime);
				var frames = (rapidTime === false) ? this.fadeFrames : this.rapidFrames;
				var instObj = this;
				var callback = function(){
					instObj.slideBacking(instObj, rapidTime, 'callback of hideTab');
				}
				var timeUnit = runTime / frames;
				var opacUnit = Math.ceil(100 * (1 / frames)) / 100;

				window.clearTimeout(instObj.delayedAnim);
				var fadeOutTab = function(){					
					instObj.animCounter++;
					if (instObj.animCounter > frames) {
						instObj.animCounter = 0;
						LBI.Common.objOpacity.set(instObj.iconLink[instObj.intCurrentIdx], 1);
						LBI.Common.objOpacity.set(instObj.tabHolder[0], 0);
						instObj.tabOpacity = 0;
						instObj.iconOpacity = 1;
						window.clearTimeout(instObj.delayedAnim);
						return callback();
					}					
					instObj.iconOpacity = LBI.Common.addDecimal({
						item1: instObj.iconOpacity,
						item2: opacUnit,
						action: 'add',
						places: 2
					});
					instObj.tabOpacity = LBI.Common.addDecimal({						
						item1: instObj.tabOpacity,
						item2: opacUnit,
						action: 'subtract',
						places: 2
					});
					LBI.Common.objOpacity.set(instObj.tabHolder[0], instObj.tabOpacity);
					LBI.Common.objOpacity.set(instObj.iconLink[instObj.intCurrentIdx], instObj.iconOpacity);
					instObj.delayedAnim = window.setTimeout(fadeOutTab, timeUnit);				
				}
				fadeOutTab();
				this.animTabState = 'fadeOut';
			},
			slideBacking: function(instObj, rapidTime, from){
				var runTime = instObj.getRTime(rapidTime);
				var callback = function(){
					instObj.tabHolder[0].style.backgroundPosition = instObj.arrTabPos[instObj.intNextIdx] + 'px 2px';
					instObj.showTab(instObj, rapidTime);
				}
				var slideBackingOpt = {
					time: runTime,
					tween: 'swing',
					style: {
						'left': instObj.arrBackingPos[instObj.intNextIdx] + "px"
					},
					callback: true
				}
				LBI.Common.applyAnim(instObj.tabBacking[0], callback, true, slideBackingOpt);
				instObj.animTabState = 'slide';
			},
			showTab: function(instObj, rapidTime){
				var runTime = instObj.getRTime(rapidTime);
				var instObj = this;
				var callback = function(){
					instObj.animComplete.add('tab');
					instObj.animCounter = 0;																	
					instObj.animComplete.update();//TODO
				}
				var frames = (rapidTime === false) ? this.fadeFrames : this.rapidFrames;
				var tabOpacity = 0;
				var iconOpacity = 1;
				var timeUnit = runTime / frames;
				var opacUnit = Math.ceil(100 * (1 / frames)) / 100;				
				window.clearTimeout(instObj.delayedAnim);
				var fadeInTab = function(){
					instObj.animCounter++;					
					if (instObj.animCounter > frames) {
						window.clearTimeout(instObj.delayedAnim);						
						LBI.Common.objOpacity.set(instObj.iconLink[instObj.intNextIdx], 0);
						LBI.Common.objOpacity.set(instObj.tabHolder[0], 1);
						instObj.tabOpacity = 1;
						instObj.iconOpacity = 0;						
						return callback();
					}
					instObj.iconOpacity = LBI.Common.addDecimal({
						item1: instObj.iconOpacity,
						item2: opacUnit,
						action: 'subtract',
						places: 2
					});
					instObj.tabOpacity = LBI.Common.addDecimal({						
						item1: instObj.tabOpacity,
						item2: opacUnit,
						action: 'add',
						places: 2
					});
					LBI.Common.objOpacity.set(instObj.tabHolder[0], instObj.tabOpacity);
					LBI.Common.objOpacity.set(instObj.iconLink[instObj.intNextIdx], instObj.iconOpacity);
					instObj.delayedAnim = window.setTimeout(fadeInTab, timeUnit);
				}
				fadeInTab();
				instObj.animTabState = 'fadeIn';
			},
			getRTime: function(rapidTime){
				if (rapidTime === true) {
					return Math.ceil(this.rapidTime / 3);
				}
				else {
					if (this.areaAnimTime === undefined) {
						this.areaAnimTime = Math.ceil(this.heroFadeTime / 3);
					}
					return this.areaAnimTime;
				}
			},
			swapHero: function(rapidTime){
				var timeType = (rapidTime === undefined) ? this.heroFadeTime : this.rapidTime;
				this.heros[this.intNextIdx].style.left = this.heroLeftPos;
				LBI.Common.objOpacity.set(this.heros[this.intNextIdx], 1);
				var animOpt = {
					time: timeType * 1.5,
					tween: 'swing',
					style: {
						'opacity': 0
					},
					callback: true
				}
				var instObj = this;
				var callback = function(){
					instObj.heros[instObj.intCurrentIdx].style.left = "-9999em";
					instObj.heros[instObj.intCurrentIdx].style.zIndex = instObj.zIndexOff;
					instObj.heros[instObj.intNextIdx].style.zIndex = instObj.zIndexOn;					
					instObj.animComplete.add("hero");
					instObj.animComplete.update();//TODO
				}
				LBI.Common.applyAnim(instObj.heros[instObj.intCurrentIdx], callback, true, animOpt);
			},
			findAreaPos: function(){
				var holderPosX = LBI.Common.getAbsoluteX(this.tabHolder[0]);
				var holderPosY = (LBI.Common.getAbsoluteY(this.tabHolder[0]) - this.scrollTop);
				var start = holderPosX;
				this.arrAreaPos = [start + this.intAreaWidth, start + (this.intAreaWidth * 2), start + (this.intAreaWidth * 3), start + (this.intAreaWidth * 4)];
				this.arrAreaBounds = [holderPosY, (holderPosY + this.tabHolder[0].offsetHeight)];
			},
			getAreaNo: function(eventObj){
				var isInBounds = this.checkInBounds(eventObj);
				if (isInBounds === false) {
					return undefined;
				};
				var cursorPos = eventObj.clientX;
				var start = (this.arrAreaPos[0] - this.intAreaWidth);
				if (cursorPos > start) {
					for (var a = 0, b = this.arrAreaPos.length; a < b; a++) {
						if (cursorPos < this.arrAreaPos[a]) {
							return a;
						}
					}
				}
			},
			checkInBounds: function(eventObj){
				var cursorY = eventObj.clientY;
				var cursorX = eventObj.clientX;
				if(this.scrollTop !== document.documentElement.scrollTop) { 
					this.scrollTop = document.documentElement.scrollTop
					this.findAreaPos(); 
				}
				if ((cursorY < this.arrAreaBounds[0]) || (cursorY > this.arrAreaBounds[1])) {
					return false;
				}
				else 
					if ((cursorX < (this.arrAreaPos[0] - this.intAreaWidth)) || (cursorX > this.arrAreaPos[this.arrAreaPos.length - 1])) {
						return false;
					}
					else {
						return true;
					}
			}
		},
		PE_tooltip: {
			arrMembers: ['tipText'],
			init: function(){
				this.tipText[0].className += " hidden";
				this.oCore.onmouseover = function(idx){
					return (function(oEvent){
						LBI.Common.getPEObj(idx, "PE_tooltip").setup(oEvent);
					});
				}(this.intIdx);
				this.oCore.onmouseout = function(idx){
					return (function(oEvent){
						LBI.Common.getPEObj(idx, "PE_tooltip").cleanUp(oEvent);
					});
				}(this.intIdx);
			},
			
			setup: function(oEvent){
				var instObj = this;
				var oEvent = LBI.Common.readEvent(oEvent, "eventObj");
				var target = LBI.Common.readEvent(oEvent, "target");
				var ttBubble = document.getElementById("tooltipBubble");
				if (ttBubble === null) {
					ttBubble = instObj.createTT();
					LBI.Custom.PEList["PE_tooltip"].elmActiveTT = target;
					LBI.Custom.PEList["PE_tooltip"].elmTip = ttBubble;
				}
				LBI.Custom.PEList["PE_tooltip"].elmTipTitle = this.tipText[0].innerHTML;
				this.tipText[0].innerHTML = "";
				instObj.injectTitle(LBI.Custom.PEList["PE_tooltip"].elmTipTitle);
				ttBubble.className = ttBubble.className.replace(/hiddenTT/, "");
				instObj.positionTT(oEvent);
				
			},
			
			cleanUp: function(oEvent){
				this.elmActiveTT = null;
				this.tipText[0].innerHTML = LBI.Custom.PEList["PE_tooltip"].elmTipTitle;
				document.getElementById("tooltipMiddle").innerHTML = "";
				document.getElementById("tooltipBubble").className += " hiddenTT";
			},
			
			positionTT: function(oEvent){
				var oEvent = LBI.Common.readEvent(oEvent, "eventObj");
				var target = LBI.Common.readEvent(oEvent, "target");
				if (LBI.Custom.PEList["PE_tooltip"].elmActiveTT !== undefined) {
					var tip = LBI.Custom.PEList["PE_tooltip"].elmTip;
					if (tip !== undefined) {
						//tip.style.top = (LBI.Common.getAbsoluteY(target) - tip.offsetHeight) + "px";
						tip.style.top = (LBI.Common.getAbsoluteY(target) + 20) + "px";
						tip.style.left = (oEvent.clientX + 20) + document.documentElement.scrollLeft + "px";
					}
				}
				
			},
			
			createTT: function(){
				var ttSurround = document.createElement("div");
				var ttTop = document.createElement("div");
				var ttMiddle = document.createElement("div");
				var ttBottom = document.createElement("div");
				ttSurround.id = "tooltipBubble";
				ttTop.className = "tooltipTop";
				ttMiddle.id = "tooltipMiddle";
				ttBottom.className = "tooltipBottom";
				ttSurround.appendChild(ttTop);
				ttSurround.appendChild(ttMiddle);
				ttSurround.appendChild(ttBottom);
				ttSurround.className = "hiddenTT";
				document.body.appendChild(ttSurround);
				return ttSurround;
			},
			
			injectTitle: function(title){
				var bubbleInner = document.getElementById("tooltipMiddle");
				bubbleInner.innerHTML = "<p>" + title + "</p>";
			}
			
		},
		PE_flashLoader: {
			init: function(){
				var flashId = this.oCore.id;
				var srcId = LBI.Common.getPEClassInfo(this.oCore, "flashLoader");
				var height = LBI.Data.flashDimensions[srcId].height + "px";
				var width = LBI.Data.flashDimensions[srcId].width + "px";
				// The file name for flash files needs to be the name of it's object in the global Data object, i.e. Preview object would assume the core swf is Preview.swf
				var flashSrc = LBI.Data.flashPath + srcId + LBI.Data.flashExt;
				var expressInstall = (LBI.Data.flashDimensions[srcId].expressInstall !== undefined) ? LBI.Data.flashDimensions[srcId].expressInstall : false;
				var params = (LBI.Data.flashDimensions[srcId].params !== undefined) ? LBI.Data.flashDimensions[srcId].params : false;
				var flashVars = (LBI.Data.flashDimensions[srcId].flashVars !== undefined) ? LBI.Data.flashDimensions[srcId].flashVars : false;
				swfobject.embedSWF(flashSrc, flashId, width, height, "9.0.115", expressInstall, flashVars, params);
			},
			reSize: function(height, width){
				if (this.oCore) {
				
				}
			}
		},
		PE_accordian: {
			arrMembers: ["accHeader", "accContent"],
			intEm: 13.3,
			init: function(){
				if (this.accHeader.length === this.accContent.length) {
					for (var i = 0; i < this.accHeader.length; i++) {
						var initHeight = this.accContent[i].offsetHeight / this.intEm;
						if (this.accHeader[i].parentNode.className.indexOf("accOpen") === -1) {
							this.accContent[i].style.height = "0em";
						}
						this.setupAcc(i); //set up default accordian style
						// IE is having problems with retaining the height of each header tab - this is a fix for that
						/*@cc_on @*/
						/*@if (@_win32)
						this.accHeader[i].parentNode.style.marginBottom = "0px";
						@else
						this.accHeader[i].parentNode.style.marginBottom = "0px";
						/*@end @*/
						
						//var accHeadLink = document.createElement("a");
						//accHeadLink.setAttribute("href", "javascript:void(0)");
						//accHeadLink.setAttribute("title", "Open/close content");
						//$(accHeadLink).text(" ");
						
						var accHead = $(".accPanel ul li .accHeader span");
						//accHead[i].appendChild(accHeadLink);
						//$(accHead[i]).wrapInner("<a href='javascript:void(0)' title='Open/close content'></a>");
						
						var intObjIdx = this.intIdx;
						this.accHeader[i].onclick = function(idxX, idxY, baseH){
							return (function(){
								var obj = LBI.Custom.PEList["PE_accordian"].instLib[idxX].oCore;
								var newItem = this.parentNode;
								var newContent = newItem.getElementsByTagName("div")[0];
								var openItem = getElementsByClassName(obj, '*', 'accOpen')[0];
								var intEm = LBI.Custom.PEList["PE_accordian"].instLib[idxX].intEm;
								var aniOpt = {
									style: {
										height: "0px"
									},
									time: 600,
									tween: "swing",
									callback: true
								};
								var act2 = function(){ // runs as callback to 2nd animation if called - sets height back to ems
									newContent.style.height = (baseH / intEm) + "em";
								}
								if (openItem !== undefined) { // is there an open item - yes
									var openContent = openItem.getElementsByTagName("div")[0];
									var delayAct = function(){
										window.setTimeout(act, 200); // runs at end of click event animation - fires act after delay
									}
									var act = function(){ // runs at end of click event animation - delayed by delayAct
										var aniOpt2 = {
											style: {
												height: (baseH * intEm) + "px"
											},
											time: 800,
											tween: "swing",
											callback: false
										};
										openItem.className = 'accClose';
										if (openItem !== newItem) { // is the clicked item the open item? - no
											newItem.className = 'accOpen';
											LBI.Common.applyAnim(newContent, act2, true, aniOpt2);
										}
										else { // is the clicked item the open item? - yes
											newItem.className = 'accClose';
										}
									}
									LBI.Common.applyAnim(openContent, delayAct, true, aniOpt);
								}
								else { // is there an open item - no								
									var act = function(){
										newItem.className = 'accOpen';
									}
									var aniOpt2 = {
										style: {
											height: (baseH * intEm) + "px"
										},
										time: 800,
										tween: "swing",
										callback: false
									};
									LBI.Common.applyAnim(newContent, act, true, aniOpt2);
								}
							});
						}(intObjIdx, i, initHeight);
					}
				}
			},
			setupAcc: function(index){
			
				var accItem = this.accHeader[index].parentNode;
				if (accItem.className.indexOf("accOpen") === -1) {
					accItem.className = accItem.className + " accClose";
				}
			}
		},
		
		/* Library code was changed 27.10.08 to allow the images to be different sizes */
		/* They now occupy all space inside the frame, above the text area */
		
		PE_library_new: {
			arrMembers: ["libContent"],
		    intUnit: 130, // width of each item (inclusive of frame)
			intHeight: 118, // height of each item (inclusive of frame)
			intSideSpacing: 5, // margin on either side (inbetween items consider this doubled as they press against each other)
			intTextAreaHeight: 34, // height of text area at bottom of frame
			intGroupCount: 4,
			intControlWidth: 11,
			intGroupIdx: 1,
			oContent: {},
			init: function(){
				this.strSource = LBI.Common.getPEClassInfo(this.oCore, "library_new") + LBI.Data.extSrcExt;
				this.loadContent();
			},
			loadContent: function(){
				var strPath = LBI.Data.jsonPath + this.strSource;
				var intIdx = this.intIdx;
				var parObj = this;
				var oOptions = {
					url: strPath,
					timer: 60000,
					errorLog: function(){
						parObj.libContent[0].innerHTML = "The content you require is unavailable at this time"
					},
					data: "json",
					coreObj: this,
					successLog: function(data){
						parObj.createLibrary(data);
						parObj.oCore.className += " loaded";
						LBI.Common.updateBuffer();
					}
				}
				LBI.Common.ajaxLoader(oOptions);
			},
			onContentLoad: function(){
				this.createList()
			},
			createLibrary: function(data){
				var elList = this.createList(data);
				this.getValues(data);
				var elControls = this.createControls();
				var elContain = this.libContent[0];
				elContain.innerHTML = "";
				elList.style.width = this.intLength + "px";
				elContain.appendChild(elList);
				this.oCore.appendChild(elControls);
				
				//setting the initial left arrow not to dispaly on load
				$(".leftArrow").fadeTo("fast", 0);
			},
			createList: function(obj){
				var list = document.createElement("ul");
				var intItems = 0;
				for (var entry in obj) {
					this.createItem(entry, obj, list);
					intItems++;
				}
				this.intItems = intItems;
				this.intLength = intItems * (this.intUnit + (this.intSideSpacing * 2));
				return list;
			},
			createItem: function(item, obj, list){
				var listItem = document.createElement("li");
				var pic = document.createElement("img");
				var itemText = document.createElement("p");
				var backing = document.createElement("div");
				var frame = document.createElement("div");
				frame.className = "frame";
				var itemTextInner = document.createTextNode(obj[item].text);
				itemText.appendChild(itemTextInner);
				pic.src = LBI.Data.libPath + obj[item].image;
				pic.alt = "";
				listItem.style.width = this.intUnit + "px";
				/* -------Old vision library style
				pic.style.width = (this.intUnit - 10) + "px";
				pic.style.height = (this.intHeight - (10 + this.intTextAreaHeight)) + "px";
				-----------*/
				pic.style.width = this.intUnit + "px";
				pic.style.height = (this.intHeight - (10 + this.intTextAreaHeight)) + "px";
				
				listItem.appendChild(pic);
				listItem.appendChild(backing);
				listItem.appendChild(itemText);
				listItem.appendChild(frame);
				list.appendChild(listItem);
			},
			createControls: function(){
				var controls = document.createElement("ul");
				this.arrControls = [];
				controls.className = "controls";
				
				
				for (var a = 0; a < (this.groupNum + 2); a++) { 
					var control = document.createElement("li");
					var link = this.createLink(a, this.intIdx);
					this.arrControls[a] = link;

					link.onclick = function(idx, PEIdx){
						return (function(){
							var obj = LBI.Common.getPEObj(PEIdx, "PE_library_new");
							var canGo = {
								left: false,
								right: false
							};
							var isArrow = {
								left: false,
								right: false
							};
							if (obj.intGroupIdx > 1) {
								canGo.left = true;
							};

							if (obj.intGroupIdx < (obj.groupNum)) {
								canGo.right = true;
							};
							
							
							if (idx === 0) {
								isArrow.left = true;
							};
							if (idx === (obj.groupNum + 1)) {
								isArrow.right = true;
							};
							
							//Setting the hiding of navigtion buttons if there is no items to scroll in that direction
							var leftButton = $(this).hasClass("left");							
							var rightButton = $(this).hasClass("right");
																					
							if((obj.intGroupIdx)==(obj.groupNum)-1 && rightButton == true){
								$(".rightArrow").fadeTo("slow", 0);
							};
							
							if((obj.intGroupIdx)!==(obj.groupNum)-1){
								$(".rightArrow").fadeTo("slow", 1.0);
							};
							
							if((obj.intGroupIdx)==2 && leftButton == true){
								$(".leftArrow").fadeTo("slow", 0);
							};
							
							if((obj.intGroupIdx)!==2){
								$(".leftArrow").fadeTo("slow", 1.0);
							};
							
							
							obj.setControl(idx, canGo, isArrow);
							var list = obj.libContent[0].getElementsByTagName("ul")[0];
							var pos = obj.getPos(idx, canGo, isArrow);
							if (pos !== undefined) {
								var aniOpt = {
									style: {
										left: pos
									},
									time: 1000,
									tween: "swing",
									callback: false
								};
								LBI.Common.applyAnim(list, undefined, true, aniOpt);
								obj.getNewIdx(idx, canGo, isArrow);
							}
							return false;
						});
					}(a, this.intIdx);
					control.appendChild(link);
					controls.appendChild(control);
				}
				//controls.style.width = ((a - 2) * this.intControlWidth) + 64 + ((a - 3) * 6) + "px";
				return controls;
			},
			getNewIdx: function(idx, canGo, isArrow){
				if (isArrow.left) {
					if (canGo.left) {
						this.intGroupIdx = this.intGroupIdx - 1;						
					}
				}
				else 
					if (isArrow.right) {
						this.intGroupIdx = this.intGroupIdx + 1;
					}
					else { // if other controls
						this.intGroupIdx = idx;
					}
			},
			getPos: function(idx, canGo, isArrow){
				if (isArrow.left) {
					if (canGo.left) {
						var pos = this.arrMarkers[this.intGroupIdx - 2];
					}
				}
				else 
					if (isArrow.right) {
						if (canGo.right) {
							var pos = this.arrMarkers[this.intGroupIdx];
						}
					}
					else { // if other controls
						var pos = this.arrMarkers[idx - 1];
					}

				return pos;
				
			},
			setControl: function(idx, canGo, isArrow){
				var that = this;
				var setImg = function(newImg){
					newlinkImg[0].src = newImg[0].src.replace("_off.", "_on.");
					var oldlinkImg = that.arrControls[that.intGroupIdx].getElementsByTagName("img");
					oldlinkImg[0].src = oldlinkImg[0].src.replace("_on.", "_off.");
				}
				if (isArrow.left) {
					if (canGo.left) {
						var newlinkImg = this.arrControls[this.intGroupIdx - 1].getElementsByTagName("img");
						setImg(newlinkImg);
					}
				}
				else 
					if (isArrow.right) {
						if (canGo.right) {
							var newlinkImg = this.arrControls[this.intGroupIdx + 1].getElementsByTagName("img");
							setImg(newlinkImg);
						}
					}
					else { // if other controls
						var newlinkImg = this.arrControls[idx].getElementsByTagName("img");
						setImg(newlinkImg);
					}
			},
			createLink: function(idx){
				var link = document.createElement("a");
				link.href = "#";
				var linkImg = document.createElement("img");
				if (idx === 0) { // set the arrows
					linkImg.alt = "go back a set";
					linkImg.src = LBI.Data.visionImgPath + "vision_library_new_arrow_left.gif";
					linkImg.className = "leftArrow";
					link.className = "left";
				}
				else 
					if (idx === (this.groupNum + 1)) {
						linkImg.alt = "go forward a set";
						linkImg.src = LBI.Data.visionImgPath + "vision_library_new_arrow_right.gif";
						linkImg.className = "rightArrow";
						link.className = "right";
					}
					else { // set the rest
						linkImg.alt = "go to set " + (idx + 1);
						linkImg.className = "indicators";
						if (this.intGroupIdx === idx) {
							linkImg.src = LBI.Data.visionImgPath + "vision_library_control_on.gif";
						}
						else {
							linkImg.src = LBI.Data.visionImgPath + "vision_library_control_off.gif";
						}
					}
				link.appendChild(linkImg);
				return link;
			},
			getValues: function(obj){
				this.arrMarkers = [];
				var point = 0;
				var remainder = this.intItems % this.intGroupCount;
				if (remainder === 0) {
					this.groupNum = (this.intItems - remainder) / this.intGroupCount;
				}
				else {
					this.groupNum = ((this.intItems - remainder) / this.intGroupCount) + 1;
				}
				var groupLen = this.intLength / this.groupNum;
				for (var a = 0; a < this.groupNum; a++) {
					this.arrMarkers[a] = (point * -1);
					point = point + groupLen;
				}
			}
			
		},

		//Adds TAB navigation functionality for all elements with class 'PE_tabNav'
		PE_tabbedPanel: {
			arrMembers: ["tabNav", "tabContent"],
			strTabTag: "li",
			strTabLinkTag: "a",
			strContentsTag: "div",
			init: function(){
				if (LBI.Custom.PEList.PE_tabbedPanel.extMembers === undefined) {
					this.extMembers.harvest();
				}
				this.oCore.className += " tabbed";
				this.arrTabs = this.tabNav[0].getElementsByTagName(this.strTabTag);
				this.arrTabLinks = this.tabNav[0].getElementsByTagName(this.strTabLinkTag);
				this.arrContents = [];
				var counter = 0;
				var contDivs = this.tabContent[0].getElementsByTagName(this.strContentsTag);
				for (var b = 0, c = contDivs.length; b < c; b++) {
					if (contDivs[b].id.indexOf("tab") !== -1) {
						this.arrContents[counter] = contDivs[b];
						counter++;
					}
				}
				// ensure tab and content amounts are equal
				var tLength = this.arrTabs.length;
				var cLength = this.arrContents.length;
				
				if (tLength === cLength) {
					for (var i = 0; i < tLength; i++) {
						if (this.arrTabs[i].className.indexOf("tabOn") !== -1) {
							this.extMembers.alternate(this.arrContents[i].id); //hide all external members not linked to this tab					
							this.intActiveIdx = i;
							if (this.arrContents[i].className.indexOf("tabOn") === -1) {
								this.arrContents[i].className += " tabOn";
							}
						}
						if (LBI.Common.isLtIE7 === true) {
							this.arrTabLinks[i].parentNode.style.height = "1%"; /* IE fix */
						}
						this.arrTabLinks[i].onclick = function(intIdx){
							return (function(){
								var currentInst = LBI.Common.getPEObj(intIdx, 'PE_tabbedPanel');
								currentInst.setupTab(this);
								var currentTab = currentInst.arrContents[currentInst.intActiveIdx].id;
								currentInst.extMembers.alternate(currentTab); //hide all external members not linked to this tab, reveal all linked																					
								var idRef = this.href.substring((this.href.indexOf("#") + 1), this.href.length);
								//console.log(idRef);
								var area = document.getElementById(idRef);
								//area.focus();
								//currentInst.scrollToTab(this, -100);
								return false;
							});
						}(this.intIdx);
					}
				}
				if (this.intIdx === (LBI.Custom.PEList["PE_tabbedPanel"].instLib.length - 1)) {
					LBI.Custom.PEList.PE_tabbedPanel.instLib[this.intIdx].goToContent();
					LBI.Custom.PEList.PE_tabbedPanel.instLib[this.intIdx].harvestLinks();
				}
			},
			//external members those state is controlled by tab clicks
			extMembers: {
				harvest: function(){
					var buffer = LBI.Common.fuzzyClassName("*", "tabExtMember");
					LBI.Custom.PEList.PE_tabbedPanel.extMembers = {};
					for (var a = 0, b = buffer.length; a < b; a++) {
						var tabRef = LBI.Common.getPEClassInfo(buffer[a], 'tabExtMember');
						if (buffer[a].className.indexOf("invertTabLink") === -1) {
							var linkRel = "normal"
						}
						else {
							var linkRel = "invert"
						}
						var extMember = {
							memObj: buffer[a],
							linkRel: linkRel
						};
						if (tabRef !== undefined) {
							if (LBI.Custom.PEList.PE_tabbedPanel.extMembers[tabRef] !== undefined) {
								LBI.Custom.PEList.PE_tabbedPanel.extMembers[tabRef].push(extMember);
							}
							else {
								LBI.Custom.PEList.PE_tabbedPanel.extMembers[tabRef] = [extMember];
							}
						}
					}
				},
				alternate: function(strTabId){
					hideVisContent(strTabId);
					var extMembers = LBI.Custom.PEList.PE_tabbedPanel.extMembers;
					var putOnHidden = function(memObj){
						if (memObj.className.indexOf("hidden") === -1) {
							memObj.className += " hidden";
						}
					}
					var takeOffHidden = function(memObj){
						if (memObj.className.indexOf("hidden") !== -1) {
							memObj.className = extMembers[memberTabRef][c].memObj.className.replace(/hidden/, "");
						}
					}
					for (var memberTabRef in extMembers) {
						for (c = 0, d = extMembers[memberTabRef].length; c < d; c++) {
							//If a external member doesn't match it should be hidden, unless it has an invert flag
							if (strTabId !== memberTabRef) {
								if (extMembers[memberTabRef][c].linkRel === "normal") {
									putOnHidden(extMembers[memberTabRef][c].memObj);
								}
								else { //If it has an invert flag, the opposite should apply
									takeOffHidden(extMembers[memberTabRef][c].memObj);
								}
							}
							else {
								if (extMembers[memberTabRef][c].linkRel === "normal") {
									takeOffHidden(extMembers[memberTabRef][c].memObj);
								}
								else {
									putOnHidden(extMembers[memberTabRef][c].memObj);
								}
							}
						}
					}
				}
			},
			//set make all local links that links to tabContent display it
			harvestLinks: function(){
				var links = document.getElementsByTagName("a");
				var linkLen = links.length;
				var count = 0;
				var tabLinks = [];
				var tabCount = 0;
				//get all tabs on page
				var tabPanelNum = LBI.Custom.PEList["PE_tabbedPanel"].instLib.length;
				for (var x = 0; x < tabPanelNum; x++) {
					var currentInstTabs = LBI.Custom.PEList["PE_tabbedPanel"].instLib[x].arrTabLinks;
					var instTabsNum = currentInstTabs.length;
					for (var y = 0; y < instTabsNum; y++) {
						tabLinks[tabCount] = currentInstTabs[y];
						tabCount++;
					}
				}
				//d = links index
				for (var d = 0; d < linkLen; d++) {
					var isTab = false;
					var matchesHref = false;
					var tabLinkLen = tabLinks.length;
					//e = tabs index
					for (var e = 0; e < tabLinkLen; e++) {
						//if link is tablink, mark it
						if (links[d] === tabLinks[e]) {
							isTab = true;
						}
						if (links[d].href === tabLinks[e].href) {
							matchesHref = true;
							var tabToOpen = tabLinks[e];
						}
					}
					//if not a tab, use
					if (isTab === false && matchesHref === true) {
						links[d].onclick = function(intIdx, tabToOpen){
							return (function(){
								var currentTabSet = LBI.Common.getPEObj(intIdx, "PE_tabbedPanel");
								var currentHeight = this.scrollHeight;
								currentTabSet.setupTab(tabToOpen);
								currentTabSet.scrollToTab(this, -100);
								var currentTab = currentTabSet.arrContents[currentTabSet.intActiveIdx].id;
								currentTabSet.extMembers.alternate(currentTab); //hide all external members not linked to this tab, reveal all linked																					
								return false;
							})
						}(this.intIdx, tabToOpen)
					}
				}
			},
			scrollToTab: function(obj, intOffset){
				var intOffset = (intOffset === undefined) ? 0 : intOffset;
				var top = LBI.Common.getAbsoluteY(obj);
				window.scrollTo(0, (top + intOffset));
			},
			goToContent: function(){
				var strLocHash = location.hash;
				hideVisContent(strLocHash);
				var that = this;
				var getLink = function(strHash){
					var tLength = that.arrTabLinks.length;
					for (var a = 0; a < tLength; a++) {
						if (that.arrTabLinks[a].href.indexOf(strHash) !== -1) {
							return that.arrTabLinks[a];
						}
					}
				}
				if (strLocHash.indexOf("#") !== -1) {
					var strHash = getLink(strLocHash);
					if (strHash !== undefined) {
						this.setupTab(strHash);
						this.scrollToTab(strHash, top);
						return false;
					}
				}
			},
			setupTab: function(elClicked){
				var oPEObj = LBI.Common.getPEObj(this.intIdx, "PE_tabbedPanel");
				var elCurrentTab = oPEObj.arrTabs[oPEObj.intActiveIdx];
				var elTabContent = oPEObj.arrContents[oPEObj.intActiveIdx];
				elCurrentTab.className = elCurrentTab.className.replace(/tabOn/, "");
				elTabContent.className = elTabContent.className.replace(/tabOn/, "");
				var tLength = oPEObj.arrTabs.length;
				for (var a = 0; a < tLength; a++) {
					if (elClicked === oPEObj.arrTabLinks[a]) {
						oPEObj.intActiveIdx = a;
						oPEObj.arrTabs[a].className += " tabOn";
						oPEObj.arrContents[a].className += " tabOn";
					}
				}
				
				//this is triggered for package chooser;
				if(document.getElementById("chooser") !== null) {
					checkBasket();
				}
			}
		},
		
		//Adds swap functionality for all elements with class 'PE_swap'
		PE_imgSwap: {
			init: function(){
				swapImgs = LBI.Custom.PEList["PE_imgSwap"].instLib;
				for (var i = 0; i < swapImgs.length; i++) {
					swapImgs[i].oCore.onmouseover = function(){
						var newImg = this.src.replace("_off.", "_over.");
						this.src = newImg;
					};
					swapImgs[i].oCore.onmouseout = function(){
						var newImg = this.src.replace("_over.", "_off.");
						this.src = newImg;
					};
					swapImgs[i].oCore.onfocus = swapImgs[i].oCore.onmouseover;
					swapImgs[i].oCore.onblur = swapImgs[i].oCore.onmouseout;
				}
			}
		}
	
	},

	/* setUpNav re-writes the markup of the navigation to add a strong tag to the selected item.
	 * As the menu is now entirely image-based, all nav-items are given a class name referencing the level they are on and their position on it and the product area.
	 * The secondary nav is referenced for the index of the area which LBI.Data.menuSections uses to get the name (i.e. 1 = 'packages).
	 * If the area is Packages, the hero image is turned to a backing style to enable the nav to overlay it.
	 */
	setUpNav: function(){
		var navMain = document.getElementById("AreaA");
		if (navMain) {
			var internalNav = getElementsByClassName(navMain, "div", "containerA1");
			if ((internalNav.length > 0)) {
				var navHolder = getElementsByClassName(navMain, "div", "containerA1")[0];
				var innerPortlet = getElementsByClassName(navHolder, "div", "innerPortlet")[0];
				var level1 = getElementsByClassName(navMain, "ul", "menuLevel1")[0];
				var level2 = getElementsByClassName(navMain, "ul", "menuLevel2")[0];
				var selected = getElementsByClassName(navMain, "li", "blackText");
				var firstSelect = getElementsByClassName(navMain, "li", "selected");
				var secNav = document.getElementById("SecNav");				
				var valids = [];
				var count = 0;
				var firstSelects = firstSelect.length;
				if (secNav !== null) {	
					var secNavKids = secNav.getElementsByTagName("li");		
					for(var a = 0, b = secNavKids.length; a < b; a++) {
						if(secNavKids[a].className.indexOf("selected") !== -1) { var sectionIdx = a; }
					}
					// sectionIdx is the index of the area the page is in. This is later used with a property of the Data object to source the area name
					if(sectionIdx === undefined) {	
						// Check if the page is in TV
						var isTV = document.getElementById("vision");
						var fakeSelected;
						
						if(isTV)
							fakeSelected = "TV";
						/*else
							fakeSelected = "Broadband";*/
							
						for(var a = 0, b = secNavKids.length; a < b; a++) {	
							var links = secNavKids[a].getElementsByTagName("a");					
							for(var c = 0; c < links.length; c++) {	
								if(links[c].innerHTML === fakeSelected)
								{
									secNavKids[a].className = "selected";
									secNavKids[a].innerHTML = "<span>" + links[c].innerHTML + "</span>";																
								}
							}
						}					
					}
					if (selected.length !== 0) {
						var selects = selected.length;
						for (var e = 0; e < selects; e++) {
							if (selected[e].getElementsByTagName("span").length !== 0) {
								valids[count] = selected[e];
								count++;
							}
						}
					}
				}
				if(level2==null){

					$(".containerA1").css("margin-bottom", "0");
				}
				if (firstSelect.length !== 0) {
					for (var f = 0; f < firstSelects; f++) {
						if (firstSelect[f].getElementsByTagName("span").length !== 0 ||
						firstSelect[f].className.indexOf("first") !== -1) {
							valids[count] = firstSelect[f];
							count++;
						}
					}
				}
				if (valids.length > 0) {
					var lastSelect = valids[valids.length - 1];
					var newInner = document.createElement("strong");
					if (lastSelect.className.indexOf("first") !== -1) {
						newInner.innerHTML = lastSelect.innerHTML;
						lastSelect.innerHTML = "";
					}
					else {
						var innerSpan = lastSelect.getElementsByTagName("span")[0];
						newInner.innerHTML = innerSpan.innerHTML;
						LBI.Common.removeNodeByObj(innerSpan);
					}
					lastSelect.appendChild(newInner);
				}
				if (level2 !== undefined) {
					var lvl2Children = level2.getElementsByTagName("li");
					if (lvl2Children.length !== 0) {
						navHolder.className += " lvl2";
					}
					else {
						navHolder.className += " lvl1";
					}
				}
				else {
					navHolder.className += " hub";
				}
				var convertItems = function(level){
					var count = 1;
					for (var a = 0, b = level.childNodes.length; a < b; a++) {
						var name = level.childNodes[a].nodeName.toUpperCase();
						if (name === "LI") {
							var item = level.childNodes[a].getElementsByTagName("a")[0];
							if (item === undefined) {
								item = level.childNodes[a].getElementsByTagName("span")[0];
								if (item === undefined) {
									item = level.childNodes[a].getElementsByTagName("strong")[0];								
								}
							}							
							var levelNo = (level === level1) ? "Lvl1" : "Lvl2";
							var itemName = item.nodeName.toUpperCase();
							var isLvl2ParentType = (itemName === "SPAN") || (itemName === "A" && (item.parentNode.nodeName.toUpperCase() === "SPAN"));
							if ((isLvl2ParentType) && (levelNo === "Lvl1")) {
								selectedParentIdx = count;
							}
							if (item !== undefined) {
								LBI.Data.pngsToIgnore.add(item);
								// menuSection is defined in the Data property referenced above
								if (levelNo === "Lvl1") {									
									//condition for bblife
									var classNameCheck = $("#AreaA ul").attr("id")
									if(classNameCheck === "bbLifeNav"){
										item.className += " " + "bblife" + levelNo + "Nav" + count;
									}
									else{
										item.className += " " + LBI.Data.menuSections[sectionIdx] + levelNo + "Nav" + count;
									}
								}
								else {									
									//condition for bblife
									var classNameCheck = $("#AreaA ul").attr("id")
									if(classNameCheck === "bbLifeNav"){
										item.className += " " + "bblife" + "Lvl1Nav" + selectedParentIdx + "Lvl2Nav" + count;
									}
									else{
										item.className += " " + LBI.Data.menuSections[sectionIdx] + "Lvl1Nav" + selectedParentIdx + "Lvl2Nav" + count;
									}
								}
								itemInner = document.createElement("span");
								itemInner.className = "hidden";
								itemInner.innerHTML = item.innerHTML;
								item.innerHTML = "";
								item.appendChild(itemInner);
							}
							count++;
						}
					}
				}
				/* WHAT DOES THIS DO?
				if (level1 !== undefined) {
					convertItems(level1);
					if (level2 !== undefined) {
						convertItems(level2);
					}
				}*/
				// for packages pages, hero needs to sit behind the nav so is set to the content area's backing image
				if(LBI.Data.menuSections[sectionIdx] === "packages") {
					var content = document.getElementById("ContentAreas");
					var moveHeroToBacking = function(contentSection) {
						var heroImage = document.getElementById("hero").getElementsByTagName("img")[0];
						contentSection.style.backgroundImage = "url(" + heroImage.src + ")";
						//heroImage.style.visibility = "hidden";
						contentSection.style.backgroundPosition = "0 0";
						contentSection.style.backgroundRepeat = "no-repeat";
						return contentSection;
					}(content);
					LBI.Data.pngsToIgnore.add(content);									
				}				
				LBI.Data.pngsToIgnore.add(navHolder);
				LBI.Data.pngsToIgnore.add(innerPortlet);
				LBI.Common.updateBuffer();
			}
		}
	},
carousel:function(){
	var carouselNumbers = $(".carouselContainer");
	
	//configurable options for each of the carousel
	$(".carousel01 .carouselContent").css("height", 325);
	$(".carousel02 .carouselContent").css("height", 250);
	$(".carousel03 .carouselContent").css("height", 435);
	
	//general set up 
	$(".carouselContent ul").css("position", "absolute");
	$(".alternateControls").css("display", "block");
	
	$(carouselNumbers).each(function(){
		//setting up carousel's static values
		var carouselWidth = $(".carouselContent", this).css("width");
		var itemWidth = parseInt(carouselWidth);
		var carouselSpeed = 600;



		var fadeValue = 0;
		
		var carouselItems = $(".carouselContent li", this);
		var containerWidth = carouselItems.length * itemWidth;
		$(".carouselContent ul", this).css("width",containerWidth);
		var finalXpos = itemWidth - containerWidth;
		
		
		//create controls
		var cControls = $(".controls", this);		
		var cBack = document.createElement("a");
		$(cBack).attr( {
			href: "#"
		} );
		$(cBack).addClass("left");
		cControls[0].appendChild(cBack);
		var lArrow = document.createElement("span");
		$(lArrow).addClass("hidden");
		$(lArrow).text("left");
		//$(lArrow).attr( {
			//src: "../consumer/consumerProducts/images/products_and_services/entertainment/vision_library_new_arrow_left.gif",
			//alt: "Go back"
		//} );
		cBack.appendChild(lArrow);
		
		var cFrwd = document.createElement("a");
		$(cFrwd).attr( {
			href: "#"
		} );
		$(cFrwd).addClass("right");
		cControls[0].appendChild(cFrwd);
		var rArrow = document.createElement("span");
		$(rArrow).addClass("hidden");
		$(rArrow).text("right");
		//$(rArrow).attr( {
			//src: "../consumer/consumerProducts/images/products_and_services/entertainment/vision_library_new_arrow_right.gif",
			//alt: "Go forward"
		//} );
		cFrwd.appendChild(rArrow);
		
		//Assigning the current carousel
		var currentCarousel = $(".carouselContent ul", this);
		var rightButton = $(".right", this);
		var leftButton = $(".left", this);
		var alternateControlItems = $('.alternateControls li a', this);
		var alternateControl = $('.alternateControls', this);
		
		//Setting default opacity to the left button
		$(leftButton).fadeTo("fast", fadeValue);
		
		//Alternate controls to the carousel
		$(alternateControlItems).click(function tabCont(event) {
		      // if the ul is already moving, then do nothing
			  if ($(".carouselContent ul:animated").length > 0)return false; 
		 
		      var clicked_item = $(event.target);			  
		      var current_active = $(".active", alternateControl);
			  
			  if($(".carousel03").length !== 0){
				var clicked_item_parent = $(event.target).parent();			  
				var current_active_parent = $(".active", alternateControl).parent();
			  }
			 
		      var current_index = $(".active", alternateControl).attr("rel");			  
		      var new_index = $(clicked_item).attr("rel");
		      
			  var move = new_index; // get how many items it should be moved
		 
		      if (new_index != current_index) {
				var moveValue = "-" + (itemWidth*(move -1));
		        $(currentCarousel).animate({left: moveValue}, carouselSpeed);
		        clicked_item.addClass("active");
		        current_active.removeClass("active");
				
				if($(".carousel03").length !== 0){
					clicked_item_parent.addClass("current");
					current_active_parent.removeClass("current");
				}
				
				if(new_index == carouselItems.length){
					$(rightButton).fadeTo("slow", fadeValue);
					$(leftButton).fadeTo("slow", 1.0);
				}
				else if (new_index == 1){
					$(leftButton).fadeTo("slow", fadeValue);
					$(rightButton).fadeTo("slow", 1.0);
				}
				else {
					$(rightButton).fadeTo("slow", 1.0);
					$(leftButton).fadeTo("slow", 1.0);
				}				
				return false
		      }		 
		      return false;
		    });
		
		//Assigning function for right controls
		$(rightButton).click(			
			function goRight(){				
				$(leftButton).fadeTo("slow", 1.0);
				if ($(".carouselContent ul:animated").length > 0)return false;
				var currentXpos = $(currentCarousel).css("left");	
				var currentX = parseInt(currentXpos);				
				if(currentX !== finalXpos){
					currentX = currentX-itemWidth;
					$(currentCarousel).animate( { left:currentX}, carouselSpeed );					
					
					$(currentCarousel).css({left:currentX});										
					if(currentX === finalXpos){
						$(this).fadeTo("slow", fadeValue);

					}
										
					var currentTabValue = currentX/itemWidth;
					if (currentTabValue < 0){
						var currentTabValue = -1 * currentTabValue;
					}
					var currentTabValue = currentTabValue;
					var alternateTabs = $("a", alternateControl);
					$(alternateTabs).removeClass("active");
					$(alternateTabs[currentTabValue]).addClass("active");
					
					return false;					
				}				
				return false;				
			}	
		)
		
		//Assigning function for left controls
		$(leftButton).click(		
			function goLeft(){
				$(rightButton).fadeTo("slow", 1.0);
				if ($(".carouselContent ul:animated").length > 0)return false;
				var currentXpos = $(currentCarousel).css("left");
				var currentX = parseInt(currentXpos);
				if(currentX !== 0){
					currentX = currentX+itemWidth;
					$(currentCarousel).animate( { left:currentX}, carouselSpeed );
					
					$(currentCarousel).css({left:currentX});										
					if(currentX === 0){
						$(this).fadeTo("slow", fadeValue);
					}
					
					var currentTabValue = currentX/itemWidth;
					if (currentTabValue < 0){
						var currentTabValue = -1 * currentTabValue;
					}
					var currentTabValue = currentTabValue;
					var alternateTabs = $("a", alternateControl);
					$(alternateTabs).removeClass("active");
					$(alternateTabs[currentTabValue]).addClass("active");
					
					return false;
				}
				return false;
			}		
		)

	})
},

setSevenTabNav: function(){
	var navItem = $(".sevenTabNav .tabNav li");
	$(navItem).each(function(){
		$(this).click(function(){
			LBI.Custom.assignSevenTabNav();
		})
	})
},
assignSevenTabNav: function(){
	var navHolder = $(".sevenTabNav .tabNav");
	var navList = $(".sevenTabNav .tabNav li");
	$(navHolder[0]).attr({id:"navItem1"});
	if ($(navList[0]).hasClass("tabOn"))  {
		$(navHolder[0]).attr({id:""});
		$(navHolder[0]).attr({id:"navItem1"});
	}
	else if 
		($(navList[1]).hasClass("tabOn")){
		$(navHolder[0]).attr({id:""});
		$(navHolder[0]).attr({id:"navItem2"});
	}
	else if 
		($(navList[2]).hasClass("tabOn")){
		$(navHolder[0]).attr({id:""});
		$(navHolder[0]).attr({id:"navItem3"});
	}
	else if 
		($(navList[3]).hasClass("tabOn")){
		$(navHolder[0]).attr({id:""});
		$(navHolder[0]).attr({id:"navItem4"});
	}
	else if 
		($(navList[4]).hasClass("tabOn")){
		$(navHolder[0]).attr({id:""});
		$(navHolder[0]).attr({id:"navItem5"});
	}
	else if 
		($(navList[5]).hasClass("tabOn")){
		$(navHolder[0]).attr({id:""});
		$(navHolder[0]).attr({id:"navItem6"});
	}
	else if 
		($(navList[6]).hasClass("tabOn")){
		$(navHolder[0]).attr({id:""});
		$(navHolder[0]).attr({id:"navItem7"});
	}
},
	
setPreview:function(){
	var imageUrl = LBI.Data.libPath;
	var defaultImage = "dummy_video_holder";
	var imageLinks = $(".viewingPacks li a");
	
	//settting the default OmnitureClick		
	var defaultomnitureOnclick = $(imageLinks[0]).parent().attr("onclick");    
	if(defaultomnitureOnclick) {
		document.getElementById('pvImg').setAttribute("onclick", defaultomnitureOnclick);
		document.getElementById('pvTxt').setAttribute("onclick", defaultomnitureOnclick);
	}

	$(imageLinks).each(
		function(){
			$(this).hover(
				function () {
					var imageAttribute = $(this).attr("rel");
					var videoAttribute = $(this).attr("href");
					var imageName = $(".previewContainer img").attr("src");
					var textAttribute = $(this).attr("title");

					var imageCurrent = imageUrl + imageAttribute + ".jpg";
					$(".previewImage img").attr({src : imageCurrent});
					$(".previewImage a").attr({href: videoAttribute});
					$(".previewText a").attr({href: videoAttribute});
					$(".previewText p").text(textAttribute);

					//OmnitureClick
					var omnitureOnclick = $(this).parent().attr("onclick"); 
					if(omnitureOnclick) {					
						document.getElementById('pvImg').setAttribute("onclick", omnitureOnclick);
						document.getElementById('pvTxt').setAttribute("onclick", omnitureOnclick);
					}
				}, 
				function () {
					//var imageDefault = imageUrl + defaultImage + ".jpg";
					//$(".previewContainer img").attr({src : imageDefault});
				}
			); 
		});
	},
	
	articleContent:function(){
		var articleLink = $(".article");
		var iframeContainer = $(".articleContainer iframe");
		
		$(articleLink).click(function(){
			var iframeLink = $(this).attr("href");
			$(iframeContainer).attr({src: iframeLink});
		});
	},
	
	onPageFlash: function() {
		if ($(".flashContent").length !==0){
			$(".videoHolder").removeClass("hidden");
			$(".fallback").addClass("hidden");
			$(".audioDescription").addClass("hidden");

			
			
			if($(".autoplay").length !==0 || $(".onHit").length !==0){
				if($(".autoplay").length !==0){
					$(".autoplay").each(function(){
						var videoLinks = $(".flashContent a", this);
						$(videoLinks).each(function(){
							var flashType= LBI.Common.getPEClassInfo(this,"F_");
							var videoId = LBI.Common.getPEClassInfo(this,"V_");
							
							var height = LBI.Data.flashType[flashType].height + "px";
							var width = LBI.Data.flashType[flashType].width + "px";
							var videoHeight = LBI.Data.flashType[flashType].height;
							var videoWidth = LBI.Data.flashType[flashType].width;
							
							if($("#endImage").length !=- 0){
								var endimage = document.getElementById("endImage");
								var endImagePath = endimage.href;
							}
							
							var interactiveUrl = LBI.Data.interactiveDemo;
		
							var flashvars = {};
							if (this.href.indexOf(".flv") !== -1) {
								var videoLink = this.href;
								flashvars.videoSource= videoLink;
								flashvars.width = videoWidth;
								flashvars.height = videoHeight;
								flashvars.autoplay = true;
								flashvars.muted = true;
								flashvars.showInteractive = true;
								flashvars.endImage = endImagePath;
								flashvars.launchUrl = interactiveUrl;
								swfobject.embedSWF(LBI.Data.flashPlayer01, videoId, width, height, "9.0.0", "expressInstall.swf",flashvars, LBI.Data.pageVideoOptions.params);
							} else {
								var flashFile = this.href;
								swfobject.embedSWF(flashFile, videoId, width, height, "9.0.0", "expressInstall.swf",flashvars,LBI.Data.pageSWFOptions.params);
							}
						})
					})
				}
				
				if ($(".onHit").length !==0){
					
					$(".onHit").each(function(){
						var videoLinks = $(".flashContent a", this);
						var videoThumbs = $(".externalTrigger", this);
						$(videoLinks).click(function(){
							var flashType = LBI.Common.getPEClassInfo(this,"F_");
							var videoId = LBI.Common.getPEClassInfo(this,"V_");
							
							var height = LBI.Data.flashType[flashType].height + "px";
							var width = LBI.Data.flashType[flashType].width + "px";
							var videoHeight = LBI.Data.flashType[flashType].height;
		
							var videoWidth = LBI.Data.flashType[flashType].width;
			
							var flashvars = {};
							if (this.href.indexOf(".flv") !== -1) {
								var videoLink = this.href;
								flashvars.videoSource= videoLink;
								flashvars.width = videoWidth;
								flashvars.height = videoHeight;
								flashvars.autoplay = true;
								flashvars.muted = false;
								flashvars.showInteractive = false;
								swfobject.embedSWF(LBI.Data.flashPlayer01, videoId, width, height, "9.0.0", "expressInstall.swf",flashvars, LBI.Data.pageVideoOptions.params);
							} else {
								var flashFile = this.href;
								swfobject.embedSWF(flashFile, videoId, width, height, "9.0.0", "expressInstall.swf");
							}
							
							return false;
						})
						
						if($(".videoThumbHold").length !==0){
							$(".videoThumbHold").hover(
								function(){
									$(this).closest(".videoThumbHold").addClass("mouseover");
								},
								function(){
									$(this).closest(".videoThumbHold").removeClass("mouseover");
								}
							)
						}
						
						$(videoThumbs).click(function(){
							if($(".videoThumbHold").length !==0){
								$(".videoThumbHold").removeClass("active");
								$(this).closest(".videoThumbHold").addClass("active");
							}
							var flashType = LBI.Common.getPEClassInfo(this,"F_");
							var videoId = LBI.Common.getPEClassInfo(this,"V_");
							
							var height = LBI.Data.flashType[flashType].height + "px";
							var width = LBI.Data.flashType[flashType].width + "px";
							var videoHeight = LBI.Data.flashType[flashType].height;
		
							var videoWidth = LBI.Data.flashType[flashType].width;
			
							var flashvars = {};
							if (this.href.indexOf(".flv") !== -1) {
								var videoLink = this.href;
								flashvars.videoSource= videoLink;
								flashvars.width = videoWidth;
								flashvars.height = videoHeight;
								flashvars.autoplay = true;
								flashvars.muted = false;
								flashvars.showInteractive = false;
								swfobject.embedSWF(LBI.Data.flashPlayer01, videoId, width, height, "9.0.0", "expressInstall.swf",flashvars, LBI.Data.pageVideoOptions.params);
							} else {
								var flashFile = this.href;
								swfobject.embedSWF(flashFile, videoId, width, height, "9.0.0", "expressInstall.swf");
							}
							
							return false;
						})	
					
					})
					
				}
				/*
				else if ($(".onHit").length !==0){				
					$(videoLinks).click(function(){
						var flashType = LBI.Common.getPEClassInfo(this,"F_");
						var videoId = LBI.Common.getPEClassInfo(this,"V_");
						var captionFile = LBI.Common.getPEClassInfo(this,"C_");
						var fallBackImage = LBI.Common.getPEClassInfo(this,"fallback");
						
						var height = LBI.Data.flashType[flashType].height + "px";
						var width = LBI.Data.flashType[flashType].width + "px";
						var videoHeight = LBI.Data.flashType[flashType].height;
						var videoWidth = LBI.Data.flashType[flashType].width;
						var captionSource = "null&captions.file=" + LBI.Data.flashPath + captionFile;
						var videoSkin =  LBI.Data.flashPath + "bt_test_skin.swf";
						
	
						var flashvars = {};
						if (this.href.indexOf(".flv") !== -1) {
							var videoLink = this.href;
							flashvars.file= videoLink;
							flashvars.width = videoWidth;
							flashvars.height = videoHeight;
							flashvars.autostart = true;
							flashvars.mute = false;
							flashvars.controlbar = "over";
							flashvars.audioName="null&audiodescription.file=http://www.longtailvideo.com/jw/upload/corrie.mp3";
							flashvars.skin = videoSkin;
							flashvars.image = fallBackImage;
							flashvars.captionsname = captionSource;
							//flashvars.captionState = "null&captions.state";
							//flashvars.audioState = "null&audiodescription.state";
							flashvars.plugins = "captions-1, audiodescription-1";
							swfobject.embedSWF(LBI.Data.flashPlayer01, videoId, width, height, "9.0.0", "expressInstall.swf",flashvars, LBI.Data.pageVideoOptions.params);
						} else {
							var flashFile = this.href;
							swfobject.embedSWF(flashFile, videoId, width, height, "9.0.0", "expressInstall.swf");
						}
						
						return false;
					})
					
				}*/
				
			}
			
			
			else {				
				var videoLinks = $(".flashContent a");
				$(videoLinks).each(function(){					
					var flashType = LBI.Common.getPEClassInfo(this,"F_");
					var videoId = LBI.Common.getPEClassInfo(this,"V_");
					
					var height = LBI.Data.flashType[flashType].height + "px";
					var width = LBI.Data.flashType[flashType].width + "px";
					var videoHeight = LBI.Data.flashType[flashType].height;
					var videoWidth = LBI.Data.flashType[flashType].width;
	
					var flashvars = {};
					if (this.href.indexOf(".flv") !== -1) {
						var videoLink = this.href;
						flashvars.videoSource= videoLink;
						flashvars.width = videoWidth;
						flashvars.height = videoHeight;
						flashvars.autoplay = false;
						flashvars.muted = false;
						flashvars.showInteractive = false;
						swfobject.embedSWF(LBI.Data.flashPlayer01, videoId, width, height, "9.0.0", "expressInstall.swf",flashvars, LBI.Data.pageVideoOptions.params);
					} else {
						var flashFile = this.href;
						swfobject.embedSWF(flashFile, videoId, width, height, "9.0.0", "expressInstall.swf");
					}
				})
				
			}
		}	
	},
	
	tabBanner: function(){
		var tabNav = $(".bannerSwitch");
		
		if(tabNav.length !== 0){
			$(tabNav).each(function(){
				var sectionName = LBI.Common.getPEClassInfo(this, "PE_section");
				if(sectionName =="bundling"){
					rootPath = LBI.Data.bundlingImgPath;
				}
				else if(sectionName == ""){
					rootPath = LBI.Data.commonImgPath;
				}
			
				var currentTab = $("li.tabOn", this);	
				var currentPath = rootPath + LBI.Common.getPEClassInfo(currentTab[0], "PE_banner") + ".jpg";			
				var currentImage = $("#hero .heroImage img.changeBanner");
				currentImage[0].src = currentPath;
				
				var tabLinks = $("li", this);

				$(tabLinks).click(function(){				
					var imagePath = rootPath + LBI.Common.getPEClassInfo(this, "PE_banner") + ".jpg";
					var bannerImage = $("#hero .heroImage img.changeBanner");
					bannerImage[0].src = imagePath;
					
					return false
				})

			})
		}
	},
	
	columnHover: function(){
		var compareColumns = $(".PE_hover .column");
		
		if(compareColumns.length !== 0){
			$(compareColumns).hover(
				function(){
					$(this).addClass("currentColumn");
				},
				
				function(){
					$(this).removeClass("currentColumn");
				}	
			)
		}
	},
	
	columnHoverPink: function(){
		var compareColumns = $(".PE_hover .columnOffer");
		
		if(compareColumns.length !== 0){
			$(compareColumns).hover(
				function(){
					$(this).addClass("currentColumnPink");
				},
				
				function(){
					$(this).removeClass("currentColumnPink");
				}	
			)
		}
	},
    
    infoTooltop: function(){
		var toolTips = $(".PE_infoLink");
		
		if(toolTips.length !== 0){
			$(toolTips).each(function(){
				var infoContent = $(".PE_infoContainer", this);
				
				$(this).hover(
					function(){
						var infoShell = $(".PE_info", this);
						$(toolTips).css({"position": "static"});
						$(this).css({"position": "relative"});					
						$(infoContent).removeClass("hidden");
						if($(infoShell).hasClass("info_left")){
							$(infoContent).css({"left": "-205px"});
						}
						else{
							$(infoContent).css({"left": "-21px"});
						}
					},
					function(){
						$(toolTips).css({"position": "relative"});						
						$(infoContent).addClass("hidden");
						$(infoContent).css({"left": "-9999em"})
					}
				)
			})
		}
	},
	
	uiAccordion: function(){
		if($(".accordion").length !== 0){
			$(".accordion").accordion({ header: "h3" });
		}
	},
	
	featuresTab: function(){
		var itemEl = $(".itemCont");
		if (itemEl.length !== 0){
			$(itemEl).each(function(){
				var itemCont = $(this);
				var itemLink = $(".itemLink", this);
				var itemInner = $(".itemDesc", this).html();
				$(itemLink).click(function(){					
					$("#descContainer").css({'height': 'auto'});
					$("#descContainer").html(itemInner);
					
					$(itemEl).removeClass("active");
					$(itemEl).removeClass("preActive");
					$(itemCont).addClass("active");
					
					var containerHeight = $("#descContainer").height();

					if(containerHeight > 360){
						$("#descContainer").height(containerHeight);
					}
					else{
						$("#descContainer").height(360);
					}
					
					var itemClicked = itemEl.index(itemCont);					
					if(
					   itemClicked !== 0){
						$(itemEl[itemClicked-1]).addClass("preActive");
					}
					
					return false;
				});
			});
		}

	},
	
	tableGridStyle : function() {
		if($(".friendsFamilyMobile table").length !== 0){
			$(".friendsFamilyMobile table thead th:last-child").addClass("last");
			$(".friendsFamilyMobile table tbody td:last-child").addClass("last");
		}   
	},
	
	//Phone book search options
	phoneBookOptions: function() {
		var phoneBook = $(".phoneBookForm");

		if(phoneBook.length !== 0){
			$(phoneBook).each(function(){
				var inputButtons = $(".searchOptionsPB .searchOption", this);
				var phoneBookNameField = $(".PBFields .phoneBookName", this);
				var phoneBookInputItems = $(".searchOptionsPB ul li", this);
				
				$(inputButtons).click(function(){
						$(phoneBookInputItems).removeClass("selected");
						$(this).parent().addClass("selected");
						var relatedPBId = "#" + $(this).attr("id") + "Field";
						$(phoneBookNameField).addClass("hidden");
						$(relatedPBId).removeClass("hidden");
						return false;
				})
			})
		}
	},
	
	//BT Infinity combined module
	infinityTabs: function(){
		if($(".infinitySnapshot").length !== 0){
			$("#getGoing").addClass("hidden");
			
			$(".pannel").hover(
				function(){
					$(this).addClass("hover");
				},
				function(){
					$(this).removeClass("hover");
				}
				
			);
		
			$(".thumbnail").click(function(){
				$("#getGoing").addClass("hidden");
				$("#webisodes").css({'display': 'block'});
				$(".pannel").removeClass("selected");
				$(this).parent().addClass("selected");
				
				if($(this).parent().hasClass("webDemo")){
					$("#webisodes").removeClass("videos");
				}
				else{
					$("#webisodes").addClass("videos");
				}
				return false;
			})
			
			$(".htmlCont").click(function(){
				$(".pannel").removeClass("selected");
				$("#getGoing").removeClass("hidden");
				$("#webisodes").css({'display': 'none'});
				$(this).addClass("selected");
				
				return false;
			})	
			
		}
		
	}
};

/* ADDED BY C.MULLEY 15/06/09
** Dynamically hide/show Vision Panel in Packages - remove when tab1 is selected
*/	
function hideVisContent(tab){
	var visContent = document.getElementById("pacVisDetails");
	if(visContent && tab)
	{
		if (tab == 'tab1' || tab == '#tab1')
			visContent.className = "hidden";
		else
			visContent.className = visContent.className.replace(/hidden/, "");
	}		
}

LBI.Common = {
	isLtIE7 : false,
    detectLtIE7 : function() {
        var getIEMajorVersion = function() {
            if(navigator.appName === "Microsoft Internet Explorer"){
                var regExp = /MSIE\s(\d+)\./gi;
                var testUA = regExp.exec(navigator.userAgent);
                return testUA[1];
            }else{
                return false;
            }
        }
        var IEVersion = getIEMajorVersion();		
        if (IEVersion && IEVersion < 7) {
            this.isLtIE7 = true;
        }else {
            this.isLtIE7 = false;
        }
    },
	addDecimal : function(objOpt) {
		var places = [10, 100, 1000];
		var multi = places[(objOpt['places'] - 1)];
		if (objOpt['action'] === 'add') {
			result = parseInt((objOpt['item1'] * multi) + (objOpt['item2'] * multi), 10) / multi;
		} else {
			result = parseInt((objOpt['item1'] * multi) - (objOpt['item2'] * multi), 10) / multi;
		}
		return result;
	},
	objOpacity :  {
		set : function(elm, opacity) {
			$(elm).css({ 'opacity' : opacity});						
		},
		get : function(elm) {
			if(elm.filters !== undefined) { 
				return (elm.filters.alpha) ?  (elm.filters.alpha.opacity / 100) : 1;
			} else {
				return $(elm).css( 'opacity' );
			};			
		}
	},
	//get events, cross browser
	readEvent : function(oEvent, prop) {
		if(!oEvent) { var oEvent = window.event; }
		if(prop === "eventObj") { return oEvent; }
		if(prop === "target") {
			return (oEvent.target !== undefined) ? oEvent.target : oEvent.srcElement;
		}
	},
	//handle cross-browser reading of CSS-set styles
	getStyle : function(el,stylename){
		if(el.style[stylename]){
			return el.style[stylename];
		}
		else if(el.currentStyle){
			//handle IE's style-name to styleName convention
			if(stylename.indexOf("-") != -1 && !el.currentStyle[stylename]){

				//get 1st char after -, uppercase, rem -
				var preHyphen = stylename.substr(0,stylename.indexOf("-"));
				var postHyphenFirstLetter = stylename.substr(stylename.indexOf("-")+1,1).toUpperCase();
				var postHyphenRemainder = stylename.substr(stylename.indexOf("-")+2);
				stylename = preHyphen + postHyphenFirstLetter + postHyphenRemainder;
			}
			return el.currentStyle[stylename];
		}
		else if(document.defaultView && document.defaultView.getComputedStyle){
			return document.defaultView.getComputedStyle(el,null).getPropertyValue(stylename);
		}
		else{return false;}
	},
	//handle cross-browser viewport height
	getViewPortHeight : function(){
		if(window.innerHeight){
			return window.innerHeight;
		}
		else if(document.documentElement && document.documentElement.clientHeight){
			return document.documentElement.clientHeight;
		}
		else if(document.body){
			return document.body.clientHeight;
		}
		else{return false;}
	},
	//handle cross-browser viewport width
	getViewPortWidth : function(){
		if(window.innerWidth){
			return window.innerWidth;
		}
		else if(document.documentElement && document.documentElement.clientWidth){
			return document.documentElement.clientWidth;
		}
		else if(document.body){
			return document.body.clientWidth;
		}
		else{return false;}
	},
	//find and compare viewport and body heights and widths. return the largest of each dimension in array
	getFullPageDimensions : function(){
		var newHeight = LBI.Common.getViewPortHeight();
		var newWidth  = LBI.Common.getViewPortWidth();
		/*compare with body */
		if(newWidth < document.body.clientWidth){
			newWidth = document.body.clientWidth;
			newWidth += parseInt(LBI.Common.getStyle(document.body,"margin-left")) + parseInt(LBI.Common.getStyle(document.body,"margin-right"));
		}
		if(newHeight < document.body.clientHeight){
			newHeight = document.body.clientHeight;
			newHeight += parseInt(LBI.Common.getStyle(document.body,"margin-top")) + parseInt(LBI.Common.getStyle(document.body,"margin-bottom"));
			if(window.innerWidth && window.innerWidth > document.body.scrollWidth){newWidth -= 17;}//handle Firefox bug where it counts the scrollbar too for scrolling pages
		}
		else if(newHeight < document.body.scrollHeight){//quirksmode handling
			newHeight = document.body.scrollHeight;
		}
		
		return [newWidth,newHeight];
	},
	//handle cross-browser retrieval of how far user has scrolled down
	getScrollTop : function(){
		if(window.pageYOffset){
			return window.pageYOffset;
		}
		else if(document.documentElement && document.documentElement.scrollTop){
			return document.documentElement.scrollTop;
		}
		else if(document.body){
			return document.body.scrollTop;
		}
		else{return false;}
	},
	// returns values of all select options
	getSelectVals : function(oWrapper)	{
			var els=oWrapper.getElementsByTagName("select");var o=new Array();
			for (var aSelV=0;aSelV<els.length;aSelV++)	{o[aSelV]=els[aSelV].value;}
			return o;
	},
	// returns true if radio buttons inside object oWrapper is checked, else false
	getRadioSelected: function(oWrapper)	{
		var els=oWrapper.getElementsByTagName("input");
		for (var aSel=0;aSel<els.length;aSel++)	{
			if(els[aSel].checked)	{
				return true;
			}
		}
		return false;
	},	
	// returns check Boolean of first checkbox element inside object oWrapper
	getCheckboxVal: function(oWrapper)	{
		return oWrapper.getElementsByTagName("input")[0].checked;
	},
	// returns value of first textarea element inside object oWrapper
	getTextareaVal: function(oWrapper)	{
		return oWrapper.getElementsByTagName("textarea")[0].value;
	},
	// returns value of first input element inside object oWrapper
	getInputVal: function(oWrapper)	{
		return oWrapper.getElementsByTagName("input")[0].value;
	},
	// removes given node obj (oNode). returns true/false status on node removal
	removeNodeByObj: function(oNode)	{
		if (oNode)	{
			oNode.parentNode.removeChild(oNode);
			return true;
		}	else	{
			return false;
		}
	},
	// removes given node string (nodeId). returns true/false status on node removal
	removeNodeById: function(strNodeId)	{
		if (document.getElementById(strNodeId))	{
			var oNode=document.getElementById(strNodeId);
			return this.removeNodeByObj(oNode);
		}	else	{
			return false;
		}
	},
	// returns an absolute y position of the given element object 'o'.
	getAbsoluteY: function(o) {
		oTop=o.offsetTop;            
		while(o.offsetParent!=null) { 
			oParent=o.offsetParent;
			oTop+=oParent.offsetTop;
			o=oParent;
		}
		return oTop
	},
	// returns an absolute x position of the given element object 'o'.
	getAbsoluteX: function(o) {
		var oLeft = o.offsetLeft;
		while(o.offsetParent!=null) { 
			oParent=o.offsetParent;
			oLeft+=oParent.offsetLeft;
			o=oParent;
		}
		return oLeft
	},	
	// returns the object of the next parent/grand-parent etc. of the element object oEl of the tag type strTagName. Returns false if fails
	getParentByTagName: function(el,tagName){
	            var parent=el.parentNode;
	            while(tagName.toLowerCase()!=parent.nodeName.toLowerCase()){
	                        parent=parent.parentNode;
	                        if(!parent || parent.nodeName==="#document"){return false;}
	            }
	            return parent;
	},
	// simplifies fetching of first element by classname. returns element obj or false
	getFirstInstanceByClassName: function(oElm,strTagName,strClassName)	{
		var els=getElementsByClassName(oElm,strTagName,strClassName);
		if (els.length>0)	{
			return els[0];
		}
		return false;
	},
	//handle cross-browser adding events
	addEvent: function(obj,evt,fn){
		if(document.addEventListener){
			this.addEvent = function(obj,evt,fn){
				obj.addEventListener(evt,fn,false);
			}
		}
		else if(document.attachEvent){
			this.addEvent = function(obj,evt,fn){
				obj["e"+evt+fn] = fn;
				obj[evt+fn] = function() { obj["e"+evt+fn]( window.event ); }
				obj.attachEvent( "on"+evt, obj[evt+fn] );
			}
		}
		else{
			return false;
		}
		this.addEvent(obj,evt,fn);
	},
	fuzzyClassName: function(tag,fClass)	{
		var el = (tag === "*" && document.all) ? document.all : document.getElementsByTagName(tag);
		var o=new Array();
		for (var i=0;i<el.length;i++)	{
			if (el[i].className.indexOf(fClass)!=-1)	{
				o.push(el[i]);
			}
		}
		return o;
	},
	//as fuzzyClassName, but restriced to self and children of a specific DOM object
	fuzzyClassNameBlock : function(block,tag,fClass)	{
		var el = (tag === "*" && block.all) ? block.all : block.getElementsByTagName(tag);
	
		var o=new Array();
		for (var i=0;i<el.length;i++)	{
			if (el[i].className.indexOf(fClass)!=-1)	{
				o.push(el[i]);
			}
		}
		if(block.className.indexOf(fClass)!=-1){
			o.push(block);
		}
		return o;
	},
	//get the contents between ( and ) marks attached to a classname that starts with a given marker
 	getPEClassInfo: function(el,marker){
		var fullClass = el.className;
		var info = fullClass.substring(fullClass.indexOf(marker+"(")+marker.length+1);
		info = info.substring(0,info.indexOf(")"));
		return info;
	},
	/* function for making panels equal height */

	equalisePanelHeights: function() {
		var equal_container_divs = getElementsByClassName(document,'div','equalPanelHeights');
		for (var i=0; i<equal_container_divs.length; i++) {
			equalise(equal_container_divs[i]);
		}
		// the equaliser;
		function equalise(container_div) {
			var max_height = 0;
			//Get all the homePromos
			var content_divs = getElementsByClassName(container_div,'div','equalMe');
			//If there are more than 1 homePromos
			if(content_divs.length > 1) {
				//find the max height of the homePromos
				for (var i=0; i<content_divs.length; i++) {
						max_height = (content_divs[i].offsetHeight > max_height) ? content_divs[i].offsetHeight : max_height;
				}
				//set all the homePromo conts to be equivalent to this max height minus top and base
				for (var i=0; i<content_divs.length; i++) {
					//get each cont
					var innerDivToEnlarge = getElementsByClassName(content_divs[i], 'div', 'cont');
					//if there are conts
					if(innerDivToEnlarge.length > 0){
						//calculate new height
						var newHeight = equalPanel(max_height, 20)+"px";
						if (LBI.Common.isLtIE7 === true) {
							innerDivToEnlarge[0].style.height = newHeight;
						}
						innerDivToEnlarge[0].style.minHeight = newHeight;
					}
				}
			}
		}
		function equalPanel(intHeight, intExcess) {
		
		return intHeight - intExcess;
		
		}
	},
	//accessibility hack: updates the value of a hidden field to trigger a buffer refresh. called in the functions that are run when an AJAX call has returned data or error
	updateBuffer : function() {
		var bufferReset = document.getElementById("bufferReset");
		if(!bufferReset){
			var bufferReset = document.createElement("input");
			bufferReset.type="hidden";
			bufferReset.name="bufferReset";
			bufferReset.value=1;
			bufferReset.id="bufferReset";
			document.body.appendChild(bufferReset);
		}
		bufferReset.value++;
	},	
	getPEObj : function(intIdx, PEName) {
		return LBI.Custom.PEList[PEName].instLib[intIdx];
	},
	getPEName: function(strFullClass){
		var intPEStart = strFullClass.indexOf("PE_");
		return strFullClass.substring(intPEStart, strFullClass.indexOf("("));
	},
	applyAnim: function(oElm, action, anim, oAnimOpt){		
		var applyAnim = function() {
			var css = oAnimOpt.style;
			if(action !== undefined) {
				// if the action is set as a callback, run it as one. Otherwise, it gets called before the animation
				if(oAnimOpt.callback === true) {
					$(oElm).animate(css, oAnimOpt.time, oAnimOpt.tween, action);											
				} else {
					action();
					$(oElm).animate(css, oAnimOpt.time, oAnimOpt.tween);
				}
			} else {
					$(oElm).animate(css, oAnimOpt.time, oAnimOpt.tween);
			}
		};		
		var alterElm = function() {
			//if you want an animation					
			if(anim === true) {
				//run the function sent as the animation parameter
				applyAnim();						
			} else {
				action(oElm);
			}
		}
		alterElm();			
	},	
	stopAnim : function(arrAnims, arrTimeouts) {
		if(timeout !== undefined) {
			for(var timeout in arrTimeouts) {
				window.clearTimeout(arrTimeouts[timeout]);
			}
		}
		if(arrAnims !== undefined) {
			for(var anim in arrAnims) {
				$(arrAnims[anim]).stop();
			}
		}
	},
	createPE : function(oCore, intIdx, strPEName) {
		var constr = function() {};
		var oBase = new LBI.Custom.classLib.base(oCore, intIdx); // copy base
		for(var strProp in LBI.Custom.classLib[strPEName]) { // copy class members
			oBase[strProp] = LBI.Custom.classLib[strPEName][strProp];
		}		
		constr.prototype = oBase;
		oNewObj = new constr;
		if(oNewObj.arrMembers !== undefined) { oNewObj.getMembers(); }		
		return oNewObj;
	},
	
	/* ajaxLoader is a shell function for running a library-based ajax call 
	 * Parameters stored in an oOptions object are: 
	 * 	url (string)
	 * 	errorLog : function to run on error
	 * 	timer : how long before call times out (integer)
	 *  dataType : data type to request, i.e. xml (string)
	 *  coreObj : a reference to the oOptions object so it can use it's methods - usually this
	 *  successLog : function to run on success (for calls that need resulting data to be processed). Is passed resulting object as 1st param
	 */ 
	ajaxLoader : function(oOptions) {
		var strUrl = oOptions.url;
		var errorLog = oOptions.errorLog;		
		var intTimer = oOptions.timer;
		var successLog = oOptions.successLog;
		var strData = oOptions.data;
			$.ajax({
					type : "GET",
					url : strUrl,
					success : function(data) {
						successLog(data);
					},
					error : errorLog,
					timeout : intTimer,
					dataType : strData
			});	
	}
};

// function to open links in a new window

function externalLinks() {
 if (!document.getElementsByTagName) return;
 var anchors = document.getElementsByTagName("a");
 for (var i=0; i<anchors.length; i++) {
   var anchor = anchors[i];
   if (anchor.getAttribute("href") &&
       anchor.getAttribute("rel") == "external")
     anchor.target = "_blank";
 }
} 


/********** DOM READY STATE CHECKING, WITH ONLOAD FALLBACK. **********/
// hide masthead panels on Home page - to eliminate initial display of all panels in IE6/IE7 

/* DO NOT REMOVE THIS SECTION - IE CONDITIONAL COMPILATION */
/*@cc_on @*/
/*@if (@_win32)
document.write("<script id=el_ie defer src='../includes/consumer/consumerProducts/js/blank.js'><\/script>");var script = document.getElementById("el_ie");script.onreadystatechange = function() {
if (this.readyState === "complete") {onloadhandler();}}
/*@end @*/
/* IE CONDITIONAL COMPILATION ENDS */

window.initialised=false;
if (document.addEventListener) {document.addEventListener("DOMContentLoaded", layerinit, false);}

/* safari regular polling */
if (/WebKit/i.test(navigator.userAgent)) { // sniff webkit-based browser
	var _timer = setInterval(function() {
		if (/loaded|complete/.test(document.readyState)) {
			if (window.initialised){return;}
			layerinit(); // call the onload handler
		}
	}, 10);
}
/* fallback for all other browsers */
window.onload=onloadhandler;
/*########################################################################################################*/
// FUNCTIONS TO RUN WHEN DOM IS READY
function layerinit()	{

	//Functions carried forward from global.js
	btpeFlashLoad();
	restoreImages();
	clearChecks();
	if (typeof popupActions != "undefined") {
		popupActions();
	}
	colClears(2,"productResults","li","productResult");
	gallery("mainPic","thumbs","standard");
	aToZ_interactive();
	
	window.initialised=true;	

	LBI.Common.detectLtIE7();		
	LBI.Custom.setUpNav();
	LBI.Custom.PERoundUp();
	LBI.Custom.setup();
	validator();
	popup();
	Lightbox.init(); //set up lightboxes	
	setupInputHover();
	pngHandling();
	externalLinks();
	formClear();
	detectUserState();
	if(document.getElementById("calculator") !== null) { loadXML(); }
	if(document.getElementById("internationalRates") !== null) { loadTariffXML(); }
	if(document.getElementById("compareBbPage") !== null) { loadCompareXML(); }
	if(document.getElementById("compareTariff") !== null) { loadCompareXML(); }
	if(document.getElementById("compareBunPage") !== null) { loadCompareXML(); }
	if(document.getElementById("digitalMap") !== null) { digitalXML(); }
	if(document.getElementById("packageSelector") !== null) { packageSelectorXML(); }
	if(document.getElementById("chooser") !== null) { packageChooserXML(); basketDisplay();noPack()}
	if(document.getElementById("homePhnSec") !== null) { hideDetails(); }
	if(document.getElementById("pvImg") !== null) {LBI.Custom.setPreview();}
	/* Added for oneclick functionality */
	if(document.getElementById("oneclick") !== null) { initForm(); }	
	LBI.Custom.carousel();
	LBI.Custom.setSevenTabNav();
	LBI.Custom.assignSevenTabNav();
	LBI.Custom.articleContent();
	LBI.Custom.onPageFlash();
	LBI.Custom.tabBanner();
	LBI.Custom.columnHover();
	LBI.Custom.columnHoverPink();	
    LBI.Custom.infoTooltop();
	LBI.Custom.uiAccordion();
	LBI.Custom.featuresTab();
	LBI.Custom.tableGridStyle();
	LBI.Custom.phoneBookOptions();
	LBI.Custom.infinityTabs();
}

function onloadhandler()	{
	if (window.initialised){return;}
	layerinit(); // will only execute if layerinit hasn't already executed
}
/********** END DOM READY **********/
