/*
 * expandable.js
 *
 * depends on:
 *   scl.js, for iterative Array functions and add_load_event()
 */

/* Expandables:
 * Add class expandable to a container element to make it expandable via 
 * nominated trigger links.
 * Add class expandme on the child elements to be expanded/collapsed. Add class 
 * expandtrigger on A child elements which should trigger 
 * expansion/collapsation.
 */
var all_expandables = []; /* for mutual exclusivity */
var setup_expandable = function (elem) {
var donotcollapse = false; //for quicklinks
	all_expandables.push(elem);

	/* visit all of elem's children to pick out expandmes and set up 
	 * expandtriggers */
	var expandmes = [];
	var triggers = [];
	foreach(elem.getElementsByTagName('*'), function (child) {
		/* is it an expandme? */
		if (has_class(child, 'expandme')) {
			expandmes.push(child);
		}

		/* is it an expandtrigger? */
		if (has_class(child, 'expandtrigger') 
				&& /* for sanity */ child.tagName == 'A') {
			//for quicklinks
			if(child.id.length > 0 && child.id.substr((child.id.length-3),child.id.length) == '_ql') {
				if(document.getElementById('saved_QL').value.length > 0 && child.id.search(document.getElementById('saved_QL').value) != -1) {
					donotcollapse = true;
				}
			}
			if (!child.getAttribute('href')) {
				child.setAttribute('href', '#');
			}
			triggers.push(child);
		}
	});

	elem._expand = function () {
		foreach(expandmes, show_element);
		foreach(triggers, function (trigger) {
			remove_class(trigger, 'expandtrigger_collapsed');
			set_class(trigger, 'expandtrigger_expanded');
			trigger.onclick = elem._collapse;
		});
		/* collapse all other expandables */
		foreach(all_expandables, function (expandable) {
			if (expandable != elem)
				expandable._collapse();
		});
		return false; /* for HREFs */
	};

	elem._collapse = function () {
		foreach(expandmes, hide_element);
		foreach(triggers, function (trigger) {
			remove_class(trigger, 'expandtrigger_expanded');
			set_class(trigger, 'expandtrigger_collapsed');
			trigger.onclick = elem._expand;
		});
		return false; /* for HREFs */
	};
	if(!donotcollapse) {
		elem._collapse(); /* initially collapsed */
	} else {
		elem._expand();
	}

}

add_load_event(function () {
	foreach(document.getElementsByTagName('*'), function (elem) {
		if (has_class(elem, 'expandable')) {
			setup_expandable(elem);
		}
	});
});

/* One-shot expandables with (more) link:
 * Add class expandable_morelink to a container element to make it expandable 
 * once via a (more) link.
 * Add class expandme on the child elements to be expanded/collapsed. The 
 * (more) link will be added to the last P element before the first expandme.
 */
var setup_expandable_morelink = function (elem) {

	/* visit all of elem's children to pick out expandmes and to find the 
	 * P element where (more) should be added */
	var expandmes = [];
	var p_for_more = undefined;
	foreach(elem.getElementsByTagName('*'), function (child) {
		/* is it an expandme? */
		if (has_class(child, 'expandme')) {
			expandmes.push(child);
			hide_element(child);
		}

		/* is it a candidate P? */
		if (expandmes.length == 0 && child.tagName == 'P') {
			p_for_more = child;
		}
	});

	var more = document.createElement('a');
	more.appendChild(document.createTextNode('(more)'));
	more.setAttribute('href', '#');
	more.onclick = function () {
		foreach(expandmes, show_element);
		remove_element(more); /* XXX does this make a cyclic reference? */
		return false;
	};
	p_for_more.appendChild(document.createTextNode(' '));
	p_for_more.appendChild(more);

};

add_load_event(function () {
	foreach(document.getElementsByTagName('*'), function (elem) {
		if (has_class(elem, 'expandable_morelink')) {
			setup_expandable_morelink(elem);
		}
	});
});
