orion.Require = function(header) {
	if (header === null)
		throw "header cannot be null";

	this._name = null;
	this._attributes = {};
	this._directives = {};
	this._optional = false;
	this._bundleVersionRange = orion.VersionRange.emptyRange;
	this._wiredBundle = null;

	this._parseRequire(header);
};

orion.Require.prototype = {
	_parseRequire : 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)
				this._parseDirective(token);
			else if (token.indexOf(orion.Constants.ATTRIBUTE_EQUALS) !== -1)
				this._parseAttribute(token);
			else
				throw "bad import syntax: " + token + " in " + header;
		}
	},
	_parseAttribute : function(token) {
		var index = token.indexOf(orion.Constants.ATTRIBUTE_EQUALS);
		var attributeName = token.substring(0, index).replace(/^\s+|\s+$/g, '');
		if (attributeName.length === 0)
			return;

		var value = token.substring(index + orion.Constants.ATTRIBUTE_EQUALS.length).replace(/^\s+|\s+$/g, '');

		if (attributeName === orion.Constants.BUNDLE_VERSION_ATTRIBUTE)
			this._bundleVersionRange = orion.VersionRange.parseVersionRange(value);

		this._attributes[attributeName] = value;
	},
	_parseDirective : function(token) {
		var index = token.indexOf(orion.Constants.DIRECTIVE_EQUALS);
		var directiveName = token.substring(0, index).replace(/^\s+|\s+$/g, '');
		if (directiveName.length === 0)
			return;

		var value = token.substring(index + orion.Constants.DIRECTIVE_EQUALS.length).replace(/^\s+|\s+$/g, '');
		if (directiveName === orion.Constants.RESOLUTION_DIRECTIVE && value === orion.Constants.RESOLUTION_OPTIONAL)
			this._optional = true;
		this._directives[directiveName] = value;
	},
	getName : function() {
		return this._name;
	},
	getBundleVersionRange : function() {
		return this._bundleVersionRange;
	},
	isOptional : function() {
		return this._optional;
	},
	getAttributes : function() {
		this._attributes;
	},
	getDirectives : function() {
		return this._directives;
	},
	wire : function(candidate) {
		if (this._name !== candidate.getName())
			return false;

		if (!this._checkAttributes(candidate))
			return false;

		this._wiredBundle = candidate;
		return true;
	},
	_checkAttributes : function(candidate) {
		for ( var key in this._attributes) {
			if (key === orion.Constants.BUNDLE_VERSION_ATTRIBUTE) {
				if (!this._bundleVersionRange.isIncluded(candidate.getVersion()))
					return false;
			}
		}
		return true;
	},
	getWiredBundle : function() {
		return this._wiredBundle;
	},
	unwire : function() {
		this._wiredBundle = null;
	}
};
