addLoadEvent(function() {
	Accordion();
});

function Accordion() {
	var uls      = document.getElementsByTagName('ul'),
		accordions = [],
		aPanels    = [],
		aHeads     = [],
		i, j;

	// Collect all accordions and push them in to 'accordions' array
	for (i = 0; i < uls.length; i++) {
		if (hasClass(uls[i], 'accordion')) {
			accordions[accordions.length] = uls[i]
		}
	}

	// Collect all accordion panels, collapse them, and push them in to 'aPanels' array
	for (i = 0; i < accordions.length; i++) {
		var lis = accordions[i].getElementsByTagName('li');
		for (j = 0; j < lis.length; j++) {
			if (hasClass(lis[j], 'accordionPanel')) {
				if (!hasClass(lis[j], 'aExpanded') && !hasClass(lis[j], 'aLocked')) {
					addClass(lis[j], 'aContracted');
				}
				aPanels[aPanels.length] = lis[j];
			}
		}
	}

	// Collect all accordion heads and push them in to 'aHeads' array
	for (i = 0; i < accordions.length; i++) {
		var els = (accordions[i].getElementsByTagName('*')) ? accordions[i].getElementsByTagName('*') : accordions[i].all;
		for (j = 0; j < els.length; j++) {
			if (hasClass(els[j], 'accordionHead')) {
				aHeads[aHeads.length] = els[j];
			}
		}
	}

	// Control behaviour of accordion heads on mouseover, mouseout and click
	for (i = 0; i < aHeads.length; i++) {

		// Add class of 'aHHover' on mouseover
		aHeads[i].onmouseover = function () {
			addClass(this, 'aHHover');
		}

		// Remove class of 'aHHover' on mouseout
		aHeads[i].onmouseout = function () {
			removeClass(this, 'aHHover');
		}

		aHeads[i].onclick = function () {

			// Target clicked panel and compute whether to expand it or not
			var id    = this.getAttribute('id'),
				aPanel = document.getElementById('aP' + id.slice(2)),
				expand = hasClass(aPanel, 'aContracted');
				unlock = hasClass(aPanel, 'aLocked')

			// Collapse all panels, providing they're not locked
			for (j = 0; j < aPanels.length; j++) {
				if (!hasClass(aPanels[j], 'aLocked')) {
					addClass(aPanels[j], 'aContracted');
				}
			}

			// If panel is to be expanded, expand it.
			if (expand) {
				removeClass(aPanel, 'aContracted');
			}

			// If panel is to be unlocked, unlock it and have it behave like a normal accordion panel
			if (unlock) {
				removeClass(aPanel, 'aLocked');
				addClass(aPanel, 'aContracted');
			}
		}
	}
}

// Side functions
function hasClass(obj, className) {
	var re = new RegExp('(^|\\s)' + className + '(\\s|$)');
	if (typeof(obj) == 'string') {
		return re.test(obj);
	}
	else if (typeof(obj) == 'object' && obj.className) {
		return re.test(obj.className);
	}
	return false;
}

function addClass(el, className) {
	if (hasClass(el, className)) return;
	if (!el.className) {
		el.className = className;
	}
	else {
		el.className = el.className + ' ' + className;
	}
}

function removeClass(el, className) {
	if (el.className == className) {
		el.className = '';
	}
	else {
		el.className = el.className.replace(className, ' ');
	}
}