var AJAX_DATA_MODE = 'json';  // 'json' or 'xml'.  Must match config/config.inc's AJAX_DATA_MODE
var navLevel1 = new Array();

// return_void() - This will aid in inline javascript. If the inline stuff ends 
// with a value some browsers go to a new page and display that value.  This method 
// would prevent that from happening. Because it does nothing and, more importantly, 
// returns nothing, your inline js will end with no return value.  -- Bethany
function return_void() {}


// toggles a disable on an html element that disable applies to. 
function toggle_disable( item ) {
	item.disabled = !(item.disabled);
}

function enable_item( name ) {
	document.getElementsByName( name )[0].disabled = false;
}
function disable_item( name ) {
	document.getElementsByName( name )[0].disabled = true;
}

function enable_item_all( name ) {
	var list = document.getElementsByName( name );
	for( x = 0; x < list.length; x++ )
		list[x].disabled = false;
}
function disable_item_all( name ) {
	var list = document.getElementsByName( name );
	for( x = 0; x < list.length; x++ )
		list[x].disabled = true;
}


function show_div( divID ) {
	target = document.getElementById( divID );
	if (target == null) return;
	target.style.display = "block";
}
function hide_div( divID ) {
	target = document.getElementById( divID );
//	if (target == null) return;
	target.style.display = "none";
}

//toggle hidden divs using display
function toggle_div_display( divID ){
	target = document.getElementById( divID );
	if (target == null) return;
	if (target.style.display == "none"){
		target.style.display = "block";
	} else {
		target.style.display = "none";
	}
}

function show_tags( tag ) {
	var target= document.getElementsByTagName(tag);
	for(i = 0; i < target.length; i++) {
		target[i].style.display = "block";
	}
}
function hide_tags( tag ) {
	var target= document.getElementsByTagName(tag);
	for(i = 0; i < target.length; i++) {
		target[i].style.display = "none";
	}
}

//toggle hidden divs using visibility
function toggle_div_vis( divID ){
	target = document.getElementById( divID );
	if (target == null) return;
	if ((target.style.visibility == "hidden") || (target.style.visibility == "")) {
		target.style.visibility = "visible";
	} else {
		target.style.visibility = "hidden";
	}
}
// It's unlikely that we'll go past four levels of menus.  But if we do, just add on a few more nulls
// To close all menus, pass in (null, 0)
var openMenus = [ null, null, null, null ];
function toggle_menu_display( divID, level ){
	var last;
	var i;

	// First, close any open menus starting at the max level
	for( i = openMenus.length - 1; i >= level; i-- ) {
		if( openMenus[ i ] == null ) {
			continue;
		}

		target = document.getElementById( openMenus[ i ] );
		target.style.display = "none";

		// Yes, it's okay that this is overwritten each time.  We really just want the top one
		last = openMenus[ i ];
		openMenus[ i ] = null;
	}

	// Did they click on one that was just open?  If so, they meant to close it and we're done
	if( last == divID || divID == null ) return;

	// Let's open it!
	target = document.getElementById( divID );
	target.style.display = "block";

	// And remember it
	openMenus[ level ] = divID;
}

function menuitem_set_state( id, state ) {
	var item = document.getElementById( 'menuitem_' + id );
	if( !item ) return;
	state = ! state;
	item.disabled = state;
}

var currentHomeTab;
function showTab(strTabName) {
	var arrTabs = new Array('info', 'acnt', 'proj', 'share');

	if( strTabName == null || strTabName.length == 0 ) {
		strTabName = arrTabs[0];
	}

	help_add_context(strTabName);
	for (var i = 0; i < arrTabs.length; i++) {
		// show the content and tab
		var objContent = document.getElementById("tabcontent-" + arrTabs[i]);
		var objTab = document.getElementById("tab-" + arrTabs[i]);
		
		if (arrTabs[i] == strTabName) {
			if ( strTabName != currentHomeTab ) {
				// We need this here so set_curtab_contents() can be used.  It's also repeated down below for good measure
				help_remove_context(currentHomeTab);
				currentHomeTab = strTabName;

				//ajax in some content where appropriate
				switch (strTabName) {
				case 'proj':
					set_curtab_contents(); // This will force a refresh of the current tab.
					break;
				
				}
			}
			currentHomeTab = strTabName;

			// For some reason, the below Effect is causing bug 2977.  I'm in a hurry, so I've just
			// made it a straight transition, instead of a fancy once.  We can look into it more later.  -SS
      		//Effect.Appear(objContent,{ duration: .5 });
			objContent.style.display = "";

      		objTab.className = "active";
    	} else {
      		objContent.style.display = "none";
     		objTab.className = "";
		}
	}
}

//
// Re-fill the current home tab with something new (specified by "state").  To reset back
// to normal, pass in null.
//
// If you want to fill it with your own content, just use "custom" and then pass in the HTML via custom.
//
function set_curtab_contents( state, custom ) {
	var area = document.getElementById( 'tabcontent-' + currentHomeTab );

	// Restore to original content?
	if( state == null ) {
		loading_on();
		var urlData = 'pagestate=get_home_tab_contents&tab=' + currentHomeTab;
		// possible feature in the future. Let's see if this is noticed as a desirable feature.
		//if( currentHomeTab == 'proj' ) urlData += '&suggestJob=' + plCurrentJob + '&suggestDoc=' + plCurrentDoc;
		plCurrentJob = plCurrentDoc = 0;

		ajax_wrap( 'xml-catch.php', urlData, 'text', function( data ) {
			area.innerHTML = data;
			loading_off(500);
		});
		return;
	}

	switch( state ) {
		// Change user password
		// Change user info
		case 'chuserinfo':
		case 'chpass':
			loading_on();
			ajax_wrap( 'xml-catch.php', 'pagestate=get_' + state, 'data', function( data ) {
				area.innerHTML = data['content'];
				loading_off(250);
			});
		break;

		// Set custom text
		case 'custom':
			area.innerHTML = custom;
		break;

		case 'invite':
			loading_on();
			ajax_wrap( 'xml-catch.php', $( 'invite_email' ).serialize( true ), 'text', function( text ) {
				document.invite_email.emails.value = '';
				loading_off(250);
			});
			set_curtab_contents(null);
		break;

		default:
			alert( "Unknown state: " + state );
	}

}

function setOpacity(object, opacity) {
	obj = parent.top.document.getElementById(object);
	opacity = (opacity == 100)?99.999:opacity;
	// IE/Win
	obj.style.filter = "alpha(opacity:"+opacity+")";
	// Older Mozilla and Firefox
	obj.style.MozOpacity = opacity/100;
	// Safari 1.2, newer Firefox and Mozilla, CSS3
	obj.style.opacity = opacity/100;
}

function toggle_state( divID, call ) {
	target = document.getElementById( divID );
	if (target == null) return;

	// Since the toggle returns immidiately, we need to figure out the new value ourselves
	var newState = ( target.style.display == 'none' ? 'block' : 'none' );

	Effect.toggle( divID, 'blind' );

	ajax_wrap( 'xml-catch.php', 'pagestate=store_state&call='+call+'&name=' + divID + '&value=' + newState );
}

function toggle_and_store( divID ) {
	target = document.getElementById( divID );
	if (target == null) return;

	// Since the toggle returns immidiately, we need to figure out the new value ourselves
	var shown = ( target.style.display == 'none' ? 'true' : 'false' );
	Effect.toggle( divID, 'blind' );

	ajax_wrap( 'xml-catch.php', 'pagestate=setvariable&' + divID + '=' + shown );
}


//swap icons in projects based on id and type

function swap( imgID, imageType ) {
	if (imageType == 'arrow') {
		if (document.getElementById){
			img = document.getElementById( imgID );
     		pathlength = img.src.length;
     		sublength = pathlength - 18;
     		//this subtracted value must equal the length of the image string, and 
     		//image names must be the same length!
     		image = img.src.substr(sublength, pathlength-sublength);
     		if (image == "images/arrow_r.png") {
     			img.src = "images/arrow_d.png";
     		} else {
     			img.src = "images/arrow_r.png";
     		}
     	}
     }

	if (imageType == 'package') {
		if (document.getElementById){
			img = document.getElementById( imgID );
     		pathlength = img.src.length;
     		sublength = pathlength - 20;
     		image = img.src.substr(sublength, pathlength-sublength);
     		if (image == "images/package_c.png") {
     			img.src = "images/package_o.png";
     		} else {
     			img.src = "images/package_c.png";
     		}
     	}
     }

	if (imageType == 'document') {
		if (document.getElementById){
			img = document.getElementById( imgID );
     		pathlength = img.src.length;
     		sublength = pathlength - 21;
     		image = img.src.substr(sublength, pathlength-sublength);
     		if (image == "images/document_c.png") {
     				img.src = "images/document_o.png";
     		} else {
     				img.src = "images/document_c.png";
     		}
     	}
     }

	if (imageType == 'filedrawer') {
		if (document.getElementById){
			img = document.getElementById( imgID );
     		pathlength = img.src.length;
     		sublength = pathlength - 20;
     		image = img.src.substr(sublength, pathlength-sublength);
     		if (image == "images/filecab_c.png") {
     				img.src = "images/filecab_o.png";
     		} else {
     				img.src = "images/filecab_c.png";
     		}
     	}
     }

	if (imageType == 'checkbx') {
		if (document.getElementById){
			img = document.getElementById( imgID );
     		pathlength = img.src.length;
     		sublength = pathlength - 23;
     		//this subtracted value must equal the length of the image string, and 
     		//image names must be the same length!
     		image = img.src.substr(sublength, pathlength-sublength);
      		if (image == "images/checkbox_clr.png") {
     				img.src = "images/checkbox_chk.png";
     		} else {
     				img.src = "images/checkbox_clr.png";
     		}
     	}
     }
}

//scroll actionmenu
function pageOffset() {
	var jsMode = '';
	var footerExtra;
	if (document.all) {
		if (document.documentElement.clientHeight) {
			jsMode = 'IE6';
		} else {
			jsMode = 'IE5';
		}
	} else {
		jsMode = 'Stds';
	}	
	if ('IE6' == jsMode) {
		var actm = document.getElementById('actionmenu');
		if( !actm ) return;

		var bw = document.getElementById('box-wrap');
		var footer = document.getElementById('footer');
		innHeight = parseInt(document.documentElement.clientHeight);
		amHeight = parseInt(actm.offsetHeight);
		yOffset = parseInt(document.documentElement.scrollTop);
		footerExtra = 15; // extra bleeding padding, can't figure how to get style.top and style.margin in IE
	} else if ('IE5' == jsMode) {
		var actm = document.all['actionmenu'];
		if( !actm ) return;

		var bm = document.all['box-wrap'];
		var footer = document.all['footer'];
		innHeight = parseInt(document.body.clientHeight);
		amHeight = parseInt(actm.offsetHeight);
		yOffset = parseInt(document.body.scrollTop);
		footerExtra = 15;
	} else {
		var actm = document.getElementById('actionmenu');
		if( !actm ) return;

		var bw = document.getElementById('box-wrap');
		var footer = document.getElementById('footer');
		innHeight = parseInt(window.innerHeight);
  		amHeight = parseInt(actm.offsetHeight);
  		yOffset = parseInt(window.pageYOffset);
  		footerExtra = 0;
	}	
	var bwHeight = parseInt(bw.offsetHeight);
	var footerHeight = parseInt(footer.offsetHeight) + footerExtra;
  	newTop = (innHeight - amHeight) + yOffset;
  	if (newTop > ((bwHeight - footerHeight))) newTop = (bwHeight - footerHeight);
  	actm.style.top = newTop+'px';	
    setTimeout('pageOffset()', 100);
}

//scroll template-tickler
// Used for the filemanager???  What is different?
function pageOffset2() {
	var jsMode = '';
	var footerExtra;
	if (document.all) {
		if (document.documentElement.clientHeight) {
			jsMode = 'IE6';
		} else {
			jsMode = 'IE5';
		}
	} else {
		jsMode = 'Stds';
	}	
	if ('IE6' == jsMode) {
		var actm = document.getElementById('template-tickler');
		if( !actm ) return;
		var bw = document.getElementById('box-wrap');
		var footer = document.getElementById('footer');
		innHeight = parseInt(document.body.clientHeight);
		amHeight = parseInt(actm.offsetHeight);
		yOffset = parseInt(document.documentElement.scrollTop);
	} else if ('IE5' == jsMode) {
		var actm = document.all['template-tickler'];
		if( !actm ) return;
		var bm = document.all['box-wrap'];
		var footer = document.all['footer'];
		innHeight = parseInt(document.body.clientHeight);
		amHeight = parseInt(actm.offsetHeight);
		yOffset = parseInt(document.body.scrollTop);
	} else {
		var actm = document.getElementById('template-tickler');
		if( !actm ) return;
		var bw = document.getElementById('box-wrap');
		var footer = document.getElementById('footer');
		innHeight = parseInt(window.innerHeight);
  		amHeight = parseInt(actm.offsetHeight);
  		yOffset = parseInt(window.pageYOffset);
	}	
	var bwHeight = parseInt(bw.offsetHeight);
	var footerHeight = parseInt(footer.offsetHeight);
  	newTop = (innHeight - footerHeight) + yOffset;
  	//if (newTop > ((bwHeight - footerHeight))) newTop = (bwHeight - footerHeight);
  	actm.style.top = newTop+'px';	
    setTimeout('pageOffset2()', 100);
}


function scrollMenu() {
	// this in now essentially a debugging function. To be removed.
	var am = document.getElementById('actionmenu');
	if (am) {
		//alert(am.style.bottom);
		newbot = window.pageYOffset + window.innerHeight - parseInt(am.offsetHeight);
		alert(newbot);
		alert(window.pageYOffset);
		alert(window.innerHeight);
		alert(am.offsetHeight);
		//am.style.bottom = newbot + 'px';
		alert(am.style.bottom);
	}
	//setTimeout('scrollMenu()', 100);
}
		
function WindowGetYOffset() {
	if (document.all) {
		if (document.documentElement.clientHeight) {
			return document.documentElement.scrollTop;
		} else {	
			return document.body.scrollTop;
		}
	}	
	else if (document.getElementById)  	return window.pageYOffset;
	else if (document.layers)          	return window.pageYOffset;
}

/* This gets the window's total height (height of the scrollable area) */
function WindowGetHeight() {
	var mode = document.compatMode;
	var height = 0;

	if(( mode || Prototype.Browser.IE ) && !Prototype.Browser.Opera ) { // IE, Gecko
		switch( mode ) {
			case 'CSS1Compat':  // Standards mode
				height = (( window.innerHeight && window.scrollMaxY ) ?  window.innerHeight + window.scrollMaxY : document.documentElement.scrollHeight );
			break;

			default:  // Quirks
				height = document.body.scrollHeight;
			break;
		}
	} 
	else { // Safari & Opera
		height = document.body.scrollHeight;
	}

	return height;
}

/* This gets the window's width */
function WindowGetWidth() {
	if( self.innerWidth ) {
		frameWidth = self.innerWidth;
		//frameHeight = self.innerHeight;
	}
	else if( document.documentElement && document.documentElement.clientWidth ) {
		frameWidth = document.documentElement.clientWidth;
		//frameHeight = document.documentElement.clientHeight;
	}
	else if( document.body ) {
		frameWidth = document.body.clientWidth;
		//frameHeight = document.body.clientHeight;
	}
	else {
		frameWidth = 0;
	}

	return frameWidth;
}

function WindowGetInnerHeight() {
	if (document.all)          			return document.body.clientHeight;
	else if (document.getElementById)  	return window.innerHeight;
	else if (document.layers)          	return window.innerHeight;
}

function spellcheck(slot, form) 	{
	var spellWindow;
	var spellY;
	spellY = WindowGetInnerHeight()-20;
	text = urlencode( eval( 'document.'+form+'.elements[slot].value' ));
	var Loc="spellcheck.php?text="+text+"&slot="+slot+"&form="+form;
	spellWindow=open(Loc,'SpellCheck','toolbar=0,scrollbars=1,menubar=0,location=0,resizable=yes,directories=0,status=0,width=400,height=550,left='+spellY+',top=20');
}

function urlencode(itext) {
	var output;
	var x;

	output="";
	for(x=0; x<itext.length; x++) {
		switch(itext.charAt(x)) {
			case '%': output=output+"%25"; break;
			case '&': output=output+"%26"; break;
			case '#': output=output+"%23"; break;
			case '?': output=output+"%3F"; break;
			default: output=output+itext.charAt(x)+""; break;
		}
		if(x>100000)break;
	}
	return output;
}

function undo_enable() {
	menuitem_set_state( 'undo', true );
/*
	var undoarea = document.getElementById( 'undoButton' );
	if( !undoarea ) return;

	undoarea.innerHTML = "<a href='javascript:undo_check();'  onmouseover=\"window.status='Undo the last action';return true;\"  onmouseout=\"window.status='';return true;\"><span class=\"button\">&nbsp;UNDO&nbsp;</span></a>";
*/
}

function undo_check( target ) {
	if( se_is_in_use() ) {
		if( !confirm( "Warning: there are edit boxes open.  Lose your changes and undo the last action?" ))
			return false;
	}

	// Get the undo message
	loading_on();
	ajax_wrap( window.location.pathname, 'action=get_undo_msg', 'data', function( data ) {
		if( data['nothing'] == 1 ) {
			alert( 'Nothing to undo' );
		} else if( confirm( data['msg'] )) {
			window.location = window.location.pathname + '?SEpagestate=UNDO';
		}
		loading_off();
	} );
}

function open_help () {
	var helpcontent = document.getElementById("helpcontent");
	loading_on();
	ajax_wrap( 'help.php', "action=getHelp", 'data', function( data ) {
		helpcontent.innerHTML = data['text'];
		new Effect.Appear('help_panel', { to: 0.9 });
		loading_off(250);
	});
	// setTimeout ('toggle_div_display("helplayer")', 1000);
}
function further_help(context) {
	help_save_context();
	help_replace_context(context);
	var helpcontent = document.getElementById("helpcontent");
	ajax_wrap( 'help.php', "action=getHelp", 'data', function( data ) {
		helpcontent.innerHTML = data['text'];
	});
	help_restore_context();
}
function help_replace_context(context) {
	ajax_wrap( 'help.php', 'action=replace&context='+ context  ); 
}
function help_olreplace_context(context) {
	ajax_wrap( 'help.php', 'action=overlayReplace&context='+ context  ); 
}

function help_add_context(context) {
	ajax_wrap( 'help.php', 'action=addContext&context='+ context  ); 
}

function help_remove_context(context) {
	ajax_wrap( 'help.php', 'action=removeContext&context='+ context  ); 
}
function help_save_context(){
	ajax_wrap( 'help.php', 'action=saveContext' ); 
}
function help_restore_context(){
	ajax_wrap( 'help.php', 'action=restoreContext' ); 
}
function open_floating_help (module, descriptor) {
	var Loc="help.php?module="+module+"&descriptor="+descriptor;
	pdt = window.open(Loc,'predefines','toolbar=0,scrollbars=0,menubar=0,location=0,resizable=0,directories=0,status=0,width=420,height=300,left=50,top=50');
	pdt.focus();
}
function help_replace_and_get(context) {
	loading_on('loading help...');
	var helpcontent = document.getElementById("helpcontent");
	ajax_wrap( 'help.php', "action=replaceAndGet&context=" + context, 'data', function( data ) {
		helpcontent.innerHTML = data['text'];
		new Effect.Appear('help_panel', { to: 0.9 });
		loading_off(250);
	});
}

function open_confirm (question, yesText, yesAction, noText, noAction, mode) {
	if (document.getElementById) {
		confirmdiv = document.getElementById('confirmlayer');
	} else {
		confirmdiv = document.all['confirmlayer'];
	}		
	confirmdiv.style.top = (100 + WindowGetYOffset() ) + "px"; 
	if (confirmdiv.style.display == "none") {
		confirmdiv.src="confirmation.php?question="+question+"&yesText="+yesText+"&yesAction="+(urlencode(yesAction))+"&noText="+noText+"&noAction="+urlencode(noAction)+"&mode="+mode;
	} 		
	toggle_div_display('confirmlayer');
}	

function confirm_master_conversion(docID) {
	if ( confirm("Are you sure you want to convert this document to a master document?") ) {
		loading_on('converting master document...');
		ajax_wrap('xml-catch.php', 'pagestate=convert_to_master&docID='+docID, 'data', function (data) {
			if (data['success']) {
				showTab('acnt');
			} else {
				alert("Conversion failed. Please contact us at bugs@docuble.com");
			}
			loading_off();
		} );
	} 
}

/* opens the (QAQC) form iframe */
function open_form ( opt ) {
	if (document.getElementById) {
		vfdiv = document.getElementById('formslayer');
	} else {
		vfdiv = document.all['formslayer'];
	}		
	vfdiv.style.top = (10 + WindowGetYOffset() ) + "px"; 
	if (vfdiv.style.display == "none") {
		vfdiv.src="forms.php?"+opt;
	} 		
	toggle_div_display('formslayer');
}	

function open_view_files ( opt ) {
	if (document.getElementById) {
		vfdiv = document.getElementById('viewfileslayer');
	} else {
		vfdiv = document.all['viewfileslayer'];
	}		
	vfdiv.style.top = (10 + WindowGetYOffset() ) + "px"; 
	if (vfdiv.style.display == "none") {
		vfdiv.src="view_files.php?pagestate=viewspecs&"+opt;
	} 		
	toggle_div_display('viewfileslayer');
}	

function open_gen_iframe ( mode, opt ) {
	if (document.getElementById) {
		genif = document.getElementById('geniframe');
	} else {
		genif = document.all['geniframe'];
	}		
	genif.style.top = (10 + WindowGetYOffset() ) + "px"; 
	if (genif.style.display == "none") {
		genif.src="iframes.php?mode="+mode+"&"+opt;
	} 		
	toggle_div_display('geniframe');
}

function pop_print() {
// printFileID and printRev are js variables set by other things
	alert('popprint');
	var Loc="preview.php?fileID="+printFileID+"&revision="+printRev;
	w = window.open(Loc,'previewwin','toolbar=0,scrollbars=auto,menubar=0,location=0,resizable=yes,directories=0,status=0,width='+(screen.width/3)+',height='+(screen.height/2)+',left=50,top=50');
	w.focus();
}

function pop_preview(fileid,rev) {
	var Loc="preview.php?fileID="+fileid+"&revision="+rev;
	w = window.open(Loc,'previewwin','toolbar=0,scrollbars=auto,menubar=0,location=0,resizable=yes,directories=0,status=0,width='+(screen.width/3)+',height='+(screen.height/2)+',left=50,top=50');
	w.focus();
}
function pop_preview_id( id ) {
	var data = id.split( '-' );
	pop_preview( data[0], data[1] );
}

// This is a convenience function so we can use the ID
function submit_fileopts( id ) {
	var data = id.split( '-' );

	document.fileopts.fileID.value = data[0];
	document.fileopts.rev.value = data[1];
	document.fileopts.submit();
}


function pop_pic(file) {
	w = window.open(file,'pic','toolbar=0,scrollbars=auto,menubar=0,location=0,resizable=yes,directories=0,status=0,width='+(screen.width/3)+',height='+(screen.height/2)+',left=50,top=50');
	w.focus();
}

function pop_issue(filedrawerID,dirID,id) {
	var data = id.split( '-' );
	var fileid = data[0];
	var rev = data[1];

	var Loc="issue_sheet.php?pagestate=showIssue&filedrawerID="+filedrawerID+"&dirID="+dirID+"&fileID="+fileid+"&revision="+rev;
	w = window.open(Loc,'issuewin','toolbar=0,scrollbars=0,menubar=1,location=0,directories=0,width=750,height=500');
	w.focus();
}
/*
 * Calls the QAQC form popup into existance.
 * pagestate, module, and seqType are not optional
 * status and formID are optional. 
 */
function pop_forms(pagestate, module, seqType, status, seqID, lockID) {
	var Loc="forms.php?pagestate="+pagestate+"&seqType="+seqType+"&module="+module;

	if(status) {
		Loc += "&status=" + status;
	}

	if(seqID) {
		Loc += "&seqID=" + seqID;
	}

	if(lockID) {
		Loc += "&lockID=" + lockID;
	}

	w = window.open(Loc,'formwin','toolbar=0,scrollbars=1,menubar=1,location=0,directories=0,width=700,height=600');
	w.focus();
}
function pop_qaqc_status(docID,module) {
	var Loc="forms.php?clearsession=1&pagestate=list_for_doc";

	if( docID )
		Loc += "&docID=" + docID;
	if( module )
		Loc += "&module=" + module;

	w = window.open(Loc,'formwin','toolbar=0,scrollbars=1,menubar=1,location=0,directories=0,width=700,height=600');
	w.focus();
}
/**
 * seqID:    seqID or NULL for new
 * mode:     'edit', 'view', 'take'  (always just a suggestion)
 */
function pop_qaqc_form(seqID,mode) {
	var Loc="forms.php?clearsession=1&pagestate=" + mode + "&seqID=" + seqID;

	w = window.open(Loc,'formwin','toolbar=0,scrollbars=1,menubar=1,location=0,directories=0,width=700,height=600');
	w.focus();
}

function pop_qaqc_new(seqType,docID) {

}

function pop_lpmc_status(llocalID,mode) {
	var Loc="forms.php?clearsession=1&pagestate="+mode+"&llocalID=" + llocalID;

	w = window.open(Loc,'formwin','toolbar=0,scrollbars=1,menubar=1,location=0,directories=0,width=700,height=600');
	w.focus();
}

function form_clear_lock() {
	ajax_request( 'forms.php', 'pagestate=rlock' );
}


// toggle all the values of checkboxes that are in a grouping. 
// this is designed to be generic -
// masterCheckbox is the name of the master checkbox: document.<formname>.<checkboxname>,
// docName is the document.<formname>.  
function select_all_checkboxes(masterCheckbox, docName) {
	var numElements = docName.elements.length;
	var chkval = masterCheckbox.checked;

	// there's gotta be a better way to do this rather then looping though
	// all the elements in a page - what I really want is just the checkboxes. 
	// this currently (I think) tries to check all the elements in a page, and those
	// that can get checked, get checked, and others just "ignore" the request
	for (x = 0; x < numElements; x++) {
		docName.elements[x].checked = chkval;
	}

}

//
// Type can be:  del, undel, copy
//
function clause_propagate( type, uid ) {
	//  <input type="hidden" id="prop_{$uid}" name="propCode" value="{$propCode}">

	// Find all the clauses
	var clauses = document.getElementsByName( 'propCode' );

	// Prop Code base we're going to look for
	var propcode;
	var tid;

	// Mode specific variables
	var copyMode = 0;  // Keep track of which copy-select mode we're in, so it does the same for all

	// Are we there yet?
	var seenYet = false;
	var lookFor = 'prop_' + uid;
	for( var i = 0; i < clauses.length; i++ ) {
		// Skip everything, until we arrive at what we're looking for
		if( !seenYet ) {
			if( clauses[ i ].id == lookFor ) {
				seenYet = true;
				propcode = clauses[ i ].value;

				// Yikes!  Something must have gone wrong
				if( propcode.length == 0 ) return;
			} else {
				continue;
			}
		}

		// Lets see if this one matches the prop code
		if( clauses[ i ].value.slice( 0, propcode.length ) == propcode ) {
			tid = clauses[ i ].id.slice( 5 );

			switch( type ) {
				case 'del':
					se_del_cell( tid );
				break;

				case 'undel':
					se_undel_cell( tid );
				break;

				case 'copy':
					// The copyMode var keeps track of what we did (select or unselect) to the first
					// clause.  Then we pass it back in so we keep doing that action to all subsequent clauses
					copyMode = se_mark_for_copy( tid, copyMode );
				break;

				default:
					return;
			}
		}
		// If it doesn't match, that means we're done, and we don't have to look anymore
		else {
			return;
		}
	}

}


// the next  function depends on an array being built during page build.
function display_all(navLevel, display) {
	var i, stdMode, el;
	if (document.getElementById) {
		stdMode = true; 
	} else {
		stdMode = false;
	}		
	for (i = 0; i < navLevel.length; i++) {
		if (stdMode) {
			el = document.getElementById(navLevel[i]);
		} else {
			el = document.all[navLevel[i]];
		}
		if (display) {
			el.style.display = 'block';
		} else {
			el.style.display = 'none';
		}		
	}
}		
						

// chas's js deveiner stuff: Copyright 2004 DLSS. All rights reserved.

function print_unitArr() {
	tmp= '';
	for (i = 0; i < unitArr.length; i++) {	  
		  for (key in unitArr[i]) {
		  		//alert(i);
		  		tmp += key +'=>'+unitArr[i][key]+ " ";
		  }
		  tmp += "\n";
	 }		
//	 alert(tmp);
}

function print_vars() {
	var tmp;
	//print_unitArr();
	//init_unit_deveiner();
	//filter_units('HingeTip', 'Ball');
	tmp = '';
	for (i = 0; i < filteredUnits.length; i++) {	  
		 if (true) {
		 	tmp += i + ' '+ filteredUnits[i].partNumber+"\n";
		 }	 
		 if (false) { 
		 	for (key in filteredUnits[i]) {
		 		//alert(i);
		 		tmp += key +'=>'+filteredUnits[i][key] + " *** ";
		 	}
		 }
	 }
	 
//	 alert(tmp);		
}


var filteredUnits;
var selectArr = new Array();
var unSelected = new Array();
var selected = new Array();

function init_unit_deveiner() {
	if (unitArr) {
		reset_filters();
		set_selects();
		//final_filter();
	}
}

function reset_filters() {
	filteredUnits = unitArr;
	unSelected = selectArr;
	selected.length = 0;
}

function filter_units(key, value) {
	var tmpArr = new Array();
	var i;
	for (i = 0; i < filteredUnits.length; i++) {
		if (filteredUnits[i][key] == value) {
			tmpArr.push(filteredUnits[i]);
		}	
	}
	filteredUnits = tmpArr;
	
}

function attribute_select(attribute, ename) {
	var reselect, selValue, i;
	var tmpArr = new Array();

	reselect = false;
	for (i = 0; i < selected.length; i++) {
		if (selected[i] == attribute) {
	 		reselect = true;
	 		break;
		}
	}
	if (reselect) {
		reset_filters();
	} 
	selected.push(attribute);			
	for (i = 0; i < unSelected.length; i++) {
		if (unSelected[i] != attribute) {
			tmpArr.push(unSelected[i]);
		}
	}
	unSelected = tmpArr;
	selValue = document.docEditor.elements[ename].options[document.docEditor.elements[ename].selectedIndex].text;
	filter_units(attribute, selValue);
	if (filteredUnits.length==1) document.docEditor.unitID.value = filteredUnits[0]['unitID'];
	set_selects();

}

function get_attribute_values(attribute) {
	var tmpArr = new Array(); 
	var i, j, skip;	
	for (i = 0; i < filteredUnits.length; i++) {
		skip=false;
		for (j = 0; j < tmpArr.length; j++) 
			if (filteredUnits[i][attribute] == tmpArr[j]) skip = true;
		if (! skip) tmpArr.push(filteredUnits[i][attribute]);
	}
	return tmpArr;
}

function get_attribute_names() {
}	

function print_array(arr) {
	var tmp, i;
	tmp = '';
	for (i = 0; i < arr.length; i++) tmp += i + ':' + arr[i] + "\n";
//	alert(tmp);
}	

	
function set_selects() {
	var i, j, sel, tmpOpt, opts;
	//print_vars();
	for (i = 0; i < unSelected.length; i++) {
		opts = get_attribute_values(unSelected[i]);
		sel = document.getElementById('sel_' + unSelected[i]);
		sel.options.length = 0;
		for (j=0; j<opts.length; j++) {
			tmpOpt = new Option(opts[j]); 
			sel.options[sel.options.length] = tmpOpt;
		}
	}					
}

function final_filter() {
	var i, sel, val;
	if (filteredUnits.length == 1) return;
	for (i = 0; i < unSelected.length; i++) {
		sel = document.getElementById('sel_' + unSelected[i]);
		val = sel.options[sel.selectedIndex].text;
		filter_units(unSelected[i], val);
		if (filteredUnits.length == 1) break;
	}	
	document.docEditor.unitID.value = filteredUnits[0]['unitID'];
}

var divDoc;

function divDoc_init() {
	divDoc = window.frames['divinerlayer'].document;
}

function divDoc_build_select(attribute) {
	var j, opts;
	opts = get_attribute_values(attribute);
	if (opts.length > 1) {
		hasOptions = true; // are there any options to select from at all?
		divDoc.writeln('<p class="wizitem">');
		divDoc.writeln('Filter products by <em>' + attribute + '</em>:');
		divDoc.writeln('<select name=\"'+ attribute +'\" onchange=\"parent.divDoc_attribute_select(\''+ attribute +'\')\">');
		divDoc.writeln('<option>Please Select...</option>');
		for (j=0; j<opts.length; j++) {
			divDoc.writeln('<option>' + opts[j] + '</option>');
		}
		divDoc.writeln('</select>');
		divDoc.writeln('</p>');
	 } 
}	 

var styleSheet;
var hasOptions;

function divDoc_print_page(style) {
	styleSheet = style;
	reset_filters();
	divDoc_init();
	divDoc.open();
	divDoc_write_header();
	divDoc_print_available_selectors();
	divDoc.close();
}

function divDoc_print_available_selectors() {
	var i;
	var unitList = '';
	hasOptions = false;
	divDoc.writeln('<body>');
	divDoc.writeln('<div id=\"iframewrapper\">');
	divDoc.writeln('<form name="divForm" method="post" target="_parent" action="'+pageSelf+'">');
	divDoc.writeln('<input type="hidden" name="pagestate" value="filteredDown">');
	divDoc.writeln('<p class="wizitem">Filter further by making selections below OR <a href="javascript:document.divForm.submit();"><span class="button">Show Filtered Products</span></a></p>');
	for (i = 0; i < filteredUnits.length; i++) {
		unitList += '|' + filteredUnits[i]['unitID'];
	}
	divDoc.writeln('<input type="hidden" name="unitList" value="'+unitList+'">');
	for (i = 0; i < unSelected.length; i++) {
		divDoc_build_select(unSelected[i]);
	}	
	if (! hasOptions) {
		divDoc.writeln('<p class="wizitem">');
		divDoc.writeln('<strong>No more filters apply.</strong>');	
		divDoc.writeln('</p>');
	}	
	divDoc.writeln('</form>');
	divDoc.writeln('</div>');
	divDoc.writeln('</body>');
}

function divDoc_attribute_select(attribute) {
	var selValue, i;
	var tmpArr = new Array();
	selected.push(attribute);			
	for (i = 0; i < unSelected.length; i++) {
		if (unSelected[i] != attribute) {
			tmpArr.push(unSelected[i]);
		}
	}
	unSelected = tmpArr;
	selValue = divDoc.divForm.elements[attribute].options[divDoc.divForm.elements[attribute].selectedIndex].text;
	filter_units(attribute, selValue);
	divDoc.open();
	divDoc_write_header();
	divDoc_print_available_selectors();
	divDoc.close();
}

function divDoc_write_header() {
		
	divDoc.writeln('<head>');
	divDoc.writeln('<meta http-equiv="content-type" content="text/html; charset=iso-8859-1"></meta>');
	divDoc.writeln('<link rel="shortcut icon" href="favicon.ico" type="image/x-icon" />');
	divDoc.writeln('<link rel="icon" href="favicon.ico" type="image/x-icon" />');
	divDoc.writeln('<link rel="stylesheet" href="'+ styleSheet +'" type="text/css" media="all"></link>');
	divDoc.writeln('<!--[if ie 6]>');
	divDoc.writeln('<link rel="stylesheet" href="css/homecleanup_css.php" type="text/css" />');
	divDoc.writeln('<![endif]-->');
	divDoc.writeln('</head>');

}

// end of chas' js deveiner.

// JavaScript function for FORMS
function verify_form( formName, items ) {
	for( i = 0; i < items.length; i++ ) {	 

		// A multi?
		if( items[ i ].substr( 0, 1 ) == '*' ) {
			name = "formItem[" + items[ i ].substr( 1 ) + "][]";
		} else {
			name = "formItem[" + items[ i ] + "]";
		}

		// Get the element 
		allobjs = document.getElementsByName( name );
		obj = allobjs[0];

		// Good for debugging:
		//alert( 'Looking for: ' + name );
		//alert( 'Checking ' + obj.name + ' (' + obj.type + ')' );

		fail = false
		if( obj.type == 'checkbox' ) {
			if( obj.checked == false )
				fail = true;
		}
		else if( obj.type == 'radio' ) {
			found = 0;
			for( x = 0; x < allobjs.length; x++ ) {
				if( allobjs[x].checked )
					found = 1;
		   }

		   if( found == 0 )
		   	   fail = true;
		}
		else if( obj.value == '' ) {
			fail = true;
		}

		if( fail ) {
			alert( 'Please fill out all required fields' );
			return; 
		}

	}

	eval( "document." + formName + ".submit();" );
	return;
}
// end of FORMS functions

function preloadLEDs(){
	i = new Image();
	i.src = 'images/interstitial.gif';
	//alert( 'Loading Image!' );
	return i;
}

//
// Calendar Functions
//
function focus_on_and_select(item, itemChanged) {
	// it it has not been set yet
	if (itemChanged.value == 0) {
		item.focus();
		item.select();
	}	
}

function fill_in_days(whatItem, month, year, currentDay) {
	//alert('what item is ' + whatItem + '; numDays is ' + numDays + '; currentDay is ' + currentDay);	

	// Don't do anything if they haven't selected a year or month
	if( month == 0 || year == 0 ) return;

	numDays = numberOfDaysInMonth( month, year );
		
	// Fill in the valid days
	for (i = 0; i < numDays; i++) {
		whatItem.options[i].value = i + 1;
		whatItem.options[i].text = i + 1; 
	}

	// while the length is still greater then the number of days plus 1, 
	// reset the last few to a space (the idea is that the space is still 
	// there (makes processing easier))

	var index = whatItem.options.length - 2;
	while (index > numDays - 1) {	
		whatItem.options[index].value = 0;
		whatItem.options[index].text = ' ';
		index--;
	}

	// Make sure the selected day is a valid one
	currentDay = whatItem.selectedIndex;
	if( currentDay >= numDays ) {
		whatItem.selectedIndex = numDays - 1;
	}
}

//
// Notice:  month and year are strings!  ARG!
//
function numberOfDaysInMonth(month, year) {
	//alert( 'Month: ' + month + ', Year: ' + year );

	switch( month ) {
		case '1':  return 31;
		case '2':  return (((year % 4 == 0) && ( (!(year % 100 == 0)) || (year % 400 == 0))) ? 29 : 28 ) ;
		case '3':  return 31;
		case '4':  return 30;
		case '5':  return 31;
		case '6':  return 30;
		case '7':  return 31;
		case '8':  return 31;
		case '9':  return 30;
		case '10': return 31;
		case '11': return 30;
		case '12': return 31;
	}

	return 31;
}

function pop_calendar(mode,extra) {
	var Loc="calendar.php?pagestate=popup&mode="+mode+"&extra="+extra;
	w = window.open(Loc,'calpopwin','toolbar=0,scrollbars=auto,menubar=0,location=0,resizable=yes,directories=0,status=1,width=200,height=200,left=50,top=50');
	w.focus();
}

//
// this is for the print.php - it helps toggle the choices for headers and footers. 
// it is very specific code and is probably useless anywhere else. 
//

function toggle_header_footer_options(logoId, textId, fontId, value, textOptionVal, imageOptionVal) {

	// get the divId objects
	logoBox = document.getElementById( logoId );
	textBox = document.getElementById( textId );
	fontBox = document.getElementById( fontId );

	// do different things depending on what was selected
	if (value == textOptionVal) {
		// display the text box and the font box,
		// but supress the logo box, if it was present
		textBox.style.display = 'block';
		fontBox.style.display = 'block';
		logoBox.style.display = 'none';
	} 
	else if (value == imageOptionVal) {
		// display the logo box, but supress
		// the text and font boxes
		logoBox.style.display = 'block';
		textBox.style.display = 'none';
	    fontBox.style.display = 'none';
	} 
	else {
		// display the font box, but supress
		// the text and logo boxes
		logoBox.style.display = 'none';
		textBox.style.display = 'none';
		fontBox.style.display = 'block';
	}
}

var seCurEdit = 0;
function se_edit_cell( uid ) {
	loading_on();
	if (se_is_in_use()) {
		if( seCurEdit > 0 ) {
			se_submit_cell( seCurEdit );
		} else {
			// ajax is in progress. pretend the user didn't click anything.
			return;
		}
	}
	if (blockHolderID != null) se_del_block();

	se_set_in_use();
	ajax_wrap( window.location.pathname, "action=get_clause_edit&uid=" + uid, 'data', function( data, trans ) {
			// This is the clause wrapper
			var area = document.getElementById( 'clausewrap' + uid );
			area.innerHTML = data['text'];
			// Remove the highlight if this was a newly pasted clause
			area.className = area.className.replace( ' clauseNew', '' );

			seCurEdit = uid;

			// Add in the spelling buttons, but not in Safari.  We still have the jumping bug
			if( !Prototype.Browser.WebKit )
				createSEspell( uid );
			load_wrapArray(false);
			loading_off();

			// Set the cursor in the box
			var text = document.getElementsByName( "edit[" + uid + "]" )[0];
			text.focus();
		} );
}

function se_submit_cell( uid, cancel ) {
	var wrapping = {};
	// The new text:
	wrapping['text']  = document.getElementsByName( "edit[" + uid + "]" )[0].value;
	var level = document.getElementById( 'clauseLevel' + uid ).value;
	wrapping['level'] = level;
	wrapping['uid'] = uid;
	wrapping['die'] = 1;
	wrapping['action'] = 'submit_cell';
	oldlevel = document.getElementById( 'oldClauseLevel' + uid ).value;
	
	// Let see if there is the extra data
	var item = document.getElementsByName( "extra[" + uid + "][eval]" );
	if( item.length > 0 )
		wrapping['extendedData['+uid+'][eval]'] = item[0].value;
	item = document.getElementsByName( "extra[" + uid + "][lock]" );
	if( item.length > 0 )
		wrapping['extendedData['+uid+'][lock]'] = item[0].value;
	if( cancel )
		wrapping['cancel'] = 1;

	// If the level didn't change, just grab the new text
	// Otherwise, grab the whole row so the indentation is correct
	var forceRow = 1;
	if( forceRow || oldlevel != level ) {
		wrapping['returnrow'] = 1;
	} 
	seCurEdit = 0;
	loading_on('working ...');
	ajax_wrap( window.location.pathname, wrapping, 'data', function( data ) {
		if( forceRow || oldlevel != level ) {
			// Rewrite the whole row
			var clausewrap = document.getElementById( 'clausewrap' + uid );
			clausewrap.innerHTML = data['wholerow'];
		} else {
			// Change the text area
			var area = document.getElementById( 'uid' + uid );
			area.innerHTML = data['text'];

			// Change up the buttons
			area = document.getElementById( 'cb' + uid );
			area.innerHTML = data['actionbox'];
		}

		loading_off();
		se_unset_in_use(( oldlevel != level ));
	} );
}

function se_del_cell( uid ) {
	if( seCurEdit > 0 ) {
		se_submit_cell( seCurEdit );
	}

	
	loading_on('working ...');
	ajax_wrap( window.location.pathname, "action=delete_cell&uid=" + uid, 'data', function( data ) {
		var area = document.getElementById( 'clausewrap' + uid );
		area.innerHTML = data['wholerow'];

		// Enable the UNDO button
		undo_enable();

		se_set_needs_refresh();
		load_wrapArray(true);
		loading_off();
	} );
}

function se_undel_cell( uid ) {
	if( seCurEdit > 0 ) {
		se_submit_cell( seCurEdit );
	}

	loading_on('working ...');
	ajax_wrap( window.location.pathname, "action=undelete_cell&uid=" + uid, 'data', function( data ) {
		var area = document.getElementById( 'clausewrap' + uid );
		area.innerHTML = data['wholerow'];
		loading_off();
		// Enable the UNDO button
		undo_enable();
	});
}


// Open the next (or previous clause for edit)
function se_edit_next( goNext ) {

	// Are we editing anything?
	if( seCurEdit == 0 ) return;

	var current = 'clausewrap' + seCurEdit;
	var wrapMax = wrapArray.length - 1; 
	if ( goNext ) {
		if ( wrapMax < 1 ) return;
		for (var i=0;i<wrapMax;i++) {
			//intentionally not checking max element
			if (wrapArray[i] == current) {
				se_edit_cell(wrapArray[(i+1)].substring(10));
				return;
			}
		}
	} else {
		if ( wrapMax < 1 ) return;
		for (var i=wrapMax;i>0;i--) {
			// intentionally not checking 0th element
			if (wrapArray[i] == current) {
				se_edit_cell(wrapArray[(i-1)].substring(10));
				return;
			}
		}
	}
}

//
// Mode:  0 = auto, 1=select, 2=unselect
//
var seCopyList = Array();
function se_mark_for_copy( uid, mode ) {
	var wrap = $( 'clausewrap' + uid );  // The $() is short for document.getElementById().  Necessary for using addClassName() in IE
	if( !wrap ) return;

	var idx = seCopyList.indexOf( uid );
	if( mode == 1 || ( mode == 0 && idx == -1 )) {
		if( idx == -1 ) {
			wrap.addClassName( 'clauseSelected' );
			seCopyList.push( uid );
		}

		return 1;
	}

	if( mode == 2 || ( mode == 0 && idx >= 0 )) {
		if( idx >= 0 ) {
			wrap.removeClassName( 'clauseSelected' );
			seCopyList.splice( idx, 1 );
		}

		return 2;
	}

	// We should never get here
	return mode;
}


function se_add_comment( uid, parent ) {
	loading_on('working ...');
	ajax_wrap( window.location.pathname, 'action=get_blank_comment&uniqueID='+uid+'&parentID='+parent, 'data', function( data ) {
		var cID = data['id'];

		var container = document.createElement( 'div' );
		container.id = 'commentwrap.' + cID;
		container.innerHTML = data['block'];

		var tail = document.createElement( 'div' );
		tail.id = 'commentend.' + cID;

		var wrapper = $( 'outtercommentwrap' + uid )
		if( parent == 0 ) {
			// Ordering:  To have new level0 clauses in desc order, use the first clause.  To have level0
			// clauses go in asc order, use the second bit.
			if( 0 ) {
				// We're going to insert at the top
				var firstcomment = wrapper.firstChild;
				wrapper.insertBefore( container, firstcomment );
				wrapper.insertBefore( tail, firstcomment );
			}
			else {
				// ASC ordering:
				wrapper.appendChild( container );
				wrapper.appendChild( tail );
			}
		} else {
			// We're going to insert it at the end of the current sub-comments
			var commentend = $( 'commentend.' + uid + '.' + parent );
			wrapper.insertBefore( container, commentend );
			wrapper.insertBefore( tail, commentend );
		}

		// For some strange reason, we can't get access to the textarea right away.  It's as though
		// it's been added to the doc, but the browser hasn't realized it's there yet.  -ss
		setTimeout( "$( 'cmnt." + cID + "' ).focus();", 20 );
		loading_off();
	} );
}

function se_submit_comment( id, cancel ) {
	// Prototype Refresher:  
	//     $() == document.getElementById()
	//     $H() == new Hash()
	//     $F() == document.getElementById().value
	var area = $( 'commentwrap.' + id );
	var data = $H({ action: 'submit_comment', id: id, text: $F( 'cmnt.'+id ), cancel: cancel });
	loading_on('working ...');
	ajax_wrap( window.location.pathname, data, 'text', function( txt ) {
		area.innerHTML = txt;
		loading_off(250);
	} );
}

var wrapArray = new Array();
function load_wrapArray( really ) {
	if (!(really || ( wrapArray.length < 1 ))) return;
	wrapArray.length = 0;
	var editorBox = document.getElementById('editorbox');
	var elements = editorBox.getElementsByTagName("div");
	var count = elements.length;
	for (var i=0;i<count;i++) {
		var thisDiv = elements.item(i);
		if (thisDiv.id.search(/clausewrap/) > -1)  wrapArray.push(thisDiv.id); 
	}
}
		
		
/*
 * This is to keep track of open edit boxes in the DocEditor.  Yes, we're not keeping track of
 * which ones, just how many.  -ss
 */
var seInUse = 0;
var seRefreshAlreadyWarned = false;
var seUndoAlreadyWarned = false; // NOT USED
function se_set_in_use() {
	seInUse++;
	seRefreshAlreadyWarned = false;
	seUndoAlreadyWarned = false;
}
function se_unset_in_use( needsRefresh ) {
	seInUse--;

	seRefreshAlreadyWarned = false;
	seUndoAlreadyWarned = false;
	if( needsRefresh ) {
		se_set_needs_refresh();
	}
}
function se_is_in_use() {
	return ( seInUse > 0 );
}
function se_set_needs_refresh() {
return;
	var button = document.getElementById( 'serefresh' );
	button.style.color = 'red';
}

function se_submit_all_open() {
	// Get the list of open clauses
	loading_on('working ...');
	ajax_wrap( window.location.pathname, 'action=get_edit_list', 'data', function( uids ) {
		// Close each one
		for( i = 0; i < uids.length; i++ ) {
			se_submit_cell( uids[ i ] );
		}
		loading_off();
	} );
}

function se_get_next_page() {
	var url = window.location.pathname + '?action=get_next_page';
	//url += '&XYZ='+(new Date()).getTime();
	ajax_wrap( url, null, 'data', function( data ) {
		// Nothing more to do?
		if( (!data || ! data['b'] || data['b'].length == 0 )) {
			//alert( "Document Complete" );

			// Now we can start the code that will update the pager box
			if( document.edPager ) {
				setTimeout( 'se_pager_find_pg()', 500 );
			}
			return;
		}

		var box = document.getElementById( 'editorbox' );
		if( !box ) return;

		append_html( box, data['b'] );

		// Fix up the pager
		document.edPager.maxPage.value = data['page'];
		se_pager_refresh();

		setTimeout( 'se_get_next_page()', 100 );
	});
}

// Go to where the pager tells us to
function se_pager_go() {
	var p = parseInt( document.edPager.pager.value.split( ' ', 2 )[ 0 ] );
	se_pager_move_to( p );
}

// Move forward or backward the specified number of pages
function se_pager_move( where ) {
	var p = parseInt( document.edPager.curPage.value ) + parseInt( where );
	se_pager_move_to( p );
}
// Move to the specified page
function se_pager_move_to( p ) {
	var max = parseInt( document.edPager.maxPage.value );
	var target = '';
	var off = -70;
	if( Prototype.Browser.IE ) off = 0;
	else if( Prototype.Browser.Gecko ) off = 100;

	// Trying to go past the end of the doc?  Send them to the very end
	// ( -1 is an easy way to specify "the end")
	if( p > max || p == -1 ) {
		target = 'pageNumEND';
		document.edPager.curPage.value = max;
	} 
	// Send them to the top
	else if( p <= 1 ) {
		target = 'pageNum1';
		off = -83;
		document.edPager.curPage.value = 1;
	}
	// Send them where they want to go
	else {
		target = 'pageNum' + p;
		document.edPager.curPage.value = p;
	}

	var container = document.getElementById( 'content_125' );
	new Effect.ScrollInContainer( target, container, {offset: off} );

	document.edPager.pager.blur();
	se_pager_refresh();
}
// Refresh the text box
function se_pager_refresh() {
	// Does the box already have focus?  If so, don't touch
	if( document.edPager.pager.focus ) {
//alert( "Not touching the pager" );
//		return;
	}

	if (documentMaxPage > 0) document.edPager.maxPage.value = documentMaxPage;
	documentMaxPage=null;

	document.edPager.pager.value = 
		document.edPager.curPage.value +
		" of " +
		document.edPager.maxPage.value;
}

// Find which page we're on
var lastPagerPos = 0;
function se_pager_find_pg() {
	var container = document.getElementById( 'content_125' );
	var top = container.scrollTop;
	var height = container.clientHeight;
	var bottom = top + height;

	// Nothing to do, if we haven't moved more than 30 pixels or so
	if( lastPagerPos >= ( top - 15 ) && lastPagerPos <= ( top + 15 )) {
		setTimeout( 'se_pager_find_pg()', 500 );
		return;
	}

	// Good for debugging
	//alert( "We are currently seeing from " + top + " to " + bottom );	

    Position.prepare();

	var list = document.getElementsByName( 'pagenum' );
	var lastSeen = 'pageNum1';
	var isVis = false;
	var offsets;

	for( var i = 0; i < list.length; i++ ) {
		offsets = Position.cumulativeOffsetInside( list[ i ], container );
		// Is this link visible?
		isVis = ( offsets[ 1 ] >= top && offsets[ 1 ] <= bottom );

		// Hey - we found something - yay.
		if( isVis ) {
			// good for debugging:
			//alert( list[ i ].id + " is visible: " + offsets[ 1 ] + " of " + top + "-" + bottom );

			// If it's in the top 1/2, then we'll use it.   Otherwise, use the last seen
			if( offsets[ 1 ] < ( bottom - ( height / 2 ))) {
				//alert( "It's in the top half too" );
				lastSeen = list[ i ].id;
			} 

			break;
		}
		// Is this one below the bottom?  If so, we're done
		else if( offsets[ 1 ] > bottom ) {
			break;
		}

		lastSeen = list[ i ].id;
	}

	// Are we at the bottom?
	var pg = lastSeen.substring( 7 );
	if( pg == 'END' ) pg = document.edPager.maxPage.value;

	// Update the current page
	document.edPager.curPage.value = pg;
	se_pager_refresh();
	lastPagerPos = top;
	setTimeout( 'se_pager_find_pg()', 500 );
}

function bracket_selection(containerName, before, after) {
	container = document.getElementById(containerName);
	if (Prototype.Browser.IE) {
		 var selected = document.selection.createRange().text;
		 container.focus();
		 document.selection.createRange().text = before + selected + after;
	} else  {
		var contentLength = container.textLength;
		var start = container.selectionStart;
		var end = container.selectionEnd;
		var first = (container.value).substring(0,start);
		var bracketed = (container.value).substring(start, end);
		var last = (container.value).substring(end, contentLength);
		container.value = first + before + bracketed + after + last;
	}
}

function changeCase_selection(containerName) {
	container = document.getElementById(containerName);
	if (Prototype.Browser.IE) {
		 var selected = document.selection.createRange().text;
		 container.focus();
		 if (-1 < selected.search(/[a-z]/)) {
			 document.selection.createRange().text = selected.toUpperCase();
		 } else {
			 document.selection.createRange().text = selected.toLowerCase();
		 }
	} else  {
		var contentLength = container.textLength;
		var start = container.selectionStart;
		var end = container.selectionEnd;
		var first = (container.value).substring(0,start);
		var bracketed = (container.value).substring(start, end);
		if (-1 < bracketed.search(/[a-z]/)) {
			bracketed = bracketed.toUpperCase();
		} else {
			bracketed = bracketed.toLowerCase();
		}
		var last = (container.value).substring(end, contentLength);
		container.value = first + bracketed + last;
	}
}

function append_html( container, html ) {
	if( document.all ) {
		container.insertAdjacentHTML( 'beforeEnd', html );
	} else if( document.createRange ) {
		var range = document.createRange();
		range.setStartAfter( container.lastChild );
		var docFrag = range.createContextualFragment( html );
		container.appendChild( docFrag );
	} else {
		alert( "NO GO" );
	}
}

function load_headfoot() {
	help_add_context('headfoot');
	help_add_context('overlay');
	loading_on();
	ajax_wrap( 'print.php?action=headfootEditor', null, 'text', function( text ) {
		overlay_on(text, 'large');	
		loading_off(500);
	});
}
function hf_edit_cell(cellID) {
	var editorCell = document.getElementById('HFeditor-'+cellID);
	if (editorCell != null) return;
	loading_on('working ...');
	ajax_wrap( "print.php", "action=editHFcell&cellID=" +cellID, 'text', function( data ) {
		// This is the clause wrapper
		var area = document.getElementById( 'wrap-'+cellID );
		area.innerHTML = data;
		loading_off();

		// Set the cursor in the box
		var text = document.getElementById('edit-'+cellID);
		text.focus();
	});
} 

function hf_send_cell(cellID) {
	var target = document.getElementById('edit-'+cellID);
	var sel = document.getElementById('select-'+cellID);
	var oldsel = document.getElementById('hfOldStyle-'+cellID);

	var styleURL= (sel.value != oldsel.value) ? '&style='+sel.value : '';
	var editVal = encodeURI(target.value);

	loading_on('working ...');
	ajax_wrap( 'print.php', "action=sendHFchange&cellID="+cellID+ styleURL +"&value=" + editVal, 'text', function( text ) {
		var area = document.getElementById('wrap-'+ cellID );
		area.innerHTML = text;
		loading_off(250);
	});
}

function dict_to_array( xml ) {
	// If we don't have anything valid, let's return an empty array
	if( !xml || typeof( xml ) != 'object' ) {
		return new Array();
	}
    var items = xml.getElementsByTagName( 'xmldict' );

    // For some reason, when you get the xmldict, you get an HTMLELEMENT back
    // so we have to dig inside it for the XML stuff.  damn.
    return dict_to_array_PRIVATE( items.item( 0 ));
}

function dict_to_array_PRIVATE( node ) {
    if( !node || !node.childNodes ) return new Array;

    var array = new Array;
    var key = '';
	var child;

    for( var x = 0; x < node.childNodes.length; x++ ) {
        child = node.childNodes.item( x );
        if( child.nodeName == '#text' ) continue;

        //alert( 'found "' + child.nodeType + ': ' + node.nodeName + '" - value: ' + child.textContent);
        if( child.nodeName == 'key' ) {
            key = child.firstChild.data; //textContent;
        } else if( child.nodeName == 'dict' ) {
            grandkids = dict_to_array_PRIVATE( child );
            array[ key ] = grandkids;
        } else {
        //alert( 'found [' + key + '] => "' + child.nodeName + '" - value: ' + child.nodeValue);
			if( !child || !child.firstChild )
				array[ key ] = '';
			else
				array[ key ] = child.firstChild.data; //textContent;
        }
    }

    return array;
}

/*
 * A JavaScript version of PHP's print_r(), except it returns the text.
 */
function print_r(theObj){
	var output = '';

	if(theObj.constructor == Array || theObj.constructor == Object){
		output += "<ul>";
			for(var p in theObj){
				if(theObj[p].constructor == Array || theObj[p].constructor == Object){
					output += "<li>["+p+"] => "+typeof(theObj)+"</li>";
					output +="<li>";
					output += print_r(theObj[p]);
					output +="</li>";
				} else {
					output +="<li>["+p+"] => "+theObj[p]+"</li>";
				}
			}
		output +="</ul>";
	}

	return output;
}

function DisplayPropertyNames(obj) {
	var names ="";
	for (var name in obj) names += name + "\n";
	alert(names);
}

function show_innerHTML(div) {
	var target = document.getElementById(div);

	alert(target.innerHTML);
}

// Type can be 'text', 'data' (for xml/json), or null (for async with no return)
function ajax_wrap( url, postData, type, funcSuccess ) {
	//loading_on();
	new Ajax.Request( url, {
			onFailure:  function( transport ) { 
				loading_off();
				if( transport.status == 403 ) force_login( false ); 
				else if( transport.status == 402 ) force_login( true ); 
				else alert( "Unkown error: " + transport.status() );
			},
			onSuccess:  function( transport ) {
				//loading_off();
				if( !funcSuccess ) return;


				if( type == 'data' ) {
					if( AJAX_DATA_MODE == 'json' ) 
						funcSuccess( transport.responseText.evalJSON(), transport );
					else if( AJAX_DATA_MODE == 'xml' )
						funcSuccess( dict_to_array( transport.responseXML ), transport );
					else
						alert( "Unknown data mode: " + AJAX_DATA_MODE );
				} else if( type == 'text' ) {
					funcSuccess( transport.responseText, transport );
				} else { 
					alert( "Unknown data type: " + type );
				}
			},
			parameters: postData
		} );
}

var loginChided = false;
function force_login( loginLimit ) {
	if (! loginChided) {
		if( loginLimit )
			alert('You have been logged out because you cannot be logged in from more than one place at a time.');
		else
			alert('You have been logged out due to inactivity. Please login again.');
	}
	//loginChided = true;
			window.location = 'index.php?showlogin=1&expired=1';
}
/*
 * Clears the contents of a select box
 */
function select_clear( selectObject ) {
	while( selectObject.length > 0 ) {
		selectObject.remove( 0 );
	}
}
/*
 * Appends an option onto a select box
 */
function select_append( selectObject, value, text ) {
	var opt = document.createElement("option");
	opt.value = value;
	opt.appendChild( document.createTextNode( text ));
	selectObject.appendChild( opt );
}



//
// SELECT BOX SERIES functions ------------
//
// NOTES:  It's important (to IE) to have the 'var' declaration in front of the
// getElementById() calls.

var selectbox_series_ids = new Array();

function set_selectbox_series_id(oListID, startNum) {
	selectbox_series_ids[oListID] = startNum;
}	

function selectbox_series_append(oListID, x, y, selectOptionsStr, remValue) {
	// The list
	var oList = document.getElementById(oListID);

	// Create a new elemnt
	oNewNode = document.createElement('LI');

	// Give it an ID, so we can refer to it later
	id = x + '_' + y + '_' + selectbox_series_ids[oListID];
	oNewNode.id = id;

	selId = id + '_0';
	// create the data here - be careful of quotes.  ugh
	sel = '<select name=\"selectseries['+oListID+']['+id+']\" id=\"' + selId + '\"><br />';
	sel += selectOptionsStr;
	//for(i = 0; i < selectOptions.length; i++) {
	//	sel += '<option name=\"'+i+'\">'+selectOptions[i]+'</option>';
	//}	
	sel += '</select>';

	link = '<a href=\"javascript:selectbox_series_remove(\'' + oListID + '\',\'' + id + '\', \'' + selId + '\', \'' + remValue + '\');\"><span class=\"minibutt\">remove</span></a>';

	oNewNode.innerHTML= sel + link;
	selectbox_series_ids[oListID]++;

	// Add the new node
	oList.appendChild(oNewNode);
}

function selectbox_series_remove(oListID, id, selectBoxId, newVal) {
	var oList = document.getElementById(oListID);
	var node = document.getElementById( id );
	// reset the select box's index, as it will still get submitted w/ the page
	document.getElementById( selectBoxId ).selectedIndex = newVal; 
	oList.removeChild( node );
}


// some password change verification javascript

function verify_pw_changes(oldPassword, newPassword, newRepPassword) {
 	var retVal = true;
	if ( newPassword.value == '' || newRepPassword.value == '' ) {
		retVal = false;
		alert( 'Please fill in all fields' );
	} else if ( newPassword.value != newRepPassword.value ) {
		retVal = false;	
		alert( 'The new password does not match the retyped password.' );
	} else if ( oldPassword.value == '' ) {
		retVal = false;
		alert( 'Please enter your current password.  It cannot be left blank.' );
	}

	return retVal;
}


function jsTimerUpdate() {
	timeout = 10; /* 10 seconds */	 
	curVal = document.jsTimer.jsTimer.value = document.jsTimer.jsTimer.value - timeout;
	warnAt = document.jsTimer.warnAt.value;

	if( curVal < warnAt && warnAt > 0 ) {
		r = confirm( document.jsTimer.warnText.value );
		if( r ) {
			eval( 'd = ' + document.jsTimer.onExtend.value );
			if( d == '1' ) {
				document.jsTimer.jsTimer.value += document.jsTimer.extendSeconds.value;
			}
		}
	}

	// Still time left?  We'll continue
	if( curVal > 0 ) {
		setTimeout('jsTimerUpdate()', ( timeout * 1000 ));
	} else {
		eval( document.jsTimer.onExpire.value );
	}
}

function jsTimerStart() {
	jsTimerUpdate();	 
}


function se_insert_pastes() {
	var sourceDocID = document.pasteForm.copyDocID.value;
	var sourceClauses = document.pasteForm.copyClauses.value;
	var uniqueID = document.pasteForm.pasteAfter.value;
	var count = document.pasteForm.copyCount.value;

	if( count == 0 ) return false;

	se_insert_clause_after( uniqueID, count, sourceDocID, sourceClauses, 1 );

	var holder = document.getElementById('clausewrap-HOLDER-'+uniqueID)
	if( holder ) {
		var page = document.getElementById( 'editorbox' );
		page.removeChild( holder );
	}

}

/**
 * Submit any open clause or comment, if there is one.  Used for the hotkey
 */
function submit_open_edits( e ) {
	// First off, are we editing a clause?
	if( seCurEdit > 0 ) {
		se_submit_cell( seCurEdit );
	}
	// Otherwise, let's see if there is an open comment that has the focus.
	else if( e.target.id && e.target.id.substr( 0, 5 ) == 'cmnt.' ) {
		se_submit_comment( e.target.id.substr( 5 ) );
	}
}

function se_insert_clause_after( uniqueID, count, copyFromDocID, copyClauses, after ) {
	if (se_is_in_use()) {
		if( seCurEdit > 0 ) {
			se_submit_cell( seCurEdit );
		} else {
			// ajax is in progress. pretend the user didn't click anything.
			return;
		}
	}

	// We're going to set the system "in use" so we can finish what we're doing in peace
	se_set_in_use();

	// The node we're going to insert next to:
	var neighbor = document.getElementById( 'clausewrap' + uniqueID );
	if( !neighbor ) {
		alert( 'no clausewrap for uniqueID ' + uniqueID );
		return;
	}
	// If we're inserting after, we need to jump over the comments
	var neighborTail = document.getElementById( 'clausetail' + uniqueID );
	if( !neighborTail ) {
		neighborTail = neighbor;
		//alert( "HEY - no tail" );
	}

	// Get the new clause-row
	var url = window.location.pathname + '?action=insert_and_get&uniqueID=' + uniqueID + '&clauseCount=' + count + '&after=' + after;
	if( copyFromDocID ) url += '&copyFromDocID=' + copyFromDocID + '&copyClauses=' + copyClauses;

	loading_on();
	ajax_wrap( url, null, 'data', function( rows ) {
		// Only mark clauses with the "new" outline if we're copying.  If we're inserting blank, it will be opened for editing
		var classes = 'clausewrap' + ( copyFromDocID > 0 ? ' clauseNew' : '' );
		var page = document.getElementById( 'editorbox' );

		// Add all the rows backwards, so they come out right
		for( i = rows.length - 1; i >= 0 ; i-- ) {
			id = rows[i]['id'];
			data = rows[i]['data'];

			var newnode = document.createElement( 'div' );
			newnode.setAttribute( 'className', classes );  // For IE
			newnode.setAttribute( 'class', classes );   // For everything else
			newnode.setAttribute( 'id', "clausewrap" + id );
			newnode.innerHTML = data;

			var newcomments = document.createElement( 'div' );
			newcomments.setAttribute( 'id', 'outtercommentwrap' + id );

			var newcleaner = document.createElement( 'div' );
			newcleaner.setAttribute( 'className', 'cleaner' );  // For IE
			newcleaner.setAttribute( 'class', 'cleaner' );  // For everything else
			newcleaner.setAttribute( 'id', 'clausetail' + id );

			if( after ) {
				var next = neighborTail.nextSibling;

				page.insertBefore( newnode, next );
				page.insertBefore( newcomments, next );
				page.insertBefore( newcleaner, next );
			} else {
				page.insertBefore( newnode, neighbor );
				page.insertBefore( newcomments, neighbor );
				page.insertBefore( newcleaner, neighbor );
			}

			// If this clause is opened for edit, mark it as such
			if( rows[i]['edit'] ) {
				seCurEdit = id;  // At the moment, we'd better only get ONE back for edit (or less, of course)
				se_set_in_use();
			}

			// Regenerate the list of clauses
			load_wrapArray(true);
			loading_off(250);
		}

		// And unlock the system - this is the one that was set before we started the ajax
		se_unset_in_use();
	});
}

var clauselibwin;
function pop_clauselib( targetUniqueID ) {
	var Loc="clauselib.php?targetUniqueID="+targetUniqueID+"&pagestate=clear";
	var width = screen.width / 2;
	width = ( width < 900 ? 900 : width );  // Make sure it never gets TOO small
	var left = ( screen.width - width );
	clauselibwin = window.open(Loc,'clauselibwin','toolbar=0,scrollbars=yes,menubar=0,location=0,resizable=yes,directories=0,status=0,width='+width+',height='+screen.height+',left='+left+',top=o');
	clauselibwin.focus();
}

function pop_clausesearch( targetUniqueID, targetDocID, targetCategory ) {
	var Loc="clauselib.php?pagestate=search&targetUniqueID="+targetUniqueID+"&targetDocID="+targetDocID+"&targetCategory="+targetCategory; 
	var width = screen.width / 2;
	width = ( width < 900 ? 900 : width );  // Make sure it never gets TOO small
	var left = ( screen.width - width );
	clauselibwin = window.open(Loc,'clauselibwin','toolbar=0,scrollbars=yes,menubar=0,location=0,resizable=yes,directories=0,status=0,width='+width+',height='+screen.height+',left='+left+',top=o');
	clauselibwin.focus();
}

function pop_libsearch(fmmode) {
	var Loc="libsearch.php?pagestate=search&mode="+fmmode;
	w = window.open(Loc,'libsearchwin','toolbar=0,scrollbars=yes,menubar=0,location=0,resizable=yes,directories=0,status=0,width=800,height=600,left=50,top=50');
	w.focus();
}


function clauselib_tally_copying(docID,targetUniqueID) {
	// Ref to the form we're filling out
	var target = opener.document.pasteForm;

	if( target == null ) {
// ALSO - run check of MD5 string
		alert( 'The main browser window is no longer pointing to the correct place.  Please close this window and try again.' );
		return;
	}

	// Tally up all the clauses
	var clauselist = seCopyList.join( ',' );
	var count = seCopyList.length;

// TO DO:  Check to see if we actually have clauses to copy
	target.copyDocID.value = docID;
	target.pasteAfter.value = targetUniqueID;
	target.copyCount.value = count;
	target.copyClauses.value = clauselist;

	// Fire off the foreign form
	target.submitform.click();

	// We're done here
	window.close();
}

function fm_download_if_checked() {	
	var numElements = document.fmdownload.elements.length;
	var i=0;
	var tmpString='';
	var okForSubmit = false;
	for (i=0; i< numElements; i++) {
		if (document.fmdownload.elements[i].name.search(/downloadList/) > -1) {
			if (document.fmdownload.elements[i].checked) okForSubmit = true;
		}
	
	}
	if (okForSubmit) document.fmdownload.submit();
}

function initLayer() {
  divId = 'msgAlert';
  msg = document.getElementById(divId);
  if (msg) {
    setOpacity(msg, 20);
    msg.style.visibility = 'visible';
	msg.style.top = (5 + WindowGetYOffset() ) + "px"; 
    fadeIn(divId,0);
    window.setTimeout("fadeOut('"+divId+"',100)", 5000);
  }
}

function setOpacity(obj, opacity) {
  opacity = (opacity == 100)?99.999:opacity;
  
  // IE/Win
  obj.style.filter = "alpha(opacity:"+opacity+")";
  
  // Safari<1.2, Konqueror
  obj.style.KHTMLOpacity = opacity/100;
  
  // Older Mozilla and Firefox
  obj.style.MozOpacity = opacity/100;
  
  // Safari 1.2, newer Firefox and Mozilla, CSS3
  obj.style.opacity = opacity/100;
}

function fadeIn(objId,opacity) {
  if (document.getElementById) {
    obj = document.getElementById(objId);
    if (opacity <= 100) {
      setOpacity(obj, opacity);
      opacity += 20;
      window.setTimeout("fadeIn('"+objId+"',"+opacity+")", 100);
    }
  }
}

function fadeOut(objId,opacity) {
  if (document.getElementById) {
    obj = document.getElementById(objId);
    if (opacity <= 100) {
      setOpacity(obj, opacity);
      opacity -= 10;
      window.setTimeout("fadeOut('"+objId+"',"+opacity+")", 100);
    }
  }
}

// new and improved with ajax!
function toggle_ynv( basename, incVar ) {
	var item = document.getElementById( basename + '_item' );
	var div = document.getElementById( basename + '_div' );

	item.value++;
	item.value = item.value % ( incVar > 0 ? 3 : 2 );

	var target = 'ynv_no';
	if( item.value == 1 ) target = 'ynv_yes';
	else if( item.value == 2 ) target = 'ynv_var';

	div.className = target;

	ajax_wrap( 'xml-catch.php', 'pagestate=store_ynv&type='+ basename.substr(0,1) + '&data=' + basename.substring(2, basename.length-1) + '&value=' + item.value ); 
}

// Specify the name of the checkboxes, and true/false
function twiddle_checkboxes( name, checked ) {
	var items = document.getElementsByName( name );
	var len = items.length;

	for( i = 0; i < len; i++ ) {
		items[ i ].checked = checked;
	}
}

// check if the page is dirty before switching modes.
function switch_modes_if_clean() {
	if (specPageClean) {
		document.specState.submit();
	} else {
		alert ("There have been changes to the Document Editor which may be lost if you switch modes at this time.\nClick 'Switch Mode' again to abandon your changes, or 'Submit Page' to save them.");
		specPageClean = true;
	}
} 

function fuzz_off() {
	fuzzObj = document.getElementById("fuzz");
	if (null == fuzzObj) return; 
	fuzzObj.style.display = "none";
	shim_div( 'fuzzinfo', false, false );
} 
function fuzz_on() {
	var fuzzObj = document.getElementById( "fuzz" );
	var inside = document.getElementById( "fuzzinfo" );

	if (null == fuzzObj || null == inside) return; 

	// If we're turning this on manually, we're going to manually set the width, height, etc.  This 
	// is so that the shim will function properly
	inside.style.position = "absolute";
	inside.style.top = "200px";
	inside.style.left = (( WindowGetWidth() - 300 ) / 2 ) + "px";
	inside.style.margin = '0 0 0 0';

	//fuzzObj.style.visibility = "visible";
	fuzzObj.style.display = "block";
	shim_div( 'fuzzinfo', true, false );
} 

// Adds trim functionality to strings.   Use as:  string.trim().
String.prototype.trim = function() { return this.replace( /^\s+|\s+$/, '' ); };

function load_pl_div( type, id, key, div ) {
	// garbage data?
	if( key == 0 ) return;

	// Has this aready been done?
	div = document.getElementById( div );
	if( div.innerHTML.trim().length > 0 ) {
		return;
	}

	// Get the data
	wait_on();
	loading_on();
	ajax_wrap( 'xml-catch.php', 'pagestate=fill_pl&key='+key+'&type='+type+'&id='+id, 'text', function( text ) {
		div.innerHTML = text;
		wait_off();
		loading_off();
	});
}

// Which items are currently being viewed
var plCurrentJob = 0;
var plCurrentDoc = 0;

function pl_open_job( key, jobID ) {
	// If it's the current one, we're done
	if( jobID == plCurrentJob ) {
		return;
	}

	// This div will hold the job contents (list of docs)
	var container;
	var jobTitle;

	// Deleselect and hide current one
	if( plCurrentJob > 0 ) {
		container = document.getElementById( 'pl_job_contents_' + plCurrentJob );
		// If this has been re-drawn, it might not exist
		if( container ) {
			container.style.display = 'none';
			jobTitle = document.getElementById( 'pl_job_title_' + plCurrentJob );
			jobTitle.className = '';//'plEntry';
		} else {
			plCurrentJob = 0;
		}
	}
	if( plCurrentDoc > 0 ) {
		container = document.getElementById( 'pl_doc_contents_' + plCurrentDoc );
		// If this has been re-drawn, it might not exist
		if( container ) {
			container.style.display = 'none';
			var docTitle = document.getElementById( 'pl_doc_title_' + plCurrentDoc );
			docTitle.className = '';//'plEntry';
		}

		plCurrentDoc = 0;
	}

	// Hide the doc buttons
	container = document.getElementById( 'pl_doc_contents' );
	if( container ) {
		container.style.display = 'none';
	}

	container = document.getElementById( 'pl_job_contents_' + jobID );

	var colDoc = document.getElementById( 'projlist_doc' );
	var colJob = document.getElementById( 'projlist_job' );

	jobTitle = document.getElementById( 'pl_job_title_' + jobID );
	jobTitle.className = 'plSelected';
	plCurrentJob = jobID;

	// Do we need to create and fill the container?
	if( !container ) {
		container = document.createElement( 'div' );
		container.id = 'pl_job_contents_' + jobID;

		loading_on();
		ajax_wrap( 'xml-catch.php', 'pagestate=pl_get_job_contents&jobID='+jobID+'&key='+key, 'data', function( data ) {
			if( data['error'] ) {
				// If they had an invalid key, we'll get an error back.  let's refresh this window for them
				set_curtab_contents();
			} else {
				container.innerHTML = data['fill'];
				colDoc.appendChild( container );
			}
			loading_off(250);
		});
	} else {
		container.style.display = 'block';
	}
}

var oldIndex = null;
var oldColSelected = '';
var oldCol2 = null;
//
// Index is optional, if it's not changing
//
function home_show(what, where) {
	index = what+where;
	if( index == null ) index = oldIndex;
	oldIndex = index;

	divName = 'homelist_left_' + where + '_' + index;
	targetName = 'homelist_centerRight_' + where;
	var col1 = document.getElementById( divName );
	var col2 = document.getElementById( targetName );
	oldCol2 = col2;
	if ((oldColSelected.length) && (oldColSelected != divName)) {
		var oldCol = document.getElementById (oldColSelected);	
		oldCol.className  = '';
	}
	oldColSelected = divName;

	// Make sure it's in front
	showTab( where );

	switch (what) {
		case 'chuserinfo':
		case 'chpass':
			loading_on();
			ajax_wrap( 'xml-catch.php', 'pagestate=get_' + what, 'data', function( data ) {
				col2.innerHTML = data['content'];
				loading_off();
			});
		break;

		case 'editable_masters':
		case 'recent_projects':
		case 'invite_form':
		case 'shared_to':
		case 'shared_from':
		case 'shareform':
		case 'cancel_my_account':
		case 'acntstatus':
		case 'billinginfo':
			loading_on();	
			ajax_wrap( 'xml-catch.php', 'pagestate=get_' + what, 'text', function( data ) {
				col2.innerHTML = data;
				loading_off();
			});
		break;
	}
	col1.className = 'homelistSelected';
	col2.style.display = 'block';
}
function pl_open_doc( key, docID ) {
	// If it's the current one, we're done
	if( docID == plCurrentDoc ) {
		return;
	}

	var docTitle;
	var container;
	// Deleselect the current one
	if( plCurrentDoc > 0 ) {
		container = document.getElementById( 'pl_doc_contents_' + plCurrentDoc );
		container.style.display = 'none';
		docTitle = document.getElementById( 'pl_doc_title_' + plCurrentDoc );
		docTitle.className = '';//'plEntry';
	}

	// This div will hold the doc contents (buttons)
	container = document.getElementById( 'pl_doc_contents_' + docID );

	var colButtons = document.getElementById( 'projlist_details' );
	var colDoc = document.getElementById( 'projlist_doc' );

	docTitle = document.getElementById( 'pl_doc_title_' + docID );
	docTitle.className = 'plSelected';
	plCurrentDoc = docID;

	// Do we need to create and fill the container?
	if( !container ) {
		container = document.createElement( 'div' );
		container.id = 'pl_doc_contents_' + docID;

		loading_on();
		ajax_wrap( 'xml-catch.php', 'pagestate=pl_get_doc_buttons&docID=' + docID + '&key='+key, 'data', function( data ) {
			if( data['error'] ) {
				// If they had an invalid key, we'll get an error back.  let's refresh this window for them
				set_curtab_contents();
			} else {
				container.innerHTML = data['buttons'];
				colButtons.appendChild( container );
			}
			loading_off();
		});
	} else {
		container.style.display = 'block';
	}
}



function start_bgprint( section ) {
	sectionText = (section > 0 ? '&section='+section : ''); 
	loading_on('working...');
	ajax_wrap( 'print.php?action=print'+sectionText, null, 'text', function( text ) {
		message_on(text, true);
		loading_off();
	});
}

function wait_on() {
	waitObj = document.getElementById("hourglass");
	if( waitObj == null ) return;

	waitObj.style.top = yMousePos-20 + "px"; 
	waitObj.style.left = xMousePos-20 + "px";
	waitObj.style.visibility = 'visible';
	waitObj.focus = true;
}
function wait_off() {
	waitObj = document.getElementById("hourglass");
	if( waitObj == null ) return;
	waitObj.style.visibility = 'hidden';
}

function test_browser() {
	// Check for any questionable functions
	if( !document.getElementById ) {
		window.location='browserfailure.php';
	}
}

var msgTimerID;
var pingTimerID;
function check_for_sys_messages() {
	clearTimeout(msgTimerID);
	var sleeper = 20000; // 20 seconds
	//var sleeper = 120000; // 120 seconds
	var pingTime = 60000 //60 seconds;
	//var pingTime = 180000 //180 seconds;

	pingTimerID = setTimeout('show_ping_warning()', pingTime);

	var msgoverlay = document.getElementById('overlay');
	var senseibox = document.getElementById('message');

	//alert('check_for_sys_message');
	// There are some pages that don't have the system message - like the ClauseLib popup
	if( !(msgoverlay || senseibox) ) return;

	// Don't check if a message is currently shown
	if( msgoverlay.style.visibility == 'visible' ) {
		setTimeout( 'check_for_sys_messages()', sleeper );
		return;
	}

	// Check for messages
	var url = 'xml-catch.php?pagestate=check_push_msg&noltses=1';
	ajax_wrap( url, null, 'data', function( data ) {
		switch ( data['status']) {
			case 'file':
				var fileRevInfo = data['extra'];
				fileRevArray = fileRevInfo.split('-')		
				message_with_link_on('', 'javascript:pop_preview('+fileRevArray[0]+','+fileRevArray[1]+')', data['msg'], false);
			break;
			case 'user':
				if (data['target'] == 'overlay') {
					overlay_on(data['msg'], 'small');
				} else {
					message_on(data['msg'], true);
				}
			break;
			case 'system':
				if (data['target'] == 'overlay') {
					overlay_on(data['msg'], 'small');
				} else {
					message_on(data['msg'], true);
				}
			break;
			default:
				// do nothing in particular
			break;
		}

		// Check every sleeper seconds
		window.clearTimeout(pingTimerID);
		msgTimerID = window.setTimeout( 'check_for_sys_messages()', sleeper );
	});
}

var pingWarningShown = false;
function show_ping_warning() {
	if (! pingWarningShown) message_on('Your connection to the server is slow. You may encounter long pauses.', true);
	pingWarningShown = true;
}

/*
 * Limit the length of a TEXTAREA input
 */
function limitlen( objname, len ) {
	var obj = document.getElementsByName( objname )[0];
	
	if( obj.value.length > len ) {
		obj.value = obj.value.substr( 0, len );
	}
}

function toggle_training_mode() {
	ajax_wrap( 'xml-catch.php', 'pagestate=toggle_training_mode', 'data', function( data ) {
		var menu = $( 'menuitem_training' );

		var search = ( data['mode'] ? /On/ : /Off/ );
		var replace = ( data['mode'] ? "Off" : "On" );

		if( menu.textContent ) 
			menu.textContent = menu.textContent.replace( search, replace );
		else
			menu.innerHTML = menu.innerHTML.replace( search, replace );

		set_active_stylesheet( 'bubble', ( data['mode'] ? 'training' : 'none' ));
	});
}

function close_tooltip( id ) {
	var obj = $( 'ttid_' + id );
	if( !obj ) return;

	obj.style.display = 'none';
	ajax_wrap( 'xml-catch.php', $H({ pagestate: 'seen_tooltip', tip: id }));
}

function tooltip_on( text ) {
	var tt = document.getElementById("tooltip");
	if( tt == null ) return;

	if( tt.style.visibility == 'hidden' ) {
		tt.style.top = yMousePos-20 + "px"; 
		tt.style.left = xMousePos-20 + "px";
		tt.innerHTML = text;
		tt.style.visibility = 'visible';
		tt.focus = true;
	} else {
		tt.style.visibility = 'hidden';
	}
}

// Pass in '' for the default
function home_on( tab ) {
	overlay_on( tab, 'home' );
}

var ovlbox;
var cb;
function overlay_on( text, size ) {
	var oldbox = ovlbox;
	switch (size) {
		default:
		case 'small':
			ovlbox = document.getElementById("overlaybox_small");
			cb = document.getElementById("cb_small");
		break;
		case 'medium':
			ovlbox = document.getElementById("overlaybox_medium");
			cb = document.getElementById("cb_medium");
		break;
		case 'large':
			ovlbox = document.getElementById("overlaybox_large");
			cb = document.getElementById("cb_large");
		break;
		case 'home':
			ovlbox = document.getElementById("overlaybox_large_home");
			cb = document.getElementById("cb_large_home");
		break;
		case 'login':
			ovlbox = document.getElementById("overlaybox_login");
			cb = document.getElementById("overlay_login");
		break;
	}
	if( ovlbox == null ) return;

	var overlay = $( 'overlay' );

	if( size == "home" ) {
		help_add_context('overlay');

		// Forget the last tab (why are we doing this? -ss)
		currentHomeTab = null;

		// Make sure the correct tab is showing
		showTab( text );
	} else if( text.length > 0 ) {
		overlay_set_text( text );
	}

	// If the overlay is currently invisible, we just need to display everything
	if( overlay.style.display == 'none' ) {
		ovlbox.style.display = 'block';
		new Effect.Appear( 'overlay', { to: .98, duration: .5 });

		// Firefox is a pain in the ass!
		$( 'content_' + get_zoom() ).style.overflow = 'hidden';
	}
	// They're switching boxes
	else if( oldbox != null && oldbox.id != ovlbox.id ) {
		new Effect.Fade( oldbox.id, { duration: .5} );
		new Effect.Appear( ovlbox.id, { to: .98, duration: .5} );
	}
	else {
		// It should already be showing, so we're just changing text
	}
}

function close_overlay() {
	if( !ovlbox ) return;

	help_olreplace_context();
	ovlbox.style.display = 'none';
	new Effect.Fade('overlay');
	setTimeout( "$( 'content_' + get_zoom() ).style.overflow = '';", 500 );
}
function overlay_set_text( text, noScroll ) {
	cb.innerHTML = '<div class="message_text">' + text + '</div>';

	if( !noScroll )
		setTimeout('cb.scrollTop = 0;',50);
}

function get_zoom() {
	if( $( 'content_125' )) return 125;
	else if( $( 'content_100' )) return 100;
	else if( $( 'content_150' )) return 150;
    else if( $( 'content_ext' )) return 'ext';
}

var senseiAutoHide = false;
function message_on( text, autoHide ) {
	var msgbox = document.getElementById("message_replace");
	if( msgbox == null ) return;
	msgbox.innerHTML = text;
	if( !Prototype.Browser.WebKit ) {
		Effect.Appear('message',{ to: 1.0 });
	} else {
		msg1 = document.getElementById('message');
		msg1.style.display='block';
	}
	if (autoHide) {
		senseiAutoHide = true;
		setTimeout('message_autohide()', 5000);
	} else {
		if (msgTimerID) clearTimeout(msgTimerID);
		senseiAutoHide = false;
	}
	//if (autoHide) setTimeout('Effect.toggle("message","appear")', 10000);
}

var loadingTimer;
function loading_on(message) {
	loadingDiv = document.getElementById('loading');
	if (!loadingDiv) return;

	if (message != null ) loadingDiv.innerHTML = message;
	loadingDiv.style.display='inline';
	//loadingTimer = setTimeout('loadingDiv.innerHTML = \'Sorry! Please Try Again.\'', 10000);
	loadingTimer = setTimeout('loadingDiv.style.display=\'none\';', 10000);
}
function loading_off(delay) {
	if (delay > 0) {
		setTimeout('reset_loading_div();', delay);
	} else {
		reset_loading_div();
	}
	clearTimeout(loadingTimer);
}
function reset_loading_div(){
		loadingDiv = document.getElementById('loading');
		if (!loadingDiv ) return;

		loadingDiv.style.display='none';
		loadingDiv.innerHTML = 'loading...';
}

function message_with_link_on( text, href, link, autoHide ) {
	var msgbox = document.getElementById("message_replace");
	if( msgbox == null ) return;
	text = text + ' <a href="' + href + '">'+link+'</a>';
	msgbox.innerHTML = text;
	if( !Prototype.Browser.WebKit ) {
		Effect.Appear('message',{ to: 1.0 });
	} else {
		msg1 = document.getElementById('message');
		msg1.style.display='block';
	}
	//if (autoHide) setTimeout('Effect.toggle("message","appear")', 10000);
	if (autoHide) {
		senseiAutoHide = true;
		setTimeout('message_autohide()', 10000);
	} else {
		if (msgTimerID) clearTimeout(msgTimerID);
		senseiAutoHide = false;
	}
}

function message_autohide() {
	if (senseiAutoHide) new Effect.Fade('message');
	senseiAutoHide = false;
}

var unknownLevelWarningFired = false;
function fire_unknown_level_warning() {
	if (unknownLevelWarningFired) return;
	unknownLevelWarningFired = true;
	setTimeout('message_on(\'This subdocument has paragraphs without valid styles; They are highlighted.\')', 3000);
}

// iframe shim to show floating div in IE
function shim_div( divID, state, touchDiv )	{
return false;
	var thisdiv = $( divID );
	var thisif = $( 'shim' );

	if( !thisdiv || !thisif ) return;

	if(state) {
		if( touchDiv )
			thisdiv.style.display = "block";

		thisif.style.width = thisdiv.offsetWidth;
		thisif.style.height = thisdiv.offsetHeight;
		thisif.style.top = thisdiv.style.top;
		thisif.style.left = thisdiv.style.left;

		thisif.style.display = "block";
	} else {
		if( touchDiv )
			thisdiv.style.display = "none";

		thisif.style.display = "none";
	}
}

// Capturing the mouse position...
document.onmousemove = captureMousePosition;
xMousePos = 0; // Horizontal position of the mouse on the screen
yMousePos = 0; // Vertical position of the mouse on the screen
xMousePosMax = 0; // Width of the page
yMousePosMax = 0; // Height of the page

function captureMousePosition(e) {
	 if (! document.body) return;
	 if (document.all) {
		xMousePos = window.event.x+document.body.scrollLeft;
		yMousePos = window.event.y+document.body.scrollTop;
		xMousePosMax = document.body.clientWidth+document.body.scrollLeft;
		yMousePosMax = document.body.clientHeight+document.body.scrollTop;
	} else { 
		xMousePos = e.pageX;
		yMousePos = e.pageY;
		xMousePosMax = window.innerWidth+window.pageXOffset;
		yMousePosMax = window.innerHeight+window.pageYOffset;
	}
}

function thisThumb(fileID) {
	var thumb = document.getElementById("magnified");
	vis = thumb.style.visibility;
	if( vis == 'hidden' || vis == '' ) {
		thumb.style.top = yMousePos + "px"; 
		thumb.style.left = xMousePos+10 + "px";
		thumb.innerHTML = '<img src=\"images/sample.png\">';
		thumb.style.visibility = 'visible';
		thumb.focus = true;
	} else {
		thumb.style.visibility = 'hidden';
	}
}

function show_hide(id) {
	var thisDiv = document.getElementById(id);
	if( thisDiv == null ) return;
	if( thisDiv.style.display == 'none' || thisDiv.style.display == '' ) {
		thisDiv.style.display = 'block';
	} else {
		thisDiv.style.display = 'none';
	}
}


var blockHolderID;
function se_ins_block( uid ) {
	loading_on('working...');
	var url = window.location.pathname + "?action=get_block_insert_text&uid="+uid;
	ajax_wrap( url, null, 'text', function( block ) {
		var after = document.getElementById( 'clausewrap' + uid );
		appendAfter( after, block );
		blockHolderID = uid;
		loading_off();
	});
}

function se_del_block() {
	var holder = document.getElementById('clausewrap-HOLDER-'+blockHolderID)
	if( holder ) {
		var page = document.getElementById( 'editorbox' );
		page.removeChild( holder );
	}
	if (! clauselibwin.closed) clauselibwin.close();
	blockHolderID=null;
}

/*
function se_ins_blank( uid, count ) {
	ajax_wrap( window.location.pathname, "pagestate=insert_and_get&uniqueID="+uid+"&clauseCount="+count, 'data', function( blocks ) {
alert( block );
		var after = document.getElementById( 'clausewrap' + uid );
		//after.style.border = "1px solid red";

		appendAfter( after, block );
	});
}
*/
//
// This appends text/html after 'object'.
//
function appendAfter( object, appendText ) {
	// Used by IE and Opera
	if( object.insertAdjacentHTML ) {
		//alert( "Using insertAdjacentHTML" );
		object.insertAdjacentHTML( 'afterEnd', appendText );
	} 
	// Used by Firefox and Safari
	else {
		//alert( "Using FUNKY method" );
		var r = object.ownerDocument.createRange();
		r.setStartAfter(object);
		var df = r.createContextualFragment( appendText );
		object.parentNode.insertBefore(df, object.nextSibling);
	}
}

/* Timing functions
var timer;
function timer_begin( name ) {
	var d = new Date();
	timer = d.getTime();
}
function timer_end( name ) {
	var d = new Date();
	var diff = d.getTime() - timer;

	alert( "Timer: " + diff );
}
*/

/*  Apparently, this may not be needed!  Try ondblclick()!
var doubleclick_lastclick = 0;
var doubleclick_inuse = 0;
function doubleclick( func ) {
	// Wouldn't it be nice if we could lock with an atomic action?
	// This is to keep out quad-clicks
	if( doubleclick_inuse ) return;
	doubleclick_inuse = 1;

	var d = new Date();
	var timestamp = d.getTime();

	// Threshold - the number of milliseconds between clicks
	var threshold = 100; 

	if( timestamp - doubleclick_lastclick <= threshold ) {
		alert( "Yay - we made it in "+ (timestamp - doubleclick_lastclick) );

		// Reset to keep out triple-clicks
		doubleclick_lastclick = 0;
	} else {
		doubleclick_lastclick = timestamp;
	}

	doubleclick_inuse = 0;
}
*/


/* 
 * The next two functions handle pop-up window that tells users that their files are currently
 * being uploaded.  Simply call pop_files_uploading() just before you submit the form.  The window
 * will auto-close once the parent page is loaded.
 */
var mainWindowClean = true;
function pop_files_uploading() {
	// Bummers.  The code below was really quite clever (if I may say so).  
	fuzz_on(); 
	return;


	var Loc="preview.php?pagestate=uploading";

	var height = 240;
	var width = 540;
	w = window.open(Loc,'uploading','toolbar=0,scrollbars=no,menubar=0,location=0,resizable=no,directories=0,status=0,width='+width+',height='+height+',left='+(( screen.width - width ) / 2 )+',top='+(( screen.height - height ) / 2 ));
	w.focus();

	mainWindowClean = false;
}
function close_files_uploading() {
	// If something went wrong and our parent isn't available anymore
	if( !window.opener ) {
		self.close();
	}

	// Ah!  The main window is done and has refreshed
	else if( window.opener.mainWindowClean == true ) {
		self.close();
	}

	// We need to wait a little bit more
	else {
		setTimeout( 'close_files_uploading()', 250 );
	}
}

var lastThumbID;
function thisThumb( filerev ) {
	var thumb = document.getElementById("magnified");
	var vis = thumb.style.visibility;

	// If it's just another hit for what we're already viewing, just return
	if( vis == 'visible' && lastThumbID == filerev ) {
		return;
	} 
	else {
		if (document.all) { // how do I hate IE, let me count the ways!
			thumb.style.top = ( WindowGetYOffset() + yMousePos - 105 ) + "px"; 
		} else {
			thumb.style.top = ( yMousePos - 105 ) + "px"; 
		}
		thumb.style.left = ( xMousePos+5 ) + "px";
		thumb.innerHTML = '<img src="preview.php?combo='+ filerev + '&thumb=1" />';
		thumb.style.visibility = 'visible';
		thumb.focus = true;

		lastThumbID = filerev;
	}
}

// You must already be on the index.php page
function show_login() {
	overlay_on( '', 'login' );
	login_focus();
}

function login_focus( now ) {
	//return;
	// Sometimes it's not always the login page in here.  Forgive my abuse of this specifically named function. -ss
	var id = null;
	if( $( 'username_input' )) {
		id = 'username_input';
	} else if( $( 'anonName' )) {
		id = 'anonName';
	} 
		
	// Safari is okay with giving a hidden element the focus.  Everyone else needs to wait.  Grrr
	if( id != null ) {
		if( Prototype.Browser.Safari || now ) {
			$( id ).focus();
		} else {
			setTimeout( "$( '" + id + "' ).focus();", 700 );
		}
	}
}

function job_edit(jobmode, direction) {
	var formdata = null;
	if (direction == 'forward') {
		formdata = $( 'jobform' ).serialize();
	}

	// Easy for now, since we only have one pagestate
	if( direction == 'back' ) {
		close_overlay();
		home_on( 'proj' );
		return;
	}

	switch (jobmode) {
		case 'sendname':
			loading_on('sending data....');
			var url = 'xml-catch.php?pagestate=job_sendname';
			ajax_wrap( url, formdata, 'data', function( data ) {
				if( data['next'] == 'home-proj' ) {
					// Mark the newly created job, so we can select it
					plCurrentJob = data['jobID'];
					plCurrentDoc = 0;

					overlay_on( 'proj', 'home' );
				} else {
					// Yikes!  What shall we do here?  For now, we'll just close home.  This will
					// probably eventually be an error state where we need to tell them to fill in all
					// the fields
					close_overlay();
					loading_off();
				}
			});
		break;
	}
}



var OverlayPage;
function launch_overlay_page( page, opt1, opt2 ) {
	loading_on();
	if( page == 'newdoc' ) {
		ajax_wrap( 'newdoc.php', 'jobID=' + opt1, 'text', function( txt ) {
			overlay_on( txt, 'large' );
			loading_off(250);
		});
	} 
	else if( page == 'newjob' ) {
		ajax_wrap( 'xml-catch.php', 'pagestate=job_start&action=new', 'data', function( data ) {
			overlay_on( data['text'], 'large' );
			loading_off(250);
		});
	} 
	else if( page == 'increv' ) {
		var url = window.location.pathname + '?action=get_increv_screen';
		ajax_wrap( url, null, 'data', function( data ) {
			overlay_on( data['text'], 'small' );
			document.incRevForm.memo.focus();
			loading_off(250);
		} );
	} 
	else if( page == 'projopts' ) {
		ajax_wrap( 'project_options.php', 'docID=' + opt1 + '&pagestate=editprojinfo', 'text', function( txt ) {
			overlay_on( txt, 'large' );
			loading_off(250);
		});
	}
	else if( page == 'addsec' ) {
		ajax_wrap( 'project_options.php', 'docID=' + opt1 + '&pagestate=addsections', 'text', function( txt ) {
			overlay_on( txt, 'large' );
			loading_off(250);
		});
	}
	else if( page == 'remsec' ) {
		ajax_wrap( 'project_options.php', 'docID=' + opt1 + '&pagestate=removesections', 'text', function( txt ) {
			overlay_on( txt, 'large' );
			loading_off(250);
		});
	}
	else if( page == 'rename' ) {
		ajax_wrap( 'xml-catch.php', 'docID=' + opt1 + '&sectionID=' + opt2 + '&pagestate=renamesection', 'text', function( txt ) {
			overlay_on( txt, 'medium' );
			loading_off(250);
		});
	}
	else if( page == 'import' ) {
		ajax_wrap( 'import.php', 'docID=' + opt1 + '&jobID=' + opt2 + '&pagestate=import-ajax', 'data', function( data ) {
			overlay_on( data['text'], 'medium' );
			loading_off(250);
		});
	}
	else if( page == 'import-new' ) {
		ajax_wrap( 'import.php', 'docID=0&pagestate=import-ajax', 'data', function( data ) {
			overlay_on( data['text'], 'medium' );
			loading_off(250);
		});
	}
	else if( page == 'import-upload' ) {
		ajax_wrap( 'import.php', 'docID=' + opt1 + '&pagestate=import-ajax-upload', 'data', function( data ) {
			overlay_on( data['text'], 'medium' );
			loading_off(250);
		});
	}
	else if( page == 'import-stylehelp' ) {
		ajax_wrap( 'import.php', 'docID=' + opt1 + '&pagestate=import-ajax-stylehelp', 'data', function( data ) {
			overlay_on( data['text'], 'medium' );
			loading_off(250);
		});
	}
	else if( page == 'import-powertips' ) {
		ajax_wrap( 'import.php', 'docID=' + opt1 + '&pagestate=import-ajax-powertips', 'data', function( data ) {
			overlay_on( data['text'], 'medium' );
			loading_off(250);
		});
	}
	else if( page == 'subdocPrompt-ajax' ) {
		ajax_wrap( 'import.php', 'docID=' + opt1 + '&pagestate=subdocPrompt-ajax', 'data', function( data ) {
			overlay_on( data['text'], 'medium' );
			loading_off(250);
		});
	}
	else if( page == 'sharedoc' ) {
		showTab('share');
	}
	else if( page == 'reqcom' ) { // Request Anon Commenting
		ajax_wrap( 'xml-catch.php', 'docID=' + opt1 + '&pagestate=get_doc_anon_comment', 'text', function( text ) {
			overlay_on( text, 'small' );
			document.anon_comment_invite.email.focus();
			loading_off(250);
		});
	}
	else if( page == 'contactus' ) {
		ajax_wrap( 'xml-nouser.php', 'pagestate=show_contact_us', 'text', function( txt ) {
			overlay_on( txt, 'medium' );
			loading_off(250);
		});
	}
	else if( page == 'edit_term' ) {
		ajax_wrap( window.location.pathname, 'action=edit_term', 'data', function( data ) {
			overlay_on( data['content'], 'medium' );
			loading_off(250);
		});
	}
	else if( page == 'videos' ) {
		var input = {};
		input['pagestate'] = 'get_vid_wrap';
		input['video'] = opt1;

		ajax_wrap( 'xml-nouser.php', input, 'data', function( data ) {
			overlay_on( data['content'], 'large' );
			loading_off(500);
			eval( data['js'] );
		});
	}
	else if( page == 'upgrade' ) {
	    var type = opt1;
		var dest = opt2;

		var input = {};
		input['pagestate'] = 'get_upgrade_screen';
		input['type'] = type;
		input['dest'] = dest;

		ajax_wrap( 'xml-catch.php', input, 'text', function( txt ) {
			overlay_on( txt, 'medium' );
			loading_off( 500 );
		});
	}

	OverlayPage = page;
	help_olreplace_context('overlay');
	help_add_context(page);
	
}
function submit_overlay_page( form ) {
	if( form.id.length == 0 ) {
		alert( form.name + " has no id" );
		return false;
	}
	help_olreplace_context();

	loading_on('sending info...');
	switch( OverlayPage ) {
		case 'newdoc':
			ajax_wrap( 'newdoc.php', $( form.id ).serialize( true ), 'text', function( txt ) {
				overlay_set_text( txt );
				loading_off();
			});
		break;

		case 'increv':
			var url = window.location.pathname;
			ajax_wrap( url, $( form.id ).serialize(), 'data', function( data ) {
				close_overlay();
				// Force a refresh
				reload_browser();
				loading_off();
			});
		break;

		case 'projopts':
		case 'addsec':
		case 'remsec':
			ajax_wrap( 'project_options.php', $( form.id ).serialize( true ), 'text', function( txt ) {
				// Yes, I know this is a hack, but I'm in a hurry -ss
				if( txt == 'done' ) {
					close_overlay();

					if( OverlayPage == 'addsec' || OverlayPage == 'remsec' ) {
						se_refresh_sectionlist();
					}
				} else {
					overlay_set_text( txt );
				}
				loading_off();
			});
		break;

		case 'reqcom':
			ajax_wrap( 'xml-catch.php', $( 'anon_comment_invite' ).serialize( true ));
			close_overlay();
		break;

		case 'rename':
			ajax_wrap( 'xml-catch.php', $( 'renameSection' ).serialize( true ));
			close_overlay();
		break;

		case 'sharedoc':
			ajax_wrap( 'xml-catch.php', $( form.id ).serialize(true ), 'text', function( text ) {
				var objContent = document.getElementById("tabcontent-share");
				objContent.innerHTML = text;
				loading_off();
			});
			break;

		case 'contactus':
			ajax_wrap( 'xml-nouser.php', $( form.id ).serialize( true ), 'text', function( txt ) {
				overlay_on( txt, 'medium' );
				loading_off();
			});
		break;
	}
}

function submit_contactus( form ) {
	ajax_wrap( 'xml-nouser.php', $( form.id ).serialize( true ), 'text', function( txt ) {
		$( 'contactusdiv' ).innerHTML = txt;
		loading_off();
	});
}


// This silly function is necessary because in some cases, Safari
// hangs on any normal way of reloading
function reload_browser() {
	document.reloadForm.submit();
}

function package_form( form ) {
	var str = '';
	var i;

	for( i = 0; i < form.elements.length; i++ ) {
		// Don't submit disabled items
		if( form.elements[ i ].disabled == true ) continue;

		// Don't submit unchecked checkboxes
		if( form.elements[ i ].type == 'checkbox' && form.elements[ i ].checked == false ) continue;

		str += ( i ? '&' : '' ) + form.elements[ i ].name + '=' + urlencode( form.elements[i].value );
	}

	return str;
}

/**
 * Reload the Subdocument List menu
 */
function se_refresh_sectionlist() {
	ajax_wrap( window.location.pathname, 'action=get_doc_menu', 'data', function( data ) {
		var obj = document.getElementById( 'menu_doc' );
		if( !obj ) return null;

		obj.innerHTML = data['menu'];
	});
}

function se_update_level( uid, level, labelTxt ) {
	// Update the hidden field (used for submitting)
	var store = document.getElementById( 'clauseLevel' + uid );
	store.value = level;

	// Update the label
	var label = document.getElementById( 'clLabel' + uid );
	label.innerHTML = labelTxt;

	// Update which item is highlighted
	var list = document.getElementsByName( 'clRow' + uid );
	var cl;
	for( var i = 0; i < list.length; i++ ) {
		cl = ( list[ i ].id == ( 'cl' + level ) ? 'LSselected' : '' );

		// ARRRGGG - why doesn't this work in IE???
		list[ i ].className = cl;
	}
}

function se_manage_terms( mode, variable, value, variable_id, value_id ) {
	var input = {};  // makes an empty array
	input['action'] = 'edit_term';
	input['mode'] = mode;

	if( variable_id != null ) {
		input['variable'] = $( variable_id ).value;
	} else {
		input['variable'] = variable;
	}

	if( value_id != null ) {
		input['value'] = $( value_id ).value;
	} else {
		input['value'] = value;
	}
	
	loading_on();
	ajax_wrap( window.location.pathname, input, 'data', function( data ) {
		overlay_set_text( data['content'], 1 );
		loading_off();
	});
}


function submit_chpass() {
	loading_on('sending data ...');
	ajax_wrap( 'xml-catch.php?pagestate=submit_chpass', $( 'chpass' ).serialize( true ), 'data', function( data ) {
		if( data['success'] == 1 ) {
			// Great - we're done
			set_curtab_contents( null );
		} else {
			// They messed something up - send them back
			//set_curtab_contents( 'custom', data['content'] );
			oldCol2.innerHTML = data['content'];
			oldCol2.scrollTop = 0;
		}
		loading_off();
	});
}

function submit_shareform() {
	loading_on('sending data ...');
	ajax_wrap( 'xml-catch.php?pagestate=send_share', $( 'shareform' ).serialize( true ), 'data', function( data ) {
		var centerRight = document.getElementById('homelist_centerRight_share');
		if( data['success'] > 0  ) {
			// Great - we're done
			set_curtab_contents( null );
		} else {
			// a default
			var err = 'Could not find that user!';

			// Specific errors
			if( data['errmsg'] ) 
			  err = data['errmsg'];
			else if( data['error'] == 'acnting' ) 
			  err = 'The user cannot accept any more shared documents';
			else if( data['error'] == 'self' )
			  err = 'You can\'t share to yourself!';

			// They messed something up - send them back
			centerRight.innerHTML = '<div class="plEntry alert">' + err + '</div>';
		}
		loading_off();
	});
}

function cancel_share( shareID, what ) {
	var data = {};
	data['pagestate'] = 
	data['shareID'] = shareID;

	if( confirm( 'Are you sure you want to cancel this share?' )) {
		loading_on('sending data ...');
		ajax_wrap( 'xml-catch.php', $H({ pagestate: 'cancel_share', shareID: shareID }), 'data', function( data ) {
			home_show( what, 'share' );
			loading_off();
		});
	}
}


function submit_contactinfo( mode ) {
	// a pagestate of 'put_chuserinfo' is set by the GPP (in xml-catch)
	if( mode == 'anonuser' ) {
		document.newcontact.submit();
	} else {
/*
		ajax_wrap( page, $( 'edituser' ).serialize( true ), 'data', function( data ) {
			if( data['success'] == 1 ) {
				// Great - we're done
				set_curtab_contents( null );
			} else {
				// They messed something up - send them back
				set_curtab_contents( 'custom', data['content'] )
			}
		});
*/
	}
}

function submit_chuserinfo( mode ) {
	// a pagestate of 'put_chuserinfo' is set by the GPP (in xml-catch)
	loading_on('sending data ...');
	if( mode == 'anonuser' ) {
		document.edituser.submit();
	} else {
		ajax_wrap( 'xml-catch.php', $( 'edituser' ).serialize( true ), 'data', function( data ) {
			if( data['success'] == 1 ) {
				// Great - we're done
				set_curtab_contents( null );
			} else {
				// They messed something up - send them back
				//set_curtab_contents( 'custom', data['content'] );
				oldCol2.innerHTML = data['content'];
				oldCol2.scrollTop = 0;
			}
			loading_off();
		});
	}
}

function scroll_to_div(divID) {
	var target = document.getElementById(divID);
	if (target) {
		var container = document.getElementById( 'content_125' );
		new Effect.ScrollInContainer( divID, container, {offset: 0} );
	} 
}


function test_senseibox() {
	ajax_wrap( 'xml-catch.php?pagestate=testing&bounce=senseiBox', null, 'text', function( text ) {
		message_on(text, false);
	});
}

function prosorry() {
	var msg = "We are sorry, but we really can't take your money at this stage.\n\n"+
				"We're still a little too 'beta'.\n\n"+
				"We'll be  happy to take your money later on, but for now please try a Basic account.\n"+
				"Thank you.";
	alert(msg);
	document.userlevel.userLevel[0].checked = true;	
}

function handle_anon_user_creation( formid ) {
	loading_on('working ...');
	ajax_wrap( 'xml-nouser.php', $( formid ).serialize( true ), 'text', function( text ) {
		$( 'acntcreate' ).innerHTML = text;
		loading_off(500);
	});
}
function show_anon_account( open ) {
	loading_on('working ...');
	ajax_wrap( 'xml-nouser.php', 'pagestate=create_account&startClean=1', 'text', function( text ) {
		$( 'overlay_login' ).innerHTML = text;
		if( open ) {
			Effect.Fade('overlaybox_large'); 
			Effect.Appear('overlaybox_login',{ to: 1.0 });
		}
		loading_off(1000);
	});
}

function hide_overlaybox( box ) {
	new Effect.Fade( 'overlaybox_' + box );
}

function master_picker_select( masterID ) {			
	if (masterID != document.masterPicker.chooseMaster.options[document.masterPicker.chooseMaster.selectedIndex].value) 
		document.masterPicker.submit();
}

function submit_anon_reqinvite() {
	loading_on('working ...');
	ajax_wrap( 'xml-nouser.php', $( 'reqinv' ).serialize( true ), 'text', function( txt ) {
		$( 'overlay_login' ).innerHTML = txt;
		loading_off(500);
	});
}

function cancel_account_confirm() {
	if( confirm( 'Are you sure you want to cancel your account and delete all your projects?  This action cannot be undone.' )) {
		loading_on('working ...');
		ajax_wrap( 'xml-catch.php', 'pagestate=do_cancel_account&confirm=1', 'text', function( txt ) {
			window.location = 'index.php';
		});
	}
}

function del_doc_confirm( docID ) {
	if( confirm( 'Are you sure you want to delete this document?  This action cannot be undone.' )) {
		var data = {};
		data['docID'] = docID;
		data['confirm'] = 1;
		data['pagestate'] = 'delete_doc';

		loading_on('working ...');
		ajax_wrap( 'xml-catch.php', data, 'text', function( txt ) {
			set_curtab_contents();
			loading_off();
		});
	}

}

function submit_form_on_enter( formID, inputs ) {
	// Since non-IE browsers submit the form on their own, this isn't necessary
	// Without this check, the form actually gets submitted twice.  Yuk.  -ss
	if( !Prototype.Browser.IE ) return;

	Event.observe( window, 'load', function() {
		var key;

		for( var i=0; i < inputs.length; i++ ) {
			Event.observe( $( inputs[ i ] ), 'keypress', function( e ) {
				if( e.which )
					key = e.which;
				else if( e.keyCode )
					key = e.keyCode;
				else
					key = 0;

				if( key == 13 ) {
					$( formID ).submit();
					return false;
				}
				return true;
			});
		}
	});
}

/**
 * Use it like this:
 *
 * get_style_class('aStyleClass').style.display = 'inline';
 *
 * NOTE:  This is untested so far.
 */
function get_style_class( className ) {
	for (var s = 0; s < document.styleSheets.length; s++) {
		if(document.styleSheets[s].rules) {
			for (var r = 0; r < document.styleSheets[s].rules.length; r++) {
				if (document.styleSheets[s].rules[r].selectorText == '.' + className) {
					return document.styleSheets[s].rules[r];
				}
			}
		}
		else if(document.styleSheets[s].cssRules) {
			for (var r = 0; r < document.styleSheets[s].cssRules.length; r++) {
				if (document.styleSheets[s].cssRules[r].selectorText == '.' + className)
					return document.styleSheets[s].cssRules[r];
			}
		}
	}
	
	return null;
}

/**
 *
 */
function set_active_stylesheet( family, name ) {
	var i, a, list, fullfam;
	family = "css/" + family + "_";
	fullfam = family + name + ".";
	list = document.getElementsByTagName( "link" );

	// Go through the entire list of "link" elements
	for( i=0; i < list.length; i++ ) {
		a = list[i];

		// If it's a stylesheet and the "family" matches, we can toggle it
		if( a.getAttribute("rel").indexOf("style") != -1 && a.getAttribute("href").indexOf( family ) == 0 ) {
			a.disabled = ( a.getAttribute("href").indexOf( fullfam ) != 0 );
		}
	}
}


function se_load_page( var1, val1, var2, val2, var3, val3 ) {
	document.de_page_loader.var1.value = val1;
	document.de_page_loader.var1.name = var1;
	document.de_page_loader.var2.value = val2;
	document.de_page_loader.var2.name = var2;
	document.de_page_loader.var3.value = val3;
	document.de_page_loader.var3.name = var3;

	document.de_page_loader.submit();
}

function close_demo() {
	// This function is here so we can easily change what happens at the end of a movie.
	// For now, we'll just close the overlay it's in.  Perhaps later we could take them
	// back to the list of demos?

	close_overlay();
}