/// <module name="NI" version="0.2:18.01.2007">
/// The base module to hold all framework components.
/// </module>

var NI;

(function () {

	NI = (function (name) {

		var Module = function (name) {
			this.toString = function () {
				return name;
			};
		};

		Module.prototype.toString = function () {
			return "Module";
		};

		Module.prototype.createSubmodule = function (submodulePath) {
			var current = this;
			var parts = submodulePath.split(".");
			for (var i = 0, length = parts.length; i < length; i++) {
				var submodule = parts[i];
				if (!current[submodule]) {
					current[submodule] = new Module(submodule);
				}
				current[submodule].toString = function () {
					return (current.toString() + "." + submodule);
				};
				current = current[submodule];
			}
		};

		Module.prototype.importComponent = function (component, submodulePath) {
			var submodule = _resolveSubmodule.call(this, (submodulePath || ""));
			var componentName = (function () {
				return (this instanceof Function ? this.prototype : this).toString();
			}).call(component);
			var toString = function () {
				return (this + "." + componentName);
			};
			this[componentName] = component;
			if (component instanceof Function) {
				this[componentName].prototype.toString = toString;
			}
			else {
				this[componentName].toString = toString;
			}
		};

		Module.prototype.requireComponent = function (component) {
			var parts = component.split(".");
			var current = this;
			for (var i = 0, length = parts.length; i < length; i++) {
				var part = parts[i];
				if (part in current) {
					current = current[part];
				}
				else {
					throw new Error(this + " : '" + component + "' is required but not included ('" + part + "' does not exist)");
				}
			}
		};

		var _resolveSubmodule = function(path) {
			var result = this;			
			if (path.length > 0) {
				var parts = path.split(".");
				for (var i = 0, length = parts.length; i < length; i++) {
					var current = parts[i];
					if (current in result) {
						result = result[current];
					}
					else {
						throw new Error(this + "::_resolveSubmodule(path) : could not resolve '" + path + "' ('" + current + "' does not exist)");
					}
				}
			}
			return result;
		};

		return (function () {
			var module = new Module(name);
			module.importComponent(Module);
			return module;
		})();

	})("NI");

})();