/*
Simple script that implements an accordian-style functionality for navigation.
Designed to be used on a list nested list item (usually just two levels). When
You click on a <li> if that element has a child list then that child list
is displayed. All other child lists of sibling <li> will be closed.

If there is more than two levels in the list just the level you are clicking
on will hide and show. This allows implementation of a basic tree menu.

If script.aculo.us is loaded then it will SlideUp and SlideDown. Otherwise
it will just hide and show. When using the effects a <div> will be dynamically
inserted into the markup to correct for rendering errors by the various browsers
*/

var Accordian = Class.create();
Object.extend(Accordian.prototype, {
	initialize:	function(list) {
		this.list = $(list);
		$$('#'+this.list.id+' li').each((function(header) {
			if(!header.down('ul')) return;
			Event.observe(header, 'click',
				this.click.bindAsEventListener(this));
		}).bind(this));
	},
	click:		function(event) {
		// Determine header
		var clicked_element = Event.element(event);
		var header = clicked_element.tagName.toLowerCase() == 'li' ?
			clicked_element : clicked_element.up('li');

		// Filter out clicks in child tree
		if(!header.down('ul')) return;

		// Figure out all siblings
		var siblings = header.up('ul').immediateDescendants().findAll(
			function(c){return c.tagName.toLowerCase() == 'li'});
		siblings = siblings.reject(function(s) {return s == header});
		siblings = siblings.reject(function(s) {return !s.down('ul')});

		// If no siblings we must have hit some other markup
		if(siblings.size == 0) return;

		// For each sibling collapse child ul
		siblings.each((function(s) {this._hide(s.down('ul'))}).bind(this));

		// Show the clicked header
		this._show(header.down('ul'));
	},

	// Will act like Element.hide() and Element.show() unless the right
	// script.aculo.us effects are loaded
	_hide:		function(element) {
		if( typeof(Effect) != 'undefined' && Effect.SlideUp ) {
			this._slide_markup(element);
			if( $(element.parentNode).visible() )
				Effect.SlideUp(element.parentNode);
		} else element.hide();
	},
	_show:		function(element) {
		if( typeof(Effect) != 'undefined' && Effect.SlideDown ) {
			this._slide_markup(element);
			if( !element.parentNode.visible() )
				Effect.SlideDown(element.parentNode);
		} else {
			if( !element.visible() ) element.show();
		}
	},
	_slide_markup:	function(element) {
		if(element.parentNode.tagName == 'DIV' &&
			element.parentNode.className == 'wrapper') return;
		var wrapper = $(document.createElement('div'));
		element.parentNode.insertBefore(wrapper, element);
		wrapper.addClassName('wrapper');
		wrapper.appendChild(element);
		if( !element.visible() ) {
			wrapper.hide();
			element.show();
		}
	}
});
