orion.Bundle = function(framework, bundleData) {
	this._framework = framework;
	this._bundleData = bundleData;
	this._name = null;
	this._version = null;
	this._imports = [];
	this._requires = [];
	this._exports = [];
	this._resources = {};
	this._singleton = false;
	this._markedStarted = false;
	this._state = orion.Bundle.INSTALLED;
	this._scope = {};
	this._bundleContext = null;
	this._activator = null;
	this._script = null;

	var headers = bundleData.getHeaders();
	this._parseName(headers[orion.Constants.BUNDLE_NAME]);
	this._parseVersion(headers[orion.Constants.BUNDLE_VERSION]);
	this._parseImports(headers[orion.Constants.BUNDLE_IMPORTS]);
	this._parseExports(headers[orion.Constants.BUNDLE_EXPORTS]);
	this._parseRequires(headers[orion.Constants.BUNDLE_REQUIRES]);
	this._parseResources(headers[orion.Constants.BUNDLE_RESOURCES]);
	this._parsePath(headers[orion.Constants.BUNDLE_PATH]);
};

orion.Bundle.UNINSTALLED = 1;
orion.Bundle.INSTALLED = 2;
orion.Bundle.RESOLVED = 4;
orion.Bundle.STARTING = 8;
orion.Bundle.STOPPING = 16;
orion.Bundle.ACTIVE = 32;

orion.Bundle.prototype = {
	getName : function() {
		return this._name;
	},
	getVersion : function() {
		return this._version;
	},
	getBundleId : function() {
		return this._bundleData.getBundleId();
	},
	getLocation : function() {
		return this._bundleData.getLocation();
	},
	getHeaders : function() {
		return this._bundleData.getHeaders();
	},
	getState : function() {
		return this._state;
	},
	getEntry : function(path) {
		if (!path || !path instanceof String || !this._resources[path])
			return null;
		
		return this.getLocation() + path;
	},
	getResource : function(path) {
		if (!path || !path instanceof String)
			return null;
		
		var i = 0;
		var resource;
		for (i = 0; i < this._imports.length; i++) {
			var jsImport = this._imports[i];
			var jsExport = jsImport.getWiredExport();
			if (!jsExport)
				continue; // optional
			var name = jsExport.getName();
			if (name.charAt(0) != "/")
				continue; // not a resource
			if (path.indexOf(name)==0) {
				resource = jsExport.getExportingBundle().getEntry(path);
				if (resource)
					return resource;
			}
		}

		// process requires
		for (i = 0; i < this._requires.length; i++) {
			var jsRequire = this._requires[i];
			var wiredBundle = jsRequire.getWiredBundle();
			if (!wiredBundle) {
				continue; //optional
			}
			var wiredBundleExports = wiredBundle._getExports();
			for (var j=0; j < wiredBundleExports.length; j++) {
				jsExport = wiredBundleExports[j];
				var name = jsExport.getName();
				if (name.charAt(0) != "/")
					continue; // not a resource
				if (path.indexOf(name)==0) {
					resource = jsExport.getExportingBundle().getEntry(path);
					if (resource)
						return resource;
				}
			}
		}		
		return this.getEntry(path);	
	},
	equals : function(other) {
		if (this === other)
			return true;

		if (!other instanceof orion.Bundle)
			return false;

		if (this._name !== other._name)
			return false;
		if (this._version === null) {
			if (other._version !== null)
				return false;
		} else if (!this._version.equals(other._version))
			return false;
		return true;
	},
	uninstall : function() {
		this._state = orion.Bundle.UNINSTALLED;
	},
	start : function() {
		this._markedStarted = true;
		if (this._state !== orion.Bundle.RESOLVED)
			return;

		this._state = orion.Bundle.STARTING;
		this._bundleContext = this._framework._getBundleContext(this);
		this._activator = this._createActivatorInstance();
		if (this._activator) {
			this._activator.start(this._bundleContext);
		}
		this._state = orion.Bundle.ACTIVE;
	},
	stop : function() {
		markedStarted = false;
		if (this._state !== orion.Bundle.ACTIVE)
			return;

		this._state = orion.Bundle.STOPPING;
		if (this._activator) {
			this._activator.stop(this._bundleContext);
		}
		this._state = orion.Bundle.RESOLVED;
	},
	load : function(name) {
		var value = this._scope;
		if (value === null || value === undefined) {
			return undefined;
		}
		var names = name.split(".");
		for ( var i = 0; i < names.length; i++) {
			if (value === null || value === undefined) {
				return undefined;
			}
			value = value[names[i]];
		}
		return value;
	},
	_isSingleton : function() {
		return this._singleton;
	},
	_isMarkedStarted : function() {
		return this._markedStarted;
	},
	_getImports : function() {
		return this._imports;
	},
	_getExports : function() {
		return this._exports;
	},
	_getRequires : function() {
		return this._requires;
	},
	_createActivatorInstance : function() {
		var activatorName = this.getHeaders()[orion.Constants.BUNDLE_ACTIVATOR];
		if (activatorName === null || activatorName === undefined)
			return null;

		var activatorFunction = this.load(activatorName);
		if (typeof activatorFunction !== "function")
			throw "" + activatorName + " is not a function.";
		return new activatorFunction();
	},
	_resolve : function() {
		if (this._state != orion.Bundle.INSTALLED)
			return;

		var namedExports = {};
		var jsExport = null;
		var i = 0;
		// process imports (first)
		for (i = 0; i < this._imports.length; i++) {
			var jsImport = this._imports[i];
			var jsExport = jsImport.getWiredExport();
			if (!jsExport)
				continue; // optional
			var name = jsExport.getName();
			if (name.charAt(0) == "/")
				continue; // resource
			if (!namedExports.hasOwnProperty(name))
				namedExports[name] = jsImport.getWiredExport();
		}

		// process requires
		for (i = 0; i < this._requires.length; i++) {
			var jsRequire = this._requires[i];
			var wiredBundle = jsRequire.getWiredBundle();
			if (!wiredBundle) {
				continue; //optional
			}
			var wiredBundleExports = wiredBundle._getExports();
			for (var j=0; j < wiredBundleExports.length; j++) {
				jsExport = wiredBundleExports[j];
				var name = jsExport.getName();
				if (name.charAt(0) == "/")
					continue; // resource
				if (!namedExports.hasOwnProperty(name))
					namedExports[name] = jsImport.getWiredExport();
			}
		}
		
		var names = [];
		var exportName = null;
		for (exportName in namedExports) {
			if (namedExports.hasOwnProperty(exportName))
				names.push(exportName);
		}

		// this sorts the set of names we'll be importing alphabetically and
		// perhaps more importantly will allow us to create the shorter/parent dotted entries first
		names.sort();
		
		var importScope = {};
		for (i = 0; i < names.length; i++) {
			exportName = names[i];
			jsExport = namedExports[exportName];
			jsExport.addToScope(importScope);
		}

		this._evalScript(importScope);
		this._state = orion.Bundle.RESOLVED;
	},
	_evalScript : function(importScope) {
		var parameterNames = [];
		var parameterValues = [];
		var parameterName = null;
		for (parameterName in importScope) {
			if (importScope.hasOwnProperty(parameterName)) {
				parameterNames.push(parameterName);
				parameterValues.push(importScope[parameterName]);
			}
			
		}
		
		var exportNames = [];
		for (i = 0; i < this._exports.length; i++) {
			var exportName = this._exports[i].getName();
			if (exportName.charAt(0) == "/")
				continue; // resource
			var dotIndex = exportName.indexOf(".");
			if (dotIndex !== -1)
				exportName = exportName.substring(0,dotIndex);
			
			if (! exportNames.hasOwnProperty(exportName)) {
				exportNames[exportName] = true;
				exportNames.push(exportName + ":" + exportName);
			}
		}
		
		var parameterStatement = parameterNames.join(",");
		var returnStatement = "\n\nreturn {" + exportNames.join(",") + "};";
		
		var that = this;
		var _ResourceWrapper = function() {
			this.getResources = function(path) {
				return that.getResources(path);
			};
		};
		_ResourceWrapper.prototype = orion.global;
		var context = new _ResourceWrapper();		
		var finalScript = this._script + returnStatement;
		var load = new Function(parameterStatement, finalScript);
		// or alternately
		// var load = eval("(function("+parameterStatement+") {\n" + finalScript + "\n})");
		this._scope = load.apply(context, parameterValues);
	},
	_unresolve : function() {
		if (this._state == orion.Bundle.ACTIVE) {
			this.stop();
			markedStarted = true;
		}
		this._scope = null;

		if (this._state == orion.Bundle.RESOLVED)
			this._state = orion.Bundle.INSTALLED;
	},
	_parseName : function(header) {
		var tokens = header.split(orion.Constants.PARAMETER_DELIMITER);
		this._name = tokens[0].replace(/^\s+|\s+$/g, '');
		for ( var i = 1; i < tokens.length; i++) {
			var token = tokens[i];
			if (token.indexOf(orion.Constants.DIRECTIVE_EQUALS) != -1) {
				var index = token.indexOf(orion.Constants.DIRECTIVE_EQUALS);
				var directiveName = token.substring(0, index).replace(/^\s+|\s+$/g, '');
				if (directiveName.length === 0)
					throw "bad syntax: " + token + " in " + header;

				if (directiveName !== orion.Constants.SINGLETON_DIRECTIVE)
					continue;
				var value = token.substring(index + orion.Constants.DIRECTIVE_EQUALS.length).replace(/^\s+|\s+$/g, '');
				if (value.toLowerCase() === "true")
					this._singleton = true;
			} else
				throw "bad syntax: " + token + " in " + header;
		}
	},
	_parseVersion : function(header) {
		this._version = orion.Version.parseVersion(header);
	},
	_parseResources : function(header) {
		if (!header)
			return;

		var tokens = header.split(orion.Constants.CLAUSE_DELIMITER);
		for ( var i = 0; i < tokens.length; i++) {
			if (tokens[i]) {
				var path = tokens[i].replace(/^\s+|\s+$/g, '');
				this._resources[path] = true;
			}
		}
	},
	_parseRequires : function(header) {
		if (!header) 
			return;

		var tokens = header.split(orion.Constants.CLAUSE_DELIMITER);
		for ( var i = 0; i < tokens.length; i++) {
			var token = tokens[i];
			var jsRequire = new orion.Require(token);
			if (jsRequire !== null)
				this._requires.push(jsRequire);
		}
	},
	_parseExports : function(header) {
		if (!header)
			return;
		var tokens = header.split(orion.Constants.CLAUSE_DELIMITER);
		for ( var i = 0; i < tokens.length; i++) {
			var token = tokens[i];
			var jsExport = new orion.Export(token, this);
			if (jsExport !== null)
				this._exports.push(jsExport);
		}
	},
	_parseImports : function(header) {
		if (!header)
			return;

		var tokens = header.split(orion.Constants.CLAUSE_DELIMITER);
		for ( var i = 0; i < tokens.length; i++) {
			var token = tokens[i];
			var jsImport = new orion.Import(token);
			if (jsImport !== null)
				this._imports.push(jsImport);
		}
	},
	_parsePath : function(header) {
		if (!header) {
			this._script = this._bundleData.getHeaders()[orion.Constants.BUNDLE_SCRIPT] || "";
			return;
		}
		var tokens = header.split(orion.Constants.CLAUSE_DELIMITER);
		var scripts = [];
		for ( var i = 0; i < tokens.length; i++) {
			var token = tokens[i];
			var path = token.replace(/^\s+|\s+$/g, '');
			if (path === ".") {
				scripts[i] = this._bundleData.getHeaders()[orion.Constants.BUNDLE_SCRIPT];
			} else {
				var scriptURL = this.getResource(path);
				scripts[i] = orion.Framework._fetch(scriptURL);
			}
		}
		this._script = scripts.join("\n\n");
	}
};
