/**
 * @author Brian
 */
var FR = (typeof FR != 'undefined')?FR:{};

/**
 * EVENT CONSTRUCTOR CREATES EVENTS AND ALLOWS OTHERS TO LISTEN TO THOSE EVENTS
 * 
 * events take source argument that is the object that created the event 
 * @param {Object} source :  object that the event is attached to.
 */
FR.event = function( source){
	this.source = source || null;
	this.listeners = [];
};
FR.event.prototype.addListener = function(method, scope){
	if(typeof method == 'function'){
		this.listeners.push({
			method: method,
			scope: scope
		});
	}
};
FR.event.prototype.removeListener = function(scope){
	for(var m=this.listeners.length-1; m>=0; m--){
		if(this.listeners[m].scope === scope){
			this.listeners.splice(m,1);
		}
	}
};
FR.event.prototype.fire = function(data, source){
	var src = source || this.source;
	var eventdata = data || {};
	for(var m=0; m<this.listeners.length; m++){
		if (this.listeners[m].scope) {
			this.listeners[m].method.call(this.listeners[m].scope, eventdata, src);
		} else {
			this.listeners[m].method(eventdata, src);
		}
	}
};


FR.billboard = function(config){
	//Protected
	var theBoard = {};
	var actions = {};
	var orphanListeners = {};

	//Public
    var pubMethods = {
		/**
		 * on :: Allows other classes to subscribe to events on the billboard
		 * @param {Object} event
		 * @param {Object} method
		 * @param {Object} scope [optional]
		 */
		on : function(event, method, scope){
			if(actions[event] && method){
				actions[event].addListener(method, scope);
			} else if(method){ //If the event does not exist now perhaps it will later...lets store these just in case
				if(! orphanListeners[event] ){
					orphanListeners[event] = [];
				}
				orphanListeners[event].push({method:method, scope:scope});
			}
		},
		/**
		*/
		off : function(event, method){
			if(actions[event] && method){
				actions[event].removeListener(method);
			}
		},
		/**
		 * Create a listenable event
		 * @param {Object} title
		 */
		addEvent:function(title, source){
			if (!actions[title]) {
				actions[title] = new FR.event(source);
				if(orphanListeners[title]){
					for(var a=0; a<orphanListeners[title].length; a++){
						var thisListener = orphanListeners[title][a];
						actions[title].addListener(thisListener.method, thisListener.scope);
					}
				}
			}
			return actions[title];
		}	
	};
    return pubMethods;
}();

