/// Extend the base Element class
//dbug.enable();
Element.implement({
	addClassOnce: function(strNewClass) {
		if ( this && this.hasClass && !this.hasClass(strNewClass) ) {
			this.addClass(strNewClass);
		}
		return this;
	},
	setWithHighlight: function(strProp, strValue) {
		var objProps = new Object();
		var objOptions = new Object();
		if ($type(strProp) == 'string') {
			objProps[strProp] = strValue;
		}
		else {
			objProps = strProp;
			if ($defined(objProps.compare)) {
				objOptions.compareName = objProps.compare;
				//if (!$defined(objProps[objProps.compare])) {
					objOptions.compareValue = objProps[objProps.compare];
				//}
				objProps.compare = null;
			//console.log('Found new version');
			}
			//if ($defined(objProps[objOptions.compareName])) {
			//	objOptions.compareValue = objProps.compareValue;
			//	objProps.compareValue = null;
			//}
		}
		
		//Implements = [Chain];
		if ( this && this.get ) {
			//		console.log('objProps',objProps, objOptions.compareName, $defined(objOptions.compareValue));
			var strThisBgColor = this.getStyle('background-color');
			if (objOptions.compareName && $defined(objOptions.compareValue) ) {
				if (this.get(objOptions.compareName) != objOptions.compareValue) { 
					if (($defined(objProps['text']) || $defined(objProps['html']) )) {
						this.highlight('#fff', this.getStyle('background-color'));// && !Browser.Engine.trident
					}
					this.set(objProps);
					return this;
				}
			}
			else {
				this.set(objProps);
			}

		
			//var eleTempDiv = new Element('div')
			//eleTempDiv.set(strProperty, objOptions);
			//var objTempOptions = eleTempDiv.get(strProperty);
	//		if (this.get(strProperty) != objOptions) { 
	//			if ((strProperty == 'text' || strProperty == 'html') && !Browser.Engine.trident) {
				
					//var localProps = this.get(strProperty)
					//this.setStyle('background-color', this.getStyle('background-color') );
	//				this.highlight('#fff', this.getStyle('background-color'));
					//function SetBgBack() {
					//	this.setStyle('background-color', null);
					//};
					//SetBgBack.delay(1000, this);
					//console.log('ActuallySet:',this.get(strProperty), 'NewSet:',objOptions);
	//			}
	//			this.set(strProperty, objOptions);
	//		}
		}
		return this;
	},
	selectValue: function(arrValues) {
		if (this.type == 'select-one' || this.type == 'select-multiple') {
			var eleSelect = this;
			/// Deselect everything
			for (var i = 0; i < eleSelect.options.length; i++) {
				var eleOption = eleSelect.options[i];
				eleOption.selected = false;
			}
			/// Select everything we need
			arrValues = $type(arrValues) == 'array' ? arrValues : [arrValues];
			arrValues.each(function(item) {
				for (var i = 0; i < eleSelect.options.length; i++) {
					var eleOption = eleSelect.options[i];
					if (eleOption.value == item) {
						eleOption.selected = true;
					}
				}
			});
		}
		return this;
	},
	selectText: function(arrValues) {
		if (this.type == 'select-one' || this.type == 'select-multiple') {
			var eleSelect = this;
			/// Deselect everything
			for (var i = 0; i < eleSelect.options.length; i++) {
				var eleOption = eleSelect.options[i];
				eleOption.selected = false;
			}
			/// Select everything we need
			arrValues = $type(arrValues) == 'array' ? arrValues : [arrValues];
			arrValues.each(function(item) {
				for (var i = 0; i < eleSelect.options.length; i++) {
					var eleOption = eleSelect.options[i];
					if (eleOption.text == item) {
						eleOption.selected = true;
					}
				}
			});
		}
		return this;
	},
	getSelectValue: function(arrValues) {
		if (this.type == 'select-one' || this.type == 'select-multiple') {
			return (this.options[this.selectedIndex].value != null) ? this.options[this.selectedIndex].value : this.options[this.selectedIndex].text;
		}
		return null;
	},
	getSelectText: function(arrValues) {
		if (this.type == 'select-one' || this.type == 'select-multiple') {
			return this.options[this.selectedIndex].text;
		}
		return null;
	},
	addOptions: function(arrOptions) {
		if (this.type == 'select-one' || this.type == 'select-multiple') {
			var eleSelect = this;
			arrOptions.each(function(objOption) {
				var eleOptionRow = null;
				if ($type(objOption) == 'element') {
					eleOptionRow = objOption;
				}
				else {
					eleOptionRow = new Option(objOption.text, objOption.value, objOption.defaultSelected || false, objOption.selected || false);
				}
				eleOptionRow = $(eleOptionRow);
				$try(function() { eleSelect.add( eleOptionRow, null ); }, function() { eleSelect.add( eleOptionRow ); });
			});
		}
		return this;
	},
	clearOptions: function() {
		if (this.type == 'select-one' || this.type == 'select-multiple') {
			var eleSelect = this;
			var intFilterListLength = eleSelect.options.length;
			for(var i = 0; i < intFilterListLength; i++) {
				eleSelect.remove(0);
			}
		}
		return this;
	},
	replaceOptions: function(arrOptions) {
		if (this.type == 'select-one' || this.type == 'select-multiple') {
			var eleSelect = this;
			eleSelect.clearOptions();
			return eleSelect.addOptions(arrOptions);
		}
		return this;
	},
	populate: function(objDbRecord) {
		dbug.log('Running Populate()');
		if (this.nodeName == 'FORM') {
			if (objDbRecord) {
				delete objDbRecord[''];
			}
			var eleForm = this;
			for (var strKey in objDbRecord) {
				var strValue = objDbRecord[strKey];
				var eleInput = eleForm.getElement('*[name='+strKey+']');
				dbug.log(strKey,eleForm,eleInput );
				if (eleInput) {
					/// Set Field Values
					if (eleInput.type == 'text' || eleInput.type == 'textarea' || eleInput.type == 'hidden') {
						eleInput.value = strValue || '';
					}
					else if (eleInput.type == 'select-one' || eleInput.type == 'select-multiple') {
						eleInput.selectValue(strValue);
						//for (var i = 0; i < eleInput.options.length; i++) {
						//	var eleOption = eleInput.options[i];
						//	eleOption.selected = false;
						//}
						//for (var i = 0; i < eleInput.options.length; i++) {
						//	var eleOption = eleInput.options[i];
						//	if (eleOption.value == strValue) {
						//		eleOption.selected = true;
						//	}
						//}
					}
					else if (eleInput.type == 'radio') {
						var eleForm = eleInput.getParent('form');
						eleInput = eleForm[eleInput.name];
						//dbug.log('Length:', eleInput.length, eleInput);
						//dbug.log('-------------------------------------------------------------------');
						for (var i = 0; i < eleInput.length; i++) {
							var eleOption = eleInput[i];
							eleOption.checked = false;
						}
						for (var i = 0; i < eleInput.length; i++) {
							var eleOption = eleInput[i];
							//dbug.log('eleOption',eleOption);
							if (eleOption.value == strValue) {
								eleOption.checked = true;
							}
						}
					}
					else if (eleInput.type == 'checkbox') {
						var arrEleInput = eleForm[eleInput.name];
						//dbug.log(eleInput,eleForm);
						//eleInput.addClass('GroupCount-' + eleInput.getParent('form')[eleInput.name].length);
						if (arrEleInput.length) {
							/// eleInput is a checkbox-group, not just one checkbox
							for (var i = 0; i < arrEleInput.length; i++) {
								var eleCheckbox = arrEleInput[i];
								eleCheckbox.checked = false;
								if (objDbRecord[eleCheckbox.value] && objDbRecord[eleCheckbox.value] == 1) {
									eleCheckbox.checked = true;
								}
							}
						}
						else {
							/// We are dealing with a standard checkbox
							//dbug.log(arrEleInput );
							if (strValue == eleInput.get('value')) {
								eleInput.checked = true;
							}
							else {
								eleInput.checked = false;
							}
						}
					}
					else {
						//dbug.log('Input was not caught by the type checkers. Input is a '+eleInput.type,eleInput,eleForm);
					}
				}
				/// Catch the date fields
				//dbug.log('objDbRecord',objDbRecord,'strKey',strKey,'strValue ',strValue );
				if (strValue && $type(strValue) == 'string' && strValue.match(/^(\d\d\d\d)\-(\d\d)\-(\d\d) (\d\d):(\d\d):(\d\d)/)) {
					//var arrMatches = strValue.match(/^(\d\d\d\d)\-(\d\d)\-(\d\d) (\d\d):(\d\d):(\d\d)/);
					/// We've got a date!
					var eleYear = eleForm.getElement('select[name='+strKey+'y], input[name='+strKey+'y]');
					var eleMonth = eleForm.getElement('select[name='+strKey+'m]');
					var eleDay = eleForm.getElement('select[name='+strKey+'d]');
					var eleHour = eleForm.getElement('select[name='+strKey+'h]');
					var eleMinute = eleForm.getElement('select[name='+strKey+'n]');
					var eleSecond = eleForm.getElement('select[name='+strKey+'s]');
					var eleAmPm = eleForm.getElement('select[name='+strKey+'ampm]');
					
					//for(var i=0; i < arrMatches.length; i++) {
					//	arrMatches[i] = arrMatches[i].toInt();
					//}
					var objTime = DateParts(strValue);
					
					/// If this is actually a date field
					//dbug.log('Fount a date', strKey+'='+strValue, objTime );
					if (eleYear) {
						//console.debug('eleYear',eleYear);
						if (eleYear.type == 'text') {
							eleYear.set('value', objTime.y);
						}
						else {
							eleYear.selectValue(objTime.y);
						}
					}
					if (eleMonth) {
						eleMonth.selectValue(objTime.m);
					}
					if (eleDay) {
						eleDay.selectValue(objTime.d);
					}
					if (eleHour) {
						eleHour.selectValue(eleAmPm ? (objTime.h > 12 ? objTime.h-12 : objTime.h) : objTime.h);
					}
					if (eleMinute) {
						eleMinute.selectValue(objTime.n);
					}
					if (eleSecond) {
						eleSecond.selectValue(objTime.s);
					}
					if (eleAmPm) {
						eleAmPm.selectValue(objTime.h >= 12 ? 'PM' : 'AM');
					}
				}
				eleForm.getElements('.'+strKey).each( function(eleItem) {
					eleItem.set('text', strValue);
				});
			}
		}
		return this;
	},
	getNonContentSize: function() {
		elem = this;
		var objSize = new Object();
		objSize.x = elem.getStyle('padding-left').toInt() + elem.getStyle('padding-right').toInt() + elem.getStyle('margin-left').toInt() + elem.getStyle('margin-right').toInt() + elem.getStyle('border-left-width').toInt() + elem.getStyle('border-right-width').toInt();
		objSize.y = elem.getStyle('padding-top').toInt() + elem.getStyle('padding-bottom').toInt() + elem.getStyle('margin-top').toInt() + elem.getStyle('margin-bottom').toInt() + elem.getStyle('border-top-width').toInt() + elem.getStyle('border-bottom-width').toInt();
		return objSize;
	}

});

/// Setup Globals
var accordionHeadingSelector = 'h3';
var accordionBodySelector = 'div';
var bitDebugEnabled = false;

/// A list of domain names to consider "internal". Can include regular expressions.
var InternalDomains = new Array(
	'library.ucf.edu',
	'm.library.ucf.edu',
	/lib\.ucf\.edu/,
	'cf.aleph.fcla.edu',
	'cf.catalog.fcla.edu',
	'metalib.fcla.edu',
	'fclnx5.fcla.edu',
	'sfx.fcla.edu',
	'sfx-test.fcla.edu'
);

/// Add a class to the body tag which identifies what browser we are using. That way we can easily write CSS that can provide rules to just one browser without having to use hacks!
function AddBrowserToBody() {
	var eleBody = $(document.body);
	if (eleBody) {
		switch (Browser.Engine.name){
			case 'webkit': 
				eleBody.addClass('BrowserWebkit');
				break
			case 'gecko': 
				eleBody.addClass('BrowserGecko');
				break
			case 'presto': 
				eleBody.addClass('BrowserOpera');
				break
			case 'trident': {
				eleBody.addClass('BrowserIE');
				//window.alert('Browser Vresion: '+Browser.Engine.version);
				for (var i=Browser.Engine.version; i >= 1 && i >= Browser.Engine.version-10; i--) {
				//if (Browser.Engine.version <= 5) {
					eleBody.addClass('BrowserIE'+i);
					//window.alert('BrowserIE'+i);
				}
				//var i = Browser.Engine.version;
				//while (i >= 1 || i >= Browser.Engine-20) {
				//	eleBody.addClass('BrowserIE'+i);
				//	i--;
				//}
				break
			}
			//default : alert("No movie was seen")
		}
	}
}
AddBrowserToBody();


/// Classes //////////////////////////////////////////////////////////////////////

var DB = new Class({
	Implements: [Options, Events, Request],

	options: {
		//relatedSelect: null
		data: {},
		
		onSuccess: $empty(),
		onFail: $empty()
	},
	objData: null,
	strQuery: null,

	initialize: function(_strQueryName, _options) {
		if (!$defined(_strQueryName)) return;
		this.strQuery = _strQueryName;
		this.setOptions(_options);
		
		this.objData = this.options.data;
		if (!$defined(this.objData.q)) {
			this.objData.q = this.strQuery;
		}
		this.issueRequest();
	},
	issueRequest: function() {
		var myJSONRemote = new Request.JSON({
			'url': '/Web/Db.php',
			'data': this.objData,
			'method': 'get',
			'link': 'cancel',
			//'headers': {
			//	'Origin': 'http://develop.lib.ucf.edu'
			//},
			'onSuccess': function(objResponse, strResponse) {
				if (!objResponse) {
					//dbug.log('DB Poll Response:',objResponse, strResponse);
					//StickyWin.alert('Problem loading the data', 'There was an error encountered while trying to communicate with the database. The response we got was as follows: <br><br>'+strResponse);
					this.fireEvent('failure');
					return false;
				}
				//dbug.log('myJSONRemote:', myJSONRemote );
				//dbug.log('objResponse:', objResponse);
				var objDebug = objResponse.shift();
				var intRows = objDebug.recordcount;
				
				//dbug.log('objResponse:', objResponse, 'objDebug:', objDebug);
				//this.options.onSuccess(objResponse, intRows, objDebug);
				this.fireEvent('success', [objResponse, intRows, objDebug]);
				return this;
			}.bind(this),
			'onFailure': function(objRequest) {
				var objResponse = JSON.decode(objRequest.responseText);
				dbug.log('DB Failure Response:', objResponse, 'Request:', objRequest);
				var objDebug = null;
				var strErrorText = objRequest.statusText;
				if (objResponse && objResponse[0]) {
					strErrorText = objResponse[0]['error']['message'];
					objDebug = objResponse.shift();
				}
				StickyWin.alert('Problem loading the data', 'There was an error encountered while trying to communicate with the database. The response we got was as follows: <br><br>'+strErrorText);
				//this.options.onFail(objResponse, strResponse);
				this.fireEvent('fail', [strErrorText, objDebug, objResponse]);
				return this;
			}.bind(this)
		}, this);
		myJSONRemote.send();
	}
});

var Drawer = new Class({
	Implements: [Options, Events, Fx, Chain],

	options: {
		selectorTitle: '.Title',
		selectorBody: '.Body',
		direction: 'up',
		durationSlide: 500,
		transitionSlide: 'quad:in:out'
	},
	Fx: null,
	
	eleDrawer: null,
	eleTitle: null,
	eleChevron: null,
	eleBody: null,
	eleBodyFrame: null,
	eleBodyFrameInner: null,
	
	bitOpen: true,
	bitLastAction: false,
	bitInProgress: false,
	
	objDirections: null,
	objCoordsOpen: null,
	objCoordsClosed: null,
	objDateInit: null,
	objDateNow: null,
	
	boundToggle: $empty(),
	boundWindowSizeCheck: $empty(),

	initialize: function(eleDrawer, _options) {
		this.boundToggle = this.toggle.bind(this);
		this.boundWindowSizeCheck = this.windowSizeCheck.bind(this);
		
		this.setOptions(_options);
		
		this.eleDrawer = $(eleDrawer);
		if (!$defined( this.eleDrawer)) {
			return false;
		}
		
		this.objCoordsOpen = new Object();
		this.objCoordsClosed = new Object();
		this.objCoordsOpen.top = 0;
		this.objCoordsOpen.left = 0;
		this.objCoordsOpen.width = 0;
		this.objCoordsOpen.height = 0;
		
		this.objCoordsClosed.top = 0;
		this.objCoordsClosed.left = 0;
		this.objCoordsClosed.width = 0;
		this.objCoordsClosed.height = 0;
		
		/// Standard HTML sizes go from top left to bottom right. The following are directional multipliers. Positive is standard negative is reverse.
		this.objDirections = {
			'up': {'x': 0, 'y': 1},
			'right': {'x': -1, 'y': 0},
			'down': {'x': 0, 'y': -1},
			'left': {'x': 1, 'y': 0}
		};
		
		this.objDateInit = new Date();
		
		this.eleTitle = this.eleDrawer.getElement(this.options.selectorTitle);
		this.eleBody = this.eleDrawer.getElement(this.options.selectorBody);
		
		this.eleChevron = new Element('div', {'class': 'Chevron'});
		this.eleBodyFrame = new Element('div', {'styles': {'position': 'absolute', 'overflow': 'hidden'}});		//, 'border': '1px dashed blue'
		this.eleBodyFrameOuter = new Element('div', {'styles': {'position': 'absolute', 'overflow': 'hidden'}});		//, 'border': '1px dotted red'
		this.eleBodyFrameInner = new Element('div', {'styles': {'position': 'absolute', 'top': 0, 'left': 0}});
		this.windowSizeCheck();
		this.eleBodyFrame.setStyles({'width': this.objCoordsOpen.width, 'height': this.objCoordsOpen.height, 'top': this.objCoordsOpen.top, 'left': this.objCoordsOpen.left});
		//this.bitOpen = false;
		
		this.eleTitle.grab(this.eleChevron, 'top');
		this.eleBodyFrameInner.wraps(this.eleBody);
		this.eleBodyFrameOuter.wraps(this.eleBodyFrameInner);
		this.eleBodyFrame.wraps(this.eleBodyFrameOuter);
		
		/// Prepare the frame and set the speed to 0 so it will transition immediately instead of slowly as the page loads
		this.eleBodyFrameOuter.set('morph', {'link': 'cancel', 'unit': 'px', 'duration': 0, 'transition': this.options.transitionSlide, 'onStart': function() { this.bitInProgress = true; }, 'onComplete': function() { this.bitInProgress = false; } });
		
		this.Fx = this.eleBodyFrameOuter.get('morph');
		
		/// Close it and set the duration so it's in place and ready once it's clicked
		this.close();
		function Delayer() {
			this.Fx.options.duration = this.options.durationSlide;
		}
		Delayer.delay(20, this);
		
		this.add_events();
	},
	windowSizeCheck: function() {
		if (this.bitOpen) {
			var objWindowSize = $(window).getSize();
			var objDrawerParentSize = this.eleDrawer.getParent().getSize();
			var objTitleCoords = this.eleTitle.getCoordinates();
			var objBodyCoords = this.eleBody.getCoordinates();
			var numDirX = this.objDirections[this.options.direction].x;
			var numDirY = this.objDirections[this.options.direction].y;
			
			var numFrameTop = 0;
			var numFrameLeft = 0;
			
			var objMargins = this.eleBody.getStyles('margin-top','margin-right','margin-bottom','margin-left');
			var numMarginV = objMargins['margin-top'].toInt() + objMargins['margin-bottom'].toInt();
			var numMarginH = objMargins['margin-right'].toInt() + objMargins['margin-left'].toInt();
			//console.debug('numMarginV ', numMarginV , 'numMarginH ', numMarginH );
			
			if (numDirY == 0) {
				// Height of body matches title. Horizontal drawer.
				numFrameTop = objTitleCoords.top;
				this.objCoordsOpen.height = objBodyCoords.height + numMarginV;
				this.objCoordsOpen.top = objTitleCoords.top;
				this.objCoordsOpen.width = objBodyCoords.width + numMarginH;
				this.objCoordsClosed.width = objBodyCoords.width + numMarginH;
			}
			if (numDirX > 0) {
				/// Left drawer
				numFrameLeft = objTitleCoords.left - objBodyCoords.width - numMarginH;
				this.objCoordsOpen.left = 0;
				this.objCoordsClosed.left = objBodyCoords.width + numMarginH;
			}
			if (numDirX < 0) {
				/// Right drawer
				numFrameLeft = objTitleCoords.left + objTitleCoords.width;
				this.objCoordsOpen.left = 0;
				this.objCoordsClosed.left = (objBodyCoords.width + numMarginH) * -1;
				this.eleBodyFrameInner.setStyles({'right': 0, 'left': 'auto'});
			}
			
			if (numDirX == 0) {
				/// Width of body matches title. Vertical drawer.
				this.objCoordsOpen.width = objTitleCoords.width;
				numFrameLeft = objTitleCoords.left;
				this.objCoordsOpen.left = 0;
			}
			if (numDirY > 0) {
				/// Up drawer
				numFrameTop = objTitleCoords.top - objBodyCoords.height - numMarginV;
				this.objCoordsOpen.top = 0;
				this.objCoordsClosed.top = objBodyCoords.height + numMarginV;
				this.objCoordsOpen.height = objBodyCoords.height + numMarginV;
				this.objCoordsClosed.height = this.objCoordsOpen.height;
			}
			if (numDirY < 0) {
				/// Down drawer
				numFrameTop = objTitleCoords.top + objTitleCoords.height;
				this.objCoordsOpen.top = 0;
				this.objCoordsClosed.top = (objBodyCoords.height + numMarginV) * -1;
				this.objCoordsOpen.height = objBodyCoords.height + numMarginV;
				this.objCoordsClosed.height = this.objCoordsOpen.height;
				this.eleBodyFrameInner.setStyles({'bottom': 0, 'top': 'auto'});
			}
			
			this.eleBodyFrame.setStyles({'width': this.objCoordsOpen.width, 'height': this.objCoordsOpen.height, 'top': numFrameTop, 'left': numFrameLeft});
			this.eleBodyFrameOuter.setStyles({'width': this.objCoordsOpen.width, 'height': this.objCoordsOpen.height});
			this.eleBodyFrameInner.setStyles({'width': this.objCoordsOpen.width, 'height': this.objCoordsOpen.height});
		}
	},
	open: function() {
		this.bitOpen = true;
		this.show();
		var objChange = new Object();
		if (this.objDirections[this.options.direction].x != 0) {
			objChange.width = this.objCoordsOpen.width;
			objChange.left = this.objCoordsOpen.left;
		}
		if (this.objDirections[this.options.direction].y != 0) {
			objChange.height = this.objCoordsOpen.height;
			objChange.top = this.objCoordsOpen.top;
		}
		this.eleDrawer.removeClass('Closed');
		this.eleDrawer.addClass('Open');
		this.Fx.start(objChange).chain( function() {  });
		//console.log('Open.set("top": '+objChange.top+', "left": '+objChange.left+', "width": '+objChange.width+', "height": '+objChange.height+')');
	},
	close: function() {
		var objChange = new Object();
		if (this.objDirections[this.options.direction].x != 0) {
			objChange.width = this.objCoordsClosed.width;
			objChange.left = this.objCoordsClosed.left;
		}
		if (this.objDirections[this.options.direction].y != 0) {
			objChange.height = this.objCoordsClosed.height;
			objChange.top = this.objCoordsClosed.top;
		}
		this.eleDrawer.removeClass('Open');
		this.eleDrawer.addClass('Closed');
		this.Fx.start(objChange).chain(this.hide.bind(this));
		//console.log('Close.set("top": '+objChange.top+', "left": '+objChange.left+', "width": '+objChange.width+', "height": '+objChange.height+')');
	},
	show: function() {
		this.bitOpen = true;
		this.objDateNow = new Date();
		this.eleBodyFrame.setStyles({'display': 'block', 'z-index': ((this.objDateNow.getTime() - this.objDateInit.getTime()) / 1000) });
		this.windowSizeCheck();
	},
	hide: function() {
		//this.windowSizeCheck();
		this.bitOpen = false;
		this.eleBodyFrame.setStyle('display', 'none');
	},
	toggle: function() {
		dbug.log('Toggling the drawer', this.bitLastAction);
		if (this.bitLastAction) {
			this.bitLastAction = false;
			this.close();
		}
		else {
			this.bitLastAction = true;
			this.open();
		}
		return false;
	},
	destroy: function(_revert) {
		this.remove_events();
	},
	add_events: function() {
		this.eleTitle.addEvent('click', this.boundToggle );
		//this.eleTitle.addEvent('dblclick', this.boundToggle );
		window.addEvent('resize', this.boundWindowSizeCheck);
		window.addEvent('load', this.boundWindowSizeCheck);
	},
	remove_events: function() {
		this.eleDrawer.removeEvents();
	}
});

//dbug.enable();
var FormGen = new Class({
	Implements: [Options],

	options: {},
	
	eleForm: null,
	eleCompleteButton: null,
	objFormVars: null,
	
	initialize: function(form, _options) {
		this.setOptions(_options);
		
		if (!$(form)) return;
		this.eleForm = $(form);
		
		this.objFormVars = new Object();
		
		this.prepareFormVariables();
		this.createCompleteButton();
		this.addCompleteButton();
	},
	prepareFormVariables: function() {
		for (var i = 0; i < this.eleForm.elements.length; i++) {
			var eleInput = $(this.eleForm.elements[i]);
			if (eleInput.type == 'checkbox') {
				this.objFormVars[eleInput.get('name')] = eleInput.get('value');
			}
			else if (eleInput.type == 'radio') {
				eleInput = this.eleForm[eleInput.name];
				if (eleInput[0]) {
					this.objFormVars[eleInput[0].name] = eleInput[0].value;
				}
			}
			else if (eleInput.type == 'select-one') {
				var intSelection = Math.floor(Math.random() * eleInput.options.length)
				this.objFormVars[eleInput.get('name')] = eleInput.options[intSelection].value || eleInput.options[intSelection].text;
				//dbug.log(eleInput.get('name'), this.objFormVars);
			}
			else {
				this.objFormVars[eleInput.get('name')] = eleInput.get('name') + Math.floor(Math.random()*11);
			}
		}
		//dbug.log('this.objFormVars',this.objFormVars);
	},
	createCompleteButton: function(eleOriginalSelect) {
		
		this.eleCompleteButton = new Element('input', {
			type: 'button',
			'class': 'button',
			value: 'Auto-Complete this Form',
			styles: {
				'float': 'right',
				'display': 'block',
				'margin': '0.5em'
			},
			events: {
				click: function() {
					this.populateForm();
				}.bind(this)
			}
		});
	},
	addCompleteButton: function(eleOption) {
		this.eleForm.grab(this.eleCompleteButton, 'top');
	},
	populateForm: function() {
		//dbug.log('got to here',this);
		this.eleForm.populate(this.objFormVars);
	}
});

var CheckboxTree = new Class({
	Implements: [Options, Events],
	//Binds: ['setStates'],

	options: {},
	
	eleForm: null,

	initialize: function(form, _options) {
		if (!$(form)) return;
		this.eleForm = $(form);
		this.setOptions(_options);
		
		this.arrCheckboxes = this.eleForm.getElements('li input[type=checkbox]');
		this.arrCheckboxes.each(function(eleCheckbox) {
			eleCheckbox.checkChildren = this.checkChildren;
			eleCheckbox.checkParents = this.checkParents;
		}, this);
		
		this.add_events();
	},
	add_events: function() {
		this.arrCheckboxes.addEvent('click', this.setStates);
	},
	//destroy: function(_revert) {
	//	this.remove_events();
	//},
	setStates: function() {
		this.checkChildren();
		this.checkParents();
	},
	checkChildren: function() {
		/// 'this' is the checkbox
		var eleParentLi = this.getParent('li');
		if (eleParentLi) {
			var arrCheckboxes = eleParentLi.getElements('input[type=checkbox]');
			arrCheckboxes.each(function(eleCheckbox) {
				eleCheckbox.set('checked', this.get('checked'));
				eleCheckbox.indeterminate = false;
			}, this);
		}
	},
	checkParents: function() {
		/// 'this' is the checkbox
		var arrParentLis = this.getParents('li');
		//dbug.log(arrParentLis);
		arrParentLis.each(function(eleParentLi, indexParent) {
			if (indexParent +1 == arrParentLis.length) {
				return true;
			}
			var bitFoundChecked = false;
			var bitFoundUnchecked = false;
			var bitNewIndeterminateState = false;
			var bitNewCheckState = false;
			
			var arrSiblingLis = eleParentLi.getSiblings('li');
			arrSiblingLis.push(eleParentLi);
			arrSiblingLis.each(function(eleSiblingLi) {
				var eleCheckbox = eleSiblingLi.getElement('input[type=checkbox]');
				if (eleCheckbox) {
					var bitCheckState = eleCheckbox.get('checked') || false;
					var bitIndeterminateState = eleCheckbox.indeterminate || false;
					
					/// If it's marked as indeterminate, just trust that we found both and skip over the check
					if (bitIndeterminateState) {
						bitFoundChecked = true;
						bitFoundUnchecked = true;
					}
					else {
						if (bitCheckState == true) {
							if (bitFoundChecked == false) {
								bitFoundChecked = true;
							}
						}
						else {
							if (bitFoundUnchecked == false) {
								bitFoundUnchecked = true;
							}
						}
					}
					
					/// Set new states for the parent checkbox
					if (bitFoundChecked && bitFoundUnchecked) {
						bitNewIndeterminateState = true;
						bitNewCheckState = false;
					}
					else if (bitFoundChecked) {
						bitNewIndeterminateState = false;
						bitNewCheckState = true;
					}
					else {
						bitNewIndeterminateState = false;
						bitNewCheckState = false;
					}
				}
				//dbug.log('-eleSiblingLi',eleSiblingLi,'bitCheckState ',bitCheckState ,'bitIndeterminateState ',bitIndeterminateState );
			}, this);
			
			var eleParentCheckbox = eleParentLi.getParent('li').getElement('input[type=checkbox]');
			//dbug.log('eleParentCheckbox ',eleParentCheckbox, bitNewCheckState,  bitNewIndeterminateState);
			//eleParentCheckbox.getParent().setStyle('border', '1px dashed red');
			eleParentCheckbox.indeterminate = bitNewIndeterminateState;
			eleParentCheckbox.set('checked', bitNewCheckState);
			
		}, this);
	}
});


/// Functions //////////////////////////////////////////////////////////////////////

function Reload() {
	window.location = window.location;
}

function ResetField(obj,defaultVal) {
	if (obj) {
		if ( obj.value == '' ) {
			obj.value = defaultVal;
		}
	}
}
function ClearField(obj,defaultVal) {
	if (obj) {
		if ( obj.value == defaultVal ) {
			obj.value = '';
		}
	}
}
function goHere(me) {
	if (me.value != '0')	window.location = me.value;
}

function Tokenizer(strToken, strBodyText, strTokenContent) {
	return Token(strBodyText, strToken, strTokenContent);
}

// function StrReplace(str,token,repstr,limit,reverse) {
	// limit = limit || -1;
	// var intPos;
	// if (reverse) {
		// intPos = str.lastIndexOf(token);
	// }
	// else {
		// intPos = str.indexOf(token);
	// }
	// # print "STR: $str; POS: $pos; TOKEN: $token; \n";
	// while (intPos > -1 && (limit > 0 || limit <= -1)) {
		// if (intPos >= 0 ) {
			// substr(str, intPos, token.length() ) = repstr;
		// }
		// if (reverse) {
			// intPos = str.lastIndexOf(token);
		// }
		// else {
			// intPos = str.indexOf(token);
		// }
		// limit--;
	// }
	// return str;
// }

function Token(strFullText, strToken, strReplacement) {
	//var evaluatedRegex = eval('/%'+strToken+'/g');
	var evaluatedRegex = new RegExp('%'+strToken, 'g');
	return strFullText.replace(evaluatedRegex, strReplacement);
}

function Tokens(strFullText, objTokens) {
	//var evaluatedRegex = eval('/%'+strToken+'/g');
	for (var strToken in objTokens) {
		var evaluatedRegex = new RegExp('%'+strToken, 'g');
		strFullText = strFullText.replace(evaluatedRegex, objTokens[strToken]);
	}
	return strFullText;
}

/****************************
/
/ Toggles boolean values
/
/***************************/
function Toggle(state) {
	if (state == true || state == false) {
		if (state == true) {
			return false;
		}
		else {
			return true;
		}
	}
	return state;
}

/****************************
/
/ FactorRound will round any number by a factor to the nearest intRoundBy decimal place provided.
/ Decimal numbers can be rounded by using negative values for the intRoundBy value.
/
/ FactorRound(1234, 2) == 1200
/ FactorRound(1634, 3) == 2000
/
/***************************/
function FactorRound(numDecimal,intRoundBy) {
	var numRoundFactor = Math.pow(10,intRoundBy*-1);
	var numNew = numDecimal;
	numNew*= numRoundFactor;
	numNew = numNew.round();
	numNew/= numRoundFactor;
	return numNew;
}

/****************************
/
/ Toggles an ID or an object reference between block and none, to show or hide it.
/
/***************************/
function ToggleBlock(id, manualstate) {
	var obj = $(id);
	if (obj) {
		if ( manualstate != null ) {
			if (manualstate) {
				obj.setStyle('display', 'block');
				return true;
			}
			else {
				obj.setStyle('display', 'none');
				return false;
			}
		}
		else {
			var objstyle = obj.getStyle('display');
			if (objstyle == 'none') {
				obj.setStyle('display', 'block');
				return true;
			}
			else {
				obj.setStyle('display', 'none');
				return false;
			}
		}
	}
}

/****************************
/
/ AJAX Request object
/
/***************************/
function GetXmlHttpObject() {
	var xmlHttp;
	try {
		// Firefox, Opera 8.0+, Safari
		xmlHttp=new XMLHttpRequest();
	}
	catch (e) {
		// Internet Explorer
		try {
			xmlHttp=new ActiveXObject("Msxml2.XMLHTTP");
		}
		catch (e) {
			try {
				xmlHttp=new ActiveXObject("Microsoft.XMLHTTP");
			}
			catch (e) {
				alert("Your browser does not support AJAX!");
				return false;
			}
		}
	}
	return xmlHttp;
}

/****************************
/
/ ZeroPad - Add a zero to a number less than 10
/
/***************************/
function ZeroPad(number) {
	return (number < 10) ? '0' + number : number;
}

/****************************
/
/ Plural - if the amount is 1, don't return an S, otherwise do.
/
/***************************/
function Plural(amount) {
	return amount == 1 ? '' : 's';
}

function NumText(n) {
	n = ''+n+'';
	var ext = 'th';
	if (n == 11 || n == 12 || n == 13) {
		ext = 'th';
	}
	else if ( n.match(/1$/) ) {
		ext = 'st';
	}
	else if ( n.match(/2$/) ) {
		ext = 'nd';
	}
	else if ( n.match(/3$/) ) {
		ext = 'rd';
	}
	return n + ext;
}

/****************************
/
/ Build a query for use with either GET or POST. Send in an object wth properties and get back the whole query string.
/
/***************************/
function BuildQuery(queryObj) {
	var QueryString = new Array();
	for (fieldname in queryObj) {
		QueryString.push(fieldname + '=' + queryObj[fieldname]);
		//window.alert(fieldname + '=' + queryObj[fieldname]);
	}
	return QueryString.join('&');
}

/****************************
/
/ Build a query string. Send in an object wth properties and get back the whole query string.
/
/***************************/
function BuildQueryString(queryObj) {
	return '?' + BuildQuery(queryObj);
}



/****************************
/
/ Internal Website Domains. External ones will return false;
/
/***************************/
function isInternalDomain(url) {
	//console.log('Recieved: ' + url + ';');
	url = url.toLowerCase();
	if (url == '' || url.match(/^[\/\.]/)) {
		//console.log('BOOYA!! Found it! ' + url + ' is internal alright. And we get to stop early.');
		return true;
	}
	url = url.replace(/^[hf]tt?ps?:\/\//, '');
	url = url.replace(/\/.*$/, '');
	
	/*
	var InternalDomains = new Array(
		'library.ucf.edu',
		'm.library.ucf.edu',
		/lib\.ucf\.edu/,
		'cf.aleph.fcla.edu',
		'cf.catalog.fcla.edu',
		'metalib.fcla.edu',
		'sfx.fcla.edu'
	);
	*/
	
	//for (var domain in InternalDomains) {
	for (var i = 0; i < InternalDomains.length; i++) {
		var domain = InternalDomains[i];
		//console.log('Testing: ' + url + '; against ' + domain);
		if ( url.match(domain) ) {
			//console.log('BOOYA!! Found it! ' + url + ' is internal alright.');
			return true;
		}
	}
	
	//console.log('Well, I guess ' + url + ' must be external.');
	return false;
}

function MinutesToText(intMinutes) {
	var strHours, strMinutes, strOut;
	var intHoursOut = parseInt(intMinutes / 60);
	var intMinutesOut = intMinutes % 60;
	
	if (intHoursOut == 1) {
		strHours = intHoursOut + ' Hour';
	}
	else {
		strHours = intHoursOut + ' Hours';
	}

	if (intMinutesOut == 1) {
		strMinutes = intMinutesOut + ' Minute';
	}
	else {
		strMinutes = intMinutesOut + ' Minutes';
	}
	
	if (intHoursOut > 0 && intMinutesOut > 0) {
		strOut = strHours + ' ' + strMinutes;
	}
	else if (intHoursOut > 0) {
		strOut = strHours;
	}
	else {
		strOut = strMinutes;
	}
	return strOut;
}

function IsoDate(strDate) {
	//var strFriendlyDate = objRecord['event_date'];
	var strFriendlyDate = strDate.replace(/^(\d+)-(\d+)-(\d+) (\d+):(\d+):(\d+).*/, '$2/$3/$1 $4:$5:$6');
	// strFriendlyDate = strFriendlyDate.replace(/\..*$/, '');
	var objDate = new Date(strFriendlyDate);
	return objDate;
}

function Duration(intMinutes) {
	var strOut = '';
	var intHours = (intMinutes/60).floor();
	var intMin = intMinutes % 60;
	if (intHours)	{
		strOut+= intHours +' Hour'+ Plural(intHours);
		if (intMin) {
			strOut+= ' ';
		}
	}
	if (intMin)	{
		strOut+= intMin +' Minute'+ Plural(intMin );
	}
	return strOut;
}



/****************************
/
/	Size()
/
/ Returns the number sent is as if it were a size in bytes as a string.
/
/***************************/
function Size(s) {
	s = Math.ceil(s);
	var Chart = new Array('bytes', 'KB', 'MB', 'GB', 'TB');
	//foreach my $s (@Sizes) {
	var result = '0 bytes';
	for (var count = 0; count < Chart.length; count++) {
		var c = Chart[count];
		var key = Math.pow(2, (count*10));
		//if (s != parseInt(s)) {
		//	s = parseInt(s+1);
		//}
		if (s < key) {
			break;
		}
		//window.alert('s=' + s + '; key='+ key + '; c='+c + '; count='+count);
		result = Math.ceil((s/key) * 100) / 100;
		//result = sprintf('%.2f', s/key);
		result = result + ' ' + c;
		//count++;
	}
	return result;
}

/****************************
/
/ Save Cookie
/
/***************************/
function SaveCookie(cookie,value,reload,expiretime) {
	expiretime = expiretime || (60 * 60 * 24 * 365 * 10); // 10 years from now.
	var expiration = new Date();
	expiration.setSeconds(expiration.getSeconds() + expiretime);
	document.cookie = cookie + "=" + value
	+ "; expires=" + expiration.toUTCString() + ";path=/";
	// Fri, 31-Dec-2000 00:00:00 GMT
	if (reload) {
		window.location.href = window.location.href;
	}
}

/****************************
/
/ Get A Cookie Value By Name
/
/***************************/
//Get cookie routine by Shelley Powers (get_cookie) Thanks Shelly
function GetCookie(name) {
	var search = name + "="
	var returnvalue = "";
	if (document.cookie.length > 0) {
		offset = document.cookie.indexOf(search)
		// if cookie exists
		if (offset != -1) { 
			offset += search.length
			// set index of beginning of value
			end = document.cookie.indexOf(";", offset);
			// set index of end of cookie value
			if (end == -1) end = document.cookie.length;
			returnvalue=unescape(document.cookie.substring(offset, end))
		}
	}
	return returnvalue;
}

/****************************
/
/ Add a shadow to any element with a Shadow class
/
/***************************/
function AddShadow(item) {
	item = $(item);
	
	//var debug = '';
	//for (var prop in Aside ) {
	//	var value = Aside[prop];
	//	if (value != null && (typeof value == 'string')) {
	//		debug+= prop + ': ' + value + '\n';
	//	}
	//}
	//window.alert(debug);
	//var Aside = item.clone(true, true).cloneEvents(item);
	//Aside.className = item.className;
	//var Container = new Element('div');
	//Container.grab(Aside);
	
	//if (Browser.Engine.webkit || Browser.Engine.gecko) {
		// Browsers that support the box-shadow property
		item.addClass('Shadow');
	//}
	//else {
		// Other browsers
	//	var Shadow = new Element('div', {'class': 'ShadowFaux'});
	//	Container.grab(Shadow);
	//}
	//Container.replaces(item);
	//return Container;
	return item;
}

/****************************
/
/ Highlight the current day of the week in hours tables
/
/***************************/
function InitializeHours() {
	var Calendar = new Date();
	var weekday = Calendar.getDay();
	if ( weekday >= 1 && weekday <= 4) {
		weekday = '';
	}
	var HoursRows = $$('.HoursRow');
	HoursRows.each( function(row) {
		
		if (row.id == 'Hours'+weekday) {
			row.addClass('Active');
		}
		else {
			row.removeClass('InActive');
		}
	});
}


/****************************
/
/ Determine if the event is occuring inside a place where keyboard events normally happen
/
/***************************/
function IgnoreKeyboardInput(event) {
	var tname = event.target.nodeName;
	if (tname == 'INPUT' || tname == 'TEXTAREA' || tname == 'SELECT') {
		/// Don't bother running the function if we are in a form field.
		return true;
	}
	return false;
}

/****************************
/
/ Double flash an element's background
/
/***************************/
function HighlightThis(element, origbgcolor ) {
	if (element) {
		var origbgcolor = origbgcolor || element.getStyle('background-color');
		//window.alert(origbgcolor);
		if (origbgcolor == 'transparent') {
			origbgcolor = '#ddd';
		}
		
		//var myFx = new Fx.Tween(element, {property: 'opacity', duration: 150});
		//myFx.start(0.3).chain(
			//Notice that "this" refers to the calling object (in this case, the myFx object).
		//	function(){ this.start(1); },
		//	function(){ this.start(0.3); },
		//	function(){ this.start(1); }
		//);
		var myFx = new Fx.Tween(element, {property: 'background-color', duration: 150});
		myFx.start('#fff').chain(
			//Notice that "this" refers to the calling object (in this case, the myFx object).
			function(){ this.start(origbgcolor); },
			function(){ this.start('#fff'); },
			function(){ this.start(origbgcolor); }
		);
	}
}

dbug.enable();
/*
function ActivateAccordionHeading(strHash) {
	strHash = strHash.replace(/^#/, '');
	if (strHash) {
		//window.alert(hash);
		var arrAccHeadingAnchors = $$('a[name='+strHash+'], #'+strHash);
		if (arrAccHeadingAnchors) {
			var eleAccHeadingAnchor = arrAccHeadingAnchors.shift();
			if (eleAccHeadingAnchor) {
				var eleAccParent = eleAccHeadingAnchor.getParent('.Accordion');
				if (eleAccParent) {
					var eleAccHeading = eleAccHeadingAnchor.getParent(accordionHeadingSelector);
					var objAccordion = eleAccParent.retrieve('accordion');
					if (objAccordion) {
						var intHeadingIndex = eleAccHeading.get('index').toInt() +1;
						dbug.log('objAccordion',objAccordion, eleAccHeadingAnchor, eleAccParent, intHeadingIndex  );
						objAccordion.display( intHeadingIndex );
					}
				}
			}
		}
	}
}
*/

function ActivateAccordionHeading(strHash) {
	var intHeadingIndex = FindAccordionSectionIndex(strHash);
	dbug.log('Accordion Index:',intHeadingIndex );
	if (intHeadingIndex != false) {
		dbug.log('No need to load a new page, just activated section: '+intHeadingIndex );
		return false;
	}
	return true;
}

function FindAccordionSectionIndex(strHash) {
	strHash = strHash || window.location.hash;
	strHash = strHash.replace(/^#/, '');
	if (strHash) {
		//window.alert(hash);
		var arrAccHeadingAnchors = $$('a[name='+strHash+'], #'+strHash);
		if (arrAccHeadingAnchors) {
			var eleAccHeadingAnchor = arrAccHeadingAnchors.shift();
			if (eleAccHeadingAnchor) {
				var eleAccParent = eleAccHeadingAnchor.getParent('.Accordion');
				if (eleAccParent) {
					var eleAccHeading = eleAccHeadingAnchor.getParent(accordionHeadingSelector);
					var intHeadingIndex = eleAccHeading.get('index');
					if (intHeadingIndex) {
						intHeadingIndex = intHeadingIndex.toInt();
						
						var objAccordion = eleAccParent.retrieve('accordion');
						dbug.log('objAccordion',objAccordion, eleAccHeadingAnchor, eleAccParent, intHeadingIndex  );
						if (objAccordion) {
							objAccordion.display( intHeadingIndex );
							//dbug.log('eleAccParent',eleAccParent, 'strHash',strHash );
						}
						return intHeadingIndex;
					}
				}
			}
		}
	}
	return false;
}

function ReformatForSmallScreen() {
	var objWindowSize = window.getSize();
	var arrAsides = $$('.Aside');
	arrAsides.each(function(eleAside) {
		if (objWindowSize.x < 600) {
			eleAside.addClass('Full');
		}
		else {
			eleAside.removeClass('Full');
		}
	});
}

function GetNonContentSize(elem) {
	elem = $(elem);
	var objSize = new Object();
	objSize.x = elem.getStyle('padding-left').toInt() + elem.getStyle('padding-right').toInt() + elem.getStyle('margin-left').toInt() + elem.getStyle('margin-right').toInt() + elem.getStyle('border-left-width').toInt() + elem.getStyle('border-right-width').toInt();
	objSize.y = elem.getStyle('padding-top').toInt() + elem.getStyle('padding-bottom').toInt() + elem.getStyle('margin-top').toInt() + elem.getStyle('margin-bottom').toInt() + elem.getStyle('border-top-width').toInt() + elem.getStyle('border-bottom-width').toInt();
	return objSize;
}

/****************************
/
/ Photo Fade object. Cycles a set of LIs inside a UL.
/
/***************************/
function PhotoFade() {
	this.intCurrentIndex = 0;
	this.intNextIndex = 0;
	this.intLastIndex = 0;
	this.eleULBlock = null;
	this.arrLIs = null;
	this.intTimeTransition = 2000;
	this.intTimeHold = 4000;
	this.currentCookie = new Hash.Cookie('libPhotoFade', {duration: 7});
	this.objFxUl = null;
	
	this.Cycle = function() {
		//console.log('Rotating Ad', this);
		if (this.arrLIs) {
			var strBlockId = this.eleULBlock.get('id');
			if (this.intCurrentIndex > this.intLastIndex) {
				this.intCurrentIndex = 0;
			}
			
			this.intNextIndex = this.intCurrentIndex + 1;
			
			if (this.intNextIndex > this.intLastIndex) {
				this.intNextIndex = 0;
			}
			//console.log('Current Index:', this.intCurrentIndex, 'Next Index:', this.intNextIndex);
			var eleCurrentAd = $(this.arrLIs[this.intCurrentIndex]);
			var eleNextAd = $(this.arrLIs[this.intNextIndex]);
			eleCurrentAd.setStyle('z-index', '0');
			eleNextAd.setStyle('z-index', '1');
			eleNextAd.setStyle('width', this.eleULBlock.getSize().x - GetNonContentSize(eleNextAd).x );
			eleNextAd.set('tween', {duration: this.intTimeTransition});
			eleNextAd.fade('in');
			//var myFx = new Fx.Tween(element);
			this.objFxUl.start(eleNextAd.getSize().y);
			eleCurrentAd.fade.delay(this.intTimeTransition, eleCurrentAd, 'out');
			//console.log(this.intCurrentIndex, this.arrLIs[this.intCurrentIndex]);
			this.intCurrentIndex++;
			this.currentCookie.set(strBlockId,this.intCurrentIndex);
			//console.log('Rotating Ad Complete', this.intCurrentIndex);
		}
	}
	
	this.Apply = function(eleULBlock) {
		//if (eleULBlock) {
			this.eleULBlock = $(eleULBlock);
			if (this.eleULBlock && !this.eleULBlock.hasClass('AppliedPhotoFade')) {
				//console.log(this.eleULBlock, this.intCurrentIndex);
				this.eleULBlock.addClass('AppliedPhotoFade');
				this.arrLIs = eleULBlock.getElements('li');
				this.intLastIndex = this.arrLIs.length - 1;
				
				var strBlockId = this.eleULBlock.get('id');
				var intCookieVal = this.currentCookie.get(strBlockId);
				//console.log(this);
				if(intCookieVal){
					this.intCurrentIndex = intCookieVal;
				}
				if (this.intCurrentIndex > this.intLastIndex) {
					this.intCurrentIndex = 0;
				}
				//var intCurrentIndex = this.intCurrentIndex;
				
				this.objFxUl = new Fx.Tween(this.eleULBlock, {duration: this.intTimeTransition, property: 'height'});
				//console.log(this);
				//var intFirstLISize = null;
				this.arrLIs.each( function(eleLI, intLIIndex) {
					//var objFirstLISize = eleLI.getSize();
					//console.log('LI Loop:', intLIIndex ,' ',this.intCurrentIndex, (intLIIndex == this.intCurrentIndex), this.eleULBlock.getSize().x, GetNonContentSize(eleLI).x );
					//if (intLIIndex == 0) {
					//}
					if (intLIIndex == this.intCurrentIndex) {
						eleLI.fade('show');
						//eleLI.setStyle('width', this.eleULBlock.getSize().x - GetNonContentSize(eleLI).x );
					}
					else {
						eleLI.fade('hide');
						//eleLI.setStyle('height', intFirstLISize.y);
						//eleLI.setStyle('overflow', 'hidden');
					}
					eleLI.setStyle('position', 'absolute');
					eleLI.setStyle('z-index', '0');
				}.bind(this));
				
				this.Cycle.periodical(this.intTimeHold, this);
			}
		//}
	}
	this.UpdateLiWidth = function() {
		var intFirstLiHeight = 0;
		var eleLI = this.arrLIs[this.intCurrentIndex];
		//this.arrLIs.each( function(eleLI, intLIIndex) {
			//var objFirstLISize = eleLI.getSize();
			//console.log('LI Loop:', intLIIndex ,' ',this.intCurrentIndex, (intLIIndex == this.intCurrentIndex), this.eleULBlock.getSize().x, GetNonContentSize(eleLI).x );
			//if (intLIIndex == 0) {
			//}
			//if (intLIIndex == this.intCurrentIndex) {
				var objFirstLISize = eleLI.getSize();
				intFirstLiHeight = objFirstLISize.y
				eleLI.setStyle('width', this.eleULBlock.getSize().x - GetNonContentSize(eleLI).x );
			//}
		//}.bind(this));
		this.eleULBlock.setStyle('height', intFirstLiHeight);
		//window.alert('LI Extras Width:'+GetNonContentSize(eleLI).x);
	}
	
	window.addEvent('load', this.UpdateLiWidth.bind(this) );
	window.addEvent('resize', this.UpdateLiWidth.bind(this) );
}

var CellFade = new Class({
	Implements: [Options, Events, Fx],
	Binds: ['cycle','setCellWidth'],

	options: {
		transitiontime: 2000,
		holdtime: 4000
	},
	eleULBlock: null,
	arrLIs: null,
	objFxUl: null,
	currentCookie: null,
	
	intCurrentIndex: 0,
	intNextIndex: 0,
	intLastIndex: 0,

	initialize: function(eleUl, _options) {
		var objPF = this;
		if (!$(eleUl)) return;
		objPF.eleULBlock = $(eleUl);
		if (objPF.eleULBlock.hasClass('AppliedPhotoFade')) return;
		objPF.setOptions(_options);
		
		objPF.currentCookie = new Hash.Cookie('libPhotoFade', {duration: 7});
		
		//if (this.eleULBlock && !this.eleULBlock.hasClass('AppliedPhotoFade')) {
		//console.log(this.eleULBlock, this.intCurrentIndex);
		objPF.eleULBlock.addClass('AppliedPhotoFade');
		objPF.arrLIs = objPF.eleULBlock.getElements('li');
		if (objPF.arrLIs.length <= 1) return;
		objPF.intLastIndex = objPF.arrLIs.length - 1;
		
		var strBlockId = objPF.eleULBlock.get('id');
		var intCookieVal = objPF.currentCookie.get(strBlockId);
		//console.log(this);
		if(intCookieVal){
			objPF.intCurrentIndex = intCookieVal.toInt();
		}
		if (objPF.intCurrentIndex > objPF.intLastIndex) {
			objPF.intCurrentIndex = 0;
		}
		//var intCurrentIndex = this.intCurrentIndex;
		
		objPF.objFxUl = new Fx.Tween(objPF.eleULBlock, {duration: objPF.options.transitiontime, property: 'height'});
		//console.log(this);
		//var intFirstLISize = null;
		objPF.arrLIs.each( function(eleLI, intLIIndex) {
			//var objFirstLISize = eleLI.getSize();
			//console.log('LI Loop:', intLIIndex ,' ',this.intCurrentIndex, (intLIIndex == this.intCurrentIndex), this.eleULBlock.getSize().x, GetNonContentSize(eleLI).x );
			//if (intLIIndex == 0) {
			//}
			if (intLIIndex == objPF.intCurrentIndex) {
				eleLI.fade('show');
				//eleLI.setStyle('width', this.eleULBlock.getSize().x - GetNonContentSize(eleLI).x );
			}
			else {
				eleLI.fade('hide');
				//eleLI.setStyle('height', intFirstLISize.y);
				//eleLI.setStyle('overflow', 'hidden');
			}
			eleLI.setStyle('position', 'absolute');
			eleLI.setStyle('z-index', '0');
		});
		
		objPF.cycle.periodical(objPF.options.holdtime);
			
		objPF.add_events();
	},
	add_events: function() {
		var objPF = this;
		window.addEvent('load', objPF.setCellWidth );
		window.addEvent('resize', objPF.setCellWidth );
	},
	//destroy: function(_revert) {
	//	this.remove_events();
	//},
	cycle: function() {
		var objPF = this;
		//console.log('Rotating Ad', this);
		//if (objPF.arrLIs && objPF.arrLIs.length > 1) {
			var strBlockId = this.eleULBlock.get('id');
			if (objPF.intCurrentIndex > objPF.intLastIndex) {
				objPF.intCurrentIndex = 0;
			}
			
			objPF.intNextIndex = objPF.intCurrentIndex + 1;
			
			if (objPF.intNextIndex > objPF.intLastIndex) {
				objPF.intNextIndex = 0;
			}
			//console.log('Current Index:', this.intCurrentIndex, 'Next Index:', this.intNextIndex);
			var eleCurrentAd = $(objPF.arrLIs[objPF.intCurrentIndex]);
			var eleNextAd = $(objPF.arrLIs[objPF.intNextIndex]);
			eleCurrentAd.setStyle('z-index', '0');
			eleNextAd.setStyle('z-index', '1');
			eleNextAd.setStyle('width', objPF.eleULBlock.getSize().x - GetNonContentSize(eleNextAd).x );
			eleNextAd.set('tween', {duration: objPF.options.transitiontime});
			eleNextAd.fade('in');
			//var myFx = new Fx.Tween(element);
			objPF.objFxUl.start(eleNextAd.getSize().y);
			eleCurrentAd.fade.delay(objPF.options.transitiontime, eleCurrentAd, 'out');
			//console.log(this.intCurrentIndex, this.arrLIs[this.intCurrentIndex]);
			objPF.intCurrentIndex++;
			objPF.currentCookie.set(strBlockId,objPF.intCurrentIndex);
			//console.log('Rotating Ad Complete', this.intCurrentIndex);
		//}
	},
	setCellWidth: function() {
		var objPF = this;
		var intFirstLiHeight = 0;
		var eleLI = objPF.arrLIs[objPF.intCurrentIndex];
		//this.arrLIs.each( function(eleLI, intLIIndex) {
			//var objFirstLISize = eleLI.getSize();
			//console.log('LI Loop:', intLIIndex ,' ',this.intCurrentIndex, (intLIIndex == this.intCurrentIndex), this.eleULBlock.getSize().x, GetNonContentSize(eleLI).x );
			//if (intLIIndex == 0) {
			//}
			//if (intLIIndex == this.intCurrentIndex) {
				var objFirstLISize = eleLI.getSize();
				intFirstLiHeight = objFirstLISize.y
				eleLI.setStyle('width', objPF.eleULBlock.getSize().x - GetNonContentSize(eleLI).x );
			//}
		//}.bind(this));
		objPF.eleULBlock.setStyle('height', intFirstLiHeight);
		//window.alert('LI Extras Width:'+GetNonContentSize(eleLI).x);
	}
});

/***********************************************/
/*** Initializers ******************************/
/***********************************************/

function InitializeAside(item) {
	if (item.hasClass('GuideSections')) {
		item.removeClass('GuideSections');
		item.addClass('Aside');
	}
	//if (Browser.Engine.webkit || Browser.Engine.gecko) {
		// Do whatever. i don't care. you browsers already know what to do.
	//}
	//else {
	//if (item) {
	//	$(item.parentNode).addClass('AsideContainer');
	//}
	return item;
}

function InitializeSearchFields() {
	function FocusField(obj) {
		obj = $(obj);
		if ( obj.value == obj.get('placeholder') ) {
			obj.value = '';
			obj.removeClass('Blank');
		}
	}
	function BlurField(obj) {
		obj = $(obj);
		if ( obj.value == '' ) {
			obj.value = obj.get('placeholder');
			obj.addClass('Blank');
		}
	}
	
	var SearchFields = $$('input[placeholder]');
	SearchFields.each( function(item, index, array) {
		FocusField(item);
		BlurField(item);
		
		item.addEvent('focus', function() {
			FocusField(item);
		});
		item.addEvent('blur', function() {
			BlurField(item);
		});
		
		var parentFormObj = item.getParent('form');
		if (parentFormObj) {
			parentFormObj.addEvent('submit', function() {
				FocusField(item);
			});
		}
	});
}

var initializeattentiongettersdone = false;
function InitializeAttentionGetters() {
	
	function Blink() {
		$(this).highlight('#fff');
	}
	function Pulse() {
		element = $(this);
		var origbgcolor = element.getStyle('background-color');
		//window.alert(origbgcolor);
		if (origbgcolor == 'transparent') {
			origbgcolor = '#ddd';
		}
		var myFx = new Fx.Tween(element, {property: 'background-color', duration: 1000});
		//element.set('tween', {property: 'background-color', duration: 1000})
		myFx.start('#fff').chain(
			function(){ this.start(origbgcolor); }
		);
	}
	
	if (initializeattentiongettersdone == false) {
		var BlinkSlows = $$('.BlinkSlow');
		BlinkSlows.each( function(item) {
			Blink.periodical(2000, item);
		});
		
		var Blinks = $$('.Blink');
		Blinks.each( function(item) {
			Blink.periodical(750, item);
		});
		
		var Pulses = $$('.Pulse');
		Pulses.each( function(item) {
			//item.Pulse();
			Pulse.periodical(2000, item);
		});
		
		initializeattentiongettersdone = true;
	}
}

/* Remove duplicate references to CSS files so that only one reference exists per document. */
function InitializeCSSLinkTagLocations() {
	
	function ExtractPathFromURL(url) {
		url = url.replace(/\?.*$/, '');
		url = url.replace(/^[hf]tt?ps?\:\/\/.*?\//, '');
		url = url.replace(/\.\./g, '');
		url = url.replace(/\/+/g, '/');
		return url;
	}
	
	var LinkURLs = new Array();
	var AllLinks = $(document).getElements('link').reverse();
	AllLinks.each( function(item, index) {
		item.id = 'CSSLink' + index;
		//window.alert(item.href)
		var itemhref = ExtractPathFromURL(item.href);
		//itemhref = itemhref.replace(/^[hf]tt?ps?\:\/\/.*?\//, '');
		//itemhref = itemhref.replace(/\.\./g, '');
		//itemhref = itemhref.replace(/\/+/g, '/');
		var hrefexists = LinkURLs.some( function(href, hindex) {
			return href == itemhref;
		});
		/* Kill off the duplicates, and if it's not a duplicate add it to the pile */
		if (hrefexists) {
			item.dispose();
		}
		else {
			LinkURLs.push(itemhref);
		}
		//window.alert(itemhref);
		//console.log(item);
	});
	/* Get the HEAD tag of the document */
	var HeadObj = document.head;
	/* If one doesn't exist, create one and set our obj to the new obj */
	if (!HeadObj) {
		var newHeadObj = new Element('head');
		document.appendChild(newHeadObj);
		HeadObj = document.head;
	}
	/* Go through all the links in the body and move them to the new head section */
	var BodyLinks = $(document.body).getElements('link');
	BodyLinks.each( function(item) {
		$(document.head).grab(item);
	});
	/* Now, put all the stule tags underneath the link tags in head section so they can take precidence */
	var StyleTags = $(document).getElements('style');
	StyleTags.each( function(item) {
		$(document.head).grab(item);
	});
	//var AllLinks = $(document).getElements('link');
	//AllLinks.each( function(item, index) {
	//	window.alert(item.href);
	//});
}

function InitializeAccordions() {
	var arrAccordions = $$('.Accordion');
	//var intHeadingIndex = FindAccordionSectionIndex();
	arrAccordions.each( function(eleItem) {
		var arrHeaders = eleItem.getElements(accordionHeadingSelector);
		arrHeaders.each( function(eleHeader, hindex) {
			eleHeader.set('index', hindex);
			var eleChevron = new Element('span', {'class': 'Chevron', 'title': 'Click to expand or collapse'});
			eleHeader.grab(eleChevron, 'top');
		});
		var objAccordion = new Accordion(arrHeaders, eleItem.getChildren(accordionBodySelector), {
			onActive: function(eleToggler, block) {
				eleToggler.addClass('Active');
				//this.ActiveBlock = block;
			},
			onBackground: function(eleToggler, block) {
				eleToggler.removeClass('Active');
			}
			//onLoad: function() {
			//	var hash = window.location.hash;
			//	ActivateAccordionHeading(hash);
			//}
		});
		eleItem.store('accordion', objAccordion);
		//var intHeadingIndex = FindAccordionSectionIndex();
		//myAccordion.display(intHeadingIndex);
		ActivateAccordionHeading.delay(500);
	});
	
	var arrAnchorRefs = $$('a[href*=#]');
	arrAnchorRefs.each( function(eleA) {
		var objHash = eleA.hash;
		eleA.addEvent('click', function() {
			ActivateAccordionHeading(objHash);
		});
	});
}

function InitializeAlternatingRows() {
	//var AllElements = document.getElementsByTagName("*");
	//if (AllElements) {
	//	var AlternatingRowObjects = new Array();
	//	for (var i = 0; i < AllElements.length; i++) {
	//		if ( AllElements[i] && AllElements[i].className && AllElements[i].className.search(/AlternateRows/i) >= 0 ) {
	var AlternateRows = $$('.AlternateRows');
	AlternateRows.each( function(row, rindex) {
	
		//AlternatingRowObjects.push(AllElements[i]);
		//window.status+= ' ' + AllElements[i].className + ' at '+i+'! ';
		var RowNodes = row.childNodes;
		var RowNodesInsideTBODY = RowNodes;
		for(var j = 0; j < RowNodesInsideTBODY.length; j++) {
			if (RowNodesInsideTBODY[j].nodeName.toLowerCase() == 'tbody') {
				// We are inside a table with a tbody tag. so get *it's* children and then continue;
				RowNodes = RowNodesInsideTBODY[j].childNodes;
				// Exit the loop by forging completion
				j = RowNodesInsideTBODY.length;
			}
		}
		var rowindex = 0;
		for(var j = 0; j < RowNodes.length; j++) {
			if (RowNodes[j].nodeType == 1 && !$(RowNodes[j]).hasClass('Empty') && !$(RowNodes[j]).hasClass('Ignore') ) {
				if ( !$(RowNodes[j]).hasClass('Skip') ) {
					$(RowNodes[j]).addClass( (rowindex % 2) ? 'RowOdd' : 'RowEven');
				}
				rowindex++;
			}
		}
	});
	//		}
	//	}
		/*if (AlternatingRowObjects.length > 0) {
			for (var i = 0; i < AlternatingRowObjects()
				var RowNodes = AllElements[i].childNodes;
				for(var j = 1; i < RowNodes.length; i++) {
					RowNodes[i].className = (i % 2) ? 'RowOdd' : 'RowEven';
				}*/
	//}
}

function InitializeHeadings() {
	/// 2 possible approaches here:
	/// Select exactly only what we need... Lots of selectors and garbage that takes time to look through
	/// OR
	/// Select everything and weed out the ones we don't want.
	//var Headings = $$('#LibArticle>h3, #LibArticle>h4, #LibArticle>h5, #LibArticle>section>h3, #LibArticle>section>h4, #LibArticle>section>h5, #LibArticle>div.ThinBlock>h3, #LibArticle>div.ThinBlock>h4, #LibArticle>div.ThinBlock>h5');
	var Headings = $$('#LibArticle h3, #LibArticle h4, #LibArticle h5');
	Headings.each( function(item) {
		//var parentnode = item.getParent();
		if (item.getParent('#IndexFrame') || item.getParent('.Aside') || item.getParent('.Accordion') || item.getParent('.HeadingContainer')) {
			return false;
		}
		var heading = new Element('div', {'class': 'HeadingContainer'});
		heading.wraps(item);
	});
}

function InitializeHRs() {
	/// 2 possible approaches here:
	/// Select exactly only what we need... Lots of selectors and garbage that takes time to look through
	/// OR
	/// Select everything and weed out the ones we don't want.
	//var Headings = $$('#LibArticle>h3, #LibArticle>h4, #LibArticle>h5, #LibArticle>section>h3, #LibArticle>section>h4, #LibArticle>section>h5, #LibArticle>div.ThinBlock>h3, #LibArticle>div.ThinBlock>h4, #LibArticle>div.ThinBlock>h5');
	var Headings = $$('hr');
	Headings.each( function(item) {
		//var parentnode = item.getParent();
		var heading = new Element('div', {'class': 'hr'});
		heading.wraps(item);
	});
}

function InitializePhotoFade() {
	var arrMiniAds = $$('ul.MiniAds.Fade');
	arrMiniAds.each( function(eleUl) {
		//var objMiniAd = new PhotoFade();
		//objMiniAd.intTimeTransition = 1000;
		//objMiniAd.intTimeHold = 6000;
		//objMiniAd.Apply(eleULBlock);
		var objMiniAd = new CellFade(eleUl, {transitiontime: eleUl.get('data-transtime') || 1000, holdtime: eleUl.get('data-holdtime') || 6000});
		//objMiniAd.intTimeTransition = 1000;
		//objMiniAd.intTimeHold = 6000;
		//objMiniAd.Apply(eleULBlock);
	});
	
	var arrPhotoFades = $$('ul.PhotoFade');
	arrPhotoFades.each( function(eleUl) {
		var objPhotoFade = new CellFade(eleUl, {transitiontime: eleUl.get('data-transtime') || 1500, holdtime:  eleUl.get('data-holdtime') || 5000});
		//var objPhotoFade = new PhotoFade();
		//objPhotoFade.intTimeTransition = 1500;
		//objPhotoFade.intTimeHold = 5000;
		//objPhotoFade.Apply(eleUl);
	});
}

function InitializeVerticalBanners() {
	var arrVerticals = $$('.Vertical');
	arrVerticals.each(function(eleVertical) {
		eleVertical.setStyle('text-align', 'center');
		var strContent = eleVertical.get('text');
		eleVertical.set('text', '');
		var arrLetters = strContent.split('');
		arrLetters.each(function(strLetter) {
			var eleLetter = new Element('div', {'html': (strLetter == ' ' ? '&nbsp;' : strLetter) });
			eleLetter.inject(eleVertical);
		});
	});
}

function InitializeDrawers() {
	var arrDrawers = $$('.Drawer');
	arrDrawers.each(function(eleDrawer) {
		var strDirection = 'down';
		if (eleDrawer.hasClass('Up')) { strDirection = 'up'; }
		if (eleDrawer.hasClass('Right')) { strDirection = 'right'; }
		if (eleDrawer.hasClass('Left')) { strDirection = 'left'; }
		
		var objDrawer = new Drawer(eleDrawer, {'direction': strDirection});
	});
	//console.debug('-------------- Done Initializing ---------------------------------------');
}

function InitializeCheckboxTree() {
	var arrForms = $$('form');
	arrForms.each(function(eleForm) {
		var objCeckboxTree = new CheckboxTree(eleForm);
	});
}

function InitializeFormGen() {
	$$('form[action*=formgen.pl], form.Develop').each(function(eleForm) {
		var objFormGen = new FormGen(eleForm);
	});
}

function InitializeWarnings() {
	var arrWarnings = $$('.Warning');
	arrWarnings.each( function(eleItem) {
		var eleNewDiv1 = new Element('div', {'class': 'WarningOuter'});
		var eleNewDiv2 = new Element('div', {'class': 'DontWrapSideBar'});
		eleNewDiv1.wraps(eleItem);
		eleNewDiv2.wraps(eleNewDiv1);
	});
}

function InitializeDebug() {
	var eleDebugDiv = new Element('div', {'id': 'LibDebug', 'style': 'display: ' + (bitDebugEnabled == true ? 'block' : 'none') + ';' });
	var eleDebugHeading = new Element('h3', {'text': 'Debugging Code'});
	eleDebugDiv.grab(eleDebugHeading);
	eleDebugDiv.inject($('LibPage') || $(document.body));
}

function Debug(strDebug) {
	var eleDebugDiv = $('LibDebug');
	if (eleDebugDiv) {
		var elePre = new Element('pre', {'text': strDebug});
		eleDebugDiv.grab(elePre);
	}
}

/***********************************************/
/*** Events ************************************/
/***********************************************/

window.addEvent('domready', function(event) {
	InitializeDebug();
	/// Do this function if we are in IE and the shift key is down.
	//window.alert(event);
	//if ( Browser.Engine.trident && window.event.shift ) {
	//	InitializeCSSLinkTagLocations();
	//}
	//else if ( !Browser.Engine.trident ) { //if (window.event == null || window.event.shift == null) {
		/// If we aren't in IE, just run it anyway, because this is correct.
		//console.log('Looks like this isn\'t IE.');
		InitializeCSSLinkTagLocations();
	//}
	//console.log('Looks like this isn\'t IE.');
	//console.log(window.event);
	//window.alert('test');
	//var Shadows = $$('.Aside, aside, .GuideSections, .HasShadow');
	var Shadows = $$('.HasShadow');
	Shadows.each( AddShadow );
	
	//var Asides = $$('.Aside, aside, .GuideSections');
	//Asides.each( InitializeAside );
	ReformatForSmallScreen();
	InitializeSearchFields();
	//InitializeHeadings();
	InitializeHRs();
	
	InitializeAccordions();
	//var hash = window.location.hash;
	//ActivateAccordionHeading(hash);
	
	InitializeAlternatingRows();
	InitializeAttentionGetters();
	//InitializeSideBarOptions();
	
	InitializePhotoFade();
	InitializeVerticalBanners();
	InitializeDrawers();
	InitializeWarnings();
	
	InitializeFormGen();
	
	InitializeCheckboxTree();
	
	//HoursSelector();
	if (document.compatMode == 'CSS1Compat') {
		window.status = "Site loaded in Standards mode.";
	}
	else {
		window.status = "Site loaded in Quirks mode. Please add <!DOCTYPE html> to the top of the document.";
	}
	
	//var testurl = document.domain;
	//window.alert(testurl + ' = "' + isInternalDomain(testurl) + '"' );
	//isInternalDomain(testurl);
	var AllLinks = $$('a[href]');
	AllLinks.each( function(link) {
		if (link.target == '') {
			//console.log(link);
			//var isinternal = ;
			if ( !isInternalDomain(link.host) ) {
				link.set('target', '_blank');
				//link.setStyle('background-color', 'Highlight');
				//console.log(link);
			}
			//console.log(link, isinternal);
		}
	});
});
/// Style Dependent Code
window.addEvent('load', function(event) {
	
});
window.addEvent('resize', ReformatForSmallScreen);

//window.addEvent('load', function() {
//	window.removeEvents('unload');
//	document.removeEvents('unload');
//	$(document.body).removeEvents('unload');
//});

if (typeof(hljs) !== 'undefined') {
	hljs.tabReplace = '   ';
	hljs.initHighlightingOnLoad();
	//window.alert('Syntax colorizing the page...');
}
//window.alert(typeof(hljs) + ' ' + (typeof(hljs) !== 'undefined'));

/// Enable automatic syntax highlighting if it's been included in the scripts.


/*** OLD SECTION - UNDER REVIEW ****************/

/****************************
/
/ Hide the first vertical line in a navigation list
/
/***************************/
function StyleNavigation() {
	var allULs = document.getElementsByTagName("ul");
	for (var i=0; i<allULs.length; i++) {
		if (allULs[i].className == "Navigation") {
			var allLIs = allULs[i].getElementsByTagName("li");
			if (allLIs[0]) {
				allLIs[0].style.borderLeftWidth = "0";
			}
		}
	}
	//setClassStyle("Navigation","color","red","LI");
	//setClassStyle("Navigation","borderLeftWidth","0","li");
}

function StyleNavigationSectionHeadings() {
	//var Boxes = $$('.BasicBox');
	var Boxes = $$('.GuideSections');
	Boxes = Boxes.concat( $$('.BasicBox') );
	for (var i = 0; i < Boxes.length; i++) {
		var Headings = Boxes[i].getElementsByTagName('h4');
		for (var j = 0; j < Headings.length; j++) {
			var heading = $(Headings[j]);
			if (j == 0 && heading.addClass) {
				heading.addClass('first');
				//window.status = 'fount one';
			}
		}
	}
}

function SetupAlternatingTableRows() {
	var AllElements = document.getElementsByTagName("*");
	if (AllElements) {
		var AlternatingRowObjects = new Array();
		for (var i = 0; i < AllElements.length; i++) {
			if ( AllElements[i] && AllElements[i].className && AllElements[i].className.search(/AlternateRows/i) >= 0 ) {
				AlternatingRowObjects.push(AllElements[i]);
				//window.status+= ' ' + AllElements[i].className + ' at '+i+'! ';
				var RowNodes = AllElements[i].childNodes;
				var RowNodesInsideTBODY = RowNodes;
				for(var j = 0; j < RowNodesInsideTBODY.length; j++) {
					if (RowNodesInsideTBODY[j].nodeName.toLowerCase() == 'tbody') {
						// We are inside a table with a tbody tag. so get *it's* children and then continue;
						RowNodes = RowNodesInsideTBODY[j].childNodes;
						// Exit the loop by forging completion
						j = RowNodesInsideTBODY.length;
					}
				}
				var rowindex = 0;
				for(var j = 0; j < RowNodes.length; j++) {
					if (RowNodes[j].nodeType == 1) {
						RowNodes[j].className = (rowindex % 2) ? 'RowOdd' : 'RowEven';
						rowindex++;
					}
				}
			}
		}
		/*if (AlternatingRowObjects.length > 0) {
			for (var i = 0; i < AlternatingRowObjects()
				var RowNodes = AllElements[i].childNodes;
				for(var j = 1; i < RowNodes.length; i++) {
					RowNodes[i].className = (i % 2) ? 'RowOdd' : 'RowEven';
				}*/
	}
}


/**
*
*  Javascript sprintf
*  http://www.webtoolkit.info/
*
*
**/

sprintfWrapper = {

    init : function () {

        if (typeof arguments == 'undefined') { return null; }
        if (arguments.length < 1) { return null; }
        if (typeof arguments[0] != 'string') { return null; }
        if (typeof RegExp == 'undefined') { return null; }

        var string = arguments[0];
        var exp = new RegExp(/(%([%]|(\-)?(\+|\x20)?(0)?(\d+)?(\.(\d)?)?([bcdfosxX])))/g);
        var matches = new Array();
        var strings = new Array();
        var convCount = 0;
        var stringPosStart = 0;
        var stringPosEnd = 0;
        var matchPosEnd = 0;
        var newString = '';
        var match = null;

        while (match = exp.exec(string)) {
            if (match[9]) { convCount += 1; }

            stringPosStart = matchPosEnd;
            stringPosEnd = exp.lastIndex - match[0].length;
            strings[strings.length] = string.substring(stringPosStart, stringPosEnd);

            matchPosEnd = exp.lastIndex;
            matches[matches.length] = {
                match: match[0],
                left: match[3] ? true : false,
                sign: match[4] || '',
                pad: match[5] || ' ',
                min: match[6] || 0,
                precision: match[8],
                code: match[9] || '%',
                negative: (parseInt(arguments[convCount]) < 0) ? true : false,
                argument: String(arguments[convCount])
            };
        }
        strings[strings.length] = string.substring(matchPosEnd);

        if (matches.length == 0) { return string; }
        if ((arguments.length - 1) < convCount) { return null; }

        var code = null;
        var match = null;
        var i = null;

        for (i=0; i<matches.length; i++) {

            if (matches[i].code == '%') { substitution = '%' }
            else if (matches[i].code == 'b') {
                matches[i].argument = String(Math.abs(parseInt(matches[i].argument)).toString(2));
                substitution = sprintfWrapper.convert(matches[i], true);
            }
            else if (matches[i].code == 'c') {
                matches[i].argument = String(String.fromCharCode(parseInt(Math.abs(parseInt(matches[i].argument)))));
                substitution = sprintfWrapper.convert(matches[i], true);
            }
            else if (matches[i].code == 'd') {
                matches[i].argument = String(Math.abs(parseInt(matches[i].argument)));
                substitution = sprintfWrapper.convert(matches[i]);
            }
            else if (matches[i].code == 'f') {
                matches[i].argument = String(Math.abs(parseFloat(matches[i].argument)).toFixed(matches[i].precision ? matches[i].precision : 6));
                substitution = sprintfWrapper.convert(matches[i]);
            }
            else if (matches[i].code == 'o') {
                matches[i].argument = String(Math.abs(parseInt(matches[i].argument)).toString(8));
                substitution = sprintfWrapper.convert(matches[i]);
            }
            else if (matches[i].code == 's') {
                matches[i].argument = matches[i].argument.substring(0, matches[i].precision ? matches[i].precision : matches[i].argument.length)
                substitution = sprintfWrapper.convert(matches[i], true);
            }
            else if (matches[i].code == 'x') {
                matches[i].argument = String(Math.abs(parseInt(matches[i].argument)).toString(16));
                substitution = sprintfWrapper.convert(matches[i]);
            }
            else if (matches[i].code == 'X') {
                matches[i].argument = String(Math.abs(parseInt(matches[i].argument)).toString(16));
                substitution = sprintfWrapper.convert(matches[i]).toUpperCase();
            }
            else {
                substitution = matches[i].match;
            }

            newString += strings[i];
            newString += substitution;

        }
        newString += strings[i];

        return newString;

    },

    convert : function(match, nosign){
        if (nosign) {
            match.sign = '';
        } else {
            match.sign = match.negative ? '-' : match.sign;
        }
        var l = match.min - match.argument.length + 1 - match.sign.length;
        var pad = new Array(l < 0 ? 0 : l).join(match.pad);
        if (!match.left) {
            if (match.pad == '0' || nosign) {
                return match.sign + pad + match.argument;
            } else {
                return pad + match.sign + match.argument;
            }
        } else {
            if (match.pad == '0' || nosign) {
                return match.sign + match.argument + pad.replace(/0/g, ' ');
            } else {
                return match.sign + match.argument + pad;
            }
        }
    }
}

sprintf = sprintfWrapper.init;
