document.observe("dom:loaded", function() {

	///////// INITIALIZING REFINE BY CHECKBOX CSS //////////
	$$(".checkboxStyleNav .checkbox").each(function(el) {
		$(el).setStyle({ overflow:"hidden", width:"14px", height:"14px" });

		//check if checkbox is checked (now that's not redundant, ha)
		var checkboxEl = $(el).childElements("input")[0];
		if(checkboxEl.checked) {
			$(el).setStyle({"background":"transparent url(/images/checkbox_sprite2.gif) no-repeat -14px top"});
			$(el).up("li").addClassName("checked");
		}
		else {
			$(el).setStyle({"background":"transparent url(/images/checkbox_sprite2.gif) no-repeat left top"});
			$(el).up("li").removeClassName("checked");
		}

	});
	$$(".checkboxStyleNav .checkbox input").each(function(el) {
		$(el).setStyle({ position:"absolute", left:"-9999px" });
	});

	//handle checkbox check for image
	$$(".checkboxStyleNav .checkbox").each(function(el) {
		$(el).observe('click', function(event) { toggleImageCheckbox(el); });
	});
	///////// END INITIALIZING REFINE BY CHECKBOX CSS //////////

	fakeValue('q', 'Search');
	fakeValue('refineTerm', "Search within results");

	var nav = $('refineSearch');
	if (nav) new FilterNav(nav);

	// Homepage login link actions
	$$('#showlibcard').invoke('observe', 'click', function(event) {
		$('libcardwrapper').setStyle({display:'block'});
		$('showusernameform').setStyle({display:'block'});
		this.setStyle({display:'none'});
		$('loginwrapper1').setStyle({display:'none'});
		$('lcnum').focus()
		event.stop();
	});
	$$('#showusernameform').invoke('observe', 'click', function(event) {
		$('libcardwrapper').setStyle({display:'none'});
		$('showlibcard').setStyle({display:'block'});
		this.setStyle({display:'none'});
		$('loginwrapper1').setStyle({display:'block'});
		$('username').focus()
		event.stop();
	});

	//zebra striation on tables
	$$(".bookDetail #readPanel table").each(function(elTablo) {
		var evenRow = false;
		elTablo.select("tr").each(function(el) {
			if(evenRow) {
				el.addClassName("even");
				evenRow = false;
			}
			else {
				evenRow = true;
			}
		});
	});

});

function fakeValue(id, value) {
	var field = $(id);
	if (!field) return;
	
	field.value = value;
	field.observe('focus', function() { if (field.value == value) field.value = ''; });
	field.observe('blur', function() { if (field.value == '') field.value = value; });
	
	if (field.form)
		$(field.form).observe('submit', function() { if (field.value == value) field.value = ''; });
}


function toggleImageCheckbox(el) {
	var checkboxEl = $(el).childElements("input")[0];
	var checkBoxState = checkboxEl.checked;
	if(checkBoxState) {
		checkboxEl.checked = false;
		$(el).setStyle({"background":"transparent url(/images/checkbox_sprite2.gif) no-repeat left top"});
		$(el).up("li").removeClassName("checked");
	}
	else {
		checkboxEl.checked = true;
		$(el).setStyle({"background":"transparent url(/images/checkbox_sprite2.gif) no-repeat -14px top"});
		$(el).up("li").addClassName("checked");
	}
}

var FontResizer = Class.create({
	initialize: function(resizer) {
		resizer = $(resizer);
		this.cookies = new CookieJar();
		this.cookies.appendString = "";
		
		var normal = resizer.down('.textNormal a');
		var large = resizer.down('.textLarge a');
		
		var inst = this;
		normal.observe('click', function() {
			$$('body').first().removeClassName('largeFont');
			normal.addClassName('selected');
			large.removeClassName('selected');
			inst.cookies.remove('fontsize');
		});
		
		large.observe('click', function() {
			$$('body').first().addClassName('largeFont');
			normal.removeClassName('selected');
			large.addClassName('selected');
			inst.cookies.put('fontsize', 'largeFont');
		});

		// only set if the large one is selected
		var current = this.cookies.get('fontsize');
		if (current) {
			normal.removeClassName('selected');
			large.addClassName('selected');
		}
	}
});

/** Call to enable highlight and find for a given page. */
function enableHighlightAndFind(selector) {
    // set double click handler on unlinked text in the entry
    $("readPanel").observe('dblclick', function(event) {
        highlightAndFind();
    });
}

/** searches for the current selection */
function highlightAndFind(){
	// select the text
	var txt = '';
	if (window.getSelection)
	{
		txt = window.getSelection();
	}
	else if (document.getSelection)
	{
		txt = document.getSelection();
	}
	else if (document.selection)
	{
		txt = document.selection.createRange().text;
	}
	if (txt == '') {
		return;
	}

	var q = $('q');
	q.setValue('');
	q.setValue(txt);
	q.form.submit();
}

function selectHomepageTab(a, panelId) {
	a = $(a);
	$$('#homeTabs li').each(function(li) { li.removeClassName('active'); });
	a.up('li').addClassName('active');
	
	$$('#homePanels .panel').each(function(panel) { panel.hide(); });
	$(panelId).show();
}

function createHelpIndex() {
	var indexDiv = $("anchorIndex");
	
	$$("a[name]").each(function(a) {
		indexDiv.insert("<li><a class=\"indexLink\" href=\"/help#" + a.readAttribute("name") + "\">" + a.innerHTML + "</a></li>" );
	});
}

/** A panel represents each of the lists of the options of which there may be many and also may be nested. */
var Panel = Class.create({
	initialize: function(ul, parent, filter, lazy) {
		this.ul = ul;
		this.filter = filter;
		this.parent = parent;
		this.lazy = lazy;
		
		$T(ul).panel = this;
		
		/* if a list is really it needs to scroll. but in order to activate the overflow scrolling
		 * the element needs to have an explicit height set. on initial page load the height of the first list
		 * is automatic (because we don't want it to scroll) and needs to be carried over to all the child lists so that they scroll.
		 */
		if (parent) {
			this.height = parent.height;
			this.ul.setStyle({ 'height': this.height + 'px' });
		} else {
			// the height of the inner lists is going to be the top-level one minus the back button height
			var backHeight = ul.select("h3").first().getHeight(); //was static 25;
			this.height = this.ul.getHeight() - backHeight;
		}

		for(var i=0; i<ul.childElements().length; i++) {
			var li = ul.childElements()[i];
			var link = li.down('a');
			
			// make sure the links are well-formed for not actually doing anything
			link.href = 'javascript:void(0);';
			
			if (li.hasClassName('nochildren')) {
				link.observe('click', this.applyFilter.bindAsEventListener(this, link));
			} else {
				link.observe('click', this.showChildren.bindAsEventListener(this, li));
				
				if (!lazy)
					this.initItem(li);

				var back = li.down('h3').down('a');
				back.href = 'javascript:void(0);';
				back.observe('click', this.back.bindAsEventListener(this, li));
			}
		}
	},

	/** Inits the state for a item. */
	initItem: function(li) {
		/* initializing all of this may be slow because the options available for selection could be huge.
		 * we only need to do it for a filter when it's clicked.
		 */
		if (!$T(li).child)
			$T(li).child = new Panel(li.down('ul'), this, this.filter, this.lazy);
	},
	
	showChildren: function(e, li, direct) {
		this.initItem(li);
		
		// note: you can't use hide()/show() because the styles are set in the css
		li.down('h3').setStyle({display: 'block'});
		li.down('ul').setStyle({display: 'block'});
		
		// note: you need to manage the overflows manually or else 3rd-level lists and lower will not display
		this.ul.setStyle({overflow:'visible'});
		
		this.filter.expand(this, li, direct, function() {
			li.down('ul').setStyle({overflow: 'auto'});
		});
	},
	
	applyFilter: function(e, link) {
		// FIXME don't hardcode the id prefix or the id of the form element to store in
		var taxid = link.id.replace('taxonomy_', '');
		// TODO support having multiple widgets on the same page
		this.filter.select(link);
		$('refineTaxonomy').value = taxid;
		$('refineTerm').value = '';
		$('refineForm').submit();
	},
	
	back: function(e, li) {
		// don't hide until the transition is done or else the options disappear too quick
		var panel = this;
		this.filter.collapse(this, function() {
			li.down('h3').hide();
			li.down('ul').hide();
			li.down('ul').setStyle({overflow: 'visible'});
			panel.ul.setStyle({overflow:'auto'});
		});
	},
	
	getWidth: function() {
		// calculating width can be slow. just hard-code for now.
		return parseInt(this.ul.getWidth()) - 1;
//		return 182;
	},

	/** Returns the width of this panels ancestors */
	getAncestorWidth: function() {
		return this.parent ? this.parent.getTotalWidth() : 0;
	},

	/** Returns the width of this panel and each of it's ancestors */
	getTotalWidth: function() {
		return this.getWidth() + this.getAncestorWidth();
	}
});

/** A filter nav is an initial Panel of filters to select from.
 * Note: this requires cookiejar.js (http://www.lalit.org/lab/jsoncookies).
 */
var FilterNav = Class.create({
	speed: 0.2,			// animation speed
	startOffset: -1,	// left offset for the first panel. i think this is due to the border on the element.
	
	initialize: function(nav) {
		this.cookies = new CookieJar();
		this.breadcrumbsWrapper = nav.insert('<div class="flyoutBreadcrumbs"></div>').down('.flyoutBreadcrumbs');
		
		var selectedId = this.cookies.get('nav.selected-id');
		this.cookies.remove('nav.selected-id');
		var selectedLink = null;
		if (selectedId) {
			selectedLink = $(selectedId);
		}
		
		this.container = nav.down('ul');
		var lazy = selectedLink == null;
		this.topPanel = new Panel(this.container, null, this, true);
		
		if (selectedLink) {
			var ancestors = new Array();
			var parent = selectedLink.up('li');
			var top = false;
			do {
				if (parent.up('ul') == this.container)
					top = true;
				
				ancestors.unshift(parent);
				parent = parent.up('li');
			} while (parent && !top)
			
			for(var i=0; i<ancestors.length; i++) {
				var li = ancestors[i];
				$T(li.up('ul')).panel.showChildren(null, li, true);
			}
		}
	},
	
	/** Informs the main nav that an item has been selected. */
	select: function(link) {
		this.cookies.put('nav.selected-id', link.id);
	},

	/** direct indicates whether to use an animation or directly set the styles. */
	expand: function(panel, li, direct, finish) {
		var left = this.startOffset - panel.getTotalWidth();

		if (!direct) {
			new Effect.Morph(this.container, {
				style: 'left:' + left + 'px;',
				duration: this.speed
			});
			finish();	// note: need to have this not after effect finish to prevent flicker
		} else {
			this.container.setStyle({ 'left': left + 'px' });
			finish();
		}
		
		this.updateBreadcrumbs(panel, li);
	},
	
	collapse: function(panel, finish) {
		var left = this.startOffset - panel.getAncestorWidth();

		new Effect.Morph(this.container, {
			style: 'left:' + left + 'px;',
			duration: this.speed,
			afterFinish: finish
		});
		
		this.updateBreadcrumbs(panel.parent, panel.ul.up('li'));
	},
	
	/** Creates breadcrumbs up through the given panel. li is used to calculate the labels of the items. */
	updateBreadcrumbs: function(panel, li) {
		var ancestors = new Array();
		var item = li;
		while(item && $T(item.up('ul')).panel) {
			ancestors.unshift(item);
			item = item.up('li');
		}
		
		var ul = new Element('ul');
		for(var i=0; i<ancestors.length; i++) {
			var anc = ancestors[i];
			var label = anc.down('a').innerHTML;
			
			var li = new Element('li');
			
			if (i == 0)
				li.addClassName('first');
			if (i == ancestors.length - 1)
				li.addClassName('last');
			
			li.update(label);
			ul.insert(li);
		}
		this.breadcrumbsWrapper.update(ul);
	}
});

var TOC = Class.create({
	initialize: function(container) {
		container = $(container);
		if (!container) return;
		
		container.select("li.expandable").each(function(li) {
			var ul = li.down('ul');
			var active = li.hasClassName('current');
			
			if (!active)
				ul.hide();
			
			var toggle = $(new Element('a'));
			toggle.addClassName('toggle').addClassName(active ? 'minustoggle' : 'plustoggle').update("<span>toggle</span>");

			toggle.observe('click', function(event) {
				if (ul.visible()) {
					toggle.addClassName('plustoggle');
					toggle.removeClassName('minustoggle');
					ul.hide();
				} else {
					toggle.removeClassName('plustoggle');
					toggle.addClassName('minustoggle');
					ul.show();
				}
				event.stop();
			});

			li.insert({'top':toggle});

		});
	}
});

/** When an element is 'popped out' it is hidden and replaced with something that the user
 * can user to show the content. This method should create that something.
 * The function that will display the content in a lightbox can be accessed via: $T(e).showPopup
 * Only called if the element should be popped out.
 * @param l the suggested label to use for the trigger
 */
var popoutElement = function(e, label) {
	var link = new Element('a', {'class':'popoutContentLink'}).insert('<span>' + label + '</span>')
	link.observe('click', $T(e).showPopup);
	e.insert({'after': link});
}

/** replaces content with a link that will show said content in a lightbox. */
var popoutContent = function(elements, label) {
	// TODO render off-screen and remeasure based on actualy dimensions
	var showPopup = function(element) {
		var padding = 50 * 2;	// padding double for top/bottom & right/left
		var width = Math.min(document.viewport.getWidth() * .9, element.getWidth() + padding);
		var height = Math.min(document.viewport.getHeight() * .85, element.getHeight() + padding);
		
		// see lightbox.js & window.js
		var win = new Window({
			minimizable : false,
			maximizable : false,
			draggable : true,
			destroyOnClose: true,
			recenterAuto: false,
			width: width,
			height: height,
			zIndex: 10000
		});

		// wrap content in the same div's as the lightbox layout
		var container = new Element('div').update(new Element('div', {'id':'modalContent'}).update('<div id="modalInnerContent"><div class="popoutContentWrapper"></div></div>'));
		// TODO replace with Element.clone() after upgrading
		container.down('.popoutContentWrapper').insert(element.cloneNode(true));
		
		// note: do not use setContent() as it can cause errors in IE 7
		win.setHTMLContent(container.innerHTML);
		window.currentLightbox = win;
		
		win.showCenter(true, 80);
		
		//TEMPORARY FIX TO ADD BASE CLASS TO ALL INLINE POPUP CONTENT
		$$("div.dialog_content").each(function(el) {
			el.addClassName("mainBase");
		});
	};
	
	elements = $(elements);
	elements.each(function(e) {
		if (e.hasClassName('nosuppress') || e.up('.nosuppress')) return;
		
		var l = e.title || label;
		e.addClassName('popoutContent');
		$T(e).showPopup = showPopup.curry(e);
		popoutElement(e, l);
	});
}

/** Makes links that popout trigger the popout directly. 
the anchor may link to either the id of the item directly. */
// TODO this would probably be faster to maintain a list of tables that are popped out
var popoutLinks = function() {
	var basePath = window.location.pathname + "#";
	if (!basePath.startsWith('/')) basePath = '/' + basePath;
	
	$$('#readPanel a').each(function(a) {
		var href = a.readAttribute('href')
		if (!href || !(href.startsWith('#') || href.startsWith(basePath))) return;

		var id = href.substring(href.indexOf('#') + 1);
		var target = $(id);
		if (!target) return;

		var show = $T(target).showPopup;

		if (!show) {
			target = target.down('.popoutContent');
			if (target)
				show = $T(target).showPopup;
		}

		if (!show) return;
		a.observe('click', function(event) { show(); Event.stop(event); });
	});
}

function tableNote(link) {
//	if (window.currentLightbox) window.currentLightbox.close();
}

