/**
* Lazy Loading and Declarative Binding
* Requires Prototype 1.6
* ©2008 Bob Matsuoka
**/
var loader_binder = {};  //namespace
/** discover all elements with "hashandler" class name **/
loader_binder.discoverHandlers = function() { 
	$$('.hashandler').each(function(elem) {
		$w(elem.className).each(function(classname) {
			if (classname.indexOf('handler:') == 0) {
				var handler_parts = classname.split(':');
				// load and bind all scripts to elements
				loader_binder.bindHandler(elem, handler_parts[1], handler_parts[2]);
			}
		});
	});
}
/** load and bind script to element **/
loader_binder.bindHandler = function(elem, handler_src, handler_classname) {
	// console.log(elem);
	// console.log(handler_src);
	// console.log(handler_classname);
	if (!handler_src) {
		console.log('Sorry, no handler source provided');
		return;
	}
	// lazy load handler_src
	if (!handler_classname) {
		loader_binder.loader(handler_src);
	} else {
		loader_binder.loader(handler_src, function(){loader_binder.binder(elem, handler_classname)} );
	}
	// bind object to element
}
loader_binder.loader = function(handler_src, callback) {
	// look for script first
	$$("head")[0].childElements().each(function(elem){
		if (elem.type && elem.type.toLowerCase().indexOf('javascript') > -1) {
			// console.log(elem.src);
			// check to see if script already loaded; script may be root path
			if (elem.src.endsWith(handler_src)) {
				return;
			}
		}
	});
	var script = document.createElement("script");
	script.src = handler_src;
	script.type = "text/javascript";
	$$("head")[0].appendChild(script);
	if (callback) {
		if (Prototype.Browser.WebKit && !navigator.userAgent.match(/Version\/3/)) { 
			loader_binder._timer[handler_src] = setInterval(function() {
				try {
					eval(classname);
					clearInterval(loader_binder._timer[handler_src]);
					callback(handler_src); // call the callback handler
				} catch (e) {}
			}, 10);
		} else if (Prototype.Browser.Opera) { 
		 	loader_binder._timer[handler_src] = setInterval(function() {
				if (/loaded|complete/.test(document.readyState)) {
					clearInterval(loader_binder._timer[handler_src]);
					callback(handler_src); // call the callback handler
				}
			}, 10);
		} else {
			script.onload = function () {
				callback(handler_src);
			}
			script.onreadystatechange = function () {
				if (script.readyState == 'loaded' || script.readyState == 'complete') {
					callback(handler_src);
				}
			}
		}
	}
}
loader_binder.binder = function(elem, handler_classname) {
	// console.log('Binding: ' + elem);
	// console.log('to: ' + handler_classname);
	elem.handler = {};
	elem.handler = eval('new '+handler_classname+'(elem)');
	// console.log('...bound');
}
loader_binder._timer = {};
// load discoverHandlers on window load
Event.observe(window, 'load', loader_binder.discoverHandlers);