NS4 = (document.layers);
IE4 = (document.all);
ver4 = (NS4 || IE4);
IE5 = (IE4 && navigator.appVersion.indexOf("5.")!=-1);
IE5UP = (IE4 && IE5 && navigator.appVersion.indexOf("MSIE 5.0")==-1);



// This error handling function traps any JavaScript errors, collects the data
// and then sets the location of an invisible frame to go to the AFS error server page
// so that we can collect the information and get ahead of all JS errors



//selectBoxLayers = new Array(); 	// This contains a list of select box layers. Dynamic HTML such as hiermenus
				 // can use this to turn them invisible if necessary
function captureEnter(action,args,ev){
	if(! ev) ev = window.event;
	var keyPressed = null;
	if (ev.which) keyPressed = ev.which;
	else if (ev.keyCode) keyPressed = ev.keyCode;
	if (keyPressed == 13){
		action.apply(null,args);
	}
	return false;
}

function setDomain(){
	arrayOfStrings=document.domain.split(".");
	if(arrayOfStrings.length>=3){
		var newDomain='';
		for(var i=1;i<arrayOfStrings.length; i++){
			newDomain+=arrayOfStrings[i];
			if(i+1!=arrayOfStrings.length)
				newDomain+=".";
		}
		document.domain=newDomain;
	}
}

function contains(arry, value){
	var l=arry.length;
	for(i=0;i<l;i++){
		if(arry[i]==value){
			return true;
		}
	}
	return false;
}

var AFSJSNameValues; // Global array

function processNameValues(){
	var docURL = document.URL;
	var varString = docURL.substring(docURL.indexOf('?')+1,docURL.length);
	var varArray = varString.split('&');
	AFSJSNameValues = new Array();
	for (y=0;y<varArray.length;y++) {
		AFSJSNameValues[y] = new Array();
		AFSJSNameValues[y] = varArray[y].split('=');
	}
	return AFSJSNameValues;
}


// Good for query strings only
function getNameValue(thisName){
	if(typeof(AFSJSNameValues)=="undefined"){
		processNameValues();
	}
	var l=AFSJSNameValues.length;
	for(i=0;i<l;i++){
		if(AFSJSNameValues[i][0]==thisName){
			if(typeof(AFSJSNameValues[i][1])=="undefined") return "";
			return AFSJSNameValues[i][1];
		}
	}

	return "";
}

function getQueryStringValue(queryString,thisName){
	var pairs=new Array();
	pairs=queryString.split("&");
	for(var i=0;i<pairs.length;i++){
		if(pairs[i].indexOf(thisName+"=")==0)
			return unescape(pairs[i].substr(thisName.length+1));
	}
	return "";
}


function getCommission(_comm){
	if(_comm==""){
		commission="";
	}else if(_comm.substr(0,1)=='S'){
		commission=_comm.substr(1);
	}else if(_comm.substr(0,1)=='*'){
		commission=_comm.substr(1);
	}else if(_comm.indexOf('%')>0){
		var percent=Number(_comm.substr(0,_comm.indexOf('%')));
		if(_comm.substr(_commission.length-1,1)=='O'){
			commission=percent.toString();
		}else{
			if (contains(percent,'-')){
				commission=(Math.abs(percent)).toString();
			}else{
				commission=(0-Math.abs(percent)).toString();
			}
		}
	}else{
		commission=_comm;
	}
	return commission;
}

function getCommissionType(_comm){
	if(_comm==""){
		commissionType="";
	}else if(_comm.substr(0,1)=='S'){
		commissionType="schedule";
	}else if(_comm.substr(0,1)=='*'){
		commissionType="per_share";
	}else if(_comm.indexOf('%')>0){
		var percent=Number(_comm.substr(0,_comm.indexOf('%')));
		if(_comm.substr(_commission.length-1,1)=='O'){
			commissionType="percent_order";
		}else{
			if (contains(percent,'-')){
				commissionType="percent_discount";
			}else{
				commissionType="percent_surcharge";
			}
		}
	}else{
		commissionType="flat";
	}
	return commissionType;
}

function getFormValue(layerName, formName, fieldName){
	if(document.layers){
		if(!document.layers[layerName]){
			//alert(layerName); // Use this to tell you which form is failing
			return false;
		}
		if(!document.layers[layerName].document.forms[formName]){
			//alert(formName); // Use this to tell you which form is failing
			return false;
		}
		if(!document.layers[layerName].document.forms[formName][fieldName]){
			//alert(fieldName); // Use this to tell you which field is failing
			return false;
		}
		return document.layers[layerName].document.forms[formName][fieldName].value;
	}else{
		if(!document.forms[formName]){
			//alert(formName); // Use this to tell you which form is failing
			return "";
		}
		if(!document.forms[formName][fieldName]){
			//alert(fieldName); // Use this to tell you which field is failing
			return "";
		}
		return document.forms[formName][fieldName].value;
	}
}

function getFormChecked(layerName, formName, fieldName){
	if(document.layers){
		return document.layers[layerName].document.forms[formName][fieldName].checked;
	}else{
		if(!document.forms[formName]){
			//alert(formName); // Use this to tell you which form is failing
			return "";
		}
		if(!document.forms[formName][fieldName]){
			//alert(fieldName); // Use this to tell you which field is failing
			return "";
		}
		return document.forms[formName][fieldName].checked;
	}
}


// Positions any layer at the x/y coordinates specified. Note that the zindex is set to 1
// this is primarily for initialization purposes, but note that if you move a layer with this
// function you may want to adjust the zindex afterwards
function positionLayer(layerName, x, y, _z){
	positionLayerDoc(document, layerName, x, y, _z);
}

function positionLayerDoc(doc, layerName, x, y, _z){
	var argv = positionLayerDoc.arguments;
	var z = argv[4];
	if(!z) z=1;
	if(document.getElementById){
		if(y!=null) doc.getElementById(layerName).style.top=y;
		doc.getElementById(layerName).style.left=x;
		doc.getElementById(layerName).style.zIndex=z;
	}else if(document.layers){
		if(y!=null) doc.layers[layerName].top=y;
		doc.layers[layerName].left=x;
		doc.layers[layerName].zIndex=z;
	}else{
		if(y!=null) doc.all[layerName].style.top=y;
		doc.all[layerName].style.left=x;
		doc.all[layerName].style.zIndex=z;
	}
}

function showLayer(layerName, _doc){
	var argv = showLayer.arguments;
	var doc = argv[1];
	if(!doc) doc=document;
	if (doc.getElementById) {
		if(doc.getElementById(layerName))
			doc.getElementById(layerName).style.visibility = 'visible';
	}else if(doc.layers){
		if(doc.layers[layerName])
			doc.layers[layerName].visibility = 'show';
	}else if(doc.all){
		if(doc.all[layerName])
			doc.all[layerName].style.visibility = 'visible';
	}
}

function hideLayer(layerName, _doc){
	var argv = hideLayer.arguments;
	var doc = argv[1];
	if(!doc) doc=document;
	if (doc.getElementById){
		if(doc.getElementById(layerName))
			doc.getElementById(layerName).style.visibility = 'hidden';
	}else if(doc.layers){
		if(doc.layers[layerName])
			doc.layers[layerName].visibility = 'hide';
	}else if(doc.all){
		if(doc.all[layerName])
			doc.all[layerName].style.visibility = 'hidden';
	}
}

function changeLayerText(layerName, text){
	changeLayerTextDoc(document, layerName, text);
}

function changeLayerTextDoc(doc, layerName, text){
	if(doc.layers){
		var tWindow=doc.layers[layerName].doc;
		tWindow.open();
		tWindow.write(text);
		tWindow.close();
	}else{
		doc.all[layerName].innerHTML=text;
	}
}

// This function draws a rectangular border. Thickness is an optional argument and will
// default to one pixel if not specified.
function createBorder(x, y, width, height, borderName, thicknessArg){
	var argv = createBorder.arguments;
	var thickness = argv[5];

	if ((thickness == null)||(thickness == ''))
		thickness = 1;

	document.write('<DIV ID="' + borderName + '_top" class="any"><img src="/images/black-pixel.gif" WIDTH="' + width + '" HEIGHT="' + thickness + '"></DIV>');
	document.write('<DIV ID="' + borderName + '_left" class="any"><img src="/images/black-pixel.gif" WIDTH="' + thickness + '" HEIGHT="' + height + '"></DIV>');
	document.write('<DIV ID="' + borderName + '_right" class="any"><img src="/images/black-pixel.gif" WIDTH="' + thickness + '" HEIGHT="' + height + '"></DIV>');
	document.write('<DIV ID="' + borderName + '_bottom" class="any"><img src="/images/black-pixel.gif" WIDTH="' + width + '" HEIGHT="' + thickness + '"></DIV>');
	positionLayer(borderName + "_top",x,y);
	positionLayer(borderName + "_left",x,y);
	positionLayer(borderName + "_right",x+width-thickness,y);
	positionLayer(borderName + "_bottom",x,y+height);
}


// This function will automatically adjust the size of input fields so that they
// approximately match on different browsers

function formSize(size){
	if(document.layers){
		return size;
	}else{
		//return (size*1.0)  - ((size1*.0)%1);
		return (size*1.55) - ((size*1.55)%1);
	}
}

// Convenience function sets the selected value for a select box by name. Browsers only
// support setting the select box by number. This is often inconvenient when dynamically
// building select box options.
function setSelectBox(selectBox, value){
	for (var i = 0; i < selectBox.length; i++) {
		if (selectBox.options[i].value == value) {
			selectBox.options[i].selected=true;
		}
	}
	return true;
}

function getSelectBoxValue(selectBox){
	for (var i = 0; i < selectBox.length; i++) {
		if(selectBox.options[i].selected==true)
			return selectBox.options[i].value;
	}
	return "";
}

function checkTrailingSpaces(value, field){
	var argv = checkTrailingSpaces.arguments;
	var field = argv[1];

	if(value.length && value.length>0 && (value.charAt(0)==' ' || value.charAt(value.length-1)==' ') ) {
		if(field!=null){
			alert('The \"' + field + '\" field contains leading/trailing spaces,\nprobably due to cutting and pasting. This may result in an error.');
		}else{
			alert('The last field you modified contains leading/trailing spaces,\nprobably due to cutting and pasting. This may result in an error.');
		}
	}
}

// This function will check the previous form entries and return anything entered
// otherwise it will send back the stored value, which is passed in as "evalue".
// If the stored value is absent then the previous form entry will be returned only

function initializeFormElement(eform, ename, evalue) {
	if(session_nv_exists(ename))
		evalue=session_nv_first(ename);

	// get correct form
	for(var i=0;i<document.forms.length;i++) {
		if (document.forms[i].name==eform) break;
	}
	// get correct input item
	var f=document.forms[i].elements[ename];
	if (f.name==ename || !f.name) {
		if (f.type=="select-one" || f.type=="select-multiple") {
				// get correct option
			for(var k=0;k<f.length;k++) {
					if (f.options[k].value==evalue) {
					f.selectedIndex=k;
					break;
				}
				}
		}else if (f.type=="text" || f.type=="password" || f.type=="button" || f.type=="reset" || f.type=="submit" || f.type=="textarea" || f.type=="hidden") {
			f.value=evalue;
		}else if (f.type=="checkbox") {
			if(f.value==evalue){
					f.checked=true;
			}else{
				f.checked=false;
			}
		}else if (f[0].type=="radio") {
			for(var j=0;j<f.length;j++) {
				if(f[j].value==evalue){
						f[j].checked=true;
				}else{
					f[j].checked=false;
				}
			}
		}
	}
}

// ErrorText object is used to store error text that will be displayed in pop up error messages.
function ErrorText(){
	this.text="";
}

function isValidEmail(email, errorText){
	if(email.length==0) return true;

	re=/^([A-Z0-9]+[._-]?){1,}[A-Z0-9]+\@(([A-Z0-9]+[-]?){1,}[A-Z0-9]+\.){1,}[A-Z]{2,4}$/i;
	myResult=re.exec(email);
	if (myResult) return true;
	errorText.text="<SPAN CLASS='errorExample'>\"" + email + "\"</SPAN> is not a valid email address.";
	return false;
}

//TODO make the numeric detection work
function isValidPhoneNumber(phone, errorText){
	if(phone.length==0) return true;
	if(phone.length==10) return true;
	//if(phone.length==3) return true; // Hack, if they've filled in 3 digits we'll let it go because it is probably the first three
	//if(phone.length==6) return true; // Likewise for the second 3
	errorText.text="<SPAN CLASS='errorExample'>\"" + phone + "\"</SPAN> is not a valid phone number.";
	return false;
}

function isValidDate(value, errorText){
	if(value.length==0) return true;
	if(value.length==8) return true;
	errorText.text="<SPAN CLASS='errorExample'>\"" + value + "\"</SPAN> is not a valid date.";
	return false;
}

function isValidPassword(password, errorText){
	// Any password is valid
	return true;
}

//TODO make the numeric detection work
function isValidPin(pin, errorText){
	if(pin.length==0) return true;
	if(pin.length==4) return true;
//	if(pin[0]<'0' || pin[0]>'9') return false;
//	if(pin[1]<'0' || pin[1]>'9') return false;
//	if(pin[2]<'0' || pin[2]>'9') return false;
//	if(pin[3]<'0' || pin[3]>'9') return false;
	errorText.text="Pin numbers must be four digits. Only numbers are allowed.";
	return false;
}

function areaCode(phoneNumber){
	if(phoneNumber.length<3) return phoneNumber;
	return phoneNumber.substr(0,3);
}

function prefix(phoneNumber){
	if(phoneNumber.length<4) return "";
	var length=phoneNumber.length-3;
	if(length>3) length=3;
	return phoneNumber.substr(3,length);
}

function suffix(phoneNumber){
	if(phoneNumber.length<7) return "";
	var length=phoneNumber.length-6;
	if(length>4) length=4;
	return phoneNumber.substr(6,length);
}


// You'll need to build the containsError() function for your form. Use an example from a current form as a template.
// We assume that the hidden form is called "hidden_form"

function changeValue(field, value){
	if(typeof(containsError)!="undefined"){
		if(!containsError(field, value)){
			hideErrorLabel();
		}
	}
	document.hidden_form[field].value=value; // We'll store the value of the field in the hidden form
											// even if it is wrong, since our interface allows customers
											// to enter wrong stuff if they *really* want to.
											// This also helps the interface keep track of which fields
											// to display in red.
	return true;
}

// This function creates a button with some standard functionality. It will
// automatically do a gif change on rollover. It assumes that the two source images
// for the gifs are "/buttons/btn_source_on.gif" and "/buttons/btn_source_off.gif"
// where source is the name of the gif. Although less flexible, it cuts down on the
// number of parameters and encourages good directory structure.
//
// buttonAction is the name of the function to call when the button is pressed (without parentheses)
// Note that to get roll-overs to work in Netscape we need to jerryrig by using an anchor that goes nowhere

function createButton(layerName, source, x, y, buttonAction, alt){
	var buttonOn="/buttons/btn_" + source + "_on.gif";
	var buttonOff="/buttons/btn_" + source + "_off.gif";

	var newText;
	newText='<DIV ID="' + layerName + '" CLASS="any" STYLE="{top:' + y + 'px ; left:' + x + 'px ; }">';
	newText+='<A HREF="#" onclick="' + buttonAction + '(); return false;" onmouseout="MM_swapImgRestore()" onmouseover="MM_swapImage(\'' + layerName + '\',\'\',\'' + buttonOn + '\',1)"><IMG SRC="' + buttonOff + '" NAME="' + layerName + '" ALT="' + alt + '" BORDER=0></A>';
	newText+='</DIV>';
	document.write(newText);
	// Netscape doesn't handle inline styles well so we'll position the element
	// If we don't include the inline positioning however, IE will resize the table!
	// So we need to do both
	if(document.layers){
		positionLayer(layerName, x, y);
	}
}

// This is a generic function for making AFS style tables, that is no borders or padding.
function makeTable(tStyle, tText, tHeight, tWidth){
	var newText;
	newText='<TABLE BORDER=0 CELLSPACING=0 CELLPADDING=0><TR><TD ALIGN="RIGHT" CLASS="' + tStyle + '" HEIGHT="' + tHeight + '" WIDTH="' + tWidth + '">';
	newText+=tText;
	newText+='</TD></TR></TABLE>';
	return newText;
}


// A label (for a field) in the AFS world is nothing more than a table of size 22x200.
function changeLeftLabel(layerName, text, labelClass, width){
	var argv = changeLeftLabel.arguments;
	var width = argv[3];
	if ((width == null)||(width == ''))
	  width=200;

	var newText=makeTable(labelClass, text + "&nbsp;&nbsp;", 22, width);
	changeLayerText(layerName, newText);
}

// Simply initializes a layer for the floating error label
function createFloatingErrorLabel(){
	document.write('<DIV ID="error_label" CLASS="anyHide"></DIV>');
}

function hideErrorLabel(){
	hideLayer("error_label");
}

// First off we calculate where to put the error label based on the label
// with an error. We rely on other code to figure this out. This function may
// not be flexible enough though since it assumes labels on the left side of
// the screen.
// Note that we reset the zindex to 5 since positionLayer will set it to 1. Why 5? Why not!
// xOffset and yOffset control the relative position that the error label will display
// in, the absolute position being determined on the fly based on the x,y location of the
// label in error itself.

function showErrorLabel(changedLabel, text, argalign, xOffset, yOffset){
	var argv = showErrorLabel.arguments;
	var align = argv[2];
	var xOffset = argv[3];
	var yOffset = argv[4];

	if ((align == null)||(align == ''))
	  align = "CENTER";
	if(xOffset == null) xOffset=450;
	if(yOffset == null) yOffset=-80;

	var x;
	var y;
	if(document.layers){
		x=document.layers[changedLabel].left;
		y=document.layers[changedLabel].top;
	}else{
		x=document.all[changedLabel].style.left;
		y=document.all[changedLabel].style.top;
	}
	// Netscape stores as integers while IE stores as strings
	// As an example Netscape stores "38" while IE stores "38px"
	// So we substring out the px part and then evaluate the string
	// to get an integer value when working in IE
	if(document.layers){
		x+=xOffset;
		y+=yOffset;
	}else{
		var i=x.indexOf('p');
		x=x.substr(0, i);
		x=eval(x) + xOffset;

		i=y.indexOf('p');
		y=y.substr(0,i);
		y=eval(y) + yOffset;
	}
	showErrorLabelCoord(x, y, text, argalign);
}

function showErrorLabelCoord(x, y, text, argalign){
	var argv = showErrorLabelCoord.arguments;
	var align = argv[3];

	if ((align == null)||(align == ''))
	  align = "CENTER";

	var newText;
	newText='<TABLE BORDER=0 CELLSPACING=0 CELLPADDING=5><TR>';
	newText+='<TD ALIGN="CENTER" CLASS="tlabelerror">';
	newText+='ERROR';
	newText+='</TD></TR><TR>';
	newText+='<TD ALIGN="' + align + '" WIDTH="150" VALIGN="MIDDLE" CLASS="tlabelerrortext">';
	newText+=text;
	newText+='</TD></TR>';
	newText+='</TABLE>';

	changeLayerText("error_label", newText);
	positionLayer("error_label", x, y);
	if(document.layers){
		document.layers["error_label"].zIndex=5;
	}else{
		document.all["error_label"].style.zIndex=5;
	}
	showLayer("error_label");
	hideLayer("success_label");
}

// This makes a standard AFS label 22xWidth and places it on the screen. The fourth argument
// is an optional override style. Otherwise we will use the ".tlabel" style
function makeLabel(layerName, x, y, text, width, labelStylePM, height){
   var argv = makeLabel.arguments;
	var labelStyle = argv[5];
	if ((labelStyle == null)||(labelStyle == ''))
	  labelStyle = "tlabel";
	var height= argv[6];
	if ((height == null)||(height == ''))
		height=22;

	document.write('<DIV ID="' + layerName + '" CLASS="any" STYLE="{top:' + y + 'px ; left:' + x + 'px ; }">');
	document.write(makeTable(labelStyle, text + "&nbsp;&nbsp;", height, width));
	document.write('</DIV>');
	// Netscape doesn't handle inline styles well so we'll position the element
	// If we don't include the inline positioning however, IE will resize the table!
	// So we need to do both
	if(document.layers){
		positionLayer(layerName, x, y);
	}
}

// typeOfPadding set to:
// "padToDecimalPlaces" - Always pad out to the number of decimalPlaces
// "noPadding" - Decimal places are exactly as passed in
// "noPaddingUpToDecimalPlaces" - Decimal places are exactly passed in but no greater than decimalPlaces

function formatNumber(exp, decimalPlaces, typeOfPadding) {
  if(!typeOfPadding) typeOfPadding="padToDecimalPlaces";
  if(!exp){
	var s="0.";
	for(i=0;i<decimalPlaces;i++){
		s+="0";
	}
	return s;
  }
  if(exp=="&nbsp;") return exp;
  if(exp=="") return exp;
  var i;
  var parts;
  if(!exp.indexOf)	// if we are already an integer then we'll convert ourselves to a string
	exp=exp.toString();
  if(exp.indexOf('$')!=-1){	// In case we already have a dollar sign we'll remove it and reformat
	exp=exp.substr(1,exp.length-1);
  }
  //exp=Math.round(exp*100)/100;
  parts=(exp+'.').split('.');
  exp='';

  var negative=false;
  var plusWasThere=false;
  if (parts[0].substr(0,1)=='-') {
	parts[0]=parts[0].substr(1);
	negative=true;
  }else if (parts[0].substr(0,1)=='+') {
	parts[0]=parts[0].substr(1);
	plusWasThere=true;
  }
  if (parts[0]=='') {exp+='0'};
  for (i=parts[0].length;i>0;i-=1) {
	if (!(i%3) && (i!=parts[0].length)) {exp+=',';}
	exp+=parts[0].charAt(parts[0].length-i);
  }

  if(decimalPlaces>0 && typeOfPadding=="padToDecimalPlaces"){
	exp+='.';
	for(i=0;i<parts[1].length && i<decimalPlaces;i++)
	  exp+=parts[1].charAt(i);
	for(i=parts[1].length;i<decimalPlaces;i++)
	  exp+="0";
  }else if(decimalPlaces>0 && typeOfPadding=="noPaddingUpToDecimalPlaces"){
	for(i=0;i<parts[1].length && i<decimalPlaces;i++){
	  if(i==0) exp+='.';
	  exp+=parts[1].charAt(i);
	}
  }else if(typeOfPadding=="noPadding"){
	for(i=0;i<parts[1].length;i++){
	  if(i==0) exp+='.';
	  exp+=parts[1].charAt(i);
	}
  }

  if(negative)
	exp="-" + exp;
  if(plusWasThere)
	exp="+" + exp;
  return exp;
}

function QuoteItem(exp) {
  if (exp=='') return '';
  var i;
  var parts;
  exp=exp.toString();
  parts=(exp+'.').split('.');
  exp='';
  if (parts[0].substr(0,1)=='-') {
	exp+='-';
	parts[0]=parts[0].substr(1);
  }else if (parts[0].substr(0,1)=='+') {
	exp+='+';
	parts[0]=parts[0].substr(1);
  }
  if (parts[0]=='') {exp+='0'};
  for (i=parts[0].length;i>0;i--) {
	if (!(i%3) && (i!=parts[0].length)) {exp+=',';}
	exp+=parts[0].charAt(parts[0].length-i);
  }

  while (parts[1].length<2) {
	parts[1]=parts[1].concat(0);
  }
  return exp+'.'+parts[1];
}

function Money(exp) {
  if(!exp) return '$ 0.00';
  if(exp=="&nbsp;") return exp;
  if(exp=="") return exp;
  var i;
  var parts;
  if(!exp.indexOf)	// if we are already an integer then we'll convert ourselves to a string
	exp=exp.toString();
  if(exp.indexOf('$')!=-1){	// In case we already have a dollar sign we'll remove it and reformat
	exp=exp.substr(1,exp.length-1);
  }
  exp=Math.round(exp*100)/100;
  parts=(exp+'.').split('.');
  exp='';

  var negative=false;
  if (parts[0].substr(0,1)=='-') {
	parts[0]=parts[0].substr(1);
	negative=true;
  }
  if (parts[0]=='') {exp+='0'};
  for (i=parts[0].length;i>0;i-=1) {
	if (!(i%3) && (i!=parts[0].length)) {exp+=',';}
	exp+=parts[0].charAt(parts[0].length-i);
  }
  if (negative) {
	return '($ '+exp+'.'+(parts[1]+'00').substr(0,2) + ')';
  }else{
	return '$ '+exp+'.'+(parts[1]+'00').substr(0,2);
  }
}

function BalanceMoney(exp) {
  if(!exp) return '$ 0.00';
  if(exp=="&nbsp;") return exp;
  if(exp=="") return exp;
  var i;
  var parts;
  if(!exp.indexOf)	// if we are already an integer then we'll convert ourselves to a string
	exp=exp.toString();
  if(exp.indexOf('$')!=-1){	// In case we already have a dollar sign we'll remove it and reformat
	exp=exp.substr(1,exp.length-1);
  }
  exp=Number(exp).toString();
  parts=(exp+'.').split('.');
  exp='';

  var negative=false;
  if (parts[0].substr(0,1)=='-') {
	parts[0]=parts[0].substr(1);
	negative=true;
  }
  if (parts[0]=='') {exp+='0'};
  for (i=parts[0].length;i>0;i-=1) {
	if (!(i%3) && (i!=parts[0].length)) {exp+=',';}
	exp+=parts[0].charAt(parts[0].length-i);
  }
  while (parts[1].length<2) {
	parts[1]=parts[1].concat(0);
  }
  if (negative) {
	return '($ '+exp+'.'+parts[1]+')';
  }else{
	return '$ '+exp+'.'+parts[1];
  }
}


function Percentage(exp,precision) {
  if (exp=='') return '';
  var i;
  exp=exp.toString();
  if(exp=='NaN') exp=0;
  exp=Math.round(Number(exp)*Math.pow(10,precision))/Math.pow(10,precision);

  parts=(exp+'.').split('.');
  exp='';
  if (parts[0].substr(0,1)=='-') {
	exp+='-';
	parts[0]=parts[0].substr(1);
  }
  if (parts[0]=='') {exp+='0'};
  for (i=parts[0].length;i>0;i-=1) {
	if (!(i%3) && (i!=parts[0].length)) {exp+=',';}
	exp+=parts[0].charAt(parts[0].length-i);
  }
  return  exp +(precision>0?'.':'')+(parts[1]+'00000000').substr(0,precision)+'%';
}

function drawMessage(doc, message){
	if(document.layers) return;
	doc.open();
	doc.writeln('<HTML><BODY>');
	doc.writeln('<link rel="stylesheet" href="/brokat_css/contentstyle.css">');
	doc.writeln(message);
	doc.writeln('</BODY></HTML>');
	doc.close();
}

function drawPleaseWait(doc){
	if(document.layers) return;
	doc.open();
	doc.writeln('<HTML><BODY>');
	doc.writeln('<link rel="stylesheet" href="/brokat_css/contentstyle.css">');
	doc.writeln('<DIV ID="please_wait" class="anyHide"><IMG SRC="/images/loading.gif"></DIV>');
	positionLayerDoc(doc, "please_wait", 350, 100);
	if(document.layers){
		doc.writeln('<SCRIPT>setTimeout("document.layers[\'please_wait\'].visibility = \'show\';", 1000);</SCRIPT>');
	}else{
		doc.writeln('<SCRIPT>setTimeout("document.all[\'please_wait\'].style.visibility = \'visible\';", 1000);</SCRIPT>');
	}
	doc.writeln('</BODY></HTML>');
	doc.close();
}

// If append is true then any symbol chosen by the symbol wizard will be appended. This is used
// for input lines that require multiple symbols separated by spaces. Otherwise the input field
// will be replaced with the symbol selected.

function openSymbolWizard(item, append, securityType) {
	var argv = openSymbolWizard.arguments;
	var securityType = argv[2];
	var url;

	if(securityType==null){
		url="/symbol_wizard/symbol_wizard.html";
		if(append) url+="?append";
	}else{
		url="/symbol_wizard/symbol_wizard.html?security_type=" + securityType;
		if(append) url+="&append";
	}
	w=window.open(url,'symbol_wizard','toolbar=no,location=no,directories=no,status=yes,menubar=no,scrollbars=yes,resizable=yes,width=450,height=450');
	w.targetItem=item;
	//w.opener=self;
	//w.focus();
}

function openTradingSymbolWizard(item, securityType) {
	var argv = openTradingSymbolWizard.arguments;
	var securityType = argv[1];
	var url="/symbol_wizard/symbol_wizard.html?source=trading";

	if(securityType!=null){
		url+="&security_type=" + securityType;
	}
	w=window.open(url,'symbol_wizard','toolbar=no,location=no,directories=no,status=yes,menubar=no,scrollbars=yes,resizable=yes,width=450,height=450');
	w.targetItem=item;
}

// This function assumes that an image of btn_<buttonName>_on.gif and btn_<buttonName>_off.gif exist in the button directory
function drawButton(doc, buttonName, url){
	doc.writeln('<A href="' + url + '" class="linknav" onMouseOut="MM_swapImgRestore()" onmouseover="MM_swapImage(\'' + buttonName + '\',\'\',\'/buttons/btn_' + buttonName + '_on.gif\',1)"><img src="/buttons/btn_' + buttonName + '_off.gif" border="0" name="' + buttonName + '"></a>');
}

function rowClass(row){
	if(row%2>0) return "oddLine";
	return "evenLine";
}

function drawTitleLine(title, doc, noPadding){
	if(!doc) doc=document;
	var height="height=27";
	if(noPadding==true) height="";

	doc.writeln('<table border=0 cellpadding=0 cellspacing=0>');
	doc.writeln('	<tr>');
	doc.writeln('		<td width="22"><img src="/images/px1.gif" width="20" height="1"></td>');
	doc.writeln('		<td valign="bottom" ' + height + '><font class="title">&nbsp;' + title + '</font></td>');

	doc.writeln('	</tr>');
	doc.writeln('</table>');
	doc.writeln('<table width="771" cellspacing="0" cellpadding="0" border="0">');
	doc.writeln('	<tr>');
	doc.writeln('		<td width="22" height="4"><img src="/images/px1.gif" width="20" height="1"></td>');
	doc.writeln('		<td width="749" height="4"><img src="/images/grad749x4.gif" width="749" height="4"></td>');
	doc.writeln('	</tr>');
	doc.writeln('</table>');
}

function createCustomerLink(exp, page, _target){
	var argv = createCustomerLink.arguments;
	var target = argv[2];
	if(target==null) target="";
	else target=" target='" + target + "'";
	return '<A CLASS="customerAnchor" HREF="/cgi/online/ABSSetWorkingCustomer?file=' + page + '&text=' + exp + '&' + session_nv_output() + '" ALT="Enable this customer" onMouseOver="self.status=\'Enable customer ' + exp + '\'; return true" onMouseOut="self.status=\'\'; return true"' + target + '>' + exp + '</A>';
}

function getShortSymbol(symbol) {
  var symbolArray=symbol.split(' ');
  if(symbolArray.length==1) return symbol;
  if (symbolArray[0]=='CUSIP') return 'C.' + symbolArray[1];
  else if (symbolArray[0]=='FIXED') return 'F.' + symbolArray[1];
  else if (symbolArray[0]=='OPTION') return '.' + symbolArray[1];
  else if (symbolArray[0]=='INDICATOR') return '$' + symbolArray[1];
  else if (symbolArray[0]=='INDEX') return '#' + symbolArray[1];
  else if (symbolArray[0]=='EQUITY') {
	if (!symbolArray[2]) return symbolArray[1];
	else if (symbolArray[2]=='PREFERRED') return symbolArray[1]+'p'+(symbolArray[3]?symbolArray[3]:'');
	else if (symbolArray[2]=='CLASS') return symbolArray[1]+'/'+symbolArray[3];
	else if (symbolArray[2]=='WARRANT') return symbolArray[1]+'/WS'+(symbolArray[3]?'/'+symbolArray[3]:'');
	else if (symbolArray[2]=='WHEN_DELIVERED') return symbolArray[1]+'/WI';
	else if (symbolArray[2]=='WHEN_ISSUED') return symbolArray[1]+'w';
	else if (symbolArray[2]=='RIGHTS') return symbolArray[1]+'r';
	else if (symbolArray[2]=='EX_DIVIDEND') return symbolArray[1]+'/XD';
	else if (symbolArray[2]=='EX_RIGHTS') return symbolArray[1]+'/Xr';
	else return symbolArray[1];
  }
  return symbolArray[1];
}

function ConvertToSentence(str){
	if (str!=null|| str!='') return str.substr(0,1).toUpperCase()+str.substr(1).toLowerCase();
}

function registerSelectBoxLayer(layerName, _doc){
	var argv = registerSelectBoxLayer.arguments;
	doc=argv[1];
	if(doc==null) doc=document;
	if(typeof(doc.selectBoxLayers)=="undefined" || doc.selectBoxLayers == null){
		doc.selectBoxLayers = new Array();
	}
	doc.selectBoxLayers[doc.selectBoxLayers.length]=layerName;
}

function toggleVisibilityOfSelectBoxes(frame, visibility, iframe){
	if(IE5UP) return;
	try{
		if(typeof(frame)=="undefined" || !frame) return;
		top.status=frame.name;
		if(iframe){
			var i=0;
			for(i=0;i<frame.frames.length;i++){
				if(frame.frames[i].document.readyState=="complete")
					toggleVisibilityOfSelectBoxes(frame.frames[i], visibility, iframe);
			}
		}

		var tags=frame.document.getElementsByTagName("SELECT");
		for(i=0;i<tags.length;i++){
			if(visibility){
				tags[i].style.visibility="visible";
			}else{
				tags[i].style.visibility="hidden";
			}
		}

	}catch(err){
	}

}

function getNav(){
	if(typeof(top.globalWindow)=="undefined"){
		return top;
	}else{
		return top.globalWindow;
	}
}

function storeGlobalVariable(name, value){
  var obj=getNav();
  if(obj==null){
	alert("cannot store global variable");
	return;
  }
  obj[name]=value;
}

function getGlobalVariable(name){
  var obj=getNav();
  if(obj==null){
	return "";
  }
  var v=eval("obj." + name);
  rc=v;
  return rc;
}

// This will display all the properties of the JavaScript object passed in.
function inspectProperties(theObject){
   var theProperties = ""
   for (var i in theObject){
	if(i!="outerText" && i!="innerText" && i!="outerHTML" && i!="innerHTML")
	theProperties +=  i + " = " + theObject[i] + "\t"
   }
   alert(theProperties)
}

function formatMMDDYY(strDate){
   if(strDate=="") return "";
   date = new Date(strDate);
   var da = new Array(  date.getEDTFullYear() , date.getEDTDate(), date.getEDTMonth() )

   var result="";
   for(var i=da.length-1; i>=0; i--){
      if(i<2) result +="/";
      if(da[i]<=9){
         result += "0"+da[i];
      }else if(da[i]<=99){
         result +=da[i];
      }else{
         var tmp=String(da[i]);
         result +=tmp.substr(tmp.length-2,2);
      }
   }
   return result;
}

function formatMMDDYYHHMM(strDate){
   date = new Date(strDate);
   var da = new Array(  date.getEDTMinutes(), date.getEDTHours(), date.getEDTFullYear() , date.getEDTDate(), date.getEDTMonth() )
	var result="";
   for(var i=da.length-1; i>=0; i--){
      switch(i){
      case 2: case 3: result +="/";
      break
      case 1: result+="&nbsp;";
      break
      case 0: result+=":";
      break;
      }
      if(da[i]<=9){
         result += "0"+da[i];
      }else if(da[i]<=99){
         result += da[i];
      }else{
         var tmp=String(da[i]);
         result += tmp.substr(tmp.length-2,2);
      }
   }
   return result;
}




// private



Date.prototype.calculateEdtEquivilent = function() {
 //apparently this function was created to convert GMT to EST or EDT
 //This functionality is no longer needed as the BOM returns EST.
 //But it is still used in many places, so we have to fix.
 //It will only work if the OS retroactively applies the same DST formula. 
 //If the OS can handle different DST periods in different years (ala Vista),
 //then the function will need to be modified and the commented out lines added in.
 
   this.edtEquivilent=new Date();
   this.utcEpoch = 0;
   this.edt = false;
 
   var thisYear, StartDate, EndDate;
 
   utcEpoch=this.valueOf()
   this.edtEquivilent.setTime(utcEpoch - 18000000) // GMT-5
 

   thisYear = this.edtEquivilent.getUTCFullYear();
 
   // is it in the DST area?
   //if(thisYear<2007){
   //	StartMonth = 4;  //April
   //	EndMonth = 10;  //October
   //}else{
	StartMonth = 3;  //March
	EndMonth = 11;  //November
   //}
 
   month= this.edtEquivilent.getUTCMonth()+1;
 
   if(month<StartMonth || month>EndMonth) return;
   if(month>StartMonth && month<EndMonth) {
	this.edtEquivilent.setTime(utcEpoch - 14400000) // GMT-4
	this.edt = true;
	return;
   }
 
   //if(thisYear<2007){
   //	StartDate = (2+6 * thisYear - Math.floor (thisYear / 4) ) % 7 + 1;  //First Sunday in April
   //	EndDate=  (31-( Math.floor (thisYear * 5 / 4) + 1) % 7);  //Last Sunday in October
   //}else{
	StartDate = 14 - ( ( Math.floor (thisYear * 5 / 4) - 6) % 7 );  //Second Sunday in March
	EndDate = 7 - ( ( Math.floor (thisYear * 5 / 4) + 8) % 7 );  //First Sunday in November
   //}
 
   todaysDate= this.edtEquivilent.getUTCDate();
 
   if( (month==StartMonth && todaysDate > StartDate) || (month==EndMonth && todaysDate < EndDate) ){
	this.edtEquivilent.setTime(utcEpoch -  14400000) // GMT-4
	this.edt=true;
	return;
   }
   if( (month==StartMonth && todaysDate < StartDate) || (month==EndMonth && todaysDate > EndDate) ){
	return;
   }
 
   todaysHour=this.edtEquivilent.getUTCHours();
 
   if( (month==StartMonth && todaysHour>=2) || (month==EndMonth && todaysHour<1) ){
	this.edtEquivilent.setTime(utcEpoch -  14400000) // GMT-4
	this.edt=true;
	return;
   }
}

// public

Date.prototype.getEDTDate = function (){
   // Returns the day (date) of the month in the specified date according to universal time.
	if( this.valueOf() != this.utcEpoch ){
		this.calculateEdtEquivilent();
	}
	return this.edtEquivilent.getUTCDate()
}
Date.prototype.getEDTDay = function (){
   //Returns the day of the week in the specified date according to universal time.
	if( this.valueOf() != this.utcEpoch ){
		this.calculateEdtEquivilent();
	}
	return this.edtEquivilent.getUTCDay()
}

Date.prototype.getEDTFullYear = function (   ){
   // Returns the year in the specified date according to universal time.
	if( this.valueOf() != this.utcEpoch ){
		this.calculateEdtEquivilent();
	}
	return this.edtEquivilent.getUTCFullYear()
}

Date.prototype.getEDTHours = function (){
   // Returns the hours in the specified date according to universal time.
	if( this.valueOf() != this.utcEpoch ){
		this.calculateEdtEquivilent();
	}
	return this.edtEquivilent.getUTCHours()
}

Date.prototype.getEDTMilliseconds = function (   ){
   // Returns the milliseconds in the specified date according to universal time.
	if( this.valueOf() != this.utcEpoch ){
		this.calculateEdtEquivilent();
	}
	return this.edtEquivilent.getUTCMilliseconds()
}

Date.prototype.getEDTMinutes = function (   ){
   // Returns the minutes in the specified date according to universal time.
	if( this.valueOf() != this.utcEpoch ){
		this.calculateEdtEquivilent();
	}
	return this.edtEquivilent.getUTCMinutes()
}

Date.prototype.getEDTMonth = function (   ){
   // Returns the month according in the specified date according to universal time.
	if( this.valueOf() != this.utcEpoch ){
		this.calculateEdtEquivilent();
	}
	return this.edtEquivilent.getUTCMonth() + 1;
}

Date.prototype.getEDTSeconds = function (   ){
   // Returns the seconds in the specified date according to universal time.
	if( this.valueOf() != this.utcEpoch ){
		this.calculateEdtEquivilent();
	}
	return this.edtEquivilent.getUTCSeconds()
}


Date.prototype.toEDTString = function (){
   // Converts a date to a string, using EST locale's conventions
	if( this.valueOf() != this.utcEpoch ) this.calculateEdtEquivilent();
	time="";
	switch(this.edtEquivilent.getUTCDay()){
		case 0: time="Sun "; break;
		case 1: time="Mon "; break;
		case 2: time="Tue "; break;
		case 3: time="Wed "; break;
		case 4: time="Thu "; break;
		case 5: time="Fri "; break;
		case 6: time="Sat "; break;
	}
	switch(this.edtEquivilent.getUTCMonth()){
		case 0: time+="Jan "; break;
		case 1: time+="Feb "; break;
		case 2: time+="Mar "; break;
		case 3: time+="Apr "; break;
		case 4: time+="May "; break;
		case 5: time+="Jun "; break;
		case 6: time+="Jul "; break;
		case 7: time+="Aug "; break;
		case 8: time+="Sep "; break;
		case 9: time+="Oct "; break;
		case 10: time+="Nov "; break;
		case 11: time+="Dec "; break;
	}
	time+=this.edtEquivilent.getUTCDate();
	time+=" ";
	hours=this.edtEquivilent.getUTCHours();
	minutes=this.edtEquivilent.getUTCMinutes();
	seconds=this.edtEquivilent.getUTCSeconds();

	if(hours<10){
	   time+="0";
	}
	time+=hours;

	time+=":"

	if(minutes<10){
	   time+="0";
	}
	time+=minutes;
	
    time+=":"
  	
   	
   	if(seconds<10){
   	   time+="0";
   	}
   	time+=seconds;


   	if(this.isDstInEST()){
   	   time+=" EDT ";
   	}else{
   	   time+=" EST ";
   	}
   	time+=this.edtEquivilent.getUTCFullYear();
   	return time;
} 

Date.prototype.isDstInEST = function (){ 
    if( this.valueOf() != this.utcEpoch ) this.calculateEdtEquivilent();
	return this.edt;
}

function formatDateTime(dateVal) {
//e.g. "Thu, 06 Nov 2003 10:00:48 am EST"
	var dateTimeET=new Date(dateVal);
	time=dateVal.substr(dateVal.indexOf(":")-2);
	time=time.replace("EST","ET");
	time=time.substr(0,5)+time.substr(8);
	result=time+" " +(dateTimeET.getMonth()+1)+"/"+dateTimeET.getDate()+"/"+dateTimeET.getYear();
	return (result);
}

function zoomit(layer, last){
	l=eval(layer);
	if(last==100) return;
	if(last==-1){
		l.style.visibility="hidden";
		return;
	}
	if(last>0){
		last*=1.3;
	}else{
		last/=1.3;
	}
	if(last>=100) last=100;
	if(last>-1 && last<0) last=-1;
	if(last>0) pct=last;
	else pct=last*-1;
	l.style.zoom=pct + "%";
	setTimeout("zoomit(\'" + layer + "\', " + last + ")", 1);
}

function zoom(layer, forward){
	l=eval(layer);
	if(forward>0){
		l.style.zoom="1%";
		l.style.visibility="visible";
		setTimeout("zoomit(\'" + layer + "\', 1)", 1);
	}else{
		setTimeout("zoomit(\'" + layer + "\', -100)", 1);
	}
}

function formatODBCDateTime(dtTime) {
	//format the string to YYYYMMDDHHMMSS for transaction grab bag
	var odbcdt="";
	odbcdt=dtTime.replace(/[-:\s]/g,"");
	odbcdt=odbcdt.replace(/\.(\d+)/g,"");
	return(odbcdt);
}


function TitleLineObject(title) {
	this.title=title;
	this.download=isGreen("ALLOW_DOWNLOAD_CUSTOMER_DATA");
	this.print=isNotRed("ALLOW_PRINT_CUSTOMER_DATA");
	this.refresh=isNotRed("ALLOW_REFRESH_CUSTOMER_DATA");
	this.downloadUrl="";
	this.doc=null;
	this.padding=false;
	this.url="";
	this.windowToPrint="window";	//Override this to print a different frame
}

function randomNumber(){
	var d=new Date();
	return d.valueOf().toString();
}

function randomizeUrl(url,querystring,targetstring){
	var ret=url+"?nocache="+randomNumber();
	if(querystring!="" && querystring != null) ret+="&"+querystring;
	var command=targetstring+'.location.href="'+ret+'"';
	eval(command);
}

function refreshOutput(){
	if(!session_get_name_values) return "";
	var output="";
	for (var nv=0;nv<session_get_name_values.data.length;nv++){
		if(output!="") output +="&";
		if(session_get_name_values.data[nv].name!="nocache")
			output+=session_get_name_values.data[nv].name+"="+escape(session_get_name_values.data[nv].value);
	}
	return escape(output);
}

function printWindow(windowToPrint){
	w=eval(windowToPrint);
	w.focus();	// To print another frame you have to first set the focus in there
	w.print();
}

function drawTitleLineV2(param){
	if(!param.doc) param.doc=document;
	var doc=param.doc;
	var height="height=27";
	if(param.noPadding==true) height="";

	doc.writeln('<table width="771" border=0 cellpadding=0 cellspacing=0>');
	doc.writeln('	<tr>');
	doc.writeln('		<td width="22"><img src="/images/px1.gif" width="20" height="1"></td>');
	doc.writeln('		<td valign="bottom" ' + height + '><font class="title">&nbsp;' + param.title + '</font></td>');
	if(param.print || param.refresh || param.download){
		doc.writeln('<td align=right>');
	}
	if(param.print){
		doc.writeln('&nbsp;&nbsp;&nbsp;<a href="javascript:printWindow(' + param.windowToPrint + ');" onMouseOver="self.status=\'Print\'; return true" onMouseOut="self.status=\'\'; return true"><img style="vertical-align:bottom;" src="/images/print_button.gif" border=0 alt="Print"></a>');
	}
	if(param.refresh){
		doc.writeln('&nbsp;&nbsp;&nbsp;<a href="javascript:randomizeUrl(\'' + param.url + '\',\''+refreshOutput()+'\',\'window\');" onMouseOver="self.status=\'Refresh\'; return true" onMouseOut="self.status=\'\'; return true"><img style="vertical-align:bottom;" src="/images/refresh_button.gif" border=0 alt="Refresh"></a>');
	}
	if(param.download){
		doc.writeln('&nbsp;&nbsp;&nbsp;<a href="javascript:randomizeUrl(\'' + param.downloadUrl + '\',\''+refreshOutput()+'\',\'window\');"" onMouseOver="self.status=\'Download\'; return true" onMouseOut="self.status=\'\'; return true"><img style="vertical-align:bottom;" src="/images/download_button.gif" border=0 alt="Download"></a>');
	}
	if(param.print || param.refresh || param.download){
		doc.writeln('</td>');
	}

	doc.writeln('	</tr>');
	doc.writeln('</table>');
	doc.writeln('<table width="771" cellspacing="0" cellpadding="0" border="0">');
	doc.writeln('	<tr>');
	doc.writeln('		<td width="22" height="4"><img src="/images/px1.gif" width="20" height="1"></td>');
	doc.writeln('		<td width="749" height="4"><img src="/images/grad749x4.gif" width="749" height="4"></td>');
	doc.writeln('	</tr>');
	doc.writeln('</table>');
}

function getEntitlementLight(entitlement){
	if(!entitlements_get_entitlement) return "NONE"; // TODO, throw an error
	if(entitlements_get_entitlement.result.result!="OK") return "NONE";
	for(i=0;i<entitlements_get_entitlement.data.length;i++){
		if(entitlements_get_entitlement.data[i].name==entitlement) return entitlements_get_entitlement.data[i].light;
	}
	return "NONE";
}

function isGreen(entitlement){
	var light=getEntitlementLight(entitlement);
	if(light=="GREEN") return true;
	return false;
}

function isNotRed(entitlement){
	var light=getEntitlementLight(entitlement);
	if(light=="RED") return false;
	return true;
}