// Copyright (c) 2005-2006 Justin Palmer (http://encytemedia.com)
// Examples and documentation (http://encytemedia.com/event-selectors)
// Inspired by the work of Ben Nolan's Behaviour (http://bennolan.com/behaviour)
// Modified by Leo Plaw August 2006 (http://leo-plaw.guildmedia.net)

var EventSelectors = {
	version: '1.0_pre',
	cache: [],
	rules: {},

	register: function(newRules){
		for (var property in newRules) { this.rules[property] = newRules[property]; }
	},

  start: function(rules) {
  		
		this.register(rules);
		this.timer = new Array();
		this._extendRules();
		this.assign();
	},

	assign: function() {
		var observer = null;
		this._unloadCache();
		this.rules._each(function(rule) {
			var selectors = $A(rule.key.split(','));
			selectors.each(function(selector) {
				var pair = selector.split(/:(?=[a-z]+$)/);
				var event = pair[1];
				$$(pair[0]).each(function(element) {
					if(pair[1] == '' || pair.length == 1) return rule.value(element);
					if(event.toLowerCase() == 'loaded') {
						this.timer[pair[0]] = setInterval(this._checkLoaded.bind(this, element, pair[0], rule), 15);
					} else {
						observer = function(event) {
							var element = Event.element(event);
							if (element.nodeType == 3)	   // Safari Bug (Fixed in Webkit)
								element = element.parentNode;
							rule.value($(element), event);
						}
						this.cache.push([element, event, observer]);
						Event.observe(element, event, observer);
					}
				}.bind(this));
			}.bind(this));
		}.bind(this));
	},

	apply: function() {
		this.assign();
	},

	addRules: function(newRules) {
		Object.extend(newRules, this.rules);
	},

	addLoadEvent: function(func){
		Event.observe(window, 'load', func);
	},

	_unloadCache: function() {
		if (!this.cache) return;
		for (var i = 0; i < this.cache.length; i++) {
			Event.stopObserving.apply(this, this.cache[i]);
			this.cache[i][0] = null;
		}
		this.cache = [];
	},

	_checkLoaded: function(element, timer, rule) {
		var node = $(element);
		if(element.tagName != 'undefined') {
			clearInterval(this.timer[timer]);
			rule.value(node);
		}
	},

	_extendRules: function() {
			
  		
		Object.extend(this.rules, {
		 _each: function(iterator) {
			 for (key in this) {
			 
				 if(key == '_each') continue;
				 var value = this[key];
				 var pair = [key, value];
				 pair.key = key;
				 pair.value = value;
				 iterator(pair);
				 
			 }
		 }
		 
		});
	}
}

// Remove/Comment this if you do not wish to reapply Rules automatically
// on Ajax request.
Ajax.Responders.register({
  onComplete: function() { EventSelectors.assign(Rules);}
})