//<%--
//********************************************************************
//*-------------------------------------------------------------------
//* Licensed Materials - Property of IBM
//*
//* WebSphere Commerce
//*
//* (c) Copyright IBM Corp.  2007
//* All Rights Reserved
//*
//* US Government Users Restricted Rights - Use, duplication or
//* disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
//*
//*-------------------------------------------------------------------
//*
//--%>

	dojo.registerModulePath("wc", "wc");
	
	dojo.require("dojo.io.*");
	
	//product quick view with tooltip widget
	dojo.require("wc.widget.ProductQuickView");
	dojo.require("wc.widget.BaseContent");
	dojo.require("wc.widget.ToolTipContent");

	//category menu support
	dojo.require("dojo.widget.Button");
	dojo.require("dojo.widget.Menu2");
		
	//reload widgets when parts of the page has been re-loaded from server
	dojo.require("dojo.xml.Parse");
	
	//publish and subscribe event support
	dojo.require("dojo.event.*");
	
	dojo.require("wc.widget.ScrollablePane");
	dojo.require("dojo.animation.*");
	dojo.require("dojo.lfx.*");
	dojo.require("dojo.string.extras");
	dojo.require("dojo.collections.ArrayList");

	dojo.require("dojo.widget.TabContainer");
	dojo.require("dojo.widget.ContentPane");
	dojo.require("dojo.widget.Button");
	dojo.require("dojo.widget.Tree");
	dojo.require("dojo.widget.TreeSelector");

	dojo.require("dojo.undo.browser");

	dojo.require("wc.widget.RefreshArea");
	dojo.require("wc.render.RefreshController");
	dojo.require("wc.render.Context");
	dojo.require("dojo.widget.Tooltip");
	
Common={
	//All the global variables declarations will be here
	errorMessages: {},
	
	activeBubbles: new Array(),
	
	//summary: This is a collection of commonly used functions
	containsDoubleByte:function(target) {
		// summary:Checks whether a string contains a double byte character
		// target = the string to be checked
		//
		// Return true if target contains a double byte char; false otherwise
		 var str = new String(target);
		 var oneByteMax = 0x007F;

		 for (var i=0; i < str.length; i++){
			chr = str.charCodeAt(i);
			if (chr > oneByteMax) {return true;}
		 }
		 return false;
	},
	
	
	isValidEmail:function(strEmail){
		//summary: A simple function to validate an email address
		// It does not allow double byte characters
		// strEmail = the email address string to be validated
		//
		// Return true if the email address is valid; false otherwise
		if (Common.containsDoubleByte(strEmail)){
			return false;
		}
		
		var re = /^(("[\w-\s]+")|([\w-]+(?:\.[\w-]+)*)|("[\w-\s]+")([\w-]+(?:\.[\w-]+)*))(@((?:[\w-]+\.)*\w[\w-]{0,66})\.([a-z]{2,6}(?:\.[a-z]{2})?)$)|(@\[?((25[0-5]\.|2[0-4][0-9]\.|1[0-9]{2}\.|[0-9]{1,2}\.))((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[0-9]{1,2})\.){2}(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[0-9]{1,2})\]?$)/i	
		
 		return strEmail.match(re); 		
	},
	
	getCurrentYear: function(){
		//summary: returns the current year. 
		return new Date().getFullYear();
	}, 
	
	getCurrentMonth: function(){
		//summary: returns the current month. January is 1, and Decement is 12. 
		return new Date().getMonth()+1;	
	}, 
	
	getCurrentDay: function(){
		//summary: returns the current day of the current month, starting from 1. 
		return new Date().getDate();
	}, 
	
	getRenderContextProperty : function(/*wc.render.Context*/context, /*String*/propertyName){
		//summary: retrieves the value of the property from a render context
		//description: This function retrieves the value of the property whose name is propertName
		//	from the given context. 
		//returns: null if the context is null. undefined if the property is not found. 
		//	otherwise, the value of the property int he given context. 
		dojo.debug("enter getRenderContextProperty with propertyName = "+propertyName);
		if(context == null){
			dojo.debug("context is null. Return null...");
			return null;
		}
		
		var result = context.properties[propertyName]
		dojo.debug("the found property value is: "+result);
		
		return result;	
	}, 
	
	loadAddressContentFromURL: function(/*String*/contentURL, /*String*/areaID, /*String*/method, /*Object?*/params){
		//summary: loads the response from invoking a given URL to the area that has the given ID. 
		//description: This function invokes the given contentURL, and then updates the area whose ID is 
		//	the given areaID with the response content. 
		//contentURL: the URL used to get new content
		//areaID: the ID of the area that will be updated. The area can be anything that supports
		//	innerHTML, such as table, and div. 
		//method: The HTTP method used for invoking the given URL. The default is GET.
		//params: Optional parameters used when invoking URL
		var contentArea = document.getElementById(areaID);
		if(!contentArea){
			return;	
		}
		
		dojo.io.bind({
			url: contentURL,
			method: method?method:'GET',
			load: function(type, data, evt){
				contentArea.innerHTML = data;
				cursor_clear();	
			},
			mimetype: "text/html", 
			params: params
		});
		cursor_wait();
	}, 
	
	loadAddressContentFromForm: function(form, areaID, params){
		//summary: loads the response from submitting a given form to the area that has the given ID. 
		//description: This function submits a given form, and then updates the area whose ID is 
		//	the given areaID with the response content. 
		//form: the form that is to be submitted
		//areaID: the ID of the area that will be updated. The area can be anything that supports
		//	innerHTML, such as table, and div. 
		var contentArea = document.getElementById(areaID);
		if(!contentArea){
			return;	
		}
		
		dojo.io.bind({
			formNode: form, 
			load: function(type, data, evt){
				contentArea.innerHTML = data;
				cursor_clear();	
			},
			mimetype: "text/html", 
			params: params
		});
		cursor_wait();
	}, 
	
	
	getErrorFields: function(serviceResponse){
		if(!serviceResponse){
			return [];	
		}
		
		var result = serviceResponse.errorMessageParam;
		if(dojo.lang.isArrayLike(result)){
			return result;	
		}else{
			return [result];	
		}
	}, 
	
	reportServiceError: function(/*String*/formName, /*JSONObject*/serviceResponse){
		dojo.require("dojo.html.*");
		dojo.lang.forEach(Common.getErrorFields(serviceResponse), function(field){
			var input = document.forms[formName].elements[field];
			input.style.border="thick double red ";
			input.focus();
			input.value="Please enter this field";
		});	
	},	
	
	setErrorMessage:function(key, msg) {
	///////////////////////////////////////////////////////////////////
	// summary: This function is used to initialize the error messages object 
	//	with all the required error messages.
	// Description: Setup a JS object with any key/value.
	// key: The key used to access this error message.
	// msg: The error message in the correct language.
	//////////////////////////////////////////////////////////////////
		this.errorMessages[key] = msg;
	},
	
	formErrorHandle:function(serviceResponse,formName,parentDivName){
			
	///////////////////////////////////////////////////////////////////
	// summary: This function will show the an error message tooltip
	//    around the input field with the problem.
	// Description: The function assumes the "serviceResponse" is the
	//    JSON object from a WebSphere Commerce exception. The error 
	//    field is in the serviceResponse.errorMessageParam and the
	//    error message is in the serviceResponse.errorMessage.
	// serviceResponse: The JSON object with the error data.
	// formName: The name of the form where the error field is.
	// parentDivName: The name of the division area that contains the
	//    form with the error field.
	//////////////////////////////////////////////////////////////////	
	 this.formErrorHandleClient(serviceResponse.errorMessageParam, serviceResponse.errorMessage, formName, parentDivName);

  },

  formErrorHandleClient:function(errorInputField,errorMessage,formName,parentDivName,bypassFieldFocus,postHideFunc){
	dojo.debug("ERROR! "+parentDivName+"."+formName+"."+errorInputField+": "+errorMessage);		
	
	///////////////////////////////////////////////////////////////////
	// summary: This function will show the an error message tooltip
	//    around the input field with the problem.
	// Description: The function takes the error field name and the 
	//    error message to display.
	// errorInputField: The name of the field with error.
	// errorMessage: The error message to display.
	// formName: The name of the form where the error field is.
	// parentDivName: The name of the division area that contains the
	//    form with the error field.
	// bypassFieldFocus: An optional boolean specifying that the focus
	//    should not be given to the element.
	// postHideFun: An option function to call after the error message 
	//    is surpressed.
	//////////////////////////////////////////////////////////////////	
	 //this.hideErrorNode();	
	 var form = document.forms[formName];
	 //alert("1: "+form);
	 var parent =document.body;

	 if(form.elements[errorInputField]){
		 var input = form.elements[errorInputField];
		// dojo.debug("ERROR input id! "+input.id );		
		 
		 var oldClass = input.className;
		 var x = dojo.html.getAbsolutePosition(input, true).x + input.offsetWidth;
		 var y = dojo.html.getAbsolutePosition(input, true).y - 8;
		 if (this.activeBubbles.length == 0 && !bypassFieldFocus) {
		 	input.focus();
		 }
		 input.className += ' errorBorder';
		 if (postHideFunc) {
			 input.onclick=(function() {this.className = oldClass; Common.hideErrorNode(x,y); postHideFunc();});
			 input.onkeypress=(function() {this.className = oldClass; Common.hideErrorNode(x,y); postHideFunc();});
			 if (input.id == 'addressTypeSelection') {
			 	input.onchange=(function() {this.className = oldClass; Common.hideErrorNode(x,y); loadFields(); postHideFunc();});
			 }
			 else if (input.id == 'addressField2') {
			 	input.onchange=(function() {this.className = oldClass; Common.hideErrorNode(x,y); AddressBookFormJS.loadFields(''); postHideFunc();});
			 }
			 else if (input.id == 'WC_country_1') {
			 	input.onchange=(function() {this.className = oldClass; Common.hideErrorNode(x,y); javascript:AddressHelper.loadStatesUI(formName, ''); postHideFunc();});
			 }
			 else if (input.id == 'QAS_country') {
			 	input.onchange=(function() {this.className = oldClass; Common.hideErrorNode(x,y); javascript:AddressHelper.loadStatesUI(formName, ''); postHideFunc();});
			 }			 			 
			 else {
			 	input.onchange=(function() {this.className = oldClass; Common.hideErrorNode(x,y); postHideFunc();});
			 }
		 }
		 else {
			 input.onclick=(function() {this.className = oldClass; Common.hideErrorNode(x,y);});
			 input.onkeypress=(function() {this.className = oldClass; Common.hideErrorNode(x,y);});
			 if (input.id == 'addressTypeSelection') {
			 	input.onchange=(function() {this.className = oldClass; Common.hideErrorNode(x,y); loadFields();});
			 }
			 else if (input.id == 'addressField2') {
		    	//dojo.debug("ERROR address field! "+input.id );		
			 	input.onchange=(function() {this.className = oldClass; Common.hideErrorNode(x,y); AddressBookFormJS.loadFields('');});
			 }
			 else if (input.id == 'WC_country_1') {
			 	input.onchange=(function() {this.className = oldClass; Common.hideErrorNode(x,y); javascript:AddressHelper.loadStatesUI(formName, '');});
			 }
			 else if (input.id == 'QAS_country') {
			 	input.onchange=(function() {this.className = oldClass; Common.hideErrorNode(x,y); javascript:AddressHelper.loadStatesUI(formName, '');});
			 }			 
			 else {
			 	input.onchange=(function() {this.className = oldClass; Common.hideErrorNode(x,y);});
			 }
		 }
		 this.setErrorMsg(input.parentNode,errorMessage,x,y);
		 this.activeBubbles.push(input);
	 }else{
		 Common.hideErrorNodes();
		 alert(errorMessage);
	 }
  },

  setErrorMsg:function(parentNode,content,x,y){
    

	///////////////////////////////////////////////////////////////////
	// summary: This function will set the Error Message and position for the "errorNode".
	// Description: This function will takes "parentNode" , "content" and positions x,y  
	// as input arguments, and set those to "errorNode" 
	// if "errorNode" is not created,then it will call "createErrorNode" 
	// method first before setting message and position.
	//////////////////////////////////////////////////////////////////	

	 //if(document.getElementById('bubble')) var errorNode = document.getElementById('bubble');
	 //else 
	 var errorNode = this.createErrorNode(parentNode, x, y);
	 
	 var msg=document.getElementById("content_"+x+"_"+y);
	 msg.innerHTML = content;
	  
//	 errorNode.style.left = x +"px";
//	 errorNode.style.top = y + "px";
//	 Common.showElement(errorNode);
  },
   
  createErrorNode:function(parentNode, x, y){
	   

	///////////////////////////////////////////////////////////////////
	// summary: This function will create new "errorNode".
	// Description: This function will take "parentNode" as input arguments,  
	// it will create new "errorNode" and appends that to "parentNode", then
	// it will return that "errorNode".
	//////////////////////////////////////////////////////////////////	
    
    var errorNode = document.createElement("div")
	errorNode.id="bubble_"+x+"_"+y;
	errorNode.className="bubble";
	errorNode.style.zIndex = "2000";
	parentNode.appendChild(errorNode);
  	var imgDiv = document.createElement("div");
  	errorNode.appendChild(imgDiv);
  	var img = document.createElement("img");
  	img.src = Environment.storeImgDir+"images/error_arrow.gif";
  	imgDiv.appendChild(img);
	
	var xtop = document.createElement("div");
	xtop.className="xtop";
	errorNode.appendChild(xtop);
	
	var xt1 = document.createElement("div");
	xt1.className="xb1";
	xtop.appendChild(xt1);
	var xt2 = document.createElement("div");
	xt2.className="xb2";
	xtop.appendChild(xt2);
	var xt3 = document.createElement("div");
	xt3.className="xb3";
	xtop.appendChild(xt3);
	var xt4 = document.createElement("div");
	xt4.className="xb4";
	xtop.appendChild(xt4);

	var contentDiv = document.createElement("div");
	contentDiv.className="xboxcontent";
	errorNode.appendChild(contentDiv);
	var content = document.createElement("p");
	content.classname="content";
	content.id="content_"+x+"_"+y;
	contentDiv.appendChild(content);
	
	var xbottom = document.createElement("div");
	xbottom.className="xbottom";
	errorNode.appendChild(xbottom);
	var xb4 = document.createElement("div");
	xb4.className="xb4";
	xbottom.appendChild(xb4);
	var xb3 = document.createElement("div");
	xb3.className="xb3";
	xbottom.appendChild(xb3);
	var xb2 = document.createElement("div");
	xb2.className="xb2";
	xbottom.appendChild(xb2);
	var xb1 = document.createElement("div");
	xb1.className="xb1";
	xbottom.appendChild(xb1);
/*
    var errorNode = document.createElement("table")
	errorNode.id="bubble_"+x+"_"+y;
	errorNode.className="bubble";
	errorNode.style.zIndex = 2000;
	errorNode.cellPadding = "0";
	errorNode.cellSpacing = "0";
	parentNode.appendChild(errorNode);
	
	var xtop = document.createElement("tr");
	xtop.className = "xtop";
	errorNode.appendChild(xtop);
	var tl = document.createElement("td");
	xtop.appendChild(tl);
	var img_tl = document.createElement("img");
	img_tl.src = Environment.storeImgDir+"images/error-top-left.gif";
	tl.appendChild(img_tl);
	var tm = document.createElement("td");
	tm.style.background = "url('"+Environment.storeImgDir+"images/error-top.gif"+"')";
	xtop.appendChild(tm);
	var tr = document.createElement("td");
	xtop.appendChild(tr);
	var img_tr = document.createElement("img");
	img_tr.src = Environment.storeImgDir+"images/error-top-right.gif";
	tr.appendChild(img_tr);
	
	var xboxcontent = document.createElement("tr");
	xboxcontent.className="xboxcontent";
	errorNode.appendChild(xboxcontent);
	var ml = document.createElement("td");
	ml.style.background = "url('"+Environment.storeImgDir+"images/error-left.gif"+"')";
	xboxcontent.appendChild(ml);
	var mm = document.createElement("td");
	xboxcontent.appendChild(mm);
	var content = document.createElement("p");
	content.classname="content";
	content.id="content_"+x+"_"+y;
	mm.appendChild(content);
	var mr = document.createElement("td");
	mr.style.background = "url('"+Environment.storeImgDir+"images/error-right.gif"+"')";
	xboxcontent.appendChild(mr);
	
	var xbottom = document.createElement("tr");
	xbottom.className = "xbottom";
	errorNode.appendChild(xbottom);
	var bl = document.createElement("td");
	xbottom.appendChild(bl);
	var img_bl = document.createElement("img");
	img_bl.src = Environment.storeImgDir+"images/error-bottom-left.gif";
	bl.appendChild(img_bl);
	var bm = document.createElement("td");
	bm.style.background = "url('"+Environment.storeImgDir+"images/error-bottom.gif"+"')";
	xbottom.appendChild(bm);
	var br = document.createElement("td");
	xbottom.appendChild(br);
	var img_br = document.createElement("img");
	img_br.src = Environment.storeImgDir+"images/error-bottom-right.gif";
	br.appendChild(img_br);
*/
	return errorNode;
  },
  hideCCError:function(){
	///////////////////////////////////////////////////////////////////
	// summary: This function will remove the Error for the credit card
	// Description: This function will remove Error for the credit card if its there,  
	//////////////////////////////////////////////////////////////////	
		while (this.activeBubbles.length > 0) {
			var element = this.activeBubbles.pop();	
			if(element.id == 'userCreditCard2') {
				var removalFunction = element.onclick;
				removalFunction();
				element.onclick = "";
				element.onkeypress = "";
			}
		}
  },
  hideErrorNode:function(x,y){
	///////////////////////////////////////////////////////////////////
	// summary: This function will remove the "errorNode".
	// Description: This function will remove the "errorNode" if its there,  
	//////////////////////////////////////////////////////////////////	
	if(document.getElementById('bubble_'+x+'_'+y))
		dojo.dom.removeNode(document.getElementById('bubble_'+x+'_'+y));

  },
  hideErrorNodes:function(){
	while (this.activeBubbles.length > 0) {
		var element = this.activeBubbles.pop();
		if(element) {
			var removalFunction = element.onclick;
			removalFunction();
			element.onclick = "";
			element.onkeypress = "";
		}
  	}
  	this.activeBubbles = new Array();
  },
	
	isValidUTF8length: function(UTF16String, maxlength) {
	//////////////////////////////////////////////////////////
	// summary: This function will check if the number of bytes of the string
	// is within the maxlength specified.
	// Description: Check if the number of bytes is within the maxlength specified.
	//
	// UTF16String: the UTF-16 string
	// maxlength: the maximum number of bytes allowed in your input field
	//
	// Return false is this input string is larger then arg2
	// Otherwise return true...
	//////////////////////////////////////////////////////////
	    if (this.utf8StringByteLength(UTF16String) > maxlength) return false;
	    else return true;
	},
	
	utf8StringByteLength: function(UTF16String) {
	//////////////////////////////////////////////////////////
	// summary: This function will count the number of bytes
	// represented in a UTF-8 string
	// Description: Check if the number of bytes is within the maxlength specified.
	//
	// UTF16String: the UTF-16 string you want a byte count of...
	// Return the integer number of bytes represented in a UTF-8 string
	//////////////////////////////////////////////////////////
	  if (UTF16String === null) return 0;
	  var str = String(UTF16String);
	  var oneByteMax = 0x007F;
	  var twoByteMax = 0x07FF;
	  var byteSize = str.length;
	
	  for (i = 0; i < str.length; i++) {
	    chr = str.charCodeAt(i);
	    if (chr > oneByteMax) byteSize = byteSize + 1;
	    if (chr > twoByteMax) byteSize = byteSize + 1;
	  }  
	  return byteSize;
	},
	IsNumeric : function (text,allowDot)
	{
		// summary: this function will check whether a entered text is a numaric or not.
		// description: this function will take the 'text' and allowDot as input characters 
		// and will check whether the text is numaric or not	
		// allowDot : is a boliyan wich specifies whether to consider the '.' or not.
	   if(allowDot) var ValidChars = "0123456789.";
	   else var ValidChars = "0123456789";
	  
	   var IsNumber=true;
	   var Char;

	 
	   for (i = 0; i < text.length && IsNumber == true; i++) 
		  { 
		  Char = text.charAt(i); 
		  if (ValidChars.indexOf(Char) == -1) 
			 {
			 IsNumber = false;
			 }
		  }
	   return IsNumber;
	   
	},
	
   goBack:function(){
	
	// summary: this function belong to HistoryTracking for receiving Back notifications
	// description: this function belong to HistoryTracking for receiving Back notifications	
	
		document.getElementById(this.elementId).innerHTML = this.content;
		
        },
        
        goForward:function(){
       
	// summary: this function belong to HistoryTracking for receiving forward notifications
	// description:this function belong to HistoryTracking for receiving forward notifications	
	
        	document.getElementById(this.elementId).innerHTML = this.content;
        	
        },
		
	
	HistoryTracker:function(content, elementId, changeUrl){
	
	// summary: History state object for history tracking
	// description:History state object for history tracking
	// content: String
	//		the html to be displayed
	// elementId: String
	//		the name of the DOM object
	// changeUrl: String
	//		the identifier for the current state of this page
	
		this.content = content;
		this.elementId = elementId;
		//TODO: commenting this out breaks FF 1.5. Others? Can't seem to find iframe id/name?
		this.changeUrl =  changeUrl;
		
		
	},
	
	
	// 1 visible, 0 hidden
	toggleBox:function (szDivID, iState)  {
		var obj = document.getElementById(szDivID);
		if (obj != null) {
			obj.style.visibility = document.layers ? (iState ? "show" : "hide") : (iState ? "visible" : "hidden");
			obj.styledisplay =(iState ? "block" : "none");
		}
	},
					
	hideTabs:function (ratingsEnabled, imgDir, identifier) {
		var obj = document.getElementById('imgRev_'+identifier);
		if (obj != null && ratingsEnabled) {
			this.toggleBox('tab3_'+identifier, 0);
			obj.src=imgDir+'nav/roll_reviews_btn_up.gif';
		}
		obj = document.getElementById('imgDesc_'+identifier);
		if (obj != null) {
			this.toggleBox('tab1_'+identifier, 0);
			obj.src=imgDir+'nav/roll_description_btn_up.gif';
		}
		obj = document.getElementById('imgShip_'+identifier);
		if (obj != null) {
			this.toggleBox('tab2_'+identifier, 0);
			obj.src=imgDir+'nav/roll_shipping_btn_up.gif';
		}
	},
	
	openATab:function(ratingsEnabled, imgDir, identifier, tabNum) {
		this.hideTabs(ratingsEnabled, imgDir,identifier);
		this.toggleBox('tab'+tabNum+'_'+identifier, 1);

		switch (tabNum) {
		case 1: 
			var obj = document.getElementById('imgDesc_'+identifier);
			if (obj != null) obj.src=imgDir+'nav/roll_description_btn_dn.gif';
			break;
		case 2: 
			var obj = document.getElementById('imgShip_'+identifier);
			if (obj != null) obj.src=imgDir+'nav/roll_shipping_btn_dn.gif';
			break;
		case 3: 
			var obj = document.getElementById('imgRev_'+identifier);
			if (obj != null) obj.src=imgDir+'nav/roll_reviews_btn_dn.gif';
			break;
		}
	},

	// These methods change the display property of an element and slide an iFrame in between
	// the element and the background in order to block select boxes in IE. AKA: iframe hack.
	showElement:function (element) {
		// Create a transparent iFrame to cover select boxes in IE6
		var iframeId = 'IFRAME_'+element.id;
		var iframe = document.getElementById(iframeId);
		if (!iframe) {
			iframe = document.createElement('IFRAME');
			
			// Move the element ahead of the iframe
			iframe.style.zIndex = element.style.zIndex;
			if (!iframe.style.zIndex) {
				iframe.style.zIndex = 10;
			}
			element.style.zIndex = Number(element.style.zIndex) + 1;
		}
		
		iframe.id = iframeId;
		iframe.style.position = 'absolute';
		iframe.style.top = dojo.html.getAbsolutePosition(element, true).top+'px';
		iframe.style.left = dojo.html.getAbsolutePosition(element, true).left+'px';
		iframe.style.height = dojo.html.getContentBox(element).height+'px';
		iframe.style.width = dojo.html.getContentBox(element).width+'px';
		iframe.src = 'javascript:\'<html></html>\';';
	    iframe.style.filter = 'alpha(Opacity=0)';
		iframe.style.opacity = '0.0';

		element.parentNode.appendChild(iframe);
					
		element.style.visibility = 'visible';
	},
	
	hideElement:function (element) {
		var iframe = document.getElementById('IFRAME_'+element.id);
		if (iframe) {
			// Move the element back to it's original zIndex
			element.style.zIndex = iframe.style.zIndex;
			element.style.visibility = 'hidden';
			
			// Remove the iFrame
			element.parentNode.removeChild(iframe);
		}
	},
	
	tooltipTimeout: null,
	
	// summary: Show a tooltip
	// description: Show an element with an id of parent.id+'_tooltip'
	// parent: element
	//		the element the tooltip should appear next to
	// callbackFunction: function (optional)
	//		an optional funciton to call after the tooltip is displayed
	// skipTimeout: boolean (optional)
	//		when skipTimeout is true, the tooltip is shown immediately
	showTooltip: function(parent, callbackFunction, skipTimeout) {
		if (Common.tooltipTimeout) {
			clearTimeout(Common.tooltipTimeout);
		}
		
		if (!skipTimeout) {
			Common.tooltipTimeout = setTimeout(function() {Common.showTooltip(parent, callbackFunction, true);}, 500);
			return;
		}
		
		this.tooltipID = parent.id+'_tooltip';
		var tooltip = document.getElementById(parent.id+'_tooltip');
		if(tooltip == hoverbox_four_tooltip)
		{
		var left = (dojo.html.getAbsolutePosition(parent, true).x + dojo.html.getContentBox(parent).width)/3.1;
		var top = (dojo.html.getAbsolutePosition(parent, true).y - dojo.html.getAbsolutePosition(parent, true).y)+275;
		 
	 	}
		else if(tooltip == hoverbox_three_tooltip)
		{
		var left = (dojo.html.getAbsolutePosition(parent, true).x + dojo.html.getContentBox(parent).width)/2.4;
		var top = (dojo.html.getAbsolutePosition(parent, true).y - dojo.html.getAbsolutePosition(parent, true).y)+98;
		}
		else if(tooltip == hoverbox_two_tooltip)
		{
		var left = (dojo.html.getAbsolutePosition(parent, true).x + dojo.html.getContentBox(parent).width)/2.2;
		var top = (dojo.html.getAbsolutePosition(parent, true).y - dojo.html.getAbsolutePosition(parent, true).y)+370;
		}  
		else if(tooltip == hoverbox_three2_tooltip){	
		// Reslove defect number 3224
			var left = (dojo.html.getAbsolutePosition(parent, true).x + dojo.html.getContentBox(parent).width)/3.5;
			var top = dojo.html.getAbsolutePosition(parent, true).y-560;
		}
		else
		{
	  	var left = dojo.html.getAbsolutePosition(parent, true).x + dojo.html.getContentBox(parent).width;
		var top = dojo.html.getAbsolutePosition(parent, true).y;
		}
		tooltip.style.left = left+'px';
		tooltip.style.top = top+'px';
		tooltip.style.zIndex = '2100';
		Common.showElement(tooltip);
		if (callbackFunction) {
			callbackFunction();
		}
	},
	 
	
	hideTooltip: function(parent, delay) {
		if (Common.tooltipTimeout) {
			clearTimeout(Common.tooltipTimeout);
		}
		
		if (delay) {
			if (parent.id) {
				tooltipTimeout = setTimeout("Common.hideTooltip("+parent.id+", 0)", delay);
			}
			else {
				tooltipTimeout = setTimeout("Common.hideTooltip("+parent+", 0)", delay);
			}
			return;
		}
		
		var tooltip = document.getElementById(parent+'_tooltip');
		if (!tooltip) {
			tooltip = document.getElementById(parent.id+'_tooltip');
		}
		Common.hideElement(tooltip);
	},
	
	keepTooltip: function() {
		clearTimeout(tooltipTimeout);
	},
	
	isValidPhone: function(str) {
		tenDigits = new RegExp(/^[^\d]*(\d[^\d]*){10}$/);
		return tenDigits.test(str);
	},
	
	cleanPhone: function(str) {
		return str.replace(/[^\d]/g,'');
	},
	//Fixed bug 4524
	clearForm: function(form) {		
		for (var i=form.elements.length-1; i>=0; i--) {
			if (form.elements[i].type != "hidden") {
				if(form.elements[i].name == "country"){
					form.elements[i].value="US";
					AddressHelper.loadStatesUIForUserReg(form.name,'')
				}				
				else{					
					form.elements[i].value = "";									
				}
				
			}
		}
	}
} 
	Common.HistoryTracker.prototype.back = Common.goBack;
	Common.HistoryTracker.prototype.forward=Common.goForward;
