// ***********************************************************************
//
// main.js
//
// Copyright 2008 Optodesign, inc.
//
// Library of Javascript routines for Newman Architects.
//
//		initpage 		-- initializes javascript handling for the page
//		closepage 		-- Executes any closing code when the page is unloaded.
// 		genpopup		-- Displays a popup window, returns handle
//		closepopup		-- Closes the current popup window and passes focus back to parent
//
// 		displayoff		-- Hides the incoming layer
// 		displayon		-- Displays the incoming layer
// 		menumouseout	-- Hides the menu layers if the user moves out of the menu area
// 		getElementPos 	-- returns the absolute position of an HTML element
//		showmenu		-- hides all cat 3 divs and then shows the incoming one
// 		showpopup 		-- Shows a popup nav div
//		popupsoff 		-- turns off all popup divs
//		lockpopup 		-- shows and locks a popup nav div so that it is never hidden
//
// 		removeoptions 	-- removes all options from a dropdown list
// 		addoption 		-- adds an option to a dropdown list
//
//		getfieldobj 	-- takes in a field and form name and returns the object reference.  Browser independant.
//		getradioarray 	-- takes in a radio button and form name and returns the radio array.  Browser independant.
//		validtext 		-- returns true if a text field is not empty, or longer than
//		validnumber 	-- returns true if a text field is not empty, or longer than
//		validdate 		-- returns true if a text field contains a valid date.  Displays a popup error message
//		validemail 		-- returns true if a text field contains a valid email address.  Displays a popup error message
// 		validateform 	-- Shell function that calls the function in "validatefunction" and passes
//		wordcount		-- returns true if a text field is not longer than
//
// 		showpreview 	-- Shell function that calls the function in "previewfunction" and passes
// 		shownextimageset -- reloads the current section page with the next 4 images as
//
	// Debugging variables

var debug = false;

if ( debug ) {
	alert( "In main.js" );
}


	//
	// Constants
	//

	// Nav poup constants

var NAVPROJECT 		= 'navproject';
var NAVPRACTICE		= 'navpractice';
var NAVNEWS			= 'navnews';
var NAVCONTACT		= 'navcontact';
var NAVSUBPROJECT1	= 'navsubproject1';
var NAVSUBPROJECT2	= 'navsubproject2';
var NAVSUBNEWS1		= 'navsubnews1';

	// Browser sniffer constants

var STANDARD	= document.getElementById ? true : false;
var IE4			= document.all ? true : false;
var NS4			= document.layers ? true : false;

	//
	// Globals
	//

var lockeddiv		= "";
var lockedpopups	= false;
var popupwindow		= null;

	// Page handling routines

var	loadstring			= "";		// Set by enterKeyHandler
var	unloadstring		= "";		// Set by enterKeyHandler
var	keypressstr			= "";		// Set by enterKeyHandler

var usedefbtn			= false;
var deffield			= "";
var	jscommand			= "";		// Set this to any load command you wish to run
var	exitjscommand		= "";		// Set this to any unload command you wish to run

var validationfunction	= "";		// Set this to the validation function for an Admin form
var deleteconfirmmsg	= "Are you sure?";		// Override this for custom delete messages

var previewfunction		= "";		// Set this to the preview function for an Admin form

	// project arrays

var nmsections	= new Array();
var projects	= new Array();

var numimages	= 4;

	//
	// Functions
	//



//
//	initpage -- initializes javascript handling for the page
//
//	This function performs several important tasks:
//		-- It sets the focus if a default field has been defined
//		-- It sets the functions to be executed when the page loads
// and unloads
//		-- It sets which form should be submitted when the enter key
// is pressed
//
// This function is called for every page loaded by the Newman template.  Included
// code should set the global variables above so that it will properly
// execute.
//
function initpage() {
	var debug	= false;

	if ( debug ) {
		alert( "In initpage" );
	}

		// Execute any load command

	if ( jscommand != "" ) {
		try {
			eval( jscommand );
		} catch ( err ) {
		}
	}

		// Set the default button action

	if (( usedefbtn ) && ( defbutton != "" )) {
		if ( debug ) {
			alert( "defbutton = [" + defbutton + "]" );
		}

			// Set to capture the ENTER key

		if ( STANDARD ) {
			document.onkeypress=showOnIEEnter;
		} else if ( IE4 ) {
			document.onkeypress=showOnIEEnter;	// ???
		} else if ( NS4 ) {
			document.captureEvents( Event.KEYDOWN );
			document.onkeydown=showOnEnter;
		}

			// Set the focus to the button

		if ( STANDARD ) {
			if ( document.getElementById( defbutton )) {
				document.getElementById( defbutton ).focus();
			}
		} else if ( IE4 ) {
			eval( "document.all." + defbutton ).focus();
		} else if ( NS4 ) {
			eval( "document.form." + defbutton ).focus();
		}

		if ( debug ) {
			alert( "Done setting default button" );
		}
	}

		// Set the focus to the first field on the form.
		// note that we must set the defbutton first?

	if ( deffield != "" ) {
		if ( debug ) {
			alert( "deffield = [" + deffield + "]" );
		}


		if ( STANDARD ) {
			document.getElementById( deffield ).focus();
			if ( document.getElementById( deffield ).type != "select-one" ) {
				document.getElementById( deffield ).select();
			}
		} else if ( IE4 ) {
			eval( "document.all." + deffield ).focus();
			if ( eval( "document.all." + deffield ).type != "select-one" ) {
				eval( "document.all." + deffield ).select();
			}
		} else if ( NS4 ) {
			eval( "document.form." + deffield ).focus();
			if ( eval( "document.form." + deffield ).type != "select-one" ) {
				eval( "document.form." + deffield ).select();
			}
		}

		if ( debug ) {
			alert( "Done setting field focus" );
		}
	}

	if ( debug ) {
		alert( "Done initpage" );
	}

}



//
// closepage -- Executes any closing code when the page is unloaded.
//
function closepage() {
	var debug =	false;

	if ( debug ) {
		alert( "In closepage" );
	}

	if ( exitjscommand != "" ) {
		if ( debug ) {
			alert( "exitjscommand = [" + exitjscommand + "]" );
		}

		eval( exitjscommand );

		if ( debug ) {
			alert( "Done exitjscommand" );
		}
	}

	if ( debug ) {
		alert( "Done closepage" );
	}
}



//
//  genpopup	-- Displays a popup window, returns handle
//
// This routine displays a popup window.  It can be called to create a fixed
// position window, or to automatically position and size the window either
// vertically, horizontally, or both.  It also can create either fixed size
// or scrollable/moveable windows.
//
// Parameters:
//	urlstr		-- URL to show in window
//	name		-- Name for this window, can be used to control it
//	usecenter	-- String, not empty to auto-center/auto-size the window
//	showscroll	-- String, not empty to show scroll bars and allow sizing
//	left		-- Left position of window, zero to use centering
//	top			-- Top position of window.  zero to use centering
//	width		-- Width of window, zero to use near-fullsize
//	height		-- Height of window, zero to use near-fullsize
//	recycle		-- TRUE to use the last opened popup, if any
//
//	If usecenter is FALSE, then the top, left, width & height values are used
// as is.  If usecenter is TRUE, then the top, left, width & height values are
// used or calculated as needed.
//
//	Setting top or left to 0 with usecenter TRUE will let the code decide the
// actual position of top or left.  Setting width or height to 0 with usecenter
// TRUE will let the code decide the actual size of the window.
//
function genpopup( urlstr, name, usecenter, showscroll, left, top, width, height, recycle ) {
	var debug	= false;
	var retval	= -1;

		// Trace parameters

	if ( debug ) {
		alert( "In genpopup:\n" +
				"urlstr = [" + urlstr + "]\n" +
				"name = [" + name + "]\n" +
				"usecenter = [" + usecenter + "]\n" +
				"showscroll = [" + showscroll + "]\n" +
				"top = [" + top + "]\n" +
				"left = [" + left + "]\n" +
				"width = [" + width + "]\n" +
				"height = [" + height + "]\n" );
	}


	if ( recycle == undefined ) {
		recycle = true;
	}

		// Calculate size and positions if needed

	if ( usecenter ) {

		var RIGHTOFFSET		= 10;
		var BOTTOMOFFSET	= 25;
		var vertmargin		= 20;
		var vertoffset		= vertmargin / 2;
		var horizmargin		= 20;
		var horizoffset		= horizmargin / 2;

			// Check for auto size & position

		if ( top == 0 ) {
			if ( height == 0 ) {
				top		= vertoffset;
				height	= window.screen.availHeight - vertmargin - BOTTOMOFFSET;
			} else {
				top		= ( window.screen.availHeight - height ) / 2;
			}
		} else if ( height == 0 ) {
			height	= window.screen.availHeight - ( top * 2 ) - BOTTOMOFFSET;
		}

		if ( left == 0 ) {
			if ( width == 0 ) {
				left	= horizoffset;
				width	= window.screen.availWidth - horizmargin - RIGHTOFFSET;
			} else {
				left	= ( window.screen.availWidth - width ) / 2;
			}
		} else if ( width == 0 ) {
			width	= window.screen.availWidth - ( left * 2 ) - RIGHTOFFSET;
		}
	}

		// Set the properties string to open with

	var settingsstr	= "top=" + top + "," +
						"left=" + left + "," +
						"height=" + height + "," +
						"width=" + width + "," +
						"toolbar=no," +
						"location=no," +
						"directories=no," +
						"status=no," +
						"menubar=no,";

	if ( showscroll ) {
		settingsstr += "scrollbars=yes," +
						"resizable=yes";
	} else {
		settingsstr += "scrollbars=no," +
						"resizable=yes";
	}

	if ( debug ) {
		alert( "window.screen.availWidth = [" + window.screen.availWidth + "]\n" +
			"window.screen.availHeight = [" + window.screen.availHeight + "]" );
		alert( "settingsstr = [" + settingsstr + "]" );
	}

	if ( recycle ) {
		var oldwin	= window.open( "", name );
		if ( oldwin ) {
			oldwin.close();
		}
	}
	retval	= window.open( urlstr, name, settingsstr );

	if ( debug ) {
		alert( "retval = [" + retval + "]" );
		alert( "Done genpopup" );
	}

	return retval;
}



//
// closepopup		-- Closes the current popup window and passes focus back to parent
//
function closepopup() {
	var debug	= false;

	if ( debug ) {
		alert( "In closepopup" );
	}

	var parent	= window.opener;
	if ( parent ) {
		if ( parent.popupcallback ) {
			parent.popupcallback();
		}
		parent.focus();
	}

	if ( debug ) {
		alert( "Done closepopup" );
	}
	self.close();

}


	// *********************************************************************
	//
	// Div/Layer display routines
	//
	// *********************************************************************



//
// displayoff -- Hides the incoming layer
//
function displayoff( id ) {
	var debug	= false;

	if ( debug ) {
		alert( "In displayoff, id = [" + id + "]" );
	}

	if ( id != null ) {

			// Make it hidden

		if ( STANDARD ) {
			document.getElementById( id ).style.visibility = "hidden";
			document.getElementById( id ).style.zIndex = 1;
		} else if ( IE4 ) {
			eval( "document.all." + id ).style.visibility = "hidden";
		} else if ( NS4 ) {
			eval( "document." + id ).visibility = "hidden";
		}
	}
}



//
// displayon -- Displays the incoming layer
//
function displayon( id ) {
	var debug	= false;

	if ( debug ) {
		alert( "In displayon, id = [" + id + "]" );
	}

	if ( id != null ) {

			// Make it visible

		if ( STANDARD ) {
			document.getElementById( id ).style.visibility = "visible";
			// document.getElementById( id ).style.zIndex = 3;
		} else if ( IE4 ) {
			eval( "document.all." + id ).style.visibility = "visible";
		} else if ( NS4 ) {
			eval( "document." + id ).visibility = "visible";
		}
	}
	if ( debug ) {
		alert( "Done showing layer" );
	}
}


//
// menumouseout	-- Hides the menu layers if the user moves out of the menu area
//
function menumouseout( e, popupid, navbarid ) {
	var debug	= false;

	if ( debug ) {
		alert( "In menumouseout:\n" +
				"e = [" + e + "]\n" +
				"popupid = [" + popupid + "]\n" +
				"navbarid = [" + navbarid + "]\n" +
				"" );
	}

	if ( !e ) {
		if ( debug ) {
			alert( "e not defined" );
		}
		e = window.event;
	}

		// Get the current coords

	var x;
	var y;
	if ( e.pageX || e.pageY ) {
		x	= e.pageX;
		y	= e.pageY;
	} else if ( e.clientX || e.clientY ) {
		x	= e.clientX;
		y	= e.clientY;
	}

		// Get the popup div dimensions

	var popupdiv	= document.getElementById( popupid );
	var popuppos	= getElementPos( popupid );

		// Get the navbar dimensions

	var navbardiv	= document.getElementById( navbarid );
	var navbarpos	= getElementPos( navbarid );

		// Build the bounding area for the mouse

	var mousebounds		= popuppos;
	mousebounds.bottom	= navbarpos.bottom;

		// Check if we are in the Projects or News popups and the flyouts
		// are visible

	if ((( popupid == NAVPROJECT )
				|| ( popupid == NAVNEWS ))
			&& (( document.getElementById( NAVSUBPROJECT1 ).style.visibility == "visible" )
				|| ( document.getElementById( NAVSUBPROJECT2 ).style.visibility == "visible" )
				|| ( document.getElementById( NAVSUBNEWS1 ).style.visibility == "visible" ))) {

		if ( debug ) {
			alert( "Expanding right edge for sub project popup" );
		}

		var subpopupdiv	= mousebounds;

		if ( document.getElementById( NAVSUBPROJECT1 ).style.visibility == "visible" ) {
			subpopupdiv	= getElementPos( NAVSUBPROJECT1 );
		} else if ( document.getElementById( NAVSUBPROJECT2 ).style.visibility == "visible" ) {
			subpopupdiv	= getElementPos( NAVSUBPROJECT2 );
		} else if ( document.getElementById( NAVSUBNEWS1 ).style.visibility == "visible" ) {
			subpopupdiv	= getElementPos( NAVSUBNEWS1 );
		}
		mousebounds.right	= subpopupdiv.right;

	}

	if ( debug ) {
		alert( "mousebounds.left = [" + mousebounds.left + "]\n" +
				"mousebounds.right = [" + mousebounds.right + "]\n" +
				"mousebounds.top = [" + mousebounds.top + "]\n" +
				"mousebounds.bottom = [" + mousebounds.bottom + "]\n" +
				"" );
	}

		// Check if we are out of the bounding area

	if ( debug ) {
		alert( "x = [" + x + "]\n" +
				"y = [" + y + "]\n" +
				"" );
	}

	if (( y <= ( mousebounds.top ))
			|| ( y >= ( mousebounds.bottom ))
			|| ( x <= ( mousebounds.left ))
			|| ( x >= ( mousebounds.right ))) {

			// Turn off popup if out of bounds

		if ( debug ) {
			alert( "Mouse out of bounds" );
		}
		popupsoff();

			// Turn on the locked div

		if ( lockeddiv != "" ) {
			displayon( lockeddiv );
		}

	}

}


//
// getElementPos -- returns the absolute position of an HTML element
//
function getElementPos( elemID ) {

		// Get the incoming child element

	var offsetTrail	= document.getElementById( elemID );

		// Get the height and width of the element

	var height	= offsetTrail.offsetHeight;
	var width	= offsetTrail.offsetWidth;

		// Walk back up to the top level parent

	var offsetLeft	= 0;
	var offsetTop	= 0;
	while ( offsetTrail ) {
		offsetLeft	+= offsetTrail.offsetLeft;
		offsetTop	+= offsetTrail.offsetTop;
		offsetTrail	= offsetTrail.offsetParent;
	}

		// Catch differences for Mac

	if ( navigator.userAgent.indexOf( 'Mac' ) != -1
			&& typeof document.body.leftMargin != 'undefined' ) {
		offsetLeft	+= document.body.leftMargin;
		offsetTop	+= document.body.topMargin;
	}

	return {
		left:	offsetLeft,
		top:	offsetTop,
		right:	( offsetLeft + width ),
		bottom:	( offsetTop + height )
	};
}


//
// showmenu -- hides all cat 3 divs and then shows the incoming one
//
function showmenu( linkid, curid, showid ) {
	var debug	= false;

	if ( debug ) {
		alert( "In showmenu:\n" +
				"linkid = [" + linkid + "]\n" +
				"curid = [" + curid + "]\n" +
				"showid = [" + showid + "]\n" +
				"" );
	}

		// Set style of other links to sub-nav

	var linkprefix	= linkid.substr( 0, ( linkid.length - 1 ));
	var	curlink	= undefined;
	for ( var linknum = 1;
			(( curlink = document.getElementById( linkprefix + linknum )) != undefined );
				linknum++ ) {
		curlink.setAttribute( "class", "sub-nav" );
		curlink.setAttribute( "className", "sub-nav" );
	}

		// Set style of this link to sub-navcaps

	curlink	= document.getElementById( linkid );
	curlink.setAttribute( "class", "sub-navcaps" );
	curlink.setAttribute( "className", "sub-navcaps" );


		// Turn off all other sub project divs

	displayoff( NAVSUBPROJECT1 );
	displayoff( NAVSUBPROJECT2 );
	displayoff( NAVSUBNEWS1 );


		// Turn off the locked div
		// ??? This is not working?

	if (( lockeddiv != "" ) && ( lockeddiv != curid ))  {
		displayoff( lockeddiv );
	}

		// Turn on correct div

	if ( document.getElementById( showid )) {
		displayon( showid );
	}

	if ( debug ) {
		alert( "Done showmenu" );
	}
}


//
// showpopup -- Shows a popup nav div
//
function showpopup( id ) {

	if ( !lockedpopups ) {
		popupsoff();
		displayon( id );
	}

}


//
// popupsoff -- turns off all popup divs
//
function popupsoff() {
	var debug	= false;
	if ( debug ) {
		alert( "In popupsoff" );
	}

		// Reset styles on NAVPROJECT menu

	var linkprefix	= NAVPROJECT;
	var	curlink		= undefined;
	for ( var linknum = 1;
			(( curlink = document.getElementById( linkprefix + linknum )) != undefined );
				linknum++ ) {
		curlink.setAttribute( "class", "sub-nav" );
		curlink.setAttribute( "className", "sub-nav" );
	}

		// Hide divs

	if ( lockeddiv != NAVPROJECT ) {
		displayoff( NAVPROJECT );
	}

	if ( lockeddiv != NAVPRACTICE ) {
		displayoff( NAVPRACTICE );
	}

	if ( lockeddiv != NAVNEWS ) {
		displayoff( NAVNEWS );
	}

	if ( lockeddiv != NAVCONTACT ) {
		displayoff( NAVCONTACT );
	}

	displayoff( NAVSUBPROJECT1 );
	displayoff( NAVSUBPROJECT2 );
	displayoff( NAVSUBNEWS1 );

	if ( debug ) {
		alert( "Done popupsoff" );
	}

}


//
// lockpopup -- shows and locks a popup nav div so that it is never hidden
//
function lockpopup( id ) {
	var debug	= false;

	if ( debug ) {
		alert( "In lockpopup:\n" +
				"id = [" + id + "]\n" +
				"" );
	}


		// Show the div

	displayon( id );

		// Set the lock global

	lockeddiv	= id;

	if ( debug ) {
		alert( "Done lockpopup" );
	}
}


//
// removeoptions -- removes all options from a dropdown list
//
function removeoptions( dropdown ) {
	var	debug	= false;

	if ( debug ) {
		alert( "In removeoptions:\n" +
				"dropdown = [" + dropdown + "]\n" +
				"" );
	}


	var curoption;
	for ( curoption = dropdown.options.length - 1; curoption >= 0; curoption-- ) {
		dropdown.remove( curoption );
	}

	if ( debug ) {
		alert( "Done removeoptions" );
	}

}


//
// addoption -- adds an option to a dropdown list
//
function addoption( dropdown, value, text, selected ) {
	var	debug	= false;

	if ( debug ) {
		alert( "In addoption:\n" +
				"dropdown = [" + dropdown + "]\n" +
				"value = [" + value + "]\n" +
				"text = [" + text + "]\n" +
				"selected = [" + selected + "]\n" +
				"" );
	}

	if ( selected == undefined ) {
		selected	= false;
	}

	var optn	= document.createElement( "OPTION" );
	optn.text	= text;
	optn.value	= value;

	if ( selected ) {
		optn.selected	= true;
	}

	dropdown.options.add( optn );

	if ( debug ) {
		alert( "Done addoption" );
	}

}


	// *********************************************************************
	//
	// Generic field validation routines
	//
	// *********************************************************************



//
//	getfieldobj -- takes in a field and form name and returns the object reference.
// Browser independant.  Note that if there is more than one element with the same
// name, it returns the first element found.
//
function getfieldobj( field, form ) {
	var debug 	= false;
	var retval	= null;

	if ( debug ) {
		alert( "In getfieldobj:\n" +
				"field = [" + field + "]\n" +
				"form = [" + form + "]\n" +
				"STANDARD = [" + STANDARD + "]\n" +
				"" );
	}

		// Get the reference

	if ( STANDARD ) {
		retval	= document.getElementsByName( field ).item( 0 );
	} else {
		retval	= eval( "document." + form + "." + field );
	}

	if ( debug ) {
		alert( "Done getfieldobj:\n" +
				"retval = [" + retval + "]\n" +
				"" );
	}

	return retval;
}


//
//	getradioarray -- takes in a radio button and form name and returns the radio array.
//
function getradioarray( field, form ) {
	var debug 	= false;
	var retval	= null;

	if ( debug ) {
		alert( "In getradioarray:\n" +
				"field = [" + field + "]\n" +
				"form = [" + form + "]\n" +
				"STANDARD = [" + STANDARD + "]\n" +
				"" );
	}

		// Get the reference

	if ( STANDARD ) {
		retval	= document.getElementsByName( field );
	} else {
		retval	= eval( "document." + form + "." + field );
	}

	if ( debug ) {
		alert( "Done getradioarray:\n" +
				"retval = [" + retval + "]\n" +
				"" );
	}

	return retval;
}


//
//	validtext -- returns true if a text field is not empty, or longer than
// a given length.  Displays a popup error message otherwise and returns
// false.
//
function validtext( field, form, fieldname, maxlen, errormsg, allowempty, allowslash ) {
	var debug	= false;
	var retval	= true;

	if ( debug ) {
		alert( "In validtext:\n" +
				"field = [" + field + "]\n" +
				"form = [" + form + "]\n" +
				"fieldname = [" + fieldname + "]\n" +
				"maxlen = [" + maxlen + "]\n" +
				"errormsg = [" + errormsg + "]\n" +
				"" );
	}

	if ( allowempty == undefined ) {
		allowempty = true;
	}

	if ( allowslash == undefined ) {
		allowslash = true;
	}

		// Get the field's value

	var fieldobj = getfieldobj( field, form );

	if ( debug ) {
		alert( "fieldobj.value = [" + fieldobj.value + "]" );
	}

		// Check for empty

	var text	= fieldobj.value;
	text = text.replace( /^\s+|\s+$/g, '' );
	if ( debug ) {
		alert( "text = [" + text + "]" );
	}

	if (( !allowempty ) && ( text.length == 0 )) {
		retval	= false;

		var fullmsg = "The " + fieldname + " field is empty. ";
		if ( errormsg != "" ) {
			fullmsg += errormsg;
		}

		alert( fullmsg );

		// Check for too long

	} else if (( maxlen > 0 ) && ( fieldobj.value.length > maxlen )) {
		retval	= false;

		var fullmsg = "The " + fieldname + " field is too long. ";
		if ( errormsg != "" ) {
			fullmsg += errormsg;
		}

		alert( fullmsg );

		// Check for invalid chars

	} else if (( fieldobj.value.indexOf( "/" ) > -1 ) && ( !allowslash )) {

		retval	= false;

		var fullmsg = "The " + fieldname + " field contains a forward slash (\"/\"). Please re-enter the " +
						fieldname + " field.";
		alert( fullmsg );

	}

		// Give the field the focus on error

	if ( !retval ) {
		fieldobj.focus();
		fieldobj.select();
	}


	if ( debug ) {
		alert( "Done validtext:\n" +
				"retval = [" + retval + "]\n" +
				"" );
	}

	return retval;
}



//
//	validnumber -- returns true if a text field is not empty, or longer than
// a given length.  Displays a popup error message otherwise and returns
// false.
//
function validnumber( field, form, fieldname, allowneg, allowfraction, allowzero, errormsg, allowempty ) {
	var debug	= false;
	var retval	= true;

	if ( debug ) {
		alert( "In validnumber:\n" +
				"field = [" + field + "]\n" +
				"form = [" + form + "]\n" +
				"fieldname = [" + fieldname + "]\n" +
				"allowneg = [" + allowneg + "]\n" +
				"allowfraction = [" + allowfraction + "]\n" +
				"allowzero = [" + allowzero + "]\n" +
				"errormsg = [" + errormsg + "]\n" +
				"" );
	}

	if ( allowempty == undefined ) {
		allowempty = false;
	}

		// Get the field's value

	var fieldobj = getfieldobj( field, form );

	if ( debug ) {
		alert( "fieldobj.value = [" + fieldobj.value + "]" );
	}

		// Check for empty

	if ( fieldobj.value.length == 0 ) {
		if ( !allowempty ) {
			retval	= false;

			var fullmsg = "The " + fieldname + " value is empty. ";
			if ( errormsg != "" ) {
				fullmsg += errormsg;
			}

			alert( fullmsg );
		}

		// Check for NaN

	} else if ( isNaN( fieldobj.value )) {
		retval	= false;

		var fullmsg = "The " + fieldname + " value is not a number. ";
		if ( errormsg != "" ) {
			fullmsg += errormsg;
		}

		alert( fullmsg );

		// Check for negative

	} else if (( !allowneg ) && ( fieldobj.value < 0 )) {
		retval	= false;

		var fullmsg = "The " + fieldname + " value is negative. ";
		if ( errormsg != "" ) {
			fullmsg += errormsg;
		}

		alert( fullmsg );

		// Check for fraction

	} else if (( !allowfraction ) && ( fieldobj.value.indexOf( "." ) > -1 )) {
		retval	= false;

		var fullmsg = "The " + fieldname + " value is not a whole number. ";
		if ( errormsg != "" ) {
			fullmsg += errormsg;
		}

		alert( fullmsg );

		// Check for zero

	} else if (( !allowzero ) && ( fieldobj.value == 0 )) {
		retval	= false;

		var fullmsg = "The " + fieldname + " value is zero. ";
		if ( errormsg != "" ) {
			fullmsg += errormsg;
		}

		alert( fullmsg );

	}

		// Give the field the focus on error

	if ( !retval ) {
		fieldobj.focus();
		fieldobj.select();
	}

	if ( debug ) {
		alert( "Done validnumber:\n" +
				"retval = [" + retval + "]\n" +
				"" );
	}

	return retval;
}


//
//	validdate -- returns true if a text field contains a valid date.  Displays a popup error message
// otherwise and returns false.
//
function validdate( field, form, fieldname, errormsg ) {
	var debug	= false;
	var retval	= true;

	if ( debug ) {
		alert( "In validdate:\n" +
				"field = [" + field + "]\n" +
				"form = [" + form + "]\n" +
				"fieldname = [" + fieldname + "]\n" +
				"errormsg = [" + errormsg + "]\n" +
				"" );
	}

		// Get the field's value

	var fieldobj = getfieldobj( field, form );

	if ( debug ) {
		alert( "fieldobj.value = [" + fieldobj.value + "]" );
	}


	var parseddate = Date.parse( fieldobj.value );
	if ( debug ) {
		alert( "parseddate = [" + parseddate + "]" );
	}

	if ( fieldobj.value.length == 0 ) {
		retval	= false;

		var fullmsg = "The " + fieldname + " value is empty. ";
		if ( errormsg != "" ) {
			fullmsg += errormsg;
		}

		alert( fullmsg );

		// Check for NaN

	} else if ( isNaN( Date.parse( fieldobj.value ))) {
		retval	= false;

		var fullmsg = "The " + fieldname + " value is not a valid date. ";
		if ( errormsg != "" ) {
			fullmsg += errormsg;
		}

		alert( fullmsg );

	}

		// Give the field the focus on error

	if ( !retval ) {
		fieldobj.focus();
		fieldobj.select();
	}

	return retval;
}


//
//	validemail -- returns true if a text field contains a valid email address.
//
function validemail( field, form, fieldname, errormsg ) {
	var debug	= false;
	var retval	= true;

	if ( debug ) {
		alert( "In validemail:\n" +
				"field = [" + field + "]\n" +
				"form = [" + form + "]\n" +
				"fieldname = [" + fieldname + "]\n" +
				"errormsg = [" + errormsg + "]\n" +
				"" );
	}

		// Get the field's value

	var fieldobj = getfieldobj( field, form );

	if ( debug ) {
		alert( "fieldobj.value = [" + fieldobj.value + "]" );
	}

		// Check for empty

	if ( fieldobj.value.length == 0 ) {
		retval	= false;

		var fullmsg = "The " + fieldname + " value is empty. ";
		if ( errormsg != "" ) {
			fullmsg += errormsg;
		}

		alert( fullmsg );

		// check for /[a-z0-9]+@[a-z0-9]+\.[a-z]+/i

	} else if ( fieldobj.value.search( /[a-z0-9]+@[a-z0-9]+\.[a-z]+/i ) == -1 ) {
		retval	= false;

		var fullmsg = "The " + fieldname + " does not appear to be a valid address. ";
		if ( errormsg != "" ) {
			fullmsg += errormsg;
		}

		alert( fullmsg );

	}

		// Give the field the focus on error

	if ( !retval ) {
		fieldobj.focus();
		fieldobj.select();
	}

	if ( debug ) {
		alert( "Done validemail:\n" +
				"retval = [" + retval + "]\n" +
				"" );
	}

	return retval;
}


//
// validateform -- Shell function that calls the function in "validatefunction" and passes
// the return value back.  If validatefunction is null or the empty string, this routine
// returns true.
//
function validateform() {
	var debug	= false;
	var retval	= true

	if ( debug ) {
		alert( "In validateform:\n" +
				"validationfunction = [" + validationfunction + "]\n" +
				"" );
	}

	if ( validationfunction ) {
		retval	= eval( validationfunction );
	}

	if ( debug ) {
		alert( "Done validateform:\n" +
				"retval = [" + retval + "]\n" +
				"");
	}

	return retval;

}


//
// wordcount -- Returns number of words in a string
//
function wordcount( field, form ){
	var debug		= false;
	var retval		= 0;

	if ( debug ) {
		alert( "In wordcount:\n" +
				"field = [" + field + "]\n" +
				"form = [" + form + "]\n" +
				"" );
	}

	var fieldobj 	= getfieldobj( field, form );
	var stringvalue	= fieldobj.value;


	if ( debug ) {
		alert( "In wordcount:\n" +
				"fieldobj.value = [" + fieldobj.value + "]\n" +
				"" );
	}


		// \s Matches a whitespace character (space, tab, newline, form feed)
		// If that is found it is replaced with ' ' which is used in the split

	var wordarray	= stringvalue.replace( /\s/g, ' ' );

		// Every ' ' means that there's a new word, split just cuts up the string into substrings

	wordarray		= wordarray.split( ' ' );

	for ( curword = 0; curword < wordarray.length; curword++ ) {
		if ( wordarray[ curword ].length > 0 ) {
			retval++;
		}
	}



	if ( debug ) {
		alert( "Done wordcount:\n" +
				"retval = [" + retval + "]\n" +
				"" );
	}

	return retval;



}


//
// showpreview -- Shell function that calls the function in "previewfunction" and passes
// the return value back.  If previewfunction is null or the empty string, this routine
// returns false.
//
function showpreview() {
	var debug	= false;
	var retval	= false

	if ( debug ) {
		alert( "In showpreview:\n" +
				"validationfunction = [" + validationfunction + "]\n" +
				"" );
	}

	if ( previewfunction ) {
		retval	= eval( previewfunction );
	}

	if ( debug ) {
		alert( "Done showpreview:\n" +
				"retval = [" + retval + "]\n" +
				"");
	}

	return retval;

}


//
// shownextimageset -- reloads the current section page with the next 4 images as
// the current listings.
//
function shownextimageset() {
	var debug	= false;
	if ( debug ) {
		alert( "In shownextimageset" );
	}

		// Get current position from hidden field

	var curpos	= document.getElementById( "curposition" ).value;

	if ( debug ) {
		alert( "curpos = [" + curpos + "]" );
	}

		// Add curposition parameter to URL and reload via href.location

	var cururl	= location.href;
	if ( debug ) {
		alert( "cururl = [" + cururl + "]" );
	}

	if ( cururl.indexOf( "?" )) {
		cururl	= cururl.substring( 0, cururl.indexOf( "?" ));
	}
	cururl	+= "?curposition=" + ( parseInt( curpos ) + numimages );
	if ( debug ) {
		alert( "cururl = [" + cururl + "]" );
	}

	if ( debug ) {
		alert( "Done shownextimageset" );
	}

	location.href	= cururl;
}



	// *********************************************************************
	//
	// Main init code -- this sets up the Javascript environment and should
	// come after all functions
	//
	// *********************************************************************



if ( debug ) {
	alert( "navigator.appName = [" + navigator.appName + "]\n" +
			"navigator.appVersion = [" + navigator.appVersion + "]\n" +
			"navigator.appMinorVersion = [" + navigator.appMinorVersion + "]\n" +
			"navigator.userAgent = [" + navigator.userAgent + "]\n" +
			"navigator.appCodeBase = [" + navigator.appCodeBase + "]" );

	alert( "STANDARD = [" + STANDARD + "]\n" +
			"IE4 = [" + IE4 + "]\n" +
			"NS4 = [" + NS4 + "]" );
}

	// Set undefined for IE 5.0

if ( IE4 ) {
	if ( navigator.appVersion.search( "MSIE 5.0" ) > 0 ) {

		if ( debug ) {
			alert( "Runing IE 5.0" );
		}

		var undefined;
	}

	if ( debug ) {
		alert( "Done testing version" );
	}
}


if ( debug ) {
	alert( "Done main.js" );
}

