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

	var headers = bundleData.getHeaders();
	this._parseName(headers.name);
	this._parseVersion(headers.version);
	this._parseSingleton(headers.singleton);
	this._parseImports(headers.imports);
	this._parseExports(headers.exports);
	this._parseResources(headers.resources);
	this._parsePath(headers.path);
	this._parseGlobals(headers.globals);
};

orion.Bundle.UNINSTALLED = 1;
orion.Bundle.INSTALLED = 2;
orion.Bundle.RESOLVED = 4;

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;
			}
		}	
		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;
	},
	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;
	},
	_getImports : function() {
		return this._imports;
	},
	_getExports : function() {
		return this._exports;
	},
	_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();
		}

		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 = ["bundleContext"];
		var parameterValues = [this._framework._getBundleContext(this)];
		var parameterName = null;
		for (parameterName in importScope) {
			if (importScope.hasOwnProperty(parameterName)) {
				parameterNames.push(parameterName);
				parameterValues.push(importScope[parameterName]);
			}
		}
		
		var exportNames = [];
		for (var 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 finalScript = this._script + returnStatement;
		// var load = new Function(parameterStatement, finalScript);
		var load = orion.Framework._eval("(function("+parameterStatement+") {\n" + finalScript + "\n})//@ sourceURL=" + this.getLocation());
		this._scope = load.apply(null, parameterValues);
	},
	_unresolve : function() {
		this._scope = null;
		if (this._state == orion.Bundle.RESOLVED)
			this._state = orion.Bundle.INSTALLED;
	},
	_parseName : function(header) {
		this._name = header;
	},
	_parseSingleton : function(header) {
		if (typeof header == "boolean")
			this._singleton = header;
	},
	_parseVersion : function(header) {
		this._version = orion.Version.parseVersion(header);
	},
	_parseGlobals : function(header) {
		if (!header)
			return;

		for ( var i = 0; i < header.length; i++) {
			if (header[i]) {
				this._globals.push(header[i]);
			}
		}
	},
	_parseResources : function(header) {
		if (!header)
			return;

		for ( var i = 0; i < header.length; i++) {
			if (header[i]) {
				this._resources[header[i]] = true;
			}
		}
	},
	_parseExports : function(header) {
		if (!header)
			return;
		
		for ( var i = 0; i < header.length; i++) {
			var jsExport = new orion.Export(header[i], this);
			if (jsExport !== null)
				this._exports.push(jsExport);
		}
	},
	_parseImports : function(header) {
		if (!header)
			return;

		for ( var i = 0; i < header.length; i++) {
			var jsImport = new orion.Import(header[i]);
			if (jsImport !== null)
				this._imports.push(jsImport);
		}
	},
	_parsePath : function(header) {
		if (!header) {
			this._script = this._bundleData.getHeaders().script || "";
			return;
		}
		var scripts = [];
		for ( var i = 0; i < header.length; i++) {
			var path = header[i];
			if (path === ".") {
				scripts[i] = this._bundleData.getHeaders().script || "";
			} else {
				var scriptURL = this.getResource(path);
				scripts[i] = orion.Framework._fetch(scriptURL);
			}
		}
		this._script = scripts.join("\n\n");
	}
};
