/**
* Subject
*  subject is a event manager that propagates onchage messages (right?)
* TODO: add better description .. plz / jonas
* Author: Christian Vejrich @ firstrater com
* Refactoring: jonas @ firstrater se
* Date: 2007-09-14
*/
function Subject(name) {
    this.name = name;
    this.childSubjects;
    this.listeners = new HashMap();	
}
/**
*
*/
Subject.prototype.addChildSubject = function(subjectKey){
	//alert("adding child subject: " +subjectKey + "to subject: " + this.name);
	//lazy init.
  	if(!this.childSubjects){
  		this.childSubjects = new HashMap();
	}
	this.childSubjects.put(subjectKey,new Subject(subjectKey)); 
	return;
};

/**
 *
 */
Subject.prototype.registerListenerToSubject = function(listener){

	if(this.listeners.get(listener.name)!=null){
		alert("Warning! - Listener with name: " + listener.name + " already attached to subject.");
	}
	
		//alert("adding listener to subject:" + this.name + ", listener is: " + listener.name);
		
	 this.listeners.put(listener.name,listener);

	return;
};


/**
*
*/
Subject.prototype.removeChildSubject = function(subjectKey){
  	if(!this.childSubjects) return;
	this.childSubjects.remove(subjectKey);
};  

/**
*
*/
Subject.prototype.getAllChildSubjects = function(subjectKey){
	if(!this.childSubjects) return null;
	return this.childSubjects;
};

/**
*
*/
Subject.prototype.notifyListenersAboutChange = function(){

    this.listeners.foreach(function(listener,l) {
       if (l && l["notifyAboutIncomingChange"]) l.notifyAboutIncomingChange();
	   else alert("missing method notifyAboutIncomingChange for listener:"+listener);
    });

	//notify this subject's child subjects listeners.	
	if(this.childSubjects){
	    this.childSubjects.foreach(function(subject,s) {
			s.notifyListenersAboutChange();
		});
	}
	return;
};

/**
*
*/
Subject.prototype.notifyListenersAboutChangeStop = function(){

    this.listeners.foreach( function(listener,l) {
		l.notifyAboutIncomingChangeStop();
	});

	//notify this subject's child subjects listeners.	
	if(this.childSubjects){
		this.childSubjects.foreach( function(subject, s) {
			s.notifyListenersAboutChangeStop();
		});
	}
	return;
};

/**
*
*/
Subject.prototype.notifyListeners = function(object){

    this.listeners.foreach( function(listener,l) {
		//alert(l.name);
		l.notify(object);
	});

	//notify this subject's child subjects listeners.	
	if(this.childSubjects){
	   
	    this.childSubjects.foreach( function(subject, s) {
			s.notifyListeners(object);
		});
	}
	return;
};

/**
* getChildSubject
*/
Subject.prototype.getChildSubject = function(subjectKey){
	// alert("getChildSubject key is: " + subjectKey );
	if(!this.childSubjects) return null;
	return this.childSubjects.get(subjectKey);
};
