/*
##		snippet_helper.js

JavaScript Library used on all Revize html pages

Copyright (C) 2000-2005 Idetix Software Systems
All rights reserved.

#############################################################################
##
##	--------------------------------------------
##	Source Code Changes Required for Doc-O-Matic
##	--------------------------------------------
##
##	Separate text with blank lines to force new link on output
##
##	Use ## to ignore lines in Doc-O-Matic (like these comments)
##
##	Bracket initialization code with the following:
##		//DOM-IGNORE-BEGIN
##		//DOM-IGNORE-END
##
##	Below are sample sections used:
##
##		For RZ.*** input arguments use one of the following section names
##
##			RZ Parameters:
##			RZ Input Parameters:
##
##		Internal: Called by
##		then start description with (Internal Function) ...
##
##		Future: under development (may be available in a later release)
##
##		Parameters:
##		  	None: (no input parameters)
##
##		Returns:
##		  	no value currently returned
##
## Add the following as preceeding comment for deprecated functions
## 		Same as RZcalleditlist (retained for backward compatibility)
*/
/****************************************************************************
##	First part of code below executes before the onload handler
****************************************************************************/

/*---------------------------------------------------------------------------
Define RZ object and variables usually defined in jsp headers
This permits standalone usage of the JavaScript file without the jsp headers.
----------------------------------------------------------------------------*/
if (typeof RZ == 'undefined') var RZ = new Object();
if (typeof RZ.pagetype == 'undefined') RZ.pagetype = '';
if (typeof RZ.jsversion == 'undefined') RZ.jsversion = '1.0';

/*---------------------------------------------------------------------------
Define additional RZ objects used by javascript library functions

RZ.rte 			RTE interface variables
RZ.link			Link Manager variables
RZ.image		Image Manager variable
RZ.setvalues	Argument passing capability between templates and edit forms
				(mostly superceeded by ability to set record fields)
RZ.control		(future) All control panel variables
RZ.permits		Module Permissions determined at login time
----------------------------------------------------------------------------*/
if (typeof RZ.rte == 'undefined') RZ.rte = new Object();
if (typeof RZ.link == 'undefined') RZ.link = new Object();
if (typeof RZ.icons == 'undefined') RZ.icons = new Array();
if (typeof RZ.image == 'undefined') RZ.image = new Object();
if (typeof RZ.setvalues == 'undefined') RZ.setvalues = new Object();
if (typeof RZ.control == 'undefined') RZ.control = new Object();
if (typeof RZ.permits == 'undefined') RZ.permits = new Object();
if (typeof RZ.permits.modules == 'undefined') RZ.permits.modules = new Object();
if (typeof RZ.linkpagekey == 'undefined') RZ.linkpagekey = new Object();
if (typeof RZ.linkparentnew == 'undefined') RZ.linkparentnew = new Object();
if (typeof RZ.linkparentreset == 'undefined') RZ.linkparentreset = new Object();
if (typeof RZ.linktemplates == 'undefined') RZ.linktemplates = new Object();
if (typeof RZ.badlinks == 'undefined') RZ.badlinks = new Object();
if (typeof RZ.warning == 'undefined') RZ.warning = '';
if (typeof RZ.alert == 'undefined') RZ.alert = '';
RZ.linklevel = -1
RZ.nextseq = {linknames:{},modules:{}};

// For very old backward compatibility (probably build 27-) on templates
RZ.webSpaceName = RZ.webspace;
var rzRecordID = RZ.editrecordid;

/*---------------------------------------------------------------------------
Call additional setup functions as soon as JavaScript is compiled.
TODO: all inline code should be moved to onload handler to eliminate race
	  conditions mostly using image mananger with Firefox as of 08-01-2009
	  Of course some code is needed to hide or display buttons so that login
	  would need reworking (probably display:none until page loads)
----------------------------------------------------------------------------*/
RZpageSetup();		// get page into
RZpermits();		// setup module permissions
RZpagepermission()	// determine page permission
RZactionReset();  	// clear all action button input arguments
RZpageLoaded();		// final page setup

/****************************************************************************
Remaining code defines javaScript library functions
****************************************************************************/

/*---------------------------------------------------------------------------
(Internal Function) Set page information and display in trace window
Internal: Called by onload handler
----------------------------------------------------------------------------*/
function RZpageSetup()
{
	//----- Set flags
	RZ.revizepreview = false

	//----- Set browser settings
	RZ.MSIE = false       // MS explorer mode
	RZ.isnavigator = true // Netscape
	RZ.pos = navigator.appVersion.indexOf('MSIE')
	if(RZ.pos != -1)
	{
		RZ.MSIE = true
		RZ.isnavigator = false
	}
	if (RZ.isnavigator)
	{
		RZ.language = navigator.language.substring(0,2)
		RZ.browserversion = parseFloat(navigator.appVersion)
	}else
	{
		RZ.language = navigator.userLanguage.substring(0,2)
		RZ.browserversion = parseFloat(navigator.appVersion.substring(RZ.pos+4))
	}
	if (navigator.appVersion.toLowerCase().indexOf('windows') != -1)
	{
		RZ.platform = 'win'
		RZ.newline = '\r\n'
	}
	else
	{
		RZ.newline = '\r'
		RZ.platform = 'mac'
	}

	//----- Does browser support css (only old versions of navigator did not support)
	//		Assume true to avoid race condition with image manager on Firefox
		RZ.css = true;

	//----- Parent window if accessable (otherwise current window)
	//		TODO: susceptible to race condition with image_frame.jsp on Firefox
	RZ.parent = window;
	if (RZwinaccess(window.parent)) RZ.parent = window.parent;

	//----- Determine trace and debug mode
	RZ.trace = RZcheckHash('trace')
	RZ.debug = RZcheckHash('debug')

	//----- Set page information, login webspace and display page properties
	RZ.page = RZgetfileinfo( location.href )
	RZ.message = 'RZ.webspace: ' + RZ.webspace + '\n'
			   + 'RZ.page.domain: ' + RZ.page.domain + '\n'
			   + 'RZ.page.pathname: ' + RZ.page.pathname + '\n'
			   + 'RZ.page.filename: ' + RZ.page.filename + '\n'
			   + 'RZ.page.extension: ' + RZ.page.extension + '\n'
			   + 'RZ.page.query: ' + RZ.page.query + '\n'
			   + 'RZ.page.hash: ' + RZ.page.hash + '\n'
			   + 'RZ.page.home: ' + RZ.page.home + '\n'
			   + 'window.name: ' + window.name + '\n'
			   + 'document.referrer: ' + document.referrer + '\n'
			   + 'opener: '
	if (RZwinaccess(RZ.parent.opener))
	{
		RZ.message += RZ.parent.opener.location.href + '\n'
		if (RZ.parent.opener.name != '')
			RZ.message += 'opener.name: ' + RZ.parent.opener.name
	}
	else if (typeof RZ.parent != 'undefined')
		RZ.message += 'no access to opener'
	else
		RZ.message += 'no opener'

	RZtrace("Initializing Page", RZ.message)
	RZ.login = RZgetCookieValue('RZlogin', RZ.page.domain)

	if (RZwinaccess(parent))
	{
		if (parent.window.name=='revizepreview')
			RZ.revizepreview = true

		//----- Determine if called for workflow preview
		if ((parent.window.name != window.name			//must be in frames
			&& parent.window.name=='revizepreview') || window.name == 'workflowCompare1' || window.name == 'workflowCompare2' )
			{
				RZ.login = ''
				//RZ.revizepreview = true
				RZsetuphandler( 'onunload', 'return RZtemplateclose()' )
		}
	}
}
/*---------------------------------------------------------------------------
(Internal Function) Disables links on workflow preview page.
Internal: Called when trying to leave workflow preview page
or onclick for Firefox (TODO: allow html popup by checking the event target).
----------------------------------------------------------------------------*/
function RZtemplateclose(value)
{

	if (!RZ.revizepreview) return
	var msg = 'Links disabled during preview of content changes'
	alert(msg)
	location.href = location.href	//cancels hyperlink
	return false
}
/*---------------------------------------------------------------------------
(Internal Function) Look for specific hash (e.g. debug or trace) on current
window, opener, referrer hash and associated cookie

Internal: Diagnostic Support
----------------------------------------------------------------------------*/
function RZcheckHash(value)
{
	var key = false
	if (!RZwinaccess(top))
		return key;

	if(window.top.location.hash.indexOf('#'+value) != -1
	|| location.hash.indexOf('#'+value) != -1
	|| RZ.parent.location.hash.indexOf('#'+value) != -1
	|| RZgetCookieValue('RZ'+value) == 'ON' )
	{
		key = true
	}
	else if (RZwinaccess(RZ.parent.opener))
	{
		if( RZ.parent.opener.location.hash.indexOf('#'+value) != -1)
			key = true
		else if (typeof RZ.parent.opener.top != 'undefined'
		&& RZ.parent.opener.top.location.hash.indexOf('#'+value) != -1)
			key = true
	}
	else if (typeof document.referrer != 'undefined')
	{
		if (document.referrer.indexOf('#'+value) != -1) key = true
	}
	return key
}
/*---------------------------------------------------------------------------
(Internal Function) Sets final variables based on page type
Internal: Called after page loads and all initialzation is done.
----------------------------------------------------------------------------*/
function RZpageLoaded()
{
	window.focus()		//insure window gets focus() after loaded
	if (RZ.pagetype == 'template')
	{
		//----- Display trace information
		var recordid;
		if (typeof RZ.record != 'undefined')
			recordid = RZ.record.id
		else
			recordid = RZ.editrecordid

		RZ.string = 'RZ.webspace: ' + RZ.webspace + '\n'
				  + "RZ.editrecordid: (" + recordid + ")\n"
				  + "Clearing Return URLs ..."
		RZtrace( "Published Page Now Loaded", RZ.string )

		//----- Update cookies
		if (RZgetCookieValue('RZeditFormReturnUrl') != '')
			RZsetCookieValue('RZeditFormReturnUrl','')

		/*	deactivated when list allowed as popup
			(better supports template as list page)
		if (RZgetCookieValue('RZeditListReturnUrl') != '')
			RZsetCookieValue('RZeditListReturnUrl','')
		*/

		if (location.hash == '#logout') return

		//----- Save webSpace name in cookie unless logout call
		RZsetCookieValue('RZwebspace',RZ.webspace + "#" + document.location)

		if (RZlogin())
		{
			//----- Display page username and role in status bar
			if (RZ.pagetype == 'template')
				window.status = 'Logged in User is ' + RZ.username
							  + ' (roles: ' + RZ.roles + ')'

			//----- Call onload handler if permission warning enabled and logged in
			if (RZcheckoptions(RZ.permissions_options,"warnings"))
				RZsetuphandler( 'onload', 'RZshowIcons()' )

			//----- Display critical and warnings for templates
			if (RZ.alert != '') RZalert( RZ.alert );
			RZwarning();
		}

		//----- Create login button for page permission testing
		if (RZcheckoptions(RZ.permissions_options,"warnings")) document.write(
			'<div id="RevizeLogin" style="visibility:visible; position:absolute; z-index:1; top:30">',
			/* TODO: autoclick
			'  <a href="javascript:RZautoClick();"><img border="0"',
			'   src="/revize/images/warning-auto.gif" alt="Auto Click"></a>',
			'  <br>',
			*/
			'  <a href="/revize/security/"><img border="0"',
			'   src="/revize/images/RevizeRzSmall.gif" alt="Revize Login"></a>',
			'</div>',
			'')
	}

	//----- TODO: document why RZ.loaded not set true for edit forms
	//		(perhaps we did not want to use onload handler)
	if (RZ.pagetype != 'editform')
	{
		RZsetuphandler( 'onload', 'RZprocessHash()' )
	}
}
/*---------------------------------------------------------------------------
(Internal Function) position page on hash set by save
Internal: Runs after page is loaded
----------------------------------------------------------------------------*/
function RZprocessHash()
{
	if(location.hash.indexOf('_rz') != -1
	&& location.hash.indexOf('#trace') == -1
	&& location.hash.indexOf('#debug') == -1)
		location.hash = location.hash.substring(1);
	RZ.loaded=true;
}
/*---------------------------------------------------------------------------
(Internal Function) Displays stack trace(s) from rz.setup()
Internal: NOT YET USED
----------------------------------------------------------------------------*/
function RZprintStackTrace(msg)
{
	RZ.tracewin = RZpopupUrl('RevizeTrace');
	var msg = '<pre>' + msg + '</pre>'
	RZ.tracewin.document.write(msg);
}
/*---------------------------------------------------------------------------
(Internal Function) Repair bad page permission link
Internal: Recovery Support
Future: under development (currently placeholder with no functionality)
----------------------------------------------------------------------------*/
function RZbadlink(module,recordid,url)
{
}
/*---------------------------------------------------------------------------
(Internal Function) Displays page permissions warning on templates. NOT COMPLETED
Called as onload handler only

Internal: Called by onload handler permission warning are enabled and user is
currently logged in.

Future: under development (may be available in a later release)

Parameters:
  	None - no input parameters

Returns:
  	There is currently no value returned
----------------------------------------------------------------------------*/
function RZautoClick()
{
	var msg = 'Automatically click on every bad link to define parents.     '
	if (!confirm(msg)) return

return
	RZ.msg = ''
	var tag = 'A'
	if (tag == '')
		RZnodeProperties( 0, dw.getDocumentDOM("document").documentElement )
	else
	{
		var allTags = document.getElementsByTagName(tag);
		for (var i=0; i<allTags.length; i++)
		{
			RZ.msg += tag.toLowerCase() + '[' + i + ']:\n'
			if (allTags[i].hasChildNodes())
				for (var j=0; j<allTags[i].childNodes.length; j++)
					RZnodeProperties( 1, allTags[i].childNodes[j] )
		}
	}

	RZ.msg = RZ.msg.replace( /\t/g, '     ' )
	var pattern = /(.*\n){0,40}/g
	var matchArray = RZ.msg.match(pattern)
	alert('Written to ' + RZ.constant.tempDOM + '\n\n'
	     +'Up to 40 lines below:' + '\n' + matchArray[0])

}
/*---------------------------------------------------------------------------------------------
Parse a DOM node
Future: under development (may be available in a later release)
---------------------------------------------------------------------------------------------*/
function RZnodeProperties( level, childObj )
{
	var i,text
	var tab = ''
	var Node = new Object()
	Node.TEXT_NODE = 2
	Node.ELEMENT_NODE = 1
	Node.COMMENT_NODE = 1


	for (i=0; i<level; i++) tab += '\t'

	if ( childObj.nodeType == Node.TEXT_NODE)
	{
		RZ.msg += tab + 'TEXT NODE:\n'
		text = childObj.data
		text = text.replace(/\r/g,'\\r')
		text = text.replace(/\n/g,'\\n')
		RZ.msg += tab + '\t' + text + '\n'
	}
	else if (childObj.nodeType == Node.ELEMENT_NODE)
	{
		var name = ''
		if ( typeof childObj.getAttribute('name') != 'undefined')
			name = ' ' + childObj.getAttribute('name')
		RZ.msg += tab + '<' + childObj.tagName + '>'+name+':\n'
	}
	else if (childObj.nodeType == Node.COMMENT_NODE)
	{
		RZ.msg += tab + 'COMMENT NODE:\n'
		text = childObj.data
		text = text.replace(/\n/g, '\n\t' + tab )
		RZ.msg += tab + '\t' + text + '\n'
	}
	else
	{
		RZ.msg += tab + 'UKNOWN nodeType=' + childObj.nodeType + ':\n'
		RZ.msg += tab + 'Properties:\n'
		for (i in childObj)
			RZ.msg += tab + '-->' + i + '<--:' + childObj[i]
	}

	//----- Chase child nodes
	if (childObj.hasChildNodes())
		for (i=0; i<childObj.childNodes.length; i++)
			RZnodeProperties( level+1, childObj.childNodes[i] )
}
/*---------------------------------------------------------------------------
(Internal Function) Displays page permissions warning on templates.
Internal: Called by onload handler if warning are active and a user logged in
----------------------------------------------------------------------------*/
function RZshowIcons()
{
	//----- Show top left icon
	var icon = document.getElementById('RevizePageMessage')
	if (icon != null)
		icon.style.visibility = "visible";

	//----- Show frown icon if button must specify a template
	for (var i=0; i<RZ.icons.length; i++)
	{
		var module = RZ.icons[i]
		if(typeof RZ.linktemplates[module] == 'undefined'
		|| RZ.linktemplates[module] == '')
		{
			var icon = document.getElementById('RevizeButtonWarning' + i)
			if (icon != null)
				icon.style.visibility = "visible";
		}
	}
}

/* Same as RZgetfileinfo (retained for backward compatibility) */
function RZgetFileInfo( pathname, options )
{ return RZgetfileinfo( pathname, options ) }
/*---------------------------------------------------------------------------
Get File Info for specifiec URL or file.

Description:
	Parses either a url or file and breaks apart into individual fully
	qualified components.  By default the input pathname is assumed to be a
	file if the	syntax is ambigious.  To intepret first component as domain
	as browsers do on the address line specify domain as an option.

	If port 80 is specified on input, it is omitted like IE location functions
	TODO: have not verified if Netscape location omits port 80

Parameters:
	pathname-		fully or partially qualified url or path/filename
	options-		=domain treat everything up to first / as domain
					(if protocol not specified e.g. http://)

Return Value List:
	page.domain     = 'http://localhost:8080'		//no trailing slash
	page.pathname   = '/revize/demositeIII'	//with leading slash but not trailing
	page.filename   = 'contacts'
	page.extension  = 'html'
	page.query      = '?webSpace=demositeII&recordid=1'	//contains leading ?
	page.hash       = 'trace'						//leading # omitted
	page.home       = 'http://localhost:8080//revize/demositeIII/index.html'

Notes:
	Regression test at .../revize/util/snippet_helper_getfileinfo_test

	TODO: some scenarios noted as in above test do not currently work properly.
	Many scenarios of domains ARE ONLY intrepreted correctly if domain option
	is specified and the input pathname ends with a slash when no filename.
	(remember page.href however is never returned with ending slash by design)
	See: .../revize/util/snippet_helper_getfileinfo_test for details.
----------------------------------------------------------------------------*/
function RZgetfileinfo( pathname, options )
{
	var pos,idx,text
	var href=''
	var domain=''
	var filename=''
	var sep=''
	var extension=''
	var query=''
	var hash=''
	var home=''
	if (typeof options == 'undefined')
		options = '';
	else
		options += ','
	if (!pathname) pathname = '';
	if (pathname == '#') pathname = location.href
	if (pathname != '')
	{
		pathname = pathname.split('\\').join('/');

		//----- Determine domain
		domain = ''
		pos = pathname.indexOf(':')				//check for first colon :

		//----- If domain option & protocol is missing, prepend to pathname
		if(options.indexOf('domain,') != -1
		&& RZsubstring(pathname,pos+1,pos+3) != '//')
		{
			if (location.protocol != '')
				pathname = location.protocol + '//' + pathname
			else
				pathname = 'http://' + pathname
			pos = pathname.indexOf(':')			//reset colon pos
		}

		//----- If protocol present, e.g. //http:// https:// ftp://
		if (RZsubstring(pathname,pos+1,pos+3) == '//')
		{
			pos += 3
			if (pathname.indexOf('/',pos) != -1)	//if first slash following //:
				pos = pathname.indexOf('/',pos)		//domain goes up to slash
			else if (RZsubstring(pathname,0,4).toLowerCase() != 'file')
				pos = pathname.length				//assume domain is all of pathname
		}
		else if (pos == -1)		//not file type (e.g. C:) so use current page domain
		{
			if(options.indexOf('domain,') != -1
			|| RZsubstring(pathname,0,4).toLowerCase() == 'www.')
			{
				pos = pathname.indexOf('/')
				if (pos >= 0)
				{
					domain = pathname.substring(0,pos)
					pathname = pathname.substring(pos+1)
				}else
				{
					domain = pathname
					pathname = ''
				}
			}
			else
			{
				domain = document.location.host			//blank if file
				if (document.location.protocol != '')	//if not file
				{
					domain = document.location.protocol + '//' + domain
					pos = domain.length
					if (RZsubstring(pathname,0,1) != '/')
						pathname = '/' + pathname
					pathname = domain + pathname
				}
			}
		}

		//-----  if : found, file format of C: (split into domain and pathname)
		if (pos != -1)
		{
			if (pathname.substring(pos,pos+1) == ':')
				domain = pathname.substring(0,pos+1)
			else
				domain = pathname.substring(0,pos)

			pathname = pathname.substring(pos)
			if (pathname.substring(0,1) == ':')
				pathname = pathname.substring(1)
		}

		//----- Strip port 80 if present in domain
		pos = (domain+'/').indexOf(':80/')
		if ( pos != -1) domain = domain.substring(0,pos)

		//----- Parse pathname and filename
		text = pathname;
		idx = text.indexOf("?");
		if (idx != -1) text = text.substring(0,idx)
		pos = text.lastIndexOf('/') // url
		if (pos == -1)
		{
			filename = pathname
			pathname = ''
		}
		else
		{
			filename = pathname.substring(pos+1)
			pathname = pathname.substring(0,pos)
			if (pathname != '' && pathname.substring(0,1) != '/')
				pathname = '/' + pathname
		}

		//------ Parse search (query)
		hash = filename
		pos = filename.lastIndexOf('?')
		if (pos == -1)
			query = ''
		else
		{
			query = filename.substring(pos)
			filename = filename.substring(0,pos)
			pos = query.indexOf('#')
			if (pos != -1)
			{
				hash = query.substring(pos)
				query = query.substring(0,pos)
			}
		}

		//------ Parse hash
		pos = hash.lastIndexOf('#')
		if (pos == -1)
			hash = ''
		else
			hash = hash.substring(pos+1)
		pos = filename.lastIndexOf('#')
		if (pos != -1) filename = filename.substring(0,pos)

		//------ Parse filename extension
		pos = filename.lastIndexOf('.')
		if (pos == -1)
			extension = ''
		else
		{
			extension = filename.substring(pos+1)
			filename = filename.substring(0,pos)
		}
		if (filename == '')		// use index.html when filename is blank
		{
			filename = ''
			extension = ''
		}

		//----- home page (questionable value)
		home = domain + pathname
		if (RZright(home,1) != '/' && pathname != '') home += '/'
	}

	//----- Return all the components
	var page = new Object()
	page.domain = domain
	page.pathname = pathname
	page.filename = filename
	page.extension = extension
	page.query = query
	page.hash = hash
	page.home = home

	page.sep = ((extension != '') ? '.' : '')
	page.href = domain
	page.href += pathname
	page.href += ((filename != ''&& RZright(page.href,1) != '/') ? '/' : '')
	page.href += filename + page.sep + extension + query
	if (hash != '') page.href += '#' + hash

	return page
}
/*---------------------------------------------------------------------------
----------------------------------------------------------------------------*/
function RZbuildurl(fileInfo)
{
	var location = fileInfo.domain + fileInfo.pathname
	if (RZright(location,1) != '/') location += '/'
	location += fileInfo.filename + fileInfo.sep + fileInfo.extension
	          + fileInfo.query
	if (fileInfo.hash != '') location += '#' + fileInfo.hash
	return location
}
/*---------------------------------------------------------------------------
Return Browser Version - report page design flaw if unknown

Parameters:
	None- (no input parameters)

Returns: Browser version
----------------------------------------------------------------------------*/
function RZbrowserversion()
{
	var version = 0
	if (RZ.isnavigator)
	{
		version = parseFloat( navigator.appVersion )
	}else
	{
		var pos = navigator.appVersion.indexOf("MSIE")
		version = parseFloat(navigator.appVersion.substring(pos+4))
	}
	if (isNaN(version) || version == 0)
		RZalert( "Unable to determine Browser version\n"
			 + "navigator.appVersion: " + navigator.appVersion )

	return version
}
/*---------------------------------------------------------------------------
Return true if layer exists and is currently visible.

Parameters:
----------
layerName-	text representing layer name

doc-		Optional argument specifing document object
			(appropriate when caller in in another frame or window)
----------------------------------------------------------------------------*/
function RZisvisible(layerName,doc)
{
	if (typeof doc == 'undefined') doc = document
    if (typeof doc == 'undefined') return false;    //firefox cludge
	var status = false;

	if (doc.layers && doc.layers[layerName])		//ns
	{
		if(typeof doc.layers[layerName] != 'undefined'
		&& doc.layers[layerName].visibility == 'visible') status = true
	}
	else if (RZ.css)			//ie or firefox (see notes in RZshowlayer)
	{
		var el = doc.getElementById(layerName)
		if (!el && RZ.MSIE) el = doc.all[layerName];
		if (el != null)
		{
			var layerStyle = el.style
			if (layerStyle.visibility != ''	&& layerStyle.visibility == 'visible')
				status = true
			if (layerStyle.display != '' && layerStyle.display != 'none')
				status = true
		}
	}

	return status;
}
/*---------------------------------------------------------------------------
Does layer exist?

Parameters:
----------
layerName-	text representing layer name

trueFalse-	Not used

doc-		Optional argument specifing document object
			(appropriate when caller in in another frame or window)
----------------------------------------------------------------------------*/
function RZhavelayer(layerName,trueFalse,doc)
{
	if (typeof doc == 'undefined') doc = document
	if (doc.layers && doc.layers[layerName])		//ns
	{
		if(typeof doc.layers[layerName] == 'undefined') return false
	}
	else if (RZ.css)			//ie or firefox (see notes in RZshowlayer)
	{
        var el = document.getElementById(layerName)
        if (el == null) return false
		//if(typeof doc.all[layerName] == 'undefined') return false
	}
	return true
}
/*---------------------------------------------------------------------------
Show or hide a layer based on browser type.  If the layer visibility property
is valid (non-blank), it is used to show or hide layer however it does not
work for Firefox.  If the visibility property is blank and the style.display
property if not blank, it is used to hide or show layer.

This feature was initially added as a simple backward compatible method to use
this function in Firefox in legacy utility functions such as the link manager
by simply changing the condictionally displayed code to define a display
property and leave the visiblity property blank.

Parameters:
----------
layerName-	text representing layer name

trueFalse- 	optional argument:
			if not passed, toggle layer (i.e. hide if showing or show if hidden)
			otherwise: if true show layer, if false hide layer

doc-		Optional argument specifing document object
			(appropriate when caller in in another frame or window)
----------------------------------------------------------------------------*/
function RZshowlayer(layerName,trueFalse,doc)
{
	if (typeof doc == 'undefined') doc = document

	//----- Netscape 4 loses layers if page was resized so leave layer visible
	if (RZ.isnavigator
	&& RZ.isnavigatorLayers == true
	&& doc.layers.length == 0) return

	//----- If layerName of object, set status and return
	if (typeof layerName != 'string')
	{
		window.status = 'RZshowlayer: invalid layer name (must be text argument)';
		return;
	}

    //----- Get div/span/layer element
	var el = doc.getElementById(layerName)
	if (!el && RZ.MSIE) el = doc.all[layerName];

	//----- If trueFalse not specified, toggle setting
	if (typeof trueFalse == 'undefined')
	{
		if ( RZisvisible(layerName,doc) == true)
			trueFalse = false
		else
			trueFalse = true
	}

	//----- See if layers are found on Netscape
	var msg = "Can't Hide Layer because ...\n"
	if (trueFalse == true) msg ="Can't Show Layer because ...\n"
	if (doc.layers)									//ns
	{
		if(doc.layers.length == 0)
		{
			msg += 'No Netscape Layers Defined (may be caused by resizing the window)\n'
				 + 'Try refreshing the page and re-entering information'
			RZalert(msg)
			return
		}
		RZ.isnavigatorLayers = trueFalse;	//indicate layer existed at one time
		if(typeof doc.layers[layerName] == 'undefined')
		{
			msg += 'Netscape Layer Not Defined: ' + layerName

			// list defined layers
			msg += '\n\nDOM document.layers properties'
			for (i in doc.layers)
				msg += '\n      ' + i + '=' + doc.layers[i]
			RZalert(msg)
			return
		}
	}
	else if (RZ.css)					//ie or firefox (see notes in description)
	{
		if (el == null)
		{
			msg += 'Layer Not Defined: ' + layerName
			RZalert(msg)
			return
		}
	}

	//----- Show or hide layer
	if (trueFalse == true)	// show layer
	{
		if (doc.layers && doc.layers[layerName])			//ns
			doc.layers[layerName].visibility = 'visible';
		else if (RZ.css)				//ie or firefox (see notes in description)
		{
			if (el.style.visibility != '')
			{
				el.style.visibility = 'visible';
				el.style.zIndex = 100;
			}
			else if (el.style.display != 'block')
				el.style.display = 'block';
		}
    }
    else 					// hide layer
    {
		if (doc.layers && doc.layers[layerName])			//ns
			doc.layers[layerName].visibility = 'hidden';
		else if (RZ.css)				//ie or firefox (see notes in description)
		{
			if (el.style.visibility != '')
				el.style.visibility = 'hidden';
			else if (el.style.display != 'none')
				el.style.display = 'none';
		}
	}
}

/* Same as RZsetcookie (retained for backward compatibility) */
function RZsetCookieValue( key, value )
{ RZsetcookie( key, value ) }
/*---------------------------------------------------------------------------
Set Cookie value

Parameters:
----------
key-		Key part of the Cookie key=value pair

value-		Value part of key=value (may contain optional qualifier)

Note:
	Qualifier is usually the current page url

Example:
	RZsetcookie('RZwebspace',RZ.webspace + "#" + document.location)
----------------------------------------------------------------------------*/
function RZsetcookie( key, value )
{
	var domain = '';
	//DO-KS: was causing problems with Netscape when running from a remote host
	//if (document.location.host.indexOf('.') >= 0)
	//  domain = '; domain=' + document.domain;
	document.cookie = key + '=' + value
   	                + '; path=/' + domain;

	var text = key + "=" + value + domain
	RZtrace( 'Set Cookie', text )
}

/* Same as RZgetcookie (retained for backward compatibility) */
function RZgetCookieValue( key, qualifier )
{ return RZgetcookie( key, qualifier ) }
/*---------------------------------------------------------------------------
Get Cookie value

Parameters:
----------
key-		Key part of the Cookie key=value pair

qualifier-	Optional parameter that qualifies the cookie by requiring the
			value to end with qualifier string.  Either a blank value is
			returned the qualifier string is removed from the returned value.
			Examples qualifies are: server domain and/or page url

			If qualifer is blank, accept any qualified value after stripping
			the cookie qualifier
----------------------------------------------------------------------------*/
function RZgetcookie( key, qualifier )
{
	var value
	var allcookies = document.cookie + ';'
	var pos = allcookies.toLowerCase().indexOf( key.toLowerCase()+';' );
	if (pos == -1)	// not empty string value
		pos = allcookies.toLowerCase().indexOf( key.toLowerCase()+'=' );
	if (pos == -1) 	// if no cookie defined, return blank
		value = ""
	else // when cookie defined, return value
	{
		var valStart = pos + key.length + 1;
		if (allcookies.substring(valStart-1,valStart) != "=" )
			value = ""
		else
		{
			var valEnd = allcookies.indexOf( ";", valStart );
			if (valEnd == -1 ) valEnd = allcookies.length - 1
			value = allcookies.substring( valStart, valEnd );  //keep value case sensitive
		}
	}

	//----- Build trace message; check for qualifier and remove or set value to blank
	var msg = key + "=" + value
	if (typeof qualifier != 'undefined')
	{
		msg += '\nQualifier: (' + qualifier + ')'
		pos = value.indexOf('#')
		if (pos <= 0)
			value = ''
		else if (qualifier != '' && value.substring(pos+1) != qualifier)
			value = ''
		else
			value = value.substring(0,pos)
		msg += '\nQualified Value: (' + value + ')'
	}

	RZtrace("Get Cookie",msg)
	return value
}
/*---------------------------------------------------------------------------
Setup or lookup module permits.
-----------------------------------------------------------------------------
Used by RZaction() and RZlogin to determine if buttons or html should be
displayed based on known permissions.

If RZpermits() is called with no parameters, the following setup occures:

	Get all module permissions determined at login from RZpermits cookie
	Permits (crud) are stored in the cookie as: global=crud,links=r

	RZ.permits.modules will be loaded with individual module permissions
	Following example above:
		RZ.permits.modules.global='crud';
		RZ.permits.modules.links='r'

Currently only the links module permissions are stored at after sucessful
login by the control_panel.jsp page (which is only used by the revizelogin
template).

Parameters:
	module-			Name of module to check
	requirePermits-	One of more of the following characters: (crud)
					c = Create
					r = Read
					u = Update
					d = Delete

TODO: Look up all module permissions, store in future control_panel window

Returns:

If RZpermits() is called with a module and permissions, the specified module
object is checked for the requested permissions returning true or false.

If there is no object for the specified module, the permissions are not known
therefore the function returns true.
----------------------------------------------------------------------------*/
function RZpermits(module,requiredPermits)
{
	if (RZ.isauthenticationactive == false)
		return true

	//----- If setup call...
	else if (typeof module == 'undefined')
	{
		//----- Module permissions
		RZ.message = 'none defined';
		var permits = RZgetCookieValue('RZpermits')
		if (permits != '')
		{
			var permitsArray = permits.split(',')
			RZ.message = '';
			for (var i=0; i<permitsArray.length; i++)
			{
				var module_permit = permitsArray[i].split(':')
				RZ.permits.modules[module_permit[0]] = module_permit[1]
				if (module_permit[1] == '') module_permit[1] = '-none-'
				RZmsgAdd(module_permit[0], ' ' + module_permit[1])
			}
		}
		RZtrace('Module Permissions',RZ.message)

		//----- Page permissions
		RZ.message = ''
		RZmsgAdd( 'RZ.page_key       ', ' ' + RZ.page_key )
		if (RZ.pagetype == 'template')
		{
			RZmsgAdd( 'RZ.page_role      ', ' ' + RZ.page_roles )
			RZmsgAdd( 'RZ.page_users     ', ' ' + RZ.page_users )
		}
		else
		{
			RZmsgAdd( 'RZ.permissions_module  ', ' ' + RZ.permissions_module )
			RZmsgAdd( 'RZ.permissions_parent  ', ' ' + RZ.permissions_parent )
			RZmsgAdd( 'RZ.permissions_template', ' ' + RZ.permissions_template )
		}
		RZtrace('Page Permissions',RZ.message)
	}

	//----- Check permissions...
	else
	{
		//----- Assume full permissions if module not listed in permits
		var modulePermits = 'crud';
		if (typeof RZ.permits.modules[module] != 'undefined')
			modulePermits = RZ.permits.modules[module]
		var requiredPermitsOptions = requiredPermits.split('|')

		var status = true
		for (var j=0; j<requiredPermitsOptions.length; j++)
		{
			var optionStatus = true
			for (var i=0; i<requiredPermitsOptions[j].length; i++)
			{
				var ch = requiredPermitsOptions[j].substring(i,i+1).toLowerCase()
					if (modulePermits.indexOf(ch) == -1)
					{
						optionStatus = false
						break;
					}
			}
			status = optionStatus
			if (optionStatus == true) break;
		}

		RZ.message = ''
		RZmsgAdd( 'module', module)
		RZmsgAdd( 'module permits', modulePermits)
		RZmsgAdd( 'permits required', requiredPermits)
		RZmsgAdd( 'status', status)
		RZtrace('Permissions Checked', RZ.message)
		return status;
	}
}
/*---------------------------------------------------------------------------------------------
Determine current page permissions
---------------------------------------------------------------------------------------------*/
function RZpagepermission()
{
	RZ.roles = ''
	RZ.username = RZgetCookieValue('RZusername',RZ.page.domain)
	if (RZ.username != '') RZ.roles = RZgetCookieValue('RZroles')

	RZ.pagepermission = false;

	//----- Get login username and roles
	var roles = '|' + RZ.roles + '|'
	var username = '|' + RZ.username + '|'

	if (RZ.isauthenticationactive == false)
		RZ.pagepermission = true;		//all permits if authentication disabled

	else if (username == '|')
		RZ.pagepermission = false;	//do nothing (not logged in)

	else if( roles.indexOf( '|superuser|' ) != -1
	||  roles.indexOf( '|administrator|') != -1)
		RZ.pagepermission = true;

	else if (RZ.page_roles == '' && RZ.page_users == '')
		RZ.pagepermission = true;		//no users or roles defined so everyone has access

	else
	{
		if ( ('|'+RZ.page_users+'|').indexOf(username) != -1)
			RZ.pagepermission = true;
		else
		{
			var rolesArray = roles.split('|')
			for (var i in rolesArray)
			{
				if ( rolesArray[i] == '' ) continue;
				if ( ('|'+RZ.page_roles+'|').indexOf('|'+rolesArray[i]+'|') != -1)
				{
					RZ.pagepermission = true;
					break;
				}
			}
		}
	}
	return
}
/*---------------------------------------------------------------------------------------------
Enable a new handler (append to current handler if one defined)
---------------------------------------------------------------------------------------------*/
function RZsetuphandler(handlerType,handlerFunction)
{
	var jsversion = 0
	if (typeof RZ.jsversion != 'undefined') jsversion = RZ.jsversion
	if (jsversion < 1.2)
	{
		RZtrace(handlerType + " Handler Not Intialized",
		        'JavaScript version: ' + RZ.jsversion + ' does not support')
		return false;
	}

	var functionStr = window[handlerType]; //existing handler function if defined
	var parameters = ""; //parameters string
	var pos = -1; //position of '{'
	var pos1 = -1; //position of '('
	var pos2 = -1; //position of ')'

	if ( functionStr != null )
	{
		functionStr = functionStr.toString()
		pos = functionStr.indexOf( '{' );
		pos1 = functionStr.indexOf( '(' );
		pos2 = functionStr.indexOf( ')' );
	}

	//Check if parameters exist.  If they do, then append them to the current
	//parameters string.
	if ( pos1 >= 0  && pos2 >= 0 )
		parameters += functionStr.substring( pos1+1, pos2 );

	//Check if the call to Function() exists.  If it does, then append a call to
	//new handler to it at the beginning; otherwise, just call new handler.
	if ( pos < 0 )
		functionStr = handlerFunction + ';'
	else
		functionStr = handlerFunction + ';'		//appended function call
					+ functionStr.substring( pos+1, functionStr.length-1 );	//existing function

	//----- Set new handler and make trace entry
	window[handlerType] = new Function( parameters, functionStr );

	RZtrace("Initialized " + handlerType + " Handler", window[handlerType].toString() )
	return true;
}
/*-----------------------------------------------------------------------------------
  Implements button action operations (e.g. forward, save, delete, new, exit)
  Either a button or image is displayed on the page if a valid user is
  authenticated via the login page. If security is disabled any username is
  allowed.

  Normally code is generated to display button if authorized however if RZ.action=html
  function does not display button only returns html executed by specified button.

  TODO:  Document remaining RZ.* variables

  Parameters:
  action-		String representing type of action button (See Remarks)
  Parameters Format:
  <table 20c%>
  action         Button Types
  -------------  -----------------------------------------------
  editpage       "Edit this Page" calls -editform.jsp page
  editform       (same as above backward compatibility)
  editglobal     "Edit Globals" globals-editform.jsp
  \
  editlist       Edit this List (-editlist.jsp)
  exit           Exit Edit List page; return to caller
  newitem        Create new list item
  new            (same as above backward compatibility)
  edititem       Edit an existing list item
  edit           (same as above backward compatibility)
  delete         Delete an existing list item
  deleteitem     (same as above backward compatibility)
  \
  save           Edit form save button
  cancel         Edit form or Edit List cancel button
  \
  history        Edit form current record history
  editversion    Selects record to edit on history
  copyversion    Copy record on history as new version
  newversion     Create new version of current record
  permissions    opens permissions window
  </table>

  RZ Input Parameters:
  RZ.module-      Name of module
  RZ.recordid-	  recordid to process
  RZ.nexturl-     url of page recieving control from button
  RZ.popupwidth-  width of popup window
  RZ.popupheight- height of popup window
  RZ.popupscroll- indicate if popup window has scroll bars
  RZ.img-         if non\-blank html displayed for button
  				  (usually an image tag but can be any html)
  RZ.caption-     Label of input type=button
  				  (image button used if RZ.img not blank)
  RZ.tagname-     If non\-blank specified form button name)
  RZ.parentkey-   If not blank, specified parent key rather than letting Revize
  				  automatically determine.
  RZ.action-	  =html, does not display button
                  =false TODO
                  =true TODO

  Returns:  script executed when button clicked; If RZ.action
  -----------------------------------------------------------------------------------*/
function RZaction(action)
{

	if (RZ.nexturl == null || RZ.nexturl == 'null' ) RZ.nexturl = ''
	if (RZ.popupwidth == null || RZ.popupwidth == 'null') RZ.popupwidth = ''
	if (RZ.popupheight == null || RZ.popupheight == 'null') RZ.popupheight = ''
	if (RZ.popupscroll == null || RZ.popupscroll == 'null') RZ.popupscroll = ''

	var script=''
	var html=''
	var anchor = ''
	var level = ''
	var buttonName=''
	var requiredModule = RZ.module
	var requiredPermits = ''
	var options = ''
	var recordid = ''
	var parentkey = ''
	var msg = ''

	//----- Create specific JavaScript executed when button clicked
	//		(based on type of action requested)
	switch ( action.toLowerCase() )
	{

		case "editlist":
			requiredPermits = 'c|u|d'
			if (RZ.tagname == '') RZ.tagname = 'RZeditlist';
			script = "RZcalleditlist("
				   + "'" + RZ.nexturl + "',"
				   + "'" + RZ.popupwidth + "',"
				   + "'" + RZ.popupheight + "',"
				   + "'" + RZ.popupscroll + "', "
			       + "'" + RZ.set + "')"
			break;


		//----- Common code for all new and edit actions
		case "new":
		case "newitem":
			level = RZ.linklevel;
			if (!RZ.linklevel && RZ.module)
				level = RZ.nextseq.listid ? RZ.nextseq.listid : 1;

		case "edit":
		case "edititem":
		case "editform":
		case "editpage":
		case "editglobal":

			recordid = RZ.recordid

			//----- Format edit form call
			//		Note: without the isNaN test, remaining JavaScript not executed
			if ( !isNaN(RZ.recordid) || RZ.recordid.toLowerCase() != 'no items in list' )
			{
				if(action == 'edit' || action == 'edititem')
				{
					if (RZ.parentkey != '')
						parentkey = RZ.parentkey
					else
						parentkey = RZlevelQualifier(RZ.linkname,RZ.linklevel,RZ.recordid)
				}
				else if(action == 'new' || action == 'newitem')
				{
					parentkey = RZ.parentkey;	//non-blank if specified
				}


				if(action == 'new' || action == 'newitem'
				|| action == 'edit' || action == 'edititem')
				{
					//----- If page permissions warnings are enabled...
					if (RZcheckoptions(RZ.permissions_options,"warnings"))
					{
						// Display icon if module not specified on new or edit item button
						if (RZ.module == '' && RZ.template != '*none*')
						{
							msg = "'" + RZpermissionWarning(action,'') + "'"	//module req msg
							html += '<a href="JavaScript:RZpagemessage(' + RZreplace(msg,'\n','--') + ')">'
								 +  '  <img src="/revize/images/warning-button.gif" border=0>'
								 +  '</a>'
						}

						// Display hidden icon in case template can not be determineed
						else if (RZ.template == '' && RZ.linkname == '')
						{
							RZ.html = '<span id="RevizeButtonWarning' + RZ.icons.length + '"'
									+ ' style="visibility:hidden">'
									+ '  <a href="JavaScript:RZiconMessage(\''+ action +'\','
									+ RZ.icons.length + ')"'
									+ '   ><img src=\"/revize/images/warning-button.gif\"'
									+ '   border=0 alt="Click for Details"></a>'
									+ '</span>'
							//RZ.html = RZ.html.replace(/</g,'&lt;')	//display html
							document.write( RZ.html )
							RZ.icons[RZ.icons.length] = RZ.module
						}
					}
				}

				script = "RZedit( "
				       + "'" + RZ.recordid + "', "
				       + "'" + RZ.nexturl + "', "
				       + "'" + RZ.popupwidth + "',"
				       + "'" + RZ.popupheight + "',"
				       + "'" + RZ.popupscroll + "', "
				       + "'" + RZ.set + "', "
				       + "'" + RZ.module + "',"
				       + "'" + RZ.field + "',"
				       + "'" + RZ.linkname + "',"
				       + "'" + action + "',"
				       + "'" + RZ.template + "',"
				       + "'" + level + "',"
				       + "'" + parentkey + "')"
			}

			// if setting a recordid, ignore the recordid.value
			if ( RZ.set.indexOf('_recordid=') >= 0 ) RZ.recordid = ''

			//----- Button name dependent on action
			if (RZ.tagname == '')
			{
				switch (action)
				{
					case "new":
					case "newitem":
						RZ.tagname = 'RZnewitem';
						requiredPermits = 'c'
						anchor = 'Revize_' + RZ.module + '[new]'

						break;
					case "edit":
					case "edititem":
						RZ.tagname = 'RZedititem' + RZ.recordid;
						requiredPermits = 'u'
						anchor = 'Revize_' + RZ.module + '[' + RZ.recordid + ']'
						break;
					case "editform":
					case "editpage":
						RZ.tagname = 'RZeditpage';
						requiredPermits = 'c|u'
						break;
					case "editglobal":
						RZ.tagname = 'RZeditglobal';
						requiredPermits = 'c|u'
						break;
				}
			}
			break;

		case "exit":
			if(typeof RZ.nexturl != 'undefined' && RZ.nexturl != '' && RZ.nexturl != 'NEXTURL')
				script = "location='" + RZ.nexturl + "'";
			else
				script = "RZback( 'RZeditListReturnUrl' );"
			if (RZ.tagname == '') RZ.tagname = 'RZexit';
			break;

		case "delete":
		case "deleteitem":
			if (RZ.recordid.toLowerCase() != 'no items in list')
			{
				//script = "RZrecordDelete( '" + RZ.recordid +  "', '" + RZ.module + "' );"
				script = "RZdelete( '" + RZ.recordid +  "', '" + RZ.module
				if (RZ.nexturl != '') script += "', '" + RZ.nexturl
				script +=  "' );"
			}
			if (RZ.tagname == '') RZ.tagname = 'RZdeleteitem';
			requiredPermits = 'd'
			break;

		case "save":
			script = "RZsave( document.XMLForm, '" + RZ.nexturl + "' );"
			if (RZ.tagname == '') RZ.tagname = 'RevizeSave';
			break;

		case "save_as_draft":
			script = "RZsave_as_draft( '" + RZgetoption(RZ.options,'workflow') + "' );"
			if (RZ.tagname == '') RZ.tagname = 'RevizeSaveAsDraft';
			break;

		case "cancel":
			script = "RZeditFormCancel();"
			if (RZ.tagname == '') RZ.tagname = 'RevizeCancel';
			break;

		case "history":
			if (RZ.nexturl != '')
				options += 'nexturl='+RZ.nexturl
			if (RZ.field != '')
				options += 'fields='+RZ.field
			script = "RZhistory("
			       + "'" + RZ.module + "',"
			       + "'" + RZ.recordid + "', "
			       + "'" + RZ.version + "', "
			       + "'" + options + "') "
			if (RZ.tagname == '') RZ.tagname = 'RevizeHistory';
			break;

		case "permissions":
			requiredModule = RZ.permissions_module
			requiredPermits = 'u'
			if (RZ.nexturl != '')
				options += 'nexturl='+RZ.nexturl
			if (RZ.linkname != '')
				options += 'linkname='+RZ.linkname
			if (RZ.module != '')
				options += 'module='+RZ.module
			if (RZ.object != '')
				options += 'object='+RZ.object
			if (RZ.permissions_module != '')	//if permissions active
				script = "RZpermissions("
					   + "'" + RZ.set + "',"
					   + "'" + options + "') "
			if (RZ.tagname == '') RZ.tagname = 'RevizePermissions';
			break;

		case "copyversion":
				options += ',copy'
		case "newversion":
		case "editversion":
			if (RZ.nexturl != '')
				options += 'nexturl='+RZ.nexturl
			script = "RZeditversion("
			       + "'" + RZ.module + "',"
			       + "'" + RZ.version + "', "
			       + "'" + options + "') "
			//TODO: perhaps button should be displayed and message if clicked.
			if (RZ.editnextversion == '') script = ''	//new record - no history
			if (RZ.tagname == '') RZ.tagname = 'RevizeVersion';
			break;

		default:
			script = "RZalert('Unknown or Invalid Revize Action Request');"
	}

	//----- Build html containing script (image or button version)
	if (script == '')
		html = ''
	else
	{
		if (RZ.script != '')
		{
			/*	use conditional operator below
			if (RZright(RZ.script,1) != ';')
				RZ.script += ';'
			script = RZ.script + script;	//Prepend user specified script
			*/

			//----- Test results of user specified script via conditional operator
			//		so RZ.script code can cancel the button by returing false
			//
			// 			e.g. if (!user script)?donothing:button script;
			//
			if (RZright(RZ.script,1) != ';') RZ.script += ';'
			script = 'RZ.results=' + RZ.script
			       + '(!RZ.results && typeof RZ.results != \'undefined\')?void(0):'
			       + script;

			/* was not backward compatible if return was not true
			if (RZright(RZ.script,1) == ';')
				RZ.script = RZ.script.substring(0,RZ.script.length-1);
			script = '(!' + RZ.script + ')?void(0):' + script;
			*/
		}

		if (RZ.img != "")
			html += '<a href="javascript:' + script + '">' + RZ.img + '</a>'
		else
		{
			if (RZ.caption == '') RZ.caption = 'Edit Page'
			html += '<input type="button" name="' + RZ.tagname + '" value="' + RZ.caption + '" '
				 + 'onClick="' + script + ';">'
		}
	}

	//----- Add <br> and/or anchor tag to html if requested
	if (html != '')
	{
		if (RZ.options.indexOf('<br>') != -1) html += '<br>'
		if (anchor != '') anchor = '<a name="' + anchor + '"></a>'
		html += anchor
	}

	//----- write html if logged into this webspace with correct permits
	//
	//		If RZ.active is blank or false, only write html if logged in with
	//		correct permissions for specified module and only return script
	//		when html written (default case).
	//
	//		If RZ.active is true, always write html
	//
	//		If RZ.active = 'html': return html instead of writting.  If not
	//		logged in or do not have permissions return blank for html.

	var active = RZ.active;
	if (active == 'html')
	{
		if ( RZlogin('', requiredModule, requiredPermits, action) )
			script = html;
		else
			script = '';
	}
	//----- If action is blank (i.e. not used)...
	else if (active == '')	// RZ.active blank or false (note: blank returns false)
	{
		// write html if logged into this webspace & permits for module
		active = RZlogin( html, requiredModule, requiredPermits, action );
		if (!active) script = '';
	}
	//----- If RZ.action is true, write html without checks
	else if ( active == 'true'						// RZ.active is 'true'
	|| (typeof active == 'boolean' && active) )		// RZ.active is true
	{
		document.write(html);
	}

	RZ.message = ''
	RZmsgAdd( "action", action )
    RZmsgAdd( "active", active )
	RZmsgAdd( "webspace", '\t' + RZ.webspace )
    RZmsgAdd( "module  ", '\t' + RZ.module )
    RZmsgAdd( "field   ", '\t' + RZ.field )
    RZmsgAdd( "linkname", '\t' + RZ.linkname )
    RZmsgAdd( "recordid", "\t(" + RZ.recordid + ")" )
    RZmsgAdd( "nexturl",  RZ.nexturl )
    RZmsgAdd( "popup",    RZ.popupwidth + "," + RZ.popupheight + "," + RZ.popupscroll )
    RZmsgAdd( "set",      RZ.set )
    RZmsgAdd( "img tag",  RZ.img )
    RZmsgAdd( "tagname",  RZ.tagname )
    RZmsgAdd( "caption",  RZ.caption )
    RZmsgAdd( "options",  options )
    RZmsgAdd( "generated html", html )
	RZtrace( "Action Button Processed", RZ.message );

	//----- clear RZ.* action arguments
	RZactionReset();

	//if (!active) script = ''
	return script;		//return generated script
}
/*---------------------------------------------------------------------------
Append "key: value" to RZ.message if value is not blank
Note: empty string same as false AND false matches \t & \t\t
----------------------------------------------------------------------------*/
function RZmsgAdd(key,val)
{
	//----- Following line avoids false matching empty string, \t & \t\t
	//		(also allow use of substring on true and false values)
	value = String(val)

	//----- Return if any empty value
	if(value==''
	|| value==null
	|| value=='\t()'					// empty recordid
	|| value=='0,0,' || value==',,'		// empty popup
	|| value=='\t' || value=='\t\t')
		return

	//----- Append : to key if value does not begin with a tab
	if (value.substring(0,1) != '\t') key += ': '

	//----- Append value to message
	RZ.message += key + value + '\n'
}
/*---------------------------------------------------------------------------
  (Internal Function) Resets RZ.* variables used as input variables for
  serveral functions called using RZ input parameters:
  	RZaction, RZlinkmanager, RZdelete

  This function is called during page setup and after arguments are used.
  This ensures values from one call are not carried forward to the next call.

  Parameters:
	  None  (no input parameters)

  Returns:
  No return value but the RZ input objects are set to an empty string
  * (see source code for current list of objects)
  ---------------------------------------------------------------------------*/
function RZactionReset()
{
	RZ.module=""; RZ.field=""; RZ.recordid=""; RZ.nexturl="";
	RZ.popupwidth=0; RZ.popupheight=0; RZ.popupscroll="";
	RZ.img=""; RZ.set=""; RZ.caption=""; RZ.tagname="";
	RZ.options=""; RZ.active=""; RZ.script="";
	RZ.rtefont=""; RZ.rtestyles = "";
	RZ.template=""; RZ.object="";
	RZ.linkname=""; RZ.linkmodule=""; RZ.linklevel="";
	RZ.filelocation=""; RZ.imagelocation="";
	RZ.version=""; RZ.nextversion="";
	RZ.imagemaxwidth=''; RZ.imagemaxheight=''; RZ.imagemaxbytes='';
	RZ.parentkey='';

	// optional link properties not initialized by RZTagSupport
	RZ.linkpathname = ''
	RZ.linknewsection = ''
	RZ.linkdisplaydefault = ''
	RZ.linktemplatedefault = ''
	RZ.linkfilenamedefault = ''
	RZ.linkautocontinue = ''
}

/*--------------------------------------------------------------------------
  Convert url to absolute url using the page location information determined
  during page initialization.
  Parameters:
  url :  url to convert
  --------------------------------------------------------------------------*/
function RZabsoluteUrl(url)
{
	if (url != '')
	{
		if ( !RZisAbsoluteUrl(url) )
		{
			if(url.substring(0,4) == 'www.')
				url = 'http://'+url;
			else
            {
                //DCO 02-22-2007\\
                //url = RZ.page.domain + RZ.page.pathname + '/' + url

                // domain + page pathname + baseprefix yeilds url relative to base channel
                url = RZ.page.domain + RZ.page.pathname + '/' + RZ.baseurlprefix + url
                while (url.indexOf("/../") > 0)
                {   //for each ../ remove it along with preceeding folder
                    var offsetEnd = url.indexOf("/../");
                    var offsetBeg = url.lastIndexOf("/",offsetEnd-1);
                    url = RZsubstring(url,0,offsetBeg)
                        + RZsubstring(url,offsetEnd+3);
                }
                //DCO 02-22-2007//
            }
		}
	}
	return url
}
/*---------------------------------------------------------------------------
is url absolute reference
----------------------------------------------------------------------------*/
function RZisAbsoluteUrl(url)
{
	if(url.substring(0,1) != '/'
	&& url.substring(0,7) != 'http://'
	&& url.substring(0,8) != 'https://')
		return false
	else
		return true
}
/*---------------------------------------------------------------------------
Determine Edit Page URL
----------------------------------------------------------------------------*/
function RZgetEditPageUrl( editPageUrl )
{
	var url = ""
	if (editPageUrl == 'EDITLISTURL')
		url = RZ.page.filename + '-editlist.jsp'
	else if (editPageUrl == 'EDITFORMURL')
		url = RZ.page.filename + '-editform.jsp'
	else
		url = editPageUrl
	return url
}
/*---------------------------------------------------------------------------
Save return URL in cookie
TODO: store in control panel window
----------------------------------------------------------------------------*/
function RZsaveReturnUrl( returnUrlKey )
{
	var url = location.href
	var hash = location.hash
	if (hash != '')
		url = url.substring(0,url.length-hash.length)
	if (RZ.trace)
		url += '#trace'
	if (RZ.debug)
		url += '#debug'
	RZsetCookieValue( returnUrlKey, url )
}

/* Same as RZcalleditlist (retained for backward compatibility) */
function RZcallEditList( editPageUrl )
{return RZcalleditlist( editPageUrl )}
/*---------------------------------------------------------------------------
Call EDIT LIST page
----------------------------------------------------------------------------*/
function RZcalleditlist( editPageUrl, width, height, scroll, set )
{
	if (typeof width == 'undefined') width = '';
	if (typeof height == 'undefined') height = '';
	if (typeof scroll == 'undefined') scroll = '';
	if (typeof set == 'undefined') set = '';

	var url = RZgetEditPageUrl( editPageUrl )
	if (RZ.MSIE && url != '' && !RZisAbsoluteUrl(url)
	&& typeof RZ.baseurlprefix != 'undefined' && RZ.baseurlprefix.length > 0)
		url = RZ.baseurlprefix + url

	RZ.message = ''
	RZ.parameters = url
	RZaddUrlParameter( 'webspace=' + RZ.webspace )
	RZsetParameter(set)
	RZaddUrlParameter( 'permissions_template=' + RZ.pagetemplatename )
	RZaddUrlParameter( 'permissions_parent=' + RZ.page_key )

	RZtrace("Calling Edit List", RZ.message )

	RZ.editWindow = RZpopupUrl( 'ListWindow', RZ.parameters, width, height, scroll)
	if (RZ.editWindow == null)
	{
		RZsaveReturnUrl( 'RZeditListReturnUrl' )
		document.location = RZ.parameters
	}

	return void(0)
}
/*---------------------------------------------------------------------------
----------------------------------------------------------------------------*/
function RZlistbegin( listid )
{
	RZ.nextseq.listid = listid + 1;
}
/*---------------------------------------------------------------------------
Called by closing list tag to remember the dependent template used by a link
tag inside the list.  See Dreamweaver help for more details.

TODO: consider triggering a warning if there is more than one list using the
same module which puts the template determination at risk.  Also RZTagSupport
might consider multple links and/or templates ambigous.

This function is also called with the linkname if a link manager link tag was
encountered inside the list.
----------------------------------------------------------------------------*/
function RZlinktemplate( module, template, listlinkname )
{
	if (module != '')
	{
		if (typeof RZ.linktemplates[module] == 'undefined'
		||  RZ.linktemplates[module] == '')
			RZ.linktemplates[module] = template
	}
}

/*---------------------------------------------------------------------------
Multi-level menu / page permissions support:

This function NOW called by RZaction to determine parentkey for level > 0.
For level 0, blank is returned because parent is determined by other means.
The parentkey is stored in RZ.linkpagekey by RZlinkmanager() which is called
via the script generated by the rz:link tag.
TODO: RZ.linkpagekey should probably be qualified by linkname.

This function WAS called by RZlinkmanager() and RZaction() to remember the 1st
recordid encountered at each level change for use by edit buttons.

This scheme is required to pass information from link tag to edit button
processing because the link tag may occur after the button in the html.
----------------------------------------------------------------------------*/
function RZlevelQualifier(linkname,level,recordid)
{
	var parentkey = ''

	if (isNaN(level)) return '';
	level = parseInt(level)

	/* deprecated but strategy may be useful in the future
	//----- If recordid not a number return
	if (isNaN(recordid)) return '';

	if (typeof RZ.linklevelmemory == 'undefined')
		RZ.linklevelmemory = -1

	//----- Clear level qualifier whenever level moves up
	if (level < RZ.linklevelmemory)
	{
		RZ.linklevelmemory = level
		RZ.levelrecordid[level] == null
	}

	//----- Save page_key of prior menu item when level moves down
	else if (level > RZ.linklevelmemory)
	{
		RZ.linklevelmemory = level
		RZ.levelrecordid[level] = recordid

	}
	*/

	//----- Get above level pagekey if level > 0
	if (level > 0)
		parentkey = RZ.linkpagekey[level-1]

	return parentkey
}

/* Same as RZedit (retained for backward compatibility) */
function RZcallEditForm( recordid, editPageUrl, width,height,scroll, set )
{
	return RZedit( recordid, editPageUrl, width,height,scroll, set )
}
/* Same as RZedit (retained for backward compatibility) */
function RZcalleditform( recordid, editPageUrl, width,height,scroll, set,
	module, field, linkname)
{
	return RZedit( recordid, editPageUrl, width,height,scroll, set)
}
/*---------------------------------------------------------------------------
Call EDIT FORM page (work horse - called by code generated by RZaction)
----------------------------------------------------------------------------*/
function RZedit( recordid, editPageUrl, width, height, scroll, set,
	module, field, linkname, action, template, level, parentkey)
{
	//----- For backward compability initilize new parameters
	if (typeof set == 'undefined') set = '';
	if (typeof module == 'undefined') module = '';
	if (typeof field == 'undefined') field = '';
	if (typeof linkname == 'undefined') linkname = '';
	if (typeof action == 'undefined') action = '';
	if (typeof template == 'undefined') template = '';
	if (typeof level == 'undefined') level = '';
	if (typeof parentkey == 'undefined') parentkey = '';

	var str = '';
	var msg = '';

	RZtrace( "Edit Form Button Clicked", "Record Id: (" + recordid + ")" );

	//----- Call Developer defined onedit handler and quit if it returns false
	if (typeof window.onedit == 'function')
	{
		if (window.onedit() == false)
		{
			window.status = 'Edit Canceled'
			return void(0)
		}
	}

	var url = RZgetEditPageUrl( editPageUrl )	//nexturl

	//----- Append edit parameters
	if (linkname == '')
	{
		//----- Apply baseurl prefix to nexturl if IE browser
		if (RZ.MSIE && url != '' && !RZisAbsoluteUrl(url)
		&& typeof RZ.baseurlprefix != 'undefined' && RZ.baseurlprefix.length > 0)
			url = RZ.baseurlprefix + url

		RZ.message = ''

		var nextseqKey = module + '_' + level;	//level is listid
		if (action == 'newitem' && RZ.nextseq.modules[nextseqKey]
		&& (','+set).indexOf(','+ module + '.' + RZ.nextseq.modules[nextseqKey].field) == -1)
		{
			str = module + '.' + RZ.nextseq.modules[nextseqKey].field + '=' + RZ.nextseq.modules[nextseqKey].seq;
			if (set) set += ',';
			set += str;
		}

		RZsetEditParameters(module,field,set)

		recordidParameter = RZsetEditRecordParameter(recordid)
		if (recordidParameter == '*ERROR*') return void(0)

		//----- Page Permissions processing (non-link manager)
		if (RZ.permissions_module != '')
		{
			if (action == 'new' || action == 'newitem'
			|| action == 'edit' || action == 'edititem')
			{
				msg = RZpermissionWarning(action,template,module)
				if (msg != '')
					if (!RZconfirm(msg)) return

				if (template == '')
					if (typeof RZ.linktemplates[module] != 'undefined')
						template = RZ.linktemplates[module];

				// When template passed on url, RZsave will include template & parent page_key
				// in the save record XML request (template defined by new & edit buttons).
				if (template != '' && template != '*none*')
					RZaddUrlParameter( 'permissions_template=' + template )
			}
			else if (action == 'editform' || action == 'editpage' || action == 'editglobal')
			{
				// edit this page button(s) do not define parents because the edited recordid
				// is usually not the dependent record module.  Another issue is parent passed
				// below is the current page when links are added and would not be correct for
				// this dependent page.
				//RZaddUrlParameter( 'permissions_template=' + RZ.pagetemplatename )
			}

			//----- Always pass parent_key in case the edit form adds links via the RTE.
			//		NOTE: Don't add parent if already on url but this is a very specific scenario.
			if (RZ.pagetype == 'template' && url.indexOf("permissions_parent=") == -1)
				RZaddUrlParameter( 'permissions_parent=' + RZ.page_key )
			else	//editlist page
				RZaddUrlParameter( 'permissions_parent=' + RZ.permissions_parent )

			//----- Pass caller page key to determine workflowname
			if (RZ.page_key != '')
				RZaddUrlParameter( 'page_key=' + RZ.page_key )
		}

		url += RZ.parameters + recordidParameter
		RZtrace('Edit Form url parameters',RZ.message)
	}

	//----- Check for link manager parameters
	else
	{
		if (typeof RZ.link[linkname] != 'object')
			msg = 'Specified Link Name ('+linkname+') Does Not Exist or is Not\n'
				+ 'Properly Defined (make sure the ' + linkname + ' link exists).\n'
				+ 'The link tag defines required options used by Link Manager\n\n'
				+ 'If the list is not displaying a message when empty,\n'
				+ '(i.e. noemptylistmessage option set) a copy of the\n'
				+ 'link tag must be inside the list header.\n\n'
				+ 'If link tag exists make sure its name matches the name specified\n'
				+ 'specified on this button.'

		if (msg == '' && module == '')
			msg = 'Link Name ('+linkname+') associated with this action has\n'
				+ 'not specified a module.\n\n'
				+ 'Link Manager can not be called without knowing the module\n'
				+ '(check associated link and make sure a module is specified).'

		//----- If errors display message and return
		if (msg != '' )
		{
			RZalert(msg);
			return void(0);
		}

		//----- Set all link manager properties including window size and url
		//		(RZsetLinkManagerProperties calls RZsetEditParameters)
		//
		RZsetLinkManagerProperties(linkname,module,field,recordid,set,url)
		recordidParameter = RZsetEditRecordParameter(recordid)
		if (recordidParameter == '*ERROR*') return void(0)

		//----- Pass user popup window values to link manager on url
		RZ.link[linkname].popupwidth = width
		RZ.link[linkname].popupheight = height
		RZ.link[linkname].popupscroll = scroll
		RZ.link[linkname].nexturl = RZabsoluteUrl( url )

		//----- Get link manager popup window properties
		width  = RZ.link[linkname].linkwidth
		height = RZ.link[linkname].linkheight
		scroll = RZ.link[linkname].linkscroll
		url    = RZ.link[linkname].linkurl + recordidParameter

		//----- Pass linkparent
		var parent = ''
		if (level == '')
		{
			if (typeof RZ.link[linkname].linkparent != 'undefined')
				parent = RZ.link[linkname].linkparent
			if (parent == '')
				parent = RZ.page_key;
		}
		else	//multi-level processing
		{
			if (parentkey != '')	//if passed as argument
				parent = parentkey;
			else if ( isNaN(level) )
			{
				msg = 'Non-numberic level specified for this button.\n\n'
				    + 'Multi-level menu relationships can not be maintained\n'
				    + '(check button and specify a numeric level).'
				if (!RZconfirm(msg)) return
			}
			else if (action == 'new' || action == 'newitem')
			{
				// for existing level, linkparentnew should be defined
				if(typeof RZ.linkparentnew[linkname] != 'undefined'
				&& typeof RZ.linkparentnew[linkname][level] != 'undefined')
					parent = RZ.linkparentnew[linkname][level]

				// new level; use last item recordid at prior level for parent
				else if (eval(level) != 0)	//TODO: should be min level (not 0)
					parent = RZ.linkpagekey[level-1];	//undefined caught below
				else
					parent = RZ.permissions_parent
			}
			else if (action == 'edit' || action == 'edititem')
			{
				if (eval(level) == 0)
				{
					if(typeof RZ.linkparentnew[linkname] != 'undefined'
					&& typeof RZ.linkparentnew[linkname][level] != 'undefined')
						parent = RZ.linkparentnew[linkname][level]
				}
				else	//level > 0
					parent = parentkey;		//undefined caught below
			}
		}		// end of multi-level processing

		//----- Must have a parent when page permissions are enabled
		if (RZ.permissions_module != ''
		&& (typeof parent == 'undefined' || parent == 'undefined' || parent == ''))
		{
			msg = 'this'
			if (action.indexOf('new') == 0) msg = 'new'
			msg = 'This button is not configured for the '+msg+' page to properly INHERIT\n'
			    + 'page permissions because the parent is unknown'
			if (level != '') msg += ' for level ' + level
			msg +='.\n\n'
			    + 'Permissions may need to be explicitly defined on the page\n'
			    + 'associated with this link.'
			if ( !RZconfirm(msg) ) return
		}

		if (parent != '' && parent != 'undefined')
			RZ.link[linkname].linkparent = parent

		if (!RZ.link[linkname].linkseq && RZ.nextseq.linknames[linkname])
			RZ.link[linkname].linkseq = RZ.nextseq.linknames[linkname].seq;
	}

	RZtrace("Calling Edit Form", "URL: " + url )

	//----- Call popup window if requested else goto Edit Page URL
	var windowName = 'EditWindow';
	if (window.name == 'EditWindow')
		windowName = 'EditWindowPopup';
	RZ.editWindow = RZpopupUrl(windowName , url, width, height, scroll)
	if ( RZ.editWindow == null )
	{
		RZsaveReturnUrl( 'RZeditFormReturnUrl' )
		document.location = url
	}

	//----- Suspend processing if called as submit
	return void(0);
}
/*---------------------------------------------------------------------------
(Internal Function) Display page permission warning
Internal: Diagnostics Support
----------------------------------------------------------------------------*/
function RZlinkWithoutParent(module,recordid,code)
{
	if (typeof RZ.noparent[module] == 'undefined')
		RZ.noparent[module] = new Object();
	RZ.noparent[module][recordid] = code

	code = "'" + code + "'"
	var html = '<a href="javascript:RZpagemessage(' + code + ')">'
	         + '<img src="/revize/images/warning-parent.gif" border="0"></a>'
	RZlogin(html)
}
/*---------------------------------------------------------------------------
(Internal Function) Display message regarding button configuration issue
Internal: Diagnostics Support
----------------------------------------------------------------------------*/
function RZiconMessage(action,index)
{
	module = RZ.icons[index]
	var msg = RZpermissionWarning(action,'',module)
	if (msg != '')
		if (!RZconfirm(msg)) return
}
/*---------------------------------------------------------------------------
(Internal Function) Display warning if button not configured correctly
Internal: Diagnostics Support
----------------------------------------------------------------------------*/
function RZpermissionWarning(action,template,module)
{
	var msg = '';
	var buttonName = ''
	if (RZsubstring(action,0,3).toLowerCase() == 'new')
		buttonName = 'NEW '
	else if (RZsubstring(action,0,4).toLowerCase() == 'edit')
		buttonName = 'EDIT '

	// Get dependent template for page permissions
	if (template == '')
	{
		if (module == '')	//test by clearing RZ.template and RZ.module on button
		{
			msg = 'The template used to create the new page could not be \n'
				+ 'determined because no module was specified on the '
				+ buttonName + 'button.'
			}

		// Get template processed from the list associated with the specified module
		else if (typeof RZ.linktemplates[module] != 'undefined')
			template = RZ.linktemplates[module];

		else				//test by specifing incorrect module on button
			msg = 'The template used to create new pages can not be determined\n'
				+ 'because there does not appear to be any lists associated with\n'
				+ 'with the currently specified module: ' + module + '.'
	}
	if (msg == '' && template == '')	//test by clearing RZ.template on button
		msg = 'The template used to create new pages can not be determined\n'
			+ 'because there are no links in the list associated with the\n'
			+ 'currently specified module: ' + module + '\n\n'
			+ 'The developer may need to specify the template on the ' + buttonName + 'button\n'
			+ 'If pages are not created when list items are added, a template of none\n'
			+ 'should be specified.'

	// template not required for single record edits
	if (template == '*none*'
	|| action == 'editform' || action == 'editpage' || action == 'editglobal')
		msg = ''

	// Warn content editor about potential permissions inheritance issues
	if (msg != '')
	{
		if (buttonName == 'NEW ')
			msg = 'If this NEW button creates a new page, that page will NOT\n'
				+ 'inherit permissions for the following reason:\n\n'
				+ msg
		else if ( !RZcheckoptions(RZ.permissions_options,"warnings") )
			msg = ''	//no warning if migration option not enabled
		else
			msg = 'The EDIT button is not configured to properly pass page permissions\n'
				+ 'to the page created when this item was added to the associated list.\n\n'
				+ 'The template must be known to assign a parent to child pages.\n\n'
				+ msg
	}
	return msg
}
/*---------------------------------------------------------------------------
(Internal Function) Sets general edit url parameters used with or w/o link manager.
Internal: Update Record Support
----------------------------------------------------------------------------*/
function RZsetEditParameters(module,field,set)
{
	RZ.parameters = ''

	//----- Append webspace parameter
	RZaddUrlParameter( 'webspace=' + RZ.webspace )

	/* Was considered for page navigation variables
	//----- Template name used to create pageid
	if (RZ.pagetemplatename	!= '')
		RZaddUrlParameter( 'template=' + RZ.pagetemplatename )
	*/

	//----- Append module & field
	if (module!='')
		RZaddUrlParameter( 'module=' + module )	//used by link manager
	if (field!='')
		RZaddUrlParameter( 'field=' + field )		//future


	RZsetParameter(set);	//Append set parameters
}
/*---------------------------------------------------------------------------
(Internal Function) Adds the RZ.set values to the url
Called by RZsetEditParameters() & RZcalleditlist()
Internal: Update Record Support
----------------------------------------------------------------------------*/
function RZsetParameter(set)
{
	RZaddUrlParameter( 'pagetemplateid=' + RZ.pagetemplateid );
	RZaddUrlParameter( 'linkedmoduleid=' + RZ.pagemoduleid );
	RZaddUrlParameter( 'linkedrecordid=' + RZ.pagerecordid );
	//----- Append set parameters
	if (set != '')
	{
		set = set.split('pagerecord._recordid').join( RZ.editrecordid )
		RZaddUrlParameter( 'set=' + escape(set) )
	}
}
/*---------------------------------------------------------------------------
(Internal Function) Sets recordid parameter used with or w/o link manager.
Internal: Update Record Support
----------------------------------------------------------------------------*/
function RZsetEditRecordParameter(recordid)
{
	var recordidParameter = '*ERROR*'

	if (recordid == 'new')
		recordidParameter = '&new'

	//----- Calculated value
	else if (recordid.length>0 && recordid.substring(recordid.length-1)==';')
		recordidParameter = '&recordid=' + eval(recordid)

	//----- If rz.fetch returned an error message as text
	//		(use alert because it may not be design flaw)
	else if (recordid != '' && isNaN(recordid))
		alert( 'Revize Button specifies Invalid Record Id: \n' + recordid )

	else if (recordid != '')
		recordidParameter = '&recordid=' + recordid

	else
		recordidParameter = ''

	return recordidParameter
}
/*---------------------------------------------------------------------------
(Internal Function) Called from above and also from snippet_helper_editform.js
before calling RTE.

Computed window size just fits 800 X 600 for all options.
Create link object if undefined and use default options if undefined.

Internal: Link Manager Support
----------------------------------------------------------------------------*/
function RZsetLinkManagerProperties(linkname,module,field,recordid,set,url)
{
	//----- Set general edit Url paramters
	RZ.message = ''
	RZsetEditParameters(module,field,set)

	//----- If link object not yet defined, define it
	if (typeof RZ.link[linkname] == 'undefined') RZ.link[linkname] = new Object()

	//----- Get current options (use default values if undefined)
	var options = RZ.link[linkname].options
	if (typeof options == 'undefined') options = 'url,template,file'
	RZ.link[linkname].options = options

	if (typeof RZ.linkoptions != 'undefined' && RZ.linkoptions != '')
	RZ.link[linkname].options = RZ.linkoptions

	//----- Following properties are used by jsp code and must be passed on url
	RZaddUrlParameter( "linkname=" + linkname )
	RZsetLinkUrlParameter(linkname,'options')
	RZaddUrlParameter( "nexturl=" + RZabsoluteUrl(url) )

	//----- Template specfic properties (DW only defines template property)
	RZdefaultLinkParameter(linkname,'template')			//blank for all templates
	RZdefaultLinkParameter(linkname,'editform')			//template specific editforms
	RZdefaultLinkParameter(linkname,'modulelinkfield')	//back link from dependent module

	//----- TODO: Following properties are now passed on url (but should NOT)
	//		(they are not used by jsp code except to retrieve values for js)
	RZdefaultLinkParameter(linkname,'filelocation')		//file manager location (supported by RTE)
	RZdefaultLinkParameter(linkname,'fileextension')	//file manager extensions

	//----- TODO: Following properties are now passed on url (but probably NOT even used)
	RZdefaultLinkParameter(linkname,'imagelocation')	//image manager location
	RZdefaultLinkParameter(linkname,'imageextension')	//image manager extensions

	//----- Following properties NOT used by jsp code are accessed from the opener window
	//		They can be set on RZ.link.<linkname>.<property_below>
	RZdefaultLinkOption(linkname,'linkpathname')		//prepended pathname (supported by RTE)
	RZdefaultLinkOption(linkname,'linknewsection')		//list of templates that can start new sections

	RZdefaultLinkOption(linkname,'linkdisplaydefault')	//default linkdisplay
	RZdefaultLinkOption(linkname,'linktemplatedefault')	//default template
	RZdefaultLinkOption(linkname,'linkfilenamedefault')	//default path/filename
	RZdefaultLinkOption(linkname,'linkautocontinue')	//Auto click Continue button
	RZdefaultLinkOption(linkname,'nexturl')				//next editform for all templates
	RZdefaultLinkOption(linkname,'set')					//Set passed to dependent module
	RZdefaultLinkOption(linkname,'linkparent')			//parent that added link
	RZdefaultLinkOption(linkname,'linkmodule')			//list module

	//----- Determine link parent (defined by new or edit button - single level menu)
	var linkparent = RZ.link[linkname].linkparent
	if (linkparent == '')
	{
		if (RZ.permissions_parent != '')	//this page is surogate parent (e.g. editlist)
			linkparent = RZ.permissions_parent
		else
			linkparent = RZ.page_key
	}
	RZ.link[linkname].linkparent = linkparent

	//----- Convert nexturl to absolute url (some RTE calls have property defined at this time)
	var nexturl = RZ.link[linkname].nexturl
	if (nexturl != '')
		RZ.link[linkname].nexturl = RZabsoluteUrl(nexturl)

	//----- Compute link manager window size
	var width = 600
	var height = 240 		// base height IE or NS (includes target)
	var testopt = ',' + options + ','
	if (testopt.indexOf(',none,') != -1) height += 25
	if (testopt.indexOf(',url,') != -1) height += 40
	if (testopt.indexOf(',file,') != -1) height += 45
	if (testopt.indexOf(',template,') != -1)
	{
		height += 220 + 40;		//add 40 for section prompt
		if (RZ.isnavigator) height += 25
	}

	//----- Store computed values in the link object itself
	RZ.link[linkname].linkwidth   = width
	RZ.link[linkname].linkheight  = height
	RZ.link[linkname].linkscroll  = 'yes'

	//----- Store link manager url with parameters
	RZ.link[linkname].linkurl = '/revize/util/linkmanager_frame.html' + RZ.parameters

	//----- Display all link manager properties on trace
	RZtrace('Link Manager linkname (' + linkname + ') url parameters',RZ.message)
	var msg = ''
	for (var i in RZ.link[linkname])
		msg += i + '  =  ' + RZ.link[linkname][i] + '\n'
	RZtrace('RZsetLinkManagerProperties() linkname (' + linkname + ')',msg)
}
/*---------------------------------------------------------------------------
(Internal Function)Save all link manager information for this link in a new
object that is referenced at run time by new and edit buttons.

This function is called by the link object to define link properties for use by
new and edit buttons.  A separate link object is defined for each linkname so
these properties are available when the new or edit button is clicked. The new
and edit buttons can then simply supply the linkname to access these properties.

See RZTagSupport.java for more information on the link manager calling process.

**IMPORTANT**
When changing functionality, please update Dreamweaver help file:
	RevizePermissionsWorks-Help.htm (contains high level description)

Internal: Link Manager / Page Permissions Support
----------------------------------------------------------------------------*/
function RZlinkmanager( linkname, linkmodule, linkrecordid, linklevel,
	                    linkpagekey, linkparent )
{
	if (typeof linkname == 'undefined') linkname = RZ.linkname
	if (typeof linkmodule == 'undefined') linkmodule = ''
	if (typeof recordid == 'undefined') recordid = ''
	if (typeof linklevel == 'undefined') linklevel = ''
	if (typeof linkpagekey == 'undefined') linkpagekey = ''
	if (typeof linkparent == 'undefined') linkparent = ''
	if (linkparent.indexOf('This is a STANDARD text field:') == 0) linkparent = '';

	//----- For multi-level link manager lists...
	if (linkmodule != '' && linklevel != '')
	{
		//----- Save first non-blank linkparent for this level
		if (typeof RZ.linkparentnew[linkname] == 'undefined')
			RZ.linkparentnew[linkname] = new Object();

		if (typeof RZ.linkparentreset[linklevel] == 'undefined')
			RZ.linkparentreset[linklevel] = 'reset'

		if (typeof RZ.linkparentnew[linkname][linklevel] == 'undefined'
		|| RZ.linkparentreset[linklevel] == 'reset')
		{
			if (linkparent == '') linkparent = RZ.permissions_parent
			RZ.linkparentnew[linkname][linklevel] = linkparent
			RZ.linkparentreset[linklevel] = ''
		}

		//----- Indicate new next higher level linkparent can be reset
		var nextlevel = RZinteger(linklevel) + 1
		RZ.linkparentreset[nextlevel] = 'reset'

		//----- Save most recent pagekey (used to get parent for new level button)
		RZ.linkpagekey[linklevel] = linkpagekey
		if (typeof RZ.linkpagekey[linklevel+1] != 'undefined')
			RZ.linkpagekey[linklevel+1] = 'undefined';	//clear lower level value
	}

	//----- Create link object if not defined to hold module and parent
	if (typeof RZ.link[linkname] == 'undefined')
	{
		RZ.link[linkname] = new Object()
		RZ.link[linkname].linkparent = ''
		RZ.link[linkname].linkmodule = ''
	}

	//----- Set linkparent to 1st non-blank parent encountered (used for single level links)
	//		When no linkparent is set, the page_key is used when new or edit button clicked.
	if (linkparent != '' && RZ.link[linkname].linkparent == '')
		RZ.link[linkname].linkparent = linkparent

	//----- Save additional link properties
	if(RZ.linkname != '')
	{

		if (RZ.link[linkname].linkmodule == '' && linkmodule != '')
			RZ.link[linkname].linkmodule = linkmodule;

		RZ.link[RZ.linkname].options = RZ.linkoptions
		RZ.link[RZ.linkname].filelocation = RZ.linkfilelocation
		RZ.link[RZ.linkname].fileextension = RZ.linkfileextension
		RZ.link[RZ.linkname].imagelocation = RZ.linkimagelocation
		RZ.link[RZ.linkname].imageextension = RZ.linkimageextension

		RZ.link[RZ.linkname].template = RZ.linktemplate
		RZ.link[RZ.linkname].editform = RZ.linkeditform
		RZ.link[RZ.linkname].modulelinkfield = RZ.linkmodulelinkfield

		//----- Properties not passed on url
		//		TODO: automatically pick up all options starting with link
		RZ.link[RZ.linkname].linkpathname = RZ.linkpathname
		RZ.link[RZ.linkname].linknewsection = RZ.linknewsection
		RZ.link[RZ.linkname].linkdisplaydefault = RZ.linkdisplaydefault
		RZ.link[RZ.linkname].linktemplatedefault = RZ.linktemplatedefault
		RZ.link[RZ.linkname].linkfilenamedefault = RZ.linkfilenamedefault
		RZ.link[RZ.linkname].linkautocontinue = RZ.linkautocontinue
	}

	//----- clear RZ.* action arguments
	RZactionReset();
}
/*---------------------------------------------------------------------------
(Internal Function) Call RZdefaultLinkOption then add to RZ.parameters
Internal: Link Manager Support
----------------------------------------------------------------------------*/
function RZdefaultLinkParameter(linkname,property)
{
	RZdefaultLinkOption(linkname,property)
	RZsetLinkUrlParameter(linkname,property)
}
/*---------------------------------------------------------------------------
(Internal Function) If property is undefined, set to blank
Internal: Link Manager Support
----------------------------------------------------------------------------*/
function RZdefaultLinkOption(linkname,property)
{
	if (typeof RZ.link[linkname][property] == 'undefined')
		RZ.link[linkname][property] = ''

	//RZtrace('RZdefaultLinkOption('+linkname+'):' + property
	//       + '<br>-->' +(RZ.link[linkname][property])+ '<--')
}
/*---------------------------------------------------------------------------
(Internal Function) Build link manager url parameters using link properties
presumably defined elsewhere on the page if property is defined and not blank.

Internal: Link Manager Support
----------------------------------------------------------------------------*/
function RZsetLinkUrlParameter(linkname,property)
{
	if (typeof RZ.link[linkname][property] != 'undefined')
	{
		var value = RZ.link[linkname][property]
		if (value != '')
			RZaddUrlParameter( 'link' + property + '=' + value )
	}
}
/*---------------------------------------------------------------------------
Adds jsp parameter to url
* parameter appended RZ.parameters with preceeding ? or & character
* parameter appended to RZ.message for output by RZtrace()

Parameters:
	parameter-	url parameter of the form key = value
----------------------------------------------------------------------------*/
function RZaddUrlParameter(parameter)
{
	//----- Build url parameter
	if (RZ.parameters.indexOf('?') == -1)
		RZ.parameters += '?' + parameter
	else
		RZ.parameters += '&' + parameter

	//----- Build trace message
	RZ.message += unescape(parameter) + '\n'
}

/* Same as: RZback (retained for backward compatibility) */
function RZpriorPage(returnUrlKey) { RZback(returnUrlKey) }
/*-------------------------------------------------------------------------
  Return to calling page (normally called by cancel button)

  If popupcall, close window and refresh if not an editform

  If returnUrlKey ends with a semicolon, assume it is an expression for url

  Otherwise, return to PRIOR PAGE using the following steps
  * If URL defined in cookie, use it (returnUrlKey specifies cookie name)
  * If not edit list page, use history
  * If RZ.page.home is not blank, use it
  * Make trace entry and stay on current page

  Parameters:
  returnUrlKey-	if specified, one of the following:
                1) expression containing url of page to get control
                2) if expression, must end with semicolon
                3) Cookie name containing calling page url
  win-			Optional specifies the current window (default is window)
  Returns:
  There is currently no value returned
  -------------------------------------------------------------------------*/
function RZback(returnUrlKey,win)
{
	if (typeof win == 'undefined') win = window

	//----- If opener and access to opener
	if ( RZisPopupCall(win) )
	{
		//----- Added for LinkManager RTE interface (but never refresh editform)
		if(RZ.parent.opener.RZ != 'undefined'
		&& RZ.parent.opener.RZ != null
		&& RZ.parent.opener.RZ.pagetype != 'editform')
			win.opener.location.reload(true);
		win.close()
		return;
	}

	//----- Not a popup call
	var returnUrl = ''
	if (RZright(returnUrlKey,1) == ';')		//url passed as variable / equation
		returnUrl = eval( returnUrlKey )
	else									//url read from cookie
	{
		returnUrl = RZgetCookieValue(returnUrlKey)
		if (returnUrl != "")
		{	// if cookie defined
			RZsetCookieValue(returnUrlKey,"")
		}else
		{	// when cookie not defined
			if (RZ.pagetype == 'editform')
			{
				returnUrl = ''
				history.go(-1); // use history if not edit list
			}
			else
			{
				returnUrl = RZ.page.home // use home if edit list
			}
		}
	}

	if (returnUrl != null && returnUrl != '')
		RZ.parent.location = returnUrl
	else
		RZtrace('snipper_helper: RZback('+returnUrlKey+')',
				'No Prior URL could be determined')
}
/*--------------------------------------------------------------------------
(Internal Function) Determine if this page was called as a popup.

Internal: Used by Save & Cancel functions to return to calling window.

Returns: true if opener with RZ.pagetype variable defined; otherwise false
--------------------------------------------------------------------------*/
function RZisPopupCall(win)
{
	if (typeof win == 'undefined') win = window

	if (RZwinaccess(win.parent.opener)
	&& typeof win.parent.opener != 'undefined'
	&& typeof win.parent.opener.RZ != 'undefined'	//opener is a Revize page
	&& win.parent.opener.RZ != null
	&& typeof RZ.parent.opener.RZ.pagetype != 'undefined'
	&& typeof RZ.parent.opener.RZ.editWindow != 'undefined'
	&& win.parent.opener.RZ.editWindow == win.parent)
		return true;

	//----- If opened from workflow task window
	//		TODO: probably should always assume popup if opener exists but too risky w/o
	//		more analysis and serious regression testing.
	else if (win.parent.name == 'Revize_Edit_Record' && typeof win.opener != 'undefined')
		return true;

	//----- If callback function specified after save
	else if(RZ.nextsavereturn
	&& RZ.nextsavereturn.indexOf('(') > 0 && RZ.nextsavereturn.indexOf(')') > 0)
		return true;

	else
		return false;
}
/*---------------------------------------------------------------------------
Following function is called by the DELETE ITEM button

***** Delete current row (after prompting) *****

	1. Confirm delete, return if not Ok

	2. Make trace entry

	3. Submit Xml request to revize, redirect to current page
----------------------------------------------------------------------------*/
function RZrecordDelete( recordID, moduleName )
{ RZdelete( recordID, moduleName ) }
function RZdelete( recordID, moduleName, nextUrl, win )
{
	if (typeof win == 'undefined') win = window;
	if (typeof nextUrl == 'undefined' || nextUrl == '')
		nextUrl = win.location.href
	RZ.message = "WebSpace: " + RZ.webspace + "\n"
			 + "Module: " + moduleName + "\n"
			 + "Record Id: (" + recordID + ")\n"
			 + "Redirect Url: " + nextUrl + "\n"
	RZtrace( "Delete Item Clicked", RZ.message );

	if (isNaN(recordID))
	{
		win.alert( 'Invalid Record Id: ' + recordID )
		return void(0)
	}
	else if (recordID=='')
	{
		win.alert( 'Record Not Specified (Id is Blank)' )
		return void(0)
	}
	if (!win.confirm("Ok to Delete This Item?")) return

	//----- Call Developer defined ondelete handler and quit if it returns false
	if (typeof window.ondelete == 'function')
	{
		RZ.recordid = recordID
		RZ.module = moduleName
		var status = window.ondelete()
		if (status == false)
		{
			window.status = 'Delete Canceled'
			return void(0)
		}
		else if (typeof status == 'object')
		{
			if (typeof status.nexturl != 'undefined')
				nextUrl = status.nexturl
		}
	}

	// Use the XML translator servlet instead of the old XML form method.
	var deleteUrl =	"/revize/HTTPTranslatorServlet" +
					"?resourcetype=record" +
					"&action=delete" +
					"&webspace=" + RZ.webspace +
					"&id=" + recordID +
					"&pagetemplateid=" + RZ.pagetemplateid +
					"&linkedmoduleid=" + RZ.linkedmoduleid +
					"&linkedrecordid=" + RZ.linkedrecordid +
					"&modulename=" + moduleName +
					"&pagekey=" + RZ.page_key +
					"&redirect=" + escape(RZabsoluteUrl(nextUrl));
	RZtrace( "Delete Item Request", deleteUrl );
	RZactionReset();
	win.location = deleteUrl;
}
/*---------------------------------------------------------------------------
Bring up page permissions window.

The options argument can contain one of the following:
	nexturl, linkname, module, object
----------------------------------------------------------------------------*/
function RZpermissions(set,options)
{
	var pos;
	if (typeof set == 'undefined') set = ''
	if (typeof options == 'undefined') options = ''

	var nexturl = RZgetoption( options, 'nexturl' )
	var linkname = RZgetoption( options, 'linkname')
	var module = RZgetoption( options, 'module')

	if (nexturl == '')
	{
		var fileInfo = RZgetfileinfo('/revize/util/permissions-editform.jsp')
		nexturl = RZbuildurl(fileInfo)
	}

	RZ.message = ''
	RZ.parameters = nexturl
	RZaddUrlParameter( 'webspace=' + RZ.webspace )
	RZaddUrlParameter( 'page_key=' + RZ.page_key )
	if(RZ.workflowmodule != '' && RZ.workflowmodule != undefined)
		RZaddUrlParameter( 'workflowmodule=' + RZ.workflowmodule );
	if (set == '')
	{
		set = RZ.permissions_module + '.page_key=' + RZ.page_key
		if (linkname != '')
			set += linkname
		else if (module != '')
			set += module
	}
	RZaddUrlParameter('set='+escape(set))

	RZtrace('Page Permissions Call',RZ.message)
	RZ.editWindow = RZpopupUrl( 'EditWindow', RZ.parameters, 600, 500, 'yes')
}
/*------------------------------------------------------------------------------
Remove any leading and ending blank spaces from string (trim)

Parameters:
	tmpStr - Input string

Returns:
	String with leading and trailing spaces removed
------------------------------------------------------------------------------*/
function RZtrim(tmpStr)
{
	while(tmpStr.substring(0,1) == ' ')
		tmpStr = tmpStr.substring(1, tmpStr.length);

	while(tmpStr.substring(tmpStr.length-1,tmpStr.length) == ' ')
		tmpStr = tmpStr.substring(0, tmpStr.length - 1);

	return tmpStr;
}
/*------------------------------------------------------------------------------
RZreplace(inStr, fromString, toString)

Replace all occurances of fromString with toString
(retain RZreplaceAll & RZreplacesubstring for backward compatibility)

Parameters:
	inStr - Input String
	fromString - String to replace
	toString - Replacement String

Returns:
	String with replacements
------------------------------------------------------------------------------*/
function RZreplace( inStr, fromString, toString )
{ return RZreplacesubstring( inStr, fromString, toString ) }
function RZreplaceAll( inStr, fromString, toString )
{ return RZreplacesubstring( inStr, fromString, toString ) }
function RZreplacesubstring( inStr, fromString, toString )
{
	var pos = 0
	if (inStr == null
	|| typeof inStr.length == 'undefined' //true or false
	|| inStr.length == 0) return '';

	var fromLen = fromString.length
	if (fromLen == 0) return inStr

	while (true)
	{
		pos = inStr.indexOf(fromString,pos)
		if (pos == -1) break
		inStr = RZsubstring( inStr, 0, pos )
		      + toString
		      + RZsubstring( inStr, pos + fromLen )
		pos += toString.length
	}
	return inStr
}
/*------------------------------------------------------------------------------
Subsitute for substring method (does not produce javascript errors)

A null or empty input string returns empty string

Start and end positions outside boundries intrepreted as follows:

	if end position not specified or greater than string length,
	adjust to input string length

	if end position before 1st character,
	return empty string

	if start position greater than ending position,
	return empty string

	if start position less than 0,
	assume 0

Parameters:
----------
	str-		Input string
	startpos-	Starting position
	endpos-		Ending position (optional)

Returns:
	substring as described above.

------------------------------------------------------------------------------*/
function RZsubstring(str, startpos, endpos)
{
	if (typeof endpos == 'undefined') endpos = str.length + 1

	//----- Validate input string
	if (str == null || str.length == 0)	//if null or empty string
		return "";						//...return empty string

	//----- Validate end position
	if (endpos > str.length )			//greater than string length
		endpos = str.length;			//...set to length

	else if( endpos <= 0 )				//if end position before 1st character
		return "";						//...return empty string

	//----- Validate start position
	if( startpos >= endpos )  			//if start position greater than ending position
		return "";						//...return empty string

	else if (startpos < 0) 				//if start position less than 0
		startpos = 0;					//...assume 0

	//----- Return the substring
	return str.substring(startpos,endpos);
}
/*---------------------------------------------------------------------------
returns rightmost number of characters specified

Parameters:
	str - Input String
	noChars - number of rightmost characters desired

Example:
	* right("1234",2) returns "34"
    * right("1234",0) returns ""
    * right("0",4) returns "0"

Returns:
	Rightmost substring possible; does not throw exception if string too short
----------------------------------------------------------------------------*/
function RZright( str, noChars )
{
	if (!str) return '';
	var len = str.length;
	if (len == 0) return "";

	if (noChars > len) noChars = len;
	return str.substring(len-noChars);
}
/*---------------------------------------------------------------------------------------------
Converts number to the nearest integer
0 is returned if not a valid number unless a defaultValue is supplied

Parameters:
	number - string or number to be converted to an integer (whole number)
	defaultValue - number returned in number parameter is not a valid number

Returns:
	Nearest whole number of input number; if input number or string is undefined or not
	a number, the defaultValue is returned
---------------------------------------------------------------------------------------------*/
function RZinteger(number,defaultValue)
{
	if (typeof defaultValue == 'undefined') defaultValue = 0

	if (isNaN(number))
		return defaultValue

	return parseInt( parseFloat(number)+.5 )	//convert number to number then round up
}

/* Same as RZcheckoptions (retained for backward compatibility) */
function RZcheckOptions( pOptions, pChoices )
{ return RZcheckoptions( pOptions, pChoices ) }
/*---------------------------------------------------------------------------
Look for specific option choice(s) in the options string.  Both options and
choices use commas to seperate multiple individual options.

Parameters:
        pOptions - Caller supplied options (e.g. "filter,editsingle,alt")
        pChoices - specific option choices to look for (e.g. alt,url,image)

Returns:
        True if at least one choice is contained in options
        False if none of the choice(s) are found
----------------------------------------------------------------------------*/
function RZcheckoptions( pOptions, pChoices )
{
	if(typeof pOptions == 'undefined' ||typeof  pChoices == 'undefined')
		return false;
	var str, pos;
	var inputOpts = "," + pOptions + ",";
	inputOpts = inputOpts.toLowerCase();

	var searchOpts = pChoices.toLowerCase();

	//----- For each desired choice ...
	while ( !searchOpts == "" )
	{
		str = searchOpts;
		pos = str.indexOf(",");
		if (pos == 0)
		{
			searchOpts = str.substring(pos+1);	//strip comma
			continue;
		} else if (pos > 0)
		{
			searchOpts = str.substring(pos+1);
			str = str.substring(0,pos);
		} else
		{// no commaa
			searchOpts = "";
		}
		// check for this choice
		if (inputOpts.indexOf("," + str + ",") >= 0) return true;
		if (inputOpts.indexOf("," + str + "=") >= 0) return true;
	}
	return false;
}

/* Same as RZgetoption (retained for backward compatibility) */
function RZgetKeyValue( pOptions, pKey)
{ return RZgetoption( pOptions, pKey ) }
/*---------------------------------------------------------------------------
Looks for a key=value in the options string and returns the value portion.
(clone of getValue in RZTabSupport)

Parameters:
	options - String searched for key=value
	key - Key to find in options string

Returns:
	Associated value when key is found, otherwise returns blank string
----------------------------------------------------------------------------*/
function RZgetoption( pOptions, pKey )
{
	var pos, str, keyEqual;

	//----- Search for key=
	keyEqual = pKey + "=";
	str = "," + pOptions;
	pos = str.toLowerCase().indexOf( keyEqual.toLowerCase() );

	if (pos == -1) 	// key not found
		str = "";
	else
	{
		//----- Keep everything after =
		str = pOptions.substring(pos + keyEqual.length - 1);
		pos = str.indexOf(",");
		if (pos >= 0) str = str.substring( 0, pos );	// value
	}

	return str;
}
/*---------------------------------------------------------------------------
Call Next URL (popup or forward link)
----------------------------------------------------------------------------*/
function RZcallNextUrl( name,url, width,height,scroll)
{
	if ( RZpopupUrl(name,url, width,height,scroll) == null )
	{
		RZtrace("Calling Next URL Form", "URL: " + url )
		document.location = url
	}
}
/*---------------------------------------------------------------------------
RZeditor(): See RZeditorsetup in snippet_helper_rte.
Stub kept here for backward compatibility and warning message.
----------------------------------------------------------------------------*/
function RZeditor()
{
	if( RZ.pagetype == 'editform' )
		RZeditorsetup()
	else
		RZalert('Rich Text Editor Must be Opened on Form Page')
}
/*---------------------------------------------------------------------------
Set Link Property value in link object passed to RTE (NOT yet used or tested)
Might be useful on edit forms to set link manager properties.
----------------------------------------------------------------------------*/
function RZsetLinkProperty( linkObj, property )
{
	if (typeof RZ.link[linkname] != 'object')
		if (typeof RZ.link[property] == 'undefined')
			linkObj[property] = ''
		else
			linkObj[property] = RZ[property]
}
/*---------------------------------------------------------------------------
Append key=value to end of set if key not already in set and value not blank.

Optional argument options argument
	if not an object and true, replace existing key with specified value.
	if object then
		options.replace contains replaceFlag true to override a prior value
		options.update set true if value changed (replaceFlag must be true)

Returns true if prior value for key was changed.
----------------------------------------------------------------------------*/
function RZaddset(key, value, options)
{
	var replaceFlag = false;
	if (typeof options == 'object')
		replaceFlag = options.replace;
	else if (options)
		replaceFlag = options;

    // will property be updated (i.e. over-ridden)
	var status = false;			//default return status
	if (typeof value == 'undefined' || value == '') return status;

	var setCheck = ','+ RZ.set;
	var start = setCheck.indexOf(','+key);
	if (start == -1)
	{
		if (RZ.set != '') RZ.set += ','
		RZ.set += key + '=' + value;
	}
	else if (replaceFlag)
	{
		var end = RZ.set.indexOf(',',start);
		if (end == -1) end = RZ.set.length;
		var oldStr = RZ.set.substring(start,end);
		var newStr = key + '=' + value;
		if (oldStr != newStr)  status = true;
		RZ.set = RZreplace( RZ.set, oldStr , newStr );
	}

	if (typeof options == 'object')
	 	options.update = (options.update || status);

	return status;
}
/*---------------------------------------------------------------------------
Set or update RZ property
	options.replace contains replaceFlag true to override a prior value
	options.update set true if value changed (replaceFlag must be true)
----------------------------------------------------------------------------*/
function RZupdate(key,value,options)
{
	if (!options.replace && RZ[key] != '') return;
	if (!value == 'undefined' || value == '') return;

    // will property be updated (i.e. over-ridden)
	if (RZ[key] != '' && RZ[key] != value)
		options.update = true;

	RZ[key] = value;
}
/*---------------------------------------------------------------------------
Set or update form property (probably won't work for Firefox).
	options.replace contains replaceFlag true to override a prior value
	options.update set true if value changed (replaceFlag must be true)
----------------------------------------------------------------------------*/
function RZupdateFormProperty(field,key,value,options)
{
	if (!options.replace && typeof field[key] != 'undefined') return;
    if (!field || typeof value == 'undefined') return;

    if (typeof value == 'string' && value == '')
    	return;

    else if (typeof value == 'object')
    {
		if (typeof value.length == 'undefined'
		|| value.length < 1
		|| value[0] == '')
    		return;
	}

    // will property be updated (i.e. over-ridden)
    if (typeof field[key] != 'undefined' && field[key] != '' && field[key] != value)
		options.update = true;

    field[key] = value;
}
/*---------------------------------------------------------------------------
Open Trace Window and Display Message
----------------------------------------------------------------------------*/
function RZtrace(heading,text)
{
	if( !RZ.trace ) return
	if( typeof text == 'undefined') text = ''
	text = text.toString();
	text = text.split('--').join('\n')

	var MSIE = true;
	if (navigator.appVersion.indexOf('MSIE') == -1) MSIE = false;

	//----- Always open using browser specific options
	//		(if already open, it reconnects to existing window)
	while (true)
	{
		if(!MSIE) //Navigator
		{
			RZ.tracewin = window.open('', 'RevizeTrace',
			'width=420,height=580,location=no,menubar=no,resizable=yes,screenX='
			+ (screen.availWidth-430)
			+ ',screenY=20,directories=no,status=no,scrollbars=yes');
		}
		else  //IE
		{
			RZ.tracewin = window.open('', 'RevizeTrace',
			'width=420,height=580,location=no,menubar=no,resizable=yes,left='
			+ (screen.availWidth-430)
			+ ',top=20,directories=no,status=no,scrollbars=yes');
		}
		//----- Close trace window if no access and open again
		if (MSIE && !RZwinaccess(RZ.tracewin))
			RZ.tracewin.close()
		else
			break
	}

	//----- Convert special characters
	text = text.split('<').join('&lt;');
	text = text.split('>').join('&gt;');

	//----- Display message.
	if (heading != '')
		RZ.tracewin.document.writeln(
			'</pre>',
			'<html><title>Trace</title><body>\n',
			'<b>',heading,'</b><br>\n',
			'<font size="-2" face="Arial">',location.href,'</font>\n',
			'<pre>\n',
			text)
	else if (text != '')
		RZ.tracewin.document.writeln( text )
	else
		RZ.tracewin.document.writeln( '</pre>' )

	//----- Give focus, if trace window already open and accessible
	if (!MSIE || RZwinaccess(RZ.tracewin)) RZ.tracewin.scrollBy(0,600)
}

/*---------------------------------------------------------------------------
POPUP EDITOR CAN NO LONGER BE CALLED FROM PUBLISHED PAGES

***** Editor Support Code *****

Open Html Editor in popup window
If specified field exists in XMLForm, use that value.
Otherwise Revize editor will read and store data from content database.
----------------------------------------------------------------------------*/
function RZcallEditor( moduleName, fieldName, width, height, options, recordid )
{
	if (typeof moduleName == 'undefined') moduleName = '';
	if (typeof fieldName == 'undefined') fieldName = '';
	if (typeof width == 'undefined' || width=='' ) width = '600';
	if (typeof height == 'undefined' || height=='') height = '400';
	if (typeof options == 'undefined') options = '';
	if (typeof recordid == 'undefined') recordid = '';

	//----- Make sure field and image elements are supplied
	var msg = '';
	var useDatabase = false;
	if (moduleName == '')
		msg = "Module Name Not Specified"
	else
	{
		if (fieldName == '')
			msg = "Editable Field Name Not Specified"
		else
		{
		if (typeof document.XMLForm == 'undefined')
			useDatabase = true;
		else
			if (typeof document.XMLForm[fieldName] == 'undefined')
			useDatabase = true;
		}
	}


	//----- Report any problems with arguments before using
	if (msg != '')
	{
		RZalert( 'Invalid Revize Editor Request\n\n'
			   + 'Function: snippet_helper.js:RZcallEditor()\n\n'
			   + 'Problem: ' + msg + '\n' )
		return;
	}

	//----- Make trace entry
	RZ.message = '';
	RZmsgAdd( "module"  , '\t' + moduleName )
	RZmsgAdd( "field"   , '\t' + fieldName )
	RZmsgAdd( "width"   , '\t' + width )
	RZmsgAdd( "height"  , '\t' + height )
	RZmsgAdd( "recordid", '\t' + recordid )
	RZmsgAdd( "options" , '\t' + options )
	RZtrace( "Revize Editor Request", RZ.message )

	//----- Call Editor screen, passing parameters via Url
	var url;
	var editorDir = '/revize/'

	if (!RZ.MSIE || RZ.browserversion < 5.5)
	{
		editorDir += 'javaeditor'

		// Convert any rich edit options to applet editor Url parameters syntax
		options = RZ.options.split(';').join('&')
		if (options.substring(1,3) == '&&') options = options.substring(1)
	}else
	{
		editorDir += 'htmleditor'
		options = RZeditorOptions(options);		//convert to rich edit format
		options = 'options=' + escape(options)	//passed as a single parameter
	}
	url = editorDir + '/editor-editform.jsp?webspace=' + RZ.webspace;
	if (useDatabase != '') url += '&module=' + moduleName;
	url += '&field=' + fieldName
	if (recordid != '') url += '&recordid=' + recordid
	url += '&width=' + width + '&height=' + height + '&' + options
	RZpopupUrl('revize_editor',url,width,height,'no')
}
/*---------------------------------------------------------------------------
Open Url in Popup Window (return true if popup)

Originally used popup window if either width, height or SCROLL was not blank;
with advent of RZaction() and use of RZ object arguments, do not assume popup
based on scroll value or if both width and height are set to 0.

Since scroll is last feature, it can specify other features after the scroll
value. For example:
	yes,location=yes,menubar=yes,toolbar=yes,directories=yes'

If niether width, heigth or scroll are specified assume popup window with no
features specified.

Returns:
	window object of popup window or null if popup window not used
----------------------------------------------------------------------------*/
function RZpopupUrl(name,url,width,height,scroll)
{
	var useFeatures = true;
	if(typeof width == 'undefined'
	&& typeof height == 'undefined'
	&& typeof scroll == 'undefined')
		useFeatures = false;
	else
	{
		var popup = false;
		if(typeof width != 'undefined' && width != '' && width != 0 && width != '0')
			popup = true;
		if(typeof height != 'undefined' && height != ''	&& height != 0 && height!= '0')
			popup = true;
		if ( !popup) return null;
	}

	RZ.message = "Name: " + name + "\n"
		 + "Url:  " + url + "\n"
		 + "Width:  " + width + "\n"
		 + "Heigth: " + height + "\n"
		 + "Scroll: " + scroll + "\n"
	RZtrace("Opening Popup Window", RZ.message)

	//----- Determine popup properties
	if(typeof url == 'undefined') url = ''
	if(typeof name == 'undefined') name = 'RevizeWindow'
	if(typeof width == 'undefined' || width=='') width = 400
	if(typeof height == 'undefined' || height=='') height = 400
	if(typeof scroll == 'undefined' || scroll=='') scroll = 'yes'

	var menubar = 'no'
	var location = 'no'
	var toolbar = 'no'
	var directories = 'no'
	var status = 'yes'
	if( RZ.trace || RZ.debug )
	{
		scroll = 'yes'
		menubar = 'yes'
		location = 'yes'
		toolbar = 'yes'
		directories = 'yes'
		status = 'yes'
		width = parseInt(width) + 15
		height = parseInt(height) + 50
	}
	else if (name == 'admin')
	{
		menubar = 'yes'
		location = 'yes'
	}

	var features = 'width=' + width + ',height=' + height
			   + ',location='+location
			   + ',menubar='+menubar
			   + ',resizable=yes'
			   + ',toolbar=' + toolbar
			   + ',directories=' + directories
			   + ',status=' + status
			   + ',scrollbars=' + scroll	//must be last to allow specify features

	var x = (screen.availWidth - width) / 2 - 10
	var y = (screen.availHeight - height) / 2 - 30
	if (y < 50) y = 0

	if(navigator.appVersion.indexOf('MSIE') == -1)  // Netscape
		features += ',screenX=' + x.toString()
				 +  ',screenY=' + y.toString()
	else                                            // IE browser
		features += ',left=' + x.toString()
				 +  ',top=' + y.toString()
	if (!useFeatures) features = ''	//do not specify features

	/*****
	First open the popup window and give it focus in case it was already open.
	It is possible that the popup window has been left open by another instance
	of the browser.  When this occurs on IE, the popup window will NOT have
	access to window.opener property.  To avoid this problem, we wait a second
	and then call RZpopupAccess() to close and reopen the popup if the popup
	window does not have proper access to this window.  We did not want to
	always close and reopen the window because it can be distracting for
	content editors.
	*****/

	//TODO:	This statement gets 1075 error on IE when opening publishing window
	//		if popup edit form was left open from another edit (calendar_app)
	RZ.popupwin = window.open( url, name, features );

	//----- On Netscape, RZ.popupwin sometimes not defined
	if (RZ.popupwin == null || typeof RZ.popupwin == 'undefined')
		RZ.popupwin = window.open( url, name, features );

	//----- Give popup window focus
	RZ.timeoutfocus = window.setTimeout('RZfocus(RZ.popupwin)', 500);

	//----- Check for access after page loads
	var str = 'RZpopupAccess("' + url + '","' + name+ '","' + features + '")'
	RZ.timeoutaccess = window.setTimeout(str, 1000)

	return RZ.popupwin;
}
/*---------------------------------------------------------------------------
Cancel focus and access timeout events.
----------------------------------------------------------------------------*/
function RZcancelPopupEvents()
{
	window.clearTimeout(RZ.timeoutfocus)
	window.clearTimeout(RZ.timeoutaccess)
}
/*---------------------------------------------------------------------------
Sets focus in case the specified window was left open from a previous call
----------------------------------------------------------------------------*/
function RZfocus(win)
{
    if (RZwinaccess(win))
        if (win.name != 'rzrte' && win.name != 'RZpublishing') win.focus();
}
/*---------------------------------------------------------------------------
See above description in RZpopupUrl
----------------------------------------------------------------------------*/
function RZpopupAccess(url,name,features)
{
	var str = ''
	if (!RZwinaccess(RZ.popupwin))
	{
		str = 'popup window closed'
	}else
	{
		str = 'opener: '
		if (RZwinaccess(RZ.popupwin.opener))
		{
			if (typeof RZ.popupwin.opener.location == 'undefined')
				str += '*no url*'
			else
				str += RZ.popupwin.opener.location.href
		}
		else if (typeof RZ.popupwin.opener != 'undefined')
			str += 'no access to opener'
		else
			str += 'opener not defined'
	}

	var msg = 'name: ' + name + '\n'
            + 'url: ' + url + '\n'
            + str + '\n'
	//alert('Popup Properties\n\n' + msg)
	RZtrace( 'Popup Properties', msg)

	//----- Quit if popup window has been closed
	if (!RZwinaccess(RZ.popupwin)) return

	//----- If no access to opener, close window and reopen
	if ( !RZwinaccess(RZ.popupwin.opener))
	{
		RZ.popupwin.close();
		RZ.popupwin = window.open( url, name, features );
		return
	}

	/*
	//----- If Revize Control Panel... (future)
	if ( name == 'revizecontrol' )
	{
		if (typeof RZ.popupwin.RZ == 'undefined')
		{
			window.focus()
			RZ.popupwin.document.write('<title>Revize Control Panel</title>')
		}
	}
	*/
  	RZ.popupwin = null		//indicate popup processing complete
}
/*---------------------------------------------------------------------------------------------
Wait for access to "win" to perform "waitCommand" displaying "waitMsg" while waiting;
Only wait "maxSeconds" (default 30); check every "msInterval" (default 1000) milliseconds.
---------------------------------------------------------------------------------------------*/
function RZwait(win, waitCommand, waitMsg, maxSeconds, msInterval)
{
	if (typeof waitMsg == 'undefined') waitMsg = 'Waiting for access'
	if (typeof maxSeconds == 'undefined') maxSeconds = 30
	if (typeof msInterval == 'undefined') msInterval = 1000

	RZcancelPopupEvents()	//RZwait overrides automatic popup events

	//----- Validate arguments
	var msg = ''
	if (typeof win != 'string')
		msg = '1st Argument is type ' + typeof win;
	else if(typeof waitCommand != 'string')
		msg = '2nd Argument is type ' + typeof win;

	if (msg != '')
	{
		msg = 'RZwait must be called with string variables\n\n' + msg;
		RZalert(msg)
		return;
	}

	//----- Setup call to RZwaitCheck...
	var now = new Date()
	RZ.waitstart = now.getTime()	//start of wait
	RZ.waitaccess = 0

	waitCommand = RZreplacesubstring( waitCommand, '"', '\\"' )

	RZ.waitcall = 'RZwaitCheck( ' + win
	                          + ', "' + waitCommand + '" '
	                          + ', "' + waitMsg  + '" '
	                          + ', ' + maxSeconds
	                          + ', ' + msInterval
	                          + ' )'

	RZtrace('Setup Wait', RZ.waitcall )
	//eval( RZ.waitcall )		//call RZwaitCheck() immediately
	setTimeout( RZ.waitcall, msInterval );	//give the url a chance to load
}
/*---------------------------------------------------------------------------
----------------------------------------------------------------------------*/
function RZwaitError(message)
{
	return true
}
/*---------------------------------------------------------------------------------------------
If access to "win" or "maxSeconds" have passed since "RZ.waitstart", perform "waitCommand";
otherwise wait another "msInterval" milliseconds.

Access means permisison to access window, RZ not null and...
either window name is not blank (works for most non-Revize enabled pages)
--or-- RZ.loaded is not undefined nor null

Notes:
It is possible that access to "win" is lost after checking access but prior to actually
accessing "win" variables which can cause one of the following JavaScript errors:
	RZ is null or not an object
	object does not support this property or method

Checking the page access before the new url starts to load is believed to be one cause.
An alternative onerror handler is set to catch these potential javascript errors.
This function stops running after a javascript error but unfortunately when MS studio is
installed and IE script debugging is not disabled, the currently defined onerror handler
does not run either and therefore can't be used to restore the original onerror handler
or schedule RZwaitCheck() to run again.

In order to restart RZwaitCheck in all cases is therefore rescheduled before the any
javascript error can occur and canceled if no more waiting is required.
---------------------------------------------------------------------------------------------*/
function RZwaitCheck (win, waitCommand, waitMsg, maxSeconds, msInterval)
{
	if (window.onerror == RZwaitError)
		window.onerror = RZ.waitonerror		//restore original handler

	var now = new Date()
	var seconds = (now.getTime() - RZ.waitstart).toString() / 1000
	waitcallId = setTimeout( RZ.waitcall, msInterval)

	var waitMore = ''
	if( !RZwinaccess(win) )
	{
		waitMore = 'no access'
		RZ.waitaccess = 0
	}
	else
	{	// see debugger notes this function description for onerror handling
		if (window.onerror != RZwaitError)
			RZ.waitonerror = window.onerror
		window.onerror = RZwaitError

		//simulate race error one time as described in debugger notes above
		RZ.waitaccess++
		//if (RZ.waitaccess <= 1 && RZ.error.force) RZ.waitaccess = 99

		// if window reloading, RZ.loaded first set to null
		if (typeof win.RZ != 'undefined' && win.RZ != null
		&& typeof win.RZ.loaded != 'undefined' && win.RZ.loaded != true)
			waitMore = 'refresh pending'

		// window name undefined until window loaded (at least on IE)
		else if (typeof win.name == 'undefined')
			waitMore = 'window loading'

		// if window name is not blank, assume window loaded
		// (recognizes non-revize enabled pages especially frames)
		else if (win.name != '')
			waitMore = ''

		// RZ.loaded not defined until onload handler complete
		else if (typeof win.RZ == 'undefined' || win.RZ == null
		|| typeof win.RZ.loaded == 'undefined' || win.RZ.loaded != true)
			waitMore = 'onload pending'

		window.onerror = RZ.waitonerror		//restore original handler
	}

	var waitDone = false
	if (waitMore != '')
	{
		var waitedMsg = ' waited ' + parseInt(seconds) + ' seconds'
		RZtrace(waitMsg, waitedMsg )
		RZ.parent.status = waitMsg + ': ' +  waitedMsg + ' (' + waitMore + ')'
		if (seconds > maxSeconds )	//don't wait too long
			waitDone = true;		//waited long enough
	}
	if (waitMore=='' || waitDone)
	{
		RZ.waitcall = ''			//clear in case scheduled timeout starts
		clearTimeout( waitcallId )	//cancel scheduled waitCheck
		waitedMsg = 'waited ' + seconds + ' total seconds'
		RZtrace('RZwaitCheck(): ' + waitMsg, waitedMsg )
		if (!waitDone) RZ.parent.status = ''
		eval( waitCommand )
	}
}

/*---------------------------------------------------------------------------
Determine if opener properties are still accessible
(they will not be if window closed or moved to another url)

TODO: check access on NS (unknown)

The following is always false on Netscape:

if ( typeof RZ.popupwin.opener.document == 'unknown' )
----------------------------------------------------------------------------*/
function RZwinaccess(win)
{
	//default to opener for backward compatibility but all calls
	//now probably pass an argument.
	if (arguments.length == 0) win = RZ.parent.opener

	try
	{
		//TODO: gets interface error if calling window is closed
		if (typeof win == 'undefined' || win == 'undefined') return false

		if(win != null
		&& typeof win != 'undefined'
		&& win.closed != true
		&& win !='undefined')
		{
			if (RZ.MSIE && typeof win.document == 'unknown')
				return false;
			//force error if access denied
			else if (!RZ.MSIE && win.location.href == '')
				return false;
			else
				return true;
		}
	}
	catch (ex)
	{
		return false;
	}
	return false
}

/*---------------------------------------------------------------------------
Give focus to opener if still accessible.
----------------------------------------------------------------------------*/
function RZopenerFocus(win)
{
	if (RZ.refresh)
		RZ.refresh = false
	else
	{
      if (typeof win == 'undefined') win = RZ.parent.opener
		if (RZwinaccess(win)) win.focus()
	}
}

/*---------------------------------------------------------------------------
Display page permission warning defined by code.
----------------------------------------------------------------------------*/
function RZpagemessage(code,linkname,linkparent,linklevel)
{
	if (typeof linkname == 'undefined') linkname = ''
	if (typeof linkparent == 'undefined') linkparent = ''
	if (typeof linklevel == 'undefined') linklevel = ''

	var msg = ''
	var hash = '';

	switch ( code )
	{
		// button warning
		case "":
			break;

		// page permission icon appearing in upper left corner of page is clicked.
		case "noparent":
			msg += 'No parent defined for this PAGE'
			break;

		// link manager
		case "nolinkparentfield":
			msg += 'No linkparent field defined for this LINK'
			break;

		// link manager
		case "nolinkparent":
			msg += 'No parent defined for this LINK'
			break;

		// button warning
		case "nomodule":
			msg += 'Revize module not defined on button'
			break;

		// button warning
		case "parent_itself":
			msg += 'Page can not be a parent of itself \n(no longer true)'
			break;

		// unknown warning
		default:
			msg += 'Page permission incongruency'
			code = RZreplace(code,'--','\n')
			if (code.length > 25)
				msg += ':\n\n' + code
			else
				msg += ' (reason:' + code + ')'
			break;
	}

	RZ.message = ''
	RZ.parameters = ''
	if (linkname != '')
	{
		RZ.message += 'Link Information:\n\n'
		RZaddUrlParameter('Link Name: ' + linkname )
		RZaddUrlParameter('Link Module: ' + RZ.link[linkname].linkmodule )
		RZ.message += '\n'

		if (linkparent == '*nofield*')
			RZ.message += 'No linkparent field in linkmodule\n'
		else if (RZ.link[linkname].linkmodule != '')
			RZaddUrlParameter(RZ.link[linkname].linkmodule+'.linkparent: '+ linkparent)
		RZaddUrlParameter('First List Item Parent: '+ RZ.link[linkname].linkparent)

		if (linklevel != '')
		{
			RZ.message += '\n'
			RZaddUrlParameter('Link Level: '+ linklevel)
			if (typeof RZ.linkparentnew[linkname] != 'undefined')
				RZaddUrlParameter('Level '+linklevel+' new parent_key: '
				                 + RZ.linkparentnew[linkname][linklevel])
		}
	}
	else
	{
		RZ.message += 'Page Information:\n\n'
		var templateType = '(unique)'
		if (RZ.pagemodule != '') templateType = '(dependent)'
		RZaddUrlParameter('Template: ' + RZ.pagetemplatename + '  ' + templateType )
		if (RZ.pagemodule != '')
		{
			RZaddUrlParameter('Module: '    + RZ.pagemodule )
			RZaddUrlParameter('Record Id: ' + RZ.editrecordid )
			hash = '#' + RZ.pagemodule + "_" + RZ.editrecordid;
		}
		RZ.message += '\n'
		RZaddUrlParameter('page_key:     '   + RZ.page_key )
		RZaddUrlParameter('parent_key:  '   + RZ.parent_key )
		RZ.message += '\n'
		RZaddUrlParameter('Permitted roles: ' + RZ.page_roles )
		RZaddUrlParameter('Permitted users: ' + RZ.page_users )
		if (RZ.inherit_key != '')
			RZaddUrlParameter('Inherited from: ' + RZ.inherit_key )
	}
	RZ.message += '\n'
	RZaddUrlParameter('permissions_options: ' + RZ.permissions_options )

	if (msg != '')
	{
		msg =  '---------------------------------------------------\n' + msg + '\n'
		msg += '---------------------------------------------------\n\n'
	}
	msg += RZ.message + '\n'
	msg += '---------------------------------------------------\n'
	msg += 'Click Ok to find pages that link to this page      \n'
	msg += '---------------------------------------------------\n'

	if (confirm(msg))
		location.href = RZ.webspacelinksurl + hash
	return void(0)
}

/*---------------------------------------------------------------------------
Display and clear warning from jsp code
----------------------------------------------------------------------------*/
function RZwarning()
{
	if (RZ.warning != '')
	{
		window.status = RZreplaceAll( RZ.warning, '-- --', '; ')
		RZtrace( 'Warning from JSP code', RZ.warning )
		RZ.warning = ''
	}
}
/*---------------------------------------------------------------------------
Display alert or confirm dialog using RZalert (with prepended issue message)

By using RZalert, the javascript debugger can be started if in debug mode.

Parameters:
	message	- Message describing problem encounted with page
	isConfirm - Optional If true, confirm dialog is used (default is false)
----------------------------------------------------------------------------*/
function RZnote(message,isConfirm)
{
	var isNote = true
	return RZalert(message,isConfirm,isNote)
}
/*---------------------------------------------------------------------------
Display alert using confirm dialog

Parameters:
	message	- Message describing problem encounted with page
----------------------------------------------------------------------------*/
function RZconfirm(message)
{
	return RZalert(message,true)
}
/*---------------------------------------------------------------------------
Add message to trace window (including calling stack)

Display message in alert with prepended with notation that page has a problem

If RZ.debug is true, a confirm dialog is used with option to start the
JavaScript debugger.

Parameters:
	message	- Message describing problem encounted with page
	isConfirm - Optional If true, confirm dialog is used (default is false)
	isNote - If true, display message without warning
----------------------------------------------------------------------------*/
function RZalert(message,isConfirm,isNote)
{
  	if (typeof isNote == 'undefined') isNote = false;
  	if (typeof isConfirm == 'undefined') isConfirm = false;
  	if (typeof message == 'undefined' || typeof message == 'object')
  		message = 'Error Message is ' + typeof message
  	if (message == '')
  		message = 'No Error Details'

  	message = message.split('--').join('\n\n')

    var trace = message + '\n\n' + 'CALLED FROM: ...\n';

	if (typeof RZ.jsversion == 'undefined' || RZ.jsversion < 1.2)
		trace += '\ncaller trace requires IE 5.0 or Netscape 4.0 browser'
	else
	{
		for(var a = arguments.caller; a != null; a = a.caller)
		{
			funcName = a.callee.toString().match(/function (\w*)/)[1];
			if (funcName == null || funcName.length == 0) funcName = "anonymous"

			trace += funcName + "\n";
			if (a.caller == a) break;	//NS 4.0 bug workaround
		}
		trace += '-main html page-'
	}

	RZtrace('Alert: ', trace)
	if (!isNote)
	{
		message = 'This Revize page has the following problem:\n\n'
		        + message + '\n\n'
				+ 'Developers can enable trace with the URL below: \n'
				+ '          ' + RZ.page.domain + '/revize/trace/'
	}

	//----- Determine whether to prompt for debugger
	if (RZ.debug || RZ.trace)
	{
		if ( confirm(message + '\n\nStart Debugger?') ) RZstartDebugger();
	}

	//----- Always use confirm or alert to proceed
	if (isConfirm)
		return confirm(message)
	else
		alert(message)

	//----- Clear message - only works if message is called by reference
	//		which is unlikely calling scenario.
	message = ''
	return ''	//can be used to clear message
}

/*---------------------------------------------------------------------------
Resize window; if width or hieght not specified use available size

Parameters:
	width -		specifies requested window width (text or number)
	hieght -	specifies requested window hieght (text or number)
	justify -	Optional string; right or left to justify window respectively
	win -		Optional window object to specify window if not window/frame
				that includes the snippet_helper.js library file.
----------------------------------------------------------------------------*/
function RZresize(width,height,justify,win)
{
	if (!width) width = screen.availWidth;
	if (!height) height = screen.availHeight;
	if (!justify) justify = 'center'
	if (!win) win = window

	//DCO 08-03-2009
	//if (RZ.isnavigator) height -= 125		//TODO: for linkmanager ???

	var x = (screen.availWidth - width) / 2
	var y = (screen.availHeight - height) / 2
	if (justify == 'right')
		x = screen.availWidth - width - 10
	else if (justify == 'left')
		x = 0
	if (x < 0) x = 0
	if (y < 0) y = 0

	win.resizeTo(width,height);
	win.moveTo( x,y )
}
/*---------------------------------------------------------------------------
Write html if user is authenticated for current webspace (RZ.webspace).
During page initialization RZ.login is set to the RZlogin cookie defined by
the login function.
TODO: Do not write any html for production channels.

Parameters:
	html -			html code to be written if logged in and proper permission
	module -		Module requiring permissions
	permits -		Permissions required on module
	action -		Button action
----------------------------------------------------------------------------*/
function RZlogin( html, module, permits, action )
{
	// 2nd parameter was webspace way back and there was not a 3rd parameter
	// so defaulting permits to blank retains backward compatibility.
	if (typeof module == 'undefined') module = '';
	if (typeof permits == 'undefined') permits = '';
	if (typeof action == 'undefined') action = '';

	// backward compatibility
	if(typeof RZ.webspace == 'undefined'
	&& typeof RZ.webSpaceName != 'undefined')
		RZ.webspace = RZ.webSpaceName

	// if login webspace does not match page webspace, return false
	if(RZ.login != RZ.webspace && RZ.login != '*ALL')
		return false

	// if pointbasedemo webspace and NOT preview directory, return false
	if(RZ.webspace.indexOf('pointbasedemo') >= 0
	&& RZ.page.pathname.indexOf('-preview') == -1)
		return false;

	// if demosite webspace and production directory, return false
	if(RZ.webspace.indexOf('demosite') >= 0
	&& RZ.page.pathname.indexOf('-prod') != -1)
		return false;

	// if atwatercounty webspace and production directory, return false
	if(RZ.webspace.indexOf('atwatercounty') == 0
	&& RZ.page.pathname.indexOf('-prod') != -1)
		return false;

	// if paradigm webspace and production directory, return false
	if(RZ.webspace.indexOf('paradigm') == 0
	&& RZ.page.pathname.indexOf('-prod') != -1)
		return false;


	//----- If called with a module and required permits, check them.
	//		If no access, return false and do not write any html.
	if ( module != '' && permits != ''
	&& RZpermits(module , permits) != true )
		return false;


	//----- Hide button if no page permissions (TODO: hides what? seq?)
	if ( action != 'save' && action != 'cancel' && action != 'history')
		if ( !RZ.pagepermission && module != '' ) return false;


	if ( typeof html != 'undefined' && html != '')
		document.write(html);

	return true;
}
/*---------------------------------------------------------------------------
Display rendered width of element
----------------------------------------------------------------------------*/
function RZrte(id)
{
	if (!id) 
	{
		id=prompt('Enter element id',RZgetcookie('RZrte'));
		if (!id) return;
		RZsetcookie('RZrte',id);
	}
	var msg = '';
	var el = document.getElementById(id);
	if (!el) 
		msg = 'id='+id+' not found';
	else
	{
		msg += '\n    font-family=' + currentStyle('font-family') + ';';
		msg += '\n    font-size=' + currentStyle('font-size') + ';';
		while (el.clientWidth == 0 && el.parentNode)
			el = el.parentNode;
		var padding = parseInt(currentStyle('padding-left')) 
		            + parseInt(currentStyle('padding-right'));
		msg = '.rte-format {' + msg + '\n}'
			+ '\n\nwidth=' + el.clientWidth;
		if (padding > 0)
			msg += '\n\nwidth=' + (el.clientWidth - padding) + ' (less padding for RTE)';
	}
	alert(msg);
	return;
	
	function currentStyle(style)	//style is css format (e.g. font-size)
	{
		if (!document.defaultView)
		{
			style = style.replace(/(-)(\w)/, function (all,dash,word){
				return word.toUpperCase();
			})
			return el.currentStyle[style];
		}
		else
		{
			var renderedStyle = document.defaultView.getComputedStyle(el,'');
			return renderedStyle.getPropertyValue(style);
		}
	}
}
/*---------------------------------------------------------------------------
Toggle debug mode with prompt that includes optional notes argument.
----------------------------------------------------------------------------*/
function RZdebug(notes,win)
{
	if (typeof win == 'undefined') win = window;
	if (typeof notes == 'object')
	{
		win = notes;
		notes = '';
	}

	var debugState = !RZ.debug
	var msg = 'Set debug ' + debugState + '?'
	if (typeof notes != 'undefined')
		msg = notes + '\n\n' + msg
	if (win.confirm(msg))
		RZ.debug = debugState
	return void(0)
}
/*---------------------------------------------------------------------------
Prompt to start debugger with optional notes argument.
----------------------------------------------------------------------------*/
function RZdebugger(notes)
{
	var msg = 'Start Debugger?'
	if (typeof notes != 'undefined')
		msg = notes + '\n\n' + msg

	if (confirm(msg)) RZcallDebugger()

	return void(0)
}
/*---------------------------------------------------------------------------
Ask to start IE or Netscript Javascript debugger.
----------------------------------------------------------------------------*/
function RZstartDebugger()
{
	if (RZ.MSIE)
		RZcallDebugger()
	else
	{
		if (!confirm('Start debugger?')) return void(0)
		alert( 'Set breakpoint on following return statement in:\n'
		     + 'snippet_helper.js::RZstartDebugger()\n\n'
		     + 'When debugger then appears after displaying this statement,\n'
		     + 'Click on Out button once or twice to see calling statement')
	}
	return void(0)
}
if (RZ.css)		//the debugger statement causes syntax error in NS (include does not work for Firefox)
	document.write('<script language="JavaScript" type="text/JavaScript" src="/revize/util/debugger_ie.js"></'+'script>')
/*---------------------------------------------------------------------------
Load Color Picker.
----------------------------------------------------------------------------*/
function RZcolorpicker(field)
{
	RZ.colorfield = field;
	while (RZ.colorfield.tagName != 'INPUT')
	{
		RZ.colorfield = RZ.colorfield.previousSibling
		if (RZ.colorfield == null || typeof RZ.colorfield == 'undefined')
		{
			RZalert('Input field does not preceed Color Picker Icon')
			return false;
		}
	}
	features = 'width=320,height=160,scroll=auto,status=no,titlebar=no,resizable=yes';
	var x = (screen.availWidth - 320) / 2 - 10;
	var y = (screen.availHeight - 160) / 2 - 30;
	if (y < 50)
		y = 0;

	if(navigator.appVersion.indexOf('MSIE') == -1)  // Netscape
	{
		features += ',screenX=' + x.toString()
				 +  ',screenY=' + y.toString();
	}
	else                                            // IE browser
	{
		features += ',left=' + x.toString()
				 +  ',top=' + y.toString();
	}
	colorPicker = window.open('/revize/util/snippet_helper_colorpicker.html','',features);
	return true;
}
/*---------------------------------------------------------------------------
Load Color Picker.
----------------------------------------------------------------------------*/
function RZspellcheck(field)
{
	RZ.spellcheckfield = field;
	while (RZ.spellcheckfield.tagName != 'INPUT'
	&& RZ.spellcheckfield.tagName != 'TEXTAREA')
	{
		RZ.spellcheckfield = RZ.spellcheckfield.previousSibling
		if (RZ.spellcheckfield == null || typeof RZ.spellcheckfield == 'undefined')
		{
			RZalert('Input field does not preceed Spell Check Icon')
			return false;
		}
	}

	var sURL = "/revize/spellcheck/spellingchecker.html";

	features = 'width=490,height=400,scroll=auto,status=yes,resizable=yes,'
	         + 'titlebar=yes,menubar=no,location=no,'
	         + 'channelmode=0,directories=0,fullscreen=0,center=1'

	RZspellcheckwin = window.open(sURL,'_blank',features);
	return true;
}
/************************* End of snippet_helper.js *************************/