var Utils = {	
	js_includes: new Array(),
	css_includes: new Array(),
	loading: new Array(),
	failed: new Array(),	
	base_url: function(href) {
		var length = href.indexOf('?');
		if (length == -1) {
			length = href.length;
		}
		length = href.indexOf('#');
		if (length == -1) {
			length = href.length;
		}		
		return href.substr(0, length);		
	},	
	self_url: function() {
		return this.base_url(window.location.href);
	},	
	include: function(jsFileLocation) {
		if(this.jsIsIncluded(jsFileLocation)) return;
		document.write("\n<script type=\"text/javascript\" src=\""+jsFileLocation+"\"><\/script>\n");
		this.js_includes.push(jsFileLocation);
	},
	includeAJAX: function(jsFileLocation, callback) {
		if(	this.jsIsLoaded(jsFileLocation) || this.isLoading(jsFileLocation) ) return;
		this.loading.push(jsFileLocation);
		var req = new Ajax.Request(jsFileLocation, {
			method: "GET",
			onSuccess: function(transport) {
				window.eval(transport.responseText);				
				this.js_includes.push(jsFileLocation);
				this.loading = this.loading.without(jsFileLocation);
				eval(callback);
			}.bind(this),
			onFailure: function() {
				this.loading = this.loading.without(jsFileLocation);
				this.failed.push(jsFileLocation);
			}.bind(this)
		});		
	},
	jsIsIncluded: function(jsFileLocation) {
		if(this.js_includes.indexOf(jsFileLocation) != -1) {
			return true;
		}
		return false;
	},
	jsIsLoaded: function(jsFileLocation) {
		return this.jsIsIncluded(jsFileLocation);
	},
	isLoading: function(item) {
		if (this.loading.indexOf(item) != -1) {
			return true;
		} 
		return false;
	},
	includeCSS: function(cssFileLocation) {
		if(this.css_includes.indexOf(cssFileLocation) != -1) return; // include only once
		document.write("\n<link rel=\"stylesheet\" type=\"text/css\" href=\""+cssFileLocation+"\" />\n");
		this.css_includes.push(cssFileLocation);		
	},
	requireScriptaculous: function() {
		this.include("/js/lib/scriptaculous/scriptaculous.js");
	},
	sleep: function(obj, callback, wait_seconds) {
		var ms = wait_seconds*1000;
  		window.setTimeout( function() { eval("obj." + callback); }, ms);	
	}	
};

var NLMTA = {
	ajax_on_click: null,
	sub_nav_anchors: null,
	load: function() {
		this.ajax_on_click = this.ajaxOnClick.bindAsEventListener(this); 
		this.sub_nav_anchors = '#subnav a';
		this.setSubNav();
		this.ajaxify();
	},
	setSubNav: function () {
		var items = $$(this.sub_nav_anchors);
		for(var i = 0; i < items.length; i++) {
			var anchor = items[i];
			if(anchor.href == Utils.self_url()) {
				anchor.addClassName('active');
			}
		}
	},
	ajaxify: function() {
		$$('a.ajax').each(function (s) {
			Event.observe(s, "click", this.ajax_on_click);
		}.bind(this));
	},
	ajaxOnClick: function(event) {	
		event.stop();
		this.ajax = new Ajax_Follow(event);
		this.ajax.run();
	},
	closeAjaxResponse: function() {
		this.ajax.close();
	}
};

function Ajax_Follow(event) {
	this.element = Event.element(event).identify();
	this.href = $(this.element).href;
	this.ajax_block_class = 'ajax_response';   
	this.ajax_blocks = 'div.'+this.ajax_block_class;
	this.loading_div = 'loading';
	this.response_div = 'response';
	this.run = function() {
		this.showLoading();
		this.sendRequest();
	};
	this.clearResults = function() {
		$$(this.ajax_blocks).each(function(s) {
			s.hide();
		});		
	};
	this.showLoading = function() {
		var id = this.loading_div;
		var div = new Element("div", {'id': id, 'class' : this.ajax_block_class}).update("Loading...");
		div.hide();
		Element.insert($(this.element), {"after": div});
		Effect.BlindDown(div);
	};
	this.hideLoading = function() {
		$(this.loading_div).remove();
	};
	this.sendRequest = function() {
		var req = new Ajax.Request(this.href, {
			method: 'post',
			parameters: {ajax: "true"},
			on401: function() {
				$(this.loading_div).update("Server Error");
			}.bind(this),
			onSuccess: function(transport) {
				this.hideLoading();
				this.displayResults(transport.responseText);
			}.bind(this),
			onFailure: function() {
				$(this.loading_div).update("Server Error");
			}.bind(this)			
		});
	};
	this.displayResults = function(results) {
		var id = this.response_div;
		if($(id) == undefined) {
			var div = new Element("div", {'id': id, 'class' : this.ajax_block_class});
			Element.insert($('ajax_list'), {"before": div});
			div.hide();
		} else {
			var div = $(id);
		}
		//TODO out of scope
		var close_button = new Element('a', {id: "close_button", href: "javascript:NLMTA.closeAjaxResponse()", title: "Close"});
		close_button.style.display = "block";
		close_button.style.cssFloat = "right";
		close_button.style.color = "#9F9"; // ie6
		close_button.update("Close");		
		div.update(results);
		Element.insert(div, {"bottom": close_button});		
		Effect.Appear(div, {duration: .5, from:0, to:1});		
	};	
	this.close = function() {
		$(this.response_div).remove();
	};
}
var Object_Loader = {
	object_names: new Array(),
	objects: new Array(),	
	usr_object_library: "/js/usr/lib/",
	usr_object_file_ext: ".js", 
	loadUsrObject: function(object_name) {
		this.object_names.push(object_name);
		Utils.include(this.usr_object_library + object_name + this.usr_object_file_ext);
	},
	create_class: function(class_name) {
       return new Function('return new ' + class_name)();
    },	
	run: function() {
		for(var i=0; i < this.object_names.length; i++) {
			var str = "new " + this.object_names[i] + "()";
			this.objects[i] = eval(str);
			this.objects[i].initialize();
		}
	},
	changeUsrObjectLibrary: function(new_library) {}
};

Element.addMethods('INPUT', {
	getLabel: function(element) {
		return element.identify();
		//return Element.previous(element).innerHTML.split(':')[0];
	}
});

Number.prototype.toRad = function() {  // convert degrees to radians
	return this * Math.PI / 180;
}

Number.prototype.roundUp = function() {
	return this.ceil();
}	

String.prototype.ucwords = function(){ //v1.0
    return this.replace(/[\w']+/g, function(a){    	
        return a.charAt(0).toUpperCase() + a.substr(1);
    });
};

Utils.requireScriptaculous();		
Event.observe(window, 'load', Object_Loader.run.bind(Object_Loader));
Event.observe(window, "load", NLMTA.load.bind(NLMTA));
