/**
 * General Javascript Functions
 *
 * Developed by 1000camels
 *
 */
 
/**
 * disable submit from an return key on a form field
 */
/*document.onkeypress = function(evt) {
	evt = evt || window.event;
	
	var keyCode = evt.keyCode || evt.which || 0;
  if(keyCode == '13') {
		//Event.stop(evt);
  	//return false;
  }
  
  return true;
}*/


/**
 * Hidden Function Keys
 *
 *	 Cmd(mac)/Ctrl(pc) + Option/Alt + B = switch to browse mode
 *	 Cmd(mac)/Ctrl(pc) + Option/Alt + E = switch to edit mode
 *	 Cmd(mac)/Ctrl(pc) + Option/Alt + L = show/hide login window
 *	 Cmd(mac)/Ctrl(pc) + Option/Alt + O = show/hide objectSpace
 *
 */
 
document.onkeydown = function (evt) {
	evt = evt || window.event;
	var keyCode = evt.keyCode || evt.which || 0;
		//try { evt.keyCode = 0;} catch(e) {}
		var keyString = String.fromCharCode(keyCode);
 
  //console.log('keyCode: '+keyCode+' - keyString: '+keyString);
  //alert('keyCode: '+keyCode+' - keyString: '+keyString);
	
	if(keyCode && (keyCode == '18')) { // alt=18, ctrl=17, meta/cmd=224
  	if($('editMode')) {
			//console.log('meta key pressed');
			openCBMessage();
			showAllContainers();
  	}
	}
		
	if (keyCode && evt.altKey && (evt.ctrlKey || evt.metaKey)) {
		//try { evt.keyCode = 0;} catch(e) {}
		//var keyString = String.fromCharCode(keyCode);
		if(keyString == 'B') {
			changeMode('browse');
		}
		if(keyString == 'E') {
			changeMode('edit');
		}
		else if(keyString == 'L') {
			showLoginWindow();
		}
		else if(keyString == 'O') {
			if($('objectSpace')) showHideObjectSpace();
		}
		else if(keyString == 'D') {
			showSystemMessages();
		}
		else if(keyString == 'I') {
			showHide('pageInfo');
		}
		else if(keyCode == '37') {  // left arrow
			if($('previousButton'))  window.location = $('previousButton').href;
		}
		else if(keyCode == '39') {  // right arrow
			if($('nextButton')) window.location = $('nextButton').href;
		}
		return true;
	}
	
	return true;
}


document.onkeyup = function (evt) {
	evt = evt || window.event;
	var keyCode = evt.keyCode || evt.which || 0;
		var keyString = String.fromCharCode(keyCode);
	
	if(keyCode && (keyCode == '18')) { // alt=18, ctrl=17, meta/cmd=224
		if($('editMode')) {
			//console.log('meta key released');
			ModalWindow = false;
			closeCBMessage();
			hideOtherContainerOutlines(0);
		}
	}
 
	return true;
} 


document.onmousedown = function (evt) {
	evt = evt || window.event;
	
	if($('editMode') && !ModalWindow && (evt.altKey) && Event.isLeftClick(evt)) {
  	Event.stop(evt);
  	if(Event.element(evt).hasClassName('koContainer')) {
  		var thisKO = Event.element(evt);
  	} else {
			var koContainer = Event.element(evt).up('.koContainer');
			if(koContainer) {
  			var thisKO = koContainer;
			}
  	}
  	if(thisKO) {
  		var koId = getId(thisKO.getAttribute('id'), '^ko(\\d+)');
			/*Event.observe(thisKO, 'mouseup', function(e) {
					//destroyContainerOutline(koId);
					Event.stop(e);
				}
			);*/
  		//console.log('enclosed in '+koId);
			showProgressOverlay();
  		openControlBox(koId);
  		ModalWindow = true;
  	}
  	
		return true;
	}

	return true;
}
var ModalWindow = false;
 

/* *****************************************************************************************/

function openCBMessage() {
  var cbMessage = document.getElementById('cbMessage');
  if(cbMessage) {
  	cbMessage.style.visibility = 'visible';
  } else {
 		var cbMessage = document.createElement('div');
  	 cbMessage.setAttribute('id','cbMessage');
 		 $$('BODY')[0].appendChild(cbMessage);
 		var cbMessageContainer = document.createElement('div');
 		 cbMessage.appendChild(cbMessageContainer);
 		var cbMessageSpan = document.createElement('span');
 		 cbMessageContainer.appendChild(cbMessageSpan);
 		var cbMessageText = document.createTextNode('Click anywhere to open a control panel for that object');
 		 cbMessageSpan.appendChild(cbMessageText);
 		 
 		Event.observe(cbMessage,'mouseover',closeCBMessage);
  }
} 
 
function closeCBMessage() {
  var cbMessage = $('cbMessage');
  if(cbMessage) {
  	cbMessage.style.visibility = 'hidden';
	}
}


function showAllContainers() {
	var allKOs = $$('.koContainer');
	for(var i=0;i<allKOs.length;i++) {
		var id = allKOs[i].getAttribute('id')
		if(matches = id.match(/^ko(\d+)/)) {
			var thisId = matches[1];
  		createContainerOutline(thisId);
		}
	}
}

/*function hideAllContainers() {
	var allKOs = $$('.koContainer');
	for(var i=0;i<allKOs.length;i++) {
		var id = allKOs[i].getAttribute('id')
		if(matches = id.match(/^ko(\d+)/)) {
			var thisId = matches[1];
  		createContainerOutline(thisId);
		}
	}
}*/


/**
 * opens new window and manages focusing
 *
 * http://www.codestore.net/store.nsf/unid/DOMM-4PYJ3S?OpenDocument
 *
 * @access public
 * @return TBD
 */
function windowOpener(url, windowName, args) {
	/* ******************************
	the newWindows array stores an object reference for
	each separate window that is called, based upon
	the url attribute that is supplied as an argument
	*******************************/
	
	//if(window[windowName]) alert('found the new window');
	
	if ( typeof( newWindows[windowName] ) != "object" ){
		newWindows[windowName] = window.open(url,windowName,args);
	} else {
		if (!newWindows[windowName].closed && newWindows[windowName].location) {
			if(newWindows[windowName].location.href != url) {
				newWindows[windowName].location.href = url;
			}
		} else {
			newWindows[windowName] = window.open(url,windowName,args);
		}
	}
	if(!newWindows[windowName].opener) newWindows[windowName].opener = self;
	
	if(window.focus) newWindows[windowName].focus();
	
	// save newWindows to php session
	
	return newWindows[windowName];
}
var newWindows = new Array();


/**
 * Wrapper for overlib - not being used right now
 *
 * @access public
 * @return TBD              
 */
function showMessage(koId) 
{
	//overlib(msg, STICKY);
	var helpWindow = 'help'+koId;
	
	var over = document.getElementById("overDiv");
	
	
	if (olNs4) {
		var lyr = o3_frame.document[helpWindow].document
		lyr.write(txt)
		lyr.close()
	} else if (typeof over.innerHTML != 'undefined') {
		if (olIe5 && isMac) over.innerHTML = '';
		over.innerHTML = txt;
	} else {
		range = o3_frame.document.createRange();
		range.setStartAfter(over);
		domfrag = range.createContextualFragment(txt);
		
		while (over.hasChildNodes()) {
			over.removeChild(over.lastChild);
		}
		
		over.appendChild(domfrag);
	}
	
	return;
}

/**
 * Opens a window with the system messages of the last execution cycle
 *
 * @access public
 * @return TBD            
 */
function showSystemMessages() {
	var baseURL = getBaseURL();
	windowOpener(baseURL+'lib/Core/KO/scripts/getSystemMessages.php', 'systemMessages', "width=640,height=480,top=20,left=20,toolbar=no,location=no,directories=no,status=yes,menubar=yes,scrollbars=yes,resizable=yes");
}


/**
 * Opens a window for the help
 *
 * @access public
 * @return TBD            
 */
function showHelp(url) 
{
	if(!helpWindow || helpWindow && helpWindow.closed) {
		helpWindow = window.open(url, "HelpViewer", "width=640,height=480,top=20,left=20,toolbar=no,location=no,directories=no,status=yes,menubar=yes,scrollbars=yes,resizable=yes");
	} else {
		//helpWindow.location.reload();
		helpWindow.focus();
	}
}
// defines variable outside of function to make it global
var helpWindow = null;


/**
 * toggles the bort's information drawer
 *
 * @access public
 * @return TBD
 */
function showHide(id,cleanUrlBase)
{
	var obj = document.getElementById(id);
	
	if(!obj) { return false; }
	if(obj.style.display == 'none'){
		obj.style.display = '';
	}
	else{
		obj.style.display = 'none';
		
		// redraw content to avoid bug - turned off because it's too flashy - dwc
		redrawParentElement('content');
	}
}


/**
 * 
 */
function showHideByLink(id,donotredraw)
{	
	var obj = document.getElementById(id);
	
	if(!obj) { return false; }
	if(obj.style.display == 'none'){
		obj.style.display = '';
			}
	else{
		obj.style.display = 'none';
				
		// redraw content to avoid bug - turned off because it's too flashy - dwc
		if(!donotredraw) redrawParentElement('content');
	}	
}


/**
 * Redraws the parent node, to force changes in the dom
 *
 * @access public
 * @return TBD             
 */
function redrawParentElement(thisId) {
	var thisContent = document.getElementById(thisId);
	thisContent.parentNode.replaceChild(thisContent, thisContent);
}


/**
 * loads in html fragments into a given location
 */
function insertHTMLFragment(container,url,onCompleteFunction) {
	var myAjax = new Ajax.Updater (
		container,
		url,
		{ 
			method: 'get',
			onComplete: onCompleteFunction,
			onFailure: showFailureMessage,
			onException: showException
		}
	);
}


/**
 * Opens up a new window with the session manager in it
 *
 * @access public
 * @return TBD              
 */
function manageSessions(basePath) {
	if(!sessionWin || sessionWin && sessionWin.closed) {
		sessionWin = window.open(basePath + "lib/CLN/interfaces/SessionVars.php", "SessionManager", "width=640,height=480,top=20,right=20,toolbar=no,location=no,directories=no,status=yes,menubar=yes,scrollbars=yes,resizable=yes");
	} else {
		sessionWin.location.reload();
		sessionWin.focus();
	}	
}
var sessionWin = null;		// needs to be defined globally for manageSessions to work


/**
 * prepares the input button to use js updateVersioNumber()
 */
function prepareUpdateVersionNumber() {
	if($('updateVersionNumber')) Event.observe('updateVersionNumber', 'click', updateVersioNumber);
}


/**
 *
 */
function updateVersioNumber() {
	var koMetadataVersion = document.getElementById('koMetadataVersion');
	var versionNumberDisplay = document.getElementById('versionNumberDisplay');
	
	if(koMetadataVersion.value) {
		var newVersionNumber = Math.ceil(koMetadataVersion.value+1).toPrecision(2);
	} else {
		var newVersionNumber = 0.1;
	}
	koMetadataVersion.value = newVersionNumber+'NEW';
	versionNumberDisplay.firstChild.nodeValue = newVersionNumber;
	this.parentNode.removeChild(this);
}


/**
 * changes the view for the photogallery - deprecated - use changeDisplayStyle()
 */
function changeView(view) {
	if($('imageDisplay')) {
		if(view == 'list') {
			$('imageDisplay').addClassName('imageList');
			$('imageDisplay').removeClassName('imageThumbs');
			setSessionVariable('imageDisplayType','imageList');
		} else {
			$('imageDisplay').addClassName('imageThumbs');
			$('imageDisplay').removeClassName('imageList');
			setSessionVariable('imageDisplayType','imageThumbs');
		}
	}
}


/**
 * tries to determine whether to show thumbnails or a list
 */
function prepareSetDisplay() {
	console.log('prepareSetDisplay');
	
	var setDisplays = $$('ul.setDisplay');
	// :QUESTION: could there be more than one set?
	var setDisplay = setDisplays[0];
	if(setDisplay) {
		var images = $$('ul.setDisplay img');
		for(var i=0;i<images.length;i++) {
			if(src = images[i].getAttribute('src')) {
				var hasImageSrc = true;
				break;
			}
		}
		if(hasImageSrc) {
			changeDisplayStyle('thumbnailDisplay');
		} else {
			changeDisplayStyle('listDisplay');
		}
	}
}


/**
 * changes the view for the photogallery
 */
function changeDisplayStyle(style) {
  console.log('changing to '+style);
			
	var setDisplays = $$('ul.setDisplay');
	var setDisplay = setDisplays[0];
	if(setDisplay) {
		if($('listDisplayLink')) $('listDisplayLink').removeClassName('activeDisplayStyle');
		if($('columnDisplayLink')) $('columnDisplayLink').removeClassName('activeDisplayStyle');
		if($('thumbnailDisplayLink')) $('thumbnailDisplayLink').removeClassName('activeDisplayStyle');
		
		if(style == 'listDisplay') {
			setDisplay.addClassName( 'listDisplay');
			if($('listDisplayLink')) $('listDisplayLink').addClassName('activeDisplayStyle');
			setDisplay.removeClassName( 'columnDisplay');
			setDisplay.removeClassName( 'thumbnailDisplay');
			//setSessionVariable('SetDisplayStyle','listDisplay');
		}
		else if(style == 'columnDisplay') {
			setDisplay.addClassName( 'columnDisplay');
			if($('columnDisplayLink')) $('columnDisplayLink').addClassName('activeDisplayStyle');
			setDisplay.removeClassName( 'listDisplay');
			setDisplay.removeClassName( 'thumbnailDisplay');
			//setSessionVariable('SetDisplayStyle','columnDisplay');
		}
		else if(style == 'thumbnailDisplay') {
			setDisplay.addClassName( 'thumbnailDisplay');
			if($('thumbnailDisplayLink')) $('thumbnailDisplayLink').addClassName('activeDisplayStyle');
			setDisplay.removeClassName( 'listDisplay');
			setDisplay.removeClassName( 'columnDisplay');
			//setSessionVariable('SetDisplayStyle','thumbnailDisplay');
		} else {
			// default to list
			setDisplay.addClassName( 'listDisplay');
			if($('listDisplayLink')) $('listDisplayLink').addClassName('activeDisplayStyle');
			setDisplay.removeClassName( 'columnDisplay');
			setDisplay.removeClassName( 'thumbnailDisplay');
			//setSessionVariable('SetDisplayStyle','listDisplay');
		}
		
		setAllMiniControlBoxPositions();
	}
}


/**
 *
 */
function getContentSelector(e) {
	//var triggerElement = Event.element(e);
	
	if(!$('allContentSearch')) {
		var allContentSearch = document.createElement('span');
	 	allContentSearch.setAttribute('id','allContentSearch');
		$$('BODY')[0].appendChild(allContentSearch);
		
		var url = getBaseURL()+"lib/Core/KO/scripts/getAllContent.php";
		insertHTMLFragment($('allContentSearch'),url, searchIsLoaded);
		showProgressOverlay();
	} else {
		$('allContentSearch').style.display = 'block';
	}
}


/**
 *
 */
function searchIsLoaded() {
	$('allContentSearch').style.display = 'block';
	$('allContentSearch').addClassName('multiSelectionContainer');
	discoverMultiSelectionContainers();
	hideProgressOverlay();
}


/**
 *
 */
function hideContentSelector() {
	$('allContentSearch').style.display = 'none';
}


/**
 * add a slide container around content
 */
function addSlideContainer(imageContent) {
	var photoSlideContainer = document.createElement('div');
	 photoSlideContainer.setAttribute('class','photoSlideContainer');
	var photoSlide = document.createElement('div');
	 photoSlide.setAttribute('class','photoSlide');
	 photoSlideContainer.appendChild(photoSlide);
	var emptySpan = document.createElement('span');
	 photoSlide.appendChild(emptySpan);
	 photoSlide.appendChild(imageContent);
	
	return photoSlideContainer;
}


/**
 * add a slide container around content
 */
function removeSlideContainer() {

}


/**
 * sets the title for the page
 */
function setPageTitle(title) {
	var pageTitle = document.getElementById('pageTitle');
	var pageTitleValue = pageTitle.firstChild.nodeValue;
	var titleParts = pageTitleValue.split(' - ');
	pageTitle.firstChild.nodeValue = titleParts[0]+title;
}


/**
 * 
 */
function setupMessageWindows() {
	if($('userMessages')) {
		Event.observe('userMessages', 'click', function(e) {
				if(window.event) {
					var srcElement = window.event.srcElement;
				} else {
					var srcElement = e.currentTarget;
				}
				srcElement.style.visibility = 'hidden';
			}
		);
	}
	if($('errorMessages')) {
		Event.observe('errorMessages', 'click', function(e) {
				if(window.event) {
					var srcElement = window.event.srcElement;
				} else {
					 var srcElement = e.currentTarget;
				}
				srcElement.style.visibility = 'hidden';
			}
		);
	}
}


/**
 * prepares slidingDrawers (markup that can be toggled)
 *	- requires two nodes with classes, slidingDrawer and slidingDrawerController and the controller
 *  must have the same id as the drawer with the word 'Controller' appended to it (ie. someDrawerController)
 */
function setupDrawers() {
	// this is done in css now, to make it immediate
	var allDrawers = $$('.slidingDrawer');
	if(allDrawers.length > 0) {
		for (i=0; i < allDrawers.length ; i++) {
			// hide drawers
			var styles = 'display:none';
			var oldStyles = allDrawers[i].getAttribute('style');
			if(oldStyles) {
				styles = styles+';'+oldStyles;
			}
			allDrawers[i].setAttribute('style',styles);
			
			// create close button
			if(allDrawers[i].getStyle('position') == 'absolute') {
				var closeButton = document.createElement('span');
				 allDrawers[i].appendChild(closeButton);
				 closeButton.setAttribute('class','closeButton');
				 closeButton.style.position = 'absolute';
				var closeButtonText = document.createTextNode('close');
				 closeButton.appendChild(closeButtonText);
				 
						var dimensions = allDrawers[i].getDimensions();
						closeButton.style.top = allDrawers[i].offsetTop+dimensions.height-20+'px';
						closeButton.style.left = allDrawers[i].offsetLeft+dimensions.width-30+'px';
				 
				Event.observe(closeButton,'click',function(e) {
						var slidingDrawer = Event.element(e).parentNode;
						var thisId = slidingDrawer.getAttribute('id');
						Effect.toggle(thisId,'APPEAR'); 
					}
				);
			}
		}
	}
	var allDrawerControllers = $$('.slidingDrawerController');
	if(allDrawerControllers.length > 0) {
		for (i=0; i < allDrawerControllers.length; i++) {
			Event.observe(allDrawerControllers[i],'click', function() {
					var thisId = this.getAttribute('id');
					if(matches = thisId.match(/^(\w+)Controller/)) {
						var thisDrawerId = matches[1];
						
						Effect.toggle(thisDrawerId,'APPEAR');
						return false;
					}
				}
			);
		}
	}
}


function setupVersionSelector() {
	var allVersionSelectors = $$('.versionSelector');
	if(allVersionSelectors.length > 0) {
		for (i=0;i<allVersionSelectors.length;i++) {
			Event.observe(allVersionSelectors[i],'change',function(e) {
					var thisSelect = Event.element(e);
					var selectedVersion = thisSelect.options[thisSelect.selectedIndex].value;
					if(window.location.search == '') {
						window.location.search = '?setVersion='+selectedVersion;
					} else {
						window.location.search = window.location.search+'&setVersion='+selectedVersion;
					}
				}
			);
		}
	}
}



/* ***************************************************************************/
// AutoCompleter

/**
 *
 */
function setupAutoCompleter() {
	var allAutoCompleters = $$('input.autocompleter');
	
	// doesn't prevent this from being loaded for input fields other than text
	for (i=0; i < allAutoCompleters.length ; i++) {
		// prepare autocompleter
		var autocompleteField = allAutoCompleters[i];
			//autocompleteField.value = '';
		var autocompleteId = allAutoCompleters[i].getAttribute('id');  // autocomplete id
		if(autocompleteId) {
			// create autocomplete indicator image
			var indicatorId = autocompleteId+'Indicator';		// indicator image id
			var autocompleteIndicatorElement = createACIndicatorElement(indicatorId);
			 insertAfter(autocompleteIndicatorElement, autocompleteField);
			 
			// create autocompleter choices field
			var autocompleteChoicesId = autocompleteId+'Choices';
			var autocompleteChoicesField = createACChoicesElement(autocompleteChoicesId);
			 insertAfter(autocompleteChoicesField, autocompleteField);
			
			if($(autocompleteId+'MinChars')) {
				var minimumCharacters = document.getElementById(autocompleteId+'MinChars').firstChild.nodeValue;
			} else {
				var minimumCharacters = 3;
			}

			// url for autocompleter script
			var baseURL = getBaseURL();
				
			var urlElement = $(autocompleteId+'URL');
			if(urlElement) {
				var url = baseURL+urlElement.firstChild.nodeValue;
			} else {
				// get modIds
				var modIdsElement = $(autocompleteId+'ModIds');
				if(modIdsElement) {
					var url = baseURL+"lib/Core/KO/scripts/getAutoCompletion.php?modId="+modIdsElement.firstChild.nodeValue;;
				}
			}
			
			if(url) {
				var options = { paramName: "hint", minChars: minimumCharacters, indicator: indicatorId, afterUpdateElement: ACAfterUpdateElement };
				
				if(autocompleterObject[autocompleteId] == undefined) {
					autocompleterObject[autocompleteId] = new Ajax.Autocompleter(autocompleteId, autocompleteChoicesId, url, options);
				} else {
					autocompleterObject[autocompleteId].initialize(autocompleteId, autocompleteChoicesId, url, options);
				}
				
				// not clear that we always want to focus on this element
				//autocompleteField.focus();
			}
		}
	}
}


/**
 * create autocompleter indicator image element
 */
function createACIndicatorElement(indicatorId) {
	var baseURL = getBaseURL();
	
	var autocompleteIndicatorElement = document.createElement('span');
	autocompleteIndicatorElement.setAttribute('id',indicatorId);
	autocompleteIndicatorElement.setAttribute('class','autocompleterIndicator');
	autocompleteIndicatorElement.style.display = 'none';
	var autocompleteIndicatorImage = document.createElement('img');
	autocompleteIndicatorImage.setAttribute('src',baseURL+'lib/Core/KO/images/indicator-black.gif');
	autocompleteIndicatorImage.setAttribute('alt','working...');
	 autocompleteIndicatorElement.appendChild(autocompleteIndicatorImage);
	
	return autocompleteIndicatorElement;
}


/**
 * create autocompleter choices element
 */
function createACChoicesElement(choicesId) {
	// create autocompleter choices field
	var autocompleteChoicesField = document.createElement('div');
	autocompleteChoicesField.setAttribute('id',choicesId);
	autocompleteChoicesField.setAttribute('class','autocomplete');
	
	return autocompleteChoicesField;
	 //insertAfter(autocompleteChoicesField, autocompleteField);
}


/**
 *
 */
function ACAfterUpdateElement(text, li) {
	var acName = text.getAttribute('name');
	// only create once
	var hiddenField = document.getElementById((acName+'SelectedKoId'));
	if (hiddenField == null) {
		var hiddenField = document.createElement('input');
		hiddenField.setAttribute('type','hidden');
		hiddenField.setAttribute('id',acName+'SelectedKoId');
		hiddenField.setAttribute('name',acName+'SelectedKoId');
		hiddenField.setAttribute('value',li.id.replace('result',''));
		text.parentNode.appendChild(hiddenField);
	} else {
		hiddenField.setAttribute('value',li.id.replace('result',''));
	}
	
	// look for additional functions to call
	var afterUpdate = document.getElementById((acName+'AfterUpdate'));
	if(afterUpdate) {
		var afterUpdateFunction = afterUpdate.firstChild.nodeValue;
		eval(afterUpdateFunction);
	}
}
var autocompleterObject = new Array();



/* ***************************************************************************/
// In Place Editors

/**
 * find and setup inPlace editors
 *
 * requires classname 'inPaceEditor' and another object holding the url with the classname equal to object's id + 'EditorURL'
 */
function setupInPlaceEditors(root) {
	if(root == undefined) var root = document
	var inPlaceEditors = $$('.inPlaceEditor');

	for (i=0; i < inPlaceEditors.length ; i++) {
		var editorName = inPlaceEditors[i].getAttribute('id');
 		if(editorName) {
 			var editorURLs = $$('.'+editorName+'EditorURL');
 			if(editorURLs[0]) {
 				var thisURL = editorURLs[0].firstChild.nodeValue;
				var options = { size: "10", callback: inPlaceEditorCallback, ajaxOptions: { method: 'get' }, okText: "save" };
				
				if(newInPlaceEditors[editorName] == undefined) {
					newInPlaceEditors[editorName] = new Ajax.InPlaceEditor(editorName, getBaseURL()+thisURL, options);
 				} else {
 					newInPlaceEditors[editorName].initialize(editorName, getBaseURL()+thisURL, options);
 				}
 			}
 		}
 	}
}
var newInPlaceEditors = new Array();


/**
 *
 */
function inPlaceEditorCallback(form, value) {
	var matches = form.getAttribute('id').match(/^(\w+)-/);
	var editorName = matches[1];
	var data = 'editorName='+editorName;
	var additionalParams = $$('.'+editorName+'Params');
	if(additionalParams[0]) {
		data += '&'+additionalParams[0].firstChild.nodeValue;
	}
	return data+'&value=' + escape(value);
}



/* ***************************************************************************/


/**
 * finds baseurl in document and returns it
 */
function getBaseURL() {
	var baseurl = document.getElementById("baseurl").firstChild.nodeValue;
	if(baseurl) {
		return baseurl;
	} else {
		return '';
	}
}


/**
 * checks and unchecks all checkboxes within container
 */
function checkUncheckAll(checkboxContainer, check) {
	var checkboxContainer = document.getElementById(checkboxContainer);
	var allInputs = checkboxContainer.getElementsByTagName('input');
	for(var i=0;i<allInputs.length;i++) {
		if(allInputs[i].getAttribute('type') == 'checkbox') {
			if(check) {
				allInputs[i].setAttribute('checked',1);
			} else {
				allInputs[i].removeAttribute('checked');
			}
		}
	}
}


/**
 * 
 */
function showMessages() {
	if(messageWindow) messageWindow.style.visibility = 'visible';
}


/**
 * 
 */
function showLoginWindow() {
	//showProgressOverlay();
	showHideByLink('loginExpand');
	var loginButtons = $$('.loginButton');
	if(loginButtons.length > 0) {	
		for(var i=0;i<loginButtons.length;i++) {
				var loginText = loginButtons[i].childNodes[0].nodeValue;
				if(loginText) {
					if(loginText == 'Login') {
						loginButtons[i].childNodes[0].nodeValue = 'Hide Login';
					} else {
						loginButtons[i].childNodes[0].nodeValue = 'Login';
					}
				}
		}
	}
}


/**
 * switches between edit and browse mode
 */
function changeMode(newMode) {
	var myString = top.location.search;
	
	// We get rid of the leading "?"
	myString = myString.substring(1);
	
	// We separate each name and value pairs
	var myArray = myString.split("&");
	
	// We are going through the array one element at a time
	for (i=0; i < myArray.length ; i++) {
	
		// We split the name and value pair
		var mySubArray = myArray[i].split("=");
	
		if(mySubArray[0] == 'editMode') {
			mySubArray[1] = newMode;
			var editMode = true;
		}
		myArray[i] = mySubArray.join("=");
		
	}
	
	if(!editMode) {
		if(myArray[0] == '') { var myArray = new Array(); }
		myArray.push('editMode='+newMode);
	}
	
	var myString = myArray.join("&");
	var newSearch = '?'+myString;
	
	if(newSearch != top.location.search) {
		top.location.search = newSearch;
	}
}




/**
 * 
 */
function addLoadEvent(func) {
  var oldonload = window.onload;
  if (typeof window.onload != 'function') {
    window.onload = func;
  } else {
    window.onload = function() {
    	oldonload();
      func();
    }
  }
  // this helps with a bug where the controllers are not redrawn after resizing
  // i've commented this out for now, because when IE loads, this causes it to fire several times - dwc
  //window.onresize = window.onload
}

/**
 * 
 */
function insertAfter(newElement,targetElement) {
  var parent = targetElement.parentNode;
  if (parent.lastChild == targetElement) {
    parent.appendChild(newElement);
  } else {
    parent.insertBefore(newElement,targetElement.nextSibling);
  }
}


/**
 * does element have className - deprecated - uses prototypes method
 */
function hasClass(element,value) {
  return element.hasClassName(value);
}


/**
 * add className - deprecated - uses prototypes method
 */
function addClass(element,value) {
  return element.addClassName(value);
}


/**
 * remove className - deprecated - uses prototypes method
 */
function removeClass(element,value) {
  return element.removeClassName(value);
}


/**
 * getElementsByClassName
 *	- Written by Jonathan Snook, http://www.snook.ca/jonathan
 *  - Add-ons by Robert Nyman, http://www.robertnyman.com
 */
function getElementsByClassName(oElm, strTagName, strClassName) {
    return $$(strTagName+' .'+strClassName);
}


/**
 * removes the element, but keeps the children
 */
function removeSurroundingElement(element) {
	var children = element.childElements();
	for(var i=0;i<children.length;i++) {
		element.parentNode.appendChild(children[i]);
	}
	element.remove();
}


/**
 * parses a url and provides interfaces to the key/values
 *
 * found at: http://www.eggheadcafe.com/articles/20020107.asp
 */
function ParseURL(url) {
	if(url.length > 1) {
		this.url = url.substring(1, url.length);
	} else {
		this.url = null;
	}
	if(this.url.match('/?/')) {
		this.base = this.url.split("?")[0];
		this.path = this.url.split("?")[1];
	} else {
		this.base = this.url;
		this.path = this.url;
	}
	this.keyValuePairs = new Array();
	if(this.path) {
		for(var i=0; i < this.path.split("&").length; i++) {
			this.keyValuePairs[i] = this.path.split("&")[i];
		}
	}
	this.getKeyValuePairs = function() { return this.keyValuePairs; }
	this.getValue = function(s) {
		for(var j=0; j < this.keyValuePairs.length; j++) {
			if(this.keyValuePairs[j].split("=")[0] == s) return this.keyValuePairs[j].split("=")[1];
		}
		return false;
	}
	this.getParameters = function() {
		var a = new Array(this.getLength());
		for(var j=0; j < this.keyValuePairs.length; j++) {
			a[j] = this.keyValuePairs[j].split("=")[0];
		}
		return a;
	}
	this.getLength = function() { return this.keyValuePairs.length; }
}


/**
 * sets a registered session variable
 */
function setSessionVariable(name,value) {
	var baseurl = getBaseURL();
	var data = 'name='+name+'&value='+value;
	var setSessionURL = baseurl+'lib/Core/KO/scripts/setSessionVariables.php';
	
	var myAjax = new Ajax.Request(
    setSessionURL,
    { 
    	method: 'get',
    	parameters: data, 
    	onSuccess: function() {
				//alert(name+','+value);
    	},
    	onFailure: showFailureMessage,
    	onException: showException
    }
	);
}

/**
 * loads header items from Ajax calls
 * 	- borrowed from ajaxtabs until a rewrite
 */
function loadHeaders(revattribute) {
	if (revattribute!=null && revattribute!="") { //if "rev" attribute is defined (load external .js or .css files)
		//var objectlist=revattribute.split(/\s*,\s*/) //split the files and store as array
		var objectlist = document.getElementById(revattribute).getElementsByTagName('link');
		alert(objectlist.length);
		for (var i=0; i<objectlist.length; i++) {
			var file=objectlist[i].getAttribute('href');
			var fileref=""
			alert(file)
			if (loadedobjects.indexOf(file)==-1) { //Check to see if this object has not already been added to page before proceeding
				if (file.indexOf(".js")!=-1) { //If object is a js file
					fileref=document.createElement('script')
					fileref.setAttribute("type","text/javascript");
					fileref.setAttribute("src", file);
				}
				else if (file.indexOf(".css")!=-1) { //If object is a css file
					fileref=document.createElement("link")
					fileref.setAttribute("rel", "stylesheet");
					fileref.setAttribute("type", "text/css");
					fileref.setAttribute("href", file);
				}
			}
			if (fileref!=""){
				document.getElementsByTagName("head").item(0).appendChild(fileref)
				loadedobjects+=file+" " //Remember this object as being already added to page
			}
		}
	}
}


/**
 * this is just a rough outline of what we can do with clnFormContext - help for the form fields
 * eventually, we'll make them a little more stylized
 */
function setupFormContext() {
	var allFormContext = $$('.clnFormContext');
	//var allFormContext = new Array();
	if(allFormContext.length > 0) {
		for(var i=0;i<allFormContext.length;i++) {
			//Elements.extend(allFormContext[i].parentNode);
			var formContainer = allFormContext[i].parentNode;
			// must extend the element or this fails in IE
			Element.extend(formContainer);
			if(formContainer) { // && formContainer.hasClassName('clnRow')) {
				var labels = formContainer.getElementsByTagName('label');
				if(labels[0]) {
					textBoxDisplay(labels[0], allFormContext[i]);
				}
			}
		}
	}
}

/**
 * shows one object overtop of the trigger object - much like overlib
 *
 */
function textBoxDisplay(triggerObj,displayObj) {
	Event.observe(triggerObj, 'mouseover', function(e) {
			setPosition(Event.element(e));
			displayObj.style.visibility = 'visible';
			displayObj.style.top = (Event.element(e).y+Event.element(e).h)+'px'; //(posy+offset)+'px';
			displayObj.style.left = (Event.element(e).x+Event.element(e).w)+'px'; //(posx+offset)+'px';
		}
	);
	
	Event.observe(triggerObj, 'mouseout', function(e) {
			displayObj.style.visibility = 'hidden';
		}
	);
}


/**
 * handles failure from ajax request
 */
function showFailureMessage(requestObj) {
	//alert('Ajax Failure: '+requestObj.statusText);
	return true;
}


/**
 * handles exception from ajax request
 */
function showException(requestObj, exception) {
	//alert('Ajax Exception: '+exception);
	return true;
}



/**
 * Returns true if the passed value is found in the
 * array.  Returns false if it is not.
 */
Array.prototype.inArray = function (value){
	var i;
	for (i=0; i < this.length; i++) {
			// Matches identical (===), not just similar (==).
			if (this[i] === value) {
					return true;
			}
	}
	return false;
};


/**
 * remove value from array, wherever it is in the array
 */
function removeElement(thisArray,thisValue) {	
	if(thisArray.length > 0) {
		newArray = new Array();
		for(i=0;i<thisArray.length;i++) {
			if(thisArray[i] != thisValue) {
				newArray.push(thisArray[i]);
			}
		}
		
		return newArray;
	} else {
		return thisArray;
	}
}


/**
 *
 */
function prepareDeleteMarkupElement() {
	var deleteMarkupElements = $$('.deleteMarkupElement');
	for(i=0;i<deleteMarkupElements.length;i++) {
		deleteMarkupElements[i].setAttribute('title','Remove Field');
		Event.observe(deleteMarkupElements[i],'click',deleteMarkupElement);
	}
}


/**
 *
 */
function deleteMarkupElement(e) {
	var thisElement = Event.element(e).previous();
	var elementId = thisElement.getAttribute('id');
	if(matches = elementId.match(/^(\w+)\[/)) {
		var rootElement = matches[1];
		
		if(!$('delete_'+elementId)) {
			var deleteElement = document.createElement('input');
			deleteElement.setAttribute('type','hidden');
			deleteElement.setAttribute('id','delete_'+elementId);
			deleteElement.setAttribute('name',rootElement+'[#DELETE][]');
			deleteElement.setAttribute('value',elementId);
			
			insertAfter(deleteElement, Event.element(e));
			
			// indicate element is marked for deletion
			var thisLabel = thisElement.up(1).down('label');
			if(thisLabel) {
				thisLabel.style.textDecoration = 'line-through';
			}
		} else {
			$('delete_'+elementId).remove();
			// indicate element is no longer marked for deletion
			var thisLabel = thisElement.up(1).down('label');
			if(thisLabel) {
				thisLabel.style.textDecoration = 'none';
			}
		}
	}
}




/**
 * check to make sure getElementById is defined, otherwise create the method
 * - used for IE
 */
/*if(!HTMLDocument.prototype.getElementById) {
	HTMLDocument.prototype.getElementById = function (value) {
		return document.all[value];
	}
}*/


/** pulled from controller.js in order to try and lighten the load **/

/**
 * displays the controlBox, setting it in place
 */
function openControlBox(thisKoId) {
	if (!document.all) {
		winW = window.innerWidth;
		winH = window.innerHeight;
 	} else {
		winW = document.body.offsetWidth;
		winH = document.body.offsetHeight;
	}
	
	//var thisController = document.getElementById('controller'+thisKoId);
	//var startx = (thisController.offsetLeft + thisController.style.width/2);
	//var starty = thisController.offsetTop;
	
	//alert(startx+" "+document.getElementById('controller'+id).style.width);
	//if(startx+thisController.style.width > winW) {
		//startx = startx - (thisController.style.width/2);
	//}

	var thisContainer = document.getElementById('ko'+thisKoId);
	var thisControlBox = document.getElementById('controlBox'+thisKoId);
	if(!thisControlBox) {
		var thisControlBox = document.createElement('div');
			thisControlBox.setAttribute('id','controlBox'+thisKoId);
			//thisControlBox.setAttribute('class','controlBox');
			thisControlBox.addClassName('controlBox');
			//thisControlBox.addClassName('miniControlBox');
			//thisControlBox.setAttribute('style','z-index:99');
			thisControlBox.style.zIndex = '99';
			thisControlBox.style.visibility = 'hidden';
		
			//thisContainer.appendChild(thisControlBox);
			document.getElementsByTagName('BODY')[0].appendChild(thisControlBox);
		
		createCloseControlBoxButton(thisKoId);
			
		setControlBoxSize(thisKoId);
		getControlBox('controlBox'+thisKoId,thisKoId);
	} else {
		var TB_load = document.getElementById('TB_load');
		TB_load.parentNode.removeChild(TB_load);
		
		showControlBox(thisKoId);
	}
		
}


/**
 * 
 */
function showControlBox(thisKoId) {
	var thisController = document.getElementById('controller'+thisKoId);
	var thisControlBox = document.getElementById('controlBox'+thisKoId);
	var thisCloseControlBox = document.getElementById('closeControlBox'+thisKoId);
	
	thisControlBox.style.visibility = "visible";
	thisCloseControlBox.style.visibility = "visible";

	//thisController.style.visibility = 'hidden';
}


/**
 * closes the controlBox
 */
function closeControlBox(thisKoId) {
	var closeControlBox = document.getElementById('closeControlBox'+thisKoId)
	if(closeControlBox) {
		closeControlBox.style.visibility = "hidden";
	}
	
	var thisControlBox = document.getElementById('controlBox'+thisKoId);
	if(thisControlBox) {
		thisControlBox.style.visibility = "hidden";
		thisControlBox.style.overflow = "hidden";
	}
	
	thisControlBox.parentNode.removeChild(thisControlBox);
	
	hideProgressOverlay();
	
	//showAllControllers();
}


/**
 * closes other controlBoxes, so that only one can be open at a time
 */
function closeOtherControlBoxes(thisKoId) {
	var allKOs = $$('.koContainer');
	for(var i=0;i<allKOs.length;i++) {
		var id = allKOs[i].getAttribute('id')
		if(matches = id.match(/^ko(\d+)/)) {
			var thisId = matches[1];
			KOs.push(thisId);
		}
	}
	
	for(var i=0;i<KOs.length;i++) {
		if(KOs[i] != thisKoId) {
			closeControlBox(KOs[i]);
		}
	}
}


/**
 * 
 */
function setControlBoxSize(thisKoId) {
	var inset = 100;
	
	var thisControlBox = document.getElementById('controlBox'+thisKoId);
		thisControlBox.style.top = inset+"px";
		thisControlBox.style.left = inset+"px";
		//thisControlBox.style.right = "20px";
		//thisControlBox.style.bottom = "20px";
		//thisControlBox.style.width = "auto";
		//thisControlBox.style.height = "auto";
		thisControlBox.style.width = winW - (2*inset) + "px";
		thisControlBox.style.height = winH - (2*inset) + "px";
		//thisControlBox.style.overflow = "auto";
		thisControlBox.style.zIndex = "100";
		thisControlBox.style.position = 'absolute';  // ideally should be fixed, even if it doesn't work in IE
	
	
	var thisCloseControlBox = document.getElementById('closeControlBox'+thisKoId);	
	if(thisCloseControlBox) {
		thisCloseControlBox.style.left = parseInt(thisControlBox.style.left)+parseInt(thisControlBox.style.width) - 22 + "px";
		thisCloseControlBox.style.top = parseInt(thisControlBox.style.top) + 2 + "px";
		thisCloseControlBox.style.zIndex = "101";
		
		Event.observe(thisCloseControlBox, 'click', function(e) {
				var thisKoId = Event.element(e).id.substr(21,99); // closeControllerButton
				closeControlBox(thisKoId);
			}
		);
	}
}


/**
 * calls controlBox dynamically and loads it into the window
 */
function getControlBox(controlBoxContainerId,koId,editLang) {
	parameters = 'koId='+koId+'&noheader=1&view=Panel';
	if(editLang != null) parameters += '&editLang='+editLang;
	
	var baseurl = getBaseURL();
	controlBoxURL = baseurl+'lib/Core/KO/scripts/controller/getControlBox.php';
	
	var myAjax = new Ajax.Updater(
		controlBoxContainerId,
    controlBoxURL,
    { 
    	method: 'get', 
    	parameters: parameters, 
    	onComplete: function() {
				var TB_load = document.getElementById('TB_load');
				//TB_load.parentNode.removeChild(TB_load);
				TB_load.style.display = 'none';
				
    		var thisControlBox = document.getElementById(controlBoxContainerId);
    		
    		var editLangSelectMenus = $$('select.editLangSelectMenu');
    		if(editLangSelectMenus.length > 0) {
    			editLangSelectMenus[0].koId = koId
    			editLangSelectMenus[0].onchange = setEditLanguage;
    		}
    		
    		// change the id ( ko<koId> ) for the controlBox, so we don't end up with duplicate ids
    		var koContainer = document.getElementById('ko'+koId);
    		if(koContainer) {
    			koContainer.setAttribute('id','koControlBox'+koId);
    		}
    		
    		// show controlBox
    		showControlBox(koId);
			},
    	onFailure: showFailureMessage,
    	onException: showException
    }
	);
	
	return false;
}


/**
 *
 */
function setEditLanguage() {
	var editLang = this.options[this.selectedIndex].value;
	//alert(editLang);
	
	getControlBox('controlBox'+this.koId, this.koId, editLang);
}


/**
 * calls view dynamically and loads it into the window
 */
function getView(viewURL) {
	data = '';
	
	var myAjax = new Ajax.Request(
    viewURL,
    { 
    	method: 'get', 
    	parameters: data, 
    	onComplete: loadView, 
    	onFailure: showFailureMessage,
    	onException: showException
    }
	);
	
	return false;
}


/**
 * loads the view into the page
 */
function loadView(requestObj) {
	//alert(requestObj.responseXML); alert(requestObj.responseText); return;
	
	body = requestObj.responseXML.getElementsByTagName('body');
	
	//create a new XMLSerializer - only in mozilla - for debugging purposes only
	//var objXMLSerializer = new XMLSerializer;
	//var strXML = objXMLSerializer.serializeToString(body[0]);
  //alert(strXML);
  
	divs = body[0].getElementsByTagName('div');
	for(var i=0;i<divs.length;i++) {
		if(matches = divs[i].id.match(/^ko(\d+)/)) {
			if(!divs[i].id) continue;
			var thisId = matches[1];
			alert('working with ko'+thisId);
		}
	}
}


/**
 * shows the controller / now hidden until the user roles over top of the koContainer
 */
function showController(e) {
	var thisElement = Event.element(e);
	
	var dash = document.createTextNode(thisElement.nodeName+'#'+thisElement.getAttribute('id')+' ');
	document.getElementsByTagName('BODY')[0].appendChild(dash);
	
	
	var thisId = thisElement.getAttribute('id');
	if(thisId) {
		var matches = thisId.match(/^ko(\d+)/);
		if(matches && matches.length > 1) {
			var koId = matches[1];
			var thisController = document.getElementById('controller'+koId);
			
			var dash = document.createTextNode('controller'+koId+' ');
			document.getElementsByTagName('BODY')[0].appendChild(dash);
			
			thisController.style.visibility = "visible";
			var thisContainer = document.getElementById('ko'+koId);
			//thisContainer.style.borderColor = 'black';
			//thisContainer.style.borderStyle = 'solid';
			
			// very cool function from prototype.js - i've been looking for this kind of functionality for quite some time - dwc
			Event.stop(e);
			hideOtherControllers(koId);
			//closeOtherControlBoxes(this.koId);
		}
	}
	
	return true;
	
	//Event.stop(e);
	//Event.stopObserving(thisElement,'mouseover',showController,false);
}


/**
 * hides the controller
 */
function hideController(e) {
	var dot = document.createTextNode('.');
	document.getElementsByTagName('BODY')[0].appendChild(dot);
			
	var thisElement = Event.element(e);
	var thisId = thisElement.getAttribute('id');
	if(thisId) {
		var matches = thisId.match(/^ko(\d+)/);
		if(matches && matches.length > 1) {
			var koId = matches[1];
			var thisController = document.getElementById('controller'+koId);
			thisController.style.visibility = "hidden";
			var thisContainer = document.getElementById('ko'+koId);
			//thisContainer.style.borderColor = 'transparent';
			//thisContainer.style.borderStyle = 'dashed';
						
			//hideOtherControllers(koId);
		}
	}
	
	//Event.stop(e);
	//Event.stopObserving(thisElement,'mouseout',hideController,false);
}


/**
 * shows all controllers
 */
function showAllControllers() {
	for(var i=0;i<KOs.length;i++) {
		//if(KOs[i] != thisKoId) {
			var controller = document.getElementById('controller'+KOs[i]);
			controller.style.visibility = "visible";
			//var thisContainer = document.getElementById('ko'+KOs[i]);
			//thisContainer.style.borderColor = 'transparent';
			//thisContainer.style.borderStyle = 'dashed';
		//}
	}
}


/**
 * hides all other controllers, so that only one can be open at a time
 */
function hideOtherControllers(thisKoId) {
	for(var i=0;i<KOs.length;i++) {
		if(KOs[i] != thisKoId) {
			var controller = document.getElementById('controller'+KOs[i]);
			controller.style.visibility = "hidden";
			var thisContainer = document.getElementById('ko'+KOs[i]);
			//thisContainer.style.borderColor = 'transparent';
			//thisContainer.style.borderStyle = 'dashed';
		}
	}
}


/**
 * hides all other container outlines, so that only one can be seen at a time
 */
function hideOtherContainerOutlines(thisKoId) {
	/*var allKOs = $$('.koContainer');
	var KOs = new Array();
	for(var i=0;i<allKOs.length;i++) {
		var id = allKOs[i].getAttribute('id')
		if(matches = id.match(/^ko(\d+)/)) {
			var thisId = matches[1];
			KOs.push(thisId);
		}
	}*/
	
	for(var i=0;i<KOs.length;i++) {
		if(KOs[i] != thisKoId) {
			destroyContainerOutline(KOs[i]);
			/*var containerOutline = document.getElementById('containerOutline'+KOs[i]);
			if(containerOutline) {
				containerOutline.style.visibility = "hidden";
			}*/
		}
	}
}


/**
 * displays overlay with progress wheel
 */
function showProgressOverlay(elementToOverlay) {
	if($('TB_load')) return true;

	var baseurl = getBaseURL();
	
	if(elementToOverlay == undefined) {
		var body = document.getElementsByTagName('body');
		var elementToOverlay = body[0];
		elementToOverlay.x = 0;
		elementToOverlay.y = 0;
		elementToOverlay.w = window.innerWidth;
		elementToOverlay.h = window.innerHeight;
	} else {
		setPosition(elementToOverlay);
	}
	
	var overlay = document.createElement('div');
		overlay.setAttribute('id','overlay');
		overlay.setAttribute('class','ghosted');
		overlay.style.overlay = 'hidden';
		overlay.style.zIndex = '99';
		overlay.style.left = elementToOverlay.x+'px';
		overlay.style.top = elementToOverlay.y+'px';
		overlay.style.width = elementToOverlay.w+'px';
		overlay.style.height = elementToOverlay.h+'px';
		
		elementToOverlay.appendChild(overlay);
			
		Event.observe(overlay,'click',function() { 
				closeOtherControlBoxes(0);
			}
		);
			
		var TB_load = document.createElement('div');
			TB_load.setAttribute('id','TB_load');
		var TB_loadContent = document.createElement('div');
			TB_loadContent.setAttribute('id','TB_loadContent');
			TB_load.appendChild(TB_loadContent);
			showProgressAnimation(TB_loadContent);
			elementToOverlay.appendChild(TB_load);
}


/**
 *
 */
function showProgressAnimation(progressElement) {
	var baseurl = getBaseURL();
	
	//if(!$('loadingIndicator')) {
		var loadingIndicator = document.createElement('div');
		 loadingIndicator.setAttribute('id','loadingIndicator');
		var circleAnimation = document.createElement('img');
		 circleAnimation.setAttribute('src',baseurl+'lib/Core/KO/images/circle_animation.gif');
		 circleAnimation.setAttribute('alt','progress animation');
		 loadingIndicator.appendChild(circleAnimation);
		
		//progressElement.innerHTML = loadingIndicator.cloneNode(true);
		//progressElement.parentNode.appendChild(loadingIndicator);
		
		progressElement.appendChild(loadingIndicator);
	//} else {
	//	$('loadingIndicator').style.display = 'block';
	//}
}


/**
 *
 */
function hideProgressAnimation(progressElement) {
	if($('loadingIndicator')) $('loadingIndicator').remove();
}


/**
 * removes overlay with progress wheel
 */
function hideProgressOverlay() {
	var overlay = document.getElementById('overlay');
	if(overlay) overlay.parentNode.removeChild(overlay);
	
	var TB_load = document.getElementById('TB_load');
	if(TB_load) TB_load.parentNode.removeChild(TB_load);
}


/**
 * creates the controller and thec close controller buttons 
 * :NOTE: this could be simplified - instead of creating another div,
 * 				we could simply change the text and the event handler for the button - this would lighten the code
 */
function createControllerButtons(id) {
	var thisContainer = document.getElementById('ko'+id);
		matches = thisContainer.className.match(/type_(\w+)/);
		if(matches != undefined) {
			var modName = matches[1];
		} else {
			var modName = '';
		}
		
	var thisKOTitle = $('koTitle'+id).firstChild.nodeValue;
	
	// get position of container
	setPosition(thisContainer);
	var thisContainerLeft = thisContainer.x;
	var thisContainerTop = thisContainer.y;
	var thisContainerWidth = thisContainer.w;
	var thisContainerHeight = thisContainer.h;
	 //alert(id+': '+thisContainerLeft+','+thisContainerTop+' '+thisContainerWidth+'x'+thisContainerHeight);
	 
	 
	// create controller
	
	var controller = document.getElementById('controller'+id);
	if(!controller) {
		var baseurl = getBaseURL();
		
		// create open ControlBox button
		var controller = document.createElement('div');
			controller.setAttribute('id','controller'+id);
			controller.setAttribute('class','controller clearfix');
			// needed to position the object before it is placed
			controller.style.position = 'absolute';
			controller.style.top = '10px';
			controller.style.left = '10px';
			controller.style.visibility = 'hidden';
			
		var controllerButton = document.createElement('img');
			controllerButton.setAttribute('id','controllerButton'+id);
			//controllerButton.setAttribute('src',baseurl+'lib/Core/KO/scripts/controller/images/openControlBox.jpg');
			controllerButton.setAttribute('src',baseurl+'lib/Core/KO/scripts/controller/images/green.gif');
			controllerButton.setAttribute('title',thisKOTitle+' - '+modName+' (koId '+id+')');
			controllerButton.setAttribute('alt','controller image for ko'+id);
			//controllerButton.setAttribute('class','controllerButton'); // for some reason, this doesn't work in IE
			controllerButton.addClassName('controllerButton');
			controller.appendChild(controllerButton);
		
		
		// createCloseControlBoxButton
		createCloseControlBoxButton(id);
		
	
		Event.observe(controller, 'mouseover', function() {
				//thisContainer.style.border = '1px dotted black';
				createContainerOutline(id); //,thisContainerLeft,thisContainerTop,thisContainerWidth,thisContainerHeight)
			}
		);
		
		Event.observe(controller, 'mouseout', function() {
				//thisContainer.style.border = 'none';
				destroyContainerOutline(id);
			}
		);
	
		// add event handlers to controller
		Event.observe(controller, 'click', function(e) {
				//alert(e.currentTarget.getAttribute('id'));
				//alert(e.target.getAttribute('id'));
				showProgressOverlay();
				var thisKoId = Event.element(e).id.substr(16,99); // controllerButton12345
				openControlBox(thisKoId);	
			}
		);
	}
		
	//thisContainer.style.border = '1px solid black';
	
	var newRight = thisContainerLeft+thisContainerWidth-2;
	
	// position controller
	var leftOffsetWidth = controller.offsetWidth;
	if($('ko'+id).parentNode.nodeName != 'BODY') {
		leftOffsetWidth = leftOffsetWidth-4;
	}
	var topOffsetWidth = 0;
	if($('ko'+id).parentNode.nodeName != 'BODY') {
		topOffsetWidth = topOffsetWidth+2;
	}
	
	// 15 seems to be based upon padding - we should account for this - dwc
	controller.style.left = controller.style.left = (newRight-leftOffsetWidth)+"px";
	controller.style.top = controller.style.top = (thisContainerTop-topOffsetWidth)+"px";
}


function createCloseControlBoxButton(id) {
	//alert('createCloseControlBoxButton: '+id);
	var baseurl = getBaseURL();
		
	// create close ControlBox button
	var closeControlBoxButton = document.createElement('div');
		closeControlBoxButton.setAttribute('id','closeControlBox'+id);
		closeControlBoxButton.setAttribute('class','closeControlBoxButton');
		// needed to position the object before it is placed
		closeControlBoxButton.style.position = 'absolute';
		closeControlBoxButton.style.top = '0px';
		closeControlBoxButton.style.left = '0px';
		closeControlBoxButton.style.visibility = 'hidden';
	
	var closeControllerButton = document.createElement('img');
		closeControllerButton.setAttribute('id','closeControllerButton'+id);
		closeControllerButton.setAttribute('src',baseurl+'lib/Core/KO/scripts/controller/images/red.gif');
		closeControllerButton.setAttribute('alt','close controller for ko'+id);
		//closeControllerButton.setAttribute('class','controllerButton'); // for some reason, this doesn't work in IE
		closeControllerButton.addClassName('controllerButton');
		closeControlBoxButton.appendChild(closeControllerButton);
	
	//insertAfter(closeControlBoxButton,$('ko'+id));
	document.getElementsByTagName('BODY')[0].appendChild(closeControlBoxButton);
	
	
	//alert(baseurl+'lib/Core/KO/scripts/controller/images/red.gif');
	
	//var thisControlBox = document.getElementById('controlBox'+id);
		//thisContainer.insertBefore(controller,thisControlBox);
		//document.getElementsByTagName('BODY')[0].insertBefore(controller,thisControlBox);
		//insertAfter(closeControlBoxButton,controller);
}


/**
 *
 */
function createContainerOutline(koId,left,top,width,height) {
	var emptyText = document.createTextNode(' ');

	// get the positions now - they may have changed
	// adjust top level element to include entire page
	if($('ko'+koId).parentNode.nodeName == 'BODY') {
		var thisKO = $('ko'+koId);
		var dimensions = thisKO.parentNode.getDimensions();
		var left = 0;
		var top = 0;
		var width = dimensions.width;
		var height = dimensions.height;
	} else {
		var thisKO = $('ko'+koId);
		setPosition(thisKO);
		var left = thisKO.x;
		var top = thisKO.y;
		var width = thisKO.w;
		var height = thisKO.h;
	}
	
	/*alert(
		thisKO.offsetLeft+','+thisKO.offsetTop+' - '+dimensions.width+','+dimensions.height+'\n'+
		left+','+top+' - '+width+','+height
	);*/
	
	// add to array
	KOs.push(koId);
	
	var outlineWidth = 2;  // :NOTE: can we get this from the css? from .containerOutline border-width
	if(thisKO.getStyle('-mozBoxSizing') == 'border-box') {
		var outlineWidth = 2;
	} else {
		var outlineWidth = 0;
	}
	
	var topOutline = document.createElement('div');
	 topOutline.setAttribute('id','topOutline'+koId);
	 topOutline.setAttribute('class','controllerOutline');
	 topOutline.setAttribute('style','left:'+left+'px;top:'+top+'px;width:'+width+'px;height:'+outlineWidth+'px');
	  topOutline.appendChild(emptyText);
	  
	var leftOutline = document.createElement('div');
	 leftOutline.setAttribute('id','leftOutline'+koId);
	 leftOutline.setAttribute('class','controllerOutline');
	 leftOutline.setAttribute('style','left:'+left+'px;top:'+top+'px;width:'+outlineWidth+'px;height:'+height+'px');
	  leftOutline.appendChild(emptyText);
	  
	var rightOutline = document.createElement('div');
	 rightOutline.setAttribute('id','rightOutline'+koId);
	 rightOutline.setAttribute('class','controllerOutline');
	 rightOutline.setAttribute('style','left:'+(left+width-outlineWidth)+'px;top:'+top+'px;width:'+outlineWidth+'px;height:'+height+'px');
	  rightOutline.appendChild(emptyText);
	  
	var bottomOutline = document.createElement('div');
	 bottomOutline.setAttribute('id','bottomOutline'+koId);
	 bottomOutline.setAttribute('class','controllerOutline');
	 bottomOutline.setAttribute('style','left:'+left+'px;top:'+(top+height-outlineWidth)+'px;width:'+width+'px;height:'+outlineWidth+'px');
	  bottomOutline.appendChild(emptyText);
	  
	 var body = document.getElementsByTagName('body');
	 body[0].appendChild(topOutline);
	 body[0].appendChild(leftOutline);
	 body[0].appendChild(rightOutline);
	 body[0].appendChild(bottomOutline);
}


/**
 *
 */
function destroyContainerOutline(koId) {
	if($('topOutline'+koId)) $('topOutline'+koId).parentNode.removeChild($('topOutline'+koId));
	if($('leftOutline'+koId)) $('leftOutline'+koId).parentNode.removeChild($('leftOutline'+koId));
	if($('rightOutline'+koId)) $('rightOutline'+koId).parentNode.removeChild($('rightOutline'+koId));
	if($('bottomOutline'+koId)) $('bottomOutline'+koId).parentNode.removeChild($('bottomOutline'+koId));
}


/**
 * find and set the x,y and w (width) and h (height) for the element and set them as properties
 */
function setPosition(el) {
	var position = el.cumulativeOffset();
	var dimensions = el.getDimensions();
		//alert(position.left+','+position.top+' - '+dimensions.width+'x'+dimensions.height);

	el.x = position.left, 
	el.y = position.top;
	el.w = dimensions.width; 
	el.h = dimensions.height;
	
	return el;
}


/**
 * finds all kos and creates controllers for each of them
 */
function setupControllers() {
	var editMode = document.getElementById("editMode");
	if(editMode) {
		// setup main controllers
		var divs = document.getElementsByTagName("div");
		for(var i=0;i<divs.length;i++) {
			var thisId = divs[i].getAttribute('id');
			if(thisId) {
				var matches = thisId.match(/^ko(\d+)/);
				if(matches && matches.length > 1) {
					var thisKoId = matches[1];
	
					//if(divs[i].hasClassName('excludeControls')) continue
					
					// keep track of all koIds
					KOs.push(thisKoId);
	
					// trying to account for bug where parent div has a display of none
					//if(divs[i].style.display == 'none') continue; 
					createControllerButtons(thisKoId);
					
					//divs[i].setAttribute('id = thisKoId;
					//divs[i].style.borderStyle = 'dashed';
					
					var thisController = document.getElementById('controller'+thisKoId);
					thisController.style.visibility = "visible";
				}
			}
		}
		
		// setup mini controllers
		/*var baseurl = getBaseURL();
		var miniControllers = $$(".miniController");
		for(var i=0;i<miniControllers.length;i++) {
			miniControllers[i].setAttribute('class','miniController');
			var thisId = miniControllers[i].getAttribute('id');
			if(thisId) {
				var koId = getId(thisId, '^miniController(\\d+)');
				var miniControllerButtonImg = document.createElement('img');
					miniControllerButtonImg.setAttribute('id','miniControlButtonImg'+koId);
					miniControllerButtonImg.setAttribute('src',baseurl+'lib/Core/KO/images/miniController.gif');
					miniControllerButtonImg.setAttribute('alt','mini controller for '+koId);
					
				miniControllers[i].appendChild(miniControllerButtonImg);
				
				Event.observe(miniControllerButtonImg,'click',showMiniController);
			}
		}*/
	}
}
var KOs = Array();

/**
 *
 */
function showMiniController(e) {
	
	// try to find the koId
	var thisElement = Event.element(e);
	var thisId = thisElement.getAttribute('id');
	var koId = '';
	if(thisId) {
		if(koId = getId(thisId, '^miniController(\\d+)')) {
			//console.log(koId+' '+thisId);
		}
		else if(koId = getId(thisId, '^miniControlButton(\\d+)')) {
			//console.log(koId+' '+thisId);
		}
		else if(koId = getId(thisId, '^miniControlButtonImg(\\d+)')) {
			//console.log(koId+' '+thisId);
		} else {
			//console.log('FALSE: '+thisId);
			return false;
		}
	}
	
	if(koId) {
		var miniController = document.getElementById('miniController'+koId);
		//console.log(miniController.getAttribute('id'));
		setPosition(miniController);
		var top = miniController.y;
		var left = miniController.x+miniController.w;
		
		var miniControlBox = document.getElementById('miniControlBox'+koId);
		if(!miniControlBox) {					
			var miniControlBox = document.createElement('span');
				miniControlBox.setAttribute('id','miniControlBox'+koId);
				miniControlBox.setAttribute('class','miniControlBox clearfix');
				miniControlBox.setAttribute('style','left:'+left+'px;top:'+top+'px;');
				
			//insertAfter(miniControlBox,miniController);
			miniController.appendChild(miniControlBox);
			
			//parameters = 'koId='+koId+'&noheader=1&view=Panel';
			//if(editLang != null) parameters += '&editLang='+editLang;
			
			//var baseurl = getBaseURL();
			//var miniControlBoxURL = baseurl+'lib/Core/KO/scripts/controller/getControlBox.php?koId='+koId+'&view=Views';
			
			aURL = window.location.href;
			if(aURL.match('/?/')) aURL = aURL.split("?")[0];
			
			var miniControlBoxURL = aURL+'/KO/'+koId+'/Views?noheader=1';
			
			insertHTMLFragment(miniControlBox,miniControlBoxURL, function() { miniController.style.cursor = 'pointer'; } ); //,onCompleteFunction);
			
			miniController.style.cursor = 'progress';
		} else {
			/*if(miniControlBox.style.display == 'none') {
				miniControlBox.style.display = 'block';
			} else {
				miniControlBox.style.display = 'none';
			}*/
		}
		
		
		//Event.observe(document,'mousemove',hideMiniControlBox);
	}
}

/**
 *
 */
function setAllMiniControlBoxPositions() {
	var allMiniControllers = $$('span.miniController');
	for(var i=0;i<allMiniControllers.length;i++) {
		var thisId = allMiniControllers[i].getAttribute('id');
		var koId = '';
		if(thisId) {
			if(koId = getId(thisId, '^miniController(\\d+)')) {
				var miniController = document.getElementById('miniController'+koId);
				var miniControlBox = document.getElementById('miniControlBox'+koId);
				if(miniController && miniControlBox) {
					setPosition(miniController);
					var top = miniController.y;
					var left = miniController.x+miniController.w;
					miniControlBox.setAttribute('style','left:'+left+'px;top:'+top+'px;');
				}
			}
		}
	}
}


/**
 *
 */
function hideMiniControlBox(e) {	
	if (!e) var e = window.event;
	var srcElement = e.relatedTarget || e.toElement;
	//alert(srcElement);
	
	if(srcElement) {
		console.log(srcElement.nodeName+' '+srcElement.getAttribute('id'));
		var srcId = srcElement.getAttribute('id');
	}
	if(srcId) {
		var koId = getId(srcId, '^miniControlBox(\\d+)');
	}
	if(!koId) {
		//var miniController = Event.element(e);
		//var koId = miniController.getAttribute('koId');
			//alert('miniControlBox'+koId);
		
		var miniControlBox = document.getElementById('miniControlBox'+koId);
		if(miniControlBox) {
			miniControlBox.style.display = 'none';
			Event.Stop(e);
		}
	}
}


/**
 * simple wrapper for accessing a portion of a string, using a pattern match
 */
function getId(thisString, pattern) {
	if(pattern) {
		var regEx = new RegExp(pattern);
		var matches = thisString.match(regEx);
		if(matches) {
			if(matches.length == 2) {
				var thisKoId = matches[1];
				return thisKoId;
			} else {
				return matches;
			}
		}
	} else {
		return false;
	}
}



/**
 * simple wrapper for replacing a portion of a string
 */
function setId(thisString, pattern, replace) {
	if(pattern) {
		var regEx = new RegExp(pattern);
		return thisString.replace(regEx, replace);
	} else {
		return thisString;
	}
}


/**
 * code yanked from the Yahoo media player. Thanks, Yahoo.
 */
if (! ("console" in window) || !("firebug" in console)) {
	var names = ["log", "debug", "info", "warn", "error", "assert", "dir", "dirxml", "group", "groupEnd", "time", "timeEnd", "count", "trace", "profile", "profileEnd"];
	window.console = {};
  for (var i = 0; i <names.length; ++i) window.console[names[i]] = function() {};
}




/* *******************************************************************************************/
// this is where all the functions get setup to fire once the document loads

addLoadEvent(prepareSetDisplay);
addLoadEvent(setupDrawers);
addLoadEvent(setupMessageWindows);
addLoadEvent(setupFormContext);
addLoadEvent(setupAutoCompleter);
addLoadEvent(setupInPlaceEditors);
//addLoadEvent(setupControllers);
addLoadEvent(prepareUpdateVersionNumber);
addLoadEvent(setupVersionSelector);
