//////////////////////////////////////////////////////////////////////////////
//                                                                          //
// ADI Web Site JavaScript Library                                          //
// ===============================                                          //
//                                                                          //
// These are the JavaScript functions required to support the ADI web site. //
//                                                                          //
// Written: Dr Ian Sedwell, Secure Data Services Group, New Media           //
//          21 June 2007.                                                   //
//                                                                          //
// Copyright (c) Secure Data Services Group 2007                            //
//                                                                          //
//////////////////////////////////////////////////////////////////////////////

// Each time a window attaches a check is made for PNG images.
if (window.attachEvent) window.attachEvent("onload", correctPNG);

// This corrects for MSIE versions that do not support alpha transparency.
function correctPNG() {
  if (typeof document.body.style.maxHeight != "undefined") {
	  // do nothing, because IE7 supports alpha transparency!
	}
	else {
    for (var i=0; i<document.images.length; i++) {
	    var img = document.images[i];
	    var imgName = img.src.toUpperCase();
		 
	    if (imgName.substring(imgName.length-3, imgName.length) == "PNG") {
		    var imgID = (img.id) ? "id='" + img.id + "' " : "";
		    var imgClass = (img.className) ? "class='" + img.className + "' " : "";
		    var imgTitle = (img.title) ? "title='" + img.title + "' " : "title='" + img.alt + "' ";
		    var imgStyle = "display:inline-block;" + img.style.cssText ;
		    var imgAttribs = img.attributes;
			 
		    for (var j=0; j<imgAttribs.length; j++) {
			    var imgAttrib = imgAttribs[j];
			   
				  if (imgAttrib.nodeName == "align") {		  
			      if (imgAttrib.nodeValue == "left") imgStyle = "float:left;" + imgStyle;
			      if (imgAttrib.nodeValue == "right") imgStyle = "float:right;" + imgStyle;
			      break;
			    }
        }
			 
		    var strNewHTML = "<span " + imgID + imgClass + imgTitle;
			 
		    strNewHTML += " style=\"" + "width:" + img.width + "px; height:" + img.height + "px;" + imgStyle + ";"
	      strNewHTML += "filter:progid:DXImageTransform.Microsoft.AlphaImageLoader";
		    strNewHTML += "(src=\'" + img.src + "\', sizingMethod='scale');\"></span>" ;
		    img.outerHTML = strNewHTML;
		    i = i-1;
	    }
    }
  }
}

// This displays a map containing the information given above. It checks that the user's browser is compatible.
// If it is not, it issues a warning (in a real application it would take the user to a different page). If all
// is well it creates a new GMap2 instance in the "map" <div> and adds the standard controls. Then it centres
// the map at the default coordinates and with the default zoom. Finally, it adds a marker at the coordinates of
// the qualifying element..
function loadGoogleMap (mapZoom,mapLat,mapLong) {
  // check that the user's browser is compatible
  if (GBrowserIsCompatible()) {
    // it is so create a new map instance to go in the "map" <div>
    var map = new GMap2(document.getElementById("map"));
    // add Map and Type controls
    map.addControl(new GSmallMapControl());
    map.addControl(new GMapTypeControl());
    // set the centre of the map
    map.setCenter(new GLatLng(mapLat,mapLong), mapZoom);
    // set the point at which the location is to be shown
    var point = new GLatLng(mapLat,mapLong);
    // add the property's marker to the map as an overlay
    map.addOverlay(createMapMarker(point));
  }
  else {
    // it isn't so tell the user
    alert("We are sorry but your browser is too old to support our interface.");
  }
}

// This creates a new location marker that is displayed on the map.
function createMapMarker (point) {
  // create a new property marker to be shown at the point
  var locationMarker = new GMarker(point);

  return locationMarker;
}

// This function sends an email from information supplied on the "contact.htm" page.
function emailContact () {
  var crlf = " | ";
  var mailto = "sales@adiltd.co.uk";
	var messageBody = "";
	
	var enquiryName = (document.Enquiry.EnquiryName.value != "") ? document.Enquiry.EnquiryName.value : "Not given";
	var enquiryCompany = (document.Enquiry.EnquiryCompany.value != "") ? document.Enquiry.EnquiryCompany.value : "Not given";
	var enquiryEmail = (document.Enquiry.EnquiryEmail.value != "") ? document.Enquiry.EnquiryEmail.value : "Use sender";
	var enquiryTelephone = (document.Enquiry.EnquiryTelephone.value != "") ? document.Enquiry.EnquiryTelephone.value : "Not given";
	var enquirySubject = (document.Enquiry.EnquirySubject.value != "") ? document.Enquiry.EnquirySubject.value : "General Enquiry";
	var enquiryDetail = (document.Enquiry.EnquiryDetail.value != "") ? document.Enquiry.EnquiryDetail.value : "Not given";
	var contactTelephone = (document.Enquiry.ContactByTelephone.value == 1) ? "Yes" : "No";
	var contactEmail = (document.Enquiry.ContactByEmail.value == 1) ? "Yes" : "No";
  
  if (enquiryName == "Not given") {
		alert("Please enter your Name...");
		return 0;
	}
	else {
		if ((enquiryTelephone == "Not given") && (contactTelephone == "Yes")) {
		  alert("Please enter your Telephone...");
		  return 0;
	  }
	  else {
	    messageBody += "Name = " + enquiryName + crlf;
			messageBody += "Company = " + enquiryCompany + crlf;
			messageBody += "Email = " + enquiryEmail + crlf;
			messageBody += "Contact by Email = " + contactEmail + crlf;
			messageBody += "Telephone = " + enquiryTelephone + crlf;
			messageBody += "Contact by Telephone = " + contactTelephone + crlf;
			messageBody += "Enquiry Details..." + crlf;
			messageBody += enquiryDetail;

      parent.location.href='mailto:' + mailto + '?subject=' + "From ADI Website: " + enquirySubject + '&body=' + messageBody;
			
			return 1;
    }
	}
}

// This function sends an email from information supplied on the "vacancies.htm" page.
function emailVacancies () {
  var crlf = " | ";
  var mailto = "sales@adiltd.co.uk";
	var messageBody = "";
	
	var enquiryName = (document.Enquiry.EnquiryName.value != "") ? document.Enquiry.EnquiryName.value : "Not given";
	var enquiryCompany = (document.Enquiry.EnquiryCompany.value != "") ? document.Enquiry.EnquiryCompany.value : "Not given";
	var enquiryEmail = (document.Enquiry.EnquiryEmail.value != "") ? document.Enquiry.EnquiryEmail.value : "Use sender";
	var enquiryTelephone = (document.Enquiry.EnquiryTelephone.value != "") ? document.Enquiry.EnquiryTelephone.value : "Not given";
	var enquirySubject = "Vacancies Enquiry";
	var enquiryDetail = (document.Enquiry.EnquiryDetail.value != "") ? document.Enquiry.EnquiryDetail.value : "Not given";
	var contactTelephone = (document.Enquiry.ContactByTelephone.value == 1) ? "Yes" : "No";
	var contactEmail = (document.Enquiry.ContactByEmail.value == 1) ? "Yes" : "No";
  
  if (enquiryName == "Not given") {
		alert("Please enter your Name...");
		return 0;
	}
	else {
		if ((enquiryTelephone == "Not given") && (contactTelephone == "Yes")) {
		  alert("Please enter your Telephone...");
		  return 0;
	  }
	  else {
	    messageBody += "Name = " + enquiryName + crlf;
			messageBody += "Company = " + enquiryCompany + crlf;
			messageBody += "Email = " + enquiryEmail + crlf;
			messageBody += "Contact by Email = " + contactEmail + crlf;
			messageBody += "Telephone = " + enquiryTelephone + crlf;
			messageBody += "Contact by Telephone = " + contactTelephone + crlf;
			messageBody += "Summary of Experience..." + crlf;
			messageBody += enquiryDetail;

      parent.location.href='mailto:' + mailto + '?subject=' + "From ADI Website: " + enquirySubject + '&body=' + messageBody;
			
			return 1;
    }
	}
}

// This function sends an email requesting a CD-ROM from information supplied on the "cdrom.htm" page.
function emailCDROM () {
  var crlf = " | ";
  var mailto = "sales@adiltd.co.uk";
	var messageBody = "Please send me the Systems ADI Group CD-ROM:" + crlf;
	
	var requestName = (document.CDROM.RequestName.value != "") ? document.CDROM.RequestName.value : "Not given";
	var requestCompany = (document.CDROM.RequestCompany.value != "") ? document.CDROM.RequestCompany.value : "Not given";
	var requestAddress1 = (document.CDROM.RequestAddress1.value != "") ? document.CDROM.RequestAddress1.value : "Not given";
	var requestAddress2 = (document.CDROM.RequestAddress2.value != "") ? document.CDROM.RequestAddress2.value : "";
	var requestAddress3 = (document.CDROM.RequestAddress3.value != "") ? document.CDROM.RequestAddress3.value : "";
	var requestPostcode = (document.CDROM.RequestPostcode.value != "") ? document.CDROM.RequestPostcode.value : "Not given";
  
  if ((requestName == "Not given") || (requestCompany == "Not given") || (requestAddress1 == "Not given") || (requestPostcode == "Not given")) {
		alert("Please enter your Name, Company, Address and Postcode...");
		return 0;
	}
	else {
	  messageBody += "Name = " + requestName + crlf;
	  messageBody += "Company = " + requestCompany + crlf;
		messageBody += "Address = " + requestAddress1 + crlf;
		
		if (requestAddress2 != "") messageBody += requestAddress2 + crlf;
		if (requestAddress3 != "") messageBody += requestAddress3 + crlf;
		
		messageBody += requestPostcode + crlf;

    parent.location.href='mailto:' + mailto + '?subject=' + "From ADI Website: ADI CD-ROM Request" + '&body=' + messageBody;
			
		return 1;
  }
}

// This function sends an email containing information supplied by the user on the feedback page.
//
// NB. The form used is called "Feedback". A test call to find "document.forms[0].name" returned "Feedback",
// so something knows about the name of the form. However, if a statement like "document.Feedback.field" is
// used instead of "document.forms[0].field" there is an error that Feedback has no properties!
function emailFeedback () {
  var crlf = " | ";
  var mailto = "sales@adiltd.co.uk";
	var cc = "iansedwell@sds-group.co.uk";
	var messageBody = "Please find below my feedback concerning the ADI Website:" + crlf;
	
	// deal with the option lists
	var found = document.forms[0].Found.options[document.forms[0].Found.selectedIndex].value;
	var os = document.forms[0].OS.options[document.forms[0].OS.selectedIndex].value;
	var modem = document.forms[0].Modem.options[document.forms[0].Modem.selectedIndex].value;
	
	// deal with the radio buttons
  for (i = 0; i < document.forms[0].Ease.length; i++) {
    if (document.forms[0].Ease[i].checked) {
      var ease = 5 - i;
	    break;
	  }
  }

  for (i = 0; i < document.forms[0].Visual.length; i++) {
    if (document.forms[0].Visual[i].checked) {
      var visual = 5 - i;
	    break;
	  }
  }

  for (i = 0; i < document.forms[0].Detail.length; i++) {
    if (document.forms[0].Detail[i].checked) {
      var detail = 5 - i;
	    break;
	  }
  }

  for (i = 0; i < document.forms[0].Perform.length; i++) {
    if (document.forms[0].Perform[i].checked) {
      var perform = 5 - i;
	    break;
	  }
  }

  for (i = 0; i < document.forms[0].Wanted.length; i++) {
    if (document.forms[0].Wanted[i].checked) {
      var wanted = 5 - i;
	    break;
	  }
  }

  for (i = 0; i < document.forms[0].Bookmark.length; i++) {
    if (document.forms[0].Bookmark[i].checked) {
      var bookmark = 5 - i;
	    break;
	  }
  }

  // structure the email
	messageBody += "Found = " + found + crlf;
	messageBody += "Ease = " + ease + crlf;
	messageBody += "Visual = " + visual + crlf;
	messageBody += "Detail = " + detail + crlf;
	messageBody += "Perform = " + perform + crlf;
	messageBody += "OS = " + os + crlf;
	messageBody += "Modem = " + modem + crlf;
	messageBody += "Wanted = " + wanted + crlf;
	messageBody += "Bookmark = " + bookmark + crlf;
	messageBody += "Comments = " + document.forms[0].Comments.value + crlf;
	
  // send it
	parent.location.href='mailto:' + mailto + '?subject=' + "From ADI Website: Website Feedback" + '&cc=' + cc + '&body=' + messageBody;
			
  return 1;
}

// This does the groundwork prior to calling the main routine "displayRouteMap".
function prepareDisplayRouteMap (postcodeTo) {
	var postcodeFrom = (document.Directions.UserPostcode.value != "") ? document.Directions.UserPostcode.value : "";
	
	if (postcodeFrom == "") {
		alert("Please enter your postcode.");
		return 0;
	}
	else {
		return displayRouteMap(postcodeFrom,postcodeTo)
	}
}

// Displays a route map from postcode1 to postcode2. It calls the RAC Route Planner to calculate the route.
function displayRouteMap (postcodeFrom,postcodeTo) {
  var routeWindow = null;
  // make sure postcodeFrom and postcodeTo are well formed
  var fromCode = validatePostcode("From",postcodeFrom);
  var destCode = validatePostcode("To",postcodeTo);
  // if we have good codes, neither will be null
  if ((fromCode != null) && (destCode != null)) {
	  var theURL = "http:\/\/rp.rac.co.uk\/rp\/routeplanner?advanced=false&fromcity=" + fromCode + "&tocity=" + destCode + "&rpgo.x=17&rpgo.y=13";
	  var winName = "RAC Route Planner";
    var features = "scrollbars=yes,";

    features += "toolbar=yes,";
    features += "menuBar=yes,";
    features += "directories=yes,";
    features += "status=yes,";
    features += "resizable=yes,";
  
    routeWindow = openDisplayWindow(routeWindow,theURL,winName,features);
  }
	
	return (routeWindow != null);
}

// Very basic postcode validation routine. It can be greatly improved. For now it just checks that the postcode is
// at least 7 characters long, but no longer than 8, that it contains a single space and that the space is at
// character 4 or 5. If all of those tests are passed, the space is replaced by a "+" and the modified postcode is
// returned as the result. If any of the tests fail, it issues an error message and returns null.
function validatePostcode (id,postcode) {
  // set a test flag
  var goodCode = 0;
  // check that the postcode is well formed
  if ((postcode.length > 6) && (postcode.length < 9)) {
    var pos = postcode.indexOf(" ");
	  if ((pos == 3) || (pos == 4)) {
	    var outbound = postcode.substring(0,pos);
	    var inbound = postcode.substring(pos+1,postcode.length);
	    if (inbound.indexOf(" ") == -1) {
	      goodCode = 1;
	    }
	  }
  }
  // has the test flag been set?
  if (goodCode == 1) {
    // this is most likely a good postcode
	  return outbound + "+" + inbound;
  }
  else {
	  // this is most likely an invalid postcode
	  alert("Please enter a valid '" + id + "' postcode, with a space separating the 'outbound' and 'inbound' elements, e.g. 'BH12 9QT'.");
    return null; 
  }
}

// This retrieves the required image details and calls for it to be displayed in a popup window.
function viewLargeImage(whichCompany,whichImage) {
	// get the company name
	var companyName = getFullCompanyName(whichCompany);
	
	// get the path to where the image should be
	var imagePath = "images/" + whichCompany + "/" + whichImage + "-large.jpg";
	
  // get the image details
	var imageDetails = getImageDetails(whichImage);
	
	// display the image in a popup window
	displayImageWindow(companyName,imagePath,imageDetails[0],imageDetails[1],imageDetails[2]);
}

// This function returns the full name of a company from the supplied mnemonic.
function getFullCompanyName(whichCompany) {
	var companyName = "";
	
	switch (whichCompany) {
		case "adibs":
		  companyName = "ADI Building Services"; break;
		case "adienv":
		  companyName = "ADI Environmental"; break;
		case "adifm":
		  companyName = "ADI Facilities Management"; break;
		case "adiire":
		  companyName = "ADI Ireland"; break;
		case "adiltd":
		  companyName = "ADI Limited"; break;
		case "adimec":
		  companyName = "ADI Mechanical"; break;
		case "adipm":
		  companyName = "ADI Project Management"; break;
		case "adisys":
		  companyName = "Systems ADI Group"; break;
		default:
		  companyName = "Unrecognised Company"; break;
	}
	
	return companyName;
}

// This function returns the required image details as an array - this can be much improved!
function getImageDetails(whichImage) {
	var imageDetails = new Array(3);
	
	switch (whichImage) {
		case "adiltd01":
		  imageDetails = [600,367,"Example installation 1"]; break;
		case "adiltd02":
		  imageDetails = [600,413,"Example installation 2"]; break;
		case "adiltd03":
		  imageDetails = [600,400,"Fermentation attemperation control system diagram"]; break;
		case "adiltd04":
		  imageDetails = [600,450,"FV25 vessel design detail"]; break;
		case "adiltd05":
		  imageDetails = [600,415,"Regenerative fuel cell, Black Start power station"]; break;
		case "adiltd06":
		  imageDetails = [600,449,"Regenerative fuel cell, Crystalliser (Main Process), Black Start power station"]; break;
		case "adiltd07":
		  imageDetails = [600,424,"Control panel manufacture and test facility"]; break;
		case "adiltd08":
		  imageDetails = [600,451,"'Wardrobe' style control panel (access panels removed for clarity)"]; break;
		case "adifm01":
		  imageDetails = [600,480,"Self-service food and beverage counter"]; break;
		case "adifm02":
		  imageDetails = [450,260,"40-year cycle building's operational cost breakdown"]; break;
		case "adimec01":
		  imageDetails = [600,401,"Silo Load Cell Installation, 3 no. - 100 tonne cement silos - cust support legs and install load cells"]; break;
		case "adimec02":
		  imageDetails = [600,427,"Animal Feed Production Plant - Process cell mounting, pipework, control panel, install as system"]; break;
		case "adimec03":
		  imageDetails = [600,448,"Major Plant Installation - fabrication, on-site assembly, foundation, placement"]; break;
		case "adimec06":
		  imageDetails = [600,450,"Assembly shop detail - Light duty system"]; break;
		case "adimec07":
		  imageDetails = [600,398,"White Goods Parts Handling - Belt conveyor"]; break;
		case "adimec08":
		  imageDetails = [600,400,"White Goods Parts Handling - Roller conveyor"]; break;
		case "adimec09":
		  imageDetails = [700,393,"Conveyor System Design"]; break;
		case "adimec10":
		  imageDetails = [400,488,"Process vessel, supports, pipework"]; break;
		case "adimec11":
		  imageDetails = [400,497,"Housing, process vessel, supports, pipework"]; break;
		case "adimec12":
		  imageDetails = [600,519,"Hygenic food standard installation"]; break;
		case "adimec13":
		  imageDetails = [600,406,"Process vessels, support steelwork, pipebridge and piping installation"]; break;
	}
	
	return imageDetails;
}

// This is a constructor function that returns an array created from the details passed to it.

// This prepares an HTML string in which to display a large image from the currently selected property.
// The resulting HTML is then displayed in its own window.
function displayImageWindow (whichCompany,whichImage,imageWidth,imageHeight,imageCaption) {
  var windowRef = null;
  var htmlString = "<!DOCTYPE HTML PUBLIC \"-\/\/W3C\/\/DTD HTML 4.01 Transitional\/\/EN\"";

  htmlString += "<!DOCTYPE html PUBLIC \"-\/\/W3C\/\/DTD XHTML 1.0 Transitional\/\/EN\" \"http:\/\/www.w3.org\/TR\/xhtml1\/DTD\/xhtml1-transitional.dtd\">";
  htmlString += "<html xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">";
  htmlString += "<head>";
  htmlString += "<meta http-equiv=\"Content-Type\" content=\"text\/html; charset=ISO-8859-1\" \/>";
  htmlString += "<title>" + whichCompany + "<\/title>";
  htmlString += "<style type=\"text\/css\">";
  htmlString += "<!--";
  htmlString += "body {";
  htmlString += "margin-left: 10px;";
  htmlString += "margin-top: 10px;";
  htmlString += "margin-right: 10px;";
  htmlString += "margin-bottom: 10px;";
  htmlString += "}";
  htmlString += "-->";
  htmlString += "<\/style>";
  htmlString += "<link href=\"scripts\/adi.css\" rel=\"stylesheet\" type=\"text\/css\" \/>";
  htmlString += "<\/head>";
  htmlString += "<body>";
  htmlString += "<table width=\"100%\" border=\"0\" cellspacing=\"0\" cellpadding=\"0\">";
  htmlString += "<tr>";
  htmlString += "<td width=\"100%\" height=\"40\">";
  htmlString += "<center>";
  htmlString += "<img src=\"" + whichImage + "\" width=\"" + imageWidth + "\" height=\"" + imageHeight + "\" alt=\"Large View Image\" \/>";
  htmlString += "<\/center>";
  htmlString += "<\/td>";
  htmlString += "<\/tr>";
  htmlString += "<tr>";
  htmlString += "<td width=\"100%\" height=\"40\">";
  htmlString += "<center>";
  htmlString += "<p class=\"imageCaption\">" + imageCaption + "<\/p>";
  htmlString += "<\/center>";
  htmlString += "<\/td>";
  htmlString += "<\/tr>";
  htmlString += "<tr>";
  htmlString += "<td width=\"100%\" height=\"40\" align=\"center\">";
  htmlString += "<form id=\"form1\" name=\"form1\" method=\"post\" action=\"\">";
  htmlString += "<input name=\"Close\" type=\"button\" class=\"cmsButtonLabel\" id=\"Close\" value=\"Close\" onclick=\"javascript:window.close();\" \/>";
  htmlString += "<\/form>";
  htmlString += "<\/td>";
  htmlString += "<\/tr>";
  htmlString += "<\/table>";
  htmlString += "<\/body>";
  htmlString += "<\/html>";

  var windowName = whichCompany;
  var scrollbars = "no";
  var location = "no";
  var menuBar = "no";
  var toolBar = "no";
  var directories = "no";
  var status = "no";
  var resizable = "no";
  var width = imageWidth + 20;    // i.e. 10 + 10
  var height = imageHeight + 100; // i.e. 10 + 10 + 40 + 40
  var left = getXCoordinate (width);
  var top = getYCoordinate (height);
  
  windowRef = displayHTMLInWindow(windowRef,htmlString,windowName,scrollbars,location,menuBar,toolBar,directories,status,resizable,width,height,left,top)
}

//
// This function calculates the position of the left edge (x-coordinate) of a window of a
// given width in order to be able to display it in the centre of the screen.
//
//    windowW - width of the window to be displayed
//
// Note it is up to the programmer to make sure the window will fit the available screen
// width in the first place (see "checkAvailScreenSize").
//
function getXCoordinate (windowW) {
  var screenW = screen.availWidth;
  
  return Math.floor((screenW - windowW) / 2);
}

//
// This function calculates the position of the top edge (y-coordinate) of a window of a
// given height in order to be able to display it in the centre of the screen.
//
//    windowH - height of the window to be displayed
//
// Note that it is up to the programmer to make sure the window will fit the available screen
// width in the first place (see "checkAvailScreenSize").
//
function getYCoordinate (windowH) {
  var screenH = screen.availHeight;
  
  return Math.floor((screenH - windowH) / 2);
}

// Display HTML in a new window. If the window already exists, the call to give the window
// the focus ensures it is brought to the front of the open window stack. If it is not given
// the focus and the window is already open, it will be redrawn with the appropriate content
// but it will remain at its current position in the open window stack and may be hidden by
// windows higher in the stack.
//
//    windowRef   - reference variable pointing to the window
//    pageContent - HTML content to be displayed in the new window
//    windowName  - name to be displayed in the window's caption bar
//    scrollbars  - "yes" if the window is drawn with scrollbars, "no" otherwise
//    location    - "yes" if the window is drawn with a location bar, "no" otherwise
//    menuBar     - "yes" if the window is drawn with a menuBar, "no" otherwise (ignored by MacOS)
//    toolBar     - "yes" if the window is drawn with a toolBar, "no" otherwise
//    directories - "yes" if the window is drawn with the default button panel, "no" otherwise
//    status      - "yes" if the window is drawn with a status bar, "no" otherwise
//    resizable   - "yes" if the window is resizable, "no" otherwise
//    width       - width of the window's drawRect in pixels
//    height      - height of the window's drawRect in pixels
//    left        - left edge (x-coordinate) of the window's drawRect in pixels
//    top         - top edge (y-coordinate) of the window's drawRect in pixels
function displayHTMLInWindow (windowRef,pageContent,windowName,scrollbars,location,menuBar,toolBar,directories,status,resizable,width,height,left,top) {
  var featureStr = "scrollbars=" + scrollbars + ",";
  featureStr += "location=" + location + ",";
  featureStr += "menuBar=" + menuBar + ",";
  featureStr += "toolBar=" + toolBar + ",";
  featureStr += "directories=" + directories + ",";
  featureStr += "status=" + status + ",";
  featureStr += "resizable=" + resizable + ",";
  featureStr += "width=" + width + ",";
  featureStr += "height=" + height + ",";
  featureStr += "left=" + left + ",";
  featureStr += "top=" + top;

  if ((windowRef == null) || (windowRef.closed)) {
    windowRef = window.open("","",featureStr);
      
    if (windowRef != null) {
      windowRef.document.writeln(pageContent);
      windowRef.document.close();
      windowRef.focus();
    }
    else {
      alert("The '" + windowName + "' cannot be opened. You might be low on memory.");      
    }   
  }
  else {
    windowRef.focus();
  }
  
  return windowRef;
}

// Display a page in a new window. If the window already exists, the call to give the window
// the focus ensures it is brought to the front of the open window stack. If it is not given
// the focus and the window is already open, it will be redrawn with the appropriate content
// but it will remain at its current position in the open window stack and may be hidden by
// windows higher in the stack.
function openDisplayWindow (windowRef,contentURL,windowName,features) {
  if ((windowRef == null) || (windowRef.closed)) {
    windowRef = window.open(contentURL,"",features);
  }
  else {
    windowRef.focus();
  }
  
  return windowRef;
}
