/*****     snippet_helper.js
           ___________________________________________________
          |                                                   |
          | JavaScript Library used on most Revize pages      |
          |                                                   |
          | Copyright (C) 2000-2003 Idetix Incorporated       |
          | All rights reserved.                              |
          |                                                   |
          |___________________________________________________|

           $Revision:   1.90  $
           $Date:   24 Nov 2003 07:09:10  $
           $Author:   daveotto  $
*****/
/****************************************************************************
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.lastset	Argument passing capability between templates and edit forms
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.lastset == 'undefined') RZ.lastset = 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

// 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.
----------------------------------------------------------------------------*/
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
****************************************************************************/

/*---------------------------------------------------------------------------
Set page information and display in trace window
----------------------------------------------------------------------------*/
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'
	}

	//----- Parent window if accessable (otherwise current window)
	//		Note: RZwinaccess() may require browser settings in future
	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.location.href + '\n'
		if (RZ.parent.name != '')
			RZ.message += 'opener.name: ' + RZ.parent.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)

	//----- 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()' )
	}
}
/*---------------------------------------------------------------------------
Called when leaving page.
----------------------------------------------------------------------------*/
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
}
/*---------------------------------------------------------------------------
Check for value on current window, opener, referrer hash and associated cookie
----------------------------------------------------------------------------*/
function RZcheckHash(value)
{
	var key = false
	if( (RZwinaccess(window.top) && 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
}
/*---------------------------------------------------------------------------
Sets final variables based on page type
----------------------------------------------------------------------------*/
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','')
		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()' )
		}

		//----- 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()' )
	}
}
/*---------------------------------------------------------------------------
Runs after page is loaded to position page on revize save hash
----------------------------------------------------------------------------*/
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;
}
/*---------------------------------------------------------------------------
Displays stack trace(s) from rz.setup() NOT YET USED
----------------------------------------------------------------------------*/
function RZprintStackTrace(msg)
{
	RZ.tracewin = RZpopupUrl('RevizeTrace');
	var msg = '<pre>' + msg + '</pre>'
	RZ.tracewin.document.write(msg);
}
/*---------------------------------------------------------------------------
Called to process bad links
----------------------------------------------------------------------------*/
function RZbadlink(module,recordid,url)
{
}
/*---------------------------------------------------------------------------
Displays page permissions warning on templates. NOT COMPLETED
Called as onload handler only if warning are active and user is logged in
----------------------------------------------------------------------------*/
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])

}
/*---------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------*/
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] )
}
/*---------------------------------------------------------------------------
Displays page permissions warning on templates.
Called as onload handler only if warning are active and user is 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";
		}
	}
}
/*---------------------------------------------------------------------------
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)

Input Argumments:
	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://)

Example return values:
	page.domain     = 'http://localhost:8080'		//no trailing /
	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 )
{ return RZgetfileinfo( pathname, options ) }
function RZgetfileinfo( pathname, options )
{
	var pos,idx
	var href=''
	var domain=''
	var filename=''
	var sep=''
	var extension=''
	var query=''
	var hash=''
	var home=''
	if (typeof options == 'undefined')
		options = '';
	else
		options += ','
	if (typeof pathname == 'undefined') 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
		pos = pathname.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
	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
----------------------------------------------------------------------------*/
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
----------------------------------------------------------------------------*/
function RZisvisible(layerName,doc)
{
	if (typeof doc == 'undefined') doc = document
	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 (doc.all)								//ie
	{
		if(typeof doc.all[layerName] != 'undefined'
		&& doc.all[layerName].style.visibility == 'visible') status = true
	}

	return status;
}
/*---------------------------------------------------------------------------
Does layer exist?
----------------------------------------------------------------------------*/
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 (doc.all)								//ie
	{
		if(typeof doc.all[layerName] == 'undefined') return false
	}
	return true
}
/*---------------------------------------------------------------------------
Show or hide a layer based on browser type
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
----------------------------------------------------------------------------*/
function RZshowlayer(layerName,trueFalse,doc)
{
	//----- Netscape 4 loses layers if page was resized so leave layer visible
	if (RZ.isnavigator
	&& RZ.isnavigatorLayers == true
	&& document.layers.length == 0) return

	if (typeof doc == 'undefined') doc = document

	//----- 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 (doc.all)								//ie
	{
		if(typeof doc.all[layerName] == 'undefined')
		{
			msg += 'IE 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 (doc.all)									//ie
		{
			doc.all[layerName].style.visibility = 'visible';
			doc.all[layerName].style.zIndex = 100;
		}
    }
    else 					// hide layer
    {
		if (doc.layers && doc.layers[layerName])			//ns
			doc.layers[layerName].visibility = 'hidden';
		else if (doc.all)									//ie
			doc.all[layerName].style.visibility = 'hidden';
	}
}
/*---------------------------------------------------------------------------
Set Cookie value
----------------------------------------------------------------------------*/
function RZsetCookieValue( key, value )
{
	RZsetcookie( key, value )
}
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 )
}
/*---------------------------------------------------------------------------
Get Cookie value

Arguments:
---------
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 RZgetCookieValue( key, qualifier )
{
	return RZgetcookie( key, 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 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.  The

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).

TODO: Look up all module permissions, store in future control_panel window
----------------------------------------------------------------------------*/
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;
}
/*---------------------------------------------------------------------------
Description:
	Implements 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.

Input Arguments (passed via global RZ object):
	RZ.module, RZ.recordid, RZ.nexturl,
	RZ.popupwidth, RZ.popupheight, RZ.popupscroll
	RZ.img or RZ.caption (image button used if RZ.img not blank)
	RZ.tagname (if non-blank specified form button name)
----------------------------------------------------------------------------*/
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 + "' );"
			break;


		//----- Common code for all new and edit actions
		case "new":
		case "newitem":
		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')
				{
					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 + "',"
				       + "'" + RZ.linklevel + "',"
				       + "'" + 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 "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
	var active = RZ.active;
	if (active == '')
		active = RZlogin( html, requiredModule, requiredPermits, action );
	else if (active && active != 'false')	//non-blank values test as 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'
}
/*---------------------------------------------------------------------------
Reset action arguments.  Called at beginning of page and after arguments are
used.  This ensures values from one call are not carried forward to the next
call.
----------------------------------------------------------------------------*/
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.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 this pages revize path as starting point.
----------------------------------------------------------------------------*/
function RZabsoluteUrl(url)
{
	if (url != '')
	{
		if ( !RZisAbsoluteUrl(url) )
		{
			if(url.substring(0,4) == 'www.')
				url = 'http://'+url;
			else
				url = RZ.page.domain + RZ.page.pathname + '/' + url
		}
	}
	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 )
}
/*---------------------------------------------------------------------------
Call EDIT LIST page
----------------------------------------------------------------------------*/
function RZcallEditList( editPageUrl )
{return RZcalleditlist( editPageUrl )}
function RZcalleditlist( editPageUrl )
{
	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 )
	RZaddUrlParameter( 'permissions_template=' + RZ.pagetemplatename )
	RZaddUrlParameter( 'permissions_parent=' + RZ.page_key )

	RZsaveReturnUrl( 'RZeditListReturnUrl' )

	RZtrace("Calling Edit List", RZ.message )
	document.location = RZ.parameters

	return void(0)
}
/*---------------------------------------------------------------------------
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
}
/*---------------------------------------------------------------------------
Call EDIT FORM page (work horse - called by code generated by RZaction)
----------------------------------------------------------------------------*/
function RZcallEditForm( recordid, editPageUrl, width,height,scroll, set )
{
	return RZedit( recordid, editPageUrl, width,height,scroll, set )
}
function RZcalleditform( recordid, editPageUrl, width,height,scroll, set,
	module, field, linkname)
{
	return RZedit( recordid, editPageUrl, width,height,scroll, set)
}
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 )
	if (RZ.MSIE && url != '' && !RZisAbsoluteUrl(url)
	&& typeof RZ.baseurlprefix != 'undefined' && RZ.baseurlprefix.length > 0)
		url = RZ.baseurlprefix + url

	//----- Append edit parameters
	if (linkname == '')
	{
		RZ.message = ''
		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
				//RZaddUrlParameter( 'permissions_template=' + RZ.pagetemplatename )
			}
			// Always pass parent_key in case the edit form adds links via the RTE.
			if (RZ.pagetype == 'template')
				RZaddUrlParameter( 'permissions_parent=' + RZ.page_key )
			else
				RZaddUrlParameter( 'permissions_parent=' + RZ.permissions_parent )
		}

		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 button is not configured to properly pass page permissions\n'
				+ 'to the page created or associated with this link.\n\n'
				+ '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
	}

	RZtrace("Calling Edit Form", "URL: " + url )

	//----- Call popup window if requested else goto Edit Page URL
	RZ.editWindow = RZpopupUrl( 'EditWindow', url, width, height, scroll)
	if ( RZ.editWindow == null )
	{
		RZsaveReturnUrl( 'RZeditFormReturnUrl' )
		document.location = url
	}

	//----- Suspend processing if called as submit
	return void(0);
}
/*---------------------------------------------------------------------------
----------------------------------------------------------------------------*/
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)
}
/*---------------------------------------------------------------------------
Display message regarding button configuration issue
----------------------------------------------------------------------------*/
function RZiconMessage(action,index)
{
	module = RZ.icons[index]
	var msg = RZpermissionWarning(action,'',module)
	if (msg != '')
		if (!RZconfirm(msg)) return
}
/*---------------------------------------------------------------------------
Format a permission warning message if button not configured correctly
----------------------------------------------------------------------------*/
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
}
/*---------------------------------------------------------------------------
Sets general edit url parameters used with or w/o link manager.
----------------------------------------------------------------------------*/
function RZsetEditParameters(module,field,set)
{
	RZ.parameters = ''

	//----- Append webspace parameter
	RZaddUrlParameter( 'webspace=' + RZ.webspace )

	//----- Append module & field
	if (module!='')
		RZaddUrlParameter( 'module=' + module )	//used by link manager
	if (field!='')
		RZaddUrlParameter( 'field=' + field )		//future

	//----- Append set parameters
	if (set != '')
	{
		set = set.split('pagerecord._recordid').join( RZ.editrecordid )
		RZaddUrlParameter( 'set=' + escape(set) )
	}
}
/*---------------------------------------------------------------------------
Sets recordid parameter used with or w/o link manager.
----------------------------------------------------------------------------*/
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
}
/*---------------------------------------------------------------------------
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.
----------------------------------------------------------------------------*/
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

	//----- 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 = 225 		// 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)
}
/*---------------------------------------------------------------------------
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)
----------------------------------------------------------------------------*/
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 = ''

	//----- 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();
}
/*---------------------------------------------------------------------------
Call RZdefaultLinkOption then add to RZ.parameters
----------------------------------------------------------------------------*/
function RZdefaultLinkParameter(linkname,property)
{
	RZdefaultLinkOption(linkname,property)
	RZsetLinkUrlParameter(linkname,property)
}
/*---------------------------------------------------------------------------
If property is undefined, set to blank
----------------------------------------------------------------------------*/
function RZdefaultLinkOption(linkname,property)
{
	if (typeof RZ.link[linkname][property] == 'undefined')
		RZ.link[linkname][property] = ''

	//RZtrace('RZdefaultLinkOption('+linkname+'):' + property
	//       + '<br>-->' +(RZ.link[linkname][property])+ '<--')
}
/*---------------------------------------------------------------------------
Build link manager url parameters using link properties presumably defined
elsewhere on the page if property is defined and not blank.
----------------------------------------------------------------------------*/
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
----------------------------------------------------------------------------*/
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'
}
/*---------------------------------------------------------------------------
Return back to calling page

If returnUrlKey ends with a semicolon, assume it is an expression for url

Otherwise, return to PRIOR PAGE using the following steps
	1. If URL defined in cookie, use it (returnUrlKey specifies cookie name)
	2. If not edit list page, use history
	3. If RZ.page.home is not blank, use it
	4. Make trace entry and stay on current page
----------------------------------------------------------------------------*/
function RZpriorPage(returnUrlKey) { RZback(returnUrlKey) }
function RZback(returnUrlKey)
{
	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 != '')
		document.location = returnUrl
	else
		RZtrace('snipper_helper: RZback('+returnUrlKey+')',
				'No Prior URL could be determined')
}
/*---------------------------------------------------------------------------
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 )
{
	if (typeof nextUrl == 'undefined') nextUrl = 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))
	{
		alert( 'Invalid Record Id: ' + recordID )
		return void(0)
	}
	else if (recordID=='')
	{
		alert( 'Record Not Specified (Id is Blank)' )
		return void(0)
	}
	if (!confirm("Klicka på OK för att ta bort")) 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 +
					"&modulename=" + moduleName +
					"&redirect=" + escape(RZabsoluteUrl(nextUrl));
	RZtrace( "Delete Item Request", deleteUrl );
	RZactionReset();
	document.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 )
	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, 400, 400, 'yes')
}
/*------------------------------------------------------------------------------
Remove any leading or ending blank spaces from string
------------------------------------------------------------------------------*/
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)
------------------------------------------------------------------------------*/
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

Input Arguments
===============
	str			Input string
	startpos	Starting position
	endpos		Ending position (optional)

------------------------------------------------------------------------------*/
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

Example: right("1234",2) returns "34"
         right("1234",0) returns ""
         right("0",4) returns "0"
----------------------------------------------------------------------------*/
function RZright( str, noChars )
{
	var len = str.length;
	if (len == 0) return "";

	if (noChars > len) noChars = len;
	return str.substring(len-noChars);
}
/*---------------------------------------------------------------------------------------------
this function converts number to the nearest integer
0 is returned if not a valid number unless a defaultValue is supplied
---------------------------------------------------------------------------------------------*/
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
}
/*---------------------------------------------------------------------------------------------
Look for specific option choice(s) in the options string.

Input Arguments:
	pOptions	String of options to be checked
	pChoices	One of more choices to check separated by comma

Returns
	true		if at least one of the choices found in the options

**NOTE** copy and converted from RZTagSupport but not yes tested
---------------------------------------------------------------------------------------------*/
function RZcheckoptions( pOptions, pChoices )
{
	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;
}
/*---------------------------------------------------------------------------
Looks for a key=value in the options string and returns the value portion.
(clone of getValue in RZTabSupport)

Input Arguments:
	options		String searched for key=value
	key			Key to find in options string

Returns	the 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]
}
/*---------------------------------------------------------------------------
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.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

	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
}
/*---------------------------------------------------------------------------------------------
RZwaitCheck
-----------
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

Debugger 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

	//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
	&& typeof win.document != 'unknown'	//if access denied on IE (not sure for NS)
	&& win !='undefined')
		return true
	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 using confirm
----------------------------------------------------------------------------*/
function RZconfirm(message)
{
	return RZalert(message,true)
}
/*---------------------------------------------------------------------------
Send alert & trace message
----------------------------------------------------------------------------*/
function RZalert(message,isConfirm)
{
  	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)
	message = 'This Revize ' + RZ.pagetype + ' 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 user alert or confirm
	if (RZ.debug == false && RZ.trace == false)
	{
		if (isConfirm)
			return confirm(message)
		else
			alert(message)
	}
	else if ( confirm(message + '\n\nEnter Debug Mode?') )
		RZstartDebugger()

	//----- 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 respectively
----------------------------------------------------------------------------*/
function RZresize(width,height,justify,win)
{
	if (typeof width == 'undefined' || width=='') width = screen.availWidth;
	if (typeof height == 'undefined' || height=='') height = screen.availHeight;
	if (typeof justify == 'undefined') justify = 'center'
	if (typeof win == 'undefined') win = window

	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 html for production channels.

Input 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;
}
/*---------------------------------------------------------------------------
Toggle debug mode with prompt that includes optional notes argument.
----------------------------------------------------------------------------*/
function RZdebug(notes)
{
	var debugState = !RZ.debug
	var msg = 'Set debug ' + debugState + '?'
	if (typeof notes != 'undefined')
		msg = notes + '\n\n' + msg
	if (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.MSIE)		//the debugger statement causes syntax error in NS
	document.write('<script language="JavaScript" type="text/JavaScript" src="/revize/util/debugger_ie.js"></'+'script>')
/************************* End of snippet_helper.js *************************/
