/**
 * Construtor da classe DOM.Register
 * 
 * @constructor
 * @return {DOM.Register}
 */

DOM.Register = function() {
	
	/**
	 * @private, @type Hash
	 */
	this.events = new Hash();
};

/**
 * Adiciona um tratador de evento (ou uma lista de tratadores) a lista de tratadores de um evento (ou as listas de tratadores de eventos)
 * 
 * @param {String|String[]} event
 * @param {Function|Function[]} handler
 * @return {DOM.Register}
 */
DOM.Register.prototype.addEvent = function(event, handler) {
	if (Util.isArray(event)) {
		var register = this;
		event.forEach(function(event) { register.addEvent(event, handler); });
	} else if (Util.isArray(handler)) {
		var register = this;
		handler.forEach(function(handler) { register.addEvent(event, handler); });
	} else {
		this.getEventList(event).push(handler);
	}

	return this;
};

/**
 * Retorna a lista de eventos
 * 
 * @param {String} event
 * @return {Function[]}
 */
DOM.Register.prototype.getEventList = function(event) {
	if (!this.hasEvent(event)) {
		var list = [];
		this.events.set(event, list);
		return list;
	}
	
	return this.events.get(event);
};

/**
 * Remove da lista de evento (ou das listas de eventos) um tratador de evento (ou uma lista de tratadores de eventos) do registro
 * Caso for omitido o tratador de evento, então remove todos os tratadores da lista de evento (ou das listas de eventos)
 * 
 * @param {String|String[]} event
 * @param {Function|Function[]} handler [undefined]
 * @return {Function|Function[]}
 */
DOM.Register.prototype.removeEvent = function(event, handler) {
	if (Util.isArray(event)) {
		event.forEach(function(/*String*/ event) { this.removeEvent(event, handler); }, this);
	} else if (Util.isArray(handler)) {
		handler.forEach(function(/*Function*/ handler) { this.removeEvent(event, handler); }, this);
	} else {
		if (Util.isUndefined(handler)) {
			this.events.remove(event);
			return null;
		}

		if (!this.events.exists(event)) {
			return null;
		}
		
		var list = this.getEventList(event);
		list.removeElement(handler);
		if (Util.isEmpty(list)) {
			this.events.remove(event);
		}
	
	}

	return handler;		
};

/**
 * Verifica se todos os eventos estão vazios
 * 
 * @return {Boolean}
 */
DOM.Register.prototype.isEmpty = function() {
	return this.events.isEmpty() || this.events.toArray().every(function(/*Hash*/ item) { return item.isEmpty(); });
};

/**
 * Retorna a lista de tipos de eventos registrados
 * 
 * @type String[]
 */
DOM.Register.prototype.getEventTypes = function() {
	return this.events.indexes();
};

/**
 * Verifica se um determinado evento está registrado
 * 
 * @param {String} event
 * @return {Boolean}
 */
DOM.Register.prototype.hasEvent = function(event) {
    return this.events.exists(event);
}
