// based on 
// Justin Palmer's EventSelectors (http://encytemedia.com/event-selectors)
// Dan Webb's LowPro http://svn.danwebb.net/external/lowpro
if (!CD3) var CD3 = {};

CD3.Behaviors = function(rules){
	if (Prototype.Browser.IE)
		Event.observe(window, 'load', CD3.Behaviors.assign.curry(rules));
	else
		document.observe('dom:loaded', CD3.Behaviors.assign.curry(rules));
}

Object.extend(CD3.Behaviors, {
	cache: [],
	assign: function(rules){
		for (var selector in rules) {
			var observer = rules[selector];
			selector.split(',').each(function(sel) {
				var parts = sel.split(/:(?=[a-z]+$)/), css = parts[0], event = parts[1];
				$$(css).each(function(element) {
					if (event) {
						CD3.Behaviors.observe(element, event, observer);
					} else if (Object.isArray(observer)){
						var klass = observer.shift();
						new klass(element, observer.shift()); 
					} else if (observer.prototype && observer.prototype.initialize){
						new observer(element);
					} else if (Object.isFunction(observer)){
						observer.call(element, element);
					} else {
						for(var e in observer)
							CD3.Behaviors.observe(element, e, observer[e]);
					}
				});
			});
		}
	},
	observe: function(element, event, observer){
		var behavior = CD3.Behaviors;

		if (!Object.isFunction(observer))
			observer = behavior.delegate(observer);
				
		$(element).observe(event, observer);
		behavior.cache.push([element, event, observer]);
	},
	delegate: function(rules){
		return function(e){
			var element = $(e.element());
			for (var selector in rules)
				if (element.match(selector))
					return rules[selector].call(this, e);
		}
	},
	unload: function(){
		CD3.Behaviors.cache.each(function(c) {
			Event.stopObserving.apply(Event, c);
		});
		CD3.Behaviors.cache = [];
	}
});

Event.observe(window, 'unload', CD3.Behaviors.unload);