/**
* I am forever indebted to:
* Dustin Diaz, for general Javascript references
* Peter Michaux, for the lazy definition pattern (http://peter.michaux.ca/article/3556).
*/

var Bootstrap = Bootstrap || function() {
	// Set up Bootstrap namespace

	var Core = {
		hasClass: function(el, className) {
			if(el.className) {
				var classArr = el.className.split(' ');
				var i = classArr.length;
				while(i--) {
					if(classArr[i] == className) {
						return true;
					}
				}
			}
			return false;
		},
		addEvent: function (object,e,callback) {
			if(window.addEventListener){ // Mozilla, Netscape, Firefox
				object.addEventListener(e, callback, false);
			} else { // IE
				object.attachEvent('on' + e, callback);
			}
		},
		getTarget: function (e) {
			e = e || window.event;				// W3 || IE
			return e.target || e.srcElement;	// W3 || IE
		}
	};

	var elementCollection = function() { 		
		this.elements = [];

		this.getFromIds = function(els) {
			this.elements = [];
			var i = els.length;
			var element;

			while(element = els[--i]) {
				if (typeof element == 'string') {
					element = document.getElementById(element);
				}
				
				if(element) {
					this.elements.push(element);
				}
			}
			return this;
		}
		
		this.getFromClassName = function(searchClass,node,tag) {
			// get elements by classname. If parent is set, pull subnodes from parent rathern
			// than from document.root
			this.elements = [];
			
			if (node == null) {
				node = document;
			}
			if (tag == null) {
				tag = '*';
			}
			var els = node.getElementsByTagName(tag);
			
			var i = els.length;
			
			while(i--) {
				if ( Bootstrap.Core.hasClass(els[i], searchClass) ) {
					this.elements.push(els[i]);
				}
			}
			return this;
		}
	
		this.each = function(f_ptr) {
			var i = this.elements.length;
			while(i--) {
				f_ptr.call(this, this.elements[i]);
			}
		}
		
		this.on = function(e, f_ptr) {
			var i = this.elements.length;
			while(i--) {
				Bootstrap.Core.addEvent.call(this, this.elements[i], e, function(el){f_ptr.call(this,el)});
			}
		}
	};

	/* Global namespace functions */

	window.$ = function() {
		var args = arguments;
		var els = new elementCollection();
		els.getFromIds(args);
		return els;
	}

	window.$$ = function(searchClass,node,tag) {
    	var els = new elementCollection();
		els.getFromClassName(searchClass,node,tag);
		return els;
	}

	window.$lambda = function (v) {
		return (typeof v == 'function') ? value : function(){
			return v;
		};
	}
	
	String.prototype.capitalize = function() {
		var str_arr = this.split(' ');
		var i = str_arr.length;
		while(i--) {
			str_arr[i] = str_arr[i].substr(0,1).toUpperCase() + str_arr[i].substr(1);
		}
		return str_arr.join(' ');
	}

	Function.prototype.bind = function(obj) {
		var method = this;
		return function() {
			method.apply(obj, arguments);
		};
	} 
	
	Function.prototype.emit = function(e) {
		if((handler = ('on'+e)) && typeof(handler) == 'function') {
			return handler();	
		}
		return false;
	}

	return {	
		Core: Core,
		toString: function() { 
			return 'Campaign';
		},
		implement: function() {
				
		}
	};
}();

/**
* Loader: Used for the inclusion of additional files.
*/
Bootstrap.Loader = new function() {
	var ticToc = 50;
	var queue = [];

	var _file_included = function(path) {
		var scripts = document.getElementsByTagName('scripts');
		var i = scripts.length;
		while(i--) {
			if(scripts.src == path) {
				return true;
			}
		}
		return false;
	}

	var _include_file = function(path) {
		var script = document.createElement('script');
		script.type = 'text/javascript';
		script.src = path;
		document.getElementsByTagName('head').item(0).appendChild(script);
	}
	
	var _library_path = function() {
		var cur, 
			scripts = document.getElementsByTagName('script'),
			i = scripts.length;
			
		while(cur = scripts[--i]) {
			if(cur.src) {
				var path = cur.src.split('/');
				var filename = path.pop();
				if(filename == 'master.js') {
					var result = path.join('/') + '/';
					_library_path = function() {
						return result;
					}
					return _library_path();
				}
			}
		}
		return false;
	}

	var _monitor = function() {

		var i = queue.length;

		while(i--) {
			if(queue[i].verify()) {
				if(queue[i].callback) {
					queue[i].callback();	
				}
				queue.splice(i,1);
			}
		}
		
		if( queue.length > 0) {
			window.setTimeout( _monitor.bind(this), ticToc);
		}
		else {
			Bootstrap.Loader.onCompletion();
		}
	}

	this.Enqueue = function() {
		for(var i = 0; i < arguments.length; i++) {
			var script = [];
			if(typeof(arguments[i]) == 'string') {
				script.name = arguments[i];
			}
			else {
				script = arguments[i];
			}

			if((script.src=_library_path() + script.name + '.js') && ! _file_included(script.src)) {
				script.verify = function(){
					var className = script.name.capitalize();
					return typeof Bootstrap[className] == 'undefined' ? false : true; 
				};

				_include_file(script.src);
				queue.push(script);
			}
		}
	}
	
	this.Load = function(f_ptr) {
		this.onCompletion = f_ptr || function(){};
		_monitor();
	}
}