var OhBehave=function (root) {
	var _appliedElements=[],
		_appliedBeheviors=[];

	function initialize(element) {
		// prevent double initializations
		var i=_appliedElements.length;
		while (i-->0) if (_appliedElements[i]===element) return;

		var elementBehaviors=[],
			rx=getRx(),
			result;
		while (result=rx.exec(element.className)) elementBehaviors.push(result[1]);
		_appliedElements.push(element);
		_appliedBeheviors.push(elementBehaviors);

		for (var i=elementBehaviors.length;i--;) apply(element,elementBehaviors[i]);
	}
	function apply(element,behavior) {
		var f=OhBehave.behaviors[behavior] || root[behavior];
		if (f) f(element);
	}

	var _rx;
	function getRx() {
		if (!_rx) {
			_rx=new RegExp("(?:^|\\s)"+OhBehave.behaviorPattern.replace("*","(\\S+)")+"(?=\\s|$)","g");
		}
		return _rx;
	}

	return {
		behaviors:{},
		initialize:initialize,
		behaviorPattern:"oh-behave-*"
	};
}(this);


(function () {
	// WebKit/Presto specific

	if (!window.opera && !/webkit/i.test(navigator.userAgent)) return;
	// can be overriden with your own js framework's selector engine
	
	if (document.querySelectorAll) OhBehave.querySelectorAll=function (parent,selector) { return parent.querySelectorAll(selector); };
	else {
		if (!OhBehave.customQuerySelectorAll) {
			if (window.console && typeof(console.log)=="function") console.log("OhBehave.customQuerySelectorAll implementation is needed")
			return;
		}
		OhBehave.querySelectorAll=OhBehave.customQuerySelectorAll;
	}

	function applyOnChildren(parent) {
		var items=OhBehave.querySelectorAll(parent,".oh-behave"),
			i=items.length;
		while (i-->0) OhBehave.initialize(items[i]);
	}

	document.addEventListener("DOMContentLoaded",function (event) {
		applyOnChildren(document);
	},true);
	document.addEventListener("DOMNodeInserted",function (event) {
		// apply on current element and its children
		if (/(?:^|\s)oh-behave(?:\s|$)/.test(event.target.className)) OhBehave.initialize(event.target);
		applyOnChildren(event.target)
	},true);
})();



// customizable stuff
// OhBehave.behaviorPattern="behavior-prefix-*";
// OhBehave.customQuerySelectorAll=function (parent,selector) { return $(parent).getElements(selector); } // MooTools
// OhBehave.customQuerySelectorAll=function (parent,selector) { return $(selector,parent); } // jQuery
// OhBehave.customQuerySelectorAll=function (parent,selector) { return $(parent).select(selector); } // Prototype