/**
 * @class HD.util.Observable
 * @description A reusable class that other classes can extend with to provide event notifications.
 * @constructor
 */
HD.util.Observable = function() {
	/** The array of observers */
	this.observers = [];
};

HD.util.Observable.prototype = {
	/**
	 * Sets the array of observers
	 * @param {array} observers The array of observers to store
	 */
	setObservers : function(observers) {
		this.observers = observers;
	},
	
	/**
	 * Adds an observer
	 * @param {object} observer The observer to add, example:
	 *                          { update: function(eventName, eventData) { ... } }
	 */
	addObserver : function(observer) {
		this.observers.push(observer);				
	},
	
	/**
	 * Removes an observer
	 * @param {object} observer The observer to remove
	 */
	removeObserver : function(observer) {
		var tempObservers = [];
		var observers = this.observers;
		for(var i = 0, len = observers.length; i < len; i++) {
			var tempObserver = observers[i];
			if(tempObserver != observer) {
				tempObservers.push(tempObserver);
			}
		}
		this.setObservers(tempObservers);
	},
	
	/**
	 * Notifies all observers of an event
	 * @param {string} eventName The name of the event
	 * @param {object} eventData Contextual data to include with the event
	 */
	notifyObservers : function(eventName, eventData) {
		var observers = this.observers;
		for(var i = observers.length - 1; i > -1; i--) {
			observers[i].update(eventName, eventData);
		}
	},
	
	/**
	 * Checks for the existence of an observer
	 * @param {object} observer The observer to search for
	 * @returns {boolean} Whether the observer exists
	 */
	checkObservers : function(observer) {
		var observers = this.observers;		
		for(var i = 0, len = observers.length; i < len; i++) {
			var tempObserver = observers[i];
			if(tempObserver == observer) {
				return true;
			}
		}		
		return false;
	}
};

HD.register("hd_observable", HD.util.Observable, {version: "1.0", build: "1"});
