 // CLASSES ////////////////////////////////////////////////////////////////////
var DropDown = new Class({
	Implements: [Options, Events],

	options: {
		dropdownTitle: 'Dropdown Menu',
		
		onSlideEnd: $empty()
	},
	
	elem: null,
	// eleTitleFrame: null,
	eleTitle: null,
	eleTitleText: null,
	eleOptionsFrame: null,
	
	bitKeepOpen: false,
	bitOpen: false,
	bitHovering: false,
	timHoverOut: null,
	
	boundShow: $empty(),
	boundShowKeepOpen: $empty(),
	boundHide: $empty(),
	boundHideKeepOpen: $empty(),

	initialize: function(elem, _options) {
		this.boundShowHover = this.showHover.bind(this);
		this.boundHideHover = this.hideHover.bind(this);
		this.boundShowClick = this.showClick.bind(this);
		this.boundHideBlur = this.hideBlur.bind(this);
		
		if (!$(elem)) return;
		var eleOriginalSelect = $(elem);
		this.setOptions(_options);
		
		this.eleSubmitButton = $('LibHeaderQuickLinksSubmit');
		if (this.eleSubmitButton) {
			this.eleSubmitButton.setStyle('display','none');
		}
		
		this.createSelect(eleOriginalSelect);
		this.add_events();
	},
	destroy: function(_revert) {
		this.remove_events();
	},
	createSelect: function(eleOriginalSelect) {
		eleOriginalSelect = $(eleOriginalSelect);
		var objOrigProperties = eleOriginalSelect.getProperties('id', 'class', 'title');
		this.elem = new Element('div', objOrigProperties);
		// this.eleTitleFrame = new Element('div', {'class': 'DropDownTitleFrame'});
		this.eleTitle = new Element('a', {'class': 'DropDownTitle', 'href': '#'});
		this.eleTitleText = new Element('span', {'class': 'DropDownTitleText', 'text': this.options.dropdownTitle});
		this.eleOptionsFrame = new Element('div', {'class': 'DropDownOptionsFrame'});
		
		eleOriginalSelect.set('name', eleOriginalSelect.get('name') + 'Orig');
		eleOriginalSelect.set('id', eleOriginalSelect.get('id') + 'Orig');
		eleOriginalSelect.setStyle('display', 'none');
		this.elem.inject(eleOriginalSelect, 'after');
		
		this.eleTitle.grab(this.eleTitleText);
		this.elem.grab(this.eleTitle);
		this.elem.grab(this.eleOptionsFrame);
		
		eleOriginalSelect.getElements('option').each( function(eleOption, index) {
			this.addOptionFromDom(eleOption);
		}, this);
	},
	addOptionFromDom: function(eleOption) {
		eleOption = $(eleOption);
		var objOrigProperties = eleOption.getProperties('id', 'class', 'title', 'value', 'text');
		// objOrigProperties.value = eleOption.get('value');
		this.addOption(objOrigProperties);
	},
	addOption: function(objProperties, position) {
		// eleOption = $(eleOption);
		// var objOrigProperties = eleOption.getProperties('id', 'class', 'title');
		if (!objProperties.href) {
			objProperties.href = objProperties.value;
			objProperties.value = null;
		}
		// var strHref = objProperties.href || objProperties.value;
		var strText = objProperties.text;
		// objProperties.href || objProperties.value = null;
		objProperties.text = null;
		
		var eleOption = new Element('a', objProperties);
		// eleOption.set('href', strHref);
		var eleOptionText = new Element('span', {'text': strText});
		
		eleOptionText.inject(eleOption);
		eleOption.inject(this.eleOptionsFrame, position);
	},
	removeOption: function(index) {
		var arrOptions = this.eleOptionsFrame.getChildren();
		arrOptions[index].destroy();
	},
	show: function(bitKeepOpen) {
		if (this.bitOpen == false) {
			this.eleOptionsFrame.setStyle('display', 'block');
			this.eleTitle.addClass('Active');
			this.eleTitle.focus();
			this.bitOpen = true;
		}
	},
	hide: function(bitKeepOpen) {
		if (this.bitOpen == true) {
			this.eleOptionsFrame.setStyle('display', 'none');
			this.eleTitle.removeClass('Active');
			this.bitOpen = false;
			this.bitKeepOpen = false;
		}
	},
	showHover: function() {
		this.bitHovering = true;
		$clear(this.timHoverOut);
		this.show();
	},
	hideHover: function() {
		this.bitHovering = false;
		if (this.bitKeepOpen == false) {
			this.timHoverOut = this.hide.delay(250, this);
		}
	},
	showClick: function() {
		if (this.bitKeepOpen == true) {
			this.hide();
		}
		else {
			this.show();
			this.bitKeepOpen = true;
		}
		return false;
	},
	hideBlur: function(e) {
		this.bitKeepOpen = false;
		if (this.bitHovering == true) {
			/// Mouse is inside the menu
			return false;
		}
		else {
			this.hide();
		}
	},
	add_events: function() {
		this.elem.addEvents({
			'mouseenter': this.boundShowHover,
			'mouseleave': this.boundHideHover
		});
		this.eleTitle.addEvents({
			'click': this.boundShowClick,
			'blur': this.boundHideBlur
		});
	},
	remove_events: function() {
		this.elem.removeEvents();
		this.eleTitle.removeEvents()
	}
});

var SiteSearch = new Class({
	Implements: [Options, Events, Fx],

	options: {
		suggestionsElement: 'LibHeaderSearchSuggestions',
		maxResults: 5,
		width: 25,
		widthExtended: 35,
		
		onSlideEnd: $empty()
	},
	
	elem: null,
	eleSuggestions: null,
	Fx: null,
	fxWidth: null,
	
	boundSuggestSearch: $empty(),

	initialize: function(elem, _options) {
		this.boundSuggestSearch = this.suggestSearch.bind(this);
		this.boundProcessResults = this.processResults.bind(this);
		
		if (!$(elem)) return;
		this.elem = $(elem);
		this.setOptions(_options);
		this.eleSuggestions = $(this.options.suggestionsElement);
		
		this.Fx = new Fx.Tween(this.eleSuggestions, {'property': 'opacity', 'duration': 100});
		
		this.fxWidth = new Fx.Tween(this.elem, {'link': 'cancel','property': 'width', 'duration': 250, 'unit': 'ex'});
		this.fxWidth.set('width', this.options.width);
		//this.fxWidth = new Fx.Morph(this.elem).set('.Extended');
		
		this.eleSuggestions.setStyles({
			'opacity': 0,
			'visibility': 'visible',
			'display': 'block'
		});
		// this.eleSuggestions.setStyle('display','block');
		this.add_events();
	},
	suggestSearch: function() {
		var strSearch = this.elem.get('value');
		// resultsObj.set('html','');
		//var myFx = new Fx.Tween(resultsObj, {link: 'cancel'});
		//myFx.set('height', '0px');
		//resultsObj.hide();
		
		if (strSearch.length <= 1) {
			this.hide();
			return;
		}
		
		var url = "/Web/SearchSuggest.asp";
		url+= "?q=" + strSearch;
		url+= "&sid=" + Math.random();
		
		//, update: 'SearchSuggestions'
		var myHTMLRequest = new Request.HTML({
			url: url,
			async: true,
			onSuccess: this.boundProcessResults
		});
		myHTMLRequest.get();
	},
	processResults: function(responseText, responseXML) {
		// console.log(responseXML);
		this.eleSuggestions.empty();
		//if (Terms.length > 0) {
		var docFragObj = document.createDocumentFragment();
		//var SearchTerms = responseXML.getElement('term');
		var SearchTerms = responseXML.getElements('term');
		var arrTerms = SearchTerms[0];
		// console.log(arrTerms);
		arrTerms.each( function(eleTerm, index) {
			// console.log(eleTerm);
			if (index < this.options.maxResults) {
				var eleLink = new Element('a', {
					//'text': Terms[i].nodeValue,
					'text': eleTerm.get('text'),
					'href': '#',
					'events': {
						'click': function() {
							//console.log('populationg the field');
							var strNewText = eleTerm.get('text');
							this.elem.set('value', strNewText);
							this.hide();
							this.elem.focus();
							return false;
						}.bind(this)
					}
				});
				docFragObj.appendChild(eleLink);
			}
		}, this);
		this.eleSuggestions.appendChild( docFragObj );
		if (arrTerms.length > 0) {
			this.show();
		}
		else {
			this.hide();
		}
	},
	// searchForThis: function(e) {
		// e = new Event(e);
		// var sender = e.srcElement || e.target;

		// var resultsObj = $('LibHeaderSearchSuggestions');
		// if (resultsObj) {
			// $('LibHeaderSearchField').value = sender.get('text');
			// resultsObj.setStyle('display','none');
		// }
		// return false;
		
	// },
	add_events: function() {
		this.elem.addEvents({
			'keyup': this.boundSuggestSearch,
			'click': this.boundSuggestSearch,
			// 'change': this.boundSuggestSearch
			'focus': function() {
				this.fxWidth.start(this.options.widthExtended);
				//this.fxWidth.set('.Extended');
				//this.fxWidth.start();
				if (this.elem.value) {
					this.show();
				}
			}.bind(this),
			'blur': function() {
				//if (!this.elem.value) {
					this.fxWidth.start(this.options.width);
					//this.fxWidth.set('');
					//this.fxWidth.start();
					this.hide();
				//}
			}.bind(this)
		});
	},
	show: function() {
		// this.eleSuggestions.setStyle('display','block');
		this.eleSuggestions.setStyle('display', 'block');
		this.Fx.start(1);
	},
	hide: function() {
		this.Fx.start(0).chain(function() { this.eleSuggestions.setStyle('display', 'none'); }.bind(this) );
		// this.eleSuggestions.setStyle('display','none');
	}
});

var SideBar = new Class({
	Implements: [Options, Events, Fx],
	Binds: ['buttonOn','buttonOff','windowSizeCheck','keyCheck'],

	options: {
		autoMenuOffWidth: 800,
		optionsTextTitle: 'Side Menu: ',
		optionsTextOn: 'On',
		optionsTextOff: 'Off',
		durationMenu: 500,
		durationOptions: 500,
		transitionMenu: 'quad:in:out',
		transitionOptions: 'cubic:out'
	},
	Fx: null,
	FxOptions: null,
	
	eleSideBar: null,
	eleSideBarOptions: null,
	
	bitActive: true,
	bitStateSetManually: false,
	bitMenuFitsOnScreen: true,
	
	boundShow: $empty(),
	boundHide: $empty(),
	boundWindowSizeCheck: $empty(),
	boundKeyCheck: $empty(),

	initialize: function(_options) {
		//this.boundButtonOn = this.buttonOn.bind(this);
		//this.boundButtonOff = this.buttonOff.bind(this);
		//this.boundWindowSizeCheck = this.windowSizeCheck.bind(this);
		//this.boundKeyCheck = this.keyCheck.bind(this);
		
		this.setOptions(_options);
		
		this.eleSideBar = $('LibSideBar');
		if (!$defined( this.eleSideBar )) {
			return false;
		}
		
		this._createOptions();
		
		this.Fx = new Fx.Tween(this.eleSideBar, {'link': 'cancel', 'unit': 'px', 'duration': this.options.durationMenu, 'transition': this.options.transitionMenu});
		this.FxOptions = new Fx.Morph(this.eleOptionsForm, {'link': 'cancel', 'unit': 'px', 'duration': this.options.durationOptions, 'transition': this.options.transitionOptions});
		
		this.add_events();
	},
	_createOptions: function() {
		//		<div id="LibSideBarOptions"><form id="LibSideBarOptionsForm" name="LibSideBarOptionsForm"><div id="LibSideBarOptionsContents">
		//			Menu: 
		//			<label><input type="radio" name="menustate" value="on">On</label>
		//			<label><input type="radio" name="menustate" value="off">Off</label>
		//		</div></form></div>
		var eleOptions = new Element('div', {id: 'LibSideBarOptions', title: 'Keyboard Shortcut: Use the < and > keys to toggle the side menu.'});	/// , style: 'width: 10px; height: 10px; border: 1px dashed red;'
		this.eleOptionsForm = new Element('form', {id: 'LibSideBarOptionsForm', name: 'LibSideBarOptionsForm'});
		var eleOptionsContents = new Element('fieldset', {id: 'LibSideBarOptionsSet', text: this.options.optionsTextTitle});
		var eleLabelOn = new Element('label', {'text': this.options.optionsTextOn});
		var eleLabelOff = new Element('label', {'text': this.options.optionsTextOff});
		this.eleInputOn = new Element('input', {type: 'radio', id: 'SetMenuOn', name: 'menustate', value: 'on', checked: 'checked'});
		this.eleInputOff = new Element('input', {type: 'radio', id: 'SetMenuOff', name: 'menustate', value: 'off'});
		
		eleLabelOn.grab(this.eleInputOn, 'top');
		eleLabelOff.grab(this.eleInputOff, 'top');
		eleOptionsContents.grab(eleLabelOn);
		eleOptionsContents.grab(eleLabelOff);
		this.eleOptionsForm.grab(eleOptionsContents);
		eleOptions.grab(this.eleOptionsForm);
		$('LibPageW').grab(eleOptions, 'top');
	},
	windowSizeCheck: function() {
		var objWindowSize = $(window).getSize();
		this.bitMenuFitsOnScreen = (objWindowSize.x > this.options.autoMenuOffWidth) ? true : false;
		if (!this.bitMenuFitsOnScreen && this.bitActive == true && this.bitStateSetManually == false) {
			this.hide();
			this.bitStateSetManually = false;
		}
		else if (this.bitMenuFitsOnScreen && this.bitActive == false && this.bitStateSetManually == false) {
			this.show();
			this.bitStateSetManually = false;
		}
	},
	keyCheck: function(event) {
		if ( IgnoreKeyboardInput(event) ) {
			/// Don't bother running the function if we are in a form field.
			return true;
		}
		//window.alert('You pressed a key: '+event.key);
		/// Toggle the menu with comma and period
		if (event.key == ',') {
			/// go left, deactivate menu.
			this.hide();
			this.bitStateSetManually = true;
		}
		if (event.key == '.') {
			/// go right, activate menu.
			this.show();
			this.bitStateSetManually = true;
		}
	},
	buttonOn: function() {
		this.show();
		this.bitStateSetManually = true;
	},
	buttonOff: function() {
		this.hide();
		this.bitStateSetManually = true;
	},
	show: function() {
		/// Check if this method was fired from a DOM event or internally. Rerout it if it was from a DOM event.
		if (this.eleSideBar) {
			//var objSideBarSize = this.eleSideBar.getSize();
			this.Fx.start('margin-left', 0);
			this.FxOptions.start({
				//'left': 16,
				//'top': -12
				//'left': 30,
				//'top': -12,
				'left': 33,
				'top': -9,
				'background-color': '#eeeeee'
			});
			this.eleInputOn.checked = true;
			this.bitActive = true;
		}
	},
	hide: function() {
		if (this.eleSideBar) {
			var objSideBarSize = this.eleSideBar.getCoordinates();
			//this.Fx.effect('transition', 'cubic:out');
			this.Fx.start('margin-left', ((objSideBarSize.width + objSideBarSize.left) * -1));
			this.FxOptions.start({
				//'left': 0,
				//'top': -55
				//'left': 20,
				//'top': -29,
				'left': 20,
				'top': -26,
				//'background-color': '#E4D5AA'
				'background-color': '#e7c36c'
			});
			this.eleInputOff.checked = true;
			this.bitActive = false;
		}
	},
	destroy: function(_revert) {
		this.remove_events();
	},
	add_events: function() {
		this.eleInputOn.addEvent('click', this.buttonOn);
		this.eleInputOff.addEvent('click', this.buttonOff);
		window.addEvent('resize', this.windowSizeCheck);
		window.addEvent('load', this.windowSizeCheck);
		window.addEvent('keydown', this.keyCheck);
		$(document.body).addEvent('keydown', this.keyCheck);
	},
	remove_events: function() {
		this.eleInputOn.removeEvents();
		this.eleInputOff.removeEvents();
	}
});

var TabBarOverflow = new Class({
	Implements: [Options, Events, Fx],

	options: {
		mainContainer: 'LibTabBarOverflow',
		menuContainer: 'LibTabBarOverflowContents',
		menuList: 'LibTabBarOverflowMenu',
		button: 'LibTabBarOverflowButton',
		
		onSlideEnd: $empty()
	},
	
	elem: null,
	eleMenuContainer: null,
	eleMenu: null,
	
	arrTabs: null,
	numItemCount: 0,
	
	bitVisible: false,
	bitActive: false,
	bitUserActivated: false,
	
	boundToggleMenu: $empty(),
	boundOverflowDetection: $empty(),

	initialize: function(_options) {
		this.boundToggleMenu = this.toggleMenu.bind(this);
		this.boundOverflowDetection = this.overflowDetection.bind(this);
		
		this.setOptions(_options);
		
		this.elem = this._elementCheck(this.options.mainContainer) || new Element('div', {'id': this.options.mainContainer});
		this.eleMenuContainer = this._elementCheck(this.options.menuContainer) || new Element('div', {'id': this.options.menuContainer});
		this.eleMenu = this._elementCheck(this.options.menuList) || new Element('ul',  {'id': this.options.menuList});
		this.eleChevron = this._elementCheck(this.options.button) || new Element('div', {'id': this.options.button});
		
		this.eleMenuContainer.appendChild(this.eleMenu);
		this.elem.appendChild(this.eleChevron);
		this.elem.appendChild(this.eleMenuContainer);
		
		this.Fx = new Fx.Tween(this.elem, {'property': 'opacity', 'duration': 100, 'link': 'cancel'});
		this.FxMenu = new Fx.Tween(this.eleMenuContainer, {'property': 'opacity', 'duration': 100});
		this.elem.setStyles({
			'opacity': 0,
			'visibility': 'visible',
			'display': 'block'
		});
		this.eleMenuContainer.setStyles({
			'opacity': 0,
			'visibility': 'visible',
			'display': 'block'
		});
		
		this.arrTabs = $$('.NavTab');
		this.arrTabs.each( function(eleTab, index) {
			eleTab.getElement('a').title+= ' - Keyboard Shortcut: Use [' + (index+1) + '] to activate this index tab.';
		});
		this.arrTabs.reverse();
		
		$(document.body).grab(this.elem);

		this.add_events();
	},
	_elementCheck: function(input) {
		if ($type(input) == 'element' || ($type(input) == 'string' && $(input))) {
			return $(input);
		}
		return false;
	},
	highlightThis: function() {
		this.highlight('#eee');
	},
	show: function() {
		this.elem.setStyle('display', 'block');
		this.Fx.start(1);
		this.bitVisible = true;
	},
	hide: function() {
		this.Fx.start(0).chain(function() { this.elem.setStyle('display', 'none'); }.bind(this) );
		this.bitVisible = false;
	},
	toggleMenu: function() {
		if (this.bitActive) {
			this.deactivate();
		}
		else {
			this.activate();
		}
	},
	activate: function() {
		this.eleMenuContainer.setStyle('display', 'block');
		this.FxMenu.start(1);
		this.bitActive = true;
	},
	deactivate: function() {
		this.FxMenu.start(0).chain(function() { this.eleMenuContainer.setStyle('display', 'none'); }.bind(this) );
		this.bitActive = false;
	},
	addItem: function(id, text, link) {
		var eleListItem = this.eleMenu.getElement('#Overflow' + id);
		
		if (eleListItem == null) {
			eleListItem = new Element('li', {'id': 'Overflow' + id});
			var eleLink = new Element('a', {'href': link, 'text': text});
			eleListItem.grab(eleLink);
			
			this.eleMenu.grab(eleListItem, 'top');
			this.numItemCount++;
			this.highlightThis.delay(100, eleListItem);
		}
	},
	dropItem: function(id) {
		var eleListItem = this.eleMenu.getElement('#Overflow' + id);
		if (eleListItem) {
			var eleRemovedItem = eleListItem.dispose();
			this.numItemCount--;
		}
	},
	overflowDetection: function() {
		var objWindowSize = $(window).getSize();
		var bitAnyTabsHidden = false;
		this.arrTabs.each( function(eleTab) {
			var objTabSize = eleTab.getCoordinates();
			objTabSize.fromright = objWindowSize.x - objTabSize.right;
			objTabSize.frombottom = objWindowSize.y - objTabSize.top + objTabSize.height;
			objTabSize.isoffscreen = false;
			if (objTabSize.fromright < 0 || objTabSize.frombottom < 0) {
				objTabSize.isoffscreen = true;
				bitAnyTabsHidden = true;
			}
			this.elem.setStyle('top', (objTabSize.top + objTabSize.height + 10) + 'px');
			
			if (objTabSize.isoffscreen) {
				var eleLink = eleTab.getElement('a');
				this.addItem(eleTab.id, eleLink.get('text'), eleLink.get('href'));
			}
			else {
				this.dropItem(eleTab.id);
			}
		}, this);
		
		if (this.numItemCount > 0) {
			if (this.bitVisible == false) {
				this.show();
			}
		}
		else {
			if (this.bitVisible == true) {
				this.hide();
			}
		}
	},
	destroy: function(_revert) {
		this.remove_events();
	},
	add_events: function() {
		this.eleChevron.addEvent('click', this.boundToggleMenu);
		window.addEvent('resize', this.boundOverflowDetection);
		window.addEvent('load', this.boundOverflowDetection);
	},
	remove_events: function() {
		this.eleChevron.removeEvents();
	}
});

// FUNCTIONS //////////////////////////////////////////////////////////////////
function InitializeLoginState() {
	var objLibLoginStateText = $('LibLoginStateText');
	if (objLibLoginStateText) {
		if (objLibLoginStateText.href) {
			objLibLoginStateText.addEvent('click', function() {
				var objLibLogin = $('LibLogin');
				ToggleBlock(objLibLogin);
				if (objLibLogin.getStyle('display') == 'none') {
					this.removeClass('LibLoginStateTextOn');
					this.addClass('LibLoginStateTextOff');
				}
				else {
					this.removeClass('LibLoginStateTextOff');
					this.addClass('LibLoginStateTextOn');
				}
				return false;
			});
		}
		objLibLoginStateText.addClass('LibLoginStateTextOff');
	}
}
function UpdateLoginStatePosition() {
	var eleLibLoginState = $('LibLoginState');
	var eleLibTitleBar = $('LibTitleBar');
	if (eleLibLoginState && eleLibTitleBar) {
		var objTitleBarSize = eleLibTitleBar.getCoordinates();
		var intLoginStateTop = (objTitleBarSize.top + objTitleBarSize.height);
		eleLibLoginState.setStyle('top', intLoginStateTop + 'px');
	}
}


var arrExcludeFromQuickNav = new Array('/Ask/.*', 'SomeFlashThing');

function KeyPressHandler(event) {
	if ( IgnoreKeyboardInput(event) ) {
		/// Don't bother running the function if we are in a form field.
		return true;
	}
	
	/// Load an index based on the number key you press
	var numpadkey = event.key.replace(/^numpad /, '');
	var navtabObj = $('NavIndex' + parseInt(numpadkey || event.key) );
	if (navtabObj) {
		var linkhref = navtabObj.getElement('a').href;
		var bitSafeToForward = true;
		var strDocumentUri = window.location.pathname;
		arrExcludeFromQuickNav.each(function(strUrl) {
			//console.log('is '+strDocumentUri+' == '+strUrl, strDocumentUri.search(strUrl));
			if (strDocumentUri.search(strUrl) != -1) {
				bitSafeToForward = false;
			}
		});
		if (bitSafeToForward) {
			//window.alert(linkhref);
			//console.log('Forwarding to '+linkhref);
			window.location.href = linkhref;
		}
	}
}

// PREPARE THE HEADER /////////////////////////////////////////////////////////

window.addEvent('domready', function() {
	var TabBarOverflowObj = new TabBarOverflow();
	
	var objSideBar = new SideBar();
	
	var objDropDown = new DropDown( 'LibHeaderQuickLinksSelect', {dropdownTitle: 'Quick Links'} );
	
	var objSiteSearch = new SiteSearch( 'LibHeaderSearchField' );
	
	InitializeHours();
	InitializeLoginState();
	
	/// Example of how to add an item to the dropdown menu.
	/// $('LibTitleBar').addEvent('click', function() {
		/// objDropDown.addOption({'text': 'new option', 'href': '/'});
		/// objDropDown.removeOption(1);
	/// });
	
	/// Add aliases to the keycodes for comma and period
	Event.Keys.comma = 188;
	Event.Keys.period = 190;
	for (var i = 0; i <= 9; i++) {
		Event.Keys['numpad '+i] = i + 96;
	}
	
	$(document.body).addEvent('keydown', KeyPressHandler);
	window.addEvent('keydown', KeyPressHandler);
	
	window.addEvent('load', UpdateLoginStatePosition);
	window.addEvent('resize', UpdateLoginStatePosition);
	
});


