/*
  Get the value of a form field in the current window or a given
  window. The field can be text, textarea, hidden or combobox.

  Parameters:
  	sName			The name of the field. 
  	sFormName	Optional. The name of the form containing the field.
 
  Returns:
  	The field value as a string. 
*/
function StdGetFieldValue(sName, sFormName)
{
	var f = (sFormName==null) ? _StdGetMainForm() : window.document.forms[sFormName];
	if (f==null) return null;

	var fld = f[sName];	
	if (fld==null) return null;

	var sType = fld.type ? fld.type : fld[0].type ;

	if (sType=="text"||sType=="textarea"||sType=="hidden"||sType=="password") {
        if (fld.length) {
			alert("Duplicate fields for name "+sName);
           return null;
		}
		return fld.value;
	}

	if (sType=="select-one" ) {
		var opt = fld.options[fld.selectedIndex]
		return (opt.value.length) ? opt.value : opt.text 
	}

	if (!fld.length) fld = new Array(fld);

    if (sType=="radio" || sType=="checkbox") {

		var s = "";
	    for (var n=0; n<fld.length; n++)  
			if (fld[n].checked=="1") s += fld[n].value;
        return s;   

	}

	return null;
}



/*
	
*/
function _StdGetMainForm()
{
 	/*

  	*/
  	var f = document.forms.mainform;
  	if (f!=null) return f;

  	var f = document.forms[0];
  	if (f!=null&&f.name!="qsform") return f;

  	var f = document.forms[1];
  	if (f!=null&&f.name!="qsform") return f;

  	alert("Cannot locate main form");
}

/*
	Set the list of options for a dropdown field.

  	Parameters:
  		sName		the name of the field
		aValues	an array holding the list of option values (may contain a '|' character as in Notes)
       bHeader   boolean set to true if the first option currently in the list is NOT to be replaced ('---select from list---')


*/
function _StdSetSelOptions( sName, aValues, bHeader, iDefaultIndex)
{
	/*
		Values paramter can be String or Array.
	*/
	if (aValues=="") aValues = new Array( );
	if (typeof(aValues)=="string") aValues = aValues.split("; "); 

 	/*
    	Get a handle to the form.
  	*/
  	var f = _StdGetMainForm();
  	if (f==null) return;

 	/*
    	Get a handle to the dropdown list.
  	*/
	var sel = f[sName];
    if (sel==null) return;

    /*
		Handle preservation of a header option line if required.      
    */
	var i = (bHeader==false) ? 0 : 1;
	sel.selectedIndex = 0;
	sel.options.length = aValues.length+i;

    /*
      Loop through the values setting the option text.
    */
    for (var j=0; j<aValues.length; j++, i++) {
	  var a = aValues[j].split("|"); 
      sel.options[i].text = a[0];
      sel.options[i].value = a[1]?a[1]:a[0];
    }

   /* 
       Set the default value	
   */
       if (iDefaultIndex != null && iDefaultIndex <= aValues.length) {
         sel.options[iDefaultIndex].selected = true;
         }

}



/*
	Set the list of options for a dropdown field and optionally set the value of the field.

  	Parameters:
  		sName		the name of the field
		aValues	an array holding the list of option values (may contain a '|' character as in Notes)
	    bHeader   boolean set to true if the first option currently in the list is NOT to be replaced ('---select from list---')
        sValue      the selected value to set in the field

*/
function StdSetDropdownOptions( sName, aValues, bHeader, sValue)
{
	/*
		Values paramter can be String or Array.
	*/
	if (aValues=="") aValues = new Array( );
	if (typeof(aValues)=="string") aValues = aValues.split("; "); 

 	/*
    	Get a handle to the form.
  	*/
  	var f = _StdGetMainForm();
  	if (f==null) return;

 	/*
    	Get a handle to the dropdown list.
  	*/
	var sel = f[sName];
    if (sel==null) return;

    /*
		Handle preservation of a header option line if required.      
    */
	var i = (bHeader==false) ? 0 : 1;
	sel.selectedIndex = 0;
	sel.options.length = aValues.length+i;

    /*
      Loop through the values setting the option text.
    */
    for (var j=0; j<aValues.length; j++, i++) {
	  var a = aValues[j].split("|"); 
      sel.options[i].text = a[0];
      sel.options[i].value = a[1]?a[1]:a[0];
	  if (sValue!=null&&sel.options[i].value == sValue) sel.options[i].selected = true;
    }

}


/*
  This function initializes combo box option lists. This is a workaround for the
  fact that we cannot set the width of a combo box in Netscape. We allow the page
  to load with a truncated list of options, setting the size of the box on the page,
  and we then fill out the option list in this onload routine.
*/
function _StdSetListChoices()
{  
  /*
    Get a handle to the form.
  */
  var f = _StdGetMainForm();
  if (f==null) return;

  /*
    Loop through the fields on the form.
  */
  for (var n=0; n<f.length; n++) {

    /*
      Get the current field.
    */
    var e = f.elements[n];
        
    /*
      We are only interested in fields names xxxChoices (this field
      will hold the choices for the combobox called xxx).
    */
    if (e.name.match(/Choices$/)==null) continue;
  
    /*
      Get the combobox field and check its not hidden.
    */
    var sName = e.name.replace(/Choices$/, "");
    var sel = f[sName];
    if (sel.type=="hidden") continue;

    /*
      Extract the list of choices.
    */
    var aValues = e.value.split("; ");
  
    /*
      Skip a '--Select from List--' marker which may be in the 
      existing option list.
    */
    var i;
    if (sel.options.length>0&&sel.options[0].text.match(/[-]*select from list[-]*/i)) 
      i=1;
    else
      i=0;

    /*
      Handle the case of a listbox, just fill in the list of values.
    */
    if (sel.type=="select-multiple") {
      MslSetList(sel, aValues);    
      return;
    }
  
    /*
      Loop through the values setting the full option text
      in place of the truncated text.
    */
    for (var j=0; j<aValues.length; j++,i++) {
      sel.options[i].text = aValues[j];  }

  }
  
}

/*
	Extract a named parameter from the query string.
*/
function StdGetQueryStringParameter(sName)
{
	var r = new RegExp("[?|&]"+sName+"=([^&]*)","i");
	var a = location.search.match(r);
    return a==null ? null : a[1];
}

/*
    The Standard Subform sets this routine as the OnLoad routine for every page
     after saving any previously existing onload routine in the variable OldOnLoad.
*/
function _StdOnLoad()
{ 
	/*
		If the current location is at the top of the backlink stack then remove it.
	*/
	if (_NavGetCurrentLocation( ).toLowerCase()==_NavPeekBacklink( ).toLowerCase())
		_NavPopBacklink();
  
	/*
		Loop through all the links on the page removing any that use SSL.
	*/
	var a = document.links;
	for (var n=0; a && n<a.length; n++) {
		var e = a[n];
		if (e.href.substr(0,6)=="https:")
			e.href = "http:"+e.href.substr(6)
	}

	/*
		Call the original OnLoad routine.
	*/
  	if (window.OldOnLoad) OldOnLoad();
 
	/*
		Call any page-specific OnLoad routine.
	*/
  	if (window.doOnLoad) doOnLoad();
 
	/*
		Put up any alert message.
	*/
	var sAlert = window.FcmAlert ? window.FcmAlert : StdGetCookie("FcmAlert");  
 	if (sAlert&&sAlert!="-") {
		alert(unescape(sAlert));  
		StdSetCookie("FcmAlert", "-", -1000);
	}

	/*
		Position cursor in scroll box if present..
	*/
   if (document.forms.VScrollBox)
	   document.forms.VScrollBox.VKey.focus();

}

/*
    The JSPs set this routine as the OnSubmit routine for every form page.
*/
function _StdOnSubmit()
{
	/*
		Call any page-specific OnSubmit handler.
	*/
  	if (window.doOnSubmit) if (doOnSubmit()==false) return false;

	if (window._ActionPostInProgress == 1) return true;
	return false;
}


/*
    Escape the three characters not allowed in a cookie value.
*/
function _StdCookieEscape ( s )
{
    return s.replace( / /g, "%20" ).replace( /;/g, "%3B" ).replace( /,/g, "%2C" );	
}

/*
    Unescape the three characters not allowed in a cookie value.
*/
function _StdCookieUnescape ( s )
{
    return s.replace( /%20/g, " " ).replace( /%3B/g, ";"  ).replace( /%2C/g, "," );	
}

/*
  Get a cookie by name.

  Parameters:
  	sName	The name of the field.

  Returns:
  	The cookie value as a string.

*/
function StdGetCookie(name) 
{   
	///////NB. What if the name appears twice?(!!)
	var start = document.cookie.indexOf(name+"=");
    var len = start+name.length+1;
    if ((!start) && (name != document.cookie.substring(0,name.length))) return null;
    if (start == -1) return null;    
    var end = document.cookie.indexOf(";",len);
    if (end == -1) end = document.cookie.length;
    return _StdCookieUnescape(document.cookie.substring(len,end));
}
    
/*
  Set a cookie into the browser.

  Parameters:
  	sName		The name of the cookie.
  	sValue		The value of the cookie.
  	iLifetime		The cookie lifetime in minutes (0 for cookie to live until browser reload) .
  	sPath			The cookie path.
  	sDomain	The cookie domain.
	bSecure		True if the cookie is only to be sent over a secure (SSL) session.

  Returns:
  	None.
*/
function StdSetCookie(name,value,lifetime,path,domain,secure) 
{
	if (lifetime<0 || value=="") lifetime = -10000;

	if (path==null) path = (window.CurrentDir?window.CurrentDir:"/");
	if (path.charAt(0)!='/') path = "/" + path;
	if (path!="/" && path.charAt(path.length-1)=='/') path = path.substring(0, path.length-1);

	//If no domain specified take the domain part of the current host name.	
	if (domain==null) {
		domain = location.host ;
        if (domain.search(/\.[^\.]*\./)>0)  domain = domain.replace(/^[^\.]*\./, ".") ;
    }

	//Remove a port number if present.	
	var i =domain.indexOf(":");
	if (i > -1) domain = domain.substring(0, i);

  	var now = new Date( );
	var expires = lifetime?new Date(now.getTime()+1000*60*lifetime):null;

     document.cookie = name + "=" +_StdCookieEscape(value) +
        ( (expires) ? ";expires=" + expires.toGMTString() : "") +
        ( (path) ? ";path=" + path : "") + 
        ( (domain) ? ";domain=" + domain : "") +
        ( (secure) ? ";secure" : "");

}


/*
	Invoke the IE4 debugger.
function _debugger( )
{
	debugger
}
*/



/*
  Add a new element onto the end of an Array.
  
  Parameters:
  	a 	the Array 
  	o 	the element to be appended
*/
function _push (a, o)
{
	a[a.length]=o
}

/*
  Remove (and return) the last element of an Array.
  Return null if the array is empty.

  Parameters:
  	a 	the Array 
  
  Returns:
  	The removed element, or null if the Array is empty
*/
function _pop(a)
{
	if (a.length==0) return null
	var o = a[a.length-1]
	a.length = a.length-1
	return o
}


/*
  Reduce the size of an Array by deleting entries from the front
  so as to leave only the last n entries.
  
  Parameters:
  	a 		the Array to reduce
  	nSize	the new size of the Array   	
*/
function _compressArray(a, nSize)
{
    for (var n=0; n<nSize; n++) a[n] = a[(a.length-nSize)+n];
    a.length = nSize;
}

/*



*/
function _StdViewCacheAdd(sTag, sValue)
{
	var a = this[sTag];

	if (a==null) {
		this[sTag]=new Array(sValue);
		return;
	}

	_push(a, sValue); 	
}


/*
  Determine whether the current window, whose location is about to change,
  may contain unsaved changes entered by the user. If the page
  may contain unsaved updates then warn the user and allow the user
  to cancel the location changing operation.
   
  Returns:
  	false if the user indicated the windows contents should not be
  	changed, true otherwise
*/
function NavConfirmExit( )
{
   /*
   	Check for the presence of the EditMode variable, which is set by
     the Standard Subform to indicate a document in edit mode, and also
     for the ConfirmExit variable which a form will set if it requires exit 
     confirmation processing.
   */
	var win = window;
   var bConfirm = win.ConfirmExit && win.EditMode;
  
   /*
   	Apply the same check to all frames within the window.
   */
   for (var n=0; n<win.frames.length; n++)
   	 bConfirm = bConfirm || (win.frames[n].ConfirmExit&&win.frames[n].EditMode)

   /*
   	No need for confirmation.
   */
   if (!bConfirm) return true;
   
   /*
   	Allow the user to cancel the operation.
   */
   return confirm("If there are unsaved changes on the current page they will be lost.\nAre you sure you want to proceed?");
}



/*
  Store the Backlinks structure in a (non-peristent) browser cookie.
  
  Parameters:
  	a	the array of backlinks

*/
function _NavSetBacklinks ( a )
{
	/*
		Build a string.
	*/
	var s = "";
	for (var n=0; n<a.length; n++) {
		s += (n==0) ? "" : "~";
		s += a[n];
	}
	if (s=="") s = "(null)";
	
	/*
		Store the cookie. The domain is one level up from the current host name
       so the same stack will be shared by www1.frost.com and www2.frost.com.
	*/
   StdSetCookie ( "FcmBLnk", s, 0 );
}


/*
  Get the Backlinks structure from the browser cookie.
  
  Returns:
  	a	  the (possibly empty) array of backlinks

*/
function _NavGetBacklinks (  )
{
	var s = StdGetCookie ( "FcmBLnk");
	if (s==null) return new Array;
	if (s=="(null)"	) return new Array;
    var a = s.split("~");	
//	for (var n=0; n<a.length; n++) a[n]=_NavDecodeBacklink(a[n]);
	return a;
}

/*
  Store the current location in the Backlink structure to 
  facilitate a return to this location.  
*/
function NavPushBacklink( href )
{
	/*
	  Get the current location if no location was passed.
	*/
	if (href==null) href = _NavGetCurrentLocation( );
	
	/*
	  Get the backlinks structure.
	*/
	var aBacklinks = _NavGetBacklinks( );

	/*
	  If this address is already at the top of the stack then return.
	*/
	if (aBacklinks.length>0&&href==aBacklinks[aBacklinks.length-1]) return;

	/*
	  Compress the array if we have exceeded the maximum size.
	*/
	if (aBacklinks.length>12) _compressArray(aBacklinks, 8);  ////////////////////////////

	/*
	  Add to the backlinks structure.
	*/	
	_push(aBacklinks, href);

	/*
	  Update the cookie.
	*/
	_NavSetBacklinks(aBacklinks);
}


/*
  Return the current top of the backlink stack.  
*/
function _NavPeekBacklink( )
{
	var a = _NavGetBacklinks( );
	return (a.length==0)?"":a[a.length-1];
}

/*
	Remove and return the current top of the backlink stack.     
*/
function _NavPopBacklink( )
{
	/*
	  Get the backlinks structure.
	*/
	var al = _NavGetBacklinks( );
	if (al.length==0) return null 
	
	/*
	  Get the backlink location.
	*/
     var href = _pop(al);   
     
	/*
	  Update the backlinks structure.
	*/
	_NavSetBacklinks(al);

	/*
	  Return the result.
	*/
	return href;
}

/*
  Get the href attribute from any <BASE> tag on the page.
  
  Parameters:
  	None.
*/
function _NavGetBaseHref()
{
	var a = document.getElementsByTagName("BASE");
	if (a.length==0) return null;
	if (a.length>1) { alert("Multiple base tags"); return null; }
	var s = a[0].href;
	return s==""?null:s;
}

/*
  Navigate to a new location.
  
  Parameters:
  	url			the new location
  	bReload	true to force a reload from the server
	bReplace true to suppress creation of a browser history entry
*/
function _NavSetLocation(url, bReload, bReplace)
{
     var dTemp = new Date();

	/* 
	  Add a dummy query string parameter to force a reload from the
	  server by ensuring the url is not found in the browser cache.
	*/
     if (bReload) {
     	NavSetParameter(url, "fcmseq", dTemp.valueOf());
     }

	/*
	  If this is a relative url then expand it into a full url relative the 
	  any <base> tag. (This does not seem to be done automatically 
	  by the browser javascript engine.)
	*/
	url = _NavExpandUrl(url);

     /*
        Set the location.
     */	
	 if (bReplace) window.location.replace(url);
	 	else window.location.href = url;
}


/*

*/
function _NavGetCurrentLocation( )
{
	/*
	  Remove transient query string paramters.
	*/
	return window.location.href.replace(/&alert=[^&]*/gi, "");
}

/*
  Set the window location to the last baclink location 
  stored in the backlinks structure.
  
  Parameters:
  	bRefresh	true to force a reload from the server

*/
function NavBack(bReload)
{
	/*
	  Get the backlink.   
	*/
	var href = _NavPopBacklink(  ); 
     if (href==null) {
		history.back( );
 		return;
	}

	/*
	 	If the backlink contains fcmseq=0 then this indicates to always reload.   
	*/
	if (href.search(/&fcmseq=0/i)>=0) bReload = true;
	
     /*
       Set the new location.
     */
     _NavSetLocation(href, bReload, true);
}


/*
  Refresh the contents of the current window. 	
*/
function NavReload( )
{ 
	_NavSetLocation(window.location.href, true, true);
}


/*
  Navigate to a new location.    

  Parameters:
  	url     	 the new location.
  	bBacklink  true if the current location should be saved as a backlink.
  	bReload true to force a reload from the server.
	bReplace true to suppress creation of a browser history entry
  	
*/
function _NavGo(url, bBacklink, bReload, bReplace)
{	
	/*
	  Check for possible unsaved changes in the frame.
	*/
	if (!NavConfirmExit( )) return null;

	/*
	  Store the backlink if necessary.
	*/
	if (bBacklink) NavPushBacklink( );

	/*
	  Set the new location.
	*/
	return _NavSetLocation(url, bReload, bReplace);
}

/*
  Navigate to a new location with standard history updated.    

  Parameters:
  	url     	 the new frame location.
  	bBacklink  true if the current location should be saved as a backlink.
  	bReload true to force a reload from the server.
  	
*/
function NavOpen(url, bBacklink, bReload)
{	
	return _NavGo(url, bBacklink, bReload, false);
}

/*
	Return the hostname of the server's cluster.
*/
function _NavGetClusterHost()
{	
	var h = location.hostname;

	if (_NavIsTestHost()) return h;

	if (window.ClusterHost==null||window.ClusterHost=="") {
		if (h.indexOf("test")>=0) return h;
		if (h.indexOf("conseq")>=0) return h;
		if (h.substr(0,3)=="www" && h.substr(3,4)>="0" && h.substr(3,4)<="9")
			return "www"+h.substr(4);
		else
  		   return h;
	}
	else {
		return window.ClusterHost;
	}
}


/*
	Put up the login screen with appropriate redirect.
*/
function _NavLogin()
{	
	if (location.href.indexOf("/frost-home.pag")>0)
		_NavLogin1();
	else
		_NavLogin2();
}

/*
	Put up the login screen with redirect to the users personal home page.
*/
function _NavLogin1()
{	
    var url = NavGetServletUrl("home.pag");
	var prot = (window.SecureLogin==1) ? "https:" : "http:";
	var login = NavGetServletUrl("login-form.pag", window.CertifiedHost, prot);
	window.location = login + "?RedirectTo="+escape(url);
}

/*
	Put up the login screen with redirect to the current page.
*/
function _NavLogin2()
{	
	var prot = (window.SecureLogin==1) ? "https:" : "http:";
	var login = NavGetServletUrl("login-form.pag", window.CertifiedHost, prot);
	window.location = login + "?RedirectTo="+escape(location.href);
}

/*
	Logout and leave the user with a login screen with onward redirection to home page.
*/
function _NavLogout()
{	
  	NavOpen("logout.act");
}

/*
  Navigate to a new location with standard browser history not updated.    

  Parameters:
  	url     	 the new location.
  	bBacklink  true if the current location should be saved as a backlink.
  	bReload true to force a reload from the server.
  	
*/
function NavReplace(url, bBacklink, bReload)
{	
	return _NavGo(url, bBacklink, bReload, true);
}

/*
	Submit the current form to an agent for processing.
	
	Parameter:
		sAgent 				The name of the agent (must reside in bin.nsf).
		sQueryString		Any paramters to pass in the query string
		bBacklink			True to push the current location onto the backlink stack
*/
function NavPostAgent ( sAgent, sQueryString, bBacklink )
{
    /*
		Guard against double pressing of an action button.
	*/
	if (window._NavActionRunning==1) { window.status="Action already in progress.\nPlease wait..."; return; }			

	/*
		If form validation routines are present then call them.
	*/
    if (_NavValidateForm()==false) return;

	/*
		Fix for loss of REMOTE_USER when websphere dsapi is installed.
	*/
	StdSetCookie("Fcmru", window.CurrentUser,null,"/"+window.CurrentDir)

    var dTemp = new Date( );

	var f = _StdGetMainForm(); 
	if (bBacklink) NavPushBacklink( );
	f.action="../bin.nsf/"+sAgent+"?OpenAgent"+(sQueryString?sQueryString:"")+"&fcmseq="+dTemp.valueOf( );
	f.submit( );
	window._NavActionRunning = 1;
}


/*
	
*/
function _NavValidateForm()
{
	/*
		If a format validation routine is present (generated by jsp tags) then call it.
	*/
	if (window.doFormatValidation) {
		var msg = doFormatValidation( ); 
		if (msg) { 
			alert(msg); 
			return false; 
		}
	}

	/*
		If a page validation routine is present then call it.
	*/
	if (window.doPageValidation) {
		var msg = doPageValidation( ); 
		if (msg) { 
			alert(msg); 
			return false; 
		}
	}

	var f = _StdGetMainForm(); 
	if ( f.onsubmit ) {
		window._ActionPostInProgress = 1
		var b = f.onsubmit( );
		window._ActionPostInProgress = 0
		if (b==false) return false;
	} 

    return true;
}


/*
	Invoke an agent via a GET request.
	
	Parameter:
		sAgent 				The name of the agent (must reside in bin.nsf).
		sQueryString		Any paramters to pass in the query string
		bBacklink			True to push the current location onto the backlink stack
*/
function NavGetAgent ( sAgent, sQueryString, bBacklink )
{
    /*
		Guard against double pressing of an action button in Netscape.
	*/
	if (window._NavActionRunning==1) { window.status="Action already in progress.\nPlease wait..."; return; }			

	/*
		Fix for loss of REMOTE_USER when websphere dsapi is installed.
	*/
	StdSetCookie("Fcmru", window.CurrentUser,null,"/"+window.CurrentDir)

   var url = "../bin.nsf/"+sAgent+"?OpenAgent"+(sQueryString?sQueryString:"");
	NavReplace(url, bBacklink, true);
	window._NavActionRunning = 1;
}

/*
	Determine whether hostname is a local test environment host.
	
	Parameter:
		sHost			        The given host.
*/
function _NavIsTestHost ( sHost )
{
	if (sHost==null || sHost=="") sHost = location.hostname;
	return (sHost.substr(0,3)=="tst" && sHost.substr(4,1)=="." );
}

/*
	Determine the servlet host for a given host name.
	
	Parameter:
		sHost			        The given target host.
*/
function _NavGetServletHost ( sHost )
{
	if (sHost==null) sHost = location.hostname;
	if (_NavIsTestHost(sHost) && sHost.indexOf(":")<0) sHost += ":8080";
	return sHost;
}

/*
	Determine the domino host for a given host name.
	
	Parameter:
		sHost			        The given target host.
*/
function _NavGetDominoHost ( sHost )
{
	if (sHost==null) sHost = location.hostname;
	if (_NavIsTestHost(sHost) && sHost.indexOf(":")>0) {
		var i = sHost.indexOf(":");
		sHost = sHost.substring(i);
    }
	return sHost;
}

/*
	Get the URL for a servlet.
	
	Parameter:
		sServlet 				The name of the servlet.
		sHost			        The host on which the action is to be run (null for current host)
		sProtocol		        The protocol to use (null for current protocol)
*/
function NavGetServletUrl( sServlet, sHost, sProtocol )
{
	/*
		Map host name to corresponding servlet host.
	*/
   sHost = _NavGetServletHost( sHost );

	/*
		Default the protocol if not supplied
    */
    if (sProtocol==null) sProtocol = location.protocol;

	sPort = (location.port == "80"||location.port == "") ? "" : ":" + location.port;

	/*
		Add a colon if needed.
    */
    if (sProtocol=="http") sProtocol = "http:";
    if (sProtocol=="https") sProtocol = "https:"; 

	/*
		Build the url using the current path so as to ensure cookies are sent by the browser.
	*/
   return sProtocol + "/" + "/" + sHost + sPort +"/"+ window.CurrentDir+sServlet;

}


/*
	Get the submit address for an action handler.
	
	Parameter:
		sAction 				The name of the action.
		sQueryString		Any paramters to pass in the query string
		sHost			        The host on which the action is to be run (null for current host)
		sProtocol		        The protocol to use (null for current protocol)
*/
function NavGetActionUrl( sAction, sQueryString,sHost, sProtocol )
{
	/*
		Get the URL of the fcom servlet.
	*/
   var url = NavGetServletUrl("fcom",sHost, sProtocol);

   var dTemp = new Date( );

	//NB: Don't include OpenAgent because the lack of an '=' breaks the websphere query string parser.
	return url+"?ActionName="+sAction+(sQueryString?sQueryString:"")+"&fcmseq="+dTemp.valueOf( ); 
}


/*
	Submit the current form to a servlet for processing.
	
	Parameter:
		sAction					The name of the action 
		sQueryString		Any paramters to pass in the query string
		bBacklink				True to push the current location onto the backlink stack
		sHost			        	The host on which the action is to be run
*/
function NavPostAction ( sAction, sQueryString, bBacklink, sHost, sProtocol )
{
    /*
		Guard against double pressing of an action button in Netscape.
	*/
	if (window._NavActionRunning==1) { window.status="Action already in progress.\nPlease wait..."; return; }			

	/*
		.
	*/
	if (sProtocol==null) sProtocol=window.location.protocol;
  
	/*
		If form validation routines are present then call them.
	*/
    if (_NavValidateForm()==false) return;

	/*
		Get the action url.
	*/
   var url = NavGetActionUrl(sAction, sQueryString, sHost, sProtocol);

	/*
		Push a backlink if required.
	*/
	if (bBacklink) NavPushBacklink( );

	/*
		Submit the form.
	*/
	var f = _StdGetMainForm(); 
	f.action=url;
	f.submit( );

	/*
		Set flag to prevent duplicate submission.
	*/
	window._NavActionRunning = 1;

}


/*
	Invoke an action handler via a GET request.
	
	Parameter:
		sAction 				The name of the action.
		sQueryString		Any paramters to pass in the query string
		bBacklink			True to push the current location onto the backlink stack
		sHost			        The host on which the action is to be run
*/
function NavGetAction ( sAction, sQueryString, bBacklink, sHost, sProtocol)
{
    /*
		Guard against double pressing of an action button.
	*/
	if (window._NavActionRunning==1) { window.status="Action already in progress.\nPlease wait..."; return; }			

	/*
		Get the action url.
	*/
   var url = NavGetActionUrl(sAction, sQueryString, sHost, sProtocol);

	/*
		Get the action url.
	*/
	NavOpen(url, bBacklink, true);

    /*
		Guard against double pressing of an action button.
	*/
	window._NavActionRunning = 1;
}

/*
	Invoke an action on  a PageServlet via a GET request.
	
	Parameter:
		sServlet 			The servlet name.
		sMode 				The mode parameter (open, edit create).
		sQueryString		Any paramters to pass in the query string
		bBacklink			True to push the current location onto the backlink stack
		sHost			       The host on which the action is to be run
		sProtocol			   Either http or https
*/
function _NavGetPageAction (sServlet, sMode, sQueryString, bBacklink, sHost, sProtocol)
{
    /*
		Guard against double pressing of an action button.
	*/
	if (window._NavActionRunning==1) { window.status="Action already in progress.\nPlease wait..."; return; }			

	/*
		Get the servlet url.
	*/
   var url = NavGetServletUrl(sServlet, sHost, sProtocol);


	NavOpen(url+"?mode="+sMode+(sQueryString?sQueryString:""), bBacklink, true);

    /*
		Guard against double pressing of an action button.
	*/
	window._NavActionRunning = 1;
}


/*
	Invoke an action on  a PageServlet via a GET request.
	
	Parameter:
		sServlet 			The servlet name.
		sMode 				The mode parameter (open, edit create).
		sQueryString		Any paramters to pass in the query string
		bBacklink			True to push the current location onto the backlink stack
		sHost			       The host on which the action is to be run
		sProtocol			   Either http or https
*/
function _NavGetPageActionPop (sServlet, sMode, sQueryString, bBacklink, sHost, sProtocol)
{
    /*
		Guard against double pressing of an action button.
	*/
	if (window._NavActionRunning==1) { window.status="Action already in progress.\nPlease wait..."; return; }			

	/*
		Map host name to corresponding servlet host.
	*/
  	sHost = _NavGetServletHost( sHost );

	/*
		Determine the protocol to use.
	*/
  	if (sProtocol==null) sProtocol = location.protocol;

	/*
		Add a colon if needed.
    */
    if (sProtocol=="http") sProtocol = "http:";
    if (sProtocol=="https") sProtocol = "https:"; 

	/*
		Build the url using the current path so as to ensure cookies are sent by the browser.
	*/
   var url = sProtocol + "/" + "/" + sHost + "/"+ window.CurrentDir+sServlet;

NavOpenSmallPopup(url+"?mode="+sMode+(sQueryString?sQueryString:""), bBacklink, true);
	

    /*
		Guard against double pressing of an action button.
	*/
	window._NavActionRunning = 1;
}

/*


*/
function NavVPMail( ) 
{
	if (StdGetCookie("FcmUser2")==null)
		NavOpen('../portal.nsf/frmUserRegistration?OpenForm', true, true);
	else if (window.UType==-1)
		alert("Please login before modifying    \nyour email subscription details");
	else 
		NavDbEdit('&p=frmNewsByEmail&v=UserBase&k='+window.CurrentUserId, true);
}



/*
	Display the next page of Search Results, starting at the selected result
	Calls ContentSearchHandler, passing in the id of the search document and the start of the next page
*/
function NavSrchScroll(sStart)
{
	var sQueryString = '&start='+sStart; 
   if (window.SchRefine!=null && window.SchRefine!="") sQueryString += '&SrsRefine='+window.SchRefine;
//	var sXtra = StdGetFieldValue('SrsXtra');
//	if (sXtra!=null && sXtra!="") sQueryString += '&SrsXtra='+escape(sXtra);
	var sUrl = 'search-results.pag?srchid='+window.SchID+ sQueryString;
	//We would always want context propagated between pages
	if (window.CtxPropagate) sUrl = CtxPropagate(sUrl);
	NavReplace(sUrl);
}


/*

*/
function StdLinkMOver( e, s )
{
 	if (e.style) {
		 e._StdSaveUState = e.style.textDecoration;
		 e.style.textDecoration = 'underline';
	}
	window.status = s ? s : (e.title ? e.title : "");
}

/*

*/
function StdLinkMOut( e )
{
	if (e.style!=null &&  e._StdSaveUState!=null) e.style.textDecoration = e._StdSaveUState;
	window.status = "";
}

/*

*/
function _StdDefaultMOver( )
{
	StdLinkMOver(this, null);
	return true;
}

/*

*/
function _StdDefaultMOut( )
{
	StdLinkMOut(this);
	return true;
}


/*
	Expand a relative url into a full url. 
*/
function _NavExpandUrl(url)
{
	/*
		If the page has a <base> tag then use it. Otherwise
		take the base url to be one level up from the page url.
	*/	
	var sBase = _NavGetBaseHref();
	if (sBase==null) sBase = location.href.substr(0, location.href.lastIndexOf("/"));
	
	/*
		Remove a trailing slash if present.
	*/	
	if (sBase.charAt(sBase.length-1)=='/') sBase = sBase.substr(0, sBase.length-1);

	/*
		Get the parent directory (for use with ..) by going one level up.
	*/	
	var sParentDir = sBase.substr(0, sBase.lastIndexOf("/"));

	/*
		There are four cases:
			..  		go relative to the parent directory
		    /  			go relative to the current host
			http		we already have a complete url
			else		go relative to the base url
	*/
	if (url.substr(0, 2)=="..")
           return sParentDir+"/"+ url.substr(3);
	else if (url.substr(0,1)=="/")
            return location.protocol+"/"+"/"+location.hostname + url ;
	else if (url.substr(0, 4)=="http")
			return url;
	else
           return sBase+"/"+ url ;
}



/*
	Open a url in a new window. 
*/
function NavOpenPopupWindow(sUrl, sOptions)
{
	/*
		Size the window appropriately.
	*/
	var x = Math.floor(screen.availWidth * 0.1) ;
	var y = Math.floor(screen.availHeight* 0.06) ;
	var w = Math.floor(screen.availWidth * 0.75);
	var h = Math.floor(screen.availHeight * 0.8);

	/*
		Set up the options string for window.open
	*/
	var sPos = 'width='+w+',height='+h+',screenX='+x+',screenY='+y+',left='+x+',top='+y;
	if (sOptions==null) sOptions = 'toolbar=yes,menubar=yes,status=no,resizable=yes,scrollbars=yes'

	/*
		Use setTimeout so as not to leave an hour glass
		cursor stuck on the menu page in IE.
	*/
	setTimeout ("window.open('"+_NavExpandUrl(sUrl)+"','','"+ sPos+","+sOptions +"')", 1);
}

/*
	Open a url in a new window. 
*/
function NavOpenSmallPopup(sUrl, sOptions)
{
	/*
		Size the window appropriately.
	*/
	var x = Math.floor(screen.availWidth * 0.1) ;
	var y = Math.floor(screen.availHeight* 0.04) ;

	var w = Math.floor(screen.availWidth * 0.45);
	var h = Math.floor(screen.availHeight * 0.6);

	/*
		Set up the options string for window.open
	*/
	var sPos = 'width='+w+',height='+h+',screenX='+x+',screenY='+y+',left='+x+',top='+y;
	if (sOptions==null) sOptions = 'toolbar=yes,menubar=yes,status=no,resizable=yes,scrollbars=yes'

	/*
		Use setTimeout so as not to leave an hour glass
		cursor stuck on the menu page in IE.
	*/
	setTimeout ("window.open('"+_NavExpandUrl(sUrl)+"','','"+ sPos+","+sOptions +"')", 1);
}

/*
	Open a url in a new window. 
*/
function NavOpenReport(sUrl)
{
	/*
		Size the window appropriately.
	*/
	var x = 15;
	var y = 10;
	var w = screen.availWidth - 40;
	var h = screen.availHeight - 140;

	/*
		Set up the options string for window.open
	*/
	var sPos = 'width='+w+',height='+h+',screenX='+x+',screenY='+y+',left='+x+',top='+y;
	var sOptions = sPos + ',toolbar=yes,menubar=yes,status=no,resizable=yes,scrollbars=yes'

	/*
		Use setTimeout so as not to leave an hour glass
		cursor stuck on the menu page in IE.
	*/
	setTimeout ("window.open('"+_NavExpandUrl(sUrl)+"','','"+ sOptions +"')", 1);
}

/*
	Open the Register form.
*/
function NavRegister( )
{
	NavOpen('register-form.pag?refpage='+ escape(window.location));
}
/*
	This function from the old home page has been used in some 
	user defined content to open the register screen so define it 
	here for compatibility.
*/
function RegOrMyHome() { NavRegister(); }

/*
	Open the Contact Us form.
*/
function NavContactUs( )
{
	NavOpen('contact-us-form.pag?refpage='+ escape(window.location));
}

/*
	Email a news article, using notes form
*/
function NavEmailArticle( sUnid )
{
	NavOpen('../portal.nsf/frmEmailArticle?OpenForm&Page='+ escape ( window.location )  + '&unid=' + sUnid,true,true);
}

/*
	Email a friend any frost.com page, using JSP
*/
function NavMailAFriend(sTitle, sType, sId )
{
	NavOpen('mail-a-friend-form.pag?title='+sTitle+'&type='+sType+'&id='+sId+'&refpage='+ escape(window.location), true);
}


/*
	Set a query string parameter into a url.
*/
function NavSetParameter(sUrl, sName, sValue )
{
	/*
		Remove and any anchor from the url
	*/
	sUrl = sUrl.replace(/#[^ ]*$/, "");

	/*
		Remove a trailing ? when there is no query string
	*/
	sUrl = sUrl.replace(/[?]$/, "");

	/*
		If the target url contains no ? then we can just append.
	*/
	if (sUrl.indexOf("?")<0) return sUrl+"?"+sName+"="+escape(sValue);

	/*
		If parameter found at start of query string replace it.
	*/
    var re = new RegExp("[?]"+sName+"=[^&]*", "i");
    if (sUrl.search(re)>-1) return sUrl.replace(re, "?"+sName+"="+escape(sValue));

	/*
		If parameter found in body of query string replace it.
	*/
    re = new RegExp("&"+sName+"=[^&]*", "i");
    if (sUrl.search(re)>-1) return sUrl.replace(re, "&"+sName+"="+escape(sValue));

	/*
		Parameter doesn't appear so just append.
	*/
    return sUrl+"&"+sName+"="+escape(sValue);
}

function NavPageSetMode( sMode )
{
    NavOpen(NavSetParameter(location.href, "mode", "edit"), true, true);
}

function NavDbOpen(sQueryString, bBacklink, sHost, sProtocol)
{
	return _NavGetPageAction ("rpg", "open", sQueryString, bBacklink, sHost, sProtocol)
}

function NavDbCreate(sQueryString, bBacklink, sHost, sProtocol)
{
	return _NavGetPageAction ("rpg", "create", sQueryString, bBacklink, sHost, sProtocol)
}

function NavDbEdit(sQueryString, bBacklink, sHost, sProtocol)
{
	return _NavGetPageAction("rpg", "edit", sQueryString, bBacklink, sHost, sProtocol)
}
 
function NavDbPage(sPage, sQueryString, bBacklink, sHost, sProtocol)
{
	return _NavGetPageAction ("rpg", "page", "&p="+sPage+sQueryString, bBacklink, sHost, sProtocol)
}

function NavDbScrollNext( )
{
	if (window.ViewLastKey==null) return;

    var url = location.href;

    url = url.replace(/&finish[1-9]*=[^&]*/gi, "");
    url = url.replace(/finish[1-9]*=[^&]*&/gi, "");
    url = url.replace(/finish[1-9]*=[^&]*/gi, "");

	for (var n=0; n<window.ViewLastKey.length; n++) {
    	url = NavSetParameter(url, "start"+(n>0?n:""), window.ViewLastKey[n]);
    }

	//We would always want context propagated between pages
	if (window.CtxPropagate) url = CtxPropagate(url);

	NavReplace(url);
}


 
function NavDbScrollPrev( )
{
    if (window.ViewFirstKey==null) return;
   	var url = location.href;
 
    url = url.replace(/&start[1-9]*=[^&]*/gi, "");
    url = url.replace(/start[1-9]*=[^&]*&/gi, "");
    url = url.replace(/start[1-9]*=[^&]*/gi, "");
 
	for (var n=0; n<window.ViewFirstKey.length; n++) {
    	url = NavSetParameter(url, "finish"+(n>0?n:""), window.ViewFirstKey[n]);
    }
 
	//We would always want context propagated between pages
	if (window.CtxPropagate) url = CtxPropagate(url);

	NavReplace(url);
}
 
/*
	Scroll a relational view to a given key.
*/
function NavDbScrollToKey( sKey  )  
{
	var url = window.location.href;

    url = url.replace(/&finish[1-9]*=[^&]*/gi, "");
    url = url.replace(/finish[1-9]*=[^&]*&/gi, "");
    url = url.replace(/finish[1-9]*=[^&]*/gi, "");
    url = url.replace(/&start[1-9]*=[^&]*/gi, "");
    url = url.replace(/start[1-9]*=[^&]*&/gi, "");
    url = url.replace(/start[1-9]*=[^&]*/gi, "");

	NavOpen(url+"&start="+escape(sKey), false, true);
}


function NavDomOpen(sQueryString, bBacklink)
{
	return _NavGetPageAction ("npg", "open", sQueryString, bBacklink)
}

function NavDomCreate(sQueryString, bBacklink)
{
	return _NavGetPageAction ("npg", "create", sQueryString, bBacklink)
}

function NavDomEdit(sQueryString, bBacklink)
{
	return _NavGetPageAction("npg", "edit", sQueryString, bBacklink)
}
 
function NavDomPage(sPage, sQueryString, bBacklink)
{
	return _NavGetPageAction ("npg", "page", "&p="+sPage+sQueryString, bBacklink)
}

function NavDomPagePop(sPage, sQueryString, bBacklink)
{
	return _NavGetPageActionPop ("npg", "page", "&p="+sPage+sQueryString, bBacklink)
}

function NavCreateContentSheet(sSheetName)
{
     NavOpen('fcom?ActionName=DisplaySheet&mode=create&sname='+sSheetName, true, false);
}