/**
 * General Javascript Functions
 *
 * Developed by 1000camels
 *
 */
 
 
 


/**
 * 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 = document.onkeypress = function (evt) {
	evt = evt || window.event;
	var keyCode = evt.keyCode || evt.which || 0;
	if (keyCode && evt.altKey && (evt.ctrlKey || evt.metaKey)) {
		try { evt.keyCode = 0;} catch(e) {}
		var keySring = String.fromCharCode(keyCode);
		if(keySring == 'B') {
			changeMode('browse');
		}
		if(keySring == 'E') {
			changeMode('edit');
		}
		else if(keySring == 'L') {
			showLoginWindow();
		}
		else if(keySring == 'O') {
			if($('objectSpace')) showHideObjectSpace();
		}
		else if(keySring == 'D') {
			showSystemMessages();
		}
		else if(keySring == '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;
}



 
 
 
 

/**
 * 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
 */
function changeView(view) {
	var imageDisplay = document.getElementById('imageDisplay');
	if(imageDisplay) {
		if(view == 'list') {
			addClass(imageDisplay, 'imageList');
			removeClass(imageDisplay, 'imageThumbs');
			setSessionVariable('imageDisplayType','imageList');
		} else {
			addClass(imageDisplay, 'imageThumbs');
			removeClass(imageDisplay, 'imageList');
			setSessionVariable('imageDisplayType','imageThumbs');
		}
	}
}


/**
 * 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';
			}
		);
	}
}


/**
 * prepare objectSpace
 */
function setupObjectSpace() {
	var objectSpace = document.getElementById('objectSpace');
	if(objectSpace) {
		objectSpaceController = document.createElement('div');
		objectSpaceController.setAttribute('id','objectSpaceController');
		objectSpaceControllerText1 = document.createTextNode('O b j e c t');
		objectSpaceControllerText2 = document.createTextNode('S p a c e');
		objectSpaceControllerSpan1 = document.createElement('div');
		objectSpaceControllerSpan2 = document.createElement('div');
		objectSpaceControllerSpan1.appendChild(objectSpaceControllerText1);
		objectSpaceControllerSpan2.appendChild(objectSpaceControllerText2);
		objectSpaceController.appendChild(objectSpaceControllerSpan1);
		objectSpaceController.appendChild(objectSpaceControllerSpan2);
		
		Event.observe(objectSpaceController, 'click', showHideObjectSpace);
		
		insertAfter(objectSpaceController,objectSpace);
		
		var editMode = document.getElementById('editMode');
		var body = document.getElementsByTagName('body');
		/* interesting hack below - i'm shifting the whole body content, to make sure the objectSpace bar doesn't sit over
			 top of any content */
		if(editMode) {
			objectSpaceController.style.visibility = 'visible';
			body[0].style.marginLeft = '14px';
		} else {
			objectSpaceController.style.visibility = 'hidden';
			body[0].style.marginLeft = '0px';
		}
	}
}


/**
 * show/hide the objectSpace
 */
function showHideObjectSpace() {
	var objectSpace = document.getElementById('objectSpace');
	if(objectSpace) {
		var objectSpaceController = document.getElementById('objectSpaceController');
		var editMode = document.getElementById('editMode');
		if(objectSpace.style.display == 'none' || objectSpace.style.display == '') {
			objectSpace.style.display = 'block';
			if(!editMode) objectSpaceController.style.visibility = 'visible';
		} else {
			objectSpace.style.display = 'none'
			if(!editMode) objectSpaceController.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() {
	var allDrawers = getElementsByClassName(document, '*', 'slidingDrawer');
	for (i=0; i < allDrawers.length ; i++) {
		allDrawers[i].style.display = 'none';
	}
	var allDrawerControllers = getElementsByClassName(document, '*', 'slidingDrawerController');
	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;
				}
			}
		);
	}
}



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

/**
 *
 */
function setupAutoCompleter() {
	var allAutoCompleters = getElementsByClassName(document, '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);
			
			// get modIds
			var modIds = document.getElementById(autocompleteId+'ModIds').firstChild.nodeValue;
			if(modIds) {
				// url for autocompleter script
				var baseURL = getBaseURL();
				var url = baseURL+"lib/Core/KO/scripts/getAutoCompletion.php?modId="+modIds;
				
				var options = { paramName: "hint", minChars: 3, 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',''));
	}
}
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 = getElementsByClassName(root, '*', 'inPlaceEditor');

	for (i=0; i < inPlaceEditors.length ; i++) {
		var editorName = inPlaceEditors[i].getAttribute('id');
 		if(editorName) {
 			var editorURLs = getElementsByClassName(root, '*', 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 = getElementsByClassName(document, '*', editorName+'Params');
	if(additionalParams[0]) {
		data += '&'+additionalParams[0].firstChild.nodeValue;
	}
	return data+'&value=' + escape(value);
}



/* ***************************************************************************/
// Fckeditors

/**
 *
 */
function setupFckEditors() {
	var fckEditors = $$('.fckEditorText');
	for(var i=0;i<fckEditors.length;i++) {
		Event.observe(fckEditors[i], 'mouseover', function(e) {
				if(matches = Event.element(e).getAttribute('id').match(/^(\d)Textarea/)) {
					var thisId = matches[1];
					if(hasClass(Event.element(e),'fckEditorText')) {
						if(!$(thisId+'EditorOverlay')) {
							createEditorOverlay(Event.element(e));
							//addClass(Event.element(e), 'ghosted');
						} else {
							$(thisId+'EditorOverlay').style.display = 'block';
						}
					}
				}
			}
		);
	}
}


/**
 *
 */
function CreateFckEditor(thisId)
{
	// Copy the value of the current textarea, to the textarea that will be used by the editor.
	$(thisId+'FCKeditor').value = $(thisId+'Textarea').firstChild.nodeValue;
	$(thisId+'Textarea').style.display = 'none';
	
	var sBasePath = $(thisId+'BasePath').firstChild.nodeValue;
	var customConfigurationsPath = $(thisId+'CustomConfigurationsPath').firstChild.nodeValue;

	// Create an instance of FCKeditor (using the target textarea as the name).
	var oFCKeditor = new FCKeditor(thisId+'FCKeditor') ;
	oFCKeditor.BasePath = sBasePath ;
	oFCKeditor.Config['CustomConfigurationsPath'] = customConfigurationsPath;
	oFCKeditor.Width = '100%' ;
	oFCKeditor.Height = '350' ;
	oFCKeditor.ReplaceTextarea() ;
}


/**
 *
 */
function createEditorOverlay(objectToOverlay) {
	getPosition(objectToOverlay);
	
	var editorOverlay = document.createElement('div');
	 editorOverlay.setAttribute('id',objectToOverlay.getAttribute('id')+'EditorOverlay');
	 editorOverlay.setAttribute('class','editorOverlay');
	var editorOverlayTextContainer = document.createElement('div');
	var editorOverlayText = document.createTextNode('Edit Text');
	 editorOverlayTextContainer.appendChild(editorOverlayText);
	 editorOverlay.appendChild(editorOverlayTextContainer);
	 objectToOverlay.appendChild(editorOverlay);
	 
	addClass(editorOverlay, 'ghosted');
	editorOverlay.style.position = 'absolute';
	editorOverlay.style.left = objectToOverlay.x+'px';
	editorOverlay.style.top = objectToOverlay.y+'px';
	editorOverlay.style.width = objectToOverlay.w+'px';
	editorOverlay.style.height = objectToOverlay.h+'px';
	editorOverlay.style.zIndex = "99";
	
	
	Event.observe(editorOverlay, 'mouseout', function(e) {
			Event.element(e).style.display = 'none';
		}
	);
	
	
	
	Event.observe(editorOverlay, 'click', function(e) {
			if(matches = Event.element(e).getAttribute('id').match(/^(\d)EditorOverlay/)) {
				var thisId = matches[1];
				CreateFckEditor(thisId);
			}
		}
	);
}


/**
 *
 */
function showHideFckEditor()
{
	// Try to get the FCKeditor instance, if available.
	var oEditor ;
	if ( typeof( FCKeditorAPI ) != 'undefined' )
		oEditor = FCKeditorAPI.GetInstance( '_DataFCKeditor' ) ;

	// Get the _Textarea and _FCKeditor DIVs.
	var eTextareaDiv	= document.getElementById( '_Textarea' ) ;
	var eFCKeditorDiv	= document.getElementById( '_FCKeditor' ) ;

	// If the _Textarea DIV is visible, switch to FCKeditor.
	if ( eTextareaDiv.style.display != 'none' )
	{
		// If it is the first time, create the editor.
		if ( !oEditor )
		{
			CreateFckEditor() ;
		}
		else
		{
			// Set the current text in the textarea to the editor.
			oEditor.SetHTML( document.getElementById('_DataTextarea').value ) ;
		}

		// Switch the DIVs display.
		eTextareaDiv.style.display = 'none' ;
		eFCKeditorDiv.style.display = '' ;

		// This is a hack for Gecko 1.0.x ... it stops editing when the editor is hidden.
		if ( oEditor && !document.all )
		{
			if ( oEditor.EditMode == FCK_EDITMODE_WYSIWYG )
				oEditor.MakeEditable() ;
		}
	}
	else
	{
		// Set the textarea value to the editor value.
		document.getElementById('_DataTextarea').value = oEditor.GetXHTML() ;

		// Switch the DIVs display.
		eTextareaDiv.style.display = '' ;
		eFCKeditorDiv.style.display = 'none' ;
	}
}


/**
 * The FCKeditor_OnComplete function is a special function called everytime an
 * editor instance is completely loaded and available for API interactions.
 */
/*function FCKeditor_OnComplete( editorInstance ) {
	// Enable the switch button. It is disabled at startup, waiting the editor to be loaded.
	document.getElementById('_BtnSwitchTextarea').disabled = false ;
}*/


/**
 *
 */
function FckEditorSave()
{
	// If the textarea isn't visible update the content from the editor.
	if ( document.getElementById( '_Textarea' ).style.display == 'none' )
	{
		var oEditor = FCKeditorAPI.GetInstance( '_DataFCKeditor' ) ;
		document.getElementById( '_DataTextarea' ).value = oEditor.GetXHTML() ;
	}
}



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


/**
 * 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() {
	showHideByLink('loginExpand');
	var loginButtons = getElementsByClassName(document, '*', '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);
  }
}

/**
 * 
 */
function hasClass(element,value) {
  if (element.className) {
    classes = element.className.split(' ');
    for(i=0;i<classes.length;i++) {
    	if(classes[i] == value) {
    		return true;
    	}
    }
  }
  
  return false;
}

/**
 * 
 */
function addClass(element,value) {
  if (!element.className) {
    element.className = value;
  } else {
    newClassName = element.className;
    newClassName+= " ";
    newClassName+= value;
    element.className = newClassName;
  }
}

/**
 * 
 */
function removeClass(element,value) {
  if (element.className) {
  	newClasses = new Array();
    classes = element.className.split(' ');
    for(i=0;i<classes.length;i++) {
    	if(classes[i] != value) {
    		newClasses.push(classes[i]);
    	}
    }
    element.className = newClasses.join(' ');
  } else {
  	element.className = '';
  }
}


/**
 * getElementsByClassName
 *	- Written by Jonathan Snook, http://www.snook.ca/jonathan
 *  - Add-ons by Robert Nyman, http://www.robertnyman.com
 */
function getElementsByClassName(oElm, strTagName, strClassName) {
    var arrElements = (strTagName == "*" && document.all)? document.all : oElm.getElementsByTagName(strTagName);
    var arrReturnElements = new Array();
    strClassName = strClassName.replace(/\-/g, "\\-");
    var oRegExp = new RegExp("(^|\\s)" + strClassName + "(\\s|$)");
    var oElement;
    for(var i=0; i<arrElements.length; i++){
        oElement = arrElements[i];      
        if(oRegExp.test(oElement.className)){
            arrReturnElements.push(oElement);
        }   
    }
    return (arrReturnElements)
}


/**
 * 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.path = this.url.split("?")[1];
	} else {
		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/User/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 = getElementsByClassName(document,'*','clnFormContext');
	for(var i=0;i<allFormContext.length;i++) {
		var formContainer = allFormContext[i].parentNode;
		if(hasClass(formContainer,'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) {
			getPosition(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;
	}
}


/**
 * 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(thisObject) {
	if(thisObject == undefined) {
		thisObject = this;
	}
	
	var thisKoId = thisObject.id.substr(16,99);	// this is expecting an id of controller<koId>
	
	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');
			addClass(thisControlBox,'controlBox');
			//addClass(thisControlBox,'miniControlBox');
			//thisControlBox.setAttribute('style','z-index:99');
			thisControlBox.style.zIndex = '99';
			thisControlBox.style.visibility = 'hidden';
		
			//thisContainer.appendChild(thisControlBox);
			document.getElementsByTagName('BODY')[0].appendChild(thisControlBox);
			
		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(thisObject) {	
	if(thisObject == undefined) {
		thisObject = this;
	}
	
	var thisKoId = thisObject.id.substr(21,99);
	
	document.getElementById('closeControlBox'+thisKoId).style.visibility = "hidden";
	
	var thisControlBox = document.getElementById('controlBox'+thisKoId);
	if(thisControlBox) {
		thisControlBox.style.visibility = "hidden";
		thisControlBox.style.overflow = "hidden";
	}
	
	hideProgressOverlay();
	
	showAllControllers();
}


/**
 * closes other controlBoxes, so that only one can be open at a time
 */
function closeOtherControlBoxes(thisKoId) {
	for(var i=0;i<KOs.length;i++) {
		if(KOs[i] != thisKoId) {
			var cb = document.getElementById('closeControlBox'+KOs[i]);
			// setup prototype so i can call this function like a method call
			//cb.__proto__.closeCB = closeControlBox;
			//cb.closeCB();
			closeControlBox(cb);
		}
	}
}


/**
 * 
 */
function setControlBoxSize(thisKoId) {
	var thisControlBox = document.getElementById('controlBox'+thisKoId);
		thisControlBox.style.top = "20px";
		thisControlBox.style.left = "20px";
		//thisControlBox.style.right = "20px";
		//thisControlBox.style.bottom = "20px";
		//thisControlBox.style.width = "auto";
		//thisControlBox.style.height = "auto";
		thisControlBox.style.width = winW - 40 + "px";
		thisControlBox.style.height = winH - 40 + "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.width) + "px"; //thisController.style.left;
		//thisCloseControlBox.style.left = parseInt(thisControlBox.style.width) - 25 + "px";
		//thisCloseControlBox.style.left = parseInt(thisControlBox.style.right) - 6 + "px";
		//thisCloseControlBox.style.top = parseInt(thisControlBox.style.top) + 2 + "px";
		thisCloseControlBox.style.left = parseInt(thisControlBox.style.width) - 6 + "px";
		thisCloseControlBox.style.top = parseInt(thisControlBox.style.top) + 2 + "px";
		thisCloseControlBox.style.zIndex = "101";
		
		Event.observe(thisCloseControlBox, 'click', function(e) {
				closeControlBox(Event.element(e));
			}
		);
	}
}


/**
 * 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 = getElementsByClassName(thisControlBox,'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 getViewInHtml(viewContainerId,viewURL) {
	parameters = 'nohistory=1'; //'noheader=1';
	
	alert(viewURL);
	
	var myAjax = new Ajax.Updater(
		viewContainerId,
    viewURL,
    { 
    	method: 'get', 
    	parameters: parameters, 
    	onComplete: function() {
    		var thisViewContainer = document.getElementById(viewContainerId);
    		thisViewContainer.style.overflow = "scroll";
    		//alert(thisViewContainer.style.overflow);
    		/*links = thisViewContainer.getElementsByTagName('link');
    		for(var i=0;i<links.length;i++) {
    			//alert(links[i].getAttribute('href'));
    		}*/
    		
    		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);
					}
				}
    	},
    	onFailure: showFailureMessage,
    	onException: showException
    }
	);
	
	return false;
}




/**
 * 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) {
	for(var i=0;i<KOs.length;i++) {
		if(KOs[i] != thisKoId) {
			var containerOutline = document.getElementById('containerOutline'+KOs[i]);
			containerOutline.style.visibility = "hidden";
		}
	}
}


/**
 * displays overlay with progress wheel
 */
function showProgressOverlay(elementToOverlay) {
	if(elementToOverlay == undefined) {
		var body = document.getElementsByTagName('body');
		var elementToOverlay = body[0];
	}
	
	var baseurl = getBaseURL();
	
	getPosition(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);
			
		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';
	//}
}


/**
 * 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
	getPosition(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
			addClass(controllerButton,'controllerButton');
			controller.appendChild(controllerButton);
		
		
		// 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/closeControlBox.jpg');
			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
			addClass(closeControllerButton,'controllerButton');
			closeControlBoxButton.appendChild(closeControllerButton);
		
		
		var thisControlBox = document.getElementById('controlBox'+id);
			//thisContainer.insertBefore(controller,thisControlBox);
			document.getElementsByTagName('BODY')[0].insertBefore(controller,thisControlBox);
			insertAfter(closeControlBoxButton,controller);
			
	
		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();
				openControlBox(Event.element(e));
			}
		);
	}
		
	//thisContainer.style.border = '1px solid black';
	
	var newRight = thisContainerLeft+thisContainerWidth-2;
	
	// position controller
	 var offsetWidth = controller.offsetWidth;
	
	// 15 seems to be based upon padding - we should account for this - dwc
	controller.style.left = controller.style.left = (newRight-offsetWidth)+"px";
	controller.style.top = controller.style.top = thisContainerTop+"px";
}


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

	// get the positions now - they may have changed
	getPosition($('ko'+koId));
	var left = $('ko'+koId).x;
	var top = $('ko'+koId).y;
	var width = $('ko'+koId).w;
	var height = $('ko'+koId).h;

	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-2)+'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-2)+'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) {
	$('topOutline'+koId).parentNode.removeChild($('topOutline'+koId));
	$('leftOutline'+koId).parentNode.removeChild($('leftOutline'+koId));
	$('rightOutline'+koId).parentNode.removeChild($('rightOutline'+koId));
	$('bottomOutline'+koId).parentNode.removeChild($('bottomOutline'+koId));
}


/**
 * find and set the x,y and w (width) and h (height) for the element
 *
 * based upon code found here: http://www.quirksmode.org/js/findpos.html
 */
function getPosition(el) {
	el.w = el.offsetWidth, 
	el.h = el.offsetHeight;
	
	var curleft = curtop = 0;
	if (el.offsetParent) {
		var obj = el;
		curleft = obj.offsetLeft
		curtop = obj.offsetTop
		while (obj = obj.offsetParent) {
			curleft += obj.offsetLeft
			curtop += obj.offsetTop
		}
		el.x = curleft;
		el.y = curtop;
	} else {
		el.x = el.offsetLeft;
		el.y = el.offsetTop;
	}
	
	return el;
}


/**
 * finds all kos and creates controllers for each of them
 */
function setupControllers() {
	var editMode = document.getElementById("editMode");
	if(editMode) {
		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(hasClass(divs[i],'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";
				}
			}
		}
	}
}
var KOs = Array();


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

addLoadEvent(setupMessageWindows);
addLoadEvent(setupObjectSpace);
addLoadEvent(setupDrawers);
addLoadEvent(setupFormContext);
addLoadEvent(setupAutoCompleter);
addLoadEvent(setupInPlaceEditors);
//addLoadEvent(setupFckEditors);
addLoadEvent(setupControllers);
addLoadEvent(prepareUpdateVersionNumber);
