module = function()
{
	var baseUrl = '.';

	var moduleName = '';

	var loadModule = function(moduleName, loadCallback)
	{
		var r = xhr();
		r.open("GET", baseUrl + "/" + moduleName + ".js", true);
		r.onreadystatechange = function() {
			if (r.readyState == 4)
				loadCallback(r.responseText);
		};
		r.send(null);
	};

	var xhr = function(loadCallback)
	{
		var xhr = (window.XMLHttpRequest && (window.location.protocol !== "file:"
		                                 || !window.ActiveXObject))
			    	? window.XMLHttpRequest()
				    : window.ActiveXObject("Microsoft.XMLHTTP");

		return (xhr);
	};
	
	return {

		source: [],
		modules: [],
		requires: [],

		load: function(name)
		{
			moduleName = name;
			loadModule(moduleName, function(code) {
				eval(code);
			});
		},

		init: function(name)
		{
			moduleName = name;
			return (this);
		},

		require: function(modules)
		{
			this.requires[moduleName] = [];

			for (var i in modules) {
				//alert(modules[i]);
				this.requires[moduleName].push(modules[i]);
				loadModule(modules[i], function(code) {
					with (window)
					    window.eval(code);
				});
			}

			return (this);
		},

		declare: function(module)
		{
			if (this.modules[moduleName])
				return (this);

			if (!this.requires[moduleName] || this.source[moduleName]) {
				var func = eval(module);
				var args = [];
				for (var i in this.requires[moduleName])
					args.push(this.modules[this.requires[moduleName][i]]);
				this.modules[moduleName] = func.apply(this, args);
			} else {
				this.source[moduleName] = module;
			}

			for (var i in this.requires) {
				var deps = 0;
				for (var j in this.requires[i])
					if (this.modules[this.requires[i][j]])
						deps++;
				if (this.requires[i].length == deps) {
					with (window)
						module.init(i).declare(this.source[i]);
				}
			}

			return (this);
		}
	};
}();
