orion.Framework = function () {
	this._installOrderBundles = [];
	this._resolveOrderBundles = [];
	this._exports = {};
	this._requiredBundles = {};
	this._properties = {};
	this._currentBundleId = 0;
	this._loader = new orion.ModuleLoader(this);
};

orion.Framework.prototype = {
	getBundles : function() {
		return this._installOrderBundles.slice();
	},
	getProperty : function(name) {
		return this._properties[name];
	},
	setProperty : function(name, value) {
		this._properties[name] = value;
	},
	installBundle : function(location, headers) {
		if (location === undefined)
			throw "location cannot be undefined";
		
		if (location === null)
			throw "location cannot be null";

		var bundle = new orion.Bundle(this, this._currentBundleId, location, headers);

		for ( var i = 0; i < this._installOrderBundles.length; i++) {
			if (bundle.equals(this._installOrderBundles[i]))
				return this._installOrderBundles[i];
		}
		this._installOrderBundles[this._currentBundleId] = bundle;
		this._currentBundleId++;

		return bundle;
	},
	refresh : function() {
		var uninstalledBundleFound = false;
		var resolvedBundles = this._resolveOrderBundles.slice();
		var i = 0;
		var bundle = null;
		
		var newInstallOrderBundles = [];
		for (i = 0; i < this._installOrderBundles.length; i++) {
			bundle = this._installOrderBundles[i];
			if (bundle.getState() !== orion.Bundle.UNINSTALLED) {
				newInstallOrderBundles.push(bundle);
			}
		}
		this._installOrderBundles = newInstallOrderBundles;
		
		for (i = 0; i < resolvedBundles.length; i++) {
			bundle = resolvedBundles[i];
			if (bundle.getState() === orion.Bundle.UNINSTALLED) {
				uninstalledBundleFound = true;
			}

			if (uninstalledBundleFound) {
				this._unresolveBundle(bundle);
			}
		}
		if (uninstalledBundleFound) {
			var newResolveOrderBundles = [];
			for (i = 0; i < this._resolveOrderBundles.length; i++) {
				bundle = this._resolveOrderBundles[i];
				if (bundle.getState() === orion.Bundle.RESOLVED || bundle.getState() === orion.Bundle.ACTIVE) {
					newResolveOrderBundles.push(bundle);
				}
			}
			this._resolveOrderBundles = newResolveOrderBundles;

			this.resolve();
		}
	},
	resolve : function() {
		var unresolvedBundles = [];
		var i = 0;
		for (i = 0; i < this._installOrderBundles.length; i++) {
			var bundle = this._installOrderBundles[i];
			if (bundle.getState() === orion.Bundle.INSTALLED)
				unresolvedBundles.push(bundle);
		}

		var resolvedBundles = [];
		var resolvedBundle = null;
		while (unresolvedBundles.length !== 0) {
			resolvedBundle = this._stepResolver(unresolvedBundles);
			if (resolvedBundle !== null)
				resolvedBundles.push(resolvedBundle);
			else
				break;
		}
	},
	shutdown : function() {
		var reversed = this._installOrderBundles.slice().reverse();
		for ( var i = 0; i < reversed.length; i++) {
			var bundle = reversed[i];
			bundle.uninstall();
		}
		this.refresh();
	},
	_getBundleContext : function(bundle) {
		return new orion.BundleContext(bundle, this);
	},
	_stepResolver : function(unresolvedBundles) {
		for (var i = 0; i < unresolvedBundles.length; i++) {
			var bundle = unresolvedBundles[i];
			if (this._resolveBundle(bundle)) {
				this._resolveOrderBundles.push(bundle);
				unresolvedBundles.splice(i,1);
				return bundle;
			}
		}
		return null;
	},
	_resolveBundle: function(bundle) {
		if (bundle._isSingleton() && this._requiredBundles[bundle.getName()])
			return false;

		if (this._wire(bundle)) {
			bundle._resolve();
			this._addExports(bundle);
			this._addRequiredBundle(bundle);
			return true;
		}
		this._unwire(bundle);
		return false;
	},
	_wire : function(bundle) {
		var imports = bundle._getImports();
		for (var i = 0; i < imports.length; i++) {
			var jsImport = imports[i];
			var name = jsImport.getName();
			var candidates = this._exports[name];
			var satisfied = false;
			if (candidates) {
				for (var j = 0; j < candidates.length; j++) {
					var candidate = candidates[j];
					satisfied = jsImport.wire(candidate);
					if (satisfied)
						break;
				}
			}
			if (!satisfied && !jsImport.isOptional())
				return false;
		}
		return true;
	},
	_addExports : function(bundle) {
		var exports = bundle._getExports();
		for (var i = 0; i < exports.length; i++) {
			var jsExport = exports[i];
			var name = jsExport.getName();
			var namedExports = this._exports[name];
			if (!namedExports) {
				namedExports = [];
				this._exports[name] = namedExports;
			}
			namedExports.push(jsExport);
			namedExports.sort(orion.Framework._exportsComparator);
		}
	},
	_addRequiredBundle : function(bundle) {
		var name = bundle.getName();
		var namedBundles = this._requiredBundles[name];
		if (! namedBundles) {
			namedBundles = [];
			this._requiredBundles[name]= namedBundles;
		}
		namedBundles.push(bundle);
		namedBundles.sort(orion.Framework._requireBundlesComparator);
	},
	_unresolveBundle : function(bundle) {
		this._removeExports(bundle);
		this._removeRequiredBunde(bundle);
		bundle._unresolve();
		this._unwire(bundle);
	},
	_removeExports : function(bundle) {
		var exports = bundle._getExports();
		for ( var i = 0; i < exports.length; i++) {
			var jsExport = exports[i];
			var name = jsExport.getName();
			var namedExports = this._exports[name];
			if (!namedExports)
				continue;

			for ( var j = 0; j < namedExports.length; j++) {
				if (namedExports[j] === jsExport) {
					namedExports.splice(j, 1);
					break;
				}
			}
			if (namedExports.length === 0)
				delete this._exports[name];
		}
	},
	_removeRequiredBunde : function(bundle) {
		var name = bundle.getName();
		var namedBundles = this._requiredBundles[name];
		if (!namedBundles)
			return;

		for ( var i = 0; i < namedBundles.length; i++) {
			if (namedBundles[i] === bundle) {
				namedBundles.splice(i, 1);
				break;
			}
		}
		if (namedBundles.length === 0)
			delete this._requiredBundles[name];
	},
	_unwire : function(bundle) {
		var imports = bundle._getImports();
		for ( var i = 0; i < imports.length; i++) {
			var jsImport = imports[i];
			jsImport.unwire();
		}
	}
};

orion.Framework._exportsComparator = function(export0, export1) {
	// order switched for descending order
	var result = export1.getVersion().compareTo(export0.getVersion());
	if (result == 0)
		result = export0.getBundleId() - export1.getBundleId();

	return result;
};

orion.Framework._requireBundlesComparator = function(bundle0, bundle1) {
	// order switched for descending order
	var result = bundle1.getVersion().compareTo(bundle0.getVersion());
	if (result == 0)
		result = bundle0.getBundleId() - bundle1.getBundleId();

	return result;
};

orion.Framework._fetch = function(location){
	if (typeof XMLHttpRequest != "undefined") {
		var request = new XMLHttpRequest();
		request.open("GET", location, false);
		request.send();
		return request.responseText;
	}
	
	var url = new java.net.URL(location);	
    var reader = new java.io.InputStreamReader(url.openStream());
    var stringWriter = new java.io.StringWriter();
    var buffer = java.lang.reflect.Array.newInstance(java.lang.Character.TYPE, 1024);    
    var charsRead;
	
	try { 
	    while ((charsRead = reader.read(buffer, 0, 1024)) != -1) {
	    	stringWriter.write(buffer, 0, charsRead);
	    }
	} finally {
		reader.close;
		stringWriter.close();
	}
	return stringWriter.toString();		
};

orion.Framework._eval = function(script){
	// done to give global scope when evaling
	return eval(script);
};





