//____________________________________________________________________
function Authorisation(){

	var self				= this;
	
	var superAuthority		= null;
	var defined_bool		= false;
	var netAuth_bool 		= true;
	var localAuth_bool		= true;
		
	var user;
	var getSuperAuthorisation = function(){return true;};
	
	var broadcaster			= new Broadcaster(this);
	broadcaster.createEventType('validate');
	broadcaster.createEventType('invalidate');
	
	this.__defineGetter__('valid',function(){return netAuth_bool;});
	evaluateValidity();
	
	//----------------------------------------------------------------
	function evaluateValidity(){
		
		// if provided then defer to either user login or parent authority
		var superAuth_bool	= getSuperAuthorisation();
		var newNetAuth_bool = (superAuth_bool && localAuth_bool);
		
		// store new validity and broadcast change if necessary 
		if(newNetAuth_bool != netAuth_bool){
			netAuth_bool	= newNetAuth_bool;
			var event_str	= netAuth_bool? 'validate' : 'invalidate';
			broadcaster.triggerEvent(event_str);
		}
	};
	//________________________________________________________________
	this.validate = function(){
		
		localAuth_bool		= true;
		evaluateValidity();
	};
	//________________________________________________________________
	this.invalidate = function(){
		
		localAuth_bool		= false;
		evaluateValidity();
	};
	//________________________________________________________________
	this.reevaluate = function(){
		
		evaluateValidity();
	};
	//________________________________________________________________
	this.removeUserLoginRequirement = function(usernameProperty){
		
		getSuperAuthorisation = function(){return true;};
	
		user.removeEventListener('login',evaluateValidity);
		user.removeEventListener('logout',evaluateValidity);
		usernameProperty.removeEventListener('valueChange',evaluateValidity);
		user				= null;
		evaluateValidity();
	};
	//________________________________________________________________
	this.requireUserLogin = function(user_arg,usernameProperty){
		
		// ensure we don't over-authorise
		if(superAuthority){
			throw new Error('SuperAuthority has already been defined');
		}
		user				= user_arg;
		
		// define superAuthorisation property
		getSuperAuthorisation = function(){
			return (user.loggedIn && user.username==usernameProperty.value);
		};
		
		user.addEventListener('login',evaluateValidity);
		user.addEventListener('logout',evaluateValidity);
		usernameProperty.addEventListener('valueChange',evaluateValidity);
		evaluateValidity();
	};
	//________________________________________________________________
	this.defineSuperAuthority = function(superAuthority_arg){
		
		// ensure we don't over-authorise
		if(user){
			throw new Error('User authorisation has already been defined');
		}

		// if changing authority then detach listeners from old one
		if(superAuthority){
			superAuthority.removeEventListener('validate',evaluateValidity);
			superAuthority.removeEventListener('invalidate',evaluateValidity);
		}

		// define new superAuthority
		superAuthority		= superAuthority_arg;
		getSuperAuthorisation = function(){
			return superAuthority.valid;
		}

		// add new event listeners
		superAuthority.addEventListener('validate',evaluateValidity);
		superAuthority.addEventListener('invalidate',evaluateValidity);
		evaluateValidity();
	};
};	//________________________________________________________________
//____________________________________________________________________