/*
Class: ListSelect
	

Arguments:
	el - the $(element) to apply the transformation to.
	options - optional. The options object.

Options:
	
*/

Element.implement({
	getAllChildren: function(match, nocash){
		var children = [];
		this.getChildren(match, nocash).each(function(child){
			children.push(child);
			children.extend(child.getAllChildren(match, nocash));
		});
		return children;
	}
});

var ListSelect = new Class({
	
	Implements: Options,
	
	options: {
		name: '',
		wrap: 'dl'
	},
	
	initialize: function(el, options){
		this.setOptions(options);
		this.container = $(el);
		this.inputs = [];
		
		this.container.getAllChildren().filter(function(el){
			return el.get('name') == this.options.name;
		}, this).each(function(input) {
			var container = this.getContainer(input);
			
			input.addEvent('change', (function(e){
				// Enable selected
				this.toggleChildInputs(container, false);
				
				// Disable others
				this.inputs.filter(function(el){
					return el != input;
				}).map(this.getContainer).each(function(container){
					this.toggleChildInputs(container, true);
				}, this);
			}).bind(this));
			
			this.inputs.push(input);
		}, this);
		
		this.inputs.each(function(input){
			if (input.checked){
				input.fireEvent('change');
			}
		});
	},
	
	getContainer: function(el){
		var container = el;
		while (!(container = container.getParent()).match('dt'));
		return container.getNext();
	},
	
	toggleChildInputs: function(container, disabled){
		return container.getAllChildren(false, true).filter(function(el){
			return ['input', 'textarea', 'select', 'button'].contains(el.tagName.toLowerCase()) && !this.inputs.contains(el);
		}, this).each(function(el){
			el.disabled = disabled;
		});
	}
});

/*
Class: Element
	Custom class to allow all of its methods to be used with any DOM element via the dollar function <$>.
*/

Element.implement({

	/*
	Property: makeListSelect
		

	Arguments:
		options - see <ListSelect> for acceptable options.
	*/

	makeListSelect: function(options){
		return new ListSelect(this, options);
	}

});
