Element.addMethods({
	accordion: function (element, o) {
		var options = Object.extend({
			action: 'click',
			openEntry: 0,
			animateOpenEntry: true,
			titleTag: 'dt',
			contentTag: 'dd',
			direction: 'vertical',
			collapsedSize: '0px',
			openSize: 'auto',
			duration: 0.6
		}, o || {});
		
		var titles = element.select(options.titleTag),
		 	content = element.select(options.contentTag),
			height = content.invoke('getHeight'),
			width = content.invoke('getWidth'),
			styling = new Template('#{dimension}: #{size}'),
			openStyling = styling.evaluate({
				dimension: (options.direction === 'vertical') ? 'height' : 'width',
				size: options.openSize
			}),
			closedStyling = styling.evaluate({
				dimension: (options.direction === 'vertical') ? 'height' : 'width',
				size: options.collapsedSize
			});
		
		if (element.readAttribute('data-open')) {
			options.openEntry = parseInt(element.readAttribute('data-open'), 10) - 1;
		}
		
		if (element.readAttribute('data-duration')) {
			options.duration = parseFloat(element.readAttribute('data-duration'));
		}
		
		if (element.readAttribute('data-action')) {
			options.action = element.readAttribute('data-action');
		}
		
		if (element.readAttribute('data-size')) {
			options.openSize = element.readAttribute('data-size');
		}
		
		var currentEntry = options.openEntry;
		
		titles.each(function (t, i) {
			var c = content[i];
			if (i !== currentEntry) {
				c.setStyle(closedStyling);
			} else {
				t.addClassName('selected');
			}
			
			t.observe(options.action, function (event) {
				event.stop();
				if ((i === currentEntry && options.openEntry === -1) || i !== currentEntry) {
					if (titles[currentEntry]) {
						titles[currentEntry].removeClassName('selected');
					}
	
					if (content[currentEntry]) {
						content[currentEntry].morph(closedStyling, { duration: options.duration });
					}
				}
											
				if (i !== currentEntry) {
					titles[i].addClassName('selected');
					c.morph(styling.evaluate({
						dimension: (options.direction === 'vertical') ? 'height' : 'width',
						size: ((options.direction === 'vertical') ? height[i] : width[i]) + 'px'
					}), { duration: options.duration });
					
					currentEntry = i;
				}
				
			});
		});
	}
});

document.observe('dom:loaded', function () {
	$$('.accordion.vertical').invoke('accordion', { direction: 'vertical' });
	$$('.accordion.horizontal').invoke('accordion', { direction: 'horizontal' });
});

